pen.c revision 21673
1#ifndef lint 2static const char *rcsid = "$FreeBSD: head/usr.sbin/pkg_install/lib/pen.c 21673 1997-01-14 07:20:47Z jkh $"; 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 * Routines for managing the "play pen". 22 * 23 */ 24 25#include "lib.h" 26#include <sys/signal.h> 27#include <sys/param.h> 28#include <sys/mount.h> 29 30/* For keeping track of where we are */ 31static char Current[FILENAME_MAX]; 32static char Previous[FILENAME_MAX]; 33 34char * 35where_playpen(void) 36{ 37 return Current; 38} 39 40/* Find a good place to play. */ 41static char * 42find_play_pen(char *pen, size_t sz) 43{ 44 char *cp; 45 struct stat sb; 46 47 if (pen[0] && stat(pen, &sb) != FAIL && (min_free(pen) >= sz)) 48 return pen; 49 else if ((cp = getenv("PKG_TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) 50 sprintf(pen, "%s/instmp.XXXXXX", cp); 51 else if ((cp = getenv("TMPDIR")) != NULL && stat(cp, &sb) != FAIL && (min_free(cp) >= sz)) 52 sprintf(pen, "%s/instmp.XXXXXX", cp); 53 else if (stat("/var/tmp", &sb) != FAIL && min_free("/var/tmp") >= sz) 54 strcpy(pen, "/var/tmp/instmp.XXXXXX"); 55 else if (stat("/tmp", &sb) != FAIL && min_free("/tmp") >= sz) 56 strcpy(pen, "/tmp/instmp.XXXXXX"); 57 else if ((stat("/usr/tmp", &sb) == SUCCESS || mkdir("/usr/tmp", 01777) == SUCCESS) && min_free("/usr/tmp") >= sz) 58 strcpy(pen, "/usr/tmp/instmp.XXXXXX"); 59 else { 60 barf("Can't find enough temporary space to extract the files, please set\n" 61 "your PKG_TMPDIR environment variable to a location with at least %d bytes\n" 62 "free.", sz); 63 return NULL; 64 } 65 return pen; 66} 67 68/* 69 * Make a temporary directory to play in and chdir() to it, returning 70 * pathname of previous working directory. 71 */ 72char * 73make_playpen(char *pen, size_t sz) 74{ 75 if (!find_play_pen(pen, sz)) 76 return NULL; 77 78 if (!mktemp(pen)) { 79 barf("Can't mktemp '%s'.", pen); 80 return NULL; 81 } 82 if (mkdir(pen, 0755) == FAIL) { 83 barf("Can't mkdir '%s'.", pen); 84 return NULL; 85 } 86 if (Verbose) { 87 if (sz) 88 fprintf(stderr, "Requested space: %d bytes, free space: %qd bytes in %s\n", (int)sz, min_free(pen), pen); 89 } 90 if (min_free(pen) < sz) { 91 rmdir(pen); 92 barf("Not enough free space to create: `%s'\n" 93 "Please set your PKG_TMPDIR environment variable to a location\n" 94 "with more space and\ntry the command again.", pen); 95 return NULL; 96 } 97 if (Current[0]) 98 strcpy(Previous, Current); 99 else if (!getcwd(Previous, FILENAME_MAX)) { 100 upchuck("getcwd"); 101 return NULL; 102 } 103 if (chdir(pen) == FAIL) 104 barf("Can't chdir to '%s'.", pen); 105 strcpy(Current, pen); 106 return Previous; 107} 108 109/* Convenience routine for getting out of playpen */ 110void 111leave_playpen(char *save) 112{ 113 void (*oldsig)(int); 114 115 /* Don't interrupt while we're cleaning up */ 116 oldsig = signal(SIGINT, SIG_IGN); 117 if (Previous[0] && chdir(Previous) == FAIL) 118 barf("Can't chdir back to '%s'.", Previous); 119 else if (Current[0] && strcmp(Current, Previous)) { 120 if (vsystem("rm -rf %s", Current)) 121 whinge("Couldn't remove temporary dir '%s'", Current); 122 strcpy(Current, Previous); 123 } 124 if (save) 125 strcpy(Previous, save); 126 else 127 Previous[0] = '\0'; 128 signal(SIGINT, oldsig); 129} 130 131off_t 132min_free(char *tmpdir) 133{ 134 struct statfs buf; 135 136 if (statfs(tmpdir, &buf) != 0) { 137 perror("Error in statfs"); 138 return -1; 139 } 140 return (off_t)buf.f_bavail * (off_t)buf.f_bsize; 141} 142