diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 49385f4f..73c84cc0 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -39,6 +39,10 @@ #include #include +/* libarchive */ +#include +#include + /* libalpm */ #include "add.h" #include "alpm_list.h" @@ -280,6 +284,7 @@ int _alpm_add_prepare(pmtrans_t *trans, pmdb_t *db, alpm_list_t **data) return(0); } +/* TODO clean up this monster 554 line function */ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) { int i, ret = 0, errors = 0, pkg_count = 0; @@ -287,6 +292,9 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) struct archive_entry *entry; char cwd[PATH_MAX] = ""; alpm_list_t *targ, *lp; + const int archive_flags = ARCHIVE_EXTRACT_OWNER | + ARCHIVE_EXTRACT_PERM | + ARCHIVE_EXTRACT_TIME; ALPM_LOG_FUNC; @@ -536,9 +544,11 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) archive_entry_set_pathname(entry, tempfile); - if(archive_read_extract(archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { - _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), entryname, strerror(errno)); - alpm_logaction(_("could not extract %s (%s)"), entryname, strerror(errno)); + if(archive_read_extract(archive, entry, archive_flags) != ARCHIVE_OK) { + _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), + entryname, strerror(errno)); + alpm_logaction(_("could not extract %s (%s)"), + entryname, strerror(errno)); errors++; unlink(tempfile); FREE(hash_orig); @@ -686,7 +696,7 @@ int _alpm_add_commit(pmtrans_t *trans, pmdb_t *db) archive_entry_set_pathname(entry, filename); - if(archive_read_extract(archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { + if(archive_read_extract(archive, entry, archive_flags) != ARCHIVE_OK) { _alpm_log(PM_LOG_ERROR, _("could not extract %s (%s)"), filename, strerror(errno)); alpm_logaction(_("error: could not extract %s (%s)"), filename, strerror(errno)); errors++; diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 9a5ae8f4..d0aba7ba 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -34,6 +34,10 @@ #include #include +/* libarchive */ +#include +#include + /* libalpm */ #include "package.h" #include "alpm_list.h" diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index 9af25c13..7823a67b 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -28,10 +28,8 @@ #include #include #include +#include #include -#ifdef CYGWIN -#include /* PATH_MAX */ -#endif #include /* libalpm */ diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c index 87b8c1b6..cb873e7a 100644 --- a/lib/libalpm/trans.c +++ b/lib/libalpm/trans.c @@ -27,6 +27,15 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#ifndef __sun__ +#include +#endif /* libalpm */ #include "trans.h" @@ -364,8 +373,253 @@ int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg) return(0); } +/* A cheap grep for text files, returns 1 if a substring + * was found in the text file fn, 0 if it wasn't + */ +static int grep(const char *fn, const char *needle) +{ + FILE *fp; -pmtranstype_t alpm_trans_get_type() + if((fp = fopen(fn, "r")) == NULL) { + return(0); + } + while(!feof(fp)) { + char line[1024]; + fgets(line, 1024, fp); + if(feof(fp)) { + continue; + } + if(strstr(line, needle)) { + fclose(fp); + return(1); + } + } + fclose(fp); + return(0); +} + +int _alpm_runscriptlet(const char *root, const char *installfn, + const char *script, const char *ver, + const char *oldver, pmtrans_t *trans) +{ + char scriptfn[PATH_MAX]; + char cmdline[PATH_MAX]; + char tmpdir[PATH_MAX] = ""; + char *scriptpath; + struct stat buf; + char cwd[PATH_MAX] = ""; + pid_t pid; + int retval = 0; + + ALPM_LOG_FUNC; + + if(stat(installfn, &buf)) { + /* not found */ + _alpm_log(PM_LOG_DEBUG, "scriptlet '%s' not found", installfn); + return(0); + } + + if(!strcmp(script, "pre_upgrade") || !strcmp(script, "pre_install")) { + snprintf(tmpdir, PATH_MAX, "%stmp/", root); + if(stat(tmpdir, &buf)) { + _alpm_makepath(tmpdir); + } + snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", root); + if(mkdtemp(tmpdir) == NULL) { + _alpm_log(PM_LOG_ERROR, _("could not create temp directory")); + return(1); + } + _alpm_unpack(installfn, tmpdir, ".INSTALL"); + snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir); + /* chop off the root so we can find the tmpdir in the chroot */ + scriptpath = scriptfn + strlen(root) - 1; + } else { + strncpy(scriptfn, installfn, PATH_MAX); + /* chop off the root so we can find the tmpdir in the chroot */ + scriptpath = scriptfn + strlen(root) - 1; + } + + if(!grep(scriptfn, script)) { + /* script not found in scriptlet file */ + goto cleanup; + } + + /* 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")); + /* in case of error, cwd content is undefined: so we set it to something */ + cwd[0] = 0; + } + + /* just in case our cwd was removed in the upgrade operation */ + if(chdir(root) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)"), root, strerror(errno)); + goto cleanup; + } + + _alpm_log(PM_LOG_DEBUG, _("executing %s script..."), script); + + if(oldver) { + snprintf(cmdline, PATH_MAX, "source %s %s %s %s", + scriptpath, script, ver, oldver); + } else { + snprintf(cmdline, PATH_MAX, "source %s %s %s", + scriptpath, script, ver); + } + _alpm_log(PM_LOG_DEBUG, "%s", cmdline); + + pid = fork(); + if(pid == -1) { + _alpm_log(PM_LOG_ERROR, _("could not fork a new process (%s)"), strerror(errno)); + retval = 1; + goto cleanup; + } + + if(pid == 0) { + FILE *pp; + _alpm_log(PM_LOG_DEBUG, _("chrooting in %s"), root); + if(chroot(root) != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)"), strerror(errno)); + return(1); + } + if(chdir("/") != 0) { + _alpm_log(PM_LOG_ERROR, _("could not change directory to / (%s)"), strerror(errno)); + return(1); + } + umask(0022); + _alpm_log(PM_LOG_DEBUG, _("executing \"%s\""), cmdline); + pp = popen(cmdline, "r"); + if(!pp) { + _alpm_log(PM_LOG_ERROR, _("call to popen failed (%s)"), strerror(errno)); + retval = 1; + goto cleanup; + } + while(!feof(pp)) { + char line[1024]; + if(fgets(line, 1024, pp) == NULL) + break; + /*TODO clean this code up, remove weird SCRIPTLET_START/DONE, + * (void*)atol call, etc. */ + /* "START " */ + if((strlen(line) > strlen(SCRIPTLET_START)) + && !strncmp(line, SCRIPTLET_START, strlen(SCRIPTLET_START))) { + EVENT(trans, PM_TRANS_EVT_SCRIPTLET_START, + _alpm_strtrim(line + strlen(SCRIPTLET_START)), NULL); + /* "DONE " */ + } else if((strlen(line) > strlen(SCRIPTLET_DONE)) + && !strncmp(line, SCRIPTLET_DONE, strlen(SCRIPTLET_DONE))) { + EVENT(trans, PM_TRANS_EVT_SCRIPTLET_DONE, + (void*)atol(_alpm_strtrim(line + strlen(SCRIPTLET_DONE))), + NULL); + } else { + _alpm_strtrim(line); + /* log our script output */ + alpm_logaction(line); + EVENT(trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); + } + } + pclose(pp); + exit(0); + } else { + if(waitpid(pid, 0, 0) == -1) { + _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)"), + strerror(errno)); + retval = 1; + goto cleanup; + } + } + +cleanup: + if(strlen(tmpdir) && _alpm_rmrf(tmpdir)) { + _alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s"), tmpdir); + } + if(strlen(cwd)) { + chdir(cwd); + } + + return(retval); +} + +#ifndef __sun__ +static long long get_freespace() +{ + struct mntent *mnt; + const char *table = MOUNTED; + FILE *fp; + long long ret=0; + + if((fp = setmntent(table, "r")) == NULL) { + _alpm_log(PM_LOG_ERROR, _("cannot read disk space information from %s: %s"), + table, strerror(errno)); + return(-1); + } + + while ((mnt = getmntent(fp))) + { + struct statvfs64 buf; + + statvfs64(mnt->mnt_dir, &buf); + ret += buf.f_bavail * buf.f_bsize; + } + + endmntent(fp); + + return(ret); +} + +int _alpm_check_freespace(pmtrans_t *trans, alpm_list_t **data) +{ + alpm_list_t *i; + long long pkgsize=0, freespace; + + ALPM_LOG_FUNC; + + for(i = trans->packages; i; i = i->next) { + if(trans->type == PM_TRANS_TYPE_SYNC) + { + pmsyncpkg_t *sync = i->data; + if(sync->type != PM_SYNC_TYPE_REPLACE) { + pmpkg_t *pkg = sync->pkg; + pkgsize += alpm_pkg_get_isize(pkg); + } + } + else + { + pmpkg_t *pkg = i->data; + pkgsize += alpm_pkg_get_size(pkg); + } + } + freespace = get_freespace(); + _alpm_log(PM_LOG_DEBUG, _("check_freespace: total pkg size: %lld, disk space: %lld"), pkgsize, freespace); + if(pkgsize > freespace) { + if(data) { + long long *ptr; + if((ptr = (long long*)malloc(sizeof(long long)))==NULL) { + _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(long long)); + pm_errno = PM_ERR_MEMORY; + return(-1); + } + *ptr = pkgsize; + *data = alpm_list_add(*data, ptr); + if((ptr = (long long*)malloc(sizeof(long long)))==NULL) { + _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(long long)); + FREELIST(*data); + pm_errno = PM_ERR_MEMORY; + return(-1); + } + *ptr = freespace; + *data = alpm_list_add(*data, ptr); + } + pm_errno = PM_ERR_DISK_FULL; + return(-1); + } + else { + return(0); + } +} +#endif + +pmtranstype_t SYMEXPORT alpm_trans_get_type() { /* Sanity checks */ ASSERT(handle != NULL, return(-1)); @@ -383,7 +637,7 @@ unsigned int SYMEXPORT alpm_trans_get_flags() return handle->trans->flags; } -alpm_list_t * alpm_trans_get_targets() +alpm_list_t SYMEXPORT * alpm_trans_get_targets() { /* Sanity checks */ ASSERT(handle != NULL, return(NULL)); diff --git a/lib/libalpm/trans.h b/lib/libalpm/trans.h index 11f15f85..eb152a04 100644 --- a/lib/libalpm/trans.h +++ b/lib/libalpm/trans.h @@ -79,6 +79,12 @@ int _alpm_trans_addtarget(pmtrans_t *trans, char *target); int _alpm_trans_prepare(pmtrans_t *trans, alpm_list_t **data); int _alpm_trans_commit(pmtrans_t *trans, alpm_list_t **data); int _alpm_trans_update_depends(pmtrans_t *trans, pmpkg_t *pkg); +int _alpm_runscriptlet(const char *root, const char *installfn, + const char *script, const char *ver, + const char *oldver, pmtrans_t *trans); +#ifndef __sun__ +int _alpm_check_freespace(pmtrans_t *trans, alpm_list_t **data); +#endif #endif /* _ALPM_TRANS_H */ diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 1f7b7190..f821beb2 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -27,38 +27,23 @@ #include #include -#ifdef __sun__ -#include -#endif #include -#include -#include #include +#include #include #include #include #include -#include -#if defined(__APPLE__) || defined(__OpenBSD__) -#include -#endif -#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__sun__) -#include -#endif -#ifdef CYGWIN -#include /* PATH_MAX */ -#endif -#include -#ifndef __sun__ -#include -#endif +#include + +/* libarchive */ +#include +#include /* libalpm */ #include "util.h" #include "alpm_list.h" #include "log.h" -#include "trans.h" -#include "sync.h" #include "error.h" #include "package.h" #include "alpm.h" @@ -266,6 +251,9 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn) register struct archive *_archive; struct archive_entry *entry; char expath[PATH_MAX]; + const int archive_flags = ARCHIVE_EXTRACT_OWNER | + ARCHIVE_EXTRACT_PERM | + ARCHIVE_EXTRACT_TIME; ALPM_LOG_FUNC; @@ -288,7 +276,7 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn) } snprintf(expath, PATH_MAX, "%s/%s", prefix, archive_entry_pathname(entry)); archive_entry_set_pathname(entry, expath); - if(archive_read_extract(_archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { + if(archive_read_extract(_archive, entry, archive_flags) != ARCHIVE_OK) { _alpm_log(PM_LOG_ERROR, _("could not extract %s: %s\n"), archive_entry_pathname(entry), archive_error_string(_archive)); return(1); } @@ -388,252 +376,6 @@ int _alpm_ldconfig(const char *root) return(0); } -/* A cheap grep for text files, returns 1 if a substring - * was found in the text file fn, 0 if it wasn't - */ -static int grep(const char *fn, const char *needle) -{ - FILE *fp; - - if((fp = fopen(fn, "r")) == NULL) { - return(0); - } - while(!feof(fp)) { - char line[1024]; - fgets(line, 1024, fp); - if(feof(fp)) { - continue; - } - if(strstr(line, needle)) { - fclose(fp); - return(1); - } - } - fclose(fp); - return(0); -} - -int _alpm_runscriptlet(const char *root, const char *installfn, - const char *script, const char *ver, - const char *oldver, pmtrans_t *trans) -{ - char scriptfn[PATH_MAX]; - char cmdline[PATH_MAX]; - char tmpdir[PATH_MAX] = ""; - char *scriptpath; - struct stat buf; - char cwd[PATH_MAX] = ""; - pid_t pid; - int retval = 0; - - ALPM_LOG_FUNC; - - if(stat(installfn, &buf)) { - /* not found */ - _alpm_log(PM_LOG_DEBUG, "scriptlet '%s' not found", installfn); - return(0); - } - - if(!strcmp(script, "pre_upgrade") || !strcmp(script, "pre_install")) { - snprintf(tmpdir, PATH_MAX, "%stmp/", root); - if(stat(tmpdir, &buf)) { - _alpm_makepath(tmpdir); - } - snprintf(tmpdir, PATH_MAX, "%stmp/alpm_XXXXXX", root); - if(mkdtemp(tmpdir) == NULL) { - _alpm_log(PM_LOG_ERROR, _("could not create temp directory")); - return(1); - } - _alpm_unpack(installfn, tmpdir, ".INSTALL"); - snprintf(scriptfn, PATH_MAX, "%s/.INSTALL", tmpdir); - /* chop off the root so we can find the tmpdir in the chroot */ - scriptpath = scriptfn + strlen(root) - 1; - } else { - strncpy(scriptfn, installfn, PATH_MAX); - /* chop off the root so we can find the tmpdir in the chroot */ - scriptpath = scriptfn + strlen(root) - 1; - } - - if(!grep(scriptfn, script)) { - /* script not found in scriptlet file */ - goto cleanup; - } - - /* 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")); - /* in case of error, cwd content is undefined: so we set it to something */ - cwd[0] = 0; - } - - /* just in case our cwd was removed in the upgrade operation */ - if(chdir(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to %s (%s)"), root, strerror(errno)); - goto cleanup; - } - - _alpm_log(PM_LOG_DEBUG, _("executing %s script..."), script); - - if(oldver) { - snprintf(cmdline, PATH_MAX, "source %s %s %s %s", - scriptpath, script, ver, oldver); - } else { - snprintf(cmdline, PATH_MAX, "source %s %s %s", - scriptpath, script, ver); - } - _alpm_log(PM_LOG_DEBUG, "%s", cmdline); - - pid = fork(); - if(pid == -1) { - _alpm_log(PM_LOG_ERROR, _("could not fork a new process (%s)"), strerror(errno)); - retval = 1; - goto cleanup; - } - - if(pid == 0) { - FILE *pp; - _alpm_log(PM_LOG_DEBUG, _("chrooting in %s"), root); - if(chroot(root) != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change the root directory (%s)"), strerror(errno)); - return(1); - } - if(chdir("/") != 0) { - _alpm_log(PM_LOG_ERROR, _("could not change directory to / (%s)"), strerror(errno)); - return(1); - } - umask(0022); - _alpm_log(PM_LOG_DEBUG, _("executing \"%s\""), cmdline); - pp = popen(cmdline, "r"); - if(!pp) { - _alpm_log(PM_LOG_ERROR, _("call to popen failed (%s)"), strerror(errno)); - retval = 1; - goto cleanup; - } - while(!feof(pp)) { - char line[1024]; - if(fgets(line, 1024, pp) == NULL) - break; - /*TODO clean this code up, remove weird SCRIPTLET_START/DONE, - * (void*)atol call, etc. */ - /* "START " */ - if((strlen(line) > strlen(SCRIPTLET_START)) - && !strncmp(line, SCRIPTLET_START, strlen(SCRIPTLET_START))) { - EVENT(trans, PM_TRANS_EVT_SCRIPTLET_START, - _alpm_strtrim(line + strlen(SCRIPTLET_START)), NULL); - /* "DONE " */ - } else if((strlen(line) > strlen(SCRIPTLET_DONE)) - && !strncmp(line, SCRIPTLET_DONE, strlen(SCRIPTLET_DONE))) { - EVENT(trans, PM_TRANS_EVT_SCRIPTLET_DONE, - (void*)atol(_alpm_strtrim(line + strlen(SCRIPTLET_DONE))), - NULL); - } else { - _alpm_strtrim(line); - /* log our script output */ - alpm_logaction(line); - EVENT(trans, PM_TRANS_EVT_SCRIPTLET_INFO, line, NULL); - } - } - pclose(pp); - exit(0); - } else { - if(waitpid(pid, 0, 0) == -1) { - _alpm_log(PM_LOG_ERROR, _("call to waitpid failed (%s)"), - strerror(errno)); - retval = 1; - goto cleanup; - } - } - -cleanup: - if(strlen(tmpdir) && _alpm_rmrf(tmpdir)) { - _alpm_log(PM_LOG_WARNING, _("could not remove tmpdir %s"), tmpdir); - } - if(strlen(cwd)) { - chdir(cwd); - } - - return(retval); -} - -#ifndef __sun__ -static long long get_freespace() -{ - struct mntent *mnt; - const char *table = MOUNTED; - FILE *fp; - long long ret=0; - - if((fp = setmntent(table, "r")) == NULL) { - _alpm_log(PM_LOG_ERROR, _("cannot read disk space information from %s: %s"), - table, strerror(errno)); - return(-1); - } - - while ((mnt = getmntent(fp))) - { - struct statvfs64 buf; - - statvfs64(mnt->mnt_dir, &buf); - ret += buf.f_bavail * buf.f_bsize; - } - - endmntent(fp); - - return(ret); -} - -int _alpm_check_freespace(pmtrans_t *trans, alpm_list_t **data) -{ - alpm_list_t *i; - long long pkgsize=0, freespace; - - ALPM_LOG_FUNC; - - for(i = trans->packages; i; i = i->next) { - if(trans->type == PM_TRANS_TYPE_SYNC) - { - pmsyncpkg_t *sync = i->data; - if(sync->type != PM_SYNC_TYPE_REPLACE) { - pmpkg_t *pkg = sync->pkg; - pkgsize += alpm_pkg_get_isize(pkg); - } - } - else - { - pmpkg_t *pkg = i->data; - pkgsize += alpm_pkg_get_size(pkg); - } - } - freespace = get_freespace(); - _alpm_log(PM_LOG_DEBUG, _("check_freespace: total pkg size: %lld, disk space: %lld"), pkgsize, freespace); - if(pkgsize > freespace) { - if(data) { - long long *ptr; - if((ptr = (long long*)malloc(sizeof(long long)))==NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(long long)); - pm_errno = PM_ERR_MEMORY; - return(-1); - } - *ptr = pkgsize; - *data = alpm_list_add(*data, ptr); - if((ptr = (long long*)malloc(sizeof(long long)))==NULL) { - _alpm_log(PM_LOG_ERROR, _("malloc failure: could not allocate %d bytes"), sizeof(long long)); - FREELIST(*data); - pm_errno = PM_ERR_MEMORY; - return(-1); - } - *ptr = freespace; - *data = alpm_list_add(*data, ptr); - } - pm_errno = PM_ERR_DISK_FULL; - return(-1); - } - else { - return(0); - } -} -#endif - /* convert a time_t to a string - buffer MUST be large enough for * YYYYMMDDHHMMSS - 15 chars */ void _alpm_time2string(time_t t, char *buffer) diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 0584b73b..b98d8a7a 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -27,15 +27,12 @@ #include #include /* here so it doesn't need to be included elsewhere */ -#include -#include +#include #define FREE(p) do { if (p) { free(p); p = NULL; } } while(0) #define ASSERT(cond, action) do { if(!(cond)) { action; } } while(0) -#define ARCHIVE_EXTRACT_FLAGS ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_PERM | ARCHIVE_EXTRACT_TIME - /* define _() as shortcut for gettext() */ #ifdef ENABLE_NLS #define _(str) dgettext ("libalpm", str) @@ -57,15 +54,6 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn); int _alpm_rmrf(const char *path); int _alpm_logaction(unsigned short usesyslog, FILE *f, const char *str); int _alpm_ldconfig(const char *root); -/* TODO wtf? this can't be right */ -#ifdef _ALPM_TRANS_H -int _alpm_runscriptlet(const char *root, const char *installfn, - const char *script, const char *ver, - const char *oldver, pmtrans_t *trans); -#ifndef __sun__ -int _alpm_check_freespace(pmtrans_t *trans, alpm_list_t **data); -#endif -#endif void _alpm_time2string(time_t t, char *buffer); int _alpm_str_cmp(const void *s1, const void *s2);