diff options
Diffstat (limited to 'lib/libalpm/be_files.c')
-rw-r--r-- | lib/libalpm/be_files.c | 291 |
1 files changed, 163 insertions, 128 deletions
diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c index f3619277..078136ed 100644 --- a/lib/libalpm/be_files.c +++ b/lib/libalpm/be_files.c @@ -1,9 +1,9 @@ /* * be_files.c - * + * * Copyright (c) 2006 by Christian Hamar <krics@linuxforum.hu> * Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, * USA. */ @@ -27,16 +27,13 @@ #include <stdlib.h> #include <errno.h> #include <string.h> -#ifdef __sun__ -#include <strings.h> -#endif +#include <stdint.h> /* uintmax_t */ #include <sys/stat.h> #include <dirent.h> -#include <libintl.h> -#include <locale.h> -#ifdef CYGWIN +#include <ctype.h> +#include <time.h> #include <limits.h> /* PATH_MAX */ -#endif +#include <locale.h> /* setlocale */ /* libalpm */ #include "db.h" @@ -47,6 +44,8 @@ #include "error.h" #include "handle.h" #include "package.h" +#include "delta.h" +#include "deps.h" /* This function is used to convert the downloaded db file to the proper backend @@ -56,9 +55,9 @@ int _alpm_db_install(pmdb_t *db, const char *dbfile) { ALPM_LOG_FUNC; - /* TODO we should not simply unpack the archive, but better parse it and + /* TODO we should not simply unpack the archive, but better parse it and * db_write each entry (see sync_load_dbarchive to get archive content) */ - _alpm_log(PM_LOG_DEBUG, _("unpacking database '%s'"), dbfile); + _alpm_log(PM_LOG_DEBUG, "unpacking database '%s'\n", dbfile); if(_alpm_unpack(dbfile, db->path, NULL)) { RET_ERR(PM_ERR_SYSTEM, -1); @@ -75,7 +74,7 @@ int _alpm_db_open(pmdb_t *db) RET_ERR(PM_ERR_DB_NULL, -1); } - _alpm_log(PM_LOG_DEBUG, _("opening database from path '%s'"), db->path); + _alpm_log(PM_LOG_DEBUG, "opening database from path '%s'\n", db->path); db->handle = opendir(db->path); if(db->handle == NULL) { RET_ERR(PM_ERR_DB_OPEN, -1); @@ -109,6 +108,43 @@ void _alpm_db_rewind(pmdb_t *db) rewinddir(db->handle); } +static int _alpm_db_splitname(const char *target, char *name, char *version) +{ + /* the format of a db entry is as follows: + * package-version-rel/ + * package name can contain hyphens, so parse from the back- go back + * two hyphens and we have split the version from the name. + */ + char *tmp, *p, *q; + + if(target == NULL) { + return(-1); + } + tmp = strdup(target); + p = tmp + strlen(tmp); + + /* do the magic parsing- find the beginning of the version string + * by doing two iterations of same loop to lop off two hyphens */ + for(q = --p; *q && *q != '-'; q--); + for(p = --q; *p && *p != '-'; p--); + if(*p != '-' || p == tmp) { + return(-1); + } + + /* copy into fields and return */ + if(version) { + strncpy(version, p+1, PKG_VERSION_LEN); + } + /* insert a terminator at the end of the name (on hyphen)- then copy it */ + *p = '\0'; + if(name) { + strncpy(name, tmp, PKG_NAME_LEN); + } + + free(tmp); + return(0); +} + pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target) { struct dirent *ent = NULL; @@ -142,7 +178,7 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target) if(stat(path, &sbuf) || !S_ISDIR(sbuf.st_mode)) { continue; } - STRNCPY(name, ent->d_name, PKG_FULLNAME_LEN); + strncpy(name, ent->d_name, PKG_FULLNAME_LEN); /* truncate the string at the second-to-last hyphen, */ /* which will give us the package name */ if((ptr = rindex(name, '-'))) { @@ -179,21 +215,25 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, const char *target) pkg = _alpm_pkg_new(NULL, NULL); if(pkg == NULL) { - _alpm_log(PM_LOG_DEBUG, _("db scan could not find package: %s"), target); + _alpm_log(PM_LOG_DEBUG, "db scan could not find package: %s\n", target); return(NULL); } - if(_alpm_pkg_splitname(ent->d_name, pkg->name, pkg->version, 0) == -1) { - _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'"), ent->d_name); - return(NULL); + /* split the db entry name */ + if(_alpm_db_splitname(ent->d_name, pkg->name, pkg->version) != 0) { + _alpm_log(PM_LOG_ERROR, _("invalid name for database entry '%s'\n"), + ent->d_name); + alpm_pkg_free(pkg); + pkg = NULL; + continue; } /* explicitly read with only 'BASE' data, accessors will handle the rest */ if(_alpm_db_read(db, pkg, INFRQ_BASE) == -1) { /* TODO removed corrupt entry from the FS here */ - FREEPKG(pkg); + _alpm_pkg_free(pkg); } else { - pkg->data = db; pkg->origin = PKG_FROM_CACHE; + pkg->origin_data.db = db; } } @@ -206,10 +246,6 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) struct stat buf; char path[PATH_MAX+1]; char line[513]; - /* - alpm_list_t *tmplist; - char *locale; - */ ALPM_LOG_FUNC; @@ -218,12 +254,12 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) } if(info == NULL || info->name[0] == 0 || info->version[0] == 0) { - _alpm_log(PM_LOG_DEBUG, _("invalid package entry provided to _alpm_db_read, skipping")); + _alpm_log(PM_LOG_DEBUG, "invalid package entry provided to _alpm_db_read, skipping\n"); return(-1); } if(info->origin == PKG_FROM_FILE) { - _alpm_log(PM_LOG_DEBUG, _("request to read database info for a file-based package '%s', skipping..."), info->name); + _alpm_log(PM_LOG_DEBUG, "request to read database info for a file-based package '%s', skipping...\n", info->name); return(-1); } @@ -236,7 +272,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) /* already loaded this info, do nothing */ return(0); } - _alpm_log(PM_LOG_FUNCTION, _("loading package data for %s : level=%d"), info->name, inforeq); + _alpm_log(PM_LOG_FUNCTION, _("loading package data for %s : level=%d\n"), info->name, inforeq); /* clear out 'line', to be certain - and to make valgrind happy */ memset(line, 0, 513); @@ -244,7 +280,8 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) snprintf(path, PATH_MAX, "%s/%s-%s", db->path, info->name, info->version); if(stat(path, &buf)) { /* directory doesn't exist or can't be opened */ - _alpm_log(PM_LOG_DEBUG, _("cannot find '%s-%s' in db '%s'"), info->name, info->version, db->treename); + _alpm_log(PM_LOG_DEBUG, "cannot find '%s-%s' in db '%s'\n", + info->name, info->version, db->treename); return(-1); } @@ -252,7 +289,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) if(inforeq & INFRQ_DESC) { snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version); if((fp = fopen(path, "r")) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s"), path, strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); goto error; } while(!feof(fp)) { @@ -273,32 +310,6 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) if(fgets(info->desc, sizeof(info->desc), fp) == NULL) { goto error; } - /* - while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { - info->desc_localized = alpm_list_add(info->desc_localized, strdup(line)); - PKG_ - } - - if((locale = setlocale(LC_ALL, "")) == NULL) { //To fix segfault when locale invalid - setenv("LC_ALL", "C", 1); - locale = setlocale(LC_ALL, ""); - } - - if(info->desc_localized && !info->desc_localized->next) { - snprintf(info->desc, 512, "%s", (char*)info->desc_localized->data); - } else { - for (tmplist = info->desc_localized; tmplist; tmplist = tmplist->next) { - if (tmplist->data && strncmp(tmplist->data, locale, strlen(locale))) { - strncpy(info->desc, (char *)info->desc_localized->data, sizeof(info->desc)); - } else { - char *p = (char *)tmplist->data; - p += strlen(locale) + 1; - strncpy(info->desc, p, sizeof(info->desc)); - break; - } - } - } - */ _alpm_strtrim(info->desc); } else if(!strcmp(line, "%GROUPS%")) { while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { @@ -319,20 +330,39 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) } _alpm_strtrim(info->arch); } else if(!strcmp(line, "%BUILDDATE%")) { - if(fgets(info->builddate, sizeof(info->builddate), fp) == NULL) { + char tmp[32]; + if(fgets(tmp, sizeof(tmp), fp) == NULL) { goto error; } - _alpm_strtrim(info->builddate); - } else if(!strcmp(line, "%BUILDTYPE%")) { - if(fgets(info->buildtype, sizeof(info->buildtype), fp) == NULL) { - goto error; + _alpm_strtrim(tmp); + + char first = tolower(tmp[0]); + if(first > 'a' && first < 'z') { + struct tm tmp_tm = {0}; //initialize to null incase of failure + setlocale(LC_TIME, "C"); + strptime(tmp, "%a %b %e %H:%M:%S %Y", &tmp_tm); + info->builddate = mktime(&tmp_tm); + setlocale(LC_TIME, ""); + } else { + info->builddate = atol(tmp); } - _alpm_strtrim(info->buildtype); } else if(!strcmp(line, "%INSTALLDATE%")) { - if(fgets(info->installdate, sizeof(info->installdate), fp) == NULL) { + char tmp[32]; + if(fgets(tmp, sizeof(tmp), fp) == NULL) { goto error; } - _alpm_strtrim(info->installdate); + _alpm_strtrim(tmp); + + char first = tolower(tmp[0]); + if(first > 'a' && first < 'z') { + struct tm tmp_tm = {0}; //initialize to null incase of failure + setlocale(LC_TIME, "C"); + strptime(tmp, "%a %b %e %H:%M:%S %Y", &tmp_tm); + info->installdate = mktime(&tmp_tm); + setlocale(LC_TIME, ""); + } else { + info->installdate = atol(tmp); + } } else if(!strcmp(line, "%PACKAGER%")) { if(fgets(info->packager, sizeof(info->packager), fp) == NULL) { goto error; @@ -357,6 +387,10 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) } _alpm_strtrim(tmp); info->size = atol(tmp); + /* also store this value to isize if isize is unset */ + if(info->isize == 0) { + info->isize = atol(tmp); + } } else if(!strcmp(line, "%ISIZE%")) { /* ISIZE (installed size) tag only appears in sync repositories, * not the local one. */ @@ -366,12 +400,6 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) } _alpm_strtrim(tmp); info->isize = atol(tmp); - } else if(!strcmp(line, "%SHA1SUM%")) { - /* SHA1SUM tag only appears in sync repositories, - * not the local one. */ - if(fgets(info->sha1sum, sizeof(info->sha1sum), fp) == NULL) { - goto error; - } } else if(!strcmp(line, "%MD5SUM%")) { /* MD5SUM tag only appears in sync repositories, * not the local one. */ @@ -398,7 +426,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) if(inforeq & INFRQ_FILES) { snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version); if((fp = fopen(path, "r")) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s"), path, strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); goto error; } while(fgets(line, 256, fp)) { @@ -421,7 +449,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) if(inforeq & INFRQ_DEPENDS) { snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version); if((fp = fopen(path, "r")) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s"), path, strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); goto error; } while(!feof(fp)) { @@ -429,11 +457,12 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) _alpm_strtrim(line); if(!strcmp(line, "%DEPENDS%")) { while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { - info->depends = alpm_list_add(info->depends, strdup(line)); + pmdepend_t *dep = alpm_splitdep(line); + info->depends = alpm_list_add(info->depends, dep); } - } else if(!strcmp(line, "%REQUIREDBY%")) { + } else if(!strcmp(line, "%OPTDEPENDS%")) { while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { - info->requiredby = alpm_list_add(info->requiredby, strdup(line)); + info->optdepends = alpm_list_add(info->optdepends, strdup(line)); } } else if(!strcmp(line, "%CONFLICTS%")) { while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { @@ -451,7 +480,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) * not the local one. * while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { info->replaces = alpm_list_add(info->replaces, strdup(line)); - } + } } else if(!strcmp(line, "%FORCE%")) { * FORCE tag only appears in sync repositories, * not the local one. * @@ -462,6 +491,24 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) fp = NULL; } + /* DELTAS */ + if(inforeq & INFRQ_DELTAS) { + snprintf(path, PATH_MAX, "%s/%s-%s/deltas", db->path, info->name, info->version); + if((fp = fopen(path, "r"))) { + while(!feof(fp)) { + fgets(line, 255, fp); + _alpm_strtrim(line); + if(!strcmp(line, "%DELTAS%")) { + while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { + info->deltas = alpm_list_add(info->deltas, _alpm_delta_parse(line)); + } + } + } + fclose(fp); + fp = NULL; + } + } + /* INSTALL */ if(inforeq & INFRQ_SCRIPTLET) { snprintf(path, PATH_MAX, "%s/%s-%s/install", db->path, info->name, info->version); @@ -509,22 +556,17 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) /* DESC */ if(inforeq & INFRQ_DESC) { - _alpm_log(PM_LOG_DEBUG, _("writing %s-%s DESC information back to db"), info->name, info->version); + _alpm_log(PM_LOG_DEBUG, "writing %s-%s DESC information back to db\n", + info->name, info->version); snprintf(path, PATH_MAX, "%s/%s-%s/desc", db->path, info->name, info->version); if((fp = fopen(path, "w")) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s"), path, strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); retval = -1; goto cleanup; } fprintf(fp, "%%NAME%%\n%s\n\n" "%%VERSION%%\n%s\n\n", info->name, info->version); if(info->desc[0]) { - /*fputs("%DESC%\n", fp); - for(lp = info->desc_localized; lp; lp = lp->next) { - fprintf(fp, "%s\n", (char *)lp->data); - } - fprintf(fp, "\n"); - */ fprintf(fp, "%%DESC%%\n" "%s\n\n", info->desc); } @@ -551,17 +593,13 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) fprintf(fp, "%%ARCH%%\n" "%s\n\n", info->arch); } - if(info->builddate[0]) { + if(info->builddate) { fprintf(fp, "%%BUILDDATE%%\n" - "%s\n\n", info->builddate); - } - if(info->buildtype[0]) { - fprintf(fp, "%%BUILDTYPE%%\n" - "%s\n\n", info->buildtype); + "%ju\n\n", (uintmax_t)info->builddate); } - if(info->installdate[0]) { + if(info->installdate) { fprintf(fp, "%%INSTALLDATE%%\n" - "%s\n\n", info->installdate); + "%ju\n\n", (uintmax_t)info->installdate); } if(info->packager[0]) { fprintf(fp, "%%PACKAGER%%\n" @@ -585,10 +623,7 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) fprintf(fp, "%%ISIZE%%\n" "%lu\n\n", info->isize); } - if(info->sha1sum) { - fprintf(fp, "%%SHA1SUM%%\n" - "%s\n\n", info->sha1sum); - } else if(info->md5sum) { + if(info->md5sum) { fprintf(fp, "%%MD5SUM%%\n" "%s\n\n", info->md5sum); } @@ -599,10 +634,11 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) /* FILES */ if(local && (inforeq & INFRQ_FILES)) { - _alpm_log(PM_LOG_DEBUG, _("writing %s-%s FILES information back to db"), info->name, info->version); + _alpm_log(PM_LOG_DEBUG, "writing %s-%s FILES information back to db\n", + info->name, info->version); snprintf(path, PATH_MAX, "%s/%s-%s/files", db->path, info->name, info->version); if((fp = fopen(path, "w")) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s"), path, strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); retval = -1; goto cleanup; } @@ -626,23 +662,26 @@ int _alpm_db_write(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) /* DEPENDS */ if(inforeq & INFRQ_DEPENDS) { - _alpm_log(PM_LOG_DEBUG, _("writing %s-%s DEPENDS information back to db"), info->name, info->version); + _alpm_log(PM_LOG_DEBUG, "writing %s-%s DEPENDS information back to db\n", + info->name, info->version); snprintf(path, PATH_MAX, "%s/%s-%s/depends", db->path, info->name, info->version); if((fp = fopen(path, "w")) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s"), path, strerror(errno)); + _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); retval = -1; goto cleanup; } if(info->depends) { fputs("%DEPENDS%\n", fp); for(lp = info->depends; lp; lp = lp->next) { - fprintf(fp, "%s\n", (char *)lp->data); + char *depstring = alpm_dep_get_string(lp->data); + fprintf(fp, "%s\n", depstring); + free(depstring); } fprintf(fp, "\n"); } - if(local && info->requiredby) { - fputs("%REQUIREDBY%\n", fp); - for(lp = info->requiredby; lp; lp = lp->next) { + if(info->optdepends) { + fputs("%OPTDEPENDS%\n", fp); + for(lp = info->optdepends; lp; lp = lp->next) { fprintf(fp, "%s\n", (char *)lp->data); } fprintf(fp, "\n"); @@ -709,67 +748,63 @@ int _alpm_db_remove(pmdb_t *db, pmpkg_t *info) return(0); } -/* reads dbpath/.lastupdate and populates *ts with the contents. - * *ts should be malloc'ed and should be at least 15 bytes. - * - * Returns 0 on success, 1 on error - * +/* + * Return the last update time as number of seconds from the epoch. + * Returns 0 if the value is unknown or can't be read. */ -int _alpm_db_getlastupdate(pmdb_t *db, char *ts) +time_t _alpm_db_getlastupdate(const pmdb_t *db) { FILE *fp; char file[PATH_MAX]; + time_t ret = 0; ALPM_LOG_FUNC; - if(db == NULL || ts == NULL) { - return(-1); + if(db == NULL) { + return(ret); } - snprintf(file, PATH_MAX, "%s%s.lastupdate", handle->root, db->path); + snprintf(file, PATH_MAX, "%s.lastupdate", db->path); /* get the last update time, if it's there */ if((fp = fopen(file, "r")) == NULL) { - return(-1); + return(ret); } else { - char line[256]; + char line[64]; if(fgets(line, sizeof(line), fp)) { - STRNCPY(ts, line, 15); /* YYYYMMDDHHMMSS */ - ts[14] = '\0'; - } else { - fclose(fp); - return(-1); + ret = atol(line); } } fclose(fp); - return(0); + return(ret); } -/* writes the dbpath/.lastupdate with the contents of *ts +/* + * writes the dbpath/.lastupdate file with the value in time */ -int _alpm_db_setlastupdate(pmdb_t *db, char *ts) +int _alpm_db_setlastupdate(const pmdb_t *db, time_t time) { FILE *fp; char file[PATH_MAX]; + int ret = 0; ALPM_LOG_FUNC; - if(db == NULL || ts == NULL || strlen(ts) == 0) { + if(db == NULL || time == 0) { return(-1); } - snprintf(file, PATH_MAX, "%s%s.lastupdate", handle->root, db->path); + snprintf(file, PATH_MAX, "%s.lastupdate", db->path); if((fp = fopen(file, "w")) == NULL) { return(-1); } - if(fputs(ts, fp) <= 0) { - fclose(fp); - return(-1); + if(fprintf(fp, "%ju", (uintmax_t)time) <= 0) { + ret = -1; } fclose(fp); - return(0); + return(ret); } /* vim: set ts=2 sw=2 noet: */ |