extract.c revision 22997
1#ifndef lint 2static const char *rcsid = "$Id$"; 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 * 18 July 1993 20 * 21 * This is the package extraction code for the add module. 22 * 23 */ 24 25#include "lib.h" 26#include "add.h" 27 28 29#define STARTSTRING "tar cf -" 30#define TOOBIG(str) ((strlen(str) + 6 + strlen(home) + where_count > maxargs) \ 31 || (strlen(str) + 6 + strlen(home) + perm_count > maxargs)) 32 33#define PUSHOUT(todir) /* push out string */ \ 34 if (strlen(where_args) > sizeof(STARTSTRING)-1) { \ 35 strcat(where_args, "|tar xf - -C "); \ 36 strcat(where_args, todir); \ 37 if (system(where_args)) \ 38 barf("can't invoke tar pipeline"); \ 39 strcpy(where_args, STARTSTRING); \ 40 where_count = sizeof(STARTSTRING)-1; \ 41 } \ 42 if (perm_count) { \ 43 apply_perms(todir, perm_args); \ 44 perm_args[0] = 0;\ 45 perm_count = 0; \ 46 } 47 48void 49extract_plist(char *home, Package *pkg) 50{ 51 PackingList p = pkg->head; 52 char *last_file; 53 char *where_args, *perm_args, *last_chdir; 54 int maxargs, where_count = 0, perm_count = 0, add_count; 55 56 maxargs = sysconf(_SC_ARG_MAX); 57 maxargs -= 64; /* some slop for the tar cmd text, 58 and sh -c */ 59 where_args = alloca(maxargs); 60 if (!where_args) 61 barf("can't get argument list space"); 62 perm_args = alloca(maxargs); 63 if (!perm_args) 64 barf("can't get argument list space"); 65 66 strcpy(where_args, STARTSTRING); 67 where_count = sizeof(STARTSTRING)-1; 68 perm_args[0] = 0; 69 70 last_chdir = 0; 71 72 /* Reset the world */ 73 Owner = NULL; 74 Group = NULL; 75 Mode = NULL; 76 last_file = NULL; 77 Directory = home; 78 79 /* Do it */ 80 while (p) { 81 char cmd[FILENAME_MAX]; 82 83 switch(p->type) { 84 case PLIST_NAME: 85 PkgName = p->name; 86 if (Verbose) 87 printf("extract: Package name is %s\n", p->name); 88 break; 89 90 case PLIST_FILE: 91 last_file = p->name; 92 if (Verbose) 93 printf("extract: %s/%s\n", Directory, p->name); 94 if (!Fake) { 95 char try[FILENAME_MAX]; 96 97 /* first try to rename it into place */ 98 sprintf(try, "%s/%s", Directory, p->name); 99 if (rename(p->name, try) == 0) { 100 /* try to add to list of perms to be changed, 101 and run in bulk. */ 102 if (p->name[0] == '/' || TOOBIG(p->name)) 103 PUSHOUT(Directory); 104 add_count = snprintf(&perm_args[perm_count], 105 maxargs - perm_count, 106 "%s ", p->name); 107 if (add_count > maxargs - perm_count) 108 barf("oops, miscounted strings!"); 109 perm_count += add_count; 110 } 111 else { 112 /* rename failed, try copying with a big tar command */ 113 if (p->name[0] == '/' || TOOBIG(p->name) || 114 last_chdir != Directory) { 115 PUSHOUT(last_chdir); 116 last_chdir = Directory; 117 } 118 add_count = snprintf(&where_args[where_count], 119 maxargs - where_count, 120 " %s", p->name); 121 if (add_count > maxargs - where_count) 122 barf("oops, miscounted strings!"); 123 where_count += add_count; 124 add_count = snprintf(&perm_args[perm_count], 125 maxargs - perm_count, 126 "%s ", p->name); 127 if (add_count > maxargs - perm_count) 128 barf("oops, miscounted strings!"); 129 perm_count += add_count; 130 if (p->name[0] == '/') { 131 PUSHOUT(Directory); 132 } 133 } 134 } 135 break; 136 137 case PLIST_CWD: 138 if (Verbose) 139 printf("extract: CWD to %s\n", p->name); 140 PUSHOUT(Directory); 141 if (strcmp(p->name, ".")) { 142 if (!Fake && make_hierarchy(p->name) == FAIL) 143 barf("Unable make directory '%s'.", p->name); 144 Directory = p->name; 145 } 146 else 147 Directory = home; 148 break; 149 150 case PLIST_CMD: 151 format_cmd(cmd, p->name, Directory, last_file); 152 PUSHOUT(Directory); 153 if (Verbose) 154 printf("extract: execute '%s'\n", cmd); 155 if (!Fake && system(cmd)) 156 whinge("Command '%s' failed.", cmd); 157 break; 158 159 case PLIST_CHMOD: 160 PUSHOUT(Directory); 161 Mode = p->name; 162 break; 163 164 case PLIST_CHOWN: 165 PUSHOUT(Directory); 166 Owner = p->name; 167 break; 168 169 case PLIST_CHGRP: 170 PUSHOUT(Directory); 171 Group = p->name; 172 break; 173 174 case PLIST_COMMENT: 175 break; 176 177 case PLIST_IGNORE: 178 p = p->next; 179 break; 180 } 181 p = p->next; 182 } 183 PUSHOUT(Directory); 184} 185