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