summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2004-11-29 16:23:23 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2004-11-29 16:23:23 +0000
commit55df41b563d595673e105141cf8ac1ab1c382847 (patch)
tree65338a97c83cc2c47badadcdb40164542b859e09 /bin
parenta86db4536b7a6efb18d910baba52cf31ec5e9fbd (diff)
Build the table of created directories in-memory, instead of using
a tmp file. Makes it possible to unpack an archive without using /tmp, while memory usage is still within every reasonable limit. "love it" deraadt@ ok millert@ jaredy@
Diffstat (limited to 'bin')
-rw-r--r--bin/pax/extern.h4
-rw-r--r--bin/pax/file_subs.c10
-rw-r--r--bin/pax/tables.c114
-rw-r--r--bin/pax/tables.h13
4 files changed, 58 insertions, 83 deletions
diff --git a/bin/pax/extern.h b/bin/pax/extern.h
index a05050a9cf1..f4237debfbc 100644
--- a/bin/pax/extern.h
+++ b/bin/pax/extern.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: extern.h,v 1.28 2004/03/30 16:14:22 millert Exp $ */
+/* $OpenBSD: extern.h,v 1.29 2004/11/29 16:23:22 otto Exp $ */
/* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */
/*-
@@ -271,7 +271,7 @@ void atdir_end(void);
void add_atdir(char *, dev_t, ino_t, time_t, time_t);
int get_atdir(dev_t, ino_t, time_t *, time_t *);
int dir_start(void);
-void add_dir(char *, int, struct stat *, int);
+void add_dir(char *, struct stat *, int);
void proc_dir(void);
u_int st_hash(char *, int, int);
diff --git a/bin/pax/file_subs.c b/bin/pax/file_subs.c
index 2a4e063ba9f..cd05bd1c4f0 100644
--- a/bin/pax/file_subs.c
+++ b/bin/pax/file_subs.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: file_subs.c,v 1.27 2004/04/16 22:50:23 deraadt Exp $ */
+/* $OpenBSD: file_subs.c,v 1.28 2004/11/29 16:23:22 otto Exp $ */
/* $NetBSD: file_subs.c,v 1.4 1995/03/21 09:07:18 cgd Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static const char sccsid[] = "@(#)file_subs.c 8.1 (Berkeley) 5/31/93";
#else
-static const char rcsid[] = "$OpenBSD: file_subs.c,v 1.27 2004/04/16 22:50:23 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: file_subs.c,v 1.28 2004/11/29 16:23:22 otto Exp $";
#endif
#endif /* not lint */
@@ -508,9 +508,9 @@ badlink:
* we have to force the mode to what was set here,
* since we changed it from the default as created.
*/
- add_dir(nm, strlen(nm), &(arcn->sb), 1);
+ add_dir(nm, &(arcn->sb), 1);
} else if (pmode || patime || pmtime)
- add_dir(nm, strlen(nm), &(arcn->sb), 0);
+ add_dir(nm, &(arcn->sb), 0);
}
if (patime || pmtime)
@@ -645,7 +645,7 @@ chk_path(char *name, uid_t st_uid, gid_t st_gid)
if ((access(name, R_OK | W_OK | X_OK) < 0) &&
(lstat(name, &sb) == 0)) {
set_pmode(name, ((sb.st_mode & FILEBITS) | S_IRWXU));
- add_dir(name, spt - name, &sb, 1);
+ add_dir(name, &sb, 1);
}
*(spt++) = '/';
continue;
diff --git a/bin/pax/tables.c b/bin/pax/tables.c
index b90e47ceb21..6fc1446e127 100644
--- a/bin/pax/tables.c
+++ b/bin/pax/tables.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tables.c,v 1.21 2003/08/16 17:31:55 deraadt Exp $ */
+/* $OpenBSD: tables.c,v 1.22 2004/11/29 16:23:22 otto Exp $ */
/* $NetBSD: tables.c,v 1.4 1995/03/21 09:07:45 cgd Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static const char sccsid[] = "@(#)tables.c 8.1 (Berkeley) 5/31/93";
#else
-static const char rcsid[] = "$OpenBSD: tables.c,v 1.21 2003/08/16 17:31:55 deraadt Exp $";
+static const char rcsid[] = "$OpenBSD: tables.c,v 1.22 2004/11/29 16:23:22 otto Exp $";
#endif
#endif /* not lint */
@@ -76,8 +76,9 @@ static FTM **ftab = NULL; /* file time table for updating arch */
static NAMT **ntab = NULL; /* interactive rename storage table */
static DEVT **dtab = NULL; /* device/inode mapping tables */
static ATDIR **atab = NULL; /* file tree directory time reset table */
-static int dirfd = -1; /* storage for setting created dir time/mode */
-static u_long dircnt; /* entries in dir time/mode storage */
+static DIRDATA *dirp = NULL; /* storage for setting created dir time/mode */
+static size_t dirsize; /* size of dirp table */
+static long dircnt = 0; /* entries in dir time/mode storage */
static int ffd = -1; /* tmp file for file time table name storage */
static DEVT *chk_dev(dev_t, int);
@@ -1092,21 +1093,15 @@ get_atdir(dev_t dev, ino_t ino, time_t *mtime, time_t *atime)
int
dir_start(void)
{
-
- if (dirfd != -1)
+ if (dirp != NULL)
return(0);
- /*
- * unlink the file so it goes away at termination by itself
- */
- memcpy(tempbase, _TFILE_BASE, sizeof(_TFILE_BASE));
- if ((dirfd = mkstemp(tempfile)) >= 0) {
- (void)unlink(tempfile);
- return(0);
+ dirsize = DIRP_SIZE;
+ if ((dirp = malloc(dirsize * sizeof(DIRDATA))) == NULL) {
+ paxwarn(1, "Unable to allocate memory for directory times");
+ return(-1);
}
- paxwarn(1, "Unable to create temporary file for directory times: %s",
- tempfile);
- return(-1);
+ return(0);
}
/*
@@ -1123,38 +1118,34 @@ dir_start(void)
*/
void
-add_dir(char *name, int nlen, struct stat *psb, int frc_mode)
+add_dir(char *name, struct stat *psb, int frc_mode)
{
- DIRDATA dblk;
+ DIRDATA *dblk;
- if (dirfd < 0)
+ if (dirp == NULL)
return;
- /*
- * get current position (where file name will start) so we can store it
- * in the trailer
- */
- if ((dblk.npos = lseek(dirfd, 0L, SEEK_CUR)) < 0) {
- paxwarn(1,"Unable to store mode and times for directory: %s",name);
- return;
+ if (dircnt == dirsize) {
+ dblk = realloc(dirp, 2 * dirsize * sizeof(DIRDATA));
+ if (dblk == NULL) {
+ paxwarn(1, "Unable to store mode and times for created"
+ " directory: %s", name);
+ return;
+ }
+ dirp = dblk;
+ dirsize *= 2;
}
-
- /*
- * write the file name followed by the trailer
- */
- dblk.nlen = nlen + 1;
- dblk.mode = psb->st_mode & 0xffff;
- dblk.mtime = psb->st_mtime;
- dblk.atime = psb->st_atime;
- dblk.frc_mode = frc_mode;
- if ((write(dirfd, name, dblk.nlen) == dblk.nlen) &&
- (write(dirfd, (char *)&dblk, sizeof(dblk)) == sizeof(dblk))) {
- ++dircnt;
+ dblk = &dirp[dircnt];
+ if ((dblk->name = strdup(name)) == NULL) {
+ paxwarn(1, "Unable to store mode and times for created"
+ " directory: %s", name);
return;
}
-
- paxwarn(1,"Unable to store mode and times for created directory: %s",name);
- return;
+ dblk->mode = psb->st_mode & 0xffff;
+ dblk->mtime = psb->st_mtime;
+ dblk->atime = psb->st_atime;
+ dblk->frc_mode = frc_mode;
+ ++dircnt;
}
/*
@@ -1166,46 +1157,31 @@ add_dir(char *name, int nlen, struct stat *psb, int frc_mode)
void
proc_dir(void)
{
- char name[PAXPATHLEN+1];
- DIRDATA dblk;
- u_long cnt;
+ DIRDATA *dblk;
+ long cnt;
- if (dirfd < 0)
+ if (dirp == NULL)
return;
/*
* read backwards through the file and process each directory
*/
- for (cnt = 0; cnt < dircnt; ++cnt) {
- /*
- * read the trailer, then the file name, if this fails
- * just give up.
- */
- if (lseek(dirfd, -((off_t)sizeof(dblk)), SEEK_CUR) < 0)
- break;
- if (read(dirfd,(char *)&dblk, sizeof(dblk)) != sizeof(dblk))
- break;
- if (lseek(dirfd, dblk.npos, SEEK_SET) < 0)
- break;
- if (read(dirfd, name, dblk.nlen) != dblk.nlen)
- break;
- if (lseek(dirfd, dblk.npos, SEEK_SET) < 0)
- break;
-
+ cnt = dircnt;
+ while (--cnt >= 0) {
/*
* frc_mode set, make sure we set the file modes even if
* the user didn't ask for it (see file_subs.c for more info)
*/
- if (pmode || dblk.frc_mode)
- set_pmode(name, dblk.mode);
+ dblk = &dirp[cnt];
+ if (pmode || dblk->frc_mode)
+ set_pmode(dblk->name, dblk->mode);
if (patime || pmtime)
- set_ftime(name, dblk.mtime, dblk.atime, 0);
+ set_ftime(dblk->name, dblk->mtime, dblk->atime, 0);
+ free(dblk->name);
}
- (void)close(dirfd);
- dirfd = -1;
- if (cnt != dircnt)
- paxwarn(1,"Unable to set mode and times for created directories");
- return;
+ free(dirp);
+ dirp = NULL;
+ dircnt = 0;
}
/*
diff --git a/bin/pax/tables.h b/bin/pax/tables.h
index bcf2826e695..e065387e4fa 100644
--- a/bin/pax/tables.h
+++ b/bin/pax/tables.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tables.h,v 1.6 2003/10/20 06:22:27 jmc Exp $ */
+/* $OpenBSD: tables.h,v 1.7 2004/11/29 16:23:22 otto Exp $ */
/* $NetBSD: tables.h,v 1.3 1995/03/21 09:07:47 cgd Exp $ */
/*-
@@ -51,6 +51,7 @@
#define D_TAB_SZ 317 /* unique device mapping table */
#define A_TAB_SZ 317 /* ftree dir access time reset table */
#define MAXKEYLEN 64 /* max number of chars for hash */
+#define DIRP_SIZE 64 /* initial size of created dir table */
/*
* file hard link structure (hashed by dev/ino and chained) used to find the
@@ -157,15 +158,13 @@ typedef struct atdir {
* times and/or modes). We must reset time in the reverse order of creation,
* because entries are added from the top of the file tree to the bottom.
* We MUST reset times from leaf to root (it will not work the other
- * direction). Entries are recorded into a spool file to make reverse
- * reading faster.
+ * direction).
*/
typedef struct dirdata {
- int nlen; /* length of the directory name (includes \0) */
- off_t npos; /* position in file where this dir name starts */
- mode_t mode; /* file mode to restore */
+ char *name; /* file name */
time_t mtime; /* mtime to set */
time_t atime; /* atime to set */
- int frc_mode; /* do we force mode settings? */
+ u_int16_t mode; /* file mode to restore */
+ u_int16_t frc_mode; /* do we force mode settings? */
} DIRDATA;