perform.c revision 16404
1#ifndef lint 2static const char *rcsid = "$Id: perform.c,v 1.18 1995/10/25 15:38: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 (CheckPkg) { 45 char buf[FILENAME_MAX]; 46 47 snprintf(buf, FILENAME_MAX, "%s/%s", tmp, CheckPkg); 48 return abs(access(buf, R_OK)); 49 } 50 else if (AllInstalled) { 51 DIR *dirp; 52 struct dirent *dp; 53 54 if (!isdir(tmp)) 55 return 1; 56 dirp = opendir(tmp); 57 if (dirp) { 58 for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) 59 if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) 60 err_cnt += pkg_do(dp->d_name); 61 (void)closedir(dirp); 62 } 63 } 64 else 65 for (i = 0; pkgs[i]; i++) 66 err_cnt += pkg_do(pkgs[i]); 67 return err_cnt; 68} 69 70static char *Home; 71 72static int 73pkg_do(char *pkg) 74{ 75 Boolean installed = FALSE, isTMP = FALSE; 76 char log_dir[FILENAME_MAX]; 77 char fname[FILENAME_MAX]; 78 Package plist; 79 FILE *fp; 80 struct stat sb; 81 char *cp = NULL; 82 int code = 0; 83 84 if (isURL(pkg)) { 85 if ((cp = fileGetURL(NULL, pkg)) != NULL) { 86 strcpy(fname, cp); 87 isTMP = TRUE; 88 } 89 } 90 else if (fexists(pkg) && isfile(pkg)) { 91 int len; 92 93 if (*pkg != '/') { 94 if (!getcwd(fname, FILENAME_MAX)) 95 upchuck("getcwd"); 96 len = strlen(fname); 97 snprintf(&fname[len], FILENAME_MAX - len, "/%s", pkg); 98 } 99 else 100 strcpy(fname, pkg); 101 cp = fname; 102 } 103 else { 104 if ((cp = fileFindByPath(NULL, pkg)) != NULL) 105 strncpy(fname, cp, FILENAME_MAX); 106 } 107 if (cp) { 108 /* 109 * Apply a crude heuristic to see how much space the package will 110 * take up once it's unpacked. I've noticed that most packages 111 * compress an average of 75%, but we're only unpacking the + files so 112 * be very optimistic. 113 */ 114 if (stat(fname, &sb) == FAIL) { 115 whinge("Can't stat package file '%s'.", fname); 116 code = 1; 117 goto bail; 118 } 119 Home = make_playpen(PlayPen, sb.st_size / 2); 120 if (unpack(fname, "+*")) { 121 whinge("Error during unpacking, no info for '%s' available.", pkg); 122 code = 1; 123 goto bail; 124 } 125 } 126 /* It's not an ininstalled package, try and find it among the installed */ 127 else { 128 char *tmp; 129 130 sprintf(log_dir, "%s/%s", (tmp = getenv(PKG_DBDIR)) ? tmp : DEF_LOG_DIR, 131 pkg); 132 if (!fexists(log_dir)) { 133 whinge("Can't find package `%s' installed or in a file!", pkg); 134 return 1; 135 } 136 if (chdir(log_dir) == FAIL) { 137 whinge("Can't change directory to '%s'!", log_dir); 138 return 1; 139 } 140 installed = TRUE; 141 } 142 143 /* Suck in the contents list */ 144 plist.head = plist.tail = NULL; 145 fp = fopen(CONTENTS_FNAME, "r"); 146 if (!fp) { 147 whinge("Unable to open %s file.", CONTENTS_FNAME); 148 code = 1; 149 goto bail; 150 } 151 /* If we have a prefix, add it now */ 152 read_plist(&plist, fp); 153 fclose(fp); 154 155 /* 156 * Index is special info type that has to override all others to make 157 * any sense. 158 */ 159 if (Flags & SHOW_INDEX) { 160 char tmp[FILENAME_MAX]; 161 162 snprintf(tmp, FILENAME_MAX, "%-19s ", pkg); 163 show_index(tmp, COMMENT_FNAME); 164 } 165 else { 166 /* Start showing the package contents */ 167 if (!Quiet) 168 printf("%sInformation for %s:\n\n", InfoPrefix, pkg); 169 if (Flags & SHOW_COMMENT) 170 show_file("Comment:\n", COMMENT_FNAME); 171 if ((Flags & SHOW_REQBY) && !isemptyfile(REQUIRED_BY_FNAME)) 172 show_file("Required by:\n", REQUIRED_BY_FNAME); 173 if (Flags & SHOW_DESC) 174 show_file("Description:\n", DESC_FNAME); 175 if ((Flags & SHOW_DISPLAY) && fexists(DISPLAY_FNAME)) 176 show_file("Install notice:\n", DISPLAY_FNAME); 177 if (Flags & SHOW_PLIST) 178 show_plist("Packing list:\n", &plist, (plist_t)-1); 179 if ((Flags & SHOW_INSTALL) && fexists(INSTALL_FNAME)) 180 show_file("Install script:\n", INSTALL_FNAME); 181 if ((Flags & SHOW_DEINSTALL) && fexists(DEINSTALL_FNAME)) 182 show_file("De-Install script:\n", DEINSTALL_FNAME); 183 if ((Flags & SHOW_MTREE) && fexists(MTREE_FNAME)) 184 show_file("mtree file:\n", MTREE_FNAME); 185 if (Flags & SHOW_PREFIX) 186 show_plist("Prefix(s):\n", &plist, PLIST_CWD); 187 if (Flags & SHOW_FILES) 188 show_files("Files:\n", &plist); 189 if (!Quiet) 190 puts(InfoPrefix); 191 } 192 free_plist(&plist); 193 bail: 194 leave_playpen(Home); 195 if (isTMP) 196 unlink(fname); 197 return code; 198} 199 200void 201cleanup(int sig) 202{ 203 leave_playpen(Home); 204} 205