summaryrefslogtreecommitdiff
path: root/bin/pax/ftree.c
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2003-06-13 17:51:15 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2003-06-13 17:51:15 +0000
commita42016a89f1868417d387d1913b585cc085f838f (patch)
tree18254b99fdacd0fa29113af2a4a37b68887d3ed9 /bin/pax/ftree.c
parent2beff53b1604b0bf21610bf30d8b0b92f8a29a53 (diff)
Add a -0 flag to make pax use a NUL instead of a newline as the
pathname separator. Works in list mode as well as read/copy mode. Based on a patch from David Leonard; closes PR 3310
Diffstat (limited to 'bin/pax/ftree.c')
-rw-r--r--bin/pax/ftree.c58
1 files changed, 52 insertions, 6 deletions
diff --git a/bin/pax/ftree.c b/bin/pax/ftree.c
index 63d4e854763..3107867934c 100644
--- a/bin/pax/ftree.c
+++ b/bin/pax/ftree.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ftree.c,v 1.22 2003/06/02 23:32:08 millert Exp $ */
+/* $OpenBSD: ftree.c,v 1.23 2003/06/13 17:51:14 millert Exp $ */
/* $NetBSD: ftree.c,v 1.4 1995/03/21 09:07:21 cgd Exp $ */
/*-
@@ -38,7 +38,7 @@
#if 0
static const char sccsid[] = "@(#)ftree.c 8.2 (Berkeley) 4/18/94";
#else
-static const char rcsid[] = "$OpenBSD: ftree.c,v 1.22 2003/06/02 23:32:08 millert Exp $";
+static const char rcsid[] = "$OpenBSD: ftree.c,v 1.23 2003/06/13 17:51:14 millert Exp $";
#endif
#endif /* not lint */
@@ -80,6 +80,7 @@ static FTSENT *ftent = NULL; /* current file tree entry */
static int ftree_skip; /* when set skip to next file arg */
static int ftree_arg(void);
+static char *getpathname(char *, int);
/*
* ftree_start()
@@ -259,7 +260,6 @@ ftree_chk(void)
static int
ftree_arg(void)
{
- char *pt;
/*
* close off the current file tree
@@ -279,10 +279,8 @@ ftree_arg(void)
* the user didn't supply any args, get the file trees
* to process from stdin;
*/
- if (fgets(farray[0], PAXPATHLEN+1, stdin) == NULL)
+ if (getpathname(farray[0], PAXPATHLEN+1) == NULL)
return(-1);
- if ((pt = strchr(farray[0], '\n')) != NULL)
- *pt = '\0';
} else {
/*
* the user supplied the file args as arguments to pax
@@ -499,3 +497,51 @@ next_file(ARCHD *arcn)
arcn->org_name = ftent->fts_path;
return(0);
}
+
+/*
+ * getpathname()
+ * Reads a pathname from stdin, handling NUL- or newline-termination.
+ * Return:
+ * NULL at end of file, otherwise the NUL-terminated buffer.
+ */
+
+static char *
+getpathname(char *buf, int buflen)
+{
+ char *bp, *ep;
+ int ch, term;
+
+ if (zeroflag) {
+ /*
+ * Read a NUL-terminated pathname, being especially
+ * paranoid about proper termination and pathname length.
+ */
+ for (bp = buf, ep = buf + buflen; bp < ep; bp++) {
+ if ((ch = getchar()) == EOF) {
+ if (bp != buf)
+ paxwarn(1, "Ignoring unterminated "
+ "pathname at EOF");
+ return(NULL);
+ }
+ if ((*bp = ch) == '\0')
+ return(buf);
+ }
+ /* Too long - skip this path */
+ *--bp = '\0';
+ term = '\0';
+ } else {
+ if (fgets(buf, buflen, stdin) == NULL)
+ return(NULL);
+ if ((bp = strchr(buf, '\n')) != NULL || feof(stdin)) {
+ if (bp != NULL)
+ *bp = '\0';
+ return(buf);
+ }
+ /* Too long - skip this path */
+ term = '\n';
+ }
+ while ((ch = getchar()) != term && ch != EOF)
+ ;
+ paxwarn(1, "Ignoring too-long pathname: %s", buf);
+ return(NULL);
+}