diff options
Diffstat (limited to 'src/util.c')
-rw-r--r-- | src/util.c | 491 |
1 files changed, 11 insertions, 480 deletions
@@ -24,52 +24,16 @@ #include <stdlib.h> #include <stdarg.h> #include <string.h> -#include <limits.h> #include <errno.h> #include <fcntl.h> -#include <libgen.h> -#include <getopt.h> #include <ctype.h> -#include "list.h" -#include "package.h" -#include "db.h" +#include <dirent.h> +#include <zlib.h> +#include <libtar.h> #include "util.h" -#include "pacsync.h" -#include "pacman.h" -/* command line options */ -extern char* pmo_root; -extern unsigned short pmo_op; -extern unsigned short pmo_version; -extern unsigned short pmo_verbose; -extern unsigned short pmo_help; -extern unsigned short pmo_force; -extern unsigned short pmo_nodeps; -extern unsigned short pmo_upgrade; -extern unsigned short pmo_freshen; -extern unsigned short pmo_nosave; -extern unsigned short pmo_d_vertest; -extern unsigned short pmo_d_resolve; -extern unsigned short pmo_q_isfile; -extern unsigned short pmo_q_info; -extern unsigned short pmo_q_list; -extern unsigned short pmo_q_owns; -extern unsigned short pmo_r_cascade; -extern unsigned short pmo_s_sync; -extern unsigned short pmo_s_search; -extern unsigned short pmo_s_clean; -extern unsigned short pmo_s_upgrade; -extern unsigned short pmo_s_downloadonly; -/* configuration file options */ -extern PMList *pmo_noupgrade; -extern PMList *pmo_ignorepkg; -extern unsigned short pmo_nopassiveftp; - -extern PMList *pmc_syncs; -extern PMList *pm_targets; - -/* borrowed and modifed from Per Liden's pkgutils (http://crux.nu) */ -static int gzopen_frontend(char *pathname, int oflags, int mode) +/* borrowed and modified from Per Liden's pkgutils (http://crux.nu) */ +int gzopen_frontend(char *pathname, int oflags, int mode) { char* gzoflags; int fd; @@ -102,17 +66,16 @@ static int gzopen_frontend(char *pathname, int oflags, int mode) return (int)gzf; } -tartype_t gztype = { - (openfunc_t) gzopen_frontend, - (closefunc_t)gzclose, - (readfunc_t) gzread, - (writefunc_t)gzwrite -}; - int unpack(char *archive, char *prefix) { TAR *tar = NULL; char expath[PATH_MAX]; + tartype_t gztype = { + (openfunc_t) gzopen_frontend, + (closefunc_t)gzclose, + (readfunc_t) gzread, + (writefunc_t)gzwrite + }; /* open the .tar.gz package */ if(tar_open(&tar, archive, &gztype, O_RDONLY, 0, TAR_GNU) == -1) { @@ -130,280 +93,6 @@ int unpack(char *archive, char *prefix) return(0); } -/* Parse command-line arguments for each operation - * op: the operation code requested - * argc: argc - * argv: argv - * - * Returns: 0 on success, 1 on error - */ -int parseargs(int op, int argc, char **argv) -{ - int opt; - int option_index = 0; - static struct option opts[] = - { - {"add", no_argument, 0, 'A'}, - {"remove", no_argument, 0, 'R'}, - {"upgrade", no_argument, 0, 'U'}, - {"freshen", no_argument, 0, 'F'}, - {"query", no_argument, 0, 'Q'}, - {"sync", no_argument, 0, 'S'}, - {"deptest", no_argument, 0, 'T'}, - {"vertest", no_argument, 0, 'Y'}, - {"resolve", no_argument, 0, 'D'}, - {"root", required_argument, 0, 'r'}, - {"verbose", no_argument, 0, 'v'}, - {"version", no_argument, 0, 'V'}, - {"help", no_argument, 0, 'h'}, - {"search", no_argument, 0, 's'}, - {"clean", no_argument, 0, 'c'}, - {"force", no_argument, 0, 'f'}, - {"nodeps", no_argument, 0, 'd'}, - {"nosave", no_argument, 0, 'n'}, - {"owns", no_argument, 0, 'o'}, - {"list", no_argument, 0, 'l'}, - {"file", no_argument, 0, 'p'}, - {"info", no_argument, 0, 'i'}, - {"sysupgrade", no_argument, 0, 'u'}, - {"downloadonly", no_argument, 0, 'w'}, - {"refresh", no_argument, 0, 'y'}, - {"cascade", no_argument, 0, 'c'}, - {0, 0, 0, 0} - }; - - while((opt = getopt_long(argc, argv, "ARUFQSTDYr:vhscVfnoldpiuwy", opts, &option_index))) { - if(opt < 0) { - break; - } - switch(opt) { - case 0: break; - case 'A': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_ADD); break; - case 'R': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_REMOVE); break; - case 'U': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); break; - case 'F': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_UPGRADE); pmo_freshen = 1; break; - case 'Q': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_QUERY); break; - case 'S': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_SYNC); break; - case 'T': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); break; - case 'Y': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_vertest = 1; break; - case 'D': pmo_op = (pmo_op != PM_MAIN ? 0 : PM_DEPTEST); pmo_d_resolve = 1; break; - case 'h': pmo_help = 1; break; - case 'V': pmo_version = 1; break; - case 'v': pmo_verbose = 1; break; - case 'f': pmo_force = 1; break; - case 'd': pmo_nodeps = 1; break; - case 'n': pmo_nosave = 1; break; - case 'l': pmo_q_list = 1; break; - case 'p': pmo_q_isfile = 1; break; - case 'i': pmo_q_info = 1; break; - case 'o': pmo_q_owns = 1; break; - case 'u': pmo_s_upgrade = 1; break; - case 'w': pmo_s_downloadonly = 1; break; - case 'y': pmo_s_sync = 1; break; - case 's': pmo_s_search = 1; break; - case 'c': pmo_s_clean = 1; pmo_r_cascade = 1; break; - case 'r': if(realpath(optarg, pmo_root) == NULL) { - perror("bad root path"); - return(1); - } break; - case '?': return(1); - default: return(1); - } - } - - if(pmo_op == 0) { - fprintf(stderr, "error: only one operation may be used at a time\n\n"); - return(1); - } - - if(pmo_help) { - usage(pmo_op, (char*)basename(argv[0])); - return(2); - } - if(pmo_version) { - version(); - return(2); - } - - while(optind < argc) { - /* add the target to our target array */ - char *s = strdup(argv[optind]); - pm_targets = list_add(pm_targets, s); - optind++; - } - - return(0); -} - -#define min(X, Y) ((X) < (Y) ? (X) : (Y)) -int parseconfig(char *configfile) -{ - FILE *fp = NULL; - char line[PATH_MAX+1]; - char *ptr = NULL; - char *key = NULL; - int linenum = 0; - char section[256] = ""; - sync_t *sync = NULL; - - if((fp = fopen(configfile, "r")) == NULL) { - perror(configfile); - return(1); - } - - while(fgets(line, PATH_MAX, fp)) { - linenum++; - trim(line); - if(strlen(line) == 0 || line[0] == '#') { - continue; - } - if(line[0] == '[' && line[strlen(line)-1] == ']') { - /* new config section */ - ptr = line; - ptr++; - strncpy(section, ptr, min(255, strlen(ptr)-1)); - section[min(255, strlen(ptr)-1)] = '\0'; - vprint("config: new section '%s'\n", section); - if(!strlen(section)) { - fprintf(stderr, "config: line %d: bad section name\n", linenum); - return(1); - } - if(!strcmp(section, "local")) { - fprintf(stderr, "config: line %d: %s is reserved and cannot be used as a package tree\n", - linenum, section); - return(1); - } - if(strcmp(section, "options")) { - /* start a new sync record */ - MALLOC(sync, sizeof(sync_t)); - sync->treename = strdup(section); - sync->servers = NULL; - pmc_syncs = list_add(pmc_syncs, sync); - } - } else { - /* directive */ - if(!strlen(section)) { - fprintf(stderr, "config: line %d: all directives must belong to a section\n", linenum); - return(1); - } - ptr = line; - key = strsep(&ptr, "="); - if(key == NULL) { - fprintf(stderr, "config: line %d: syntax error\n", linenum); - return(1); - } - trim(key); - key = strtoupper(key); - if(ptr == NULL) { - if(!strcmp(key, "NOPASSIVEFTP")) { - pmo_nopassiveftp = 1; - vprint("config: nopassiveftp\n"); - } else { - fprintf(stderr, "config: line %d: syntax error\n", linenum); - return(1); - } - } else { - trim(ptr); - if(!strcmp(section, "options")) { - if(!strcmp(key, "NOUPGRADE")) { - char *p = ptr; - char *q; - while((q = strchr(p, ' '))) { - *q = '\0'; - pmo_noupgrade = list_add(pmo_noupgrade, strdup(p)); - vprint("config: noupgrade: %s\n", p); - p = q; - p++; - } - pmo_noupgrade = list_add(pmo_noupgrade, strdup(p)); - vprint("config: noupgrade: %s\n", p); - } else if(!strcmp(key, "IGNOREPKG")) { - char *p = ptr; - char *q; - while((q = strchr(p, ' '))) { - *q = '\0'; - pmo_ignorepkg = list_add(pmo_ignorepkg, strdup(p)); - vprint("config: ignorepkg: %s\n", p); - p = q; - p++; - } - pmo_ignorepkg = list_add(pmo_ignorepkg, strdup(p)); - vprint("config: ignorepkg: %s\n", p); - } else { - fprintf(stderr, "config: line %d: syntax error\n", linenum); - return(1); - } - } else { - if(!strcmp(key, "SERVER")) { - /* parse our special url */ - server_t *server; - char *p; - - MALLOC(server, sizeof(server_t)); - server->server = server->path = NULL; - server->islocal = 0; - - p = strstr(ptr, "://"); - if(p == NULL) { - fprintf(stderr, "config: line %d: bad server location\n", linenum); - return(1); - } - *p = '\0'; - p++; p++; p++; - if(p == NULL || *p == '\0') { - fprintf(stderr, "config: line %d: bad server location\n", linenum); - return(1); - } - server->islocal = !strcmp(ptr, "local"); - if(!server->islocal) { - char *slash; - /* no http support yet */ - if(strcmp(ptr, "ftp")) { - fprintf(stderr, "config: line %d: protocol %s is not supported\n", linenum, ptr); - return(1); - } - /* split the url into domain and path */ - slash = strchr(p, '/'); - if(slash == NULL) { - /* no path included, default to / */ - server->path = strdup("/"); - } else { - /* add a trailing slash if we need to */ - if(slash[strlen(slash)-1] == '/') { - server->path = strdup(slash); - } else { - MALLOC(server->path, strlen(slash)+2); - sprintf(server->path, "%s/", slash); - } - *slash = '\0'; - } - server->server = strdup(p); - } else { - /* add a trailing slash if we need to */ - if(p[strlen(p)-1] == '/') { - server->path = strdup(p); - } else { - MALLOC(server->path, strlen(p)+2); - sprintf(server->path, "%s/", p); - } - } - /* add to the list */ - vprint("config: %s: server: %s %s\n", section, server->server, server->path); - sync->servers = list_add(sync->servers, server); - } else { - fprintf(stderr, "config: line %d: syntax error\n", linenum); - return(1); - } - } - line[0] = '\0'; - } - } - } - fclose(fp); - - return(0); -} - int copyfile(char *src, char *dest) { FILE *in, *out; @@ -501,94 +190,6 @@ int rmrf(char *path) return(0); } -/* Display usage/syntax for the specified operation. - * op: the operation code requested - * myname: basename(argv[0]) - */ -void usage(int op, char *myname) -{ - if(op == PM_MAIN) { - printf("usage: %s {-h --help}\n", myname); - printf(" %s {-V --version}\n", myname); - printf(" %s {-A --add} [options] <file>\n", myname); - printf(" %s {-R --remove} [options] <package>\n", myname); - printf(" %s {-U --upgrade} [options] <file>\n", myname); - printf(" %s {-F --freshen} [options] <file>\n", myname); - printf(" %s {-Q --query} [options] [package]\n", myname); - printf(" %s {-S --sync} [options] [package]\n", myname); - printf("\nuse '%s --help' with other options for more syntax\n\n", myname); - } else { - if(op == PM_ADD) { - printf("usage: %s {-A --add} [options] <file>\n", myname); - printf("options:\n"); - printf(" -f, --force force install, overwrite conflicting files\n"); - printf(" -d, --nodeps skip dependency checks\n"); - } else if(op == PM_REMOVE) { - printf("usage: %s {-R --remove} [options] <package>\n", myname); - printf("options:\n"); - printf(" -d, --nodeps skip dependency checks\n"); - printf(" -n, --nosave remove configuration files as well\n"); - printf(" -c, --cascade remove packages and all packages that depend on them\n"); - } else if(op == PM_UPGRADE) { - if(pmo_freshen) { - printf("usage: %s {-F --freshen} [options] <file>\n", myname); - } else { - printf("usage: %s {-U --upgrade} [options] <file>\n", myname); - } - printf("options:\n"); - printf(" -f, --force force install, overwrite conflicting files\n"); - printf(" -d, --nodeps skip dependency checks\n"); - } else if(op == PM_QUERY) { - printf("usage: %s {-Q --query} [options] [package]\n", myname); - printf("options:\n"); - printf(" -o, --owns <file> query the package that owns <file>\n"); - printf(" -l, --list list the contents of the queried package\n"); - printf(" -i, --info view package information\n"); - printf(" -p, --file pacman will query the package file [package] instead of\n"); - printf(" looking in the database\n"); - } else if(op == PM_SYNC) { - printf("usage: %s {-S --sync} [options] [package]\n", myname); - printf("options:\n"); - printf(" -s, --search search sync database for matching strings\n"); - printf(" -f, --force force install, overwrite conflicting files\n"); - printf(" -d, --nodeps skip dependency checks\n"); - printf(" -y, --refresh download a fresh package sync database from the server\n"); - printf(" -u, --sysupgrade upgrade all packages that are out of date\n"); - printf(" -w, --downloadonly download packages, but do not install/upgrade anything\n"); - printf(" -c, --clean remove packages from cache directory to free up diskspace\n"); - } - printf(" -v, --verbose be verbose\n"); - printf(" -r, --root <path> set an alternate installation root\n"); - } -} - -/* Version - */ -void version(void) -{ - printf("\n"); - printf(" .--. Pacman v%s\n", PACVER); - printf("/ _.-' .-. .-. .-. Copyright (C) 2002 Judd Vinet <jvinet@zeroflux.org>\n"); - printf("\\ '-. '-' '-' '-' \n"); - printf(" '--' This program may be freely redistributed under\n"); - printf(" the terms of the GNU GPL\n\n"); -} - -/* Check verbosity option and, if set, print the - * string to stdout - */ -int vprint(char *fmt, ...) -{ - va_list args; - if(pmo_verbose) { - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - fflush(stdout); - } - return(0); -} - int yesno(char *fmt, ...) { char response[32]; @@ -651,76 +252,6 @@ void indentprint(char *str, int indent) } } -/* Test for existence of a string in a PMList - */ -int is_in(char *needle, PMList *haystack) -{ - PMList *lp; - - for(lp = haystack; lp; lp = lp->next) { - if(lp->data && !strcmp(lp->data, needle)) { - return(1); - } - } - return(0); -} - - -/* Look for a filename in a pkginfo_t.backup list. If we find it, - * then we return the md5 hash (parsed from the same line) - */ -char* needbackup(char* file, PMList *backup) -{ - PMList *lp; - - /* run through the backup list and parse out the md5 hash for our file */ - for(lp = backup; lp; lp = lp->next) { - char* str = strdup(lp->data); - char* ptr; - - /* tab delimiter */ - ptr = index(str, '\t'); - if(ptr == NULL) { - FREE(str); - continue; - } - *ptr = '\0'; - ptr++; - /* now str points to the filename and ptr points to the md5 hash */ - if(!strcmp(file, str)) { - char *md5 = strdup(ptr); - FREE(str); - return(md5); - } - FREE(str); - } - return(NULL); -} - -/* Test for existence of a package in a PMList* - * of pkginfo_t* - * - * returns: 0 for no match - * 1 for identical match - * -1 for name-only match (version mismatch) - */ -int is_pkgin(pkginfo_t *needle, PMList *haystack) -{ - PMList *lp; - pkginfo_t *info; - - for(lp = haystack; lp; lp = lp->next) { - info = (pkginfo_t*)lp->data; - if(info && !strcmp(info->name, needle->name)) { - if(!strcmp(info->version, needle->version)) { - return(1); - } - return(-1); - } - } - return(0); -} - /* Convert a string to uppercase */ char* strtoupper(char *str) |