extract.c revision 8635
1#ifndef lint 2static const char *rcsid = "$Id: extract.c,v 1.6 1994/12/06 00:51:32 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 * 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 if (!isdir(todir)) 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 = malloc(maxargs); 60 if (!where_args) 61 barf("can't get argument list space"); 62 perm_args = malloc(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 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 if (p->name[0] == '/') { 109 PUSHOUT(Directory); 110 } 111 } else { 112 /* rename failed, try copying with a big tar command */ 113 if (p->name[0] == '/' || 114 TOOBIG(p->name) || 115 last_chdir != Directory) { 116 PUSHOUT(last_chdir); 117 last_chdir = Directory; 118 } 119 add_count = snprintf(&where_args[where_count], 120 maxargs - where_count, 121 " %s", p->name); 122 if (add_count > maxargs - where_count) 123 barf("oops, miscounted strings!"); 124 where_count += add_count; 125 add_count = snprintf(&perm_args[perm_count], 126 maxargs - perm_count, 127 "%s ", p->name); 128 if (add_count > maxargs - perm_count) 129 barf("oops, miscounted strings!"); 130 perm_count += add_count; 131 if (p->name[0] == '/') { 132 PUSHOUT(Directory); 133 } 134 } 135 } 136 break; 137 138 case PLIST_CWD: 139 if (Verbose) 140 printf("extract: CWD to %s\n", p->name); 141 PUSHOUT(Directory); 142 if (strcmp(p->name, ".")) { 143 if (!Fake && make_hierarchy(p->name) == FAIL) 144 barf("Unable make directory '%s'.", p->name); 145 Directory = p->name; 146 } 147 else 148 Directory = home; 149 break; 150 151 case PLIST_CMD: 152 format_cmd(cmd, p->name, Directory, last_file); 153 PUSHOUT(Directory); 154 if (Verbose) 155 printf("extract: execute '%s'\n", cmd); 156 if (!Fake && system(cmd)) 157 whinge("Command '%s' failed.", cmd); 158 break; 159 160 case PLIST_CHMOD: 161 PUSHOUT(Directory); 162 Mode = p->name; 163 break; 164 165 case PLIST_CHOWN: 166 PUSHOUT(Directory); 167 Owner = p->name; 168 break; 169 170 case PLIST_CHGRP: 171 PUSHOUT(Directory); 172 Group = p->name; 173 break; 174 175 case PLIST_COMMENT: 176 break; 177 178 case PLIST_IGNORE: 179 p = p->next; 180 break; 181 } 182 p = p->next; 183 } 184 PUSHOUT(Directory); 185} 186