Index: stable/2.2/usr.sbin/pkg_install/Makefile.inc =================================================================== --- stable/2.2/usr.sbin/pkg_install/Makefile.inc (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/Makefile.inc (revision 40699) @@ -1,2 +1,10 @@ +# $Id$ + +.if exists(${.OBJDIR}/../lib) +LIBINSTALL= ${.OBJDIR}/../lib/libinstall.a +.else +LIBINSTALL= ${.CURDIR}/../lib/libinstall.a +.endif + # Inherit BINDIR from one level up. .include "../Makefile.inc" Index: stable/2.2/usr.sbin/pkg_install/add/Makefile =================================================================== --- stable/2.2/usr.sbin/pkg_install/add/Makefile (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/add/Makefile (revision 40699) @@ -1,18 +1,12 @@ +# $Id$ + PROG= pkg_add CFLAGS+= ${DEBUG} -I${.CURDIR}/../lib -.if exists(${.OBJDIR}/../lib) -LDADD+= -L${.OBJDIR}/../lib -linstall -DPADD+= ${.OBJDIR}/../lib/libinstall.a -.else -LDADD+= -L${.CURDIR}/../lib -linstall -DPADD+= ${.CURDIR}/../lib/libinstall.a -.endif - -LDADD+= -lftpio -lmd -DPADD+= ${LIBFTPIO} ${LIBMD} +DPADD= ${LIBINSTALL} ${LIBFTPIO} ${LIBMD} +LDADD= ${LIBINSTALL} -lftpio -lmd SRCS= main.c perform.c futil.c extract.c .include Index: stable/2.2/usr.sbin/pkg_install/add/extract.c =================================================================== --- stable/2.2/usr.sbin/pkg_install/add/extract.c (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/add/extract.c (revision 40699) @@ -1,256 +1,256 @@ #ifndef lint static const char rcsid[] = - "$Id: extract.c,v 1.7.6.11 1998/07/04 14:12:19 jkh Exp $"; + "$Id: extract.c,v 1.7.6.12 1998/09/11 07:27:17 jkh 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 * * This is the package extraction code for the add module. * */ #include #include "lib.h" #include "add.h" #define STARTSTRING "tar cf - " #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 %d byte tar pipeline: %s", \ 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) { PackingList q; char try[FILENAME_MAX], bup[FILENAME_MAX], *dir; dir = home; for (q = start; q != stop; q = q->next) { if (q->type == PLIST_FILE) { snprintf(try, FILENAME_MAX, "%s/%s", dir, q->name); if (make_preserve_name(bup, FILENAME_MAX, name, try) && fexists(bup)) { (void)chflags(try, 0); (void)unlink(try); if (rename(bup, try)) warnx("rollback: unable to rename %s back to %s", bup, try); } } else if (q->type == PLIST_CWD) { if (strcmp(q->name, ".")) dir = q->name; else dir = home; } } } void extract_plist(char *home, Package *pkg) { PackingList p = pkg->head; char *last_file; char *where_args, *perm_args, *last_chdir; int maxargs, where_count = 0, perm_count = 0, add_count; Boolean preserve; 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"); } perm_args = alloca(maxargs); 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; last_chdir = 0; preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE; /* Reset the world */ Owner = NULL; Group = NULL; Mode = NULL; last_file = NULL; Directory = home; /* Do it */ while (p) { char cmd[FILENAME_MAX]; switch(p->type) { case PLIST_NAME: PkgName = p->name; if (Verbose) printf("extract: Package name is %s\n", p->name); break; case PLIST_FILE: last_file = p->name; if (Verbose) printf("extract: %s/%s\n", Directory, p->name); if (!Fake) { char try[FILENAME_MAX]; 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); if (fexists(try)) { (void)chflags(try, 0); /* XXX hack - if truly immutable, rename fails */ if (preserve && PkgName) { char pf[FILENAME_MAX]; if (make_preserve_name(pf, FILENAME_MAX, PkgName, try)) { if (rename(try, pf)) { warnx( "unable to back up %s to %s, aborting pkg_add", try, pf); rollback(PkgName, home, pkg->head, p); return; } } } } if (rename(p->name, try) == 0) { /* try to add to list of perms to be changed and run in bulk. */ if (p->name[0] == '/' || TOOBIG(p->name)) { 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!"); } perm_count += add_count; } else { /* rename failed, try copying with a big tar command */ if (last_chdir != Directory) { if (last_chdir == NULL) { PUSHOUT(Directory); } else { PUSHOUT(last_chdir); } last_chdir = Directory; } else if (p->name[0] == '/' || TOOBIG(p->name)) { 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!"); } 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!"); } perm_count += add_count; } } break; case PLIST_CWD: if (Verbose) 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); + errx(2, "unable to cwd to '%s'", p->name); } Directory = p->name; } else Directory = home; break; case PLIST_CMD: if ((strstr(p->name, "%B") || strstr(p->name, "%F") || strstr(p->name, "%f")) && last_file == NULL) { cleanup(0); errx(2, "no last file specified for '%s' command", p->name); } if (strstr(p->name, "%D") && Directory == NULL) { cleanup(0); errx(2, "no directory specified for '%s' command", p->name); } format_cmd(cmd, p->name, Directory, last_file); PUSHOUT(Directory); if (Verbose) printf("extract: execute '%s'\n", cmd); if (!Fake && system(cmd)) warnx("command '%s' failed", cmd); break; case PLIST_CHMOD: PUSHOUT(Directory); Mode = p->name; break; case PLIST_CHOWN: PUSHOUT(Directory); Owner = p->name; break; case PLIST_CHGRP: PUSHOUT(Directory); Group = p->name; break; case PLIST_COMMENT: break; case PLIST_IGNORE: p = p->next; break; } p = p->next; } PUSHOUT(Directory); } Index: stable/2.2/usr.sbin/pkg_install/add/perform.c =================================================================== --- stable/2.2/usr.sbin/pkg_install/add/perform.c (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/add/perform.c (revision 40699) @@ -1,494 +1,497 @@ #ifndef lint static const char rcsid[] = - "$Id: perform.c,v 1.37.2.12 1998/09/08 03:03:12 jkh Exp $"; + "$Id: perform.c,v 1.37.2.13 1998/09/11 07:27:17 jkh 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 * * This is the main body of the add module. * */ #include #include "lib.h" #include "add.h" #include #include static int pkg_do(char *); static int sanity_check(char *); static char LogDir[FILENAME_MAX]; +static int zapLogDir; /* Should we delete LogDir? */ int pkg_perform(char **pkgs) { int i, err_cnt = 0; signal(SIGINT, cleanup); signal(SIGHUP, cleanup); if (AddMode == SLAVE) err_cnt = pkg_do(NULL); else { for (i = 0; pkgs[i]; i++) err_cnt += pkg_do(pkgs[i]); } return err_cnt; } static Package Plist; static char *Home; /* * This is seriously ugly code following. Written very fast! * [And subsequently made even worse.. Sigh! This code was just born * to be hacked, I guess.. :) -jkh] */ static int pkg_do(char *pkg) { char pkg_fullname[FILENAME_MAX]; char playpen[FILENAME_MAX]; char extract_contents[FILENAME_MAX]; char *where_to, *tmp, *extract; FILE *cfile; int code; PackingList p; struct stat sb; int inPlace; code = 0; + zapLogDir = 0; LogDir[0] = '\0'; strcpy(playpen, FirstPen); inPlace = 0; /* Are we coming in for a second pass, everything already extracted? */ if (!pkg) { fgets(playpen, FILENAME_MAX, stdin); playpen[strlen(playpen) - 1] = '\0'; /* pesky newline! */ if (chdir(playpen) == FAIL) { warnx("pkg_add in SLAVE mode can't chdir to %s", playpen); return 1; } read_plist(&Plist, stdin); where_to = playpen; } /* Nope - do it now */ else { /* Is it an ftp://foo.bar.baz/file.tgz specification? */ if (isURL(pkg)) { if (!(Home = fileGetURL(NULL, pkg))) { warnx("unable to fetch `%s' by URL", pkg); return 1; } where_to = Home; strcpy(pkg_fullname, pkg); cfile = fopen(CONTENTS_FNAME, "r"); if (!cfile) { warnx( "unable to open table of contents file `%s' - not a package?", CONTENTS_FNAME); goto bomb; } read_plist(&Plist, cfile); fclose(cfile); } else { strcpy(pkg_fullname, pkg); /* copy for sanity's sake, could remove pkg_fullname */ if (strcmp(pkg, "-")) { if (stat(pkg_fullname, &sb) == FAIL) { warnx("can't stat package file '%s'", pkg_fullname); goto bomb; } sprintf(extract_contents, "--fast-read %s", CONTENTS_FNAME); extract = extract_contents; } else { extract = NULL; sb.st_size = 100000; /* Make up a plausible average size */ } Home = make_playpen(playpen, sb.st_size * 4); if (!Home) errx(1, "unable to make playpen for %d bytes", sb.st_size * 4); where_to = Home; /* Since we can call ourselves recursively, keep notes on where we came from */ if (!getenv("_TOP")) setenv("_TOP", Home, 1); if (unpack(pkg_fullname, extract)) { warnx( "unable to extract table of contents file from `%s' - not a package?", pkg_fullname); goto bomb; } cfile = fopen(CONTENTS_FNAME, "r"); if (!cfile) { warnx( "unable to open table of contents file `%s' - not a package?", CONTENTS_FNAME); goto bomb; } read_plist(&Plist, cfile); fclose(cfile); /* Extract directly rather than moving? Oh goodie! */ if (find_plist_option(&Plist, "extract-in-place")) { if (Verbose) printf("Doing in-place extraction for %s\n", pkg_fullname); p = find_plist(&Plist, PLIST_CWD); if (p) { if (!isdir(p->name) && !Fake) { 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; } } where_to = p->name; inPlace = 1; } else { warnx( "no prefix specified in `%s' - this is a bad package!", pkg_fullname); goto bomb; } } /* * Apply a crude heuristic to see how much space the package will * take up once it's unpacked. I've noticed that most packages * compress an average of 75%, so multiply by 4 for good measure. */ if (!inPlace && min_free(playpen) < sb.st_size * 4) { warnx("projected size of %d 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); warnx("not extracting %s\ninto %s, sorry!", pkg_fullname, where_to); goto bomb; } /* If this is a direct extract and we didn't want it, stop now */ if (inPlace && Fake) goto success; /* Finally unpack the whole mess */ if (unpack(pkg_fullname, NULL)) { warnx("unable to extract `%s'!", pkg_fullname); goto bomb; } } /* Check for sanity and dependencies */ if (sanity_check(pkg)) goto bomb; /* If we're running in MASTER mode, just output the plist and return */ if (AddMode == MASTER) { printf("%s\n", where_playpen()); write_plist(&Plist, stdout); return 0; } } /* * If we have a prefix, delete the first one we see and add this * one in place of it. */ if (Prefix) { delete_plist(&Plist, FALSE, PLIST_CWD, NULL); add_plist_top(&Plist, PLIST_CWD, Prefix); } setenv(PKG_PREFIX_VNAME, (p = find_plist(&Plist, PLIST_CWD)) ? p->name : ".", 1); /* Protect against old packages with bogus @name fields */ 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); if (isdir(LogDir) && !Force) { warnx("package `%s' already recorded as installed", PkgName); code = 1; goto success; /* close enough for government work */ } /* Now check the packing list for dependencies */ for (p = Plist.head; p ; p = p->next) { if (p->type != PLIST_PKGDEP) continue; if (Verbose) printf("Package `%s' depends on `%s'.\n", PkgName, p->name); if (vsystem("pkg_info -e %s", p->name)) { char path[FILENAME_MAX], *cp = NULL; if (!Fake) { if (!isURL(pkg) && !getenv("PKG_ADD_BASE")) { snprintf(path, FILENAME_MAX, "%s/%s.tgz", getenv("_TOP"), p->name); if (fexists(path)) cp = path; else cp = fileFindByPath(pkg, p->name); if (cp) { if (Verbose) printf("Loading it from %s.\n", cp); if (vsystem("pkg_add %s%s", Verbose ? "-v " : "", cp)) { warnx("autoload of dependency `%s' failed%s", cp, Force ? " (proceeding anyway)" : "!"); if (!Force) ++code; } } else { warnx("could not find package %s %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")) { warnx("autoloaded package %s has no +CONTENTS file?", p->name); if (!Force) ++code; } else if (vsystem("(pwd; cat +CONTENTS) | pkg_add %s-S", Verbose ? "-v " : "")) { warnx("pkg_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(); } } else { if (Verbose) printf("and was not found%s.\n", Force ? " (proceeding anyway)" : ""); else printf("Package dependency %s for %s not found%s\n", p->name, pkg, Force ? " (proceeding anyway)" : "!"); if (!Force) ++code; } } else if (Verbose) printf(" - already installed.\n"); } if (code != 0) goto bomb; /* Look for the requirements file */ if (fexists(REQUIRE_FNAME)) { vsystem("chmod +x %s", REQUIRE_FNAME); /* be sure */ if (Verbose) printf("Running requirements file first for %s..\n", PkgName); if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, PkgName)) { warnx("package %s fails requirements %s", pkg_fullname, Force ? "installing anyway" : "- not installed"); if (!Force) { code = 1; goto success; /* close enough for government work */ } } } /* If we're really installing, and have an installation file, run it */ if (!NoInstall && fexists(INSTALL_FNAME)) { vsystem("chmod +x %s", INSTALL_FNAME); /* make sure */ if (Verbose) printf("Running install with PRE-INSTALL for %s..\n", PkgName); if (!Fake && vsystem("./%s %s PRE-INSTALL", INSTALL_FNAME, PkgName)) { warnx("install script returned error status"); unlink(INSTALL_FNAME); code = 1; goto success; /* nothing to uninstall yet */ } } /* Now finally extract the entire show if we're not going direct */ if (!inPlace && !Fake) extract_plist(".", &Plist); if (!Fake && fexists(MTREE_FNAME)) { if (Verbose) 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 : "/"); if (!Fake) { if (vsystem("/usr/sbin/mtree -U -f %s -d -e -p %s", MTREE_FNAME, p ? p->name : "/")) warnx("mtree returned a non-zero status - continuing"); } unlink(MTREE_FNAME); } /* Run the installation script one last time? */ if (!NoInstall && fexists(INSTALL_FNAME)) { if (Verbose) printf("Running install with POST-INSTALL for %s..\n", PkgName); if (!Fake && vsystem("./%s %s POST-INSTALL", INSTALL_FNAME, PkgName)) { warnx("install script returned error status"); unlink(INSTALL_FNAME); code = 1; goto fail; } unlink(INSTALL_FNAME); } /* Time to record the deed? */ if (!NoRecord && !Fake) { char contents[FILENAME_MAX]; FILE *cfile; umask(022); if (getuid() != 0) warnx("not running as root - trying to record install anyway"); if (!PkgName) { warnx("no package name! can't record package, sorry"); code = 1; goto success; /* well, partial anyway */ } sprintf(LogDir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, PkgName); + zapLogDir = 1; if (Verbose) printf("Attempting to record package into %s..\n", LogDir); if (make_hierarchy(LogDir)) { warnx("can't record package into '%s', you're on your own!", LogDir); bzero(LogDir, FILENAME_MAX); code = 1; goto success; /* close enough for government work */ } /* Make sure pkg_info can read the entry */ vsystem("chmod a+rx %s", LogDir); if (fexists(DEINSTALL_FNAME)) move_file(".", DEINSTALL_FNAME, LogDir); if (fexists(REQUIRE_FNAME)) move_file(".", REQUIRE_FNAME, LogDir); sprintf(contents, "%s/%s", LogDir, CONTENTS_FNAME); cfile = fopen(contents, "w"); if (!cfile) { warnx("can't open new contents file '%s'! can't register pkg", contents); goto success; /* can't log, but still keep pkg */ } write_plist(&Plist, cfile); fclose(cfile); move_file(".", DESC_FNAME, LogDir); move_file(".", COMMENT_FNAME, LogDir); if (fexists(DISPLAY_FNAME)) move_file(".", DISPLAY_FNAME, LogDir); 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); cfile = fopen(contents, "a"); if (!cfile) warnx("can't open dependency file '%s'!\n" "dependency registration is incomplete", contents); else { fprintf(cfile, "%s\n", PkgName); if (fclose(cfile) == EOF) warnx("cannot properly close file %s", contents); } } if (Verbose) printf("Package %s registered in %s\n", PkgName, LogDir); } if ((p = find_plist(&Plist, PLIST_DISPLAY)) != NULL) { FILE *fp; char buf[BUFSIZ]; snprintf(buf, sizeof buf, "%s/%s", LogDir, p->name); fp = fopen(buf, "r"); if (fp) { putc('\n', stdout); while (fgets(buf, sizeof(buf), fp)) fputs(buf, stdout); putc('\n', stdout); (void) fclose(fp); } else warnx("cannot open %s as display file", buf); } goto success; bomb: code = 1; goto success; fail: /* Nuke the whole (installed) show, XXX but don't clean directories */ if (!Fake) delete_package(FALSE, FALSE, &Plist); success: /* delete the packing list contents */ free_plist(&Plist); leave_playpen(); return code; } static int sanity_check(char *pkg) { int code = 0; if (!fexists(CONTENTS_FNAME)) { warnx("package %s has no CONTENTS file!", pkg); code = 1; } else if (!fexists(COMMENT_FNAME)) { warnx("package %s has no COMMENT file!", pkg); code = 1; } else if (!fexists(DESC_FNAME)) { warnx("package %s has no DESC file!", pkg); code = 1; } return code; } void cleanup(int sig) { static int in_cleanup = 0; if (!in_cleanup) { in_cleanup = 1; if (sig) printf("Signal %d received, cleaning up..\n", sig); - if (!Fake && LogDir[0]) + if (!Fake && zapLogDir && LogDir[0]) vsystem("%s -rf %s", REMOVE_CMD, LogDir); leave_playpen(); } if (sig) exit(1); } Index: stable/2.2/usr.sbin/pkg_install/create/Makefile =================================================================== --- stable/2.2/usr.sbin/pkg_install/create/Makefile (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/create/Makefile (revision 40699) @@ -1,18 +1,12 @@ +# $Id$ + PROG= pkg_create CFLAGS+= ${DEBUG} -I${.CURDIR}/../lib -.if exists(${.OBJDIR}/../lib) -LDADD+= -L${.OBJDIR}/../lib -linstall -DPADD+= ${.OBJDIR}/../lib/libinstall.a -.else -LDADD+= -L${.CURDIR}/../lib -linstall -DPADD+= ${.CURDIR}/../lib/libinstall.a -.endif - -LDADD+= -lftpio -lmd -DPADD+= ${LIBFTPIO} ${LIBMD} +DPADD= ${LIBINSTALL} ${LIBFTPIO} ${LIBMD} +LDADD= ${LIBINSTALL} -lftpio -lmd SRCS= main.c perform.c pl.c .include Index: stable/2.2/usr.sbin/pkg_install/delete/Makefile =================================================================== --- stable/2.2/usr.sbin/pkg_install/delete/Makefile (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/delete/Makefile (revision 40699) @@ -1,17 +1,11 @@ +# $Id$ + PROG= pkg_delete CFLAGS+= ${DEBUG} -I${.CURDIR}/../lib -.if exists(${.OBJDIR}/../lib) -LDADD+= -L${.OBJDIR}/../lib -linstall -DPADD+= ${.OBJDIR}/../lib/libinstall.a -.else -LDADD+= -L${.CURDIR}/../lib -linstall -DPADD+= ${.CURDIR}/../lib/libinstall.a -.endif - -LDADD+= -lftpio -lmd -DPADD+= ${LIBFTPIO} ${LIBMD} +DPADD= ${LIBINSTALL} ${LIBFTPIO} ${LIBMD} +LDADD= ${LIBINSTALL} -lftpio -lmd SRCS= main.c perform.c .include Index: stable/2.2/usr.sbin/pkg_install/info/Makefile =================================================================== --- stable/2.2/usr.sbin/pkg_install/info/Makefile (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/info/Makefile (revision 40699) @@ -1,17 +1,11 @@ +# $Id$ + PROG= pkg_info CFLAGS+= ${DEBUG} -I${.CURDIR}/../lib -.if exists(${.OBJDIR}/../lib) -LDADD+= -L${.OBJDIR}/../lib -linstall -DPADD+= ${.OBJDIR}/../lib/libinstall.a -.else -LDADD+= -L${.CURDIR}/../lib -linstall -DPADD+= ${.CURDIR}/../lib/libinstall.a -.endif - -LDADD+= -lftpio -lmd -DPADD+= ${LIBFTPIO} ${LIBMD} +DPADD= ${LIBINSTALL} ${LIBFTPIO} ${LIBMD} +LDADD= ${LIBINSTALL} -lftpio -lmd SRCS= main.c perform.c show.c .include Index: stable/2.2/usr.sbin/pkg_install/lib/pen.c =================================================================== --- stable/2.2/usr.sbin/pkg_install/lib/pen.c (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/lib/pen.c (revision 40699) @@ -1,178 +1,177 @@ #ifndef lint static const char rcsid[] = - "$Id: pen.c,v 1.22.2.4 1998/04/12 16:01:28 jkh Exp $"; + "$Id: pen.c,v 1.22.2.5 1998/09/11 07:27:18 jkh 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 * * Routines for managing the "play pen". * */ #include #include "lib.h" #include #include #include /* For keeping track of where we are */ static char PenLocation[FILENAME_MAX]; static char Previous[FILENAME_MAX]; char * where_playpen(void) { return PenLocation; } /* Find a good place to play. */ static char * find_play_pen(char *pen, size_t sz) { char *cp; struct stat sb; 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.XXXXXX", cp); else if ((cp = getenv("TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) sprintf(pen, "%s/instmp.XXXXXX", cp); else if (stat("/var/tmp", &sb) != FAIL && min_free("/var/tmp") >= sz) strcpy(pen, "/var/tmp/instmp.XXXXXX"); else if (stat("/tmp", &sb) != FAIL && min_free("/tmp") >= sz) strcpy(pen, "/tmp/instmp.XXXXXX"); else if ((stat("/usr/tmp", &sb) == SUCCESS || mkdir("/usr/tmp", 01777) == SUCCESS) && min_free("/usr/tmp") >= sz) strcpy(pen, "/usr/tmp/instmp.XXXXXX"); else { cleanup(0); errx(2, "can't find enough temporary space to extract the files, please set your\n" "PKG_TMPDIR environment variable to a location with at least %d bytes\n" "free", sz); return NULL; } return pen; } #define MAX_STACK 20 static char *pstack[MAX_STACK]; static int pdepth = -1; static void pushPen(char *pen) { if (++pdepth == MAX_STACK) errx(2, "stack overflow in pushPen().\n"); pstack[pdepth] = strdup(pen); } static void popPen(char *pen) { if (pdepth == -1) { pen[0] = '\0'; return; } strcpy(pen, pstack[pdepth]); free(pstack[pdepth--]); } /* * Make a temporary directory to play in and chdir() to it, returning * pathname of previous working directory. */ char * make_playpen(char *pen, size_t sz) { if (!find_play_pen(pen, sz)) return NULL; - if (!mktemp(pen)) { + if (!mkdtemp(pen)) { cleanup(0); errx(2, "can't mktemp '%s'", pen); } - - if (mkdir(pen, 0755) == FAIL) { + if (chmod(pen, 0755) == FAIL) { cleanup(0); errx(2, "can't mkdir '%s'", pen); } if (Verbose) { if (sz) fprintf(stderr, "Requested space: %d bytes, free space: %qd bytes in %s\n", (int)sz, min_free(pen), pen); } if (min_free(pen) < sz) { rmdir(pen); cleanup(0); errx(2, "not enough free space to create '%s'.\n" "Please set your PKG_TMPDIR environment variable to a location\n" "with more space and\ntry the command again", pen); } if (!getcwd(Previous, FILENAME_MAX)) { upchuck("getcwd"); return NULL; } if (chdir(pen) == FAIL) { cleanup(0); errx(2, "can't chdir to '%s'", pen); } if (PenLocation[0]) pushPen(PenLocation); strcpy(PenLocation, pen); return Previous; } /* Convenience routine for getting out of playpen */ void leave_playpen() { void (*oldsig)(int); /* Don't interrupt while we're cleaning up */ oldsig = signal(SIGINT, SIG_IGN); if (Previous[0]) { if (chdir(Previous) == FAIL) { cleanup(0); errx(2, "can't chdir back to '%s'", Previous); } Previous[0] = '\0'; } if (PenLocation[0]) { if (PenLocation[0] == '/' && vsystem("rm -rf %s", PenLocation)) warnx("couldn't remove temporary dir '%s'", PenLocation); popPen(PenLocation); } signal(SIGINT, oldsig); } off_t min_free(char *tmpdir) { struct statfs buf; if (statfs(tmpdir, &buf) != 0) { warn("statfs"); return -1; } return (off_t)buf.f_bavail * (off_t)buf.f_bsize; } Index: stable/2.2/usr.sbin/pkg_install/lib/plist.c =================================================================== --- stable/2.2/usr.sbin/pkg_install/lib/plist.c (revision 40698) +++ stable/2.2/usr.sbin/pkg_install/lib/plist.c (revision 40699) @@ -1,507 +1,507 @@ #ifndef lint static const char rcsid[] = - "$Id: plist.c,v 1.17.2.7 1998/09/01 07:00:20 jkh Exp $"; + "$Id: plist.c,v 1.17.2.8 1998/09/11 07:27:18 jkh 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 * * General packing list routines. * */ #include "lib.h" #include #include /* Add an item to a packing list */ void add_plist(Package *p, plist_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; } } void add_plist_top(Package *p, plist_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; } } /* Return the last (most recent) entry in a packing list */ PackingList last_plist(Package *p) { return p->tail; } /* Mark all items in a packing list to prevent iteration over them */ void mark_plist(Package *pkg) { PackingList p = pkg->head; while (p) { p->marked = TRUE; p = p->next; } } /* Find a given item in a packing list and, if so, return it (else NULL) */ PackingList find_plist(Package *pkg, plist_t type) { PackingList p = pkg->head; while (p) { if (p->type == type) return p; p = p->next; } return NULL; } /* Look for a specific boolean option argument in the list */ char * find_plist_option(Package *pkg, char *name) { PackingList p = pkg->head; while (p) { if (p->type == PLIST_OPTION && !strcmp(p->name, name)) return p->name; p = p->next; } return NULL; } /* * Delete plist item 'type' in the list (if 'name' is non-null, match it * 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) { PackingList p = pkg->head; while (p) { PackingList pnext = p->next; if (p->type == type && (!name || !strcmp(name, p->name))) { free(p->name); if (p->prev) p->prev->next = pnext; else pkg->head = pnext; if (pnext) pnext->prev = p->prev; else pkg->tail = p->prev; free(p); if (!all) return; p = pnext; } else p = p->next; } } /* Allocate a new packing list entry */ PackingList new_plist_entry(void) { PackingList ret; ret = (PackingList)malloc(sizeof(struct _plist)); bzero(ret, sizeof(struct _plist)); return ret; } /* Free an entire packing list */ void free_plist(Package *pkg) { PackingList p = pkg->head; while (p) { PackingList p1 = p->next; free(p->name); free(p); p = p1; } pkg->head = pkg->tail = NULL; } /* * For an ascii string denoting a plist command, return its code and * optionally its argument(s) */ 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; } ++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, "mtree")) return PLIST_MTREE; else if (!strcmp(cmd, "dirrm")) return PLIST_DIR_RM; else if (!strcmp(cmd, "option")) return PLIST_OPTION; else return FAIL; } /* Read a packing list from a file */ void read_plist(Package *pkg, FILE *fp) { char *cp, pline[FILENAME_MAX]; int cmd; while (fgets(pline, FILENAME_MAX, fp)) { int len = strlen(pline); while (len && isspace(pline[len - 1])) pline[--len] = '\0'; if (!len) continue; cp = pline; if (pline[0] == CMD_CHAR) { cmd = plist_cmd(pline + 1, &cp); if (cmd == FAIL) { cleanup(0); errx(2, "bad command '%s'", pline); } if (*cp == '\0') cp = NULL; } else cmd = PLIST_FILE; add_plist(pkg, cmd, cp); } } /* Write a packing list to a file, converting commands to ascii equivs */ void write_plist(Package *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_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 = plist->next; } } /* * Delete the results of a package installation. * * This is here rather than in the pkg_delete code because pkg_add needs to * run it too in cases of failure. */ int delete_package(Boolean ign_err, Boolean nukedirs, Package *pkg) { PackingList p; char *Where = ".", *last_file = ""; Boolean fail = SUCCESS; Boolean preserve; char tmp[FILENAME_MAX], *name = NULL; preserve = find_plist_option(pkg, "preserve") ? TRUE : FALSE; for (p = pkg->head; p; p = p->next) { switch (p->type) { case PLIST_NAME: name = p->name; break; case PLIST_IGNORE: p = p->next; break; case PLIST_CWD: Where = p->name; if (Verbose) printf("Change working directory to %s\n", Where); break; case PLIST_UNEXEC: format_cmd(tmp, p->name, Where, last_file); if (Verbose) printf("Execute `%s'\n", tmp); if (!Fake && system(tmp)) { warnx("unexec command for `%s' failed", tmp); fail = FAIL; } break; case PLIST_FILE: last_file = p->name; sprintf(tmp, "%s/%s", Where, p->name); - if (isdir(tmp)) { - warnx("attempting to delete directory `%s' as a file\n" + if (isdir(tmp) && fexists(tmp)) { + warnx("cannot delete specified file `%s' - it is a directory!\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]; if ((cp = MD5File(tmp, buf)) != NULL) { /* Mismatch? */ if (strcmp(cp, p->next->name + 4)) { if (Verbose) printf("%s fails original MD5 checksum - %s\n", tmp, Force ? "deleted anyway." : "not deleted."); if (!Force) { fail = FAIL; continue; } } } } if (Verbose) printf("Delete file %s\n", tmp); if (!Fake) { if (delete_hierarchy(tmp, ign_err, nukedirs)) fail = FAIL; if (preserve && name) { char tmp2[FILENAME_MAX]; if (make_preserve_name(tmp2, FILENAME_MAX, name, tmp)) { if (fexists(tmp2)) { if (rename(tmp2, tmp)) warn("preserve: unable to restore %s as %s", tmp2, tmp); } } } } } break; case PLIST_DIR_RM: sprintf(tmp, "%s/%s", Where, p->name); if (!isdir(tmp) && fexists(tmp)) { warnx("cannot delete specified directory `%s' - it is a file!\n" "this packing list is incorrect - ignoring delete request", tmp); } else { if (Verbose) printf("Delete directory %s\n", tmp); if (!Fake && delete_hierarchy(tmp, ign_err, FALSE)) { warnx("unable to completely remove directory '%s'", tmp); fail = FAIL; } } last_file = p->name; break; } } return fail; } #ifdef DEBUG #define RMDIR(dir) vsystem("%s %s", RMDIR_CMD, dir) #define REMOVE(dir,ie) vsystem("%s %s%s", REMOVE_CMD, (ie ? "-f " : ""), dir) #else #define RMDIR rmdir #define REMOVE(file,ie) (remove(file) && !(ie)) #endif /* Selectively delete a hierarchy */ int delete_hierarchy(char *dir, Boolean ign_err, Boolean nukedirs) { char *cp1, *cp2; cp1 = cp2 = dir; if (!fexists(dir)) { if (!ign_err) warnx("%s `%s' doesn't really exist", isdir(dir) ? "directory" : "file", dir); return !ign_err; } else if (nukedirs) { if (vsystem("%s -r%s %s", REMOVE_CMD, (ign_err ? "f" : ""), dir)) return 1; } else if (isdir(dir)) { if (RMDIR(dir) && !ign_err) return 1; } else { if (REMOVE(dir, ign_err)) return 1; } if (!nukedirs) return 0; while (cp2) { if ((cp2 = rindex(cp1, '/')) != NULL) *cp2 = '\0'; if (!isemptydir(dir)) return 0; if (RMDIR(dir) && !ign_err) if (!fexists(dir)) warnx("directory `%s' doesn't really exist", dir); else return 1; /* back up the pathname one component */ if (cp2) { cp1 = dir; } } return 0; }