diff options
Diffstat (limited to 'lib/libalpm')
-rw-r--r-- | lib/libalpm/Makefile.am | 6 | ||||
-rw-r--r-- | lib/libalpm/add.c | 16 | ||||
-rw-r--r-- | lib/libalpm/alpm.c | 13 | ||||
-rw-r--r-- | lib/libalpm/alpm.h | 1 | ||||
-rw-r--r-- | lib/libalpm/be_files.c | 79 | ||||
-rw-r--r-- | lib/libalpm/be_package.c | 36 | ||||
-rw-r--r-- | lib/libalpm/conflict.c | 6 | ||||
-rw-r--r-- | lib/libalpm/deps.c | 2 | ||||
-rw-r--r-- | lib/libalpm/dload.c | 8 | ||||
-rw-r--r-- | lib/libalpm/error.c | 4 | ||||
-rw-r--r-- | lib/libalpm/md5.c | 13 | ||||
-rw-r--r-- | lib/libalpm/package.c | 2 | ||||
-rw-r--r-- | lib/libalpm/package.h | 6 | ||||
-rw-r--r-- | lib/libalpm/trans.c | 15 | ||||
-rw-r--r-- | lib/libalpm/util.c | 162 | ||||
-rw-r--r-- | lib/libalpm/util.h | 2 |
16 files changed, 242 insertions, 129 deletions
diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 3473a73a..e136b548 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -38,7 +38,6 @@ libalpm_la_SOURCES = \ group.h group.c \ handle.h handle.c \ log.h log.c \ - md5.h md5.c \ package.h package.c \ remove.h remove.c \ sync.h sync.c \ @@ -46,6 +45,11 @@ libalpm_la_SOURCES = \ util.h util.c \ version.c +if !HAVE_LIBSSL +libalpm_la_SOURCES += \ + md5.h md5.c +endif + libalpm_la_LDFLAGS = -no-undefined -version-info $(LIB_VERSION_INFO) libalpm_la_LIBADD = $(LTLIBINTL) diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index f39a0ecf..cc0c4c13 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -556,6 +556,7 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, struct archive *archive; struct archive_entry *entry; char cwd[PATH_MAX] = ""; + int restore_cwd = 0; _alpm_log(PM_LOG_DEBUG, "extracting files\n"); @@ -579,11 +580,16 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, /* save the cwd so we can restore it later */ if(getcwd(cwd, PATH_MAX) == NULL) { _alpm_log(PM_LOG_ERROR, _("could not get current working directory\n")); - cwd[0] = 0; + } else { + restore_cwd = 1; } /* libarchive requires this for extracting hard links */ - chdir(handle->root); + if(chdir(handle->root) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), handle->root, strerror(errno)); + ret = -1; + goto cleanup; + } /* call PROGRESS once with 0 percent, as we sort-of skip that here */ if(is_upgrade) { @@ -629,9 +635,9 @@ static int commit_single_pkg(pmpkg_t *newpkg, int pkg_current, int pkg_count, } archive_read_finish(archive); - /* restore the old cwd is we have it */ - if(strlen(cwd)) { - chdir(cwd); + /* restore the old cwd if we have it */ + if(restore_cwd && chdir(cwd) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); } if(errors) { diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 51b9e25b..6f4f4a4c 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -23,6 +23,11 @@ #include "config.h" +/* connection caching setup */ +#ifdef HAVE_FETCH +#include <fetch.h> +#endif + /* libalpm */ #include "alpm.h" #include "alpm_list.h" @@ -54,6 +59,10 @@ int SYMEXPORT alpm_initialize(void) bindtextdomain("libalpm", LOCALEDIR); #endif +#ifdef HAVE_FETCH + fetchConnectionCacheInit(5, 1); +#endif + return(0); } @@ -73,6 +82,10 @@ int SYMEXPORT alpm_release(void) _alpm_handle_free(handle); handle = NULL; +#ifdef HAVE_FETCH + fetchConnectionCacheClose(); +#endif + return(0); } diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 33291325..0c01f214 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -522,6 +522,7 @@ enum _pmerrno_t { PM_ERR_FILE_CONFLICTS, /* Misc */ PM_ERR_RETRIEVE, + PM_ERR_WRITE, PM_ERR_INVALID_REGEX, /* External library errors */ PM_ERR_LIBARCHIVE, diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c index 877bc505..44321713 100644 --- a/lib/libalpm/be_files.c +++ b/lib/libalpm/be_files.c @@ -208,7 +208,7 @@ static int remove_olddir(const char *syncdbpath, alpm_list_t *dirlist) */ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) { - char *dbfile, *dbfilepath; + char *dbfile, *dbfilepath, *syncpath; const char *dbpath, *syncdbpath; alpm_list_t *newdirlist = NULL, *olddirlist = NULL; alpm_list_t *onlynew = NULL, *onlyold = NULL; @@ -231,14 +231,18 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) RET_ERR(PM_ERR_DB_NOT_FOUND, -1); } - len = strlen(db->treename) + strlen(DBEXT) + 1; + len = strlen(db->treename) + 4; MALLOC(dbfile, len, RET_ERR(PM_ERR_MEMORY, -1)); - sprintf(dbfile, "%s" DBEXT, db->treename); + sprintf(dbfile, "%s.db", db->treename); dbpath = alpm_option_get_dbpath(); + len = strlen(dbpath) + 6; + MALLOC(syncpath, len, RET_ERR(PM_ERR_MEMORY, -1)); + sprintf(syncpath, "%s%s", dbpath, "sync/"); - ret = _alpm_download_single_file(dbfile, db->servers, dbpath, force); + ret = _alpm_download_single_file(dbfile, db->servers, syncpath, force); free(dbfile); + free(syncpath); if(ret == 1) { /* files match, do nothing */ @@ -253,9 +257,9 @@ int SYMEXPORT alpm_db_update(int force, pmdb_t *db) syncdbpath = _alpm_db_path(db); /* form the path to the db location */ - len = strlen(dbpath) + strlen(db->treename) + strlen(DBEXT) + 1; + len = strlen(dbpath) + strlen(db->treename) + 9; MALLOC(dbfilepath, len, RET_ERR(PM_ERR_MEMORY, -1)); - sprintf(dbfilepath, "%s%s" DBEXT, dbpath, db->treename); + sprintf(dbfilepath, "%ssync/%s.db", dbpath, db->treename); if(force) { /* if forcing update, remove the old dir and extract the db */ @@ -434,8 +438,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) { FILE *fp = NULL; char path[PATH_MAX]; - char line[513]; - int sline = sizeof(line)-1; + char line[1024]; char *pkgpath = NULL; ALPM_LOG_FUNC; @@ -467,7 +470,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) info->name, inforeq); /* clear out 'line', to be certain - and to make valgrind happy */ - memset(line, 0, sline+1); + memset(line, 0, sizeof(line)); pkgpath = get_pkgpath(db, info); @@ -486,12 +489,12 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) goto error; } while(!feof(fp)) { - if(fgets(line, 256, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { break; } _alpm_strtrim(line); if(strcmp(line, "%NAME%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } if(strcmp(_alpm_strtrim(line), info->name) != 0) { @@ -499,7 +502,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) "mismatch on package %s\n"), db->treename, info->name); } } else if(strcmp(line, "%VERSION%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } if(strcmp(_alpm_strtrim(line), info->version) != 0) { @@ -507,39 +510,39 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) "mismatch on package %s\n"), db->treename, info->name); } } else if(strcmp(line, "%FILENAME%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } STRDUP(info->filename, _alpm_strtrim(line), goto error); } else if(strcmp(line, "%DESC%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } STRDUP(info->desc, _alpm_strtrim(line), goto error); } else if(strcmp(line, "%GROUPS%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->groups = alpm_list_add(info->groups, linedup); } } else if(strcmp(line, "%URL%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } STRDUP(info->url, _alpm_strtrim(line), goto error); } else if(strcmp(line, "%LICENSE%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->licenses = alpm_list_add(info->licenses, linedup); } } else if(strcmp(line, "%ARCH%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } STRDUP(info->arch, _alpm_strtrim(line), goto error); } else if(strcmp(line, "%BUILDDATE%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } _alpm_strtrim(line); @@ -555,7 +558,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) info->builddate = atol(line); } } else if(strcmp(line, "%INSTALLDATE%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } _alpm_strtrim(line); @@ -571,12 +574,12 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) info->installdate = atol(line); } } else if(strcmp(line, "%PACKAGER%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } STRDUP(info->packager, _alpm_strtrim(line), goto error); } else if(strcmp(line, "%REASON%") == 0) { - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } info->reason = (pmpkgreason_t)atol(_alpm_strtrim(line)); @@ -586,7 +589,7 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) * is currently only used in sync databases, and SIZE is * only used in local databases. */ - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } info->size = atol(_alpm_strtrim(line)); @@ -597,19 +600,19 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) } else if(strcmp(line, "%ISIZE%") == 0) { /* ISIZE (installed size) tag only appears in sync repositories, * not the local one. */ - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } info->isize = atol(_alpm_strtrim(line)); } else if(strcmp(line, "%MD5SUM%") == 0) { /* MD5SUM tag only appears in sync repositories, * not the local one. */ - if(fgets(line, sline, fp) == NULL) { + if(fgets(line, sizeof(line), fp) == NULL) { goto error; } STRDUP(info->md5sum, _alpm_strtrim(line), goto error); } else if(strcmp(line, "%REPLACES%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->replaces = alpm_list_add(info->replaces, linedup); @@ -629,16 +632,16 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) _alpm_log(PM_LOG_ERROR, _("could not open file %s: %s\n"), path, strerror(errno)); goto error; } - while(fgets(line, 256, fp)) { + while(fgets(line, sizeof(line), fp)) { _alpm_strtrim(line); if(strcmp(line, "%FILES%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->files = alpm_list_add(info->files, linedup); } } else if(strcmp(line, "%BACKUP%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->backup = alpm_list_add(info->backup, linedup); @@ -657,27 +660,29 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) goto error; } while(!feof(fp)) { - fgets(line, 255, fp); + if(fgets(line, sizeof(line), fp) == NULL) { + break; + } _alpm_strtrim(line); if(strcmp(line, "%DEPENDS%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { pmdepend_t *dep = _alpm_splitdep(_alpm_strtrim(line)); info->depends = alpm_list_add(info->depends, dep); } } else if(strcmp(line, "%OPTDEPENDS%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->optdepends = alpm_list_add(info->optdepends, linedup); } } else if(strcmp(line, "%CONFLICTS%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->conflicts = alpm_list_add(info->conflicts, linedup); } } else if(strcmp(line, "%PROVIDES%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { char *linedup; STRDUP(linedup, _alpm_strtrim(line), goto error); info->provides = alpm_list_add(info->provides, linedup); @@ -693,10 +698,12 @@ int _alpm_db_read(pmdb_t *db, pmpkg_t *info, pmdbinfrq_t inforeq) snprintf(path, PATH_MAX, "%sdeltas", pkgpath); if((fp = fopen(path, "r"))) { while(!feof(fp)) { - fgets(line, 255, fp); + if(fgets(line, sizeof(line), fp) == NULL) { + break; + } _alpm_strtrim(line); if(strcmp(line, "%DELTAS%") == 0) { - while(fgets(line, sline, fp) && strlen(_alpm_strtrim(line))) { + while(fgets(line, sizeof(line), fp) && strlen(_alpm_strtrim(line))) { pmdelta_t *delta = _alpm_delta_parse(line); if(delta) { info->deltas = alpm_list_add(info->deltas, delta); diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c index 38cf357a..3d8c4e38 100644 --- a/lib/libalpm/be_package.c +++ b/lib/libalpm/be_package.c @@ -69,19 +69,19 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) } else { key = _alpm_strtrim(key); ptr = _alpm_strtrim(ptr); - if(!strcmp(key, "pkgname")) { + if(strcmp(key, "pkgname") == 0) { STRDUP(newpkg->name, ptr, RET_ERR(PM_ERR_MEMORY, -1)); - } else if(!strcmp(key, "pkgver")) { + } else if(strcmp(key, "pkgver") == 0) { STRDUP(newpkg->version, ptr, RET_ERR(PM_ERR_MEMORY, -1)); - } else if(!strcmp(key, "pkgdesc")) { + } else if(strcmp(key, "pkgdesc") == 0) { STRDUP(newpkg->desc, ptr, RET_ERR(PM_ERR_MEMORY, -1)); - } else if(!strcmp(key, "group")) { + } else if(strcmp(key, "group") == 0) { newpkg->groups = alpm_list_add(newpkg->groups, strdup(ptr)); - } else if(!strcmp(key, "url")) { + } else if(strcmp(key, "url") == 0) { STRDUP(newpkg->url, ptr, RET_ERR(PM_ERR_MEMORY, -1)); - } else if(!strcmp(key, "license")) { + } else if(strcmp(key, "license") == 0) { newpkg->licenses = alpm_list_add(newpkg->licenses, strdup(ptr)); - } else if(!strcmp(key, "builddate")) { + } else if(strcmp(key, "builddate") == 0) { char first = tolower((unsigned char)ptr[0]); if(first > 'a' && first < 'z') { struct tm tmp_tm = {0}; /* initialize to null in case of failure */ @@ -92,27 +92,27 @@ static int parse_descfile(struct archive *a, pmpkg_t *newpkg) } else { newpkg->builddate = atol(ptr); } - } else if(!strcmp(key, "packager")) { + } else if(strcmp(key, "packager") == 0) { STRDUP(newpkg->packager, ptr, RET_ERR(PM_ERR_MEMORY, -1)); - } else if(!strcmp(key, "arch")) { + } else if(strcmp(key, "arch") == 0) { STRDUP(newpkg->arch, ptr, RET_ERR(PM_ERR_MEMORY, -1)); - } else if(!strcmp(key, "size")) { + } else if(strcmp(key, "size") == 0) { /* size in the raw package is uncompressed (installed) size */ newpkg->isize = atol(ptr); - } else if(!strcmp(key, "depend")) { + } else if(strcmp(key, "depend") == 0) { pmdepend_t *dep = _alpm_splitdep(ptr); newpkg->depends = alpm_list_add(newpkg->depends, dep); - } else if(!strcmp(key, "optdepend")) { + } else if(strcmp(key, "optdepend") == 0) { newpkg->optdepends = alpm_list_add(newpkg->optdepends, strdup(ptr)); - } else if(!strcmp(key, "conflict")) { + } else if(strcmp(key, "conflict") == 0) { newpkg->conflicts = alpm_list_add(newpkg->conflicts, strdup(ptr)); - } else if(!strcmp(key, "replaces")) { + } else if(strcmp(key, "replaces") == 0) { newpkg->replaces = alpm_list_add(newpkg->replaces, strdup(ptr)); - } else if(!strcmp(key, "provides")) { + } else if(strcmp(key, "provides") == 0) { newpkg->provides = alpm_list_add(newpkg->provides, strdup(ptr)); - } else if(!strcmp(key, "backup")) { + } else if(strcmp(key, "backup") == 0) { newpkg->backup = alpm_list_add(newpkg->backup, strdup(ptr)); - } else if(!strcmp(key, "makepkgopt")) { + } else if(strcmp(key, "makepkgopt") == 0) { /* not used atm */ } else { _alpm_log(PM_LOG_DEBUG, "%s: syntax error in description file line %d\n", @@ -230,7 +230,7 @@ static pmpkg_t *pkg_load(const char *pkgfile, int full) goto pkg_invalid; } - archive_read_finish(archive); + archive_read_finish(archive); /* internal fields for package struct */ newpkg->origin = PKG_FROM_FILE; diff --git a/lib/libalpm/conflict.c b/lib/libalpm/conflict.c index e36844a8..694c38db 100644 --- a/lib/libalpm/conflict.c +++ b/lib/libalpm/conflict.c @@ -88,8 +88,8 @@ int _alpm_conflict_isin(pmconflict_t *needle, alpm_list_t *haystack) char *cpkg2 = conflict->package2; char *npkg1 = needle->package1; char *npkg2 = needle->package2; - if((!strcmp(cpkg1, npkg1) && !strcmp(cpkg2, npkg2)) - || (!strcmp(cpkg1, npkg2) && !strcmp(cpkg2, npkg1))) { + if((strcmp(cpkg1, npkg1) == 0 && strcmp(cpkg2, npkg2) == 0) + || (strcmp(cpkg1, npkg2) == 0 && strcmp(cpkg2, npkg1) == 0)) { return(1); } } @@ -321,7 +321,7 @@ static alpm_list_t *chk_filedifference(alpm_list_t *filesA, alpm_list_t *filesB) */ static alpm_list_t *add_fileconflict(alpm_list_t *conflicts, pmfileconflicttype_t type, const char *filestr, - const char* name1, const char* name2) + const char* name1, const char* name2) { pmfileconflict_t *conflict; MALLOC(conflict, sizeof(pmfileconflict_t), RET_ERR(PM_ERR_MEMORY, NULL)); diff --git a/lib/libalpm/deps.c b/lib/libalpm/deps.c index 26f9b16d..fd893a63 100644 --- a/lib/libalpm/deps.c +++ b/lib/libalpm/deps.c @@ -546,7 +546,7 @@ pmpkg_t *_alpm_resolvedep(pmdepend_t *dep, alpm_list_t *dbs, for(i = dbs; i; i = i->next) { for(j = _alpm_db_get_pkgcache(i->data); j; j = j->next) { pmpkg_t *pkg = j->data; - if(alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) && + if(alpm_depcmp(pkg, dep) && strcmp(pkg->name, dep->name) != 0 && !_alpm_pkg_find(excluding, pkg->name)) { if(_alpm_pkg_should_ignore(pkg)) { int install = 0; diff --git a/lib/libalpm/dload.c b/lib/libalpm/dload.c index c11148d1..32096e24 100644 --- a/lib/libalpm/dload.c +++ b/lib/libalpm/dload.c @@ -38,7 +38,7 @@ #include <sys/param.h> /* MAXHOSTNAMELEN */ #endif -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_FETCH #include <fetch.h> #endif @@ -58,7 +58,7 @@ static char *get_filename(const char *url) { return(filename); } -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_FETCH static char *get_destfile(const char *path, const char *filename) { char *destfile; /* len = localpath len + filename len + null */ @@ -251,7 +251,7 @@ static int download_internal(const char *url, const char *localpath, check_stop(); size_t nwritten = 0; nwritten = fwrite(buffer, 1, nread, localf); - if((nwritten != nread) || ferror(localf)) { + if((nwritten != (size_t)nread) || ferror(localf)) { pm_errno = PM_ERR_RETRIEVE; _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), tempfile, strerror(errno)); @@ -338,7 +338,7 @@ cleanup: static int download(const char *url, const char *localpath, int force) { if(handle->fetchcb == NULL) { -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_FETCH return(download_internal(url, localpath, force)); #else RET_ERR(PM_ERR_EXTERNAL_DOWNLOAD, -1); diff --git a/lib/libalpm/error.c b/lib/libalpm/error.c index 8d8d0458..b64ee67c 100644 --- a/lib/libalpm/error.c +++ b/lib/libalpm/error.c @@ -31,7 +31,7 @@ #include <sys/param.h> /* MAXHOSTNAMELEN */ #endif -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_FETCH #include <fetch.h> /* fetchLastErrString */ #endif @@ -145,7 +145,7 @@ const char SYMEXPORT *alpm_strerror(int err) * error string instead. */ return _("libarchive error"); case PM_ERR_LIBFETCH: -#if defined(INTERNAL_DOWNLOAD) +#ifdef HAVE_FETCH return fetchLastErrString; #else /* obviously shouldn't get here... */ diff --git a/lib/libalpm/md5.c b/lib/libalpm/md5.c index 7d2716f2..90635046 100644 --- a/lib/libalpm/md5.c +++ b/lib/libalpm/md5.c @@ -36,6 +36,8 @@ * int md5_file( char *path, unsigned char *output ) * to * int md5_file( const char *path, unsigned char *output ) + * * use a dynamically-allocated buffer in md5_file, and increase the size + * for performance reasons * * various static/inline changes * * NOTE: XySSL has been renamed to PolarSSL, which is available at @@ -44,6 +46,7 @@ #include <string.h> #include <stdio.h> +#include <stdlib.h> #include "md5.h" @@ -309,11 +312,16 @@ int md5_file( const char *path, unsigned char output[16] ) FILE *f; size_t n; md5_context ctx; - unsigned char buf[1024]; + unsigned char *buf; - if( ( f = fopen( path, "rb" ) ) == NULL ) + if( ( buf = calloc(8192, sizeof(unsigned char)) ) == NULL ) return( 1 ); + if( ( f = fopen( path, "rb" ) ) == NULL ) { + free( buf ); + return( 1 ); + } + md5_starts( &ctx ); while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 ) @@ -322,6 +330,7 @@ int md5_file( const char *path, unsigned char output[16] ) md5_finish( &ctx, output ); memset( &ctx, 0, sizeof( md5_context ) ); + free( buf ); if( ferror( f ) != 0 ) { diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index becbc60f..0060300c 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -749,7 +749,7 @@ int _alpm_pkg_cmp(const void *p1, const void *p2) { pmpkg_t *pkg1 = (pmpkg_t *)p1; pmpkg_t *pkg2 = (pmpkg_t *)p2; - return(strcmp(pkg1->name, pkg2->name)); + return(strcoll(pkg1->name, pkg2->name)); } /* Test for existence of a package in a alpm_list_t* diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index c8946448..14f81f92 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -67,10 +67,10 @@ struct __pmpkg_t { /* internal */ pmpkgfrom_t origin; /* Replaced 'void *data' with this union as follows: - origin == PKG_FROM_CACHE, use pkg->origin_data.db - origin == PKG_FROM_FILE, use pkg->origin_data.file + origin == PKG_FROM_CACHE, use pkg->origin_data.db + origin == PKG_FROM_FILE, use pkg->origin_data.file */ - union { + union { pmdb_t *db; char *file; } origin_data; diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 49fc0f67..2e25b787 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -107,7 +107,7 @@ static alpm_list_t *check_arch(alpm_list_t *pkgs) for(i = pkgs; i; i = i->next) { pmpkg_t *pkg = i->data; const char *pkgarch = alpm_pkg_get_arch(pkg); - if(strcmp(pkgarch,arch) && strcmp(pkgarch,"any")) { + if(strcmp(pkgarch,arch) != 0 && strcmp(pkgarch,"any") != 0) { char *string; const char *pkgname = alpm_pkg_get_name(pkg); const char *pkgver = alpm_pkg_get_version(pkg); @@ -323,11 +323,11 @@ static int grep(const char *fn, const char *needle) } while(!feof(fp)) { char line[1024]; - int sline = sizeof(line)-1; - fgets(line, sline, fp); - if(feof(fp)) { + if(fgets(line, sizeof(line), fp) == NULL) { continue; } + /* TODO: this will not work if the search string + * ends up being split across line reads */ if(strstr(line, needle)) { fclose(fp); return(1); @@ -344,6 +344,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, char scriptfn[PATH_MAX]; char cmdline[PATH_MAX]; char tmpdir[PATH_MAX]; + char *argv[] = { "sh", "-c", cmdline, NULL }; char *scriptpath; int clean_tmpdir = 0; int retval = 0; @@ -371,7 +372,7 @@ int _alpm_runscriptlet(const char *root, const char *installfn, /* either extract or copy the scriptlet */ snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir); - if(!strcmp(script, "pre_upgrade") || !strcmp(script, "pre_install")) { + if(strcmp(script, "pre_upgrade") == 0 || strcmp(script, "pre_install") == 0) { if(_alpm_unpack_single(installfn, tmpdir, ".INSTALL")) { retval = 1; } @@ -401,7 +402,9 @@ int _alpm_runscriptlet(const char *root, const char *installfn, scriptpath, script, ver); } - retval = _alpm_run_chroot(root, cmdline); + _alpm_log(PM_LOG_DEBUG, "executing \"%s\"\n", cmdline); + + retval = _alpm_run_chroot(root, "/bin/sh", argv); cleanup: if(clean_tmpdir && _alpm_rmrf(tmpdir)) { diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 32eaa442..5bf4ef12 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -43,13 +43,18 @@ #include <archive.h> #include <archive_entry.h> +#ifdef HAVE_LIBSSL +#include <openssl/md5.h> +#else +#include "md5.h" +#endif + /* libalpm */ #include "util.h" #include "log.h" #include "package.h" #include "alpm.h" #include "alpm_list.h" -#include "md5.h" #include "handle.h" #ifndef HAVE_STRSEP @@ -143,7 +148,15 @@ int _alpm_copyfile(const char *src, const char *dest) /* do the actual file copy */ while((len = fread(buf, 1, CPBUFSIZE, in))) { - fwrite(buf, 1, len, out); + size_t nwritten = 0; + nwritten = fwrite(buf, 1, len, out); + if((nwritten != len) || ferror(out)) { + pm_errno = PM_ERR_WRITE; + _alpm_log(PM_LOG_ERROR, _("error writing to file '%s': %s\n"), + dest, strerror(errno)); + ret = -1; + goto cleanup; + } } /* chmod dest to permissions of src, as long as it is not a symlink */ @@ -364,8 +377,8 @@ int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int cleanup: umask(oldmask); archive_read_finish(_archive); - if(restore_cwd) { - chdir(cwd); + if(restore_cwd && chdir(cwd) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); } return(ret); } @@ -398,7 +411,7 @@ int _alpm_rmrf(const char *path) for(dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if(dp->d_ino) { sprintf(name, "%s/%s", path, dp->d_name); - if(strcmp(dp->d_name, "..") && strcmp(dp->d_name, ".")) { + if(strcmp(dp->d_name, "..") != 0 && strcmp(dp->d_name, ".") != 0) { errflag += _alpm_rmrf(name); } } @@ -444,10 +457,11 @@ int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args) return(ret); } -int _alpm_run_chroot(const char *root, const char *cmd) +int _alpm_run_chroot(const char *root, const char *path, char *const argv[]) { char cwd[PATH_MAX]; pid_t pid; + int pipefd[2]; int restore_cwd = 0; int retval = 0; @@ -466,11 +480,17 @@ int _alpm_run_chroot(const char *root, const char *cmd) goto cleanup; } - _alpm_log(PM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n", cmd, root); + _alpm_log(PM_LOG_DEBUG, "executing \"%s\" under chroot \"%s\"\n", path, root); /* Flush open fds before fork() to avoid cloning buffers */ fflush(NULL); + if(pipe(pipefd) == -1) { + _alpm_log(PM_LOG_ERROR, _("could not create pipe (%s)\n"), strerror(errno)); + retval = 1; + goto cleanup; + } + /* fork- parent and child each have seperate code blocks below */ pid = fork(); if(pid == -1) { @@ -480,62 +500,74 @@ int _alpm_run_chroot(const char *root, const char *cmd) } if(pid == 0) { - FILE *pipe; /* this code runs for the child only (the actual chroot/exec) */ - _alpm_log(PM_LOG_DEBUG, "chrooting in %s\n", root); + close(1); + close(2); + while(dup2(pipefd[1], 1) == -1 && errno == EINTR); + while(dup2(pipefd[1], 2) == -1 && errno == EINTR); + close(pipefd[0]); + close(pipefd[1]); + + /* use fprintf instead of _alpm_log to send output through the parent */ if(chroot(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)\n"), - strerror(errno)); + fprintf(stderr, _("could not change the root directory (%s)\n"), strerror(errno)); exit(1); } if(chdir("/") != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to / (%s)\n"), - strerror(errno)); + fprintf(stderr, _("could not change directory to / (%s)\n"), strerror(errno)); exit(1); } umask(0022); - pipe = popen(cmd, "r"); - if(!pipe) { - _alpm_log(PM_LOG_ERROR, _("call to popen failed (%s)\n"), - strerror(errno)); - exit(1); - } - while(!feof(pipe)) { - char line[PATH_MAX]; - if(fgets(line, PATH_MAX, pipe) == NULL) - break; - alpm_logaction("%s", line); - EVENT(handle->trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); - } - retval = pclose(pipe); - exit(WEXITSTATUS(retval)); + execv(path, argv); + fprintf(stderr, _("call to execv failed (%s)\n"), strerror(errno)); + exit(1); } else { /* this code runs for the parent only (wait on the child) */ - pid_t retpid; int status; - do { - retpid = waitpid(pid, &status, 0); - } while(retpid == -1 && errno == EINTR); - if(retpid == -1) { - _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)\n"), - strerror(errno)); + FILE *pipe; + + close(pipefd[1]); + pipe = fdopen(pipefd[0], "r"); + if(pipe == NULL) { + close(pipefd[0]); retval = 1; - goto cleanup; } else { - /* check the return status, make sure it is 0 (success) */ - if(WIFEXITED(status)) { - _alpm_log(PM_LOG_DEBUG, "call to waitpid succeeded\n"); - if(WEXITSTATUS(status) != 0) { - _alpm_log(PM_LOG_ERROR, _("command failed to execute correctly\n")); - retval = 1; - } + while(!feof(pipe)) { + char line[PATH_MAX]; + if(fgets(line, PATH_MAX, pipe) == NULL) + break; + alpm_logaction("%s", line); + EVENT(handle->trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); + } + fclose(pipe); + } + + while(waitpid(pid, &status, 0) == -1) { + if(errno != EINTR) { + _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)\n"), strerror(errno)); + retval = 1; + goto cleanup; + } + } + + /* report error from above after the child has exited */ + if(retval != 0) { + _alpm_log(PM_LOG_ERROR, _("could not open pipe (%s)\n"), strerror(errno)); + goto cleanup; + } + /* check the return status, make sure it is 0 (success) */ + if(WIFEXITED(status)) { + _alpm_log(PM_LOG_DEBUG, "call to waitpid succeeded\n"); + if(WEXITSTATUS(status) != 0) { + _alpm_log(PM_LOG_ERROR, _("command failed to execute correctly\n")); + retval = 1; } } } cleanup: - if(restore_cwd) { - chdir(cwd); + if(restore_cwd && chdir(cwd) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)\n"), cwd, strerror(errno)); } return(retval); @@ -551,7 +583,8 @@ int _alpm_ldconfig(const char *root) if(access(line, F_OK) == 0) { snprintf(line, PATH_MAX, "%ssbin/ldconfig", root); if(access(line, X_OK) == 0) { - _alpm_run_chroot(root, "/sbin/ldconfig"); + char *argv[] = { "ldconfig", NULL }; + _alpm_run_chroot(root, "/sbin/ldconfig", argv); } } @@ -648,6 +681,42 @@ int _alpm_lstat(const char *path, struct stat *buf) return(ret); } +#ifdef HAVE_LIBSSL +static int md5_file(const char *path, unsigned char output[16]) +{ + FILE *f; + size_t n; + MD5_CTX ctx; + unsigned char *buf; + + CALLOC(buf, 8192, sizeof(unsigned char), return(1)); + + if((f = fopen(path, "rb")) == NULL) { + free(buf); + return(1); + } + + MD5_Init(&ctx); + + while((n = fread(buf, 1, sizeof(buf), f)) > 0) { + MD5_Update(&ctx, buf, n); + } + + MD5_Final(output, &ctx); + + memset(&ctx, 0, sizeof(MD5_CTX)); + free(buf); + + if(ferror(f) != 0) { + fclose(f); + return(2); + } + + fclose(f); + return(0); +} +#endif + /** Get the md5 sum of file. * @param filename name of the file * @return the checksum on success, NULL on error @@ -665,6 +734,7 @@ char SYMEXPORT *alpm_compute_md5sum(const char *filename) /* allocate 32 chars plus 1 for null */ md5sum = calloc(33, sizeof(char)); + /* defined above for OpenSSL, otherwise defined in md5.h */ ret = md5_file(filename, output); if (ret > 0) { diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 8a3154a7..35c4d288 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -68,7 +68,7 @@ int _alpm_unpack_single(const char *archive, const char *prefix, const char *fn) int _alpm_unpack(const char *archive, const char *prefix, alpm_list_t *list, int breakfirst); int _alpm_rmrf(const char *path); int _alpm_logaction(int usesyslog, FILE *f, const char *fmt, va_list args); -int _alpm_run_chroot(const char *root, const char *cmd); +int _alpm_run_chroot(const char *root, const char *path, char *const argv[]); int _alpm_ldconfig(const char *root); int _alpm_str_cmp(const void *s1, const void *s2); char *_alpm_filecache_find(const char *filename); |