pen.c revision 9953
1#ifndef lint
2static const char *rcsid = "$Id: pen.c,v 1.13 1995/04/26 07:43:35 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 * 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 Cwd[FILENAME_MAX];
32static char Pen[FILENAME_MAX];
33extern char *PlayPen;
34
35/*
36 * Make a temporary directory to play in and chdir() to it, returning
37 * pathname of previous working directory.
38 */
39char *
40make_playpen(char *pen, size_t sz)
41{
42    if (!pen) {
43	char *cp;
44
45	if ((cp = getenv("PKG_TMPDIR")) != NULL)
46	    sprintf(Pen, "%s/instmp.XXXXXX", cp);
47	else
48	    strcpy(Pen, "/var/tmp/instmp.XXXXXX");
49	PlayPen = Pen;
50    }
51    else
52	strcpy(Pen, pen);
53    if (!getcwd(Cwd, FILENAME_MAX))
54	upchuck("getcwd");
55    if (!mktemp(Pen))
56	barf("Can't mktemp '%s'.", Pen);
57    if (mkdir(Pen, 0755) == FAIL)
58	barf("Can't mkdir '%s'.", Pen);
59    if (Verbose) {
60	if (!sz)
61		fprintf(stderr, "Free temp space: %d bytes\n", min_free(Pen));
62	else
63		fprintf(stderr, "Projected package size: %d bytes, free temp space: %d bytes\n", (int)sz, min_free(Pen));
64    }
65    if (min_free(Pen) < sz) {
66	rmdir(Pen);
67	barf("Not enough free space to create `%s'.\nPlease set your PKG_TMPDIR environment variable to a location with more space and\ntry the command again.", Pen);
68	PlayPen = NULL;
69    }
70    if (chdir(Pen) == FAIL)
71	barf("Can't chdir to '%s'.", Pen);
72    return Cwd;
73}
74
75/* Convenience routine for getting out of playpen */
76void
77leave_playpen(void)
78{
79    void (*oldsig)(int);
80
81    /* Don't interrupt while we're cleaning up */
82    oldsig = signal(SIGINT, SIG_IGN);
83    if (Cwd[0]) {
84	if (chdir(Cwd) == FAIL)
85	    barf("Can't chdir back to '%s'.", Cwd);
86	if (vsystem("rm -rf %s", Pen))
87	    fprintf(stderr, "Couldn't remove temporary dir '%s'\n", Pen);
88	Cwd[0] = '\0';
89    }
90    signal(SIGINT, oldsig);
91}
92
93/* Accessor function for telling us where the pen is */
94char *
95where_playpen(void)
96{
97    if (Cwd[0])
98	return Pen;
99    else
100	return NULL;
101}
102
103long
104min_free(char *tmpdir)
105{
106    struct statfs buf;
107
108    if (!tmpdir)
109	tmpdir = Pen;
110    if (statfs(tmpdir, &buf) != 0) {
111	perror("Error in statfs");
112	return -1;
113    }
114    return buf.f_bavail * buf.f_bsize;
115}
116