extract.c revision 23109
11553Srgrimes#ifndef lint 21553Srgrimesstatic const char *rcsid = "$Id: extract.c,v 1.11 1997/02/22 16:09:16 peter Exp $"; 31553Srgrimes#endif 41553Srgrimes 51553Srgrimes/* 61553Srgrimes * FreeBSD install - a package for the installation and maintainance 71553Srgrimes * of non-core utilities. 81553Srgrimes * 91553Srgrimes * Redistribution and use in source and binary forms, with or without 101553Srgrimes * modification, are permitted provided that the following conditions 111553Srgrimes * are met: 121553Srgrimes * 1. Redistributions of source code must retain the above copyright 131553Srgrimes * notice, this list of conditions and the following disclaimer. 141553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 151553Srgrimes * notice, this list of conditions and the following disclaimer in the 161553Srgrimes * documentation and/or other materials provided with the distribution. 171553Srgrimes * 181553Srgrimes * Jordan K. Hubbard 191553Srgrimes * 18 July 1993 201553Srgrimes * 211553Srgrimes * This is the package extraction code for the add module. 221553Srgrimes * 231553Srgrimes */ 241553Srgrimes 251553Srgrimes#include "lib.h" 261553Srgrimes#include "add.h" 271553Srgrimes 281553Srgrimes 291553Srgrimes#define STARTSTRING "tar cf - " 30133249Simp#define TOOBIG(str) ((strlen(str) + 22 + strlen(home) + where_count > maxargs) \ 311553Srgrimes || (strlen(str) + 6 + strlen(home) + perm_count > maxargs)) 321553Srgrimes 331553Srgrimes#define PUSHOUT(todir) /* push out string */ \ 341553Srgrimes if (where_count > sizeof(STARTSTRING)-1) { \ 351553Srgrimes strcat(where_args, "|tar xf - -C "); \ 361553Srgrimes strcat(where_args, todir); \ 37 if (system(where_args)) \ 38 barf("can not invoke %d byte tar pipeline: %s", strlen(where_args), where_args); \ 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) / 2; /* Just use half the argument space */ 57 where_args = alloca(maxargs); 58 if (!where_args) 59 barf("can't get argument list space"); 60 perm_args = alloca(maxargs); 61 if (!perm_args) 62 barf("can't get argument list space"); 63 64 strcpy(where_args, STARTSTRING); 65 where_count = sizeof(STARTSTRING)-1; 66 perm_args[0] = 0; 67 68 last_chdir = 0; 69 70 /* Reset the world */ 71 Owner = NULL; 72 Group = NULL; 73 Mode = NULL; 74 last_file = NULL; 75 Directory = home; 76 77 /* Do it */ 78 while (p) { 79 char cmd[FILENAME_MAX]; 80 81 switch(p->type) { 82 case PLIST_NAME: 83 PkgName = p->name; 84 if (Verbose) 85 printf("extract: Package name is %s\n", p->name); 86 break; 87 88 case PLIST_FILE: 89 last_file = p->name; 90 if (Verbose) 91 printf("extract: %s/%s\n", Directory, p->name); 92 if (!Fake) { 93 char try[FILENAME_MAX]; 94 95 /* first try to rename it into place */ 96 sprintf(try, "%s/%s", Directory, p->name); 97 if (rename(p->name, try) == 0) { 98 /* try to add to list of perms to be changed and run in bulk. */ 99 if (p->name[0] == '/' || TOOBIG(p->name)) { 100 PUSHOUT(Directory); 101 } 102 add_count = snprintf(&perm_args[perm_count], 103 maxargs - perm_count, 104 "%s ", p->name); 105 if (add_count > maxargs - perm_count) 106 barf("oops, miscounted strings!"); 107 perm_count += add_count; 108 } 109 else { 110 /* rename failed, try copying with a big tar command */ 111 if (last_chdir != Directory) { 112 PUSHOUT(last_chdir); 113 last_chdir = Directory; 114 } 115 else if (p->name[0] == '/' || TOOBIG(p->name)) { 116 PUSHOUT(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 } 131 } 132 break; 133 134 case PLIST_CWD: 135 if (Verbose) 136 printf("extract: CWD to %s\n", p->name); 137 PUSHOUT(Directory); 138 if (strcmp(p->name, ".")) { 139 if (!Fake && make_hierarchy(p->name) == FAIL) 140 barf("Unable make directory '%s'.", p->name); 141 Directory = p->name; 142 } 143 else 144 Directory = home; 145 break; 146 147 case PLIST_CMD: 148 format_cmd(cmd, p->name, Directory, last_file); 149 PUSHOUT(Directory); 150 if (Verbose) 151 printf("extract: execute '%s'\n", cmd); 152 if (!Fake && system(cmd)) 153 whinge("Command '%s' failed.", cmd); 154 break; 155 156 case PLIST_CHMOD: 157 PUSHOUT(Directory); 158 Mode = p->name; 159 break; 160 161 case PLIST_CHOWN: 162 PUSHOUT(Directory); 163 Owner = p->name; 164 break; 165 166 case PLIST_CHGRP: 167 PUSHOUT(Directory); 168 Group = p->name; 169 break; 170 171 case PLIST_COMMENT: 172 break; 173 174 case PLIST_IGNORE: 175 p = p->next; 176 break; 177 } 178 p = p->next; 179 } 180 PUSHOUT(Directory); 181} 182