diff options
Diffstat (limited to 'src/pacman/util.c')
-rw-r--r-- | src/pacman/util.c | 127 |
1 files changed, 86 insertions, 41 deletions
diff --git a/src/pacman/util.c b/src/pacman/util.c index 0facfdd1..2e4ee86e 100644 --- a/src/pacman/util.c +++ b/src/pacman/util.c @@ -42,6 +42,33 @@ /* pacman */ #include "util.h" #include "conf.h" +#include "callback.h" + + +int trans_init(pmtranstype_t type, pmtransflag_t flags) +{ + if(alpm_trans_init(type, flags, cb_trans_evt, + cb_trans_conv, cb_trans_progress) == -1) { + pm_fprintf(stderr, PM_LOG_ERROR, _("failed to init transaction (%s)\n"), + alpm_strerrorlast()); + if(pm_errno == PM_ERR_HANDLE_LOCK) { + fprintf(stderr, _(" if you're sure a package manager is not already\n" + " running, you can remove %s\n"), alpm_option_get_lockfile()); + } + return(-1); + } + return(0); +} + +int trans_release() +{ + if(alpm_trans_release() == -1) { + pm_fprintf(stderr, PM_LOG_ERROR, _("failed to release transaction (%s)\n"), + alpm_strerrorlast()); + return(-1); + } + return(0); +} int needs_transaction() { @@ -94,33 +121,38 @@ int getcols() /* does the same thing as 'mkdir -p' */ int makepath(const char *path) { - char *orig, *str, *ptr; - char full[PATH_MAX+1] = ""; - mode_t oldmask; - - oldmask = umask(0000); + /* A bit of pointer hell here. Descriptions: + * orig - a copy of path so we can safely butcher it with strsep + * str - the current position in the path string (after the delimiter) + * ptr - the original position of str after calling strsep + * incr - incrementally generated path for use in stat/mkdir call + */ + char *orig, *str, *ptr, *incr; + mode_t oldmask = umask(0000); + int ret = 0; orig = strdup(path); + incr = calloc(strlen(orig) + 1, sizeof(char)); str = orig; while((ptr = strsep(&str, "/"))) { if(strlen(ptr)) { struct stat buf; - - /* TODO we should use strncat */ - strcat(full, "/"); - strcat(full, ptr); - if(stat(full, &buf)) { - if(mkdir(full, 0755)) { - free(orig); - umask(oldmask); - return(1); + /* we have another path component- append the newest component to + * existing string and create one more level of dir structure */ + strcat(incr, "/"); + strcat(incr, ptr); + if(stat(incr, &buf)) { + if(mkdir(incr, 0755)) { + ret = 1; + break; } } } } free(orig); + free(incr); umask(oldmask); - return(0); + return(ret); } /* does the same thing as 'rm -rf' */ @@ -234,6 +266,10 @@ void indentprint(const char *str, int indent) p = wcstr; cidx = indent; + if(!p) { + return; + } + while(*p) { if(*p == L' ') { const wchar_t *q, *next; @@ -464,25 +500,22 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local) pmsyncpkg_t *sync = alpm_list_getdata(i); pmpkg_t *pkg = alpm_sync_get_pkg(sync); - /* If this sync record is a replacement, the data member contains - * a list of packages to be removed due to the package that is being - * installed. */ - if(alpm_sync_get_type(sync) == PM_SYNC_TYPE_REPLACE) { - alpm_list_t *to_replace = alpm_sync_get_data(sync); + /* The removes member contains a list of packages to be removed + * due to the package that is being installed. */ + alpm_list_t *to_replace = alpm_sync_get_removes(sync); - for(j = to_replace; j; j = alpm_list_next(j)) { - pmpkg_t *rp = alpm_list_getdata(j); - const char *name = alpm_pkg_get_name(rp); + for(j = to_replace; j; j = alpm_list_next(j)) { + pmpkg_t *rp = alpm_list_getdata(j); + const char *name = alpm_pkg_get_name(rp); - if(!alpm_list_find_str(to_remove, name)) { - rsize += alpm_pkg_get_isize(rp); - to_remove = alpm_list_add(to_remove, strdup(name)); - } + if(!alpm_list_find_str(to_remove, name)) { + rsize += alpm_pkg_get_isize(rp); + to_remove = alpm_list_add(to_remove, strdup(name)); } } dispsize = alpm_pkg_get_size(pkg); - dlsize += alpm_pkg_download_size(pkg, db_local); + dlsize += alpm_pkg_download_size(pkg); isize += alpm_pkg_get_isize(pkg); /* print the package size with the output if ShowSize option set */ @@ -520,38 +553,50 @@ void display_targets(const alpm_list_t *syncpkgs, pmdb_t *db_local) printf("\n"); printf(_("Total Download Size: %.2f MB\n"), mbdlsize); - - /* TODO because all pkgs don't include isize, this is a crude hack */ - if(mbisize > mbdlsize) { - printf(_("Total Installed Size: %.2f MB\n"), mbisize); - } + printf(_("Total Installed Size: %.2f MB\n"), mbisize); FREELIST(targets); } /* presents a prompt and gets a Y/N answer */ -/* TODO there must be a better way */ -int yesno(char *fmt, ...) +int yesno(short preset, char *fmt, ...) { char response[32]; va_list args; + FILE *stream; if(config->noconfirm) { - return(1); + stream = stdout; + } else { + /* Use stderr so questions are always displayed when redirecting output */ + stream = stderr; } va_start(args, fmt); - /* Use stderr so questions are always displayed when redirecting output */ - vfprintf(stderr, fmt, args); + vfprintf(stream, fmt, args); va_end(args); + if(preset) { + fprintf(stream, " %s ", _("[Y/n]")); + } else { + fprintf(stream, " %s ", _("[y/N]")); + } + + if(config->noconfirm) { + fprintf(stream, "\n"); + return(preset); + } + if(fgets(response, 32, stdin)) { - if(strlen(response) != 0) { - strtrim(response); + strtrim(response); + if(strlen(response) == 0) { + return(preset); } - if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES")) || strlen(response) == 0) { + if(!strcasecmp(response, _("Y")) || !strcasecmp(response, _("YES"))) { return(1); + } else if (!strcasecmp(response, _("N")) || !strcasecmp(response, _("NO"))) { + return(0); } } return(0); |