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