perform.c revision 39068
1#ifndef lint 2static const char rcsid[] = 3 "$Id: perform.c,v 1.24 1998/02/16 17:16:38 jkh Exp $"; 4#endif 5 6/* 7 * FreeBSD install - a package for the installation and maintainance 8 * of non-core utilities. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * Jordan K. Hubbard 20 * 23 Aug 1993 21 * 22 * This is the main body of the info module. 23 * 24 */ 25 26#include "lib.h" 27#include "info.h" 28 29#include <signal.h> 30 31static int pkg_do(char *); 32 33int 34pkg_perform(char **pkgs) 35{ 36 int i, err_cnt = 0; 37 char *tmp; 38 39 signal(SIGINT, cleanup); 40 41 tmp = getenv(PKG_DBDIR); 42 if (!tmp) 43 tmp = DEF_LOG_DIR; 44 /* Overriding action? */ 45 if (CheckPkg) { 46 char buf[FILENAME_MAX]; 47 48 snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg); 49 return abs(access(buf, R_OK)); 50 } 51 else if (AllInstalled) { 52 DIR *dirp; 53 struct dirent *dp; 54 55 if (!isdir(tmp)) 56 return 1; 57 dirp = opendir(tmp); 58 if (dirp) { 59 for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) 60 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) 61 err_cnt += pkg_do(dp->d_name); 62 (void)closedir(dirp); 63 } 64 } 65 else 66 for (i = 0; pkgs[i]; i++) 67 err_cnt += pkg_do(pkgs[i]); 68 return err_cnt; 69} 70 71static char *Home; 72 73static int 74pkg_do(char *pkg) 75{ 76 Boolean installed = FALSE, isTMP = FALSE; 77 char log_dir[FILENAME_MAX]; 78 char fname[FILENAME_MAX]; 79 Package plist; 80 FILE *fp; 81 struct stat sb; 82 char *cp = NULL; 83 int code = 0; 84 85 if (isURL(pkg)) { 86 if ((cp = fileGetURL(NULL, pkg)) != NULL) { 87 strcpy(fname, cp); 88 isTMP = TRUE; 89 } 90 } 91 else if (fexists(pkg) && isfile(pkg)) { 92 int len; 93 94 if (*pkg != '/') { 95 if (!getcwd(fname, FILENAME_MAX)) 96 upchuck("getcwd"); 97 len = strlen(fname); 98 snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg); 99 } 100 else 101 strcpy(fname, pkg); 102 cp = fname; 103 } 104 else { 105 if ((cp = fileFindByPath(NULL, pkg)) != NULL) 106 strncpy(fname, cp, FILENAME_MAX); 107 } 108 if (cp) { 109 /* 110 * Apply a crude heuristic to see how much space the package will 111 * take up once it's unpacked. I've noticed that most packages 112 * compress an average of 75%, but we're only unpacking the + files so 113 * be very optimistic. 114 */ 115 if (stat(fname, &sb) == FAIL) { 116 warnx("can't stat package file '%s'", fname); 117 code = 1; 118 goto bail; 119 } 120 Home = make_playpen(PlayPen, sb.st_size / 2); 121 if (unpack(fname, "+*")) { 122 warnx("error during unpacking, no info for '%s' available", pkg); 123 code = 1; 124 goto bail; 125 } 126 } 127 /* It's not an ininstalled package, try and find it among the installed */ 128 else { 129 char *tmp; 130 131 sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, 132 pkg); 133 if (!fexists(log_dir)) { 134 warnx("can't find package `%s' installed or in a file!", pkg); 135 return 1; 136 } 137 if (chdir(log_dir) == FAIL) { 138 warnx("can't change directory to '%s'!", log_dir); 139 return 1; 140 } 141 installed = TRUE; 142 } 143 144 /* Suck in the contents list */ 145 plist.head = plist.tail = NULL; 146 fp = fopen(CONTENTS_FNAME, "r"); 147 if (!fp) { 148 warnx("unable to open %s file", CONTENTS_FNAME); 149 code = 1; 150 goto bail; 151 } 152 /* If we have a prefix, add it now */ 153 read_plist(&plist, fp); 154 fclose(fp); 155 156 /* 157 * Index is special info type that has to override all others to make 158 * any sense. 159 */ 160 if (Flags & SHOW_INDEX) { 161 char tmp[FILENAME_MAX]; 162 163 snprintf(tmp, FILENAME_MAX, "%-19s ", pkg); 164 show_index(tmp, COMMENT_FNAME); 165 } 166 else { 167 /* Start showing the package contents */ 168 if (!Quiet) 169 printf("%sInformation for %s:\n\n", InfoPrefix, pkg); 170 if (Flags & SHOW_COMMENT) 171 show_file("Comment:\n", COMMENT_FNAME); 172 if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME)) 173 show_file("Required by:\n", REQUIRED_BY_FNAME); 174 if (Flags & SHOW_DESC) 175 show_file("Description:\n", DESC_FNAME); 176 if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME)) 177 show_file("Install notice:\n", DISPLAY_FNAME); 178 if (Flags & SHOW_PLIST) 179 show_plist("Packing list:\n", &plist, (plist_t)-1); 180 if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) 181 show_file("Install script:\n", INSTALL_FNAME); 182 if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) 183 show_file("De-Install script:\n", DEINSTALL_FNAME); 184 if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME)) 185 show_file("mtree file:\n", MTREE_FNAME); 186 if (Flags & SHOW_PREFIX) 187 show_plist("Prefix(s):\n", &plist, PLIST_CWD); 188 if (Flags & SHOW_FILES) 189 show_files("Files:\n", &plist); 190 if (!Quiet) 191 puts(InfoPrefix); 192 } 193 free_plist(&plist); 194 bail: 195 leave_playpen(); 196 if (isTMP) 197 unlink(fname); 198 return code; 199} 200 201void 202cleanup(int sig) 203{ 204 static int in_cleanup = 0; 205 206 if (!in_cleanup) { 207 in_cleanup = 1; 208 leave_playpen(); 209 } 210 if (sig) 211 exit(1); 212} 213