141 add_plist_top(&plist, PLIST_PKGDEP, deps[i]); 142 if (Verbose && !PlistOnly) 143 printf(" %s", deps[i]); 144 } 145 } 146 147 if (Verbose && !PlistOnly) 148 printf(".\n"); 149 } 150 151 /* If a SrcDir override is set, add it now */ 152 if (SrcDir) { 153 if (Verbose && !PlistOnly) 154 printf("Using SrcDir value of %s\n", SrcDir); 155 add_plist(&plist, PLIST_SRC, SrcDir); 156 } 157 158 /* Slurp in the packing list */ 159 read_plist(&plist, pkg_in); 160 161 /* Prefix should add an @cwd to the packing list */ 162 if (Prefix) 163 add_plist_top(&plist, PLIST_CWD, Prefix); 164 165 /* Add the origin if asked, at the top */ 166 if (Origin) 167 add_plist_top(&plist, PLIST_ORIGIN, Origin); 168 169 /* 170 * Run down the list and see if we've named it, if not stick in a name 171 * at the top. 172 */ 173 if (find_plist(&plist, PLIST_NAME) == NULL) 174 add_plist_top(&plist, PLIST_NAME, basename(pkg)); 175 176 if (asprintf(&cp, "PKG_FORMAT_REVISION:%d.%d", PLIST_FMT_VER_MAJOR, 177 PLIST_FMT_VER_MINOR) == -1) { 178 errx(2, "%s: asprintf() failed", __FUNCTION__); 179 } 180 add_plist_top(&plist, PLIST_COMMENT, cp); 181 free(cp); 182 183 /* 184 * We're just here for to dump out a revised plist for the FreeBSD ports 185 * hack. It's not a real create in progress. 186 */ 187 if (PlistOnly) { 188 check_list(home, &plist); 189 write_plist(&plist, stdout); 190 exit(0); 191 } 192 193 /* Make a directory to stomp around in */ 194 home = make_playpen(PlayPen, 0); 195 signal(SIGINT, cleanup); 196 signal(SIGHUP, cleanup); 197 198 /* Make first "real contents" pass over it */ 199 check_list(home, &plist); 200 (void) umask(022); /* 201 * Make sure gen'ed directories, files don't have 202 * group or other write bits. 203 */ 204 /* copy_plist(home, &plist); */ 205 /* mark_plist(&plist); */ 206 207 /* Now put the release specific items in */ 208 add_plist(&plist, PLIST_CWD, "."); 209 write_file(COMMENT_FNAME, Comment); 210 add_plist(&plist, PLIST_IGNORE, NULL); 211 add_plist(&plist, PLIST_FILE, COMMENT_FNAME); 212 write_file(DESC_FNAME, Desc); 213 add_plist(&plist, PLIST_IGNORE, NULL); 214 add_plist(&plist, PLIST_FILE, DESC_FNAME); 215 216 if (Install) { 217 copy_file(home, Install, INSTALL_FNAME); 218 add_plist(&plist, PLIST_IGNORE, NULL); 219 add_plist(&plist, PLIST_FILE, INSTALL_FNAME); 220 } 221 if (PostInstall) { 222 copy_file(home, PostInstall, POST_INSTALL_FNAME); 223 add_plist(&plist, PLIST_IGNORE, NULL); 224 add_plist(&plist, PLIST_FILE, POST_INSTALL_FNAME); 225 } 226 if (DeInstall) { 227 copy_file(home, DeInstall, DEINSTALL_FNAME); 228 add_plist(&plist, PLIST_IGNORE, NULL); 229 add_plist(&plist, PLIST_FILE, DEINSTALL_FNAME); 230 } 231 if (PostDeInstall) { 232 copy_file(home, PostDeInstall, POST_DEINSTALL_FNAME); 233 add_plist(&plist, PLIST_IGNORE, NULL); 234 add_plist(&plist, PLIST_FILE, POST_DEINSTALL_FNAME); 235 } 236 if (Require) { 237 copy_file(home, Require, REQUIRE_FNAME); 238 add_plist(&plist, PLIST_IGNORE, NULL); 239 add_plist(&plist, PLIST_FILE, REQUIRE_FNAME); 240 } 241 if (Display) { 242 copy_file(home, Display, DISPLAY_FNAME); 243 add_plist(&plist, PLIST_IGNORE, NULL); 244 add_plist(&plist, PLIST_FILE, DISPLAY_FNAME); 245 add_plist(&plist, PLIST_DISPLAY, DISPLAY_FNAME); 246 } 247 if (Mtree) { 248 copy_file(home, Mtree, MTREE_FNAME); 249 add_plist(&plist, PLIST_IGNORE, NULL); 250 add_plist(&plist, PLIST_FILE, MTREE_FNAME); 251 add_plist(&plist, PLIST_MTREE, MTREE_FNAME); 252 } 253 254 /* Finally, write out the packing list */ 255 fp = fopen(CONTENTS_FNAME, "w"); 256 if (!fp) { 257 cleanup(0); 258 errx(2, __FUNCTION__ ": can't open file %s for writing", CONTENTS_FNAME); 259 } 260 write_plist(&plist, fp); 261 if (fclose(fp)) { 262 cleanup(0); 263 errx(2, __FUNCTION__ ": error while closing %s", CONTENTS_FNAME); 264 } 265 266 /* And stick it into a tar ball */ 267 make_dist(home, pkg, suf, &plist); 268 269 /* Cleanup */ 270 free(Comment); 271 free(Desc); 272 free_plist(&plist); 273 leave_playpen(); 274 return TRUE; /* Success */ 275} 276 277static void 278make_dist(const char *homedir, const char *pkg, const char *suff, Package *plist) 279{ 280 char tball[FILENAME_MAX]; 281 PackingList p; 282 int ret; 283 const char *args[50]; /* Much more than enough. */ 284 int nargs = 0; 285 int pipefds[2]; 286 FILE *totar; 287 pid_t pid; 288 const char *cname; 289 290 args[nargs++] = "tar"; /* argv[0] */ 291 292 if (*pkg == '/') 293 snprintf(tball, FILENAME_MAX, "%s.%s", pkg, suff); 294 else 295 snprintf(tball, FILENAME_MAX, "%s/%s.%s", homedir, pkg, suff); 296 297 args[nargs++] = "-c"; 298 args[nargs++] = "-f"; 299 args[nargs++] = tball; 300 if (strchr(suff, 'z')) { /* Compress/gzip/bzip2? */ 301 if (Zipper == BZIP2) { 302 args[nargs++] = "-j"; 303 cname = "bzip'd "; 304 } 305 else { 306 args[nargs++] = "-z"; 307 cname = "gzip'd "; 308 } 309 } else { 310 cname = ""; 311 } 312 if (Dereference) 313 args[nargs++] = "-h"; 314 if (ExcludeFrom) { 315 args[nargs++] = "-X"; 316 args[nargs++] = ExcludeFrom; 317 } 318 args[nargs++] = "-T"; /* Take filenames from file instead of args. */ 319 args[nargs++] = "-"; /* Use stdin for the file. */ 320 args[nargs] = NULL; 321 322 if (Verbose) 323 printf("Creating %star ball in '%s'\n", cname, tball); 324 325 /* Set up a pipe for passing the filenames, and fork off a tar process. */ 326 if (pipe(pipefds) == -1) { 327 cleanup(0); 328 errx(2, __FUNCTION__ ": cannot create pipe"); 329 } 330 if ((pid = fork()) == -1) { 331 cleanup(0); 332 errx(2, __FUNCTION__ ": cannot fork process for tar"); 333 } 334 if (pid == 0) { /* The child */ 335 dup2(pipefds[0], 0); 336 close(pipefds[0]); 337 close(pipefds[1]); 338 execv("/usr/bin/tar", (char * const *)(uintptr_t)args); 339 cleanup(0); 340 errx(2, __FUNCTION__ ": failed to execute tar command"); 341 } 342 343 /* Meanwhile, back in the parent process ... */ 344 close(pipefds[0]); 345 if ((totar = fdopen(pipefds[1], "w")) == NULL) { 346 cleanup(0); 347 errx(2, __FUNCTION__ ": fdopen failed"); 348 } 349 350 fprintf(totar, "%s\n", CONTENTS_FNAME); 351 fprintf(totar, "%s\n", COMMENT_FNAME); 352 fprintf(totar, "%s\n", DESC_FNAME); 353 354 if (Install) 355 fprintf(totar, "%s\n", INSTALL_FNAME); 356 if (PostInstall) 357 fprintf(totar, "%s\n", POST_INSTALL_FNAME); 358 if (DeInstall) 359 fprintf(totar, "%s\n", DEINSTALL_FNAME); 360 if (PostDeInstall) 361 fprintf(totar, "%s\n", POST_DEINSTALL_FNAME); 362 if (Require) 363 fprintf(totar, "%s\n", REQUIRE_FNAME); 364 if (Display) 365 fprintf(totar, "%s\n", DISPLAY_FNAME); 366 if (Mtree) 367 fprintf(totar, "%s\n", MTREE_FNAME); 368 369 for (p = plist->head; p; p = p->next) { 370 if (p->type == PLIST_FILE) 371 fprintf(totar, "%s\n", p->name); 372 else if (p->type == PLIST_CWD || p->type == PLIST_SRC) 373 fprintf(totar, "-C\n%s\n", p->name); 374 else if (p->type == PLIST_IGNORE) 375 p = p->next; 376 } 377 378 fclose(totar); 379 wait(&ret); 380 /* assume either signal or bad exit is enough for us */ 381 if (ret) { 382 cleanup(0); 383 errx(2, __FUNCTION__ ": tar command failed with code %d", ret); 384 } 385} 386 387static void 388sanity_check() 389{ 390 if (!Comment) { 391 cleanup(0); 392 errx(2, __FUNCTION__ ": required package comment string is missing (-c comment)"); 393 } 394 if (!Desc) { 395 cleanup(0); 396 errx(2, __FUNCTION__ ": required package description string is missing (-d desc)"); 397 } 398 if (!Contents) { 399 cleanup(0); 400 errx(2, __FUNCTION__ ": required package contents list is missing (-f [-]file)"); 401 } 402} 403 404 405/* Clean up those things that would otherwise hang around */ 406void 407cleanup(int sig) 408{ 409 int in_cleanup = 0; 410 411 if (!in_cleanup) { 412 in_cleanup = 1; 413 leave_playpen(); 414 } 415 if (sig) 416 exit(1); 417} 418 419static int 420create_from_installed(const char *pkg, const char *suf) 421{ 422 FILE *fp; 423 Package plist; 424 char homedir[MAXPATHLEN], log_dir[FILENAME_MAX]; 425 426 snprintf(log_dir, sizeof(log_dir), "%s/%s", LOG_DIR, InstalledPkg); 427 if (!fexists(log_dir)) { 428 warnx("can't find package '%s' installed!", InstalledPkg); 429 return 1; 430 } 431 getcwd(homedir, sizeof(homedir)); 432 if (chdir(log_dir) == FAIL) { 433 warnx("can't change directory to '%s'!", log_dir); 434 return 1; 435 } 436 /* Suck in the contents list */ 437 plist.head = plist.tail = NULL; 438 fp = fopen(CONTENTS_FNAME, "r"); 439 if (!fp) { 440 warnx("unable to open %s file", CONTENTS_FNAME); 441 return 1; 442 } 443 /* If we have a prefix, add it now */ 444 read_plist(&plist, fp); 445 fclose(fp); 446 447 make_dist(homedir, pkg, suf, &plist); 448 449 free_plist(&plist); 450 return TRUE; 451}
|