perform.c revision 67454
1327Sjkh#ifndef lint 230221Scharnierstatic const char rcsid[] = 350479Speter "$FreeBSD: head/usr.sbin/pkg_install/info/perform.c 67454 2000-10-23 07:01:31Z sobomax $"; 4327Sjkh#endif 5327Sjkh 6327Sjkh/* 7327Sjkh * FreeBSD install - a package for the installation and maintainance 8327Sjkh * of non-core utilities. 9327Sjkh * 10327Sjkh * Redistribution and use in source and binary forms, with or without 11327Sjkh * modification, are permitted provided that the following conditions 12327Sjkh * are met: 13327Sjkh * 1. Redistributions of source code must retain the above copyright 14327Sjkh * notice, this list of conditions and the following disclaimer. 15327Sjkh * 2. Redistributions in binary form must reproduce the above copyright 16327Sjkh * notice, this list of conditions and the following disclaimer in the 17327Sjkh * documentation and/or other materials provided with the distribution. 18327Sjkh * 19327Sjkh * Jordan K. Hubbard 20327Sjkh * 23 Aug 1993 21327Sjkh * 22327Sjkh * This is the main body of the info module. 23327Sjkh * 24327Sjkh */ 25327Sjkh 26327Sjkh#include "lib.h" 27327Sjkh#include "info.h" 28327Sjkh 2949300Sjdp#include <fts.h> 30327Sjkh#include <signal.h> 3149637Sbillf#include <err.h> 32327Sjkh 3349300Sjdpstatic int fname_cmp(const FTSENT **, const FTSENT **); 34327Sjkhstatic int pkg_do(char *); 35327Sjkh 36327Sjkhint 37327Sjkhpkg_perform(char **pkgs) 38327Sjkh{ 39327Sjkh int i, err_cnt = 0; 407937Sjkh char *tmp; 41327Sjkh 42327Sjkh signal(SIGINT, cleanup); 43327Sjkh 447937Sjkh tmp = getenv(PKG_DBDIR); 457937Sjkh if (!tmp) 467937Sjkh tmp = DEF_LOG_DIR; 47327Sjkh /* Overriding action? */ 4816404Sjkh if (CheckPkg) { 4916404Sjkh char buf[FILENAME_MAX]; 50327Sjkh 5116404Sjkh snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg); 5216404Sjkh return abs(access(buf, R_OK)); 5316404Sjkh } 5416404Sjkh else if (AllInstalled) { 5549300Sjdp FTS *ftsp; 5649300Sjdp FTSENT *f; 5749300Sjdp char *paths[2]; 588857Srgrimes 5916404Sjkh if (!isdir(tmp)) 6016404Sjkh return 1; 6149300Sjdp paths[0] = tmp; 6249300Sjdp paths[1] = NULL; 6349300Sjdp ftsp = fts_open(paths, FTS_LOGICAL | FTS_NOCHDIR | FTS_NOSTAT, 6449300Sjdp fname_cmp); 6549300Sjdp if (ftsp != NULL) { 6649300Sjdp while ((f = fts_read(ftsp)) != NULL) { 6749300Sjdp if (f->fts_info == FTS_D && f->fts_level == 1) { 6849300Sjdp err_cnt += pkg_do(f->fts_name); 6949300Sjdp fts_set(ftsp, f, FTS_SKIP); 7049300Sjdp } 7149300Sjdp } 7249300Sjdp fts_close(ftsp); 7316404Sjkh } 74327Sjkh } 7516404Sjkh else 7616404Sjkh for (i = 0; pkgs[i]; i++) 7716404Sjkh err_cnt += pkg_do(pkgs[i]); 78327Sjkh return err_cnt; 79327Sjkh} 80327Sjkh 8111780Sjkhstatic char *Home; 8211780Sjkh 83327Sjkhstatic int 84327Sjkhpkg_do(char *pkg) 85327Sjkh{ 868086Sjkh Boolean installed = FALSE, isTMP = FALSE; 87327Sjkh char log_dir[FILENAME_MAX]; 888086Sjkh char fname[FILENAME_MAX]; 89327Sjkh Package plist; 90327Sjkh FILE *fp; 918086Sjkh struct stat sb; 928142Sjkh char *cp = NULL; 938086Sjkh int code = 0; 94327Sjkh 958086Sjkh if (isURL(pkg)) { 9611780Sjkh if ((cp = fileGetURL(NULL, pkg)) != NULL) { 978086Sjkh strcpy(fname, cp); 988086Sjkh isTMP = TRUE; 998086Sjkh } 1008086Sjkh } 1019782Sache else if (fexists(pkg) && isfile(pkg)) { 1028086Sjkh int len; 103327Sjkh 1048423Sjkh if (*pkg != '/') { 1058423Sjkh if (!getcwd(fname, FILENAME_MAX)) 1068423Sjkh upchuck("getcwd"); 1078423Sjkh len = strlen(fname); 1088423Sjkh snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg); 1098423Sjkh } 1108423Sjkh else 1118423Sjkh strcpy(fname, pkg); 1128086Sjkh cp = fname; 1138086Sjkh } 1148086Sjkh else { 11511780Sjkh if ((cp = fileFindByPath(NULL, pkg)) != NULL) 1168086Sjkh strncpy(fname, cp, FILENAME_MAX); 1178086Sjkh } 1188086Sjkh if (cp) { 1193364Sjkh /* 1203364Sjkh * Apply a crude heuristic to see how much space the package will 1213364Sjkh * take up once it's unpacked. I've noticed that most packages 1223577Sjkh * compress an average of 75%, but we're only unpacking the + files so 1233577Sjkh * be very optimistic. 1243364Sjkh */ 1253364Sjkh if (stat(fname, &sb) == FAIL) { 12630221Scharnier warnx("can't stat package file '%s'", fname); 1278086Sjkh code = 1; 1288086Sjkh goto bail; 1293364Sjkh } 13011780Sjkh Home = make_playpen(PlayPen, sb.st_size / 2); 131327Sjkh if (unpack(fname, "+*")) { 13230221Scharnier warnx("error during unpacking, no info for '%s' available", pkg); 1338086Sjkh code = 1; 1348086Sjkh goto bail; 135327Sjkh } 136327Sjkh } 1378086Sjkh /* It's not an ininstalled package, try and find it among the installed */ 138327Sjkh else { 1397937Sjkh char *tmp; 1407937Sjkh 1417937Sjkh sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, 1427937Sjkh pkg); 143327Sjkh if (!fexists(log_dir)) { 14430221Scharnier warnx("can't find package `%s' installed or in a file!", pkg); 145327Sjkh return 1; 146327Sjkh } 147327Sjkh if (chdir(log_dir) == FAIL) { 14830221Scharnier warnx("can't change directory to '%s'!", log_dir); 149327Sjkh return 1; 150327Sjkh } 151327Sjkh installed = TRUE; 152327Sjkh } 153327Sjkh 154327Sjkh /* Suck in the contents list */ 155327Sjkh plist.head = plist.tail = NULL; 156327Sjkh fp = fopen(CONTENTS_FNAME, "r"); 157327Sjkh if (!fp) { 15830221Scharnier warnx("unable to open %s file", CONTENTS_FNAME); 1598086Sjkh code = 1; 1608086Sjkh goto bail; 161327Sjkh } 162327Sjkh /* If we have a prefix, add it now */ 163327Sjkh read_plist(&plist, fp); 164327Sjkh fclose(fp); 165327Sjkh 166327Sjkh /* 167327Sjkh * Index is special info type that has to override all others to make 168327Sjkh * any sense. 169327Sjkh */ 170327Sjkh if (Flags & SHOW_INDEX) { 1718086Sjkh char tmp[FILENAME_MAX]; 172327Sjkh 1738086Sjkh snprintf(tmp, FILENAME_MAX, "%-19s ", pkg); 1748086Sjkh show_index(tmp, COMMENT_FNAME); 175327Sjkh } 176327Sjkh else { 177327Sjkh /* Start showing the package contents */ 178411Sjkh if (!Quiet) 179411Sjkh printf("%sInformation for %s:\n\n", InfoPrefix, pkg); 180327Sjkh if (Flags & SHOW_COMMENT) 181379Sjkh show_file("Comment:\n", COMMENT_FNAME); 18266339Smarko if (Flags & SHOW_REQUIRE) 18366339Smarko show_plist("Depends on:\n", &plist, PLIST_PKGDEP); 1844996Sjkh if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME)) 1854996Sjkh show_file("Required by:\n", REQUIRED_BY_FNAME); 186327Sjkh if (Flags & SHOW_DESC) 187379Sjkh show_file("Description:\n", DESC_FNAME); 1884996Sjkh if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME)) 1894996Sjkh show_file("Install notice:\n", DISPLAY_FNAME); 190327Sjkh if (Flags & SHOW_PLIST) 191379Sjkh show_plist("Packing list:\n", &plist, (plist_t)-1); 192327Sjkh if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) 193379Sjkh show_file("Install script:\n", INSTALL_FNAME); 19441866Sjkh if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME)) 19541866Sjkh show_file("Post-Install script:\n", POST_INSTALL_FNAME); 196327Sjkh if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) 197379Sjkh show_file("De-Install script:\n", DEINSTALL_FNAME); 19841866Sjkh if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME)) 19941866Sjkh show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME); 2004996Sjkh if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME)) 2014996Sjkh show_file("mtree file:\n", MTREE_FNAME); 202327Sjkh if (Flags & SHOW_PREFIX) 203379Sjkh show_plist("Prefix(s):\n", &plist, PLIST_CWD); 204411Sjkh if (Flags & SHOW_FILES) 205411Sjkh show_files("Files:\n", &plist); 20662775Ssobomax if ((Flags & SHOW_SIZE) && installed) 20762775Ssobomax show_size("Package Size:\n", &plist); 20867454Ssobomax if (Flags & SHOW_ORIGIN) 20967454Ssobomax show_origin("Origin:\n", &plist); 210411Sjkh if (!Quiet) 211411Sjkh puts(InfoPrefix); 212327Sjkh } 213327Sjkh free_plist(&plist); 2148086Sjkh bail: 21533427Sjkh leave_playpen(); 2168086Sjkh if (isTMP) 2178086Sjkh unlink(fname); 2188086Sjkh return code; 219327Sjkh} 220327Sjkh 221327Sjkhvoid 222327Sjkhcleanup(int sig) 223327Sjkh{ 22433427Sjkh static int in_cleanup = 0; 22533427Sjkh 22633427Sjkh if (!in_cleanup) { 22733427Sjkh in_cleanup = 1; 22833427Sjkh leave_playpen(); 22933427Sjkh } 23039068Sjkh if (sig) 23139068Sjkh exit(1); 232327Sjkh} 23349300Sjdp 23449300Sjdpstatic int 23549300Sjdpfname_cmp(const FTSENT **a, const FTSENT **b) 23649300Sjdp{ 23749300Sjdp return strcmp((*a)->fts_name, (*b)->fts_name); 23849300Sjdp} 239