perform.c revision 71965
1229997Sken#ifndef lint 2229997Skenstatic const char rcsid[] = 3232604Strasz "$FreeBSD: head/usr.sbin/pkg_install/info/perform.c 71965 2001-02-03 20:56:32Z jkh $"; 4229997Sken#endif 5229997Sken 6232604Strasz/* 7232604Strasz * FreeBSD install - a package for the installation and maintainance 8232604Strasz * of non-core utilities. 9229997Sken * 10229997Sken * Redistribution and use in source and binary forms, with or without 11229997Sken * modification, are permitted provided that the following conditions 12229997Sken * are met: 13229997Sken * 1. Redistributions of source code must retain the above copyright 14229997Sken * notice, this list of conditions and the following disclaimer. 15229997Sken * 2. Redistributions in binary form must reproduce the above copyright 16229997Sken * notice, this list of conditions and the following disclaimer in the 17229997Sken * documentation and/or other materials provided with the distribution. 18229997Sken * 19229997Sken * Jordan K. Hubbard 20229997Sken * 23 Aug 1993 21229997Sken * 22229997Sken * This is the main body of the info module. 23229997Sken * 24229997Sken */ 25229997Sken 26229997Sken#include "lib.h" 27229997Sken#include "info.h" 28229997Sken 29229997Sken#include <fts.h> 30229997Sken#include <signal.h> 31229997Sken#include <err.h> 32229997Sken 33229997Skenstatic int fname_cmp(const FTSENT **, const FTSENT **); 34278796Smavstatic int pkg_do(char *); 35229997Sken 36229997Skenint 37229997Skenpkg_perform(char **pkgs) 38229997Sken{ 39229997Sken int i, err_cnt = 0; 40229997Sken char *tmp; 41229997Sken 42229997Sken signal(SIGINT, cleanup); 43229997Sken 44229997Sken tmp = getenv(PKG_DBDIR); 45229997Sken if (!tmp) 46229997Sken tmp = DEF_LOG_DIR; 47229997Sken /* Overriding action? */ 48229997Sken if (CheckPkg) { 49273979Smav char buf[FILENAME_MAX]; 50229997Sken 51229997Sken snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg); 52229997Sken return abs(access(buf, R_OK)); 53229997Sken } 54229997Sken else if (AllInstalled) { 55229997Sken FTS *ftsp; 56249009Strasz FTSENT *f; 57229997Sken char *paths[2]; 58229997Sken 59229997Sken if (!isdir(tmp)) 60229997Sken return 1; 61229997Sken paths[0] = tmp; 62229997Sken paths[1] = NULL; 63229997Sken ftsp = fts_open(paths, FTS_LOGICAL | FTS_NOCHDIR | FTS_NOSTAT, 64265492Strasz fname_cmp); 65229997Sken if (ftsp != NULL) { 66229997Sken while ((f = fts_read(ftsp)) != NULL) { 67275878Smav if (f->fts_info == FTS_D && f->fts_level == 1) { 68229997Sken err_cnt += pkg_do(f->fts_name); 69229997Sken fts_set(ftsp, f, FTS_SKIP); 70229997Sken } 71229997Sken } 72229997Sken fts_close(ftsp); 73229997Sken } 74229997Sken } 75229997Sken else 76229997Sken for (i = 0; pkgs[i]; i++) 77229997Sken err_cnt += pkg_do(pkgs[i]); 78229997Sken return err_cnt; 79229997Sken} 80229997Sken 81229997Skenstatic char *Home; 82229997Sken 83229997Skenstatic int 84229997Skenpkg_do(char *pkg) 85229997Sken{ 86229997Sken Boolean installed = FALSE, isTMP = FALSE; 87229997Sken char log_dir[FILENAME_MAX]; 88229997Sken char fname[FILENAME_MAX]; 89229997Sken Package plist; 90229997Sken FILE *fp; 91229997Sken struct stat sb; 92229997Sken char *cp = NULL; 93229997Sken int code = 0; 94229997Sken 95229997Sken if (isURL(pkg)) { 96229997Sken if ((cp = fileGetURL(NULL, pkg)) != NULL) { 97229997Sken strcpy(fname, cp); 98229997Sken isTMP = TRUE; 99229997Sken } 100229997Sken } 101229997Sken else if (fexists(pkg) && isfile(pkg)) { 102229997Sken int len; 103229997Sken 104229997Sken if (*pkg != '/') { 105229997Sken if (!getcwd(fname, FILENAME_MAX)) 106229997Sken upchuck("getcwd"); 107229997Sken len = strlen(fname); 108229997Sken snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg); 109229997Sken } 110229997Sken else 111229997Sken strcpy(fname, pkg); 112229997Sken cp = fname; 113229997Sken } 114276615Smav else { 115229997Sken if ((cp = fileFindByPath(NULL, pkg)) != NULL) 116229997Sken strncpy(fname, cp, FILENAME_MAX); 117229997Sken } 118229997Sken if (cp) { 119229997Sken /* 120229997Sken * Apply a crude heuristic to see how much space the package will 121229997Sken * take up once it's unpacked. I've noticed that most packages 122229997Sken * compress an average of 75%, but we're only unpacking the + files so 123229997Sken * be very optimistic. 124276615Smav */ 125229997Sken if (stat(fname, &sb) == FAIL) { 126229997Sken warnx("can't stat package file '%s'", fname); 127229997Sken code = 1; 128229997Sken goto bail; 129229997Sken } 130229997Sken Home = make_playpen(PlayPen, sb.st_size / 2); 131229997Sken if (unpack(fname, "+*")) { 132229997Sken warnx("error during unpacking, no info for '%s' available", pkg); 133276615Smav code = 1; 134273977Smav goto bail; 135273977Smav } 136273977Smav } 137273977Smav /* It's not an ininstalled package, try and find it among the installed */ 138273977Smav else { 139273977Smav char *tmp; 140273977Smav 141274732Smav sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, 142273977Smav pkg); 143273977Smav if (!fexists(log_dir)) { 144273977Smav warnx("can't find package `%s' installed or in a file!", pkg); 145273977Smav return 1; 146273977Smav } 147276615Smav if (chdir(log_dir) == FAIL) { 148273977Smav warnx("can't change directory to '%s'!", log_dir); 149273977Smav return 1; 150273977Smav } 151273977Smav installed = TRUE; 152273977Smav } 153273977Smav 154273977Smav /* Suck in the contents list */ 155273977Smav plist.head = plist.tail = NULL; 156273977Smav fp = fopen(CONTENTS_FNAME, "r"); 157273977Smav if (!fp) { 158273977Smav warnx("unable to open %s file", CONTENTS_FNAME); 159273977Smav code = 1; 160273977Smav goto bail; 161276615Smav } 162229997Sken /* If we have a prefix, add it now */ 163229997Sken read_plist(&plist, fp); 164229997Sken fclose(fp); 165229997Sken 166229997Sken /* 167229997Sken * Index is special info type that has to override all others to make 168229997Sken * any sense. 169229997Sken */ 170229997Sken if (Flags & SHOW_INDEX) { 171229997Sken char tmp[FILENAME_MAX]; 172229997Sken 173229997Sken snprintf(tmp, FILENAME_MAX, "%-19s ", pkg); 174229997Sken show_index(tmp, COMMENT_FNAME); 175229997Sken } 176229997Sken else { 177229997Sken /* Start showing the package contents */ 178276615Smav if (!Quiet) 179229997Sken printf("%sInformation for %s:\n\n", InfoPrefix, pkg); 180229997Sken if (Flags & SHOW_COMMENT) 181229997Sken show_file("Comment:\n", COMMENT_FNAME); 182229997Sken if (Flags & SHOW_REQUIRE) 183229997Sken show_plist("Depends on:\n", &plist, PLIST_PKGDEP); 184229997Sken if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME)) 185229997Sken show_file("Required by:\n", REQUIRED_BY_FNAME); 186229997Sken if (Flags & SHOW_DESC) 187229997Sken show_file("Description:\n", DESC_FNAME); 188229997Sken if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME)) 189229997Sken show_file("Install notice:\n", DISPLAY_FNAME); 190229997Sken if (Flags & SHOW_PLIST) 191229997Sken show_plist("Packing list:\n", &plist, (plist_t)-1); 192229997Sken if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) 193229997Sken show_file("Install script:\n", INSTALL_FNAME); 194276615Smav if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME)) 195229997Sken show_file("Post-Install script:\n", POST_INSTALL_FNAME); 196229997Sken if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) 197229997Sken show_file("De-Install script:\n", DEINSTALL_FNAME); 198229997Sken if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME)) 199229997Sken show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME); 200229997Sken if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME)) 201229997Sken show_file("mtree file:\n", MTREE_FNAME); 202229997Sken if (Flags & SHOW_PREFIX) 203229997Sken show_plist("Prefix(s):\n", &plist, PLIST_CWD); 204229997Sken if (Flags & SHOW_FILES) 205229997Sken show_files("Files:\n", &plist); 206229997Sken if ((Flags & SHOW_SIZE) && installed) 207229997Sken show_size("Package Size:\n", &plist); 208229997Sken if ((Flags & SHOW_CKSUM) && installed) 209229997Sken show_cksum("Mismatched Checksums:\n", &plist); 210229997Sken if (Flags & SHOW_ORIGIN) 211276615Smav show_origin("Origin:\n", &plist); 212229997Sken if (!Quiet) 213229997Sken puts(InfoPrefix); 214229997Sken } 215229997Sken free_plist(&plist); 216229997Sken bail: 217229997Sken leave_playpen(); 218229997Sken if (isTMP) 219229997Sken unlink(fname); 220229997Sken return code; 221229997Sken} 222229997Sken 223229997Skenvoid 224229997Skencleanup(int sig) 225229997Sken{ 226229997Sken static int in_cleanup = 0; 227276615Smav 228229997Sken if (!in_cleanup) { 229229997Sken in_cleanup = 1; 230229997Sken leave_playpen(); 231229997Sken } 232229997Sken if (sig) 233229997Sken exit(1); 234229997Sken} 235229997Sken 236229997Skenstatic int 237229997Skenfname_cmp(const FTSENT **a, const FTSENT **b) 238229997Sken{ 239229997Sken return strcmp((*a)->fts_name, (*b)->fts_name); 240229997Sken} 241229997Sken