perform.c revision 49300
1327Sjkh#ifndef lint 230221Scharnierstatic const char rcsid[] = 349300Sjdp "$Id: perform.c,v 1.26 1998/12/16 13:59:31 jkh Exp $"; 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> 31327Sjkh 3249300Sjdpstatic int fname_cmp(const FTSENT **, const FTSENT **); 33327Sjkhstatic int pkg_do(char *); 34327Sjkh 35327Sjkhint 36327Sjkhpkg_perform(char **pkgs) 37327Sjkh{ 38327Sjkh int i, err_cnt = 0; 397937Sjkh char *tmp; 40327Sjkh 41327Sjkh signal(SIGINT, cleanup); 42327Sjkh 437937Sjkh tmp = getenv(PKG_DBDIR); 447937Sjkh if (!tmp) 457937Sjkh tmp = DEF_LOG_DIR; 46327Sjkh /* Overriding action? */ 4716404Sjkh if (CheckPkg) { 4816404Sjkh char buf[FILENAME_MAX]; 49327Sjkh 5016404Sjkh snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg); 5116404Sjkh return abs(access(buf, R_OK)); 5216404Sjkh } 5316404Sjkh else if (AllInstalled) { 5449300Sjdp FTS *ftsp; 5549300Sjdp FTSENT *f; 5649300Sjdp char *paths[2]; 578857Srgrimes 5816404Sjkh if (!isdir(tmp)) 5916404Sjkh return 1; 6049300Sjdp paths[0] = tmp; 6149300Sjdp paths[1] = NULL; 6249300Sjdp ftsp = fts_open(paths, FTS_LOGICAL | FTS_NOCHDIR | FTS_NOSTAT, 6349300Sjdp fname_cmp); 6449300Sjdp if (ftsp != NULL) { 6549300Sjdp while ((f = fts_read(ftsp)) != NULL) { 6649300Sjdp if (f->fts_info == FTS_D && f->fts_level == 1) { 6749300Sjdp err_cnt += pkg_do(f->fts_name); 6849300Sjdp fts_set(ftsp, f, FTS_SKIP); 6949300Sjdp } 7049300Sjdp } 7149300Sjdp fts_close(ftsp); 7216404Sjkh } 73327Sjkh } 7416404Sjkh else 7516404Sjkh for (i = 0; pkgs[i]; i++) 7616404Sjkh err_cnt += pkg_do(pkgs[i]); 77327Sjkh return err_cnt; 78327Sjkh} 79327Sjkh 8011780Sjkhstatic char *Home; 8111780Sjkh 82327Sjkhstatic int 83327Sjkhpkg_do(char *pkg) 84327Sjkh{ 858086Sjkh Boolean installed = FALSE, isTMP = FALSE; 86327Sjkh char log_dir[FILENAME_MAX]; 878086Sjkh char fname[FILENAME_MAX]; 88327Sjkh Package plist; 89327Sjkh FILE *fp; 908086Sjkh struct stat sb; 918142Sjkh char *cp = NULL; 928086Sjkh int code = 0; 93327Sjkh 948086Sjkh if (isURL(pkg)) { 9511780Sjkh if ((cp = fileGetURL(NULL, pkg)) != NULL) { 968086Sjkh strcpy(fname, cp); 978086Sjkh isTMP = TRUE; 988086Sjkh } 998086Sjkh } 1009782Sache else if (fexists(pkg) && isfile(pkg)) { 1018086Sjkh int len; 102327Sjkh 1038423Sjkh if (*pkg != '/') { 1048423Sjkh if (!getcwd(fname, FILENAME_MAX)) 1058423Sjkh upchuck("getcwd"); 1068423Sjkh len = strlen(fname); 1078423Sjkh snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg); 1088423Sjkh } 1098423Sjkh else 1108423Sjkh strcpy(fname, pkg); 1118086Sjkh cp = fname; 1128086Sjkh } 1138086Sjkh else { 11411780Sjkh if ((cp = fileFindByPath(NULL, pkg)) != NULL) 1158086Sjkh strncpy(fname, cp, FILENAME_MAX); 1168086Sjkh } 1178086Sjkh if (cp) { 1183364Sjkh /* 1193364Sjkh * Apply a crude heuristic to see how much space the package will 1203364Sjkh * take up once it's unpacked. I've noticed that most packages 1213577Sjkh * compress an average of 75%, but we're only unpacking the + files so 1223577Sjkh * be very optimistic. 1233364Sjkh */ 1243364Sjkh if (stat(fname, &sb) == FAIL) { 12530221Scharnier warnx("can't stat package file '%s'", fname); 1268086Sjkh code = 1; 1278086Sjkh goto bail; 1283364Sjkh } 12911780Sjkh Home = make_playpen(PlayPen, sb.st_size / 2); 130327Sjkh if (unpack(fname, "+*")) { 13130221Scharnier warnx("error during unpacking, no info for '%s' available", pkg); 1328086Sjkh code = 1; 1338086Sjkh goto bail; 134327Sjkh } 135327Sjkh } 1368086Sjkh /* It's not an ininstalled package, try and find it among the installed */ 137327Sjkh else { 1387937Sjkh char *tmp; 1397937Sjkh 1407937Sjkh sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, 1417937Sjkh pkg); 142327Sjkh if (!fexists(log_dir)) { 14330221Scharnier warnx("can't find package `%s' installed or in a file!", pkg); 144327Sjkh return 1; 145327Sjkh } 146327Sjkh if (chdir(log_dir) == FAIL) { 14730221Scharnier warnx("can't change directory to '%s'!", log_dir); 148327Sjkh return 1; 149327Sjkh } 150327Sjkh installed = TRUE; 151327Sjkh } 152327Sjkh 153327Sjkh /* Suck in the contents list */ 154327Sjkh plist.head = plist.tail = NULL; 155327Sjkh fp = fopen(CONTENTS_FNAME, "r"); 156327Sjkh if (!fp) { 15730221Scharnier warnx("unable to open %s file", CONTENTS_FNAME); 1588086Sjkh code = 1; 1598086Sjkh goto bail; 160327Sjkh } 161327Sjkh /* If we have a prefix, add it now */ 162327Sjkh read_plist(&plist, fp); 163327Sjkh fclose(fp); 164327Sjkh 165327Sjkh /* 166327Sjkh * Index is special info type that has to override all others to make 167327Sjkh * any sense. 168327Sjkh */ 169327Sjkh if (Flags & SHOW_INDEX) { 1708086Sjkh char tmp[FILENAME_MAX]; 171327Sjkh 1728086Sjkh snprintf(tmp, FILENAME_MAX, "%-19s ", pkg); 1738086Sjkh show_index(tmp, COMMENT_FNAME); 174327Sjkh } 175327Sjkh else { 176327Sjkh /* Start showing the package contents */ 177411Sjkh if (!Quiet) 178411Sjkh printf("%sInformation for %s:\n\n", InfoPrefix, pkg); 179327Sjkh if (Flags & SHOW_COMMENT) 180379Sjkh show_file("Comment:\n", COMMENT_FNAME); 1814996Sjkh if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME)) 1824996Sjkh show_file("Required by:\n", REQUIRED_BY_FNAME); 183327Sjkh if (Flags & SHOW_DESC) 184379Sjkh show_file("Description:\n", DESC_FNAME); 1854996Sjkh if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME)) 1864996Sjkh show_file("Install notice:\n", DISPLAY_FNAME); 187327Sjkh if (Flags & SHOW_PLIST) 188379Sjkh show_plist("Packing list:\n", &plist, (plist_t)-1); 189327Sjkh if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) 190379Sjkh show_file("Install script:\n", INSTALL_FNAME); 19141866Sjkh if ((Flags & SHOW_INSTALL) && fexists(POST_INSTALL_FNAME)) 19241866Sjkh show_file("Post-Install script:\n", POST_INSTALL_FNAME); 193327Sjkh if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) 194379Sjkh show_file("De-Install script:\n", DEINSTALL_FNAME); 19541866Sjkh if ((Flags & SHOW_DEINSTALL) && fexists(POST_DEINSTALL_FNAME)) 19641866Sjkh show_file("Post-DeInstall script:\n", POST_DEINSTALL_FNAME); 1974996Sjkh if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME)) 1984996Sjkh show_file("mtree file:\n", MTREE_FNAME); 199327Sjkh if (Flags & SHOW_PREFIX) 200379Sjkh show_plist("Prefix(s):\n", &plist, PLIST_CWD); 201411Sjkh if (Flags & SHOW_FILES) 202411Sjkh show_files("Files:\n", &plist); 203411Sjkh if (!Quiet) 204411Sjkh puts(InfoPrefix); 205327Sjkh } 206327Sjkh free_plist(&plist); 2078086Sjkh bail: 20833427Sjkh leave_playpen(); 2098086Sjkh if (isTMP) 2108086Sjkh unlink(fname); 2118086Sjkh return code; 212327Sjkh} 213327Sjkh 214327Sjkhvoid 215327Sjkhcleanup(int sig) 216327Sjkh{ 21733427Sjkh static int in_cleanup = 0; 21833427Sjkh 21933427Sjkh if (!in_cleanup) { 22033427Sjkh in_cleanup = 1; 22133427Sjkh leave_playpen(); 22233427Sjkh } 22339068Sjkh if (sig) 22439068Sjkh exit(1); 225327Sjkh} 22649300Sjdp 22749300Sjdpstatic int 22849300Sjdpfname_cmp(const FTSENT **a, const FTSENT **b) 22949300Sjdp{ 23049300Sjdp return strcmp((*a)->fts_name, (*b)->fts_name); 23149300Sjdp} 232