be_files.c

Go to the documentation of this file.
00001 /*
00002  *  be_files.c
00003  *
00004  *  Copyright (c) 2006 by Christian Hamar <krics@linuxforum.hu>
00005  *  Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org>
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; either version 2 of the License, or
00010  *  (at your option) any later version.
00011  *
00012  *  This program is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *  GNU General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU General Public License
00018  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00021 #include "config.h"
00022 
00023 #include <unistd.h>
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <errno.h>
00027 #include <string.h>
00028 #include <stdint.h> /* uintmax_t */
00029 #include <sys/stat.h>
00030 #include <dirent.h>
00031 #include <ctype.h>
00032 #include <time.h>
00033 #include <limits.h> /* PATH_MAX */
00034 #include <locale.h> /* setlocale */
00035 
00036 /* libalpm */
00037 #include "db.h"
00038 #include "alpm_list.h"
00039 #include "log.h"
00040 #include "util.h"
00041 #include "alpm.h"
00042 #include "error.h"
00043 #include "handle.h"
00044 #include "package.h"
00045 #include "delta.h"
00046 #include "deps.h"
00047 
00048 
00049 /* This function is used to convert the downloaded db file to the proper backend
00050  * format
00051  */
00052 int _alpm_db_install(pmdb_t *db, const char *dbfile)
00053 {
00054     ALPM_LOG_FUNC;
00055 
00056     /* TODO we should not simply unpack the archive, but better parse it and
00057      * db_write each entry (see sync_load_dbarchive to get archive content) */
00058     _alpm_log(PM_LOG_DEBUG, "unpacking database '%s'\n", dbfile);
00059 
00060     if(_alpm_unpack(dbfile, db->path, NULL)) {
00061         RET_ERR(PM_ERR_SYSTEM, -1);
00062     }
00063 
00064     return unlink(dbfile);
00065 }
00066 
00067 int _alpm_db_open(pmdb_t *db)
00068 {
00069     ALPM_LOG_FUNC;
00070 
00071     if(db == NULL) {
00072         RET_ERR(PM_ERR_DB_NULL, -1);
00073     }
00074 
00075     _alpm_log(PM_LOG_DEBUG, "opening database from path '%s'\n", db->path);
00076     db->handle = opendir(db->path);
00077     if(db->handle == NULL) {
00078         RET_ERR(PM_ERR_DB_OPEN, -1);
00079     }
00080 
00081     return(0);
00082 }
00083 
00084 void _alpm_db_close(pmdb_t *db)
00085 {
00086     ALPM_LOG_FUNC;
00087 
00088     if(db == NULL) {
00089         return;
00090     }
00091 
00092     if(db->handle) {
00093         closedir(db->handle);
00094         db->handle = NULL;
00095     }
00096 }
00097 
00098 void _alpm_db_rewind(pmdb_t *db)
00099 {
00100     ALPM_LOG_FUNC;
00101 
00102     if(db == NULL || db->handle == NULL) {
00103         return;
00104     }
00105 
00106     rewinddir(db->handle);
00107 }
00108 
00109 static int splitname(const char *target, pmpkg_t *pkg)
00110 {
00111     /* the format of a db entry is as follows:
00112      *    package-version-rel/
00113      * package name can contain hyphens, so parse from the back- go back
00114      * two hyphens and we have split the version from the name.
00115      */
00116     char *tmp, *p, *q;
00117 
00118     if(target == NULL || pkg == NULL) {
00119         return(-1);
00120     }
00121     STRDUP(tmp, target, RET_ERR(PM_ERR_MEMORY, -1));
00122     p = tmp + strlen(tmp);
00123 
00124     /* do the magic parsing- find the beginning of the version string
00125      * by doing two iterations of same loop to lop off two hyphens */
00126     for(q = --p; *q && *q != '-'; q--);
00127     for(p = --q; *p && *p != '-'; p--);
00128     if(*p != '-' || p == tmp) {
00129         return(-1);
00130     }
00131 
00132     /* copy into fields and return */
00133     if(pkg->version) {
00134         FREE(pkg->version);
00135     }
00136     STRDUP(pkg->version, p+1, RET_ERR(PM_ERR_MEMORY, -1));
00137     /* insert a terminator at the end of the name (on hyphen)- then copy it */
00138     *p = '\0';
00139     if(pkg->name) {
00140         FREE(pkg->name);
00141     }
00142     STRDUP(pkg->name, tmp, RET_ERR(PM_ERR_MEMORY, -1));
00143 
00144     free(tmp);
00145     return(0);
00146 }
00147 
00148 pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target)
00149 {
00150     struct dirent *ent = NULL;
00151     struct stat sbuf;
00152     char path[PATH_MAX];
00153     char *ptr = NULL;
00154     int found = 0;
00155     pmpkg_t *pkg = NULL;
00156 
00157     ALPM_LOG_FUNC;
00158 
00159     if(db == NULL) {
00160         RET_ERR(PM_ERR_DB_NULL, NULL);
00161     }
00162 
00163     /* We loop here until we read a valid package.  When an iteration of this loop
00164      * fails, it means alpm_db_read failed to read a valid package, so we'll read
00165      * the next so as not to abort whole-db operations early
00166      */
00167     while(!pkg) {
00168         if(target != NULL) {
00169             /* search for a specific package (by name only) */
00170             rewinddir(db->handle);
00171             while(!found && (ent = readdir(db->handle)) != NULL) {
00172                 char *name;
00173 
00174                 if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
00175                     continue;
00176                 }
00177                 /* stat the entry, make sure it's a directory */
00178                 snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name);
00179                 if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) {
00180                     continue;
00181                 }
00182 
00183                 STRDUP(name, ent->d_name, return(NULL));
00184 
00185                 /* truncate the string at the second-to-last hyphen, */
00186                 /* which will give us the package name */
00187                 if((ptr = rindex(name, '-'))) {
00188                     *ptr = '\0';
00189                 }
00190                 if((ptr = rindex(name, '-'))) {
00191                     *ptr = '\0';
00192                 }
00193                 if(strcmp(name, target) == 0) {
00194                     found = 1;
00195                 }
00196                 FREE(name);
00197             }
00198 
00199             if(!found) {
00200                 return(NULL);
00201             }
00202         } else { /* target == NULL, full scan */
00203             int isdir = 0;
00204             while(!isdir) {
00205                 ent = readdir(db->handle);
00206                 if(ent == NULL) {
00207                     return(NULL);
00208                 }
00209                 if(strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
00210                     isdir = 0;
00211                     continue;
00212                 }
00213                 /* stat the entry, make sure it's a directory */
00214                 snprintf(path, PATH_MAX, "%s/%s", db->path, ent->d_name);
00215                 if(!stat(path, &sbuf) && S_ISDIR(sbuf.st_mode)) {
00216                     isdir = 1;
00217                 }
00218             }
00219         }
00220 
00221         pkg = _alpm_pkg_new(NULL, NULL);
00222         if(pkg == NULL) {
00223             _alpm_log(PM_LOG_DEBUG, "db scan could not find package: %s\n", target);
00224             return(NULL);
00225         }
00226         /* split the db entry name */
00227         if(splitname(ent->d_name, pkg) != 0) {
00228             _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"),
00229                     ent->d_name);
00230             alpm_pkg_free(pkg);
00231             pkg = NULL;
00232             continue;
00233         }
00234 
00235         /* explicitly read with only 'BASE' data, accessors will handle the rest */
00236         if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) {
00237             /* TODO removed corrupt entry from the FS here */
00238             _alpm_pkg_free(pkg);
00239         } else {
00240             pkg->origin = PKG_FROM_CACHE;
00241             pkg->origin_data.db = db;
00242         }
00243     }
00244 
00245     return(pkg);
00246 }
00247 
00248 int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
00249 {
00250     FILE *fp = NULL;
00251     struct stat buf;
00252     char path[PATH_MAX+1];
00253     char line[513];
00254 
00255     ALPM_LOG_FUNC;
00256 
00257     if(db == NULL) {
00258         RET_ERR(PM_ERR_DB_NULL, -1);
00259     }
00260 
00261     if(info == NULL || info->name == NULL || info->version == NULL) {
00262         _alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_db_read, skipping\n");
00263         return(-1);
00264     }
00265 
00266     if(info->origin == PKG_FROM_FILE) {
00267         _alpm_log(PM_LOG_DEBUG, "request to read database info for a file-based package '%s', skipping...\n", info->name);
00268         return(-1);
00269     }
00270 
00271     /* bitmask logic here:
00272      * infolevel: 00001111
00273      * inforeq:   00010100
00274      * & result:  00000100
00275      * == to inforeq? nope, we need to load more info. */
00276     if((info->infolevel & inforeq) == inforeq) {
00277         /* already loaded this info, do nothing */
00278         return(0);
00279     }
00280     _alpm_log(PM_LOG_FUNCTION, "loading package data for %s : level=0x%x\n",
00281             info->name, inforeq);
00282 
00283     /* clear out 'line', to be certain - and to make valgrind happy */
00284     memset(line, 0, 513);
00285 
00286     snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version);
00287     if(stat(path, &buf)) {
00288         /* directory doesn't exist or can't be opened */
00289         _alpm_log(PM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n",
00290                 info->name, info->version, db->treename);
00291         return(-1);
00292     }
00293 
00294     /* DESC */
00295     if(inforeq & INFRQ_DESC) {
00296         snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version);
00297         if((fp = fopen(path, "r")) == NULL) {
00298             _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
00299             goto error;
00300         }
00301         while(!feof(fp)) {
00302             if(fgets(line, 256, fp) == NULL) {
00303                 break;
00304             }
00305             _alpm_strtrim(line);
00306             if(strcmp(line, "%FILENAME%") == 0) {
00307                 if(fgets(line, 512, fp) == NULL) {
00308                     goto error;
00309                 }
00310                 STRDUP(info->filename, _alpm_strtrim(line), goto error);
00311           } else if(strcmp(line, "%DESC%") == 0) {
00312                 if(fgets(line, 512, fp) == NULL) {
00313                     goto error;
00314                 }
00315                 STRDUP(info->desc, _alpm_strtrim(line), goto error);
00316             } else if(strcmp(line, "%GROUPS%") == 0) {
00317                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00318                     char *linedup;
00319                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00320                     info->groups = alpm_list_add(info->groups, linedup);
00321                 }
00322             } else if(strcmp(line, "%URL%") == 0) {
00323                 if(fgets(line, 512, fp) == NULL) {
00324                     goto error;
00325                 }
00326                 STRDUP(info->url, _alpm_strtrim(line), goto error);
00327             } else if(strcmp(line, "%LICENSE%") == 0) {
00328                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00329                     char *linedup;
00330                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00331                     info->licenses = alpm_list_add(info->licenses, linedup);
00332                 }
00333             } else if(strcmp(line, "%ARCH%") == 0) {
00334                 if(fgets(line, 512, fp) == NULL) {
00335                     goto error;
00336                 }
00337                 STRDUP(info->arch, _alpm_strtrim(line), goto error);
00338             } else if(strcmp(line, "%BUILDDATE%") == 0) {
00339                 if(fgets(line, 512, fp) == NULL) {
00340                     goto error;
00341                 }
00342                 _alpm_strtrim(line);
00343 
00344                 char first = tolower(line[0]);
00345                 if(first > 'a' && first < 'z') {
00346                     struct tm tmp_tm = {0}; //initialize to null incase of failure
00347                     setlocale(LC_TIME, "C");
00348                     strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
00349                     info->builddate = mktime(&tmp_tm);
00350                     setlocale(LC_TIME, "");
00351                 } else {
00352                     info->builddate = atol(line);
00353                 }
00354             } else if(strcmp(line, "%INSTALLDATE%") == 0) {
00355                 if(fgets(line, 512, fp) == NULL) {
00356                     goto error;
00357                 }
00358                 _alpm_strtrim(line);
00359 
00360                 char first = tolower(line[0]);
00361                 if(first > 'a' && first < 'z') {
00362                     struct tm tmp_tm = {0}; //initialize to null incase of failure
00363                     setlocale(LC_TIME, "C");
00364                     strptime(line, "%a %b %e %H:%M:%S %Y", &tmp_tm);
00365                     info->installdate = mktime(&tmp_tm);
00366                     setlocale(LC_TIME, "");
00367                 } else {
00368                     info->installdate = atol(line);
00369                 }
00370             } else if(strcmp(line, "%PACKAGER%") == 0) {
00371                 if(fgets(line, 512, fp) == NULL) {
00372                     goto error;
00373                 }
00374                 STRDUP(info->packager, _alpm_strtrim(line), goto error);
00375             } else if(strcmp(line, "%REASON%") == 0) {
00376                 if(fgets(line, 512, fp) == NULL) {
00377                     goto error;
00378                 }
00379                 info->reason = atol(_alpm_strtrim(line));
00380             } else if(strcmp(line, "%SIZE%") == 0 || strcmp(line, "%CSIZE%") == 0) {
00381                 /* NOTE: the CSIZE and SIZE fields both share the "size" field
00382                  *       in the pkginfo_t struct.  This can be done b/c CSIZE
00383                  *       is currently only used in sync databases, and SIZE is
00384                  *       only used in local databases.
00385                  */
00386                 if(fgets(line, 512, fp) == NULL) {
00387                     goto error;
00388                 }
00389                 info->size = atol(_alpm_strtrim(line));
00390                 /* also store this value to isize if isize is unset */
00391                 if(info->isize == 0) {
00392                     info->isize = info->size;
00393                 }
00394             } else if(strcmp(line, "%ISIZE%") == 0) {
00395                 /* ISIZE (installed size) tag only appears in sync repositories,
00396                  * not the local one. */
00397                 if(fgets(line, 512, fp) == NULL) {
00398                     goto error;
00399                 }
00400                 info->isize = atol(_alpm_strtrim(line));
00401             } else if(strcmp(line, "%MD5SUM%") == 0) {
00402                 /* MD5SUM tag only appears in sync repositories,
00403                  * not the local one. */
00404                 if(fgets(line, 512, fp) == NULL) {
00405                     goto error;
00406                 }
00407                 STRDUP(info->md5sum, _alpm_strtrim(line), goto error);
00408             } else if(strcmp(line, "%REPLACES%") == 0) {
00409                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00410                     char *linedup;
00411                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00412                     info->replaces = alpm_list_add(info->replaces, linedup);
00413                 }
00414             } else if(strcmp(line, "%FORCE%") == 0) {
00415                 info->force = 1;
00416             }
00417         }
00418         fclose(fp);
00419         fp = NULL;
00420     }
00421 
00422     /* FILES */
00423     if(inforeq & INFRQ_FILES) {
00424         snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version);
00425         if((fp = fopen(path, "r")) == NULL) {
00426             _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
00427             goto error;
00428         }
00429         while(fgets(line, 256, fp)) {
00430             _alpm_strtrim(line);
00431             if(strcmp(line, "%FILES%") == 0) {
00432                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00433                     char *linedup;
00434                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00435                     info->files = alpm_list_add(info->files, linedup);
00436                 }
00437             } else if(strcmp(line, "%BACKUP%") == 0) {
00438                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00439                     char *linedup;
00440                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00441                     info->backup = alpm_list_add(info->backup, linedup);
00442                 }
00443             }
00444         }
00445         fclose(fp);
00446         fp = NULL;
00447     }
00448 
00449     /* DEPENDS */
00450     if(inforeq & INFRQ_DEPENDS) {
00451         snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version);
00452         if((fp = fopen(path, "r")) == NULL) {
00453             _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
00454             goto error;
00455         }
00456         while(!feof(fp)) {
00457             fgets(line, 255, fp);
00458             _alpm_strtrim(line);
00459             if(strcmp(line, "%DEPENDS%") == 0) {
00460                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00461                     pmdepend_t *dep = alpm_splitdep(_alpm_strtrim(line));
00462                     info->depends = alpm_list_add(info->depends, dep);
00463                 }
00464             } else if(strcmp(line, "%OPTDEPENDS%") == 0) {
00465                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00466                     char *linedup;
00467                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00468                     info->optdepends = alpm_list_add(info->optdepends, linedup);
00469                 }
00470             } else if(strcmp(line, "%CONFLICTS%") == 0) {
00471                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00472                     char *linedup;
00473                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00474                     info->conflicts = alpm_list_add(info->conflicts, linedup);
00475                 }
00476             } else if(strcmp(line, "%PROVIDES%") == 0) {
00477                 while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00478                     char *linedup;
00479                     STRDUP(linedup, _alpm_strtrim(line), goto error);
00480                     info->provides = alpm_list_add(info->provides, linedup);
00481                 }
00482             }
00483         }
00484         fclose(fp);
00485         fp = NULL;
00486     }
00487 
00488     /* DELTAS */
00489     if(inforeq & INFRQ_DELTAS) {
00490         snprintf(path, PATH_MAX, "%s/%s-%s/deltas", db->path, info->name, info->version);
00491         if((fp = fopen(path, "r"))) {
00492             while(!feof(fp)) {
00493                 fgets(line, 255, fp);
00494                 _alpm_strtrim(line);
00495                 if(strcmp(line, "%DELTAS%") == 0) {
00496                     while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) {
00497                         info->deltas = alpm_list_add(info->deltas, _alpm_delta_parse(line));
00498                     }
00499                 }
00500             }
00501             fclose(fp);
00502             fp = NULL;
00503         }
00504     }
00505 
00506     /* INSTALL */
00507     if(inforeq & INFRQ_SCRIPTLET) {
00508         snprintf(path, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version);
00509         if(!stat(path, &buf)) {
00510             info->scriptlet = 1;
00511         }
00512     }
00513 
00514     /* internal */
00515     info->infolevel |= inforeq;
00516 
00517     return(0);
00518 
00519 error:
00520     if(fp) {
00521         fclose(fp);
00522     }
00523     return(-1);
00524 }
00525 
00526 int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq)
00527 {
00528     FILE *fp = NULL;
00529     char path[PATH_MAX];
00530     mode_t oldmask;
00531     alpm_list_t *lp = NULL;
00532     int retval = 0;
00533     int local = 0;
00534 
00535     ALPM_LOG_FUNC;
00536 
00537     if(db == NULL || info == NULL) {
00538         return(-1);
00539     }
00540 
00541     snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version);
00542     oldmask = umask(0000);
00543     mkdir(path, 0755);
00544     /* make sure we have a sane umask */
00545     umask(0022);
00546 
00547     if(strcmp(db->treename, "local") == 0) {
00548         local = 1;
00549     }
00550 
00551     /* DESC */
00552     if(inforeq & INFRQ_DESC) {
00553         _alpm_log(PM_LOG_DEBUG, "writing %s-%s DESC information back to db\n",
00554                 info->name, info->version);
00555         snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version);
00556         if((fp = fopen(path, "w")) == NULL) {
00557             _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
00558             retval = -1;
00559             goto cleanup;
00560         }
00561         fprintf(fp, "%%NAME%%\n%s\n\n"
00562                         "%%VERSION%%\n%s\n\n", info->name, info->version);
00563         if(info->desc) {
00564             fprintf(fp, "%%DESC%%\n"
00565                             "%s\n\n", info->desc);
00566         }
00567         if(info->groups) {
00568             fputs("%GROUPS%\n", fp);
00569             for(lp = info->groups; lp; lp = lp->next) {
00570                 fprintf(fp, "%s\n", (char *)lp->data);
00571             }
00572             fprintf(fp, "\n");
00573         }
00574         if(local) {
00575             if(info->url) {
00576                 fprintf(fp, "%%URL%%\n"
00577                                 "%s\n\n", info->url);
00578             }
00579             if(info->licenses) {
00580                 fputs("%LICENSE%\n", fp);
00581                 for(lp = info->licenses; lp; lp = lp->next) {
00582                     fprintf(fp, "%s\n", (char *)lp->data);
00583                 }
00584                 fprintf(fp, "\n");
00585             }
00586             if(info->arch) {
00587                 fprintf(fp, "%%ARCH%%\n"
00588                                 "%s\n\n", info->arch);
00589             }
00590             if(info->builddate) {
00591                 fprintf(fp, "%%BUILDDATE%%\n"
00592                                 "%ju\n\n", (uintmax_t)info->builddate);
00593             }
00594             if(info->installdate) {
00595                 fprintf(fp, "%%INSTALLDATE%%\n"
00596                                 "%ju\n\n", (uintmax_t)info->installdate);
00597             }
00598             if(info->packager) {
00599                 fprintf(fp, "%%PACKAGER%%\n"
00600                                 "%s\n\n", info->packager);
00601             }
00602             if(info->size) {
00603                 /* only write installed size, csize is irrelevant once installed */
00604                 fprintf(fp, "%%SIZE%%\n"
00605                                 "%lu\n\n", info->isize);
00606             }
00607             if(info->reason) {
00608                 fprintf(fp, "%%REASON%%\n"
00609                                 "%u\n\n", info->reason);
00610             }
00611         } else {
00612             if(info->size) {
00613                 fprintf(fp, "%%CSIZE%%\n"
00614                                 "%lu\n\n", info->size);
00615             }
00616             if(info->isize) {
00617                 fprintf(fp, "%%ISIZE%%\n"
00618                                 "%lu\n\n", info->isize);
00619             }
00620             if(info->md5sum) {
00621                 fprintf(fp, "%%MD5SUM%%\n"
00622                                 "%s\n\n", info->md5sum);
00623             }
00624         }
00625         fclose(fp);
00626         fp = NULL;
00627     }
00628 
00629     /* FILES */
00630     if(local && (inforeq & INFRQ_FILES)) {
00631         _alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n",
00632                 info->name, info->version);
00633         snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version);
00634         if((fp = fopen(path, "w")) == NULL) {
00635             _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
00636             retval = -1;
00637             goto cleanup;
00638         }
00639         if(info->files) {
00640             fprintf(fp, "%%FILES%%\n");
00641             for(lp = info->files; lp; lp = lp->next) {
00642                 fprintf(fp, "%s\n", (char *)lp->data);
00643             }
00644             fprintf(fp, "\n");
00645         }
00646         if(info->backup) {
00647             fprintf(fp, "%%BACKUP%%\n");
00648             for(lp = info->backup; lp; lp = lp->next) {
00649                 fprintf(fp, "%s\n", (char *)lp->data);
00650             }
00651             fprintf(fp, "\n");
00652         }
00653         fclose(fp);
00654         fp = NULL;
00655     }
00656 
00657     /* DEPENDS */
00658     if(inforeq & INFRQ_DEPENDS) {
00659         _alpm_log(PM_LOG_DEBUG, "writing %s-%s DEPENDS information back to db\n",
00660             info->name, info->version);
00661         snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version);
00662         if((fp = fopen(path, "w")) == NULL) {
00663             _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno));
00664             retval = -1;
00665             goto cleanup;
00666         }
00667         if(info->depends) {
00668             fputs("%DEPENDS%\n", fp);
00669             for(lp = info->depends; lp; lp = lp->next) {
00670                 char *depstring = alpm_dep_get_string(lp->data);
00671                 fprintf(fp, "%s\n", depstring);
00672                 free(depstring);
00673             }
00674             fprintf(fp, "\n");
00675         }
00676         if(info->optdepends) {
00677             fputs("%OPTDEPENDS%\n", fp);
00678             for(lp = info->optdepends; lp; lp = lp->next) {
00679                 fprintf(fp, "%s\n", (char *)lp->data);
00680             }
00681             fprintf(fp, "\n");
00682         }
00683         if(info->conflicts) {
00684             fputs("%CONFLICTS%\n", fp);
00685             for(lp = info->conflicts; lp; lp = lp->next) {
00686                 fprintf(fp, "%s\n", (char *)lp->data);
00687             }
00688             fprintf(fp, "\n");
00689         }
00690         if(info->provides) {
00691             fputs("%PROVIDES%\n", fp);
00692             for(lp = info->provides; lp; lp = lp->next) {
00693                 fprintf(fp, "%s\n", (char *)lp->data);
00694             }
00695             fprintf(fp, "\n");
00696         }
00697         if(info->replaces) {
00698             fputs("%REPLACES%\n", fp);
00699             for(lp = info->replaces; lp; lp = lp->next) {
00700                 fprintf(fp, "%s\n", (char *)lp->data);
00701             }
00702             fprintf(fp, "\n");
00703         }
00704         if(info->force) {
00705             /* note the extra newline character, which is necessary! */
00706             fprintf(fp, "%%FORCE%%\n\n");
00707         }
00708         fclose(fp);
00709         fp = NULL;
00710     }
00711 
00712     /* INSTALL */
00713     /* nothing needed here (script is automatically extracted) */
00714 
00715 cleanup:
00716     umask(oldmask);
00717 
00718     if(fp) {
00719         fclose(fp);
00720     }
00721 
00722     return(retval);
00723 }
00724 
00725 int _alpm_db_remove(pmdb_t *db, pmpkg_t *info)
00726 {
00727     char path[PATH_MAX];
00728 
00729     ALPM_LOG_FUNC;
00730 
00731     if(db == NULL || info == NULL) {
00732         RET_ERR(PM_ERR_DB_NULL, -1);
00733     }
00734 
00735     snprintf(path, PATH_MAX, "%s%s-%s", db->path, info->name, info->version);
00736     if(_alpm_rmrf(path) == -1) {
00737         return(-1);
00738     }
00739 
00740     return(0);
00741 }
00742 
00743 /*
00744  * Return the last update time as number of seconds from the epoch.
00745  * Returns 0 if the value is unknown or can't be read.
00746  */
00747 time_t _alpm_db_getlastupdate(const pmdb_t *db)
00748 {
00749     FILE *fp;
00750     char file[PATH_MAX];
00751     time_t ret = 0;
00752 
00753     ALPM_LOG_FUNC;
00754 
00755     if(db == NULL) {
00756         return(ret);
00757     }
00758 
00759     snprintf(file, PATH_MAX, "%s.lastupdate", db->path);
00760 
00761     /* get the last update time, if it's there */
00762     if((fp = fopen(file, "r")) == NULL) {
00763         return(ret);
00764     } else {
00765         char line[64];
00766         if(fgets(line, sizeof(line), fp)) {
00767             ret = atol(line);
00768         }
00769     }
00770     fclose(fp);
00771     return(ret);
00772 }
00773 
00774 /*
00775  * writes the dbpath/.lastupdate file with the value in time
00776  */
00777 int _alpm_db_setlastupdate(const pmdb_t *db, time_t time)
00778 {
00779     FILE *fp;
00780     char file[PATH_MAX];
00781     int ret = 0;
00782 
00783     ALPM_LOG_FUNC;
00784 
00785     if(db == NULL || time == 0) {
00786         return(-1);
00787     }
00788 
00789     snprintf(file, PATH_MAX, "%s.lastupdate", db->path);
00790 
00791     if((fp = fopen(file, "w")) == NULL) {
00792         return(-1);
00793     }
00794     if(fprintf(fp, "%ju", (uintmax_t)time) <= 0) {
00795         ret = -1;
00796     }
00797     fclose(fp);
00798 
00799     return(ret);
00800 }
00801 
00802 /* vim: set ts=2 sw=2 noet: */

Generated on Mon Jan 14 23:53:39 2008 for libalpm by  doxygen 1.5.4