diff options
author | Marco S Hyman <marc@cvs.openbsd.org> | 1998-10-13 23:09:55 +0000 |
---|---|---|
committer | Marco S Hyman <marc@cvs.openbsd.org> | 1998-10-13 23:09:55 +0000 |
commit | 5151819038ae07cb40007b9af6f62b7a1233e1f8 (patch) | |
tree | 1da90b6e2032cccea62e8374ca25f7816dcd1948 /usr.sbin/pkg_install | |
parent | eb96b5bdfeaf891a861a757eab37a1348f1a030a (diff) |
Sync with recent NetBSD changes:
- use snprintf in place of sprintf
- code cleanup
- Package -> package_t, PackingList -> plist_t
Also: remove files that haven't been linked in a while
Pass -q to mtree so it is quiet in the presence of symlinks
Diffstat (limited to 'usr.sbin/pkg_install')
27 files changed, 1317 insertions, 1579 deletions
diff --git a/usr.sbin/pkg_install/add/add.h b/usr.sbin/pkg_install/add/add.h index 90c1b947f18..9145b95f4a9 100644 --- a/usr.sbin/pkg_install/add/add.h +++ b/usr.sbin/pkg_install/add/add.h @@ -1,4 +1,4 @@ -/* $OpenBSD: add.h,v 1.2 1998/09/07 22:30:13 marc Exp $ */ +/* $OpenBSD: add.h,v 1.3 1998/10/13 23:09:49 marc Exp $ */ /* from FreeBSD Id: add.h,v 1.8 1997/02/22 16:09:15 peter Exp */ /* @@ -39,7 +39,7 @@ extern char FirstPen[]; extern add_mode_t AddMode; int make_hierarchy(char *); -void extract_plist(char *, Package *); +void extract_plist(char *, package_t *); void apply_perms(char *, char *); #endif /* _INST_ADD_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/add/extract.c b/usr.sbin/pkg_install/add/extract.c index 7e330a860a8..58361664a48 100644 --- a/usr.sbin/pkg_install/add/extract.c +++ b/usr.sbin/pkg_install/add/extract.c @@ -1,7 +1,7 @@ -/* $OpenBSD: extract.c,v 1.6 1998/09/07 22:30:13 marc Exp $ */ +/* $OpenBSD: extract.c,v 1.7 1998/10/13 23:09:49 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: extract.c,v 1.6 1998/09/07 22:30:13 marc Exp $"; +static const char *rcsid = "$OpenBSD: extract.c,v 1.7 1998/10/13 23:09:49 marc Exp $"; #endif /* @@ -33,26 +33,28 @@ static const char *rcsid = "$OpenBSD: extract.c,v 1.6 1998/09/07 22:30:13 marc E #define TOOBIG(str) ((strlen(str) + 22 + strlen(home) + where_count > maxargs) \ || (strlen(str) + 6 + strlen(home) + perm_count > maxargs)) -#define PUSHOUT(todir) /* push out string */ \ - if (where_count > sizeof(STARTSTRING)-1) { \ - strcat(where_args, "|tar xf - -C "); \ - strcat(where_args, todir); \ - if (system(where_args)) \ - cleanup(0), errx(2, "can not invoke %lu byte tar pipeline: %s", \ - (u_long)strlen(where_args), where_args); \ - strcpy(where_args, STARTSTRING); \ - where_count = sizeof(STARTSTRING)-1; \ - } \ - if (perm_count) { \ - if (!isdir(todir)) apply_perms(todir, perm_args); \ - perm_args[0] = 0;\ - perm_count = 0; \ +#define PUSHOUT(todir) /* push out string */ \ + if (where_count > sizeof(STARTSTRING)-1) { \ + strcat(where_args, "|tar xf - -C "); \ + strcat(where_args, todir); \ + if (system(where_args)) { \ + cleanup(0); \ + errx(2, "can not invoke %lu byte tar pipeline: %s", \ + (u_long)strlen(where_args), where_args); \ + } \ + strcpy(where_args, STARTSTRING); \ + where_count = sizeof(STARTSTRING)-1; \ + } \ + if (perm_count) { \ + apply_perms(todir, perm_args); \ + perm_args[0] = 0; \ + perm_count = 0; \ } static void -rollback(char *name, char *home, PackingList start, PackingList stop) +rollback(char *name, char *home, plist_t *start, plist_t *stop) { - PackingList q; + plist_t *q; char try[FILENAME_MAX], bup[FILENAME_MAX], *dir; dir = home; @@ -76,9 +78,9 @@ rollback(char *name, char *home, PackingList start, PackingList stop) } void -extract_plist(char *home, Package *pkg) +extract_plist(char *home, package_t *pkg) { - PackingList p = pkg->head; + plist_t *p = pkg->head; char *last_file; char *where_args, *perm_args, *last_chdir; int maxargs, where_count = 0, perm_count = 0, add_count; @@ -86,12 +88,15 @@ extract_plist(char *home, Package *pkg) maxargs = sysconf(_SC_ARG_MAX) / 2; /* Just use half the argument space */ where_args = alloca(maxargs); - if (!where_args) - cleanup(0), errx(2, "can't get argument list space"); + if (!where_args) { + cleanup(0); + errx(2, "can't get argument list space"); + } perm_args = alloca(maxargs); - if (!perm_args) - cleanup(0), errx(2, "can't get argument list space"); - + if (!perm_args) { + cleanup(0); + errx(2, "can't get argument list space"); + } strcpy(where_args, STARTSTRING); where_count = sizeof(STARTSTRING)-1; perm_args[0] = 0; @@ -124,8 +129,10 @@ extract_plist(char *home, Package *pkg) if (!Fake) { char try[FILENAME_MAX]; - if (strrchr(p->name,'\'')) - cleanup(0), errx(2, "Bogus filename \"%s\"", p->name); + if (strrchr(p->name,'\'')) { + cleanup(0); + errx(2, "Bogus filename \"%s\"", p->name); + } /* first try to rename it into place */ snprintf(try, FILENAME_MAX, "%s/%s", Directory, p->name); @@ -151,11 +158,12 @@ extract_plist(char *home, Package *pkg) PUSHOUT(Directory); } add_count = snprintf(&perm_args[perm_count], maxargs - perm_count, "'%s' ", p->name); - if (add_count > maxargs - perm_count) - cleanup(0), errx(2, "oops, miscounted strings!"); + if (add_count > maxargs - perm_count) { + cleanup(0); + errx(2, "oops, miscounted strings!"); + } perm_count += add_count; - } - else { + } else { /* rename failed, try copying with a big tar command */ if (last_chdir != Directory) { PUSHOUT(last_chdir); @@ -165,14 +173,18 @@ extract_plist(char *home, Package *pkg) PUSHOUT(Directory); } add_count = snprintf(&where_args[where_count], maxargs - where_count, " '%s'", p->name); - if (add_count > maxargs - where_count) - cleanup(0), errx(2, "oops, miscounted strings!"); + if (add_count > maxargs - where_count) { + cleanup(0); + errx(2, "oops, miscounted strings!"); + } where_count += add_count; add_count = snprintf(&perm_args[perm_count], maxargs - perm_count, "'%s' ", p->name); - if (add_count > maxargs - perm_count) - cleanup(0), errx(2, "oops, miscounted strings!"); + if (add_count > maxargs - perm_count) { + cleanup(0); + errx(2, "oops, miscounted strings!"); + } perm_count += add_count; } } @@ -183,20 +195,21 @@ extract_plist(char *home, Package *pkg) printf("extract: CWD to %s\n", p->name); PUSHOUT(Directory); if (strcmp(p->name, ".")) { - if (!Fake && make_hierarchy(p->name) == FAIL) - cleanup(0), errx(2, "unable to make directory '%s'", - p->name); + if (!Fake && make_hierarchy(p->name) == FAIL) { + cleanup(0); + errx(2, "unable to make directory '%s'", p->name); + } Directory = p->name; - } - else + } else Directory = home; break; case PLIST_CMD: - if (last_file == NULL) - cleanup(0), errx(2, "no last file specified for '%s' command", - p->name); - format_cmd(cmd, p->name, Directory, last_file); + if (last_file == NULL) { + cleanup(0); + errx(2, "no last file specified for '%s' command", p->name); + } + format_cmd(cmd, sizeof(cmd), p->name, Directory, last_file); PUSHOUT(Directory); if (Verbose) printf("extract: execute '%s'\n", cmd); diff --git a/usr.sbin/pkg_install/add/main.c b/usr.sbin/pkg_install/add/main.c index 9ee9284d359..42f8d2d20f6 100644 --- a/usr.sbin/pkg_install/add/main.c +++ b/usr.sbin/pkg_install/add/main.c @@ -1,7 +1,7 @@ -/* $OpenBSD: main.c,v 1.8 1998/09/07 22:30:13 marc Exp $ */ +/* $OpenBSD: main.c,v 1.9 1998/10/13 23:09:49 marc Exp $ */ #ifndef lint -static char *rcsid = "$OpenBSD: main.c,v 1.8 1998/09/07 22:30:13 marc Exp $"; +static char *rcsid = "$OpenBSD: main.c,v 1.9 1998/10/13 23:09:49 marc Exp $"; #endif /* @@ -122,9 +122,19 @@ main(int argc, char **argv) else if (isURL(*argv)) /* preserve URLs */ pkgs[ch] = strcpy(pkgnames[ch], *argv); else { /* expand all pathnames to fullnames */ + char *s; + if (fexists(*argv)) /* refers to a file directly */ pkgs[ch] = realpath(*argv, pkgnames[ch]); - else { /* look for the file in the expected places */ + else if (ispkgpattern(*argv) + && (s=findbestmatchingname(dirname_of(*argv), + basename_of(*argv))) > 0) { + if (Verbose) + printf("Using %s for %s\n",s, *argv); + + pkgs[ch] = realpath(s, pkgnames[ch]); + } else { + /* look for the file(pattern) in the expected places */ if (!(cp = fileFindByPath(NULL, *argv))) warnx("can't find package '%s'", *argv); else diff --git a/usr.sbin/pkg_install/add/perform.c b/usr.sbin/pkg_install/add/perform.c index e654ef1db4a..92171970390 100644 --- a/usr.sbin/pkg_install/add/perform.c +++ b/usr.sbin/pkg_install/add/perform.c @@ -1,7 +1,7 @@ -/* $OpenBSD: perform.c,v 1.5 1998/09/07 22:30:13 marc Exp $ */ +/* $OpenBSD: perform.c,v 1.6 1998/10/13 23:09:49 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: perform.c,v 1.5 1998/09/07 22:30:13 marc Exp $"; +static const char *rcsid = "$OpenBSD: perform.c,v 1.6 1998/10/13 23:09:49 marc Exp $"; #endif /* @@ -53,9 +53,18 @@ pkg_perform(char **pkgs) return err_cnt; } -static Package Plist; +static package_t Plist; static char *Home; +/* called to see if pkg is already installed as some other version */ +/* note found version in "note" */ +static int +check_if_installed(const char *found, char *note) +{ + strcpy(note, found); + return 0; +} + /* * This is seriously ugly code following. Written very fast! * [And subsequently made even worse.. Sigh! This code was just born @@ -68,9 +77,10 @@ pkg_do(char *pkg) char playpen[FILENAME_MAX]; char extract_contents[FILENAME_MAX]; char *where_to, *tmp, *extract; + char *dbdir; FILE *cfile; int code; - PackingList p; + plist_t *p; struct stat sb; int inPlace; @@ -79,8 +89,10 @@ pkg_do(char *pkg) LogDir[0] = '\0'; strcpy(playpen, FirstPen); inPlace = 0; + dbdir = (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR; /* Are we coming in for a second pass, everything already extracted? */ + /* (Slave mode) */ if (!pkg) { fgets(playpen, FILENAME_MAX, stdin); playpen[strlen(playpen) - 1] = '\0'; /* pesky newline! */ @@ -95,6 +107,13 @@ pkg_do(char *pkg) else { /* Is it an ftp://foo.bar.baz/file.tgz specification? */ if (isURL(pkg)) { + if (ispkgpattern(pkg)) { + warnx("patterns not allowed in URLs, " + "please install manually!"); + /* ... until we come up with a better solution :-/ - HF */ + goto bomb; + } + if (!(Home = fileGetURL(NULL, pkg))) { warnx("unable to fetch `%s' by URL", pkg); return 1; @@ -110,18 +129,20 @@ pkg_do(char *pkg) } read_plist(&Plist, cfile); fclose(cfile); - } - else { + } else { strcpy(pkg_fullname, pkg); /* copy for sanity's sake, could remove pkg_fullname */ if (strcmp(pkg, "-")) { - if (stat(pkg_fullname, &sb) == FAIL) { + if (!ispkgpattern(pkg_fullname) + && stat(pkg_fullname, &sb) == FAIL) { warnx("can't stat package file '%s'", pkg_fullname); goto bomb; } #if 0 - sprintf(extract_contents, "--fast-read %s", CONTENTS_FNAME); + snprintf(extract_contents, sizeof( extract_comments ), + "--fast-read %s", CONTENTS_FNAME); #else - sprintf(extract_contents, "%s", CONTENTS_FNAME); + snprintf(extract_contents, sizeof( extract_contents ), + "%s", CONTENTS_FNAME); #endif extract = extract_contents; } @@ -129,7 +150,7 @@ pkg_do(char *pkg) extract = NULL; sb.st_size = 100000; /* Make up a plausible average size */ } - Home = make_playpen(playpen, sb.st_size * 4); + Home = make_playpen(playpen, sizeof(playpen), sb.st_size * 4); if (!Home) warnx("unable to make playpen for %ld bytes", (long)(sb.st_size * 4)); @@ -160,10 +181,10 @@ pkg_do(char *pkg) if (Verbose) printf("Desired prefix of %s does not exist, creating.\n", p->name); vsystem("mkdir -p %s", p->name); - if (chdir(p->name) == -1) { - warn("unable to change directory to `%s'", p->name); - goto bomb; - } + } + if (chdir(p->name) == -1) { + warn("unable to change directory to `%s'", p->name); + goto bomb; } where_to = p->name; inPlace = 1; @@ -185,10 +206,10 @@ pkg_do(char *pkg) */ if (!extract && !inPlace && min_free(playpen) < sb.st_size * 4) { - warnx("projected size of %d exceeds available free space.\n" + warnx("projected size of %ld exceeds available free space.\n" "Please set your PKG_TMPDIR variable to point to a" "location with more\n" - "free space and try again", sb.st_size * 4); + "free space and try again", (long)(sb.st_size * 4)); warnx("not extracting %s\ninto %s, sorry!", pkg_fullname, where_to); goto bomb; @@ -204,7 +225,7 @@ pkg_do(char *pkg) warnx("unable to extract `%s'!", pkg_fullname); goto bomb; } - } + } /* isURL(pkg) */ /* Check for sanity and dependencies */ if (sanity_check(pkg)) @@ -232,36 +253,65 @@ pkg_do(char *pkg) PkgName = (p = find_plist(&Plist, PLIST_NAME)) ? p->name : "anonymous"; /* See if we're already registered */ - sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, PkgName); + (void) snprintf(LogDir, sizeof(LogDir), "%s/%s", dbdir, PkgName); if ((isdir(LogDir) || islinktodir(LogDir)) && !Force) { warnx("package `%s' already recorded as installed", PkgName); code = 1; goto success; /* close enough for government work */ } + /* See if some other version of us is already installed */ + { + char buf[FILENAME_MAX]; + char installed[FILENAME_MAX]; + char *s; + + if ((s=strrchr(PkgName, '-')) != NULL){ + strcpy(buf, PkgName); + buf[s-PkgName+1]='*'; + buf[s-PkgName+2]='\0'; + + if (findmatchingname(dbdir, buf, check_if_installed, installed)) { + warnx("other version '%s' already installed", installed); + code = 1; + goto success; /* close enough for government work */ + } + } + } + /* See if there are conflicting packages installed */ for (p = Plist.head; p ; p = p->next) { + char installed[FILENAME_MAX]; + if (p->type != PLIST_PKGCFL) continue; if (Verbose) printf("Package `%s' conflicts with `%s'.\n", PkgName, p->name); - if (!vsystem("/usr/sbin/pkg_info -qe '%s'", p->name)) { - warnx("Conflicting package `%s' installed, please use pkg_delete(1)\n\t first to remove it!\n", p->name); + + /* was: */ + /* if (!vsystem("/usr/sbin/pkg_info -qe '%s'", p->name)) {*/ + if(findmatchingname(dbdir, p->name, check_if_installed, installed)){ + warnx("Conflicting package installed, please use\n\t\"pkg_delete %s\" first to remove it!\n", installed); ++code; } } /* Now check the packing list for dependencies */ for (p = Plist.head; p ; p = p->next) { + char installed [FILENAME_MAX]; + if (p->type != PLIST_PKGDEP) continue; if (Verbose) printf("Package `%s' depends on `%s'.\n", PkgName, p->name); - if (vsystem("/usr/sbin/pkg_info -qe '%s'", p->name)) { + /* if (vsystem("/usr/sbin/pkg_info -qe '%s'", p->name)) { */ + if (!findmatchingname(dbdir, p->name, check_if_installed, installed)) { char path[FILENAME_MAX], *cp = NULL; if (!Fake) { if (!isURL(pkg) && !getenv("PKG_ADD_BASE")) { + /* install depending pkg from local disk */ + snprintf(path, FILENAME_MAX, "%s/%s.tgz", Home, p->name); if (fexists(path)) cp = path; @@ -280,38 +330,55 @@ pkg_do(char *pkg) ++code; } } - else - warnx("add of dependency `%s' failed%s", - p->name, Force ? " (proceeding anyway)" : "!"); - if (!Force) - ++code; - } - else if ((cp = fileGetURL(pkg, p->name)) != NULL) { - if (Verbose) - printf("Finished loading %s over FTP.\n", p->name); - if (!fexists(CONTENTS_FNAME)) { - warnx("autoloaded package %s has no %s file?", - p->name, CONTENTS_FNAME); - if (!Force) - ++code; - } - else if (vsystem("(pwd; cat %s) | pkg_add %s%s %s-S", - CONTENTS_FNAME, - Prefix ? "-p " : "", - Prefix ? Prefix : "", - Verbose ? "-v " : "")) { + else { warnx("add of dependency `%s' failed%s", p->name, Force ? " (proceeding anyway)" : "!"); - if (!Force) - ++code; + if (!Force) + ++code; + } + } else { + /* install depending pkg via FTP */ + + if (ispkgpattern(p->name)){ + warnx("can't install dependent pkg '%s' via FTP, " + "please install manually!", p->name); + /* ... until we come up with a better solution - HF */ + goto bomb; + }else{ + char *saved_Current; /* allocated/set by save_dirs(), */ + char *saved_Previous; /* freed by restore_dirs() */ + + save_dirs(&saved_Current, &saved_Previous); + + if ((cp = fileGetURL(pkg, p->name)) != NULL) { + if (Verbose) + printf("Finished loading %s over FTP.\n", p->name); + if (!fexists(CONTENTS_FNAME)) { + warnx("autoloaded package %s has no %s file?", + p->name, CONTENTS_FNAME); + if (!Force) + ++code; + } + else if (vsystem("(pwd; cat %s) | pkg_add %s%s %s-S", + CONTENTS_FNAME, + Prefix ? "-p " : "", + Prefix ? Prefix : "", + Verbose ? "-v " : "")) { + warnx("add of dependency `%s' failed%s", + p->name, Force ? " (proceeding anyway)" : "!"); + if (!Force) + ++code; + } + else if (Verbose) + printf("\t`%s' loaded successfully.\n", p->name); + /* Nuke the temporary playpen */ + leave_playpen(cp); + + restore_dirs(saved_Current, saved_Previous); } - else if (Verbose) - printf("\t`%s' loaded successfully.\n", p->name); - /* Nuke the temporary playpen */ - leave_playpen(cp); } } - else { + } else { if (Verbose) printf("and was not found%s.\n", Force ? " (proceeding anyway)" : ""); else @@ -322,7 +389,7 @@ pkg_do(char *pkg) } } else if (Verbose) - printf(" - already installed.\n"); + printf(" - %s already installed.\n", installed); } if (code != 0) @@ -365,9 +432,12 @@ pkg_do(char *pkg) printf("Running mtree for %s.\n", PkgName); p = find_plist(&Plist, PLIST_CWD); if (Verbose) - printf("mtree -U -f %s -d -e -p %s\n", MTREE_FNAME, p ? p->name : "/"); + printf("mtree -q -U -f %s -d -e -p %s\n", MTREE_FNAME, + p ? p->name : "/"); if (!Fake) { - if (vsystem("/usr/sbin/mtree -U -f %s -d -e -p %s", MTREE_FNAME, p ? p->name : "/")) + + if (vsystem("/usr/sbin/mtree -q -U -f %s -d -e -p %s", MTREE_FNAME, + p ? p->name : "/")) warnx("mtree returned a non-zero status - continuing"); } unlink(MTREE_FNAME); @@ -399,7 +469,7 @@ pkg_do(char *pkg) code = 1; goto success; /* well, partial anyway */ } - sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, PkgName); + (void) snprintf(LogDir, sizeof(LogDir), "%s/%s", dbdir, PkgName); zapLogDir = 1; if (Verbose) printf("Attempting to record package into %s.\n", LogDir); @@ -416,7 +486,7 @@ pkg_do(char *pkg) move_file(".", DEINSTALL_FNAME, LogDir); if (fexists(REQUIRE_FNAME)) move_file(".", REQUIRE_FNAME, LogDir); - sprintf(contents, "%s/%s", LogDir, CONTENTS_FNAME); + (void) snprintf(contents, sizeof(contents), "%s/%s", LogDir, CONTENTS_FNAME); cfile = fopen(contents, "w"); if (!cfile) { warnx("can't open new contents file '%s'! can't register pkg", @@ -429,13 +499,34 @@ pkg_do(char *pkg) move_file(".", COMMENT_FNAME, LogDir); if (fexists(DISPLAY_FNAME)) move_file(".", DISPLAY_FNAME, LogDir); + + /* register dependencies */ + /* we could save some cycles here if we remembered what we installed + * above (in case we got a wildcard dependency) */ + /* XXX remembering in p->name would NOT be good! */ for (p = Plist.head; p ; p = p->next) { if (p->type != PLIST_PKGDEP) continue; if (Verbose) printf("Attempting to record dependency on package `%s'\n", p->name); - sprintf(contents, "%s/%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, - basename_of(p->name), REQUIRED_BY_FNAME); + (void) snprintf(contents, sizeof(contents), "%s/%s", dbdir, + basename_of(p->name)); + if (ispkgpattern(p->name)) { + char *s; + s=findbestmatchingname(dirname_of(contents), + basename_of(contents)); + if (s != NULL) { + char *t; + t=strrchr(contents, '/'); + strcpy(t+1, s); + }else{ + errx(1,"Where did our dependency go?!"); + /* this shouldn't happen... X-) */ + } + } + strcat(contents, "/"); + strcat(contents, REQUIRED_BY_FNAME); + cfile = fopen(contents, "a"); if (!cfile) warnx("can't open dependency file '%s'!\n" @@ -463,7 +554,7 @@ pkg_do(char *pkg) putc('\n', stdout); (void) fclose(fp); } else - warn("cannot open %s as display file", buf); + warnx("cannot open %s as display file", buf); } goto success; diff --git a/usr.sbin/pkg_install/create/create.h b/usr.sbin/pkg_install/create/create.h index 303442fb0e0..60ab22286ee 100644 --- a/usr.sbin/pkg_install/create/create.h +++ b/usr.sbin/pkg_install/create/create.h @@ -1,4 +1,4 @@ -/* $OpenBSD: create.h,v 1.2 1998/09/07 22:30:14 marc Exp $ */ +/* $OpenBSD: create.h,v 1.3 1998/10/13 23:09:50 marc Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -37,11 +37,12 @@ extern char *Mtree; extern char *Pkgdeps; extern char *Pkgcfl; extern char PlayPen[]; +extern size_t PlayPenSize; extern int Dereference; extern int PlistOnly; -void check_list(char *, Package *); +void check_list(char *, package_t *); int pkg_perform(char **); -void copy_plist(char *, Package *); +void copy_plist(char *, package_t *); #endif /* _INST_CREATE_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/create/main.c b/usr.sbin/pkg_install/create/main.c index e11f7dc1638..c8d01e741f7 100644 --- a/usr.sbin/pkg_install/create/main.c +++ b/usr.sbin/pkg_install/create/main.c @@ -1,7 +1,7 @@ -/* $OpenBSD: main.c,v 1.7 1998/09/07 22:30:14 marc Exp $ */ +/* $OpenBSD: main.c,v 1.8 1998/10/13 23:09:50 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: main.c,v 1.7 1998/09/07 22:30:14 marc Exp $"; +static const char *rcsid = "$OpenBSD: main.c,v 1.8 1998/10/13 23:09:50 marc Exp $"; #endif /* @@ -19,10 +19,10 @@ static const char *rcsid = "$OpenBSD: main.c,v 1.7 1998/09/07 22:30:14 marc Exp #include "lib.h" #include "create.h" -static char Options[] = "YNOhvf:p:P:C:c:d:i:k:r:t:X:D:m:s:"; +static char Options[] = "Ohvf:p:P:C:c:d:i:k:r:t:X:D:m:s:"; char *Prefix = NULL; -char *Comment = NULL; +char *Comment = NULL; char *Desc = NULL; char *SrcDir = NULL; char *Display = NULL; @@ -35,6 +35,7 @@ char *Mtree = NULL; char *Pkgdeps = NULL; char *Pkgcfl = NULL; char PlayPen[FILENAME_MAX]; +size_t PlayPenSize = sizeof(PlayPen); int Dereference = 0; int PlistOnly = 0; @@ -53,14 +54,6 @@ main(int argc, char **argv) Verbose = TRUE; break; - case 'N': - AutoAnswer = NO; - break; - - case 'Y': - AutoAnswer = YES; - break; - case 'O': PlistOnly = YES; break; @@ -162,7 +155,7 @@ static void usage() { fprintf(stderr, "%s\n%s\n%s\n%s\n", -"usage: pkg_create [-YNOhv] [-P dpkgs] [-C cpkgs] [-p prefix] [-f contents]", +"usage: pkg_create [-Ohv] [-P dpkgs] [-C cpkgs] [-p prefix] [-f contents]", " [-i iscript] [-k dscript] [-r rscript] [-t template]", " [-X excludefile] [-D displayfile] [-m mtreefile]", " -c comment -d description -f packlist pkg-name"); diff --git a/usr.sbin/pkg_install/create/perform.c b/usr.sbin/pkg_install/create/perform.c index 53aaf2ca084..2d21c427288 100644 --- a/usr.sbin/pkg_install/create/perform.c +++ b/usr.sbin/pkg_install/create/perform.c @@ -1,7 +1,7 @@ -/* $OpenBSD: perform.c,v 1.5 1998/09/07 22:30:14 marc Exp $ */ +/* $OpenBSD: perform.c,v 1.6 1998/10/13 23:09:50 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: perform.c,v 1.5 1998/09/07 22:30:14 marc Exp $"; +static const char *rcsid = "$OpenBSD: perform.c,v 1.6 1998/10/13 23:09:50 marc Exp $"; #endif /* @@ -34,7 +34,7 @@ static const char *rcsid = "$OpenBSD: perform.c,v 1.5 1998/09/07 22:30:14 marc E #include <unistd.h> static void sanity_check(void); -static void make_dist(char *, char *, char *, Package *); +static void make_dist(char *, char *, char *, package_t *); static char *home; @@ -44,7 +44,7 @@ pkg_perform(char **pkgs) char *pkg = *pkgs; /* Only one arg to create */ char *cp; FILE *pkg_in, *fp; - Package plist; + package_t plist; char *suffix; /* What we tack on to the end of the finished package */ /* Preliminary setup */ @@ -57,9 +57,10 @@ pkg_perform(char **pkgs) pkg_in = stdin; else { pkg_in = fopen(Contents, "r"); - if (!pkg_in) - cleanup(0), errx(2, "unable to open contents file '%s' for input", - Contents); + if (!pkg_in) { + cleanup(0); + errx(2, "unable to open contents file '%s' for input", Contents); + } } plist.head = plist.tail = NULL; @@ -136,7 +137,7 @@ pkg_perform(char **pkgs) } /* Make a directory to stomp around in */ - home = make_playpen(PlayPen, 0); + home = make_playpen(PlayPen, PlayPenSize, 0); signal(SIGINT, cleanup); signal(SIGHUP, cleanup); @@ -186,11 +187,15 @@ pkg_perform(char **pkgs) /* Finally, write out the packing list */ fp = fopen(CONTENTS_FNAME, "w"); - if (!fp) - cleanup(0), errx(2, "can't open file %s for writing", CONTENTS_FNAME); + if (!fp) { + cleanup(0); + errx(2, "can't open file %s for writing", CONTENTS_FNAME); + } write_plist(&plist, fp); - if (fclose(fp)) - cleanup(0), errx(2, "error while closing %s", CONTENTS_FNAME); + if (fclose(fp)) { + cleanup(0); + errx(2, "error while closing %s", CONTENTS_FNAME); + } /* And stick it into a tar ball */ make_dist(home, pkg, suffix, &plist); @@ -204,10 +209,10 @@ pkg_perform(char **pkgs) } static void -make_dist(char *home, char *pkg, char *suffix, Package *plist) +make_dist(char *home, char *pkg, char *suffix, package_t *plist) { char tball[FILENAME_MAX]; - PackingList p; + plist_t *p; int ret; #define DIST_MAX_ARGS 4096 char *args[DIST_MAX_ARGS]; /* Much more than enough. */ @@ -283,22 +288,27 @@ make_dist(char *home, char *pkg, char *suffix, Package *plist) } wait(&ret); /* assume either signal or bad exit is enough for us */ - if (ret) - cleanup(0), errx(2, "tar command failed with code %d", ret); + if (ret) { + cleanup(0); + errx(2, "tar command failed with code %d", ret); + } } static void sanity_check() { - if (!Comment) - cleanup(0), errx(2, - "required package comment string is missing (-c comment)"); - if (!Desc) - cleanup(0), errx(2, - "required package description string is missing (-d desc)"); - if (!Contents) - cleanup(0), errx(2, - "required package contents list is missing (-f [-]file)"); + if (!Comment) { + cleanup(0); + errx(2, "required package comment string is missing (-c comment)"); + } + if (!Desc) { + cleanup(0); + errx(2, "required package description string is missing (-d desc)"); + } + if (!Contents) { + cleanup(0); + errx(2, "required package contents list is missing (-f [-]file)"); + } } diff --git a/usr.sbin/pkg_install/create/pkg_create.1 b/usr.sbin/pkg_install/create/pkg_create.1 index 7681dc5fd07..a44dd8005a3 100644 --- a/usr.sbin/pkg_install/create/pkg_create.1 +++ b/usr.sbin/pkg_install/create/pkg_create.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pkg_create.1,v 1.4 1998/09/07 22:30:14 marc Exp $ +.\" $OpenBSD: pkg_create.1,v 1.5 1998/10/13 23:09:50 marc Exp $ .\" .\" FreeBSD install - a package for the installation and maintainance .\" of non-core utilities. @@ -32,7 +32,7 @@ .Nd a utility for creating software package distributions .Sh SYNOPSIS .Nm -.Op Fl YNOhv +.Op Fl Ohv .Op Fl P Ar dpkgs .Op Fl C Ar cpkgs .Op Fl p Ar prefix @@ -90,9 +90,8 @@ Assume a default answer of `Yes' for any questions asked. .It Fl N Assume a default answer of `No' for any questions asked. .It Fl O -Go into a `packing list Only' mode. This is a custom hack for the -.Em "FreeBSD Ports Collection" -and is used to do `fake pkg_add' operations when a port is installed. +Go into a `packing list Only' mode. +This is used to do `fake pkg_add' operations when a package is installed. In such cases, it is necessary to know what the final, adjusted packing list will look like. .It Fl v diff --git a/usr.sbin/pkg_install/create/pl.c b/usr.sbin/pkg_install/create/pl.c index a8c4c632d2b..58d956717db 100644 --- a/usr.sbin/pkg_install/create/pl.c +++ b/usr.sbin/pkg_install/create/pl.c @@ -1,7 +1,7 @@ -/* $OpenBSD: pl.c,v 1.4 1998/09/07 22:30:14 marc Exp $ */ +/* $OpenBSD: pl.c,v 1.5 1998/10/13 23:09:50 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: pl.c,v 1.4 1998/09/07 22:30:14 marc Exp $"; +static const char *rcsid = "$OpenBSD: pl.c,v 1.5 1998/10/13 23:09:50 marc Exp $"; #endif /* @@ -32,66 +32,76 @@ static const char *rcsid = "$OpenBSD: pl.c,v 1.4 1998/09/07 22:30:14 marc Exp $" /* Check a list for files that require preconversion */ void -check_list(char *home, Package *pkg) +check_list(char *home, package_t *pkg) { - char *where = home; - char *there = NULL; - PackingList p = pkg->head; - - while (p) { - if (p->type == PLIST_CWD) - where = p->name; - else if (p->type == PLIST_IGNORE) - p = p->next; - else if (p->type == PLIST_SRC) { - there = p->name; - } - else if (p->type == PLIST_FILE) { - char *cp, name[FILENAME_MAX], buf[33]; - - sprintf(name, "%s/%s", there ? there : where, p->name); - if ((cp = MD5File(name, buf)) != NULL) { - PackingList tmp = new_plist_entry(); - - tmp->name = copy_string(strconcat("MD5:", cp)); - tmp->type = PLIST_COMMENT; - tmp->next = p->next; - tmp->prev = p; - p->next = tmp; - p = tmp; - } + plist_t *tmp; + plist_t *p; + char *cwd = home; + char *there = NULL; + char *cp; + char name[FILENAME_MAX]; + char buf[LegibleChecksumLen]; + + for (p = pkg->head ; p ; p = p->next) { + switch (p->type) { + case PLIST_CWD: + cwd = p->name; + break; + case PLIST_IGNORE: + p = p->next; + break; + case PLIST_SRC: + there = p->name; + break; + case PLIST_FILE: + (void) snprintf(name, sizeof(name), "%s/%s", there ? there : cwd, p->name); + if ((cp = MD5File(name, buf)) != NULL) { + tmp = new_plist_entry(); + tmp->name = copy_string(strconcat("MD5:", cp)); + tmp->type = PLIST_COMMENT; + tmp->next = p->next; + tmp->prev = p; + p->next = tmp; + p = tmp; + } + break; + default: + break; + } } - p = p->next; - } } static int trylink(const char *from, const char *to) { - if (link(from, to) == 0) - return 0; - if (errno == ENOENT) { - /* try making the container directory */ - char *cp = strrchr(to, '/'); - if (cp) - vsystem("mkdir -p %.*s", cp - to, - to); - return link(from, to); - } - return -1; + char *cp; + + if (link(from, to) == 0) { + return 0; + } + if (errno == ENOENT) { + /* try making the container directory */ + if ((cp = strrchr(to, '/')) != (char *) NULL) { + vsystem("mkdir -p %.*s", (size_t)(cp - to), to); + } + return link(from, to); + } + return -1; } #define STARTSTRING "tar cf -" #define TOOBIG(str) strlen(str) + 6 + strlen(home) + where_count > maxargs -#define PUSHOUT() /* push out string */ \ - if (where_count > sizeof(STARTSTRING)-1) { \ - strcat(where_args, "|tar xpf -"); \ - if (system(where_args)) \ - cleanup(0), errx(2, "can't invoke tar pipeline"); \ - memset(where_args, 0, maxargs); \ - last_chdir = NULL; \ - strcpy(where_args, STARTSTRING); \ - where_count = sizeof(STARTSTRING)-1; \ +#define PUSHOUT() /* push out string */ \ + if (where_count > sizeof(STARTSTRING)-1) { \ + strcat(where_args, "|tar xpf -"); \ + if (system(where_args)) { \ + cleanup(0); \ + errx(2, "can't invoke tar pipeline"); \ + } \ + memset(where_args, 0, maxargs); \ + last_chdir = NULL; \ + strcpy(where_args, STARTSTRING); \ + where_count = sizeof(STARTSTRING)-1; \ } /* @@ -99,9 +109,9 @@ trylink(const char *from, const char *to) * have already been copied in an earlier pass through the list. */ void -copy_plist(char *home, Package *plist) +copy_plist(char *home, package_t *plist) { - PackingList p = plist->head; + plist_t *p = plist->head; char *where = home; char *there = NULL, *mythere; char *where_args, *last_chdir, *root = "/"; @@ -113,8 +123,10 @@ copy_plist(char *home, Package *plist) maxargs -= 64; /* some slop for the tar cmd text, and sh -c */ where_args = malloc(maxargs); - if (!where_args) - cleanup(0), errx(2, "can't get argument list space"); + if (!where_args) { + cleanup(0); + errx(2, "can't get argument list space"); + } memset(where_args, 0, maxargs); strcpy(where_args, STARTSTRING); @@ -140,7 +152,7 @@ copy_plist(char *home, Package *plist) /* First, look for it in the "home" dir */ - sprintf(fn, "%s/%s", home, p->name); + (void) snprintf(fn, sizeof(fn), "%s/%s", home, p->name); if (fexists(fn)) { if (lstat(fn, &stb) == 0 && stb.st_dev == curdir && S_ISREG(stb.st_mode)) { @@ -174,8 +186,10 @@ copy_plist(char *home, Package *plist) p->name); last_chdir = home; } - if (add_count > maxargs - where_count) - cleanup(0), errx(2, "oops, miscounted strings!"); + if (add_count > maxargs - where_count) { + cleanup(0); + errx(2, "oops, miscounted strings!"); + } where_count += add_count; } /* @@ -185,7 +199,7 @@ copy_plist(char *home, Package *plist) if (p->name[0] == '/') mythere = root; else mythere = there; - sprintf(fn, "%s/%s", mythere ? mythere : where, p->name); + (void) snprintf(fn, sizeof(fn), "%s/%s", mythere ? mythere : where, p->name); if (lstat(fn, &stb) == 0 && stb.st_dev == curdir && S_ISREG(stb.st_mode)) { /* if we can link it to the playpen, that avoids a copy @@ -208,8 +222,10 @@ copy_plist(char *home, Package *plist) " -C %s %s", mythere ? mythere : where, p->name); - if (add_count > maxargs - where_count) - cleanup(0), errx(2, "oops, miscounted strings!"); + if (add_count > maxargs - where_count) { + cleanup(0); + errx(2, "oops, miscounted strings!"); + } where_count += add_count; last_chdir = (mythere ? mythere : where); } diff --git a/usr.sbin/pkg_install/delete/perform.c b/usr.sbin/pkg_install/delete/perform.c index f973f57e90a..a0003701bb3 100644 --- a/usr.sbin/pkg_install/delete/perform.c +++ b/usr.sbin/pkg_install/delete/perform.c @@ -1,7 +1,7 @@ -/* $OpenBSD: perform.c,v 1.4 1998/09/07 22:30:15 marc Exp $ */ +/* $OpenBSD: perform.c,v 1.5 1998/10/13 23:09:50 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: perform.c,v 1.4 1998/09/07 22:30:15 marc Exp $"; +static const char *rcsid = "$OpenBSD: perform.c,v 1.5 1998/10/13 23:09:50 marc Exp $"; #endif /* @@ -30,7 +30,7 @@ static const char *rcsid = "$OpenBSD: perform.c,v 1.4 1998/09/07 22:30:15 marc E static int pkg_do(char *); static void sanity_check(char *); -static void undepend(PackingList, char *); +static int undepend(const char *, char *); static char LogDir[FILENAME_MAX]; @@ -44,7 +44,7 @@ pkg_perform(char **pkgs) return err_cnt; } -static Package Plist; +static package_t Plist; /* This is seriously ugly code following. Written very fast! */ static int @@ -52,21 +52,23 @@ pkg_do(char *pkg) { FILE *cfile; char home[FILENAME_MAX]; - PackingList p; + plist_t *p; char *tmp; /* Reset some state */ if (Plist.head) free_plist(&Plist); - sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, + (void) snprintf(LogDir, sizeof(LogDir), "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, pkg); if (!fexists(LogDir)) { warnx("no such package '%s' installed", pkg); return 1; } - if (!getcwd(home, FILENAME_MAX)) - cleanup(0), errx(2, "unable to get current working directory!"); + if (!getcwd(home, FILENAME_MAX)) { + cleanup(0); + errx(2, "unable to get current working directory!"); + } if (chdir(LogDir) == FAIL) { warnx("unable to change directory to %s! deinstall failed", LogDir); return 1; @@ -126,8 +128,10 @@ pkg_do(char *pkg) } } } - if (chdir(home) == FAIL) - cleanup(0), errx(2, "Toto! This doesn't look like Kansas anymore!"); + if (chdir(home) == FAIL) { + cleanup(0); + errx(2, "Toto! This doesn't look like Kansas anymore!"); + } if (!Fake) { /* Some packages aren't packed right, so we need to just ignore delete_package()'s status. Ugh! :-( */ if (delete_package(FALSE, CleanDirs, &Plist) == FAIL) @@ -144,10 +148,10 @@ pkg_do(char *pkg) if (p->type != PLIST_PKGDEP) continue; if (Verbose) - printf("Attempting to remove dependency on package `%s'\n", - p->name); + printf("Attempting to remove dependency on package `%s'\n", p->name); if (!Fake) - undepend(p, pkg); + findmatchingname((tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, + p->name, undepend, pkg); } return 0; } @@ -155,9 +159,10 @@ pkg_do(char *pkg) static void sanity_check(char *pkg) { - if (!fexists(CONTENTS_FNAME)) - cleanup(0), errx(2, "installed package %s has no %s file!", - pkg, CONTENTS_FNAME); + if (!fexists(CONTENTS_FNAME)) { + cleanup(0); + errx(2, "installed package %s has no %s file!", pkg, CONTENTS_FNAME); + } } void @@ -168,8 +173,12 @@ cleanup(int sig) exit(1); } -static void -undepend(PackingList p, char *pkgname) +/* deppkgname is the pkg from which's +REQUIRED_BY file we are + * about to remove pkg2delname. This function is called from + * findmatchingname(), deppkgname is expanded from a (possible) pattern. + */ +int +undepend(const char *deppkgname, char *pkg2delname) { char fname[FILENAME_MAX], ftmp[FILENAME_MAX]; char fbuf[FILENAME_MAX]; @@ -177,20 +186,20 @@ undepend(PackingList p, char *pkgname) char *tmp; int s; - sprintf(fname, "%s/%s/%s", + (void) snprintf(fname, sizeof(fname), "%s/%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, - p->name, REQUIRED_BY_FNAME); + deppkgname, REQUIRED_BY_FNAME); fp = fopen(fname, "r"); if (fp == NULL) { warnx("couldn't open dependency file `%s'", fname); - return; + return 0; } - sprintf(ftmp, "%s.XXXXXXXXXX", fname); + (void) snprintf(ftmp, sizeof(ftmp), "%s.XXXXXX", fname); s = mkstemp(ftmp); if (s == -1) { fclose(fp); warnx("couldn't open temp file `%s'", ftmp); - return; + return 0; } fpwr = fdopen(s, "w"); if (fpwr == NULL) { @@ -198,12 +207,12 @@ undepend(PackingList p, char *pkgname) fclose(fp); warnx("couldn't fdopen temp file `%s'", ftmp); remove(ftmp); - return; + return 0; } while (fgets(fbuf, sizeof(fbuf), fp) != NULL) { if (fbuf[strlen(fbuf)-1] == '\n') fbuf[strlen(fbuf)-1] = '\0'; - if (strcmp(fbuf, pkgname)) /* no match */ + if (strcmp(fbuf, pkg2delname)) /* no match */ fputs(fbuf, fpwr), putc('\n', fpwr); } (void) fclose(fp); @@ -211,15 +220,16 @@ undepend(PackingList p, char *pkgname) warnx("error changing permission of temp file `%s'", ftmp); fclose(fpwr); remove(ftmp); - return; + return 0; } if (fclose(fpwr) == EOF) { warnx("error closing temp file `%s'", ftmp); remove(ftmp); - return; + return 0; } if (rename(ftmp, fname) == -1) - warn("error renaming `%s' to `%s'", ftmp, fname); + warnx("error renaming `%s' to `%s'", ftmp, fname); remove(ftmp); /* just in case */ - return; + + return 0; } diff --git a/usr.sbin/pkg_install/info/info.h b/usr.sbin/pkg_install/info/info.h index b8ad23bc0e1..32cdc68cc71 100644 --- a/usr.sbin/pkg_install/info/info.h +++ b/usr.sbin/pkg_install/info/info.h @@ -1,4 +1,4 @@ -/* $OpenBSD: info.h,v 1.1 1996/06/04 07:56:09 niklas Exp $ */ +/* $OpenBSD: info.h,v 1.2 1998/10/13 23:09:51 marc Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -49,11 +49,12 @@ extern Boolean AllInstalled; extern Boolean Quiet; extern char *InfoPrefix; extern char PlayPen[]; +extern size_t PlayPenSize; extern char *CheckPkg; extern void show_file(char *, char *); -extern void show_plist(char *, Package *, plist_t); -extern void show_files(char *, Package *); +extern void show_plist(char *, package_t *, pl_ent_t); +extern void show_files(char *, package_t *); extern void show_index(char *, char *); #endif /* _INST_INFO_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/info/main.c b/usr.sbin/pkg_install/info/main.c index f3598cbcf61..1122ea9b0fa 100644 --- a/usr.sbin/pkg_install/info/main.c +++ b/usr.sbin/pkg_install/info/main.c @@ -1,7 +1,7 @@ -/* $OpenBSD: main.c,v 1.10 1998/09/07 22:30:15 marc Exp $ */ +/* $OpenBSD: main.c,v 1.11 1998/10/13 23:09:51 marc Exp $ */ #ifndef lint -static char *rcsid = "$OpenBSD: main.c,v 1.10 1998/09/07 22:30:15 marc Exp $"; +static char *rcsid = "$OpenBSD: main.c,v 1.11 1998/10/13 23:09:51 marc Exp $"; #endif /* @@ -36,6 +36,7 @@ Boolean AllInstalled = FALSE; Boolean Quiet = FALSE; char *InfoPrefix = ""; char PlayPen[FILENAME_MAX]; +size_t PlayPenSize = sizeof(PlayPen); char *CheckPkg = NULL; static void usage __P((void)); @@ -117,7 +118,8 @@ main(int argc, char **argv) Verbose = TRUE; /* Reasonable definition of 'everything' */ Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL | - SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE; + SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE | + SHOW_REQBY; break; case 'h': diff --git a/usr.sbin/pkg_install/info/perform.c b/usr.sbin/pkg_install/info/perform.c index 6f288bcd7f8..5f9cf1011a3 100644 --- a/usr.sbin/pkg_install/info/perform.c +++ b/usr.sbin/pkg_install/info/perform.c @@ -1,7 +1,7 @@ -/* $OpenBSD: perform.c,v 1.4 1998/09/07 22:30:15 marc Exp $ */ +/* $OpenBSD: perform.c,v 1.5 1998/10/13 23:09:51 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: perform.c,v 1.4 1998/09/07 22:30:15 marc Exp $"; +static const char *rcsid = "$OpenBSD: perform.c,v 1.5 1998/10/13 23:09:51 marc Exp $"; #endif /* @@ -33,7 +33,6 @@ static const char *rcsid = "$OpenBSD: perform.c,v 1.4 1998/09/07 22:30:15 marc E #include <err.h> #include <signal.h> #include <dirent.h> -#include <fnmatch.h> #include <ctype.h> static char *Home; @@ -44,7 +43,7 @@ pkg_do(char *pkg) Boolean installed = FALSE, isTMP = FALSE; char log_dir[FILENAME_MAX]; char fname[FILENAME_MAX]; - Package plist; + package_t plist; FILE *fp; struct stat sb; char *cp = NULL; @@ -59,8 +58,10 @@ pkg_do(char *pkg) int len; if (*pkg != '/') { - if (!getcwd(fname, FILENAME_MAX)) - upchuck("getcwd"); + if (!getcwd(fname, FILENAME_MAX)) { + cleanup(0); + err(1, "fatal error during execution: getcwd"); + } len = strlen(fname); snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg); } else @@ -86,7 +87,7 @@ pkg_do(char *pkg) code = 1; goto bail; } - Home = make_playpen(PlayPen, sb.st_size / 2); + Home = make_playpen(PlayPen, PlayPenSize, sb.st_size / 2); if (unpack(fname, "+*")) { warnx("error during unpacking, no info for '%s' available", pkg); code = 1; @@ -95,13 +96,13 @@ pkg_do(char *pkg) } } /* - * It's not an ininstalled package, try and find it among the + * It's not an uninstalled package, try and find it among the * installed */ else { char *tmp; - sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, + (void) snprintf(log_dir, sizeof(log_dir), "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, pkg); if (!fexists(log_dir)) { warnx("can't find package `%s' installed or in a file!", pkg); @@ -148,7 +149,7 @@ pkg_do(char *pkg) if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME)) show_file("Install notice:\n", DISPLAY_FNAME); if (Flags & SHOW_PLIST) - show_plist("Packing list:\n", &plist, (plist_t) - 1); + show_plist("Packing list:\n", &plist, PLIST_SHOW_ALL); if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) show_file("Install script:\n", INSTALL_FNAME); if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) @@ -170,171 +171,39 @@ bail: return code; } -/* use fnmatch to do a glob-style match */ -/* returns 0 if found, 1 if not (1) */ -static int -globmatch(char *pkgspec, char *dbdir, int quiet) -{ - /* Using glob-match */ - struct dirent *dp; - int found; - DIR *dirp; - - found = 0; - if ((dirp = opendir(dbdir)) == (DIR *) NULL) { - warnx("can't opendir package dir '%s'", dbdir); - return !0; - } - while ((dp = readdir(dirp)) != (struct dirent *) NULL) { - if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { - continue; - } - if (fnmatch(pkgspec, dp->d_name, FNM_PERIOD) == 0) { - if (!quiet) - printf("%s\n", dp->d_name); - found = 1; - } - } - closedir(dirp); - return !found; -} - -enum { - GT, - GE, - LT, - LE -}; - -/* compare two dewey decimal numbers */ +/* fn to be called for pkgs found */ static int -deweycmp(char *a, int op, char *b) +foundpkg(const char *found, char *data) { - int ad; - int bd; - int cmp; - - for (;;) { - if (*a == 0 && *b == 0) { - cmp = 0; - break; - } - ad = bd = 0; - for ( ; *a && *a != '.' ; a++) { - ad = (ad * 10) + (*a - '0'); - } - for ( ; *b && *b != '.' ; b++) { - bd = (bd * 10) + (*b - '0'); - } - if ((cmp = ad - bd) != 0) { - break; - } - if (*a == '.') { - a++; - } - if (*b == '.') { - b++; - } - } - return (op == GE) ? cmp >= 0 : (op == GT) ? cmp > 0 : (op == LE) ? cmp <= 0 : cmp < 0; + if(!Quiet) + printf("%s\n", found); + return 0; } -/* match on a relation against dewey decimal numbers */ -/* returns 0 if found, 1 if not (!) */ +/* check if a package "pkgspec" (which can be a pattern) is installed */ +/* return 0 if found, 1 otherwise (indicating an error). */ static int -deweymatch(char *name, int op, char *ver, char *dbdir, int quiet) +check4pkg(char *pkgspec, char *dbdir) { - struct dirent *dp; - char *cp; - DIR *dirp; - int ret; - int n; + if (strpbrk(pkgspec, "<>[]?*{")) { + /* expensive (pattern) match */ + int found; - n = strlen(name); - ret = 1; - if ((dirp = opendir(dbdir)) == (DIR *) NULL) { - warnx("can't opendir package dir '%s'", dbdir); - return 1; - } - while ((dp = readdir(dirp)) != (struct dirent *) NULL) { - if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) { - continue; - } - if ((cp = strrchr(dp->d_name, '-')) != (char *) NULL) { - if (strncmp(dp->d_name, name, cp - dp->d_name) == 0 && n == cp - dp->d_name) { - if (deweycmp(cp + 1, op, ver)) { - if (!quiet) - printf("%s\n", dp->d_name); - ret = 0; - } - } - } - } - closedir(dirp); - return ret; -} - -/* do a match on a package pattern in dbdir */ -/* returns 0 if found, 1 if not (!) */ -static int -matchname(char *pkgspec, char *dbdir, int quiet) -{ - struct stat st; + found=findmatchingname(dbdir, pkgspec, foundpkg, NULL); + return !found; + } else { + /* simple match */ char buf[FILENAME_MAX]; - char *sep; - char *last; - char *alt; - char *cp; int error; - int cnt; - int ret; + struct stat st; - if ((sep = strchr(pkgspec, '{')) != (char *) NULL) { - /* emulate csh-type alternates */ - (void) strncpy(buf, pkgspec, sep - pkgspec); - alt = &buf[sep - pkgspec]; - for (last = NULL, cnt = 0, cp = sep ; *cp && !last ; cp++) { - if (*cp == '{') { - cnt++; - } else if (*cp == '}' && --cnt == 0 && last == NULL) { - last = cp + 1; - } - } - if (cnt != 0) { - warnx("Malformed alternate `%s'", pkgspec); - return 1; - } - for (ret = 1, cp = sep + 1 ; *sep != '}' ; cp = sep + 1) { - for (cnt = 0, sep = cp ; cnt > 0 || (cnt == 0 && *sep != '}' && *sep != ',') ; sep++) { - if (*sep == '{') { - cnt++; - } else if (*sep == '}') { - cnt--; - } - } - (void) snprintf(alt, sizeof(buf) - (alt - buf), "%.*s%s", (int)(sep - cp), cp, last); - if (matchname(buf, dbdir, quiet) == 0) { - ret = 0; - } - } - return ret; - } - if ((sep = strpbrk(pkgspec, "<>")) != (char *) NULL) { - /* perform relational dewey match on version number */ - (void) snprintf(buf, sizeof(buf), "%.*s", (int)(sep - pkgspec), pkgspec); - cnt = (*sep == '>') ? (*(sep + 1) == '=') ? GE : GT : (*(sep + 1) == '=') ? LE : LT; - cp = (cnt == GE || cnt == LE) ? sep + 2 : sep + 1; - return deweymatch(buf, cnt, cp, dbdir, quiet); - } - if (strpbrk(pkgspec, "*?[]") != (char *) NULL) { - return globmatch(pkgspec, dbdir, quiet); - } - /* No shell meta character given - simple check */ - (void) snprintf(buf, sizeof(buf), "%s/%s", dbdir, pkgspec); - error = (lstat(buf, &st) < 0); - if (!error && !quiet) + snprintf(buf, sizeof(buf), "%s/%s", dbdir, pkgspec); + error = (stat(buf, &st) < 0); + if (!error && !Quiet) printf("%s\n", pkgspec); + return error; + } } void @@ -357,7 +226,7 @@ pkg_perform(char **pkgs) tmp = DEF_LOG_DIR; /* Overriding action? */ if (CheckPkg) { - return matchname(CheckPkg, tmp, Quiet); + err_cnt += check4pkg(CheckPkg, tmp); } else if (AllInstalled) { struct dirent *dp; DIR *dirp; diff --git a/usr.sbin/pkg_install/info/pkg_info.1 b/usr.sbin/pkg_install/info/pkg_info.1 index c937e751770..1457fb3748f 100644 --- a/usr.sbin/pkg_install/info/pkg_info.1 +++ b/usr.sbin/pkg_install/info/pkg_info.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: pkg_info.1,v 1.3 1998/09/07 22:30:16 marc Exp $ +.\" $OpenBSD: pkg_info.1,v 1.4 1998/10/13 23:09:51 marc Exp $ .\" .\" FreeBSD install - a package for the installation and maintainance .\" of non-core utilities. @@ -55,18 +55,26 @@ Show the install-message file (if any) for each package. .It Fl d Show the long-description field for each package. .It Fl e Ar pkg-name +This option +allows you to test for the presence of another (perhaps +prerequisite) package from a script. If the package identified by .Ar pkg-name is currently installed, return 0, otherwise return 1. -If the given pkg-name contains a +In addition, the names of any package(s) found installed are printed to +stdout unless turned off using the +.Fl q +option. + +If the given +.Ar pkg-name +contains a shell metacharacter, it will be matched against all installed packages using -.Xr fnmatch 3 , -and any packages found installed are printed to stdout, one name per -line. +.Xr fnmatch 3 . .Xr csh 1 -style {,} alternates have also been implemented. -Dewey decimal numbers can also be matched in a relational manner, +style {,} alternates have also been implemented in addition to this. +Package version numbers can also be matched in a relational manner using the .Pa >=, <=, > and @@ -77,12 +85,6 @@ For example, will match versions 1.3 and later of the .Pa name package. -This printing can be turned off using the -.Fl q -option. -This option -allows you to test for the presence of another (perhaps -prerequisite) package from a script. .It Fl f Show the packing list instructions for each package. .It Fl I diff --git a/usr.sbin/pkg_install/info/show.c b/usr.sbin/pkg_install/info/show.c index 35a21dd64b1..582d06a21d1 100644 --- a/usr.sbin/pkg_install/info/show.c +++ b/usr.sbin/pkg_install/info/show.c @@ -1,7 +1,7 @@ -/* $OpenBSD: show.c,v 1.3 1998/09/07 22:30:16 marc Exp $ */ +/* $OpenBSD: show.c,v 1.4 1998/10/13 23:09:51 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: show.c,v 1.3 1998/09/07 22:30:16 marc Exp $"; +static const char *rcsid = "$OpenBSD: show.c,v 1.4 1998/10/13 23:09:51 marc Exp $"; #endif /* @@ -29,177 +29,165 @@ static const char *rcsid = "$OpenBSD: show.c,v 1.3 1998/09/07 22:30:16 marc Exp #include "lib.h" #include "info.h" +/* structure to define entries for the "show table" */ +typedef struct show_t { + pl_ent_t sh_type; /* type of entry */ + char *sh_quiet; /* message when quiet */ + char *sh_verbose; /* message when verbose */ +} show_t; + +/* the entries in this table must be ordered the same as pl_ent_t constants */ +static show_t showv[] = { + { PLIST_FILE, "%s", "File: %s" }, + { PLIST_CWD, "@cwd: %s", "\tCWD to: %s" }, + { PLIST_CMD, "@exec %s", "\tEXEC '%s'" }, + { PLIST_CHMOD, "@chmod %s", "\tCHMOD to %s" }, + { PLIST_CHOWN, "@chown %s", "\tCHOWN to %s" }, + { PLIST_CHGRP, "@chgrp %s", "\tCHGRP to %s" }, + { PLIST_COMMENT, "@comment %s", "\tComment: %s" }, + { PLIST_IGNORE, NULL, NULL }, + { PLIST_NAME, "@name %s", "\tPackage name: %s" }, + { PLIST_UNEXEC, "@unexec %s", "\tUNEXEC '%s'" }, + { PLIST_SRC, "@srcdir: %s", "\tSRCDIR to: %s" }, + { PLIST_DISPLAY, "@display %s", "\tInstall message file: %s" }, + { PLIST_PKGDEP, "@pkgdep %s", "\tPackage depends on: %s" }, + { PLIST_MTREE, "@mtree %s", "\tPackage mtree file: %s" }, + { PLIST_DIR_RM, "@dirrm %s", "\tDeinstall directory remove: %s" }, + { PLIST_IGNORE_INST, "@ignore_inst ??? doesn't belong here", + "\tIgnore next file installation directive (doesn't belong)" }, + { PLIST_OPTION, "@option %s", "\tPackage has option: %s" }, + { PLIST_PKGCFL, "@pkgcfl %s", "\tPackage conflicts with: %s" }, + { -1, NULL, NULL } +}; + void show_file(char *title, char *fname) { - FILE *fp; - char line[1024]; - int n; + FILE *fp; + char line[1024]; + int n; - if (!Quiet) - printf("%s%s", InfoPrefix, title); - fp = fopen(fname, "r"); - if (!fp) - printf("ERROR: show_file: Can't open '%s' for reading!\n", fname); - else { - while ((n = fread(line, 1, 1024, fp)) != 0) - fwrite(line, 1, n, stdout); - fclose(fp); - } - printf("\n"); /* just in case */ + if (!Quiet) { + printf("%s%s", InfoPrefix, title); + } + if ((fp = fopen(fname, "r")) == (FILE *) NULL) { + printf("ERROR: show_file: Can't open '%s' for reading!\n", fname); + } else { + while ((n = fread(line, 1, 1024, fp)) != 0) { + fwrite(line, 1, n, stdout); + } + (void) fclose(fp); + } + printf("\n"); /* just in case */ } void show_index(char *title, char *fname) { - FILE *fp; - char line[MAXINDEXSIZE+2]; + FILE *fp; + char line[MAXINDEXSIZE+2]; - if (!Quiet) - printf("%s%s", InfoPrefix, title); - fp = fopen(fname, "r"); - if (!fp) { - warnx("show_file: can't open '%s' for reading", fname); - return; - } - if(fgets(line, MAXINDEXSIZE+1, fp)) { - if(line[MAXINDEXSIZE-1] != '\n') - line[MAXINDEXSIZE] = '\n'; - line[MAXINDEXSIZE+1] = 0; - fputs(line, stdout); - } - fclose(fp); + if (!Quiet) { + printf("%s%s", InfoPrefix, title); + } + if ((fp = fopen(fname, "r")) == (FILE *) NULL) { + warnx("show_file: can't open '%s' for reading", fname); + return; + } + if (fgets(line, MAXINDEXSIZE+1, fp)) { + if (line[MAXINDEXSIZE-1] != '\n') { + line[MAXINDEXSIZE] = '\n'; + } + line[MAXINDEXSIZE+1] = 0; + (void) fputs(line, stdout); + } + (void) fclose(fp); } -/* Show a packing list item type. If type is -1, show all */ +/* Show a packing list item type. If type is PLIST_SHOW_ALL, show all */ void -show_plist(char *title, Package *plist, plist_t type) +show_plist(char *title, package_t *plist, pl_ent_t type) { - PackingList p; - Boolean ign = FALSE; + plist_t *p; + Boolean ign; - if (!Quiet) + if (!Quiet) { printf("%s%s", InfoPrefix, title); - p = plist->head; - while (p) { - if (p->type != type && type != -1) { - p = p->next; - continue; - } - switch(p->type) { - case PLIST_FILE: - if (ign) { - printf(Quiet ? "%s\n" : "File: %s (ignored)\n", p->name); - ign = FALSE; - } - else - printf(Quiet ? "%s\n" : "File: %s\n", p->name); - break; - - case PLIST_CWD: - printf(Quiet ? "@cwd %s\n" : "\tCWD to %s\n", p->name); - break; - - case PLIST_SRC: - printf(Quiet ? "@srcdir %s\n" : "\tSRCDIR to %s\n", p->name); - break; - - case PLIST_CMD: - printf(Quiet ? "@exec %s\n" : "\tEXEC '%s'\n", p->name); - break; - - case PLIST_UNEXEC: - printf(Quiet ? "@unexec %s\n" : "\tUNEXEC '%s'\n", p->name); - break; - - case PLIST_CHMOD: - printf(Quiet ? "@chmod %s\n" : "\tCHMOD to %s\n", - p->name ? p->name : "(clear default)"); - break; - - case PLIST_CHOWN: - printf(Quiet ? "@chown %s\n" : "\tCHOWN to %s\n", - p->name ? p->name : "(clear default)"); - break; - - case PLIST_CHGRP: - printf(Quiet ? "@chgrp %s\n" : "\tCHGRP to %s\n", - p->name ? p->name : "(clear default)"); - break; - - case PLIST_COMMENT: - printf(Quiet ? "@comment %s\n" : "\tComment: %s\n", p->name); - break; - - case PLIST_IGNORE: - ign = TRUE; - break; - - case PLIST_IGNORE_INST: - printf(Quiet ? "@ignore_inst ??? doesn't belong here.\n" : - "\tIgnore next file installation directive (doesn't belong)\n"); - ign = TRUE; - break; - - case PLIST_NAME: - printf(Quiet ? "@name %s\n" : "\tPackage name: %s\n", p->name); - break; - - case PLIST_DISPLAY: - printf(Quiet ? "@display %s\n" : "\tInstall message file: %s\n", p->name); - break; - - case PLIST_PKGDEP: - printf(Quiet ? "@pkgdep %s\n" : "\tPackage depends on: %s\n", p->name); - break; - - case PLIST_MTREE: - printf(Quiet ? "@mtree %s\n" : "\tPackage mtree file: %s\n", p->name); - break; - - case PLIST_DIR_RM: - printf(Quiet ? "@dirrm %s\n" : "\tDeinstall directory remove: %s\n", p->name); - break; - - default: - cleanup(0); - errx(2, "unknown command type %d (%s)", p->type, p->name); - break; + } + for (ign = FALSE, p = plist->head; p ; p = p->next) { + if (p->type == type || type == PLIST_SHOW_ALL) { + switch(p->type) { + case PLIST_FILE: + printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name); + if (ign) { + if (!Quiet) { + printf(" (ignored)"); + } + ign = FALSE; + } + break; + case PLIST_CHMOD: + case PLIST_CHOWN: + case PLIST_CHGRP: + printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, + p->name ? p->name : "(clear default)"); + break; + case PLIST_IGNORE: + ign = TRUE; + break; + case PLIST_IGNORE_INST: + printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name); + ign = TRUE; + break; + case PLIST_CWD: + case PLIST_CMD: + case PLIST_SRC: + case PLIST_UNEXEC: + case PLIST_COMMENT: + case PLIST_NAME: + case PLIST_DISPLAY: + case PLIST_PKGDEP: + case PLIST_MTREE: + case PLIST_DIR_RM: + case PLIST_OPTION: + case PLIST_PKGCFL: + printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name); + break; + default: + warnx("unknown command type %d (%s)", p->type, p->name); + } + (void) fputc('\n', stdout); } - p = p->next; } } /* Show all files in the packing list (except ignored ones) */ void -show_files(char *title, Package *plist) +show_files(char *title, package_t *plist) { - PackingList p; - Boolean ign = FALSE; - char *dir = "."; - - if (!Quiet) - printf("%s%s", InfoPrefix, title); - p = plist->head; - while (p) { - switch(p->type) { - case PLIST_FILE: - if (!ign) - printf("%s/%s\n", dir, p->name); - ign = FALSE; - break; + plist_t *p; + Boolean ign; + char *dir = "."; - case PLIST_CWD: - dir = p->name; - break; - - case PLIST_IGNORE: - ign = TRUE; - break; - - default: - break; + if (!Quiet) { + printf("%s%s", InfoPrefix, title); + } + for (ign = FALSE, p = plist->head; p ; p = p->next) { + switch(p->type) { + case PLIST_FILE: + if (!ign) { + printf("%s/%s\n", dir, p->name); + } + ign = FALSE; + break; + case PLIST_CWD: + dir = p->name; + break; + case PLIST_IGNORE: + ign = TRUE; + break; + default: + break; + } } - p = p->next; - } } diff --git a/usr.sbin/pkg_install/lib/Makefile b/usr.sbin/pkg_install/lib/Makefile index ff1e3e686e9..2332a1bcb17 100644 --- a/usr.sbin/pkg_install/lib/Makefile +++ b/usr.sbin/pkg_install/lib/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.1 1996/06/04 07:56:11 niklas Exp $ +# $OpenBSD: Makefile,v 1.2 1998/10/13 23:09:52 marc Exp $ LIB= install -SRCS= file.c ftp.c msg.c plist.c str.c exec.c global.c pen.c +SRCS= file.c plist.c str.c exec.c global.c pen.c CFLAGS+= ${DEBUG} NOPROFILE= yes NOPIC= yes diff --git a/usr.sbin/pkg_install/lib/exec.c b/usr.sbin/pkg_install/lib/exec.c index bf7d614d845..aa0a68c9602 100644 --- a/usr.sbin/pkg_install/lib/exec.c +++ b/usr.sbin/pkg_install/lib/exec.c @@ -1,7 +1,7 @@ -/* $OpenBSD: exec.c,v 1.4 1998/09/07 22:30:16 marc Exp $ */ +/* $OpenBSD: exec.c,v 1.5 1998/10/13 23:09:52 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: exec.c,v 1.4 1998/09/07 22:30:16 marc Exp $"; +static const char *rcsid = "$OpenBSD: exec.c,v 1.5 1998/10/13 23:09:52 marc Exp $"; #endif /* @@ -35,29 +35,29 @@ static const char *rcsid = "$OpenBSD: exec.c,v 1.4 1998/09/07 22:30:16 marc Exp int vsystem(const char *fmt, ...) { - va_list args; - char *cmd; - int ret, maxargs; - - maxargs = sysconf(_SC_ARG_MAX); - maxargs -= 32; /* some slop for the sh -c */ - cmd = malloc(maxargs); - if (!cmd) { - warnx("vsystem can't alloc arg space"); - return 1; - } - - va_start(args, fmt); - if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) { - warnx("vsystem args are too long"); - return 1; - } + va_list args; + char *cmd; + size_t maxargs; + int ret; + + maxargs = (size_t) sysconf(_SC_ARG_MAX); + maxargs -= 32; /* some slop for the sh -c */ + if ((cmd = (char *) malloc(maxargs)) == (char *) NULL) { + warnx("vsystem can't alloc arg space"); + return 1; + } + + va_start(args, fmt); + if (vsnprintf(cmd, maxargs, fmt, args) > maxargs) { + warnx("vsystem args are too long"); + return 1; + } #ifdef DEBUG -printf("Executing %s\n", cmd); + printf("Executing %s\n", cmd); #endif - ret = system(cmd); - va_end(args); - free(cmd); - return ret; + ret = system(cmd); + va_end(args); + free(cmd); + return ret; } diff --git a/usr.sbin/pkg_install/lib/file.c b/usr.sbin/pkg_install/lib/file.c index 8f8ac44328c..b6bc65f7be1 100644 --- a/usr.sbin/pkg_install/lib/file.c +++ b/usr.sbin/pkg_install/lib/file.c @@ -1,7 +1,7 @@ -/* $OpenBSD: file.c,v 1.6 1998/09/07 22:30:16 marc Exp $ */ +/* $OpenBSD: file.c,v 1.7 1998/10/13 23:09:52 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: file.c,v 1.6 1998/09/07 22:30:16 marc Exp $"; +static const char *rcsid = "$OpenBSD: file.c,v 1.7 1998/10/13 23:09:52 marc Exp $"; #endif /* @@ -28,13 +28,55 @@ static const char *rcsid = "$OpenBSD: file.c,v 1.6 1998/09/07 22:30:16 marc Exp #include <sys/wait.h> +#include <assert.h> #include <err.h> #include <netdb.h> #include <pwd.h> #include <time.h> -FILE * -ftpGetURL(char *url, char *user, char *passwd, int *retcode); +/* This is as ftpGetURL from FreeBSD's ftpio.c, except that it uses + * OpenBSD's ftp command to do all FTP. + */ +static FILE * +ftpGetURL(char *url, int *retcode) +{ + FILE *ftp; + pid_t pid_ftp; + int p[2]; + + *retcode=0; + + if (pipe(p) < 0) { + *retcode = 1; + return NULL; + } + + pid_ftp = fork(); + if (pid_ftp < 0) { + *retcode = 1; + return NULL; + } + if (pid_ftp == 0) { + /* child */ + dup2(p[1],1); + close(p[1]); + + fprintf(stderr, ">>> ftp -o - %s\n",url); + execl("/usr/bin/ftp","ftp","-V","-o","-",url,NULL); + exit(1); + } else { + /* parent */ + ftp = fdopen(p[0],"r"); + + close(p[1]); + + if (ftp == (FILE *) NULL) { + *retcode = 1; + return NULL; + } + } + return ftp; +} /* Quick check to see if a file exists */ Boolean @@ -196,10 +238,9 @@ char * fileGetURL(char *base, char *spec) { char host[MAXHOSTNAMELEN], file[FILENAME_MAX]; - char pword[MAXHOSTNAMELEN + 40], *uname, *cp, *rp; + char *cp, *rp; char fname[FILENAME_MAX]; char pen[FILENAME_MAX]; - struct passwd *pw; FILE *ftp; pid_t tpid; int i, status; @@ -251,29 +292,13 @@ fileGetURL(char *base, char *spec) return NULL; } - /* Maybe change to ftp if this doesn't work */ - uname = "anonymous"; - - /* Make up a convincing "password" */ - pw = getpwuid(getuid()); - if (!pw) { - warnx("can't get user name for ID %d", getuid()); - strcpy(pword, "joe@"); - } - else { - char me[MAXHOSTNAMELEN + 1]; - - gethostname(me, sizeof me); - me[sizeof(me) - 1] = '\0'; - snprintf(pword, sizeof pword, "%s@%s", pw->pw_name, me); - } if (Verbose) printf("Trying to fetch %s.\n", fname); - ftp = ftpGetURL(fname, uname, pword, &status); + ftp = ftpGetURL(fname, &status); if (ftp) { pen[0] = '\0'; - if ((rp = make_playpen(pen, 0)) != NULL) { - rp=pen; /* XXX - pen is dynamic; make static? */ + if ((rp = make_playpen(pen, sizeof(pen), 0)) != NULL) { + rp=strdup(pen); /* be safe for nested calls */ if (Verbose) printf("Extracting from FTP connection into %s\n", pen); tpid = fork(); @@ -306,40 +331,75 @@ fileGetURL(char *base, char *spec) char * fileFindByPath(char *base, char *fname) { - static char tmp[FILENAME_MAX]; - char *cp; - - if (fexists(fname) && isfile(fname)) { - strcpy(tmp, fname); - return tmp; - } - if (base) { - strcpy(tmp, base); - - cp = strrchr(tmp, '/'); - if (cp) { - *cp = '\0'; /* chop name */ - cp = strrchr(tmp, '/'); + static char tmp[FILENAME_MAX]; + char *cp; + + if (ispkgpattern(fname)) { + if ((cp=findbestmatchingname(".",fname)) != NULL) { + strcpy (tmp, cp); + return tmp; + } + } else { + if (fexists(fname) && isfile(fname)) { + strcpy(tmp, fname); + return tmp; + } } - if (cp) { - *(cp + 1) = '\0'; - strcat(cp, "All/"); - strcat(cp, fname); - strcat(cp, ".tgz"); - if (fexists(tmp)) - return tmp; + + if (base) { + strcpy(tmp, base); + + cp = strrchr(tmp, '/'); + if (cp) { + *cp = '\0'; /* chop name */ + cp = strrchr(tmp, '/'); + } + if (cp) { + *(cp + 1) = '\0'; + strcat(cp, "All/"); + strcat(cp, fname); + strcat(cp, ".tgz"); + if (ispkgpattern(tmp)) { + cp=findbestmatchingname(dirname_of(tmp), + basename_of(tmp)); + if (cp) { + char *s; + s=strrchr(tmp,'/'); + assert(s != NULL); + strcpy(s+1, cp); + return tmp; + } + } else { + if (fexists(tmp)) { + return tmp; + } + } + } } - } - cp = getenv("PKG_PATH"); - while (cp) { - char *cp2 = strsep(&cp, ":"); - - snprintf(tmp, FILENAME_MAX, "%s/%s.tgz", cp2 ? cp2 : cp, fname); - if (fexists(tmp) && isfile(tmp)) - return tmp; - } - return NULL; + cp = getenv("PKG_PATH"); + while (cp) { + char *cp2 = strsep(&cp, ":"); + + snprintf(tmp, FILENAME_MAX, "%s/%s.tgz", cp2 ? cp2 : cp, fname); + if (ispkgpattern(tmp)) { + char *s; + s = findbestmatchingname(dirname_of(tmp), + basename_of(tmp)); + if (s){ + char *t; + t=strrchr(tmp, '/'); + strcpy(t+1, s); + return tmp; + } + } else { + if (fexists(tmp) && isfile(tmp)) { + return tmp; + } + } + } + + return NULL; } char * @@ -354,19 +414,19 @@ fileGetContents(char *fname) errx(2, "can't stat '%s'", fname); } - contents = (char *)malloc(sb.st_size + 1); + contents = (char *)malloc((size_t)(sb.st_size) + 1); fd = open(fname, O_RDONLY, 0); if (fd == FAIL) { cleanup(0); errx(2, "unable to open '%s' for reading", fname); } - if (read(fd, contents, sb.st_size) != sb.st_size) { + if (read(fd, contents, (size_t) sb.st_size) != (size_t) sb.st_size) { cleanup(0); errx(2, "short read on '%s' - did not get %qd bytes", fname, (long long)sb.st_size); } close(fd); - contents[sb.st_size] = '\0'; + contents[(size_t)sb.st_size] = '\0'; return contents; } @@ -374,7 +434,7 @@ fileGetContents(char *fname) * name for it. */ Boolean -make_preserve_name(char *try, int max, char *name, char *file) +make_preserve_name(char *try, size_t max, char *name, char *file) { int len, i; @@ -408,24 +468,23 @@ make_preserve_name(char *try, int max, char *name, char *file) void write_file(char *name, char *str) { - FILE *fp; - int len; + FILE *fp; + size_t len; - fp = fopen(name, "w"); - if (!fp) { - cleanup(0); - errx(2, "cannot fopen '%s' for writing", name); - } - len = strlen(str); - if (fwrite(str, 1, len, fp) != len) { - cleanup(0); - errx(2, "short fwrite on '%s', tried to write %d bytes", + if ((fp = fopen(name, "w")) == (FILE *) NULL) { + cleanup(0); + errx(2, "cannot fopen '%s' for writing", name); + } + len = strlen(str); + if (fwrite(str, 1, len, fp) != len) { + cleanup(0); + errx(2, "short fwrite on '%s', tried to write %d bytes", name, len); - } - if (fclose(fp)) { - cleanup(0); - errx(2, "failure to fclose '%s'", name); - } + } + if (fclose(fp)) { + cleanup(0); + errx(2, "failure to fclose '%s'", name); + } } void @@ -494,7 +553,7 @@ copy_hierarchy(char *dir, char *fname, Boolean to) int unpack(char *pkg, char *flist) { - char args[10], suffix[80], *cp; + char args[10], suff[80], *cp; args[0] = '\0'; /* @@ -504,8 +563,8 @@ unpack(char *pkg, char *flist) if (strcmp(pkg, "-")) { cp = strrchr(pkg, '.'); if (cp) { - strcpy(suffix, cp + 1); - if (strchr(suffix, 'z') || strchr(suffix, 'Z')) + strcpy(suff, cp + 1); + if (strchr(suff, 'z') || strchr(suff, 'Z')) strcpy(args, "-z"); } } @@ -519,107 +578,64 @@ unpack(char *pkg, char *flist) return 0; } -/* Using fmt, replace all instances of: - * +/* + * Using fmt, replace all instances of: + * * %F With the parameter "name" * %D With the parameter "dir" * %B Return the directory part ("base") of %D/%F * %f Return the filename part of %D/%F - * - * Does not check for overflow - caution! - * + * + * Check that no overflows can occur. */ void -format_cmd(char *buf, char *fmt, char *dir, char *name) +format_cmd(char *buf, size_t size, char *fmt, char *dir, char *name) { - char *cp, scratch[FILENAME_MAX * 2]; - - while (*fmt) { - if (*fmt == '%') { - switch (*++fmt) { - case 'F': - strcpy(buf, name); - buf += strlen(name); - break; - - case 'D': - strcpy(buf, dir); - buf += strlen(dir); - break; - - case 'B': - sprintf(scratch, "%s/%s", dir, name); - cp = &scratch[strlen(scratch) - 1]; - while (cp != scratch && *cp != '/') - --cp; - *cp = '\0'; - strcpy(buf, scratch); - buf += strlen(scratch); - break; - - case 'f': - sprintf(scratch, "%s/%s", dir, name); - cp = &scratch[strlen(scratch) - 1]; - while (cp != scratch && *(cp - 1) != '/') - --cp; - strcpy(buf, cp); - buf += strlen(cp); - break; - - default: - *buf++ = *fmt; - break; - } - ++fmt; + char scratch[FILENAME_MAX * 2]; + char *bufp; + char *cp; + + for (bufp = buf ; (int)(bufp - buf) < size && *fmt ; ) { + if (*fmt == '%') { + switch (*++fmt) { + case 'F': + strnncpy(bufp, size - (int)(bufp - buf), name, strlen(name)); + bufp += strlen(bufp); + break; + + case 'D': + strnncpy(bufp, size - (int)(bufp - buf), dir, strlen(dir)); + bufp += strlen(bufp); + break; + + case 'B': + (void) snprintf(scratch, sizeof(scratch), "%s/%s", dir, name); + if ((cp = strrchr(scratch, '/')) == (char *) NULL) { + cp = scratch; + } + strnncpy(bufp, size - (int)(bufp - buf), scratch, (size_t)(cp - scratch)); + bufp += strlen(bufp); + break; + + case 'f': + (void) snprintf(scratch, sizeof(scratch), "%s/%s", dir, name); + if ((cp = strrchr(scratch, '/')) == (char *) NULL) { + cp = scratch; + } else { + cp++; + } + strnncpy(bufp, size - (int)(bufp - buf), cp, strlen(cp)); + bufp += strlen(bufp); + break; + + default: + *bufp++ = *fmt; + break; + } + ++fmt; + } else { + *bufp++ = *fmt++; + } } - else - *buf++ = *fmt++; - } - *buf = '\0'; -} - - -/* This is as ftpGetURL from FreeBSD's ftpio.c, except that it uses - * OpenBSD's ftp command to do all FTP, which will DTRT for proxies, - * etc. - */ -FILE * -ftpGetURL(char *url, char *user, char *passwd, int *retcode) -{ - FILE *ftp; - pid_t pid_ftp; - int p[2]; - - *retcode=0; - - if( pipe(p) < 0){ - *retcode = 1; - return NULL; - } - - pid_ftp = fork(); - if(pid_ftp < 0){ - *retcode = 1; - return NULL; - } - if(pid_ftp == 0){ - /* child */ - dup2(p[1],1); - close(p[1]); - - execl("/usr/bin/ftp","ftp","-V","-o","-",url,NULL); - exit(1); - }else{ - /* parent */ - ftp = fdopen(p[0],"r"); - - close(p[1]); - - if(ftp < 0){ - *retcode = 1; - return NULL; - } - } - - return ftp; + *bufp = '\0'; } diff --git a/usr.sbin/pkg_install/lib/ftp.c b/usr.sbin/pkg_install/lib/ftp.c deleted file mode 100644 index 913ca95cefa..00000000000 --- a/usr.sbin/pkg_install/lib/ftp.c +++ /dev/null @@ -1,425 +0,0 @@ -/* $OpenBSD: ftp.c,v 1.2 1996/06/04 08:43:42 niklas Exp $ */ - -/* - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * - * Return values have been sanitized: - * -1 error, but you (still) have a session. - * -2 error, your session is dead. - * - */ - -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> -#include <netdb.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <stdarg.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include "ftp.h" -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> - -/* Handy global for us to stick the port # */ -int FtpPort; - -static void -debug(FTP_t ftp, const char *fmt, ...) -{ - char p[BUFSIZ]; - va_list ap; - va_start(ap, fmt); - strcpy(p,"LIBFTP: "); - (void) vsnprintf(p+strlen(p), sizeof p - strlen(p), fmt, ap); - va_end(ap); - write(ftp->fd_debug,p,strlen(p)); -} - -static int -writes(int fd, char *s) -{ - int i = strlen(s); - if (i != write(fd,s,i)) - return -2; - return 0; -} - -static __inline char* -get_a_line(FTP_t ftp) -{ - static char buf[BUFSIZ]; - int i,j; - - for(i=0;i<BUFSIZ;) { - j = read(ftp->fd_ctrl,buf+i,1); - if (j != 1) - return 0; - if (buf[i] == '\r' || buf[i] == '\n') { - if (!i) - continue; - buf[i] = '\0'; - debug(ftp, "received <%s>\n",buf); - return buf; - } - i++; - } - return buf; -} - -static int -get_a_number(FTP_t ftp, char **q) -{ - char *p; - int i = -1,j; - - while(1) { - p = get_a_line(ftp); - if (!p) - return -2; - if (!(isdigit(p[0]) && isdigit(p[1]) && isdigit(p[2]))) - continue; - if (i == -1 && p[3] == '-') { - i = strtol(p, 0, 0); - continue; - } - if (p[3] != ' ' && p[3] != '\t') - continue; - j = strtol(p, 0, 0); - if (i == -1) { - if (q) *q = p+4; - return j; - } else if (j == i) { - if (q) *q = p+4; - return j; - } - } -} - -static int -zap(FTP_t ftp) -{ - int i; - - i = writes(ftp->fd_ctrl,"QUIT\r\n"); - debug(ftp, "Zapping ftp connection on %d returns %d\n", ftp->fd_ctrl, i); - close(ftp->fd_ctrl); ftp->fd_ctrl = -1; - close(ftp->fd_xfer); ftp->fd_xfer = -1; - ftp->state = init; - return -2; -} - -static int -botch(FTP_t ftp, char *func, char *state) -{ - debug(ftp, "Botch: %s called outside state %s\n",func,state); - return -2; -} - -static int -cmd(FTP_t ftp, const char *fmt, ...) -{ - char p[BUFSIZ]; - int i; - - va_list ap; - va_start(ap, fmt); - (void) vsnprintf(p, sizeof p, fmt, ap); - va_end(ap); - - debug(ftp, "send <%s>\n",p); - strcat(p,"\r\n"); - if (writes(ftp->fd_ctrl,p)) - return -2; - i = get_a_number(ftp,0); - return i; -} - -FTP_t -FtpInit() -{ - FTP_t ftp; - - ftp = malloc(sizeof *ftp); - if (!ftp) - return ftp; - memset(ftp, 0, sizeof *ftp); - ftp->fd_ctrl = -1; - ftp->fd_xfer = -1; - ftp->fd_debug = -1; - ftp->state = init; - return ftp; -} - -void -FtpDebug(FTP_t ftp, int i) -{ - ftp->fd_debug = i; -} - -int -FtpOpen(FTP_t ftp, char *host, char *user, char *passwd) -{ - struct hostent *he = NULL; - struct sockaddr_in sin; - int s; - unsigned long temp; - int i; - - if (ftp->state != init) - return botch(ftp,"FtpOpen","init"); - - if (!user) - user = "ftp"; - - if (!passwd) - passwd = "??@??(FreeBSD:libftp)"; /* XXX */ - - debug(ftp, "FtpOpen(ftp, %s, %s, %s)\n", host, user, passwd); - - temp = inet_addr(host); - if (temp != INADDR_NONE) { - debug(ftp, "Using dotted IP address `%s'\n", host); - ftp->addrtype = sin.sin_family = AF_INET; - sin.sin_addr.s_addr = temp; - } - else { - debug(ftp, "Trying to resolve `%s'\n", host); - he = gethostbyname(host); - if (!he) { - debug(ftp, "Lookup of `%s' failed!\n", host); - return zap(ftp); - } - ftp->addrtype = sin.sin_family = he->h_addrtype; - bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length); - } - - sin.sin_port = htons(FtpPort ? FtpPort : 21); - - if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) - { - debug(ftp, "Socket open failed: %s (%i)\n", strerror(errno), errno); - return zap(ftp); - } - - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - debug(ftp,"Connection failed: %s (%i)\n", strerror(errno), errno); - (void)close(s); - return zap(ftp); - } - - ftp->fd_ctrl = s; - - debug(ftp, "open (%d)\n",get_a_number(ftp,0)); - - i = cmd(ftp,"USER %s",user); - if (i >= 300 && i < 400) - i = cmd(ftp,"PASS %s",passwd); - if (i >= 299 || i < 0) { - close(ftp->fd_ctrl); ftp->fd_ctrl = -1; - return zap(ftp); - } - ftp->state = isopen; - return 0; -} - -void -FtpClose(FTP_t ftp) -{ - if (ftp->state != init) - return; - - if (ftp->state != isopen) - botch(ftp,"FtpClose","open or init"); - - debug(ftp, "FtpClose(ftp)\n"); - zap(ftp); -} - -int -FtpChdir(FTP_t ftp, char *dir) -{ - int i; - if (ftp->state != isopen) - return botch(ftp,"FtpChdir","open"); - i = cmd(ftp,"CWD %s",dir); - if (i < 0) - return i; - else if (i != 250) - return -1; - return 0; -} - -int -FtpGet(FTP_t ftp, char *file) -{ - int i,s; - char *q; - unsigned char addr[64]; - struct sockaddr_in sin; - u_long a; - - debug(ftp, "FtpGet(ftp,%s)\n",file); - if (ftp->state != isopen) - return botch(ftp,"FtpGet","open"); - if(ftp->binary) { - i = cmd(ftp,"TYPE I"); - if (i < 0) - return zap(ftp); - if (i > 299) - return -1; - } else { - return -1; - } - - if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0) - return zap(ftp); - - if (ftp->passive) { - debug(ftp, "send <%s>\n","PASV"); - if (writes(ftp->fd_ctrl,"PASV\r\n")) - return zap(ftp); - i = get_a_number(ftp,&q); - if (i < 0) - return zap(ftp); - if (i != 227) - return zap(ftp); - while (*q && !isdigit(*q)) - q++; - if (!*q) - return zap(ftp); - q--; - for(i=0;i<6;i++) { - q++; - addr[i] = strtol(q,&q,10); - } - - sin.sin_family = ftp->addrtype; - bcopy(addr, (char *)&sin.sin_addr, 4); - bcopy(addr+4, (char *)&sin.sin_port, 2); - debug(ftp, "Opening active socket to %s : %u\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); - - debug(ftp, "Connecting to %s:%u\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port)); - if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - (void)close(s); - debug(ftp, "connect: %s (%d)\n", strerror(errno), errno); - return -1; - } - ftp->fd_xfer = s; - i = cmd(ftp,"RETR %s",file); - if (i < 0) { - close(s); - return zap(ftp); - } - else if (i > 299) { - debug(ftp, "FTP: No such file %s, moving on.\n", file); - close(s); - return -1; - } - ftp->state = xfer; - return s; - } else { - i = sizeof sin; - getsockname(ftp->fd_ctrl,(struct sockaddr *)&sin,&i); - sin.sin_port = 0; - i = sizeof sin; - if (bind(s,(struct sockaddr *)&sin, i) < 0) { - close (s); - debug(ftp,"bind failed %d\n",errno); - return zap(ftp); - } - getsockname(s,(struct sockaddr *)&sin,&i); - if (listen(s,1) < 0) { - close (s); - debug(ftp,"listen failed %d\n",errno); - return zap(ftp); - } - a = ntohl(sin.sin_addr.s_addr); - i = cmd(ftp,"PORT %d,%d,%d,%d,%d,%d", - (a >> 24) & 0xff, - (a >> 16) & 0xff, - (a >> 8) & 0xff, - a & 0xff, - (ntohs(sin.sin_port) >> 8) & 0xff, - ntohs(sin.sin_port) & 0xff); - if (i != 200) - return -1; - i = cmd(ftp,"RETR %s",file); - if (i < 0) { - close(s); - return zap(ftp); - } - else if (i > 299) { - debug(ftp, "FTP: No such file %s, moving on.\n", file); - close(s); - return -1; - } - ftp->fd_xfer = accept(s, 0, 0); - if (ftp->fd_xfer < 0) { - close(s); - return zap(ftp); - } - ftp->state = xfer; - close(s); - return(ftp->fd_xfer); - } -} - -int -FtpEOF(FTP_t ftp) -{ - int i; - - if (ftp->state != xfer) - return botch(ftp,"FtpEOF","xfer"); - debug(ftp, "FtpEOF(ftp)\n"); - close(ftp->fd_xfer); ftp->fd_xfer = -1; - ftp->state = isopen; - i = get_a_number(ftp,0); - if (i < 0) - return zap(ftp); - else if (i != 250 && i != 226) - return -1; - else - return 0; -} - -#ifdef STANDALONE_FTP - -/* main.c */ -int -main(int argc, char **argv) -{ - FTP_t ftp; - int i; - char c; - - ftp = FtpInit(); - if (!ftp) - err(1, "FtpInit()"); - - FtpDebug(ftp, 1); - i = FtpOpen(ftp, "freefall.cdrom.com", "ftp", "phk-libftp@"); - FtpBinary(ftp, 1); - FtpPassive(ftp, 0); - FtpChdir(ftp, "/pub"); - FtpChdir(ftp, "FreeBSD"); - i = FtpGet(ftp, "README"); - while (1 == read(i, &c, 1)) - putchar(c); - FtpEOF(ftp); - return 0; -} - -#endif /*STANDALONE_FTP*/ diff --git a/usr.sbin/pkg_install/lib/ftp.h b/usr.sbin/pkg_install/lib/ftp.h deleted file mode 100644 index 176069bc272..00000000000 --- a/usr.sbin/pkg_install/lib/ftp.h +++ /dev/null @@ -1,28 +0,0 @@ -/* $OpenBSD: ftp.h,v 1.2 1996/06/04 08:43:43 niklas Exp $ */ - -#ifndef _FTP_H_INCLUDE -#define _FTP_H_INCLUDE - -typedef struct { - enum {init, isopen, xfer} state; - int fd_ctrl; - int fd_xfer; - int fd_debug; - int binary; - int passive; - int addrtype; - char *host; - char *file; -} *FTP_t; - -FTP_t FtpInit(); -int FtpOpen(FTP_t, char *host, char *user, char *passwd); -#define FtpBinary(ftp,bool) { (ftp)->binary = (bool); } -#define FtpPassive(ftp,bool) { (ftp)->passive = (bool); } -int FtpChdir(FTP_t, char *); -int FtpGet(FTP_t, char *); -int FtpEOF(FTP_t); -void FtpClose(FTP_t); - -#endif -/* _FTP_H_INCLUDE */ diff --git a/usr.sbin/pkg_install/lib/global.c b/usr.sbin/pkg_install/lib/global.c index c86f21a7934..dcbff4c1131 100644 --- a/usr.sbin/pkg_install/lib/global.c +++ b/usr.sbin/pkg_install/lib/global.c @@ -1,7 +1,7 @@ -/* $OpenBSD: global.c,v 1.3 1998/09/07 22:30:16 marc Exp $ */ +/* $OpenBSD: global.c,v 1.4 1998/10/13 23:09:53 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: global.c,v 1.3 1998/09/07 22:30:16 marc Exp $"; +static const char *rcsid = "$OpenBSD: global.c,v 1.4 1998/10/13 23:09:53 marc Exp $"; #endif /* @@ -31,6 +31,5 @@ static const char *rcsid = "$OpenBSD: global.c,v 1.3 1998/09/07 22:30:16 marc Ex Boolean Verbose = FALSE; Boolean Fake = FALSE; Boolean Force = FALSE; -int AutoAnswer = FALSE; diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h index 15d31a40d28..2e658b44aad 100644 --- a/usr.sbin/pkg_install/lib/lib.h +++ b/usr.sbin/pkg_install/lib/lib.h @@ -1,4 +1,4 @@ -/* $OpenBSD: lib.h,v 1.2 1998/09/07 22:30:16 marc Exp $ */ +/* $OpenBSD: lib.h,v 1.3 1998/10/13 23:09:53 marc Exp $ */ /* * FreeBSD install - a package for the installation and maintainance @@ -78,39 +78,66 @@ /* The name of the "prefix" environment variable given to scripts */ #define PKG_PREFIX_VNAME "PKG_PREFIX" -enum _plist_t { - PLIST_FILE, PLIST_CWD, PLIST_CMD, PLIST_CHMOD, - PLIST_CHOWN, PLIST_CHGRP, PLIST_COMMENT, PLIST_IGNORE, - PLIST_NAME, PLIST_UNEXEC, PLIST_SRC, PLIST_DISPLAY, - PLIST_PKGDEP, PLIST_MTREE, PLIST_DIR_RM, PLIST_IGNORE_INST, - PLIST_OPTION, PLIST_PKGCFL -}; -typedef enum _plist_t plist_t; +/* enumerated constants for plist entry types */ +typedef enum pl_ent_t { + PLIST_SHOW_ALL = -1, + PLIST_FILE, + PLIST_CWD, + PLIST_CMD, + PLIST_CHMOD, + PLIST_CHOWN, + PLIST_CHGRP, + PLIST_COMMENT, + PLIST_IGNORE, + PLIST_NAME, + PLIST_UNEXEC, + PLIST_SRC, + PLIST_DISPLAY, + PLIST_PKGDEP, + PLIST_MTREE, + PLIST_DIR_RM, + PLIST_IGNORE_INST, + PLIST_OPTION, + PLIST_PKGCFL +} pl_ent_t; /* Types */ typedef unsigned int Boolean; -struct _plist { - struct _plist *prev, *next; - char *name; - Boolean marked; - plist_t type; +/* this structure describes a packing list entry */ +typedef struct plist_t { + struct plist_t *prev; /* previous entry */ + struct plist_t *next; /* next entry */ + char *name; /* name of entry */ + Boolean marked; /* whether entry has been marked */ + pl_ent_t type; /* type of entry */ +} plist_t; + +/* this structure describes a package's complete packing list */ +typedef struct package_t { + plist_t *head; /* head of list */ + plist_t *tail; /* tail of list */ +} package_t; + +enum { + ChecksumLen = 16, + LegibleChecksumLen = 33 }; -typedef struct _plist *PackingList; -struct _pack { - struct _plist *head, *tail; -}; -typedef struct _pack Package; +/* type of function to be handed to findmatchingname; return value of this + * is currently ignored */ +typedef int (*matchfn)(const char *found, char *data); /* Prototypes */ /* Misc */ int vsystem(const char *, ...); void cleanup(int); -char *make_playpen(char *, size_t); +char *make_playpen(char *, size_t, size_t); char *where_playpen(void); void leave_playpen(char *); off_t min_free(char *); +void save_dirs(char **c, char **p); +void restore_dirs(char *c, char *p); /* String */ char *get_dash_string(char **); @@ -119,7 +146,13 @@ Boolean suffix(char *, char *); void nuke_suffix(char *); void str_lowercase(char *); char *basename_of(char *); +char *dirname_of(const char *); char *strconcat(char *, char *); +int pmatch(const char *, const char *); +int findmatchingname(const char *, const char *, matchfn, char *); /* doesn't really belong here */ +char *findbestmatchingname(const char *, const char *); /* neither */ +int ispkgpattern(const char *); +char *strnncpy(char *to, size_t tosize, char *from, size_t cc); /* File */ Boolean fexists(char *); @@ -135,37 +168,31 @@ char *fileURLFilename(char *, char *, int); char *fileURLHost(char *, char *, int); char *fileFindByPath(char *, char *); char *fileGetContents(char *); -Boolean make_preserve_name(char *, int, char *, char *); +Boolean make_preserve_name(char *, size_t, char *, char *); void write_file(char *, char *); void copy_file(char *, char *, char *); void move_file(char *, char *, char *); void copy_hierarchy(char *, char *, Boolean); int delete_hierarchy(char *, Boolean, Boolean); int unpack(char *, char *); -void format_cmd(char *, char *, char *, char *); - -/* Msg */ -void upchuck(const char *); -void barf(const char *, ...); -void whinge(const char *, ...); -Boolean y_or_n(Boolean, const char *, ...); +void format_cmd(char *, size_t , char *, char *, char *); /* Packing list */ -PackingList new_plist_entry(void); -PackingList last_plist(Package *); -PackingList find_plist(Package *, plist_t); -char *find_plist_option(Package *, char *name); -void plist_delete(Package *, Boolean, plist_t, char *); -void free_plist(Package *); -void mark_plist(Package *); -void csum_plist_entry(char *, PackingList); -void add_plist(Package *, plist_t, char *); -void add_plist_top(Package *, plist_t, char *); -void delete_plist(Package *pkg, Boolean all, plist_t type, char *name); -void write_plist(Package *, FILE *); -void read_plist(Package *, FILE *); +plist_t *new_plist_entry(void); +plist_t *last_plist(package_t *); +plist_t *find_plist(package_t *, pl_ent_t); +char *find_plist_option(package_t *, char *name); +void plist_delete(package_t *, Boolean, pl_ent_t, char *); +void free_plist(package_t *); +void mark_plist(package_t *); +void csum_plist_entry(char *, plist_t *); +void add_plist(package_t *, pl_ent_t, char *); +void add_plist_top(package_t *, pl_ent_t, char *); +void delete_plist(package_t *pkg, Boolean all, pl_ent_t type, char *name); +void write_plist(package_t *, FILE *); +void read_plist(package_t *, FILE *); int plist_cmd(char *, char **); -int delete_package(Boolean, Boolean, Package *); +int delete_package(Boolean, Boolean, package_t *); /* For all */ int pkg_perform(char **); @@ -174,6 +201,5 @@ int pkg_perform(char **); extern Boolean Verbose; extern Boolean Fake; extern Boolean Force; -extern int AutoAnswer; #endif /* _INST_LIB_LIB_H_ */ diff --git a/usr.sbin/pkg_install/lib/msg.c b/usr.sbin/pkg_install/lib/msg.c deleted file mode 100644 index 2c8a839e9e3..00000000000 --- a/usr.sbin/pkg_install/lib/msg.c +++ /dev/null @@ -1,78 +0,0 @@ -/* $OpenBSD: msg.c,v 1.3 1998/09/07 22:30:17 marc Exp $ */ - -#ifndef lint -static const char *rcsid = "$OpenBSD: msg.c,v 1.3 1998/09/07 22:30:17 marc Exp $"; -#endif - -/* - * FreeBSD install - a package for the installation and maintainance - * of non-core utilities. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * Jordan K. Hubbard - - * 18 July 1993 - * - * Miscellaneous message routines. - * - */ - -#include <err.h> -#include "lib.h" - -/* Die a relatively simple death */ -void -upchuck(const char *errstr) -{ - cleanup(0); - err(1, "fatal error during execution: %s", errstr); -} - -/* - * As a yes/no question, prompting from the varargs string and using - * default if user just hits return. - */ -Boolean -y_or_n(Boolean def, const char *msg, ...) -{ - va_list args; - int ch = 0; - FILE *tty; - - va_start(args, msg); - /* - * Need to open /dev/tty because file collection may have been - * collected on stdin - */ - tty = fopen("/dev/tty", "r"); - if (!tty) { - cleanup(0); - errx(1, "can't open /dev/tty!"); - } - while (ch != 'Y' && ch != 'N') { - vfprintf(stderr, msg, args); - if (def) - fprintf(stderr, " [yes]? "); - else - fprintf(stderr, " [no]? "); - fflush(stderr); - if (AutoAnswer) { - ch = (AutoAnswer == YES) ? 'Y' : 'N'; - fprintf(stderr, "%c\n", ch); - } - else - ch = toupper(fgetc(tty)); - if (ch == '\n') - ch = (def) ? 'Y' : 'N'; - } - fclose(tty) ; - return (ch == 'Y') ? TRUE : FALSE; -} diff --git a/usr.sbin/pkg_install/lib/pen.c b/usr.sbin/pkg_install/lib/pen.c index 893b6bbf60e..7f1f2e8d38f 100644 --- a/usr.sbin/pkg_install/lib/pen.c +++ b/usr.sbin/pkg_install/lib/pen.c @@ -1,7 +1,7 @@ -/* $OpenBSD: pen.c,v 1.7 1998/09/07 22:30:17 marc Exp $ */ +/* $OpenBSD: pen.c,v 1.8 1998/10/13 23:09:54 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: pen.c,v 1.7 1998/09/07 22:30:17 marc Exp $"; +static const char *rcsid = "$OpenBSD: pen.c,v 1.8 1998/10/13 23:09:54 marc Exp $"; #endif /* @@ -34,6 +34,28 @@ static const char *rcsid = "$OpenBSD: pen.c,v 1.7 1998/09/07 22:30:17 marc Exp $ static char Current[FILENAME_MAX]; static char Previous[FILENAME_MAX]; +/* Backup Current and Previous into temp. strings that are later + * restored & freed by restore_dirs + * This is to make nested calls to makeplaypen/leave_playpen work + */ +void +save_dirs(char **c, char **p) +{ + *c=strdup(Current); + *p=strdup(Previous); +} + +/* Restore Current and Previous from temp strings that were created + * by safe_dirs. + * This is to make nested calls to makeplaypen/leave_playpen work + */ +void +restore_dirs(char *c, char *p) +{ + strcpy(Current, c); free(c); + strcpy(Previous, p); free(p); +} + char * where_playpen(void) { @@ -42,7 +64,7 @@ where_playpen(void) /* Find a good place to play. */ static char * -find_play_pen(char *pen, size_t sz) +find_play_pen(char *pen, size_t pensize, size_t sz) { char *cp; struct stat sb; @@ -50,9 +72,9 @@ find_play_pen(char *pen, size_t sz) if (pen[0] && stat(pen, &sb) != FAIL && (min_free(pen) >= sz)) return pen; else if ((cp = getenv("PKG_TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) - sprintf(pen, "%s/instmp.XXXXXXXXXX", cp); + (void) snprintf(pen, pensize, "%s/instmp.XXXXXXXXXX", cp); else if ((cp = getenv("TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) - sprintf(pen, "%s/instmp.XXXXXXXXXX", cp); + (void) snprintf(pen, pensize, "%s/instmp.XXXXXXXXXX", cp); else if (stat("/var/tmp", &sb) != FAIL && min_free("/var/tmp") >= sz) strcpy(pen, "/var/tmp/instmp.XXXXXXXXXX"); else if (stat("/tmp", &sb) != FAIL && min_free("/tmp") >= sz) @@ -75,9 +97,9 @@ find_play_pen(char *pen, size_t sz) * pathname of previous working directory. */ char * -make_playpen(char *pen, size_t sz) +make_playpen(char *pen, size_t pensize, size_t sz) { - if (!find_play_pen(pen, sz)) + if (!find_play_pen(pen, pensize, sz)) return NULL; if (!mkdtemp(pen)) { @@ -102,8 +124,8 @@ make_playpen(char *pen, size_t sz) if (Current[0]) strcpy(Previous, Current); else if (!getcwd(Previous, FILENAME_MAX)) { - upchuck("getcwd"); - return NULL; + cleanup(0); + err(1, "fatal error during execution: getcwd"); } if (chdir(pen) == FAIL) { cleanup(0); diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c index e3844ed5721..ac53026d6d7 100644 --- a/usr.sbin/pkg_install/lib/plist.c +++ b/usr.sbin/pkg_install/lib/plist.c @@ -1,6 +1,6 @@ -/* $OpenBSD: plist.c,v 1.4 1998/09/07 22:30:17 marc Exp $ */ +/* $OpenBSD: plist.c,v 1.5 1998/10/13 23:09:54 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: plist.c,v 1.4 1998/09/07 22:30:17 marc Exp $"; +static const char *rcsid = "$OpenBSD: plist.c,v 1.5 1998/10/13 23:09:54 marc Exp $"; #endif /* @@ -27,88 +27,113 @@ static const char *rcsid = "$OpenBSD: plist.c,v 1.4 1998/09/07 22:30:17 marc Exp #include <err.h> #include <md5.h> -/* Add an item to a packing list */ +/* this struct defines a plist command type */ +typedef struct cmd_t { + char *c_s; /* string to recognise */ + pl_ent_t c_type; /* type of command */ + int c_argc; /* # of arguments */ +} cmd_t; + +/* commands to recognise */ +static cmd_t cmdv[] = { + { "cwd", PLIST_CWD, 1 }, + { "src", PLIST_SRC, 1 }, + { "cd", PLIST_CWD, 1 }, + { "exec", PLIST_CMD, 1 }, + { "unexec", PLIST_UNEXEC, 1 }, + { "mode", PLIST_CHMOD, 1 }, + { "owner", PLIST_CHOWN, 1 }, + { "group", PLIST_CHGRP, 1 }, + { "comment", PLIST_COMMENT, 1 }, + { "ignore", PLIST_IGNORE, 0 }, + { "ignore_inst", PLIST_IGNORE_INST, 0 }, + { "name", PLIST_NAME, 1 }, + { "display", PLIST_DISPLAY, 1 }, + { "pkgdep", PLIST_PKGDEP, 1 }, + { "pkgcfl", PLIST_PKGCFL, 1 }, + { "mtree", PLIST_MTREE, 1 }, + { "dirrm", PLIST_DIR_RM, 1 }, + { "option", PLIST_OPTION, 1 }, + { NULL, FAIL, 0 } +}; + +/* Add an item to the end of a packing list */ void -add_plist(Package *p, plist_t type, char *arg) +add_plist(package_t *p, pl_ent_t type, char *arg) { - PackingList tmp; - - tmp = new_plist_entry(); - tmp->name = copy_string(arg); - tmp->type = type; - - if (!p->head) - p->head = p->tail = tmp; - else { - tmp->prev = p->tail; - p->tail->next = tmp; - p->tail = tmp; - } + plist_t *tmp; + + tmp = new_plist_entry(); + tmp->name = copy_string(arg); + tmp->type = type; + if (!p->head) { + p->head = p->tail = tmp; + } else { + tmp->prev = p->tail; + p->tail->next = tmp; + p->tail = tmp; + } } +/* add an item to the start of a packing list */ void -add_plist_top(Package *p, plist_t type, char *arg) +add_plist_top(package_t *p, pl_ent_t type, char *arg) { - PackingList tmp; - - tmp = new_plist_entry(); - tmp->name = copy_string(arg); - tmp->type = type; - - if (!p->head) - p->head = p->tail = tmp; - else { - tmp->next = p->head; - p->head->prev = tmp; - p->head = tmp; - } + plist_t *tmp; + + tmp = new_plist_entry(); + tmp->name = copy_string(arg); + tmp->type = type; + if (!p->head) { + p->head = p->tail = tmp; + } else { + tmp->next = p->head; + p->head->prev = tmp; + p->head = tmp; + } } /* Return the last (most recent) entry in a packing list */ -PackingList -last_plist(Package *p) +plist_t * +last_plist(package_t *p) { - return p->tail; + return p->tail; } /* Mark all items in a packing list to prevent iteration over them */ void -mark_plist(Package *pkg) +mark_plist(package_t *pkg) { - PackingList p = pkg->head; + plist_t *pp; - while (p) { - p->marked = TRUE; - p = p->next; - } + for (pp = pkg->head ; pp ; pp = pp->next) { + pp->marked = TRUE; + } } /* Find a given item in a packing list and, if so, return it (else NULL) */ -PackingList -find_plist(Package *pkg, plist_t type) +plist_t * +find_plist(package_t *pkg, pl_ent_t type) { - PackingList p = pkg->head; + plist_t *pp; - while (p) { - if (p->type == type) - return p; - p = p->next; - } - return NULL; + for (pp = pkg->head ; pp && pp->type != type ; pp = pp->next) { + } + return pp; } /* Look for a specific boolean option argument in the list */ char * -find_plist_option(Package *pkg, char *name) +find_plist_option(package_t *pkg, char *name) { - PackingList p = pkg->head; + plist_t *p; - while (p) { - if (p->type == PLIST_OPTION && !strcmp(p->name, name)) - return p->name; - p = p->next; - } - return NULL; + for (p = pkg->head ; p ; p = p->next) { + if (p->type == PLIST_OPTION && strcmp(p->name, name) == 0) { + return p->name; + } + } + return (char *) NULL; } /* @@ -116,12 +141,12 @@ find_plist_option(Package *pkg, char *name) * too.) If 'all' is set, delete all items, not just the first occurance. */ void -delete_plist(Package *pkg, Boolean all, plist_t type, char *name) +delete_plist(package_t *pkg, Boolean all, pl_ent_t type, char *name) { - PackingList p = pkg->head; + plist_t *p = pkg->head; while (p) { - PackingList pnext = p->next; + plist_t *pnext = p->next; if (p->type == type && (!name || !strcmp(name, p->name))) { free(p->name); @@ -144,24 +169,26 @@ delete_plist(Package *pkg, Boolean all, plist_t type, char *name) } /* Allocate a new packing list entry */ -PackingList +plist_t * new_plist_entry(void) { - PackingList ret; + plist_t *ret; - ret = (PackingList)malloc(sizeof(struct _plist)); - memset(ret, 0, sizeof(struct _plist)); - return ret; + if ((ret = (plist_t *)malloc(sizeof(plist_t))) == (plist_t *) NULL) { + err(1, "can't allocate %d bytes", sizeof(plist_t)); + } + memset(ret, 0, sizeof(plist_t)); + return ret; } /* Free an entire packing list */ void -free_plist(Package *pkg) +free_plist(package_t *pkg) { - PackingList p = pkg->head; + plist_t *p = pkg->head; while (p) { - PackingList p1 = p->next; + plist_t *p1 = p->next; free(p->name); free(p); @@ -177,67 +204,31 @@ free_plist(Package *pkg) int plist_cmd(char *s, char **arg) { - char cmd[FILENAME_MAX + 20]; /* 20 == fudge for max cmd len */ - char *cp, *sp; - - strcpy(cmd, s); - str_lowercase(cmd); - cp = cmd; - sp = s; - while (*cp) { - if (isspace(*cp)) { - *cp = '\0'; - while (isspace(*sp)) /* Never sure if macro, increment later */ - ++sp; - break; + cmd_t *cmdp; + char cmd[FILENAME_MAX + 20]; /* 20 == fudge for max cmd len */ + char *cp; + char *sp; + + (void) strcpy(cmd, s); + str_lowercase(cmd); + for (cp = cmd, sp = s ; *cp ; cp++, sp++) { + if (isspace(*cp)) { + for (*cp = '\0'; isspace(*sp) ; sp++) { + } + break; + } } - ++cp, ++sp; - } - if (arg) - *arg = sp; - if (!strcmp(cmd, "cwd")) - return PLIST_CWD; - else if (!strcmp(cmd, "srcdir")) - return PLIST_SRC; - else if (!strcmp(cmd, "cd")) - return PLIST_CWD; - else if (!strcmp(cmd, "exec")) - return PLIST_CMD; - else if (!strcmp(cmd, "unexec")) - return PLIST_UNEXEC; - else if (!strcmp(cmd, "mode")) - return PLIST_CHMOD; - else if (!strcmp(cmd, "owner")) - return PLIST_CHOWN; - else if (!strcmp(cmd, "group")) - return PLIST_CHGRP; - else if (!strcmp(cmd, "comment")) - return PLIST_COMMENT; - else if (!strcmp(cmd, "ignore")) - return PLIST_IGNORE; - else if (!strcmp(cmd, "ignore_inst")) - return PLIST_IGNORE_INST; - else if (!strcmp(cmd, "name")) - return PLIST_NAME; - else if (!strcmp(cmd, "display")) - return PLIST_DISPLAY; - else if (!strcmp(cmd, "pkgdep")) - return PLIST_PKGDEP; - else if (!strcmp(cmd, "pkgcfl")) - return PLIST_PKGCFL; - else if (!strcmp(cmd, "mtree")) - return PLIST_MTREE; - else if (!strcmp(cmd, "dirrm")) - return PLIST_DIR_RM; - else if (!strcmp(cmd, "option")) - return PLIST_OPTION; - else - return FAIL; + if (arg) { + *arg = sp; + } + for (cmdp = cmdv ; cmdp->c_s && strcmp(cmdp->c_s, cmd) != 0 ; cmdp++) { + } + return cmdp->c_type; } /* Read a packing list from a file */ void -read_plist(Package *pkg, FILE *fp) +read_plist(package_t *pkg, FILE *fp) { char *cp, pline[FILENAME_MAX]; int cmd; @@ -267,88 +258,28 @@ read_plist(Package *pkg, FILE *fp) /* Write a packing list to a file, converting commands to ascii equivs */ void -write_plist(Package *pkg, FILE *fp) +write_plist(package_t *pkg, FILE *fp) { - PackingList plist = pkg->head; - - while (plist) { - switch(plist->type) { - case PLIST_FILE: - fprintf(fp, "%s\n", plist->name); - break; - - case PLIST_CWD: - fprintf(fp, "%ccwd %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_SRC: - fprintf(fp, "%csrcdir %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_CMD: - fprintf(fp, "%cexec %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_UNEXEC: - fprintf(fp, "%cunexec %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_CHMOD: - fprintf(fp, "%cmode %s\n", CMD_CHAR, plist->name ? plist->name : ""); - break; - - case PLIST_CHOWN: - fprintf(fp, "%cowner %s\n", CMD_CHAR, plist->name ? plist->name : ""); - break; - - case PLIST_CHGRP: - fprintf(fp, "%cgroup %s\n", CMD_CHAR, plist->name ? plist->name : ""); - break; - - case PLIST_COMMENT: - fprintf(fp, "%ccomment %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_IGNORE: - case PLIST_IGNORE_INST: /* a one-time non-ignored file */ - fprintf(fp, "%cignore\n", CMD_CHAR); - break; - - case PLIST_NAME: - fprintf(fp, "%cname %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_DISPLAY: - fprintf(fp, "%cdisplay %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_PKGDEP: - fprintf(fp, "%cpkgdep %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_PKGCFL: - fprintf(fp, "%cpkgcfl %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_MTREE: - fprintf(fp, "%cmtree %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_DIR_RM: - fprintf(fp, "%cdirrm %s\n", CMD_CHAR, plist->name); - break; - - case PLIST_OPTION: - fprintf(fp, "%coption %s\n", CMD_CHAR, plist->name); - break; - - default: - cleanup(0); - errx(2, "unknown command type %d (%s)", plist->type, plist->name); - break; + plist_t *p; + cmd_t *cmdp; + + for (p = pkg->head ; p ; p = p->next) { + if (p->type == PLIST_FILE) { + /* Fast-track files - these are the most common */ + (void) fprintf(fp, "%s\n", p->name); + continue; + } + for (cmdp = cmdv ; cmdp->c_type != FAIL && cmdp->c_type != p->type ; cmdp++) { + } + if (cmdp->c_type == FAIL) { + warnx("Unknown PLIST command type %d (%s)", p->type, p->name); + } else if (cmdp->c_argc == 0) { + (void) fprintf(fp, "%c%s\n", CMD_CHAR, cmdp->c_s); + } else { + (void) fprintf(fp, "%c%s %s\n", CMD_CHAR, cmdp->c_s, + (p->name) ? p->name : ""); + } } - plist = plist->next; - } } /* @@ -358,11 +289,11 @@ write_plist(Package *pkg, FILE *fp) * run it too in cases of failure. */ int -delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg) +delete_package(Boolean ign_err, Boolean nukedirs, package_t *pkg) { - PackingList p; + plist_t *p; char *Where = ".", *last_file = ""; - Boolean fail = SUCCESS; + int fail = SUCCESS; Boolean preserve; char tmp[FILENAME_MAX], *name = NULL; @@ -384,7 +315,7 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg) break; case PLIST_UNEXEC: - format_cmd(tmp, p->name, Where, last_file); + format_cmd(tmp, sizeof(tmp), p->name, Where, last_file); if (Verbose) printf("Execute `%s'\n", tmp); if (!Fake && system(tmp)) { @@ -395,14 +326,14 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg) case PLIST_FILE: last_file = p->name; - sprintf(tmp, "%s/%s", Where, p->name); + (void) snprintf(tmp, sizeof(tmp), "%s/%s", Where, p->name); if (isdir(tmp)) { warnx("attempting to delete directory `%s' as a file\n" "this packing list is incorrect - ignoring delete request", tmp); } else { if (p->next && p->next->type == PLIST_COMMENT && !strncmp(p->next->name, "MD5:", 4)) { - char *cp, buf[33]; + char *cp, buf[LegibleChecksumLen]; if ((cp = MD5File(tmp, buf)) != NULL) { /* Mismatch? */ @@ -438,7 +369,7 @@ delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg) break; case PLIST_DIR_RM: - sprintf(tmp, "%s/%s", Where, p->name); + (void) snprintf(tmp, sizeof(tmp), "%s/%s", Where, p->name); if (!isdir(tmp)) { warnx("attempting to delete file `%s' as a directory\n" "this packing list is incorrect - ignoring delete request", tmp); diff --git a/usr.sbin/pkg_install/lib/str.c b/usr.sbin/pkg_install/lib/str.c index 899fa6003cf..572add98089 100644 --- a/usr.sbin/pkg_install/lib/str.c +++ b/usr.sbin/pkg_install/lib/str.c @@ -1,7 +1,7 @@ -/* $OpenBSD: str.c,v 1.3 1997/01/17 07:14:17 millert Exp $ */ +/* $OpenBSD: str.c,v 1.4 1998/10/13 23:09:54 marc Exp $ */ #ifndef lint -static const char *rcsid = "$OpenBSD: str.c,v 1.3 1997/01/17 07:14:17 millert Exp $"; +static const char *rcsid = "$OpenBSD: str.c,v 1.4 1998/10/13 23:09:54 marc Exp $"; #endif /* @@ -24,17 +24,41 @@ static const char *rcsid = "$OpenBSD: str.c,v 1.3 1997/01/17 07:14:17 millert Ex * */ +#include <err.h> +#include <fnmatch.h> #include "lib.h" /* Return the filename portion of a path */ char * basename_of(char *str) { - char *basename = str + strlen(str) - 1; + char *slash; - while (basename != str && basename[-1] != '/') - --basename; - return basename; + return ((slash = strrchr(str, '/')) == (char *) NULL) ? str : slash + 1; +} + +/* Return the dirname portion of a path */ +char * +dirname_of(const char *path) +{ + size_t cc; + char *s; + char *t; + + if ((s = strrchr(path, '/')) == (char *) NULL) { + return "."; + } + if (s == path) { + /* "/foo" -> return "/" */ + return "/"; + } + cc = (size_t)(s - path) + 1; + if ((t = (char *) malloc(cc)) == (char *) NULL) { + errx(1, "out of memory in dirname_of"); + } + (void) memcpy(t, path, cc); + t[cc] = 0; + return t; } char * @@ -110,3 +134,250 @@ str_lowercase(char *str) ++str; } } + + +enum deweycmp_ops { + GT, + GE, + LT, + LE +}; + +/* compare two dewey decimal numbers */ +static int +deweycmp(char *a, enum deweycmp_ops op, char *b) +{ + int ad; + int bd; + int cmp; + + for (;;) { + if (*a == 0 && *b == 0) { + cmp = 0; + break; + } + ad = bd = 0; + for (; *a && *a != '.'; a++) { + ad = (ad * 10) + (*a - '0'); + } + for (; *b && *b != '.'; b++) { + bd = (bd * 10) + (*b - '0'); + } + if ((cmp = ad - bd) != 0) { + break; + } + if (*a == '.') { + a++; + } + if (*b == '.') { + b++; + } + } + return (op == GE) ? cmp >= 0 : (op == GT) ? cmp > 0 : (op == LE) ? cmp <= 0 : cmp < 0; +} + +/* perform alternate match on "pkg" against "pattern", */ +/* calling pmatch (recursively) to resolve any other patterns */ +/* return 1 on match, 0 otherwise */ +static int +alternate_match(const char *pattern, const char *pkg) +{ + char *sep; + char buf[FILENAME_MAX]; + char *last; + char *alt; + char *cp; + int cnt; + int found; + + if ((sep = strchr(pattern, '{')) == (char *) NULL) { + errx(1, "alternate_match(): '{' expected in \"%s\"\n", pattern); + } + (void) strncpy(buf, pattern, (size_t)(sep - pattern)); + alt = &buf[sep - pattern]; + last = (char *) NULL; + for (cnt = 0, cp = sep; *cp && last == (char *) NULL ; cp++) { + if (*cp == '{') { + cnt++; + } else if (*cp == '}' && --cnt == 0 && last == (char *) NULL) { + last = cp + 1; + } + } + if (cnt != 0) { + warnx("Malformed alternate `%s'", pattern); + return 1; + } + for (found = 0, cp = sep + 1; *sep != '}'; cp = sep + 1) { + for (cnt = 0, sep = cp; cnt > 0 || (cnt == 0 && *sep != '}' && *sep != ','); sep++) { + if (*sep == '{') { + cnt++; + } else if (*sep == '}') { + cnt--; + } + } + (void) snprintf(alt, sizeof(buf) - (alt - buf), "%.*s%s", (int) (sep - cp), cp, last); + if (pmatch(buf, pkg) == 1) { + found = 1; + } + } + return found; +} + +/* perform dewey match on "pkg" against "pattern" */ +/* return 1 on match, 0 otherwise */ +static int +dewey_match(const char *pattern, const char *pkg) +{ + char *cp; + char *sep; + char *ver; + int found; + enum deweycmp_ops op; + int n; + char name[FILENAME_MAX]; + + found = 0; + if ((sep = strpbrk(pattern, "<>")) == NULL) + errx(1, "dewey_match(): '<' or '>' expexted in \"%s\"\n", pattern); + + /* next three lines are static in loops, too (-> cache!) */ + snprintf(name, sizeof(name), "%.*s", (int) (sep - pattern), pattern); + op = (*sep == '>') ? (*(sep + 1) == '=') ? GE : GT : (*(sep + 1) == '=') ? LE : LT; + ver = (op == GE || op == LE) ? sep + 2 : sep + 1; + n = (int)(sep - pattern); + if ((cp = strrchr(pkg, '-')) != (char *) NULL) { + if (strncmp(pkg, name, (size_t)(cp - pkg)) == 0 && n == cp - pkg) { + if (deweycmp(cp + 1, op, ver)) { + found = 1; + } + } + } + return found; +} + +/* perform glob match on "pkg" against "pattern" */ +/* return 1 on match, 0 otherwise */ +static int +glob_match(const char *pattern, const char *pkg) +{ + return fnmatch(pattern, pkg, FNM_PERIOD) == 0; +} + +/* perform simple match on "pkg" against "pattern" */ +/* return 1 on match, 0 otherwise */ +static int +simple_match(const char *pattern, const char *pkg) +{ + return !strcmp(pattern, pkg); +} + +/* match pkg against pattern, return 1 if matching, 0 else */ +/* + * Optimize: this is called many times in readdir()-loops, where the + * pattern doesn't change, so the {,} alternates may be unrolles/cached. + */ +int +pmatch(const char *pattern, const char *pkg) +{ + if (strchr(pattern, '{')) { + /* emulate csh-type alternates */ + return alternate_match(pattern, pkg); + } + if (strpbrk(pattern, "<>")) { + /* perform relational dewey match on version number */ + return dewey_match(pattern, pkg); + } + if (strpbrk(pattern, "*?[]")) { + /* glob match */ + return glob_match(pattern, pkg); + } + /* no alternate, dewey or glob match -> simple compare */ + return simple_match(pattern, pkg); +} + + +/* search dir for pattern, writing the found match in buf */ +/* let's hope there's only one ... - HF */ +/* returns -1 on error, 1 if found, 0 otherwise. */ +int +findmatchingname(const char *dir, const char *pattern, matchfn f, char *data) +{ + struct dirent *dp; + DIR *dirp; + int found; + + found = 0; + if ((dirp = opendir(dir)) == NULL) { + /* warnx("can't opendir dir '%s'", dir); */ + return -1; + } + while ((dp = readdir(dirp)) != NULL) { + if (strcmp(dp->d_name, ".") == 0 || + strcmp(dp->d_name, "..") == 0) { + continue; + } + if (pmatch(pattern, dp->d_name)) { + if(f) + f(dp->d_name, data); + found=1; + } + } + closedir(dirp); + + return found; +} + +/* does the pkgname contain any of the special chars ("{[]?*<>")? */ +/* if so, return 1, else 0 */ +int +ispkgpattern(const char *pkg) +{ + return strpbrk(pkg, "<>[]?*{") != NULL; +} + +/* auxiliary function called by findbestmatchingname() */ +static int +findbestmatchingname_fn(const char *pkg, char *data) +{ + /* if pkg > data */ + char *s1, *s2; + + s1=strrchr(pkg, '-')+1; + s2=strrchr(data, '-')+1; + + if(data[0] == '\0' || deweycmp(s1, GT, s2)) + strcpy(data, pkg); + + return 0; +} + +/* find best matching filename, i.e. the pkg with the highest + * matching(!) version */ +/* returns pointer to pkg name (which can be free(3)ed), + * or NULL if no match is available. */ +char * +findbestmatchingname(const char *dir, const char *pattern) +{ + char buf[FILENAME_MAX]; + + buf[0]='\0'; + if (findmatchingname(dir, pattern, findbestmatchingname_fn, buf) > 0 + && buf[0] != '\0') { + return strdup(buf); + } + return NULL; +} + +/* bounds-checking strncpy */ +char * +strnncpy(char *to, size_t tosize, char *from, size_t cc) +{ + size_t len; + + if ((len = cc) >= tosize - 1) { + len = tosize - 1; + } + (void) strncpy(to, from, len); + to[len] = 0; + return to; +} diff --git a/usr.sbin/pkg_install/tkpkg b/usr.sbin/pkg_install/tkpkg index 656d90f78ff..b8d25bb0a62 100644 --- a/usr.sbin/pkg_install/tkpkg +++ b/usr.sbin/pkg_install/tkpkg @@ -1,8 +1,7 @@ #!/usr/local/bin/wish -f -#$OpenBSD: tkpkg,v 1.2 1998/09/07 22:30:12 marc Exp $ +#$OpenBSD: tkpkg,v 1.3 1998/10/13 23:09:48 marc Exp $ # from FreeBSD Id: tkpkg,v 1.4 1997/02/22 16:09:13 peter Exp # -# set pkgname "" wm title . "Package Installation" #-------------------------------------------------------------- |