From: Stelian Pop Date: Mon, 11 Oct 1999 12:59:10 +0000 (+0000) Subject: Version 0.4b6. X-Git-Tag: release_0_4b6 X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=ddd2ef55b78a62c4bc3daad18bef8a90e85a2052;p=dump.git Version 0.4b6. --- diff --git a/CHANGES b/CHANGES index db2f470..7e9b617 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,24 @@ +Changes between versions 0.4b5 and 0.4b6 +======================================== + +1. Integrated multiple patches from RedHat, Debian and SuSE: + + - tweak dump/itime.c to not try to read dumpdates if the 'u' option + isn't specified. + - several fixes in the man pages. + - update the default tape device to /dev/st0. + - many updates for Linux Alpha (byte ordering, size_t etc). + - buffer overruns. + - use environment variable for TMPDIR (instead of /tmp). + - use sigjmp_buf instead of jmp_buf (RedHat bug #3260). + - workaround egcs bug (RedHat bugs #4281 and #2989). + - wire $(OPT) throughout Makefile's. + +2. Fix some compile warnings, prototype all functions. + +3. Use glibc err/glob instead of internal compatibility + routines (only if available). + Changes between versions 0.4b4 and 0.4b5 ======================================== diff --git a/MCONFIG.in b/MCONFIG.in index f3ab85f..7bb0410 100644 --- a/MCONFIG.in +++ b/MCONFIG.in @@ -27,7 +27,7 @@ MANDIR= /usr/man/man8 # # Global include directories # -GINC= -I/usr/include/bsd -I$(top_builddir) -I$(top_srcdir)/compat/include +GINC= -I$(top_builddir) -I$(top_srcdir)/compat/include # indicate where the ext2fs library can be found (this is not needed if you # have run `make install-libs' in the e2fsprogs source directory). #GINC+= -I/usr/src/e2fsprogs-0.5c/lib @@ -38,7 +38,7 @@ GINC= -I/usr/include/bsd -I$(top_builddir) -I$(top_srcdir)/compat/include # indicate where the ext2fs library can be found (this is not needed if you # have run `make install-libs' in the e2fsprogs source directory). #GLIBDIR= -L/usr/src/e2fsprogs-0.5c/lib -GLIBS= -lbsd $(GLIBDIR) -L../compat/lib -lcompat -lext2fs -lcom_err +GLIBS= $(GLIBDIR) -L../compat/lib -lcompat -lext2fs -lcom_err # # Definitions (don't change them unless you know what you are doing) diff --git a/THANKS b/THANKS index 4d5ed14..427f2cf 100644 --- a/THANKS +++ b/THANKS @@ -19,6 +19,7 @@ Thanks to people who reported problems with the port, sent patches, and suggested various improvements. Here is a partial list of them (if I have forgotten someone, please complain): +Bdale Garbee ndale@gag.com Henry Katz hkatz@hkatz.dialup.access.net Klaus Kudielka kkudielk@cacofonix.nt.tuwien.ac.at Florian La Roche florian@jurix.jura.uni-sb.de diff --git a/common/Makefile.in b/common/Makefile.in index d6a3348..9e4fd65 100644 --- a/common/Makefile.in +++ b/common/Makefile.in @@ -4,7 +4,7 @@ srcdir= @srcdir@ @MCONFIG@ INC= -I$(top_srcdir)/dump -CFLAGS= @CCOPTS@ -pipe $(GINC) $(INC) $(DEFS) +CFLAGS= @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) SRCS= dumprmt.c OBJS= dumprmt.o diff --git a/common/dumprmt.c b/common/dumprmt.c index da71748..b7cf041 100644 --- a/common/dumprmt.c +++ b/common/dumprmt.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)dumprmt.c 8.3 (Berkeley) 4/28/95"; #endif static const char rcsid[] = - "$Id: dumprmt.c,v 1.2 1999/10/11 12:53:20 stelian Exp $"; + "$Id: dumprmt.c,v 1.3 1999/10/11 12:59:16 stelian Exp $"; #endif /* not lint */ #ifdef __linux__ @@ -77,6 +77,8 @@ static const char rcsid[] = #include #include +#include +#include #include #include #include @@ -97,16 +99,16 @@ static const char rcsid[] = #define TS_OPEN 1 static int rmtstate = TS_CLOSED; -static int rmtape; -static char *rmtpeer; +static int rmtape = -1; +static const char *rmtpeer = 0; -static int okname __P((char *)); -static int rmtcall __P((char *, char *)); -static void rmtconnaborted __P((/* int, int */)); +static int okname __P((const char *)); +static int rmtcall __P((const char *, const char *)); +static void rmtconnaborted __P((int)); static int rmtgetb __P((void)); static void rmtgetconn __P((void)); -static void rmtgets __P((char *, int)); -static int rmtreply __P((char *)); +static void rmtgets __P((char *, size_t)); +static int rmtreply __P((const char *)); #ifdef KERBEROS int krcmd __P((char **, int /*u_short*/, char *, char *, int *, char *)); #endif @@ -114,16 +116,16 @@ int krcmd __P((char **, int /*u_short*/, char *, char *, int *, char *)); static int errfd = -1; extern int dokerberos; extern int ntrec; /* blocking factor on tape */ +#ifndef errno +extern int errno; +#endif int -rmthost(host) - char *host; +rmthost(const char *host) { - - rmtpeer = malloc(strlen(host) + 1); if (rmtpeer) - strcpy(rmtpeer, host); - else + free((void *)rmtpeer); + if ((rmtpeer = strdup(host)) == NULL) rmtpeer = host; signal(SIGPIPE, rmtconnaborted); rmtgetconn(); @@ -133,7 +135,7 @@ rmthost(host) } static void -rmtconnaborted() +rmtconnaborted(int signo) { msg("Lost connection to remote host.\n"); if (errfd != -1) { @@ -159,30 +161,26 @@ rmtconnaborted() exit(X_ABORT); } -void -rmtgetconn() +static void +rmtgetconn(void) { register char *cp; register const char *rmt; static struct servent *sp = NULL; static struct passwd *pwd = NULL; - char *tuser; + const char *tuser; int size; int throughput; int on; if (sp == NULL) { sp = getservbyname(dokerberos ? "kshell" : "shell", "tcp"); - if (sp == NULL) { - msg("%s/tcp: unknown service\n", + if (sp == NULL) + errx(1, "%s/tcp: unknown service", dokerberos ? "kshell" : "shell"); - exit(X_STARTUP); - } pwd = getpwuid(getuid()); - if (pwd == NULL) { - msg("who are you?\n"); - exit(X_STARTUP); - } + if (pwd == NULL) + errx(1, "who are you?"); } if ((cp = strchr(rmtpeer, '@')) != NULL) { tuser = rmtpeer; @@ -197,11 +195,11 @@ rmtgetconn() msg(""); #ifdef KERBEROS if (dokerberos) - rmtape = krcmd(&rmtpeer, sp->s_port, tuser, rmt, &errfd, + rmtape = krcmd((char **)&rmtpeer, sp->s_port, tuser, rmt, &errfd, (char *)0); else #endif - rmtape = rcmd(&rmtpeer, (u_short)sp->s_port, pwd->pw_name, + rmtape = rcmd((char **)&rmtpeer, (u_short)sp->s_port, pwd->pw_name, tuser, rmt, &errfd); if (rmtape < 0) { msg("login to %s as %s failed.\n", rmtpeer, tuser); @@ -227,16 +225,15 @@ rmtgetconn() } static int -okname(cp0) - char *cp0; +okname(const char *cp0) { - register char *cp; + register const char *cp; register int c; for (cp = cp0; *cp; cp++) { c = *cp; if (!isascii(c) || !(isalnum(c) || c == '_' || c == '-')) { - msg("invalid user name %s\n", cp0); + warnx("invalid user name %s\n", cp0); return (0); } } @@ -244,19 +241,17 @@ okname(cp0) } int -rmtopen(tape, mode) - char *tape; - int mode; +rmtopen(const char *tape, int mode) { - char buf[256]; + char buf[MAXPATHLEN]; - (void)snprintf(buf, sizeof (buf), "O%.226s\n%d\n", tape, mode); + (void)snprintf(buf, sizeof (buf), "O%s\n%d\n", tape, mode); rmtstate = TS_OPEN; return (rmtcall(tape, buf)); } void -rmtclose() +rmtclose(void) { if (rmtstate != TS_OPEN) @@ -266,14 +261,13 @@ rmtclose() } int -rmtread(buf, count) - char *buf; - int count; +rmtread(char *buf, size_t count) { char line[30]; - int n, i, cc; + int n, i; + ssize_t cc; - (void)snprintf(line, sizeof (line), "R%d\n", count); + (void)snprintf(line, sizeof (line), "R%u\n", (unsigned)count); n = rmtcall("read", line); if (n < 0) /* rmtcall() properly sets errno for us on errors. */ @@ -281,15 +275,13 @@ rmtread(buf, count) for (i = 0; i < n; i += cc) { cc = read(rmtape, buf+i, n - i); if (cc <= 0) - rmtconnaborted(); + rmtconnaborted(0); } return (n); } int -rmtwrite(buf, count) - char *buf; - int count; +rmtwrite(const char *buf, size_t count) { char line[30]; @@ -299,35 +291,8 @@ rmtwrite(buf, count) return (rmtreply("write")); } -void -rmtwrite0(count) - int count; -{ - char line[30]; - - (void)snprintf(line, sizeof (line), "W%d\n", count); - write(rmtape, line, strlen(line)); -} - -void -rmtwrite1(buf, count) - char *buf; - int count; -{ - - write(rmtape, buf, count); -} - int -rmtwrite2() -{ - - return (rmtreply("write")); -} - -int -rmtseek(offset, pos) - int offset, pos; +rmtseek(int offset, int pos) { char line[80]; @@ -338,7 +303,7 @@ rmtseek(offset, pos) struct mtget mts; struct mtget * -rmtstatus() +rmtstatus(void) { register int i; register char *cp; @@ -352,8 +317,7 @@ rmtstatus() } int -rmtioctl(cmd, count) - int cmd, count; +rmtioctl(int cmd, int count) { char buf[256]; @@ -364,22 +328,19 @@ rmtioctl(cmd, count) } static int -rmtcall(cmd, buf) - char *cmd, *buf; +rmtcall(const char *cmd, const char *buf) { if (write(rmtape, buf, strlen(buf)) != strlen(buf)) - rmtconnaborted(); + rmtconnaborted(0); return (rmtreply(cmd)); } static int -rmtreply(cmd) - char *cmd; +rmtreply(const char *cmd) { register char *cp; char code[30], emsg[BUFSIZ]; - extern int errno; rmtgets(code, sizeof (code)); if (*code == 'E' || *code == 'F') { @@ -398,26 +359,24 @@ rmtreply(cmd) msg("Protocol to remote tape server botched (code \"%s\").\n", code); - rmtconnaborted(); + rmtconnaborted(0); } return (atoi(code + 1)); } -int -rmtgetb() +static int +rmtgetb(void) { char c; if (read(rmtape, &c, 1) != 1) - rmtconnaborted(); + rmtconnaborted(0); return (c); } /* Get a line (guaranteed to have a trailing newline). */ -void -rmtgets(line, len) - char *line; - int len; +static void +rmtgets(char *line, size_t len) { register char *cp = line; @@ -433,5 +392,5 @@ rmtgets(line, len) *cp = '\0'; msg("Protocol to remote tape server botched.\n"); msg("(rmtgets got \"%s\").\n", line); - rmtconnaborted(); + rmtconnaborted(0); } diff --git a/compat/include/bsdcompat.h b/compat/include/bsdcompat.h index a29421e..421e4cf 100644 --- a/compat/include/bsdcompat.h +++ b/compat/include/bsdcompat.h @@ -205,6 +205,11 @@ struct old_bsd_inode { __u32 di_spare[4]; }; +struct bsdtimeval { /* XXX alpha-*-linux is deviant */ + __u32 tv_sec; + __u32 tv_usec; +}; + /* * This is the new (4.4) BSD inode structure * copied from the FreeBSD 2.0 include file @@ -217,9 +222,9 @@ struct new_bsd_inode { __u32 inumber; } di_u; u_quad_t di_size; - struct timeval di_atime; - struct timeval di_mtime; - struct timeval di_ctime; + struct bsdtimeval di_atime; + struct bsdtimeval di_mtime; + struct bsdtimeval di_ctime; daddr_t di_db[NDADDR]; daddr_t di_ib[NIADDR]; __u32 di_flags; diff --git a/compat/include/compaterr.h b/compat/include/compaterr.h new file mode 100644 index 0000000..a45bb98 --- /dev/null +++ b/compat/include/compaterr.h @@ -0,0 +1,93 @@ +/* + * Ported to Linux's Second Extended File System as part of the + * dump and restore backup suit + * Remy Card , 1994-1997 + * Stelian Pop , 1999 + * + */ + +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)err.h 8.1 (Berkeley) 6/2/93 + * $Id: compaterr.h,v 1.1 1999/10/11 12:59:17 stelian Exp $ + */ + +#ifndef _ERR_H_ +#define _ERR_H_ + +#include + +#if defined(HAVE_ERR) || defined(HAVE_ERRX) || defined(HAVE_VERR) || defined(HAVE_VERRX) || defined(HAVE_VWARN) || defined(HAVE_VWARNX) || defined(HAVE_WARN) || defined(HAVE_WARNX) +#include +#endif + +#include + +#include + +#ifndef _BSD_VA_LIST_ +#define _BSD_VA_LIST_ va_list +#endif + +#ifndef __dead +#define __dead volatile +#endif + +__BEGIN_DECLS +#ifndef HAVE_ERR +__dead void err __P((int, const char *, ...)); +#endif +#ifndef HAVE_VERR +__dead void verr __P((int, const char *, _BSD_VA_LIST_)); +#endif +#ifndef HAVE_ERRX +__dead void errx __P((int, const char *, ...)); +#endif +#ifndef HAVE_VERRX +__dead void verrx __P((int, const char *, _BSD_VA_LIST_)); +#endif +#ifndef HAVE_WARN +void warn __P((const char *, ...)); +#endif +#ifndef HAVE_VWARN +void vwarn __P((const char *, _BSD_VA_LIST_)); +#endif +#ifndef HAVE_WARNX +void warnx __P((const char *, ...)); +#endif +#ifndef HAVE_VWARNX +void vwarnx __P((const char *, _BSD_VA_LIST_)); +#endif +__END_DECLS + +#endif /* !_ERR_H_ */ diff --git a/compat/include/compatglob.h b/compat/include/compatglob.h new file mode 100644 index 0000000..5557880 --- /dev/null +++ b/compat/include/compatglob.h @@ -0,0 +1,104 @@ +/* + * Ported to Linux's Second Extended File System as part of the + * dump and restore backup suit + * Remy Card , 1994-1997 + * Stelian Pop , 1999 + * + */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)glob.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _GLOB_H_ +#define _GLOB_H_ + +#include + +#ifdef HAVE_GLOB +#include +#else + +#include + +struct stat; +typedef struct { + int gl_pathc; /* Count of total paths so far. */ + int gl_matchc; /* Count of paths matching pattern. */ + int gl_offs; /* Reserved at beginning of gl_pathv. */ + int gl_flags; /* Copy of flags parameter to glob. */ + char **gl_pathv; /* List of paths matching pattern. */ + /* Copy of errfunc parameter to glob. */ + int (*gl_errfunc) __P((const char *, int)); + + /* + * Alternate filesystem access methods for glob; replacement + * versions of closedir(3), readdir(3), opendir(3), stat(2) + * and lstat(2). + */ + void (*gl_closedir) __P((void *)); + struct dirent *(*gl_readdir) __P((void *)); + void *(*gl_opendir) __P((const char *)); + int (*gl_lstat) __P((const char *, struct stat *)); + int (*gl_stat) __P((const char *, struct stat *)); +} glob_t; + +#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ +#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ +#define GLOB_ERR 0x0004 /* Return on error. */ +#define GLOB_MARK 0x0008 /* Append / to matching directories. */ +#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ +#define GLOB_NOSORT 0x0020 /* Don't sort. */ + +#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ +#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ +#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ +#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ +#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ +#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ + +#define GLOB_NOSPACE (-1) /* Malloc call failed. */ +#define GLOB_ABEND (-2) /* Unignored error. */ + +__BEGIN_DECLS +int glob __P((const char *, int, int (*)(const char *, int), glob_t *)); +void globfree __P((glob_t *)); +__END_DECLS + +#endif /* !_GLOB_H_ */ + +#endif /* HAVE_GLOB */ diff --git a/compat/include/err.h b/compat/include/err.h deleted file mode 100644 index 8e168d5..0000000 --- a/compat/include/err.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Ported to Linux's Second Extended File System as part of the - * dump and restore backup suit - * Remy Card , 1994-1997 - * Stelian Pop , 1999 - * - */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)err.h 8.1 (Berkeley) 6/2/93 - * $Id: err.h,v 1.2 1999/10/11 12:53:20 stelian Exp $ - */ - -#ifndef _ERR_H_ -#define _ERR_H_ - -#include - -#include - -#ifndef _BSD_VA_LIST_ -#define _BSD_VA_LIST_ va_list -#endif - -#ifndef __dead -#define __dead volatile -#endif - -__BEGIN_DECLS -__dead void err __P((int, const char *, ...)); -__dead void verr __P((int, const char *, _BSD_VA_LIST_)); -__dead void errc __P((int, int, const char *, ...)); -__dead void verrc __P((int, int, const char *, _BSD_VA_LIST_)); -__dead void errx __P((int, const char *, ...)); -__dead void verrx __P((int, const char *, _BSD_VA_LIST_)); -void warn __P((const char *, ...)); -void vwarn __P((const char *, _BSD_VA_LIST_)); -void warnc __P((int, const char *, ...)); -void vwarnc __P((int, const char *, _BSD_VA_LIST_)); -void warnx __P((const char *, ...)); -void vwarnx __P((const char *, _BSD_VA_LIST_)); -void err_set_file __P((void *)); -void err_set_exit __P((void (*)(int))); -__END_DECLS - -#endif /* !_ERR_H_ */ diff --git a/compat/include/glob.h b/compat/include/glob.h deleted file mode 100644 index d32114e..0000000 --- a/compat/include/glob.h +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Ported to Linux's Second Extended File System as part of the - * dump and restore backup suit - * Remy Card , 1994-1997 - * Stelian Pop , 1999 - * - */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)glob.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _GLOB_H_ -#define _GLOB_H_ - -#include - -struct stat; -typedef struct { - int gl_pathc; /* Count of total paths so far. */ - int gl_matchc; /* Count of paths matching pattern. */ - int gl_offs; /* Reserved at beginning of gl_pathv. */ - int gl_flags; /* Copy of flags parameter to glob. */ - char **gl_pathv; /* List of paths matching pattern. */ - /* Copy of errfunc parameter to glob. */ - int (*gl_errfunc) __P((const char *, int)); - - /* - * Alternate filesystem access methods for glob; replacement - * versions of closedir(3), readdir(3), opendir(3), stat(2) - * and lstat(2). - */ - void (*gl_closedir) __P((void *)); - struct dirent *(*gl_readdir) __P((void *)); - void *(*gl_opendir) __P((const char *)); - int (*gl_lstat) __P((const char *, struct stat *)); - int (*gl_stat) __P((const char *, struct stat *)); -} glob_t; - -#define GLOB_APPEND 0x0001 /* Append to output from previous call. */ -#define GLOB_DOOFFS 0x0002 /* Use gl_offs. */ -#define GLOB_ERR 0x0004 /* Return on error. */ -#define GLOB_MARK 0x0008 /* Append / to matching directories. */ -#define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ -#define GLOB_NOSORT 0x0020 /* Don't sort. */ - -#define GLOB_ALTDIRFUNC 0x0040 /* Use alternately specified directory funcs. */ -#define GLOB_BRACE 0x0080 /* Expand braces ala csh. */ -#define GLOB_MAGCHAR 0x0100 /* Pattern had globbing characters. */ -#define GLOB_NOMAGIC 0x0200 /* GLOB_NOCHECK without magic chars (csh). */ -#define GLOB_QUOTE 0x0400 /* Quote special chars with \. */ -#define GLOB_TILDE 0x0800 /* Expand tilde names from the passwd file. */ - -#define GLOB_NOSPACE (-1) /* Malloc call failed. */ -#define GLOB_ABEND (-2) /* Unignored error. */ - -__BEGIN_DECLS -int glob __P((const char *, int, int (*)(const char *, int), glob_t *)); -void globfree __P((glob_t *)); -__END_DECLS - -#endif /* !_GLOB_H_ */ diff --git a/compat/include/pathnames.h b/compat/include/pathnames.h index 0bcf788..3e4194a 100644 --- a/compat/include/pathnames.h +++ b/compat/include/pathnames.h @@ -43,7 +43,7 @@ #include -#define _PATH_DEFTAPE "/dev/rmt8" +#define _PATH_DEFTAPE "/dev/st0" #define _PATH_DTMP "/etc/dtmp" #define _PATH_DUMPDATES "/etc/dumpdates" #define _PATH_LOCK "/tmp/dumplockXXXXXX" diff --git a/compat/lib/Makefile.in b/compat/lib/Makefile.in index c5ba683..8703e4a 100644 --- a/compat/lib/Makefile.in +++ b/compat/lib/Makefile.in @@ -4,9 +4,9 @@ srcdir= @srcdir@ @MCONFIG@ INC= -I$(top_srcdir)/compat/include -CFLAGS= @CCOPTS@ -pipe $(GINC) $(INC) $(DEFS) -SRCS= err.c fstab.c glob.c -OBJS= err.o fstab.o glob.o +CFLAGS= @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) +SRCS= compaterr.c fstab.c compatglob.c +OBJS= compaterr.o fstab.o compatglob.o LIB= libcompat.a all:: $(LIB) diff --git a/compat/lib/compaterr.c b/compat/lib/compaterr.c new file mode 100644 index 0000000..a77f1ba --- /dev/null +++ b/compat/lib/compaterr.c @@ -0,0 +1,229 @@ +/* + * Ported to Linux's Second Extended File System as part of the + * dump and restore backup suit + * Remy Card , 1994-1997 + * Stelian Pop , 1999 + * + */ + +/*- + * Copyright (c) 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * From: @(#)err.c 8.1 (Berkeley) 6/4/93 + */ + +#if defined(LIBC_RCS) && !defined(lint) +static const char rcsid[] = + "$Id: compaterr.c,v 1.1 1999/10/11 12:59:17 stelian Exp $"; +#endif /* LIBC_RCS and not lint */ + +#include +#include +#include +#include +#include + +#include + +#include + +extern char *__progname; /* Program name, from crt0. */ + +#if !defined(HAVE_ERR) || !defined(HAVE_ERRX) || !defined(HAVE_VERR) || !defined(HAVE_VERRX) || !defined(HAVE_VWARN) || !defined(HAVE_VWARNX) || !defined(HAVE_WARN) || !defined(HAVE_WARNX) + +__BEGIN_DECLS +__dead void errc __P((int, int, const char *, ...)); +__dead void verrc __P((int, int, const char *, _BSD_VA_LIST_)); +void warnc __P((int, const char *, ...)); +void vwarnc __P((int, const char *, _BSD_VA_LIST_)); +void err_set_file __P((void *)); +void err_set_exit __P((void (*)(int))); +__END_DECLS + +static void (*err_exit)(int); + +static FILE *err_file; /* file to use for error output */ +/* + * This is declared to take a `void *' so that the caller is not required + * to include first. However, it is really a `FILE *', and the + * manual page documents it as such. + */ +void +err_set_file(void *fp) +{ + if (fp) + err_file = fp; + else + err_file = stderr; +} + +void +err_set_exit(void (*ef)(int)) +{ + err_exit = ef; +} + +__dead void +errc(int eval, int code, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrc(eval, code, fmt, ap); + va_end(ap); +} + +__dead void +verrc(int eval, int code, const char *fmt, va_list ap) +{ + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", __progname); + if (fmt != NULL) { + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); + } + fprintf(err_file, "%s\n", strerror(code)); + if (err_exit) + err_exit(eval); + exit(eval); +} + +void +warnc(int code, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnc(code, fmt, ap); + va_end(ap); +} + +void +vwarnc(int code, const char *fmt, va_list ap) +{ + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", __progname); + if (fmt != NULL) { + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); + } + fprintf(err_file, "%s\n", strerror(code)); +} +#endif + +#ifndef HAVE_ERR +__dead void +err(int eval, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrc(eval, errno, fmt, ap); + va_end(ap); +} +#endif + +#ifndef HAVE_VERR +__dead void +verr(int eval, const char *fmt, va_list ap) +{ + verrc(eval, errno, fmt, ap); +} +#endif + +#ifndef HAVE_ERRX +__dead void +errx(int eval, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + verrx(eval, fmt, ap); + va_end(ap); +} +#endif + +#ifndef HAVE_VERRX +__dead void +verrx(int eval, const char *fmt, va_list ap) +{ + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", __progname); + if (fmt != NULL) + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); + if (err_exit) + err_exit(eval); + exit(eval); +} +#endif + +#ifndef HAVE_WARN +void +warn(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnc(errno, fmt, ap); + va_end(ap); +} +#endif + +#ifndef HAVE_VWARN +void +vwarn(const char *fmt, va_list ap) +{ + vwarnc(errno, fmt, ap); +} +#endif + +#ifndef HAVE_WARNX +void +warnx(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vwarnx(fmt, ap); + va_end(ap); +} +#endif + +#ifndef HAVE_VWARNX +void +vwarnx(const char *fmt, va_list ap) +{ + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", __progname); + if (fmt != NULL) + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); +} +#endif diff --git a/compat/lib/compatglob.c b/compat/lib/compatglob.c new file mode 100644 index 0000000..cdbab02 --- /dev/null +++ b/compat/lib/compatglob.c @@ -0,0 +1,833 @@ +/* + * Ported to Linux's Second Extended File System as part of the + * dump and restore backup suit + * Remy Card , 1994-1997 + * Stelian Pop , 1999 + * + */ + +/* + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; +#endif /* LIBC_SCCS and not lint */ + +/* + * glob(3) -- a superset of the one defined in POSIX 1003.2. + * + * The [!...] convention to negate a range is supported (SysV, Posix, ksh). + * + * Optional extra services, controlled by flags not defined by POSIX: + * + * GLOB_QUOTE: + * Escaping convention: \ inhibits any special meaning the following + * character might have (except \ at end of string is retained). + * GLOB_MAGCHAR: + * Set in gl_flags if pattern contained a globbing character. + * GLOB_NOMAGIC: + * Same as GLOB_NOCHECK, but it will only append pattern if it did + * not contain any magic characters. [Used in csh style globbing] + * GLOB_ALTDIRFUNC: + * Use alternately specified directory access functions. + * GLOB_TILDE: + * expand ~user/foo to the /home/dir/of/user/foo + * GLOB_BRACE: + * expand {1,2}{a,b} to 1a 1b 2a 2b + * gl_matchc: + * Number of matches in the current invocation of glob. + */ + +#include + +#ifndef HAVE_GLOB + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DOLLAR '$' +#define DOT '.' +#define EOS '\0' +#define LBRACKET '[' +#define NOT '!' +#define QUESTION '?' +#define QUOTE '\\' +#define RANGE '-' +#define RBRACKET ']' +#define SEP '/' +#define STAR '*' +#define TILDE '~' +#define UNDERSCORE '_' +#define LBRACE '{' +#define RBRACE '}' +#define SLASH '/' +#define COMMA ',' + +#ifndef DEBUG + +#define M_QUOTE 0x8000 +#define M_PROTECT 0x4000 +#define M_MASK 0xffff +#define M_ASCII 0x00ff + +typedef u_short Char; + +#else + +#define M_QUOTE 0x80 +#define M_PROTECT 0x40 +#define M_MASK 0xff +#define M_ASCII 0x7f + +typedef char Char; + +#endif + + +#define CHAR(c) ((Char)((c)&M_ASCII)) +#define META(c) ((Char)((c)|M_QUOTE)) +#define M_ALL META('*') +#define M_END META(']') +#define M_NOT META('!') +#define M_ONE META('?') +#define M_RNG META('-') +#define M_SET META('[') +#define ismeta(c) (((c)&M_QUOTE) != 0) + + +static int compare __P((const void *, const void *)); +static void g_Ctoc __P((const Char *, char *)); +static int g_lstat __P((Char *, struct stat *, glob_t *)); +static DIR *g_opendir __P((Char *, glob_t *)); +static Char *g_strchr __P((Char *, int)); +#ifdef notdef +static Char *g_strcat __P((Char *, const Char *)); +#endif +static int g_stat __P((Char *, struct stat *, glob_t *)); +static int glob0 __P((const Char *, glob_t *)); +static int glob1 __P((Char *, glob_t *)); +static int glob2 __P((Char *, Char *, Char *, glob_t *)); +static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *)); +static int globextend __P((const Char *, glob_t *)); +static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *)); +static int globexp1 __P((const Char *, glob_t *)); +static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); +static int match __P((Char *, Char *, Char *)); +#ifdef DEBUG +static void qprintf __P((const char *, Char *)); +#endif + +int +glob(const char *pattern, int flags, int (*errfunc) __P((const char *, int)), glob_t *pglob) +{ + const u_char *patnext; + int c; + Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; + + patnext = (u_char *) pattern; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_offs = 0; + } + pglob->gl_flags = flags & ~GLOB_MAGCHAR; + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + + bufnext = patbuf; + bufend = bufnext + MAXPATHLEN; + if (flags & GLOB_QUOTE) { + /* Protect the quoted characters. */ + while (bufnext < bufend && (c = *patnext++) != EOS) + if (c == QUOTE) { + if ((c = *patnext++) == EOS) { + c = QUOTE; + --patnext; + } + *bufnext++ = c | M_PROTECT; + } + else + *bufnext++ = c; + } + else + while (bufnext < bufend && (c = *patnext++) != EOS) + *bufnext++ = c; + *bufnext = EOS; + + if (flags & GLOB_BRACE) + return globexp1(patbuf, pglob); + else + return glob0(patbuf, pglob); +} + +/* + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic + * characters + */ +static int globexp1(const Char *pattern, glob_t *pglob) +{ + const Char* ptr = pattern; + int rv; + + /* Protect a single {}, for find(1), like csh */ + if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) + return glob0(pattern, pglob); + + while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) + if (!globexp2(ptr, pattern, pglob, &rv)) + return rv; + + return glob0(pattern, pglob); +} + + +/* + * Recursive brace globbing helper. Tries to expand a single brace. + * If it succeeds then it invokes globexp1 with the new pattern. + * If it fails then it tries to glob the rest of the pattern and returns. + */ +static int globexp2(const Char *ptr, const Char *pattern, glob_t *pglob, int *rv) +{ + int i; + Char *lm, *ls; + const Char *pe, *pm, *pl; + Char patbuf[MAXPATHLEN + 1]; + + /* copy part up to the brace */ + for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) + continue; + ls = lm; + + /* Find the balanced brace */ + for (i = 0, pe = ++ptr; *pe; pe++) + if (*pe == LBRACKET) { + /* Ignore everything between [] */ + for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) + continue; + if (*pe == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pe = pm; + } + } + else if (*pe == LBRACE) + i++; + else if (*pe == RBRACE) { + if (i == 0) + break; + i--; + } + + /* Non matching braces; just glob the pattern */ + if (i != 0 || *pe == EOS) { + *rv = glob0(patbuf, pglob); + return 0; + } + + for (i = 0, pl = pm = ptr; pm <= pe; pm++) + switch (*pm) { + case LBRACKET: + /* Ignore everything between [] */ + for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) + continue; + if (*pm == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pm = pl; + } + break; + + case LBRACE: + i++; + break; + + case RBRACE: + if (i) { + i--; + break; + } + /* FALLTHROUGH */ + case COMMA: + if (i && *pm == COMMA) + break; + else { + /* Append the current string */ + for (lm = ls; (pl < pm); *lm++ = *pl++) + continue; + /* + * Append the rest of the pattern after the + * closing brace + */ + for (pl = pe + 1; (*lm++ = *pl++) != EOS;) + continue; + + /* Expand the current pattern */ +#ifdef DEBUG + qprintf("globexp2:", patbuf); +#endif + *rv = globexp1(patbuf, pglob); + + /* move after the comma, to the next string */ + pl = pm + 1; + } + break; + + default: + break; + } + *rv = 0; + return 0; +} + + + +/* + * expand tilde from the passwd file. + */ +static const Char * +globtilde(const Char *pattern, Char *patbuf, size_t patbuf_len, glob_t *pglob) +{ + struct passwd *pwd; + char *h; + const Char *p; + Char *b, *eb; + + if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) + return pattern; + + /* + * Copy up to the end of the string or / + */ + eb = &patbuf[patbuf_len - 1]; + for (p = pattern + 1, h = (char *) patbuf; + h < (char *)eb && *p && *p != SLASH; *h++ = *p++) + continue; + + *h = EOS; + + if (((char *) patbuf)[0] == EOS) { + /* + * handle a plain ~ or ~/ by expanding $HOME first if + * we're not running setuid or setgid) and then trying + * the password file + */ + if ( +#ifndef __linux__ +#ifndef __NETBSD_SYSCALLS + issetugid() != 0 || +#endif +#endif + (h = getenv("HOME")) == NULL) { + if (((h = getlogin()) != NULL && + (pwd = getpwnam(h)) != NULL) || + (pwd = getpwuid(getuid())) != NULL) + h = pwd->pw_dir; + else + return pattern; + } + } + else { + /* + * Expand a ~user + */ + if ((pwd = getpwnam((char*) patbuf)) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + + /* Copy the home directory */ + for (b = patbuf; b < eb && *h; *b++ = *h++) + continue; + + /* Append the rest of the pattern */ + while (b < eb && (*b++ = *p++) != EOS) + continue; + *b = EOS; + + return patbuf; +} + + +/* + * The main glob() routine: compiles the pattern (optionally processing + * quotes), calls glob1() to do the real pattern matching, and finally + * sorts the list (unless unsorted operation is requested). Returns 0 + * if things went well, nonzero if errors occurred. It is not an error + * to find no matches. + */ +static int +glob0(const Char *pattern, glob_t *pglob) +{ + const Char *qpatnext; + int c, err, oldpathc; + Char *bufnext, patbuf[MAXPATHLEN+1]; + + qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char), + pglob); + oldpathc = pglob->gl_pathc; + bufnext = patbuf; + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { + switch (c) { + case LBRACKET: + c = *qpatnext; + if (c == NOT) + ++qpatnext; + if (*qpatnext == EOS || + g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + *bufnext++ = LBRACKET; + if (c == NOT) + --qpatnext; + break; + } + *bufnext++ = M_SET; + if (c == NOT) + *bufnext++ = M_NOT; + c = *qpatnext++; + do { + *bufnext++ = CHAR(c); + if (*qpatnext == RANGE && + (c = qpatnext[1]) != RBRACKET) { + *bufnext++ = M_RNG; + *bufnext++ = CHAR(c); + qpatnext += 2; + } + } while ((c = *qpatnext++) != RBRACKET); + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_END; + break; + case QUESTION: + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_ONE; + break; + case STAR: + pglob->gl_flags |= GLOB_MAGCHAR; + /* collapse adjacent stars to one, + * to avoid exponential behavior + */ + if (bufnext == patbuf || bufnext[-1] != M_ALL) + *bufnext++ = M_ALL; + break; + default: + *bufnext++ = CHAR(c); + break; + } + } + *bufnext = EOS; +#ifdef DEBUG + qprintf("glob0:", patbuf); +#endif + + if ((err = glob1(patbuf, pglob)) != 0) + return(err); + + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified + * and the pattern did not contain any magic characters + * GLOB_NOMAGIC is there just for compatibility with csh. + */ + if (pglob->gl_pathc == oldpathc && + ((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR)))) + return(globextend(pattern, pglob)); + else if (!(pglob->gl_flags & GLOB_NOSORT)) + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), compare); + return(0); +} + +static int +compare(const void *p, const void *q) +{ + return(strcmp(*(char **)p, *(char **)q)); +} + +static int +glob1(Char *pattern, glob_t *pglob) +{ + Char pathbuf[MAXPATHLEN+1]; + + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ + if (*pattern == EOS) + return(0); + return(glob2(pathbuf, pathbuf, pattern, pglob)); +} + +/* + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more + * meta characters. + */ +static int +glob2(Char *pathbuf, Char *pathend, Char *pattern, glob_t *pglob) +{ + struct stat sb; + Char *p, *q; + int anymeta; + + /* + * Loop over pattern segments until end of pattern or until + * segment with meta character found. + */ + for (anymeta = 0;;) { + if (*pattern == EOS) { /* End of pattern? */ + *pathend = EOS; + if (g_lstat(pathbuf, &sb, pglob)) + return(0); + + if (((pglob->gl_flags & GLOB_MARK) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) + || (S_ISLNK(sb.st_mode) && + (g_stat(pathbuf, &sb, pglob) == 0) && + S_ISDIR(sb.st_mode)))) { + *pathend++ = SEP; + *pathend = EOS; + } + ++pglob->gl_matchc; + return(globextend(pathbuf, pglob)); + } + + /* Find end of next segment, copy tentatively to pathend. */ + q = pathend; + p = pattern; + while (*p != EOS && *p != SEP) { + if (ismeta(*p)) + anymeta = 1; + *q++ = *p++; + } + + if (!anymeta) { /* No expansion, do next segment. */ + pathend = q; + pattern = p; + while (*pattern == SEP) + *pathend++ = *pattern++; + } else /* Need expansion, recurse. */ + return(glob3(pathbuf, pathend, pattern, p, pglob)); + } + /* NOTREACHED */ +} + +static int +glob3(Char *pathbuf, Char *pathend, Char *pattern, Char *restpattern, glob_t *pglob) +{ + register struct dirent *dp; + DIR *dirp; + int err; + char buf[MAXPATHLEN]; + + /* + * The readdirfunc declaration can't be prototyped, because it is + * assigned, below, to two functions which are prototyped in glob.h + * and dirent.h as taking pointers to differently typed opaque + * structures. + */ + struct dirent *(*readdirfunc)(); + + *pathend = EOS; + errno = 0; + + if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { + /* TODO: don't call for ENOENT or ENOTDIR? */ + if (pglob->gl_errfunc) { + g_Ctoc(pathbuf, buf); + if (pglob->gl_errfunc(buf, errno) || + pglob->gl_flags & GLOB_ERR) + return (GLOB_ABEND); + } + return(0); + } + + err = 0; + + /* Search directory for matching names. */ + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + readdirfunc = pglob->gl_readdir; + else + readdirfunc = readdir; + while ((dp = (*readdirfunc)(dirp))) { + register u_char *sc; + register Char *dc; + + /* Initial DOT must be matched literally. */ + if (dp->d_name[0] == DOT && *pattern != DOT) + continue; + for (sc = (u_char *) dp->d_name, dc = pathend; + (*dc++ = *sc++) != EOS;) + continue; + if (!match(pathend, pattern, restpattern)) { + *pathend = EOS; + continue; + } + err = glob2(pathbuf, --dc, restpattern, pglob); + if (err) + break; + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir)(dirp); + else + closedir(dirp); + return(err); +} + + +/* + * Extend the gl_pathv member of a glob_t structure to accomodate a new item, + * add the new item, and update gl_pathc. + * + * This assumes the BSD realloc, which only copies the block when its size + * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic + * behavior. + * + * Return 0 if new item added, error code if memory couldn't be allocated. + * + * Invariant of the glob_t structure: + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and + * gl_pathv points to (gl_offs + gl_pathc + 1) items. + */ +static int +globextend(const Char *path, glob_t *pglob) +{ + register char **pathv; + register int i; + u_int newsize; + char *copy; + const Char *p; + + newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); + pathv = pglob->gl_pathv ? + realloc((char *)pglob->gl_pathv, newsize) : + malloc(newsize); + if (pathv == NULL) + return(GLOB_NOSPACE); + + if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + pathv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--pathv = NULL; + } + pglob->gl_pathv = pathv; + + for (p = path; *p++;) + continue; + if ((copy = malloc(p - path)) != NULL) { + g_Ctoc(path, copy); + pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; + } + pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + return(copy == NULL ? GLOB_NOSPACE : 0); +} + +/* + * pattern matching function for filenames. Each occurrence of the * + * pattern causes a recursion level. + */ +static int +match(Char *name, Char *pat, Char *patend) +{ + int ok, negate_range; + Char c, k; + + while (pat < patend) { + c = *pat++; + switch (c & M_MASK) { + case M_ALL: + if (pat == patend) + return(1); + do + if (match(name, pat, patend)) + return(1); + while (*name++ != EOS); + return(0); + case M_ONE: + if (*name++ == EOS) + return(0); + break; + case M_SET: + ok = 0; + if ((k = *name++) == EOS) + return(0); + if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) + ++pat; + while (((c = *pat++) & M_MASK) != M_END) + if ((*pat & M_MASK) == M_RNG) { + if (c <= k && k <= pat[1]) + ok = 1; + pat += 2; + } else if (c == k) + ok = 1; + if (ok == negate_range) + return(0); + break; + default: + if (*name++ != c) + return(0); + break; + } + } + return(*name == EOS); +} + +/* Free allocated data belonging to a glob_t structure. */ +void +globfree(glob_t *pglob) +{ + register int i; + register char **pp; + + if (pglob->gl_pathv != NULL) { + pp = pglob->gl_pathv + pglob->gl_offs; + for (i = pglob->gl_pathc; i--; ++pp) + if (*pp) + free(*pp); + free(pglob->gl_pathv); + } +} + +static DIR * +g_opendir(Char *str, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + if (!*str) + strcpy(buf, "."); + else + g_Ctoc(str, buf); + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_opendir)(buf)); + + return(opendir(buf)); +} + +static int +g_lstat(Char *fn, struct stat *sb, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + g_Ctoc(fn, buf); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_lstat)(buf, sb)); + return(lstat(buf, sb)); +} + +static int +g_stat(Char *fn, struct stat *sb, glob_t *pglob) +{ + char buf[MAXPATHLEN]; + + g_Ctoc(fn, buf); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_stat)(buf, sb)); + return(stat(buf, sb)); +} + +static Char * +g_strchr(Char *str, int ch) +{ + do { + if (*str == ch) + return (str); + } while (*str++); + return (NULL); +} + +#ifdef notdef +static Char * +g_strcat(Char *dst, const Char *src) +{ + Char *sdst = dst; + + while (*dst++) + continue; + --dst; + while((*dst++ = *src++) != EOS) + continue; + + return (sdst); +} +#endif + +static void +g_Ctoc(const Char *str, char *buf) +{ + register char *dc; + + for (dc = buf; (*dc++ = *str++) != EOS;) + continue; +} + +#ifdef DEBUG +static void +qprintf(const char *str, Char *s) +{ + register Char *p; + + (void)printf("%s:\n", str); + for (p = s; *p; p++) + (void)printf("%c", CHAR(*p)); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", *p & M_PROTECT ? '"' : ' '); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", ismeta(*p) ? '_' : ' '); + (void)printf("\n"); +} +#endif + +#endif /* ! HAVE_GLOB */ diff --git a/compat/lib/err.c b/compat/lib/err.c deleted file mode 100644 index 13fefaf..0000000 --- a/compat/lib/err.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Ported to Linux's Second Extended File System as part of the - * dump and restore backup suit - * Remy Card , 1994-1997 - * Stelian Pop , 1999 - * - */ - -/*- - * Copyright (c) 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * From: @(#)err.c 8.1 (Berkeley) 6/4/93 - */ - -#if defined(LIBC_RCS) && !defined(lint) -static const char rcsid[] = - "$Id: err.c,v 1.2 1999/10/11 12:53:21 stelian Exp $"; -#endif /* LIBC_RCS and not lint */ - -#include -#include -#include -#include -#include - -#include - -#include - -extern char *__progname; /* Program name, from crt0. */ - -static FILE *err_file; /* file to use for error output */ -static void (*err_exit)(int); - -/* - * This is declared to take a `void *' so that the caller is not required - * to include first. However, it is really a `FILE *', and the - * manual page documents it as such. - */ -void -err_set_file(void *fp) -{ - if (fp) - err_file = fp; - else - err_file = stderr; -} - -void -err_set_exit(void (*ef)(int)) -{ - err_exit = ef; -} - - -#ifndef HAVE_ERR -__dead void -err(int eval, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - verrc(eval, errno, fmt, ap); - va_end(ap); -} -#endif - -#ifndef HAVE_VERR -__dead void -verr(eval, fmt, ap) - int eval; - const char *fmt; - va_list ap; -{ - verrc(eval, errno, fmt, ap); -} -#endif - -#ifndef HAVE_ERRC -__dead void -errc(int eval, int code, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - verrc(eval, code, fmt, ap); - va_end(ap); -} -#endif - -#ifndef HAVE_VERRC -__dead void -verrc(eval, code, fmt, ap) - int eval; - int code; - const char *fmt; - va_list ap; -{ - if (err_file == 0) - err_set_file((FILE *)0); - fprintf(err_file, "%s: ", __progname); - if (fmt != NULL) { - vfprintf(err_file, fmt, ap); - fprintf(err_file, ": "); - } - fprintf(err_file, "%s\n", strerror(code)); - if (err_exit) - err_exit(eval); - exit(eval); -} -#endif - -#ifndef HAVE_ERRX -__dead void -errx(int eval, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - verrx(eval, fmt, ap); - va_end(ap); -} -#endif - -#ifndef HAVE_VERRX -__dead void -verrx(eval, fmt, ap) - int eval; - const char *fmt; - va_list ap; -{ - if (err_file == 0) - err_set_file((FILE *)0); - fprintf(err_file, "%s: ", __progname); - if (fmt != NULL) - vfprintf(err_file, fmt, ap); - fprintf(err_file, "\n"); - if (err_exit) - err_exit(eval); - exit(eval); -} -#endif - -#ifndef HAVE_WARN -void -warn(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vwarnc(errno, fmt, ap); - va_end(ap); -} -#endif - -#ifndef HAVE_VWARN -void -vwarn(fmt, ap) - const char *fmt; - va_list ap; -{ - vwarnc(errno, fmt, ap); -} -#endif - -#ifndef HAVE_WARNC -void -warnc(int code, const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vwarnc(code, fmt, ap); - va_end(ap); -} -#endif - -#ifndef HAVE_VWARNC -void -vwarnc(code, fmt, ap) - int code; - const char *fmt; - va_list ap; -{ - if (err_file == 0) - err_set_file((FILE *)0); - fprintf(err_file, "%s: ", __progname); - if (fmt != NULL) { - vfprintf(err_file, fmt, ap); - fprintf(err_file, ": "); - } - fprintf(err_file, "%s\n", strerror(code)); -} -#endif - -#ifndef HAVE_WARNX -void -warnx(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vwarnx(fmt, ap); - va_end(ap); -} -#endif - -#ifndef HAVE_VWARNX -void -vwarnx(fmt, ap) - const char *fmt; - va_list ap; -{ - if (err_file == 0) - err_set_file((FILE *)0); - fprintf(err_file, "%s: ", __progname); - if (fmt != NULL) - vfprintf(err_file, fmt, ap); - fprintf(err_file, "\n"); -} -#endif diff --git a/compat/lib/fstab.c b/compat/lib/fstab.c index 0b51de5..cc2d255 100644 --- a/compat/lib/fstab.c +++ b/compat/lib/fstab.c @@ -58,7 +58,7 @@ static void error __P((int)); static int fstabscan __P((void)); static -int fstabscan() +int fstabscan(void) { struct mntent *mnt; register char *cp; @@ -111,7 +111,7 @@ int fstabscan() } struct fstab * -getfsent() +getfsent(void) { if ((!_fs_fp && !setfsent()) || !fstabscan()) return((struct fstab *)NULL); @@ -119,8 +119,7 @@ getfsent() } struct fstab * -getfsspec(name) - register const char *name; +getfsspec(const char *name) { if (setfsent()) while (fstabscan()) @@ -130,8 +129,7 @@ getfsspec(name) } struct fstab * -getfsfile(name) - register const char *name; +getfsfile(const char *name) { if (setfsent()) while (fstabscan()) @@ -140,7 +138,8 @@ getfsfile(name) return((struct fstab *)NULL); } -int setfsent() +int +setfsent(void) { if (_fs_fp) { rewind(_fs_fp); @@ -153,7 +152,7 @@ int setfsent() } void -endfsent() +endfsent(void) { if (_fs_fp) { (void)endmntent(_fs_fp); @@ -162,8 +161,7 @@ endfsent() } static -void error(err) - int err; +void error(int err) { char *p; diff --git a/compat/lib/glob.c b/compat/lib/glob.c deleted file mode 100644 index 7725dde..0000000 --- a/compat/lib/glob.c +++ /dev/null @@ -1,868 +0,0 @@ -/* - * Ported to Linux's Second Extended File System as part of the - * dump and restore backup suit - * Remy Card , 1994-1997 - * Stelian Pop , 1999 - * - */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Guido van Rossum. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; -#endif /* LIBC_SCCS and not lint */ - -/* - * glob(3) -- a superset of the one defined in POSIX 1003.2. - * - * The [!...] convention to negate a range is supported (SysV, Posix, ksh). - * - * Optional extra services, controlled by flags not defined by POSIX: - * - * GLOB_QUOTE: - * Escaping convention: \ inhibits any special meaning the following - * character might have (except \ at end of string is retained). - * GLOB_MAGCHAR: - * Set in gl_flags if pattern contained a globbing character. - * GLOB_NOMAGIC: - * Same as GLOB_NOCHECK, but it will only append pattern if it did - * not contain any magic characters. [Used in csh style globbing] - * GLOB_ALTDIRFUNC: - * Use alternately specified directory access functions. - * GLOB_TILDE: - * expand ~user/foo to the /home/dir/of/user/foo - * GLOB_BRACE: - * expand {1,2}{a,b} to 1a 1b 2a 2b - * gl_matchc: - * Number of matches in the current invocation of glob. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DOLLAR '$' -#define DOT '.' -#define EOS '\0' -#define LBRACKET '[' -#define NOT '!' -#define QUESTION '?' -#define QUOTE '\\' -#define RANGE '-' -#define RBRACKET ']' -#define SEP '/' -#define STAR '*' -#define TILDE '~' -#define UNDERSCORE '_' -#define LBRACE '{' -#define RBRACE '}' -#define SLASH '/' -#define COMMA ',' - -#ifndef DEBUG - -#define M_QUOTE 0x8000 -#define M_PROTECT 0x4000 -#define M_MASK 0xffff -#define M_ASCII 0x00ff - -typedef u_short Char; - -#else - -#define M_QUOTE 0x80 -#define M_PROTECT 0x40 -#define M_MASK 0xff -#define M_ASCII 0x7f - -typedef char Char; - -#endif - - -#define CHAR(c) ((Char)((c)&M_ASCII)) -#define META(c) ((Char)((c)|M_QUOTE)) -#define M_ALL META('*') -#define M_END META(']') -#define M_NOT META('!') -#define M_ONE META('?') -#define M_RNG META('-') -#define M_SET META('[') -#define ismeta(c) (((c)&M_QUOTE) != 0) - - -static int compare __P((const void *, const void *)); -static void g_Ctoc __P((const Char *, char *)); -static int g_lstat __P((Char *, struct stat *, glob_t *)); -static DIR *g_opendir __P((Char *, glob_t *)); -static Char *g_strchr __P((Char *, int)); -#ifdef notdef -static Char *g_strcat __P((Char *, const Char *)); -#endif -static int g_stat __P((Char *, struct stat *, glob_t *)); -static int glob0 __P((const Char *, glob_t *)); -static int glob1 __P((Char *, glob_t *)); -static int glob2 __P((Char *, Char *, Char *, glob_t *)); -static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *)); -static int globextend __P((const Char *, glob_t *)); -static const Char * globtilde __P((const Char *, Char *, size_t, glob_t *)); -static int globexp1 __P((const Char *, glob_t *)); -static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); -static int match __P((Char *, Char *, Char *)); -#ifdef DEBUG -static void qprintf __P((const char *, Char *)); -#endif - -int -glob(pattern, flags, errfunc, pglob) - const char *pattern; - int flags, (*errfunc) __P((const char *, int)); - glob_t *pglob; -{ - const u_char *patnext; - int c; - Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; - - patnext = (u_char *) pattern; - if (!(flags & GLOB_APPEND)) { - pglob->gl_pathc = 0; - pglob->gl_pathv = NULL; - if (!(flags & GLOB_DOOFFS)) - pglob->gl_offs = 0; - } - pglob->gl_flags = flags & ~GLOB_MAGCHAR; - pglob->gl_errfunc = errfunc; - pglob->gl_matchc = 0; - - bufnext = patbuf; - bufend = bufnext + MAXPATHLEN; - if (flags & GLOB_QUOTE) { - /* Protect the quoted characters. */ - while (bufnext < bufend && (c = *patnext++) != EOS) - if (c == QUOTE) { - if ((c = *patnext++) == EOS) { - c = QUOTE; - --patnext; - } - *bufnext++ = c | M_PROTECT; - } - else - *bufnext++ = c; - } - else - while (bufnext < bufend && (c = *patnext++) != EOS) - *bufnext++ = c; - *bufnext = EOS; - - if (flags & GLOB_BRACE) - return globexp1(patbuf, pglob); - else - return glob0(patbuf, pglob); -} - -/* - * Expand recursively a glob {} pattern. When there is no more expansion - * invoke the standard globbing routine to glob the rest of the magic - * characters - */ -static int globexp1(pattern, pglob) - const Char *pattern; - glob_t *pglob; -{ - const Char* ptr = pattern; - int rv; - - /* Protect a single {}, for find(1), like csh */ - if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) - return glob0(pattern, pglob); - - while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) - if (!globexp2(ptr, pattern, pglob, &rv)) - return rv; - - return glob0(pattern, pglob); -} - - -/* - * Recursive brace globbing helper. Tries to expand a single brace. - * If it succeeds then it invokes globexp1 with the new pattern. - * If it fails then it tries to glob the rest of the pattern and returns. - */ -static int globexp2(ptr, pattern, pglob, rv) - const Char *ptr, *pattern; - glob_t *pglob; - int *rv; -{ - int i; - Char *lm, *ls; - const Char *pe, *pm, *pl; - Char patbuf[MAXPATHLEN + 1]; - - /* copy part up to the brace */ - for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) - continue; - ls = lm; - - /* Find the balanced brace */ - for (i = 0, pe = ++ptr; *pe; pe++) - if (*pe == LBRACKET) { - /* Ignore everything between [] */ - for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) - continue; - if (*pe == EOS) { - /* - * We could not find a matching RBRACKET. - * Ignore and just look for RBRACE - */ - pe = pm; - } - } - else if (*pe == LBRACE) - i++; - else if (*pe == RBRACE) { - if (i == 0) - break; - i--; - } - - /* Non matching braces; just glob the pattern */ - if (i != 0 || *pe == EOS) { - *rv = glob0(patbuf, pglob); - return 0; - } - - for (i = 0, pl = pm = ptr; pm <= pe; pm++) - switch (*pm) { - case LBRACKET: - /* Ignore everything between [] */ - for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) - continue; - if (*pm == EOS) { - /* - * We could not find a matching RBRACKET. - * Ignore and just look for RBRACE - */ - pm = pl; - } - break; - - case LBRACE: - i++; - break; - - case RBRACE: - if (i) { - i--; - break; - } - /* FALLTHROUGH */ - case COMMA: - if (i && *pm == COMMA) - break; - else { - /* Append the current string */ - for (lm = ls; (pl < pm); *lm++ = *pl++) - continue; - /* - * Append the rest of the pattern after the - * closing brace - */ - for (pl = pe + 1; (*lm++ = *pl++) != EOS;) - continue; - - /* Expand the current pattern */ -#ifdef DEBUG - qprintf("globexp2:", patbuf); -#endif - *rv = globexp1(patbuf, pglob); - - /* move after the comma, to the next string */ - pl = pm + 1; - } - break; - - default: - break; - } - *rv = 0; - return 0; -} - - - -/* - * expand tilde from the passwd file. - */ -static const Char * -globtilde(pattern, patbuf, patbuf_len, pglob) - const Char *pattern; - Char *patbuf; - size_t patbuf_len; - glob_t *pglob; -{ - struct passwd *pwd; - char *h; - const Char *p; - Char *b, *eb; - - if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) - return pattern; - - /* - * Copy up to the end of the string or / - */ - eb = &patbuf[patbuf_len - 1]; - for (p = pattern + 1, h = (char *) patbuf; - h < (char *)eb && *p && *p != SLASH; *h++ = *p++) - continue; - - *h = EOS; - - if (((char *) patbuf)[0] == EOS) { - /* - * handle a plain ~ or ~/ by expanding $HOME first if - * we're not running setuid or setgid) and then trying - * the password file - */ - if ( -#ifndef __linux__ -#ifndef __NETBSD_SYSCALLS - issetugid() != 0 || -#endif -#endif - (h = getenv("HOME")) == NULL) { - if (((h = getlogin()) != NULL && - (pwd = getpwnam(h)) != NULL) || - (pwd = getpwuid(getuid())) != NULL) - h = pwd->pw_dir; - else - return pattern; - } - } - else { - /* - * Expand a ~user - */ - if ((pwd = getpwnam((char*) patbuf)) == NULL) - return pattern; - else - h = pwd->pw_dir; - } - - /* Copy the home directory */ - for (b = patbuf; b < eb && *h; *b++ = *h++) - continue; - - /* Append the rest of the pattern */ - while (b < eb && (*b++ = *p++) != EOS) - continue; - *b = EOS; - - return patbuf; -} - - -/* - * The main glob() routine: compiles the pattern (optionally processing - * quotes), calls glob1() to do the real pattern matching, and finally - * sorts the list (unless unsorted operation is requested). Returns 0 - * if things went well, nonzero if errors occurred. It is not an error - * to find no matches. - */ -static int -glob0(pattern, pglob) - const Char *pattern; - glob_t *pglob; -{ - const Char *qpatnext; - int c, err, oldpathc; - Char *bufnext, patbuf[MAXPATHLEN+1]; - - qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char), - pglob); - oldpathc = pglob->gl_pathc; - bufnext = patbuf; - - /* We don't need to check for buffer overflow any more. */ - while ((c = *qpatnext++) != EOS) { - switch (c) { - case LBRACKET: - c = *qpatnext; - if (c == NOT) - ++qpatnext; - if (*qpatnext == EOS || - g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { - *bufnext++ = LBRACKET; - if (c == NOT) - --qpatnext; - break; - } - *bufnext++ = M_SET; - if (c == NOT) - *bufnext++ = M_NOT; - c = *qpatnext++; - do { - *bufnext++ = CHAR(c); - if (*qpatnext == RANGE && - (c = qpatnext[1]) != RBRACKET) { - *bufnext++ = M_RNG; - *bufnext++ = CHAR(c); - qpatnext += 2; - } - } while ((c = *qpatnext++) != RBRACKET); - pglob->gl_flags |= GLOB_MAGCHAR; - *bufnext++ = M_END; - break; - case QUESTION: - pglob->gl_flags |= GLOB_MAGCHAR; - *bufnext++ = M_ONE; - break; - case STAR: - pglob->gl_flags |= GLOB_MAGCHAR; - /* collapse adjacent stars to one, - * to avoid exponential behavior - */ - if (bufnext == patbuf || bufnext[-1] != M_ALL) - *bufnext++ = M_ALL; - break; - default: - *bufnext++ = CHAR(c); - break; - } - } - *bufnext = EOS; -#ifdef DEBUG - qprintf("glob0:", patbuf); -#endif - - if ((err = glob1(patbuf, pglob)) != 0) - return(err); - - /* - * If there was no match we are going to append the pattern - * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified - * and the pattern did not contain any magic characters - * GLOB_NOMAGIC is there just for compatibility with csh. - */ - if (pglob->gl_pathc == oldpathc && - ((pglob->gl_flags & GLOB_NOCHECK) || - ((pglob->gl_flags & GLOB_NOMAGIC) && - !(pglob->gl_flags & GLOB_MAGCHAR)))) - return(globextend(pattern, pglob)); - else if (!(pglob->gl_flags & GLOB_NOSORT)) - qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, - pglob->gl_pathc - oldpathc, sizeof(char *), compare); - return(0); -} - -static int -compare(p, q) - const void *p, *q; -{ - return(strcmp(*(char **)p, *(char **)q)); -} - -static int -glob1(pattern, pglob) - Char *pattern; - glob_t *pglob; -{ - Char pathbuf[MAXPATHLEN+1]; - - /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ - if (*pattern == EOS) - return(0); - return(glob2(pathbuf, pathbuf, pattern, pglob)); -} - -/* - * The functions glob2 and glob3 are mutually recursive; there is one level - * of recursion for each segment in the pattern that contains one or more - * meta characters. - */ -static int -glob2(pathbuf, pathend, pattern, pglob) - Char *pathbuf, *pathend, *pattern; - glob_t *pglob; -{ - struct stat sb; - Char *p, *q; - int anymeta; - - /* - * Loop over pattern segments until end of pattern or until - * segment with meta character found. - */ - for (anymeta = 0;;) { - if (*pattern == EOS) { /* End of pattern? */ - *pathend = EOS; - if (g_lstat(pathbuf, &sb, pglob)) - return(0); - - if (((pglob->gl_flags & GLOB_MARK) && - pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) - || (S_ISLNK(sb.st_mode) && - (g_stat(pathbuf, &sb, pglob) == 0) && - S_ISDIR(sb.st_mode)))) { - *pathend++ = SEP; - *pathend = EOS; - } - ++pglob->gl_matchc; - return(globextend(pathbuf, pglob)); - } - - /* Find end of next segment, copy tentatively to pathend. */ - q = pathend; - p = pattern; - while (*p != EOS && *p != SEP) { - if (ismeta(*p)) - anymeta = 1; - *q++ = *p++; - } - - if (!anymeta) { /* No expansion, do next segment. */ - pathend = q; - pattern = p; - while (*pattern == SEP) - *pathend++ = *pattern++; - } else /* Need expansion, recurse. */ - return(glob3(pathbuf, pathend, pattern, p, pglob)); - } - /* NOTREACHED */ -} - -static int -glob3(pathbuf, pathend, pattern, restpattern, pglob) - Char *pathbuf, *pathend, *pattern, *restpattern; - glob_t *pglob; -{ - register struct dirent *dp; - DIR *dirp; - int err; - char buf[MAXPATHLEN]; - - /* - * The readdirfunc declaration can't be prototyped, because it is - * assigned, below, to two functions which are prototyped in glob.h - * and dirent.h as taking pointers to differently typed opaque - * structures. - */ - struct dirent *(*readdirfunc)(); - - *pathend = EOS; - errno = 0; - - if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { - /* TODO: don't call for ENOENT or ENOTDIR? */ - if (pglob->gl_errfunc) { - g_Ctoc(pathbuf, buf); - if (pglob->gl_errfunc(buf, errno) || - pglob->gl_flags & GLOB_ERR) - return (GLOB_ABEND); - } - return(0); - } - - err = 0; - - /* Search directory for matching names. */ - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - readdirfunc = pglob->gl_readdir; - else - readdirfunc = readdir; - while ((dp = (*readdirfunc)(dirp))) { - register u_char *sc; - register Char *dc; - - /* Initial DOT must be matched literally. */ - if (dp->d_name[0] == DOT && *pattern != DOT) - continue; - for (sc = (u_char *) dp->d_name, dc = pathend; - (*dc++ = *sc++) != EOS;) - continue; - if (!match(pathend, pattern, restpattern)) { - *pathend = EOS; - continue; - } - err = glob2(pathbuf, --dc, restpattern, pglob); - if (err) - break; - } - - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - (*pglob->gl_closedir)(dirp); - else - closedir(dirp); - return(err); -} - - -/* - * Extend the gl_pathv member of a glob_t structure to accomodate a new item, - * add the new item, and update gl_pathc. - * - * This assumes the BSD realloc, which only copies the block when its size - * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic - * behavior. - * - * Return 0 if new item added, error code if memory couldn't be allocated. - * - * Invariant of the glob_t structure: - * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and - * gl_pathv points to (gl_offs + gl_pathc + 1) items. - */ -static int -globextend(path, pglob) - const Char *path; - glob_t *pglob; -{ - register char **pathv; - register int i; - u_int newsize; - char *copy; - const Char *p; - - newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); - pathv = pglob->gl_pathv ? - realloc((char *)pglob->gl_pathv, newsize) : - malloc(newsize); - if (pathv == NULL) - return(GLOB_NOSPACE); - - if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { - /* first time around -- clear initial gl_offs items */ - pathv += pglob->gl_offs; - for (i = pglob->gl_offs; --i >= 0; ) - *--pathv = NULL; - } - pglob->gl_pathv = pathv; - - for (p = path; *p++;) - continue; - if ((copy = malloc(p - path)) != NULL) { - g_Ctoc(path, copy); - pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; - } - pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; - return(copy == NULL ? GLOB_NOSPACE : 0); -} - -/* - * pattern matching function for filenames. Each occurrence of the * - * pattern causes a recursion level. - */ -static int -match(name, pat, patend) - register Char *name, *pat, *patend; -{ - int ok, negate_range; - Char c, k; - - while (pat < patend) { - c = *pat++; - switch (c & M_MASK) { - case M_ALL: - if (pat == patend) - return(1); - do - if (match(name, pat, patend)) - return(1); - while (*name++ != EOS); - return(0); - case M_ONE: - if (*name++ == EOS) - return(0); - break; - case M_SET: - ok = 0; - if ((k = *name++) == EOS) - return(0); - if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) - ++pat; - while (((c = *pat++) & M_MASK) != M_END) - if ((*pat & M_MASK) == M_RNG) { - if (c <= k && k <= pat[1]) - ok = 1; - pat += 2; - } else if (c == k) - ok = 1; - if (ok == negate_range) - return(0); - break; - default: - if (*name++ != c) - return(0); - break; - } - } - return(*name == EOS); -} - -/* Free allocated data belonging to a glob_t structure. */ -void -globfree(pglob) - glob_t *pglob; -{ - register int i; - register char **pp; - - if (pglob->gl_pathv != NULL) { - pp = pglob->gl_pathv + pglob->gl_offs; - for (i = pglob->gl_pathc; i--; ++pp) - if (*pp) - free(*pp); - free(pglob->gl_pathv); - } -} - -static DIR * -g_opendir(str, pglob) - register Char *str; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - if (!*str) - strcpy(buf, "."); - else - g_Ctoc(str, buf); - - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_opendir)(buf)); - - return(opendir(buf)); -} - -static int -g_lstat(fn, sb, pglob) - register Char *fn; - struct stat *sb; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - g_Ctoc(fn, buf); - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_lstat)(buf, sb)); - return(lstat(buf, sb)); -} - -static int -g_stat(fn, sb, pglob) - register Char *fn; - struct stat *sb; - glob_t *pglob; -{ - char buf[MAXPATHLEN]; - - g_Ctoc(fn, buf); - if (pglob->gl_flags & GLOB_ALTDIRFUNC) - return((*pglob->gl_stat)(buf, sb)); - return(stat(buf, sb)); -} - -static Char * -g_strchr(str, ch) - Char *str; - int ch; -{ - do { - if (*str == ch) - return (str); - } while (*str++); - return (NULL); -} - -#ifdef notdef -static Char * -g_strcat(dst, src) - Char *dst; - const Char* src; -{ - Char *sdst = dst; - - while (*dst++) - continue; - --dst; - while((*dst++ = *src++) != EOS) - continue; - - return (sdst); -} -#endif - -static void -g_Ctoc(str, buf) - register const Char *str; - char *buf; -{ - register char *dc; - - for (dc = buf; (*dc++ = *str++) != EOS;) - continue; -} - -#ifdef DEBUG -static void -qprintf(str, s) - const char *str; - register Char *s; -{ - register Char *p; - - (void)printf("%s:\n", str); - for (p = s; *p; p++) - (void)printf("%c", CHAR(*p)); - (void)printf("\n"); - for (p = s; *p; p++) - (void)printf("%c", *p & M_PROTECT ? '"' : ' '); - (void)printf("\n"); - for (p = s; *p; p++) - (void)printf("%c", ismeta(*p) ? '_' : ' '); - (void)printf("\n"); -} -#endif diff --git a/config.h.in b/config.h.in index 47b9199..d7e66cb 100644 --- a/config.h.in +++ b/config.h.in @@ -12,9 +12,6 @@ /* Define if you have the err function. */ #undef HAVE_ERR -/* Define if you have the errc function. */ -#undef HAVE_ERRC - /* Define if you have the errx function. */ #undef HAVE_ERRX @@ -24,26 +21,20 @@ /* Define if you have the verr function. */ #undef HAVE_VERR -/* Define if you have the verrc function. */ -#undef HAVE_VERRC - /* Define if you have the verrx function. */ #undef HAVE_VERRX /* Define if you have the vwarn function. */ #undef HAVE_VWARN -/* Define if you have the vwarnc function. */ -#undef HAVE_VWARNC - /* Define if you have the vwarnx function. */ #undef HAVE_VWARNX /* Define if you have the warn function. */ #undef HAVE_WARN -/* Define if you have the warnc function. */ -#undef HAVE_WARNC - /* Define if you have the warnx function. */ #undef HAVE_WARNX + +/* Define if you have the glob function. */ +#undef HAVE_GLOB diff --git a/configure b/configure index a7f0137..754af59 100755 --- a/configure +++ b/configure @@ -1,7 +1,7 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.12 +# Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -77,6 +77,7 @@ mandir='${prefix}/man' # Initialize some other variables. subdirs= MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} # Maximum number of lines to put in a shell here document. ac_max_here_lines=12 @@ -360,7 +361,7 @@ EOF verbose=yes ;; -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.12" + echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) @@ -530,9 +531,11 @@ ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross +ac_exeext= +ac_objext=o if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then @@ -553,7 +556,7 @@ MCONFIG=./MCONFIG echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:557: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:560: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -580,7 +583,7 @@ else fi echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 -echo "configure:584: checking whether ln -s works" >&5 +echo "configure:587: checking whether ln -s works" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -603,7 +606,7 @@ fi # Extract the first word of "cp", so it can be a program name with args. set dummy cp; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:607: checking for $ac_word" >&5 +echo "configure:610: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_CP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -611,9 +614,13 @@ else /*) ac_cv_path_CP="$CP" # Let the user override the test with a path. ;; + ?:/*) + ac_cv_path_CP="$CP" # Let the user override the test with a dos path. + ;; *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_CP="$ac_dir/$ac_word" @@ -635,7 +642,7 @@ fi # Extract the first word of "mv", so it can be a program name with args. set dummy mv; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:639: checking for $ac_word" >&5 +echo "configure:646: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_MV'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -643,9 +650,13 @@ else /*) ac_cv_path_MV="$MV" # Let the user override the test with a path. ;; + ?:/*) + ac_cv_path_MV="$MV" # Let the user override the test with a dos path. + ;; *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_MV="$ac_dir/$ac_word" @@ -667,7 +678,7 @@ fi # Extract the first word of "rm", so it can be a program name with args. set dummy rm; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:671: checking for $ac_word" >&5 +echo "configure:682: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_RM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -675,9 +686,13 @@ else /*) ac_cv_path_RM="$RM" # Let the user override the test with a path. ;; + ?:/*) + ac_cv_path_RM="$RM" # Let the user override the test with a dos path. + ;; *) - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_path_RM="$ac_dir/$ac_word" @@ -717,33 +732,33 @@ ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. # Make sure we can run config.sub. -if $ac_config_sub sun4 >/dev/null 2>&1; then : +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:726: checking host system type" >&5 +echo "configure:741: checking host system type" >&5 host_alias=$host case "$host_alias" in NONE) case $nonopt in NONE) - if host_alias=`$ac_config_guess`; then : + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } fi ;; *) host_alias=$nonopt ;; esac ;; esac -host=`$ac_config_sub $host_alias` +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` echo "$ac_t""$host" 1>&6 echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:747: checking build system type" >&5 +echo "configure:762: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -754,7 +769,7 @@ NONE) esac ;; esac -build=`$ac_config_sub $build_alias` +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` @@ -769,15 +784,16 @@ fi # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:773: checking for $ac_word" >&5 +echo "configure:788: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_AR="${ac_tool_prefix}ar" @@ -800,15 +816,16 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:804: checking for $ac_word" >&5 +echo "configure:820: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$AR"; then ac_cv_prog_AR="$AR" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_AR="ar" @@ -834,15 +851,16 @@ fi # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:838: checking for $ac_word" >&5 +echo "configure:855: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" @@ -865,15 +883,16 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:869: checking for $ac_word" >&5 +echo "configure:887: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$RANLIB"; then ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_RANLIB="ranlib" @@ -899,15 +918,16 @@ fi # Extract the first word of "${ac_tool_prefix}patch", so it can be a program name with args. set dummy ${ac_tool_prefix}patch; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:903: checking for $ac_word" >&5 +echo "configure:922: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_PATCH'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$PATCH"; then ac_cv_prog_PATCH="$PATCH" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_PATCH="${ac_tool_prefix}patch" @@ -930,15 +950,16 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "patch", so it can be a program name with args. set dummy patch; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:934: checking for $ac_word" >&5 +echo "configure:954: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_PATCH'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$PATCH"; then ac_cv_prog_PATCH="$PATCH" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_PATCH="patch" @@ -964,15 +985,16 @@ fi # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:968: checking for $ac_word" >&5 +echo "configure:989: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" - for ac_dir in $PATH; do + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then ac_cv_prog_CC="gcc" @@ -993,16 +1015,17 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:997: checking for $ac_word" >&5 +echo "configure:1019: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else - IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" ac_prog_rejected=no - for ac_dir in $PATH; do + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do test -z "$ac_dir" && ac_dir=. if test -f $ac_dir/$ac_word; then if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then @@ -1037,25 +1060,61 @@ else echo "$ac_t""no" 1>&6 fi + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1070: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:1045: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:1102: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. ac_cpp='$CPP $CPPFLAGS' ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' -ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' cross_compiling=$ac_cv_prog_cc_cross -cat > conftest.$ac_ext < conftest.$ac_ext << EOF + +#line 1113 "configure" #include "confdefs.h" + main(){return(0);} EOF -if { (eval echo configure:1059: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1118: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -1069,18 +1128,24 @@ else ac_cv_prog_cc_works=no fi rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:1079: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:1144: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:1084: checking whether we are using GNU C" >&5 +echo "configure:1149: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1089,7 +1154,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1093: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:1158: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -1100,11 +1165,15 @@ echo "$ac_t""$ac_cv_prog_gcc" 1>&6 if test $ac_cv_prog_gcc = yes; then GCC=yes - ac_test_CFLAGS="${CFLAGS+set}" - ac_save_CFLAGS="$CFLAGS" - CFLAGS= - echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:1108: checking whether ${CC-cc} accepts -g" >&5 +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:1177: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1119,16 +1188,20 @@ rm -f conftest* fi echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 - if test "$ac_test_CFLAGS" = set; then - CFLAGS="$ac_save_CFLAGS" - elif test $ac_cv_prog_cc_g = yes; then +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then CFLAGS="-g -O2" else - CFLAGS="-O2" + CFLAGS="-g" fi else - GCC= - test "${CFLAGS+set}" = set || CFLAGS="-g" + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi fi # Find a good install program. We prefer a C program (faster), @@ -1138,28 +1211,30 @@ fi # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1146: checking for a BSD compatible install" >&5 +echo "configure:1220: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else - IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS="${IFS}:" + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" for ac_dir in $PATH; do # Account for people who put trailing slashes in PATH elements. case "$ac_dir/" in /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. - for ac_prog in ginstall installbsd scoinst install; do + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do if test -f $ac_dir/$ac_prog; then if test $ac_prog = install && grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. - # OSF/1 installbsd also uses dspmsg, but is usable. : else ac_cv_path_install="$ac_dir/$ac_prog -c" @@ -1189,6 +1264,8 @@ echo "$ac_t""$INSTALL" 1>&6 # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' @@ -1383,7 +1460,7 @@ fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:1387: checking how to run the C preprocessor" >&5 +echo "configure:1464: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -1398,14 +1475,14 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1408: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1485: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -1415,14 +1492,31 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1425: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1502: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1519: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : else @@ -1434,6 +1528,8 @@ else fi rm -f conftest* fi +rm -f conftest* +fi rm -f conftest* ac_cv_prog_CPP="$CPP" fi @@ -1445,18 +1541,18 @@ echo "$ac_t""$CPP" 1>&6 ac_safe=`echo "ext2fs/ext2fs.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for ext2fs/ext2fs.h""... $ac_c" 1>&6 -echo "configure:1449: checking for ext2fs/ext2fs.h" >&5 +echo "configure:1545: checking for ext2fs/ext2fs.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1459: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1555: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* eval "ac_cv_header_$ac_safe=yes" @@ -1478,7 +1574,7 @@ ext2fs_h=no fi echo $ac_n "checking for ext2fs_open in -lext2fs""... $ac_c" 1>&6 -echo "configure:1482: checking for ext2fs_open in -lext2fs" >&5 +echo "configure:1578: checking for ext2fs_open in -lext2fs" >&5 ac_lib_var=`echo ext2fs'_'ext2fs_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1486,7 +1582,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lext2fs -lcom_err $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -1522,15 +1618,15 @@ if test "$ext2fs_h" = no -o "$ext2fs_lib" = no; then { echo "configure: error: You need to install the Ext2fs libraries from the E2fsprogs distribution first" 1>&2; exit 1; } fi -for ac_func in err errc errx verr verrc verrx vwarn vwarnc vwarnx warn warnc warnx realpath +for ac_func in err errx verr verrx vwarn vwarnx warn warnx realpath glob do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:1529: checking for $ac_func" >&5 +echo "configure:1625: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest; then +if { (eval echo configure:1653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -1579,12 +1675,12 @@ done echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1583: checking for ANSI C header files" >&5 +echo "configure:1679: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1592,8 +1688,8 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1596: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out` +{ (eval echo configure:1692: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* ac_cv_header_stdc=yes @@ -1609,7 +1705,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1627,7 +1723,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1648,7 +1744,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1659,7 +1755,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1683,12 +1779,12 @@ EOF fi echo $ac_n "checking for quad_t""... $ac_c" 1>&6 -echo "configure:1687: checking for quad_t" >&5 +echo "configure:1783: checking for quad_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_quad_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1697,7 +1793,7 @@ else #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "quad_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + egrep "(^|[^a-zA-Z_0-9])quad_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_quad_t=yes else @@ -1716,12 +1812,12 @@ EOF fi echo $ac_n "checking for u_quad_t""... $ac_c" 1>&6 -echo "configure:1720: checking for u_quad_t" >&5 +echo "configure:1816: checking for u_quad_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_u_quad_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -1730,7 +1826,7 @@ else #endif EOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - egrep "u_quad_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then + egrep "(^|[^a-zA-Z_0-9])u_quad_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then rm -rf conftest* ac_cv_type_u_quad_t=yes else @@ -1778,7 +1874,7 @@ EOF # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. (set) 2>&1 | - case `(ac_space=' '; set) 2>&1` in + case `(ac_space=' '; set | grep ac_space) 2>&1` in *ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote substitution # turns \\\\ into \\, and sed turns \\ into \). @@ -1845,7 +1941,7 @@ do echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.12" + echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; @@ -1865,9 +1961,11 @@ sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g; s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF $ac_vpsub $extrasub +s%@SHELL@%$SHELL%g s%@CFLAGS@%$CFLAGS%g s%@CPPFLAGS@%$CPPFLAGS%g s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g s%@DEFS@%$DEFS%g s%@LDFLAGS@%$LDFLAGS%g s%@LIBS@%$LIBS%g @@ -1908,6 +2006,7 @@ s%@RANLIB@%$RANLIB%g s%@PATCH@%$PATCH%g s%@CC@%$CC%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g s%@DUMPDEBUG@%$DUMPDEBUG%g s%@RESTOREDEBUG@%$RESTOREDEBUG%g diff --git a/configure.in b/configure.in index d0d3509..b6037a0 100644 --- a/configure.in +++ b/configure.in @@ -219,7 +219,7 @@ fi dnl dnl Check for library functions dnl -AC_CHECK_FUNCS(err errc errx verr verrc verrx vwarn vwarnc vwarnx warn warnc warnx realpath) +AC_CHECK_FUNCS(err errx verr verrx vwarn vwarnx warn warnx realpath glob) dnl dnl Check for types diff --git a/dump.lsm b/dump.lsm index 19363f2..b72e9ab 100644 --- a/dump.lsm +++ b/dump.lsm @@ -1,13 +1,13 @@ Begin3 Title: dump and restore for Ext2fs -Version: 0.4b5 -Entered-date: 22SEP99 +Version: 0.4b6 +Entered-date: 03OCT99 Description: Port of the 4.4BSD dump and restore backup suite Keywords: backup, filesystem, Ext2fs Author: University of California, Berkeley -Maintained-by: pop@captimark.fr (Stelian Pop) +Maintained-by: pop@cybercable.fr (Stelian Pop) Primary-site: tsx-11.mit.edu /pub/linux/ALPHA/ext2fs - 132kB dump-0.4b5.tar.gz + 132kB dump-0.4b6.tar.gz 627 dump.lsm Alternate-site: Original-site: ftp.freebsd.org /pub/bsd-sources/4.4BSD-Lite2/sbin diff --git a/dump/Makefile.in b/dump/Makefile.in index 71435b0..a2e872a 100644 --- a/dump/Makefile.in +++ b/dump/Makefile.in @@ -3,7 +3,7 @@ srcdir= @srcdir@ @MCONFIG@ -CFLAGS= @CCOPTS@ -pipe $(GINC) $(INC) $(DEFS) @DUMPDEBUG@ +CFLAGS= @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) @DUMPDEBUG@ LDFLAGS:= $(LDFLAGS) @STATIC@ LIBS= $(GLIBS) DEPLIBS= ../compat/lib/libcompat.a @@ -14,7 +14,7 @@ SRCS= itime.c main.c optr.c tape.c traverse.c unctime.c OBJS= itime.o main.o optr.o tape.o traverse.o unctime.o \ ../common/dumprmt.o MAN8= dump.8 -MLINKS= $(MANDIR)/dump.8 $(MANDIR)/rdump.8 +MLINKS= dump.8 $(MANDIR)/rdump.8 all:: $(PROG) diff --git a/dump/dump.8 b/dump/dump.8 index 495f541..b7f427e 100644 --- a/dump/dump.8 +++ b/dump/dump.8 @@ -11,7 +11,7 @@ .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgment: +.\" must display the following acknowledgement: .\" This product includes software developed by the University of .\" California, Berkeley and its contributors. .\" 4. Neither the name of the University nor the names of its contributors @@ -31,14 +31,14 @@ .\" SUCH DAMAGE. .\" .\" @(#)dump.8 8.3 (Berkeley) 5/1/95 -.\" $Id: dump.8,v 1.2 1999/10/11 12:53:21 stelian Exp $ +.\" $Id: dump.8,v 1.3 1999/10/11 12:59:18 stelian Exp $ .\" -.Dd May 1, 1995 +.Dd June 4, 1997 .Dt DUMP 8 .Os BSD 4 .Sh NAME .Nm dump -.Nd filesystem backup +.Nd ext2 filesystem backup .Sh SYNOPSIS .Nm dump .Op Fl 0123456789acknu @@ -68,12 +68,12 @@ .in -\\n(iSu (The .Bx 4.3 -option syntax is implemented for backward compatibility, but +option syntax is implemented for backward compatibility but is not documented here.) .Sh DESCRIPTION .Nm Dump examines files -on a filesystem +on an ext2 filesystem and determines which files need to be backed up. These files are copied to the given disk, tape or other @@ -83,15 +83,15 @@ option below for doing remote backups). A dump that is larger than the output medium is broken into multiple volumes. On most media the size is determined by writing until an -end-of-media indication is returned. This can be enforced +end-of-media indication is returned. This can be enforced by using the .Fl a option. .Pp On media that cannot reliably return an end-of-media indication -(such as some cartridge tape drives) +(such as some cartridge tape drives), each volume is of a fixed size; -the actual size is determined by the tape size and density and/or +the actual size is determined by the tape size, density and/or block count options below. By default, the same output file name is used for each volume after prompting the operator to change media. @@ -108,10 +108,12 @@ guarantees the entire file system is copied option below). A level number above 0, incremental backup, -tells dump to +tells +.Nm dump +to copy all files new or modified since the -last dump of any lower level. -The default level is 0. +last dump of the same or lower level. +The default level is 9. .It Fl B Ar records The number of 1 KB blocks per volume. This option overrides the calculation of tape size @@ -126,6 +128,13 @@ drive with hardware compression (where you can never be sure about the compression ratio). .It Fl b Ar blocksize The number of kilobytes per dump record. +Since the IO system slices all requests into chunks of MAXBSIZE +(typically 64KB), it is not possible to use a larger blocksize +without having problems later with +.Xr restore 8 . +Therefore +.Nm dump +will constrain writes to MAXBSIZE. .It Fl c Change the defaults for use with a cartridge tape drive, with a density of 8000 bpi, and a length of 1700 feet. @@ -149,7 +158,7 @@ Write the backup to .Ar file may be a special device file like -.Pa /dev/rmt12 +.Pa /dev/st0 (a tape drive), .Pa /dev/rsd1c (a floppy disk drive), @@ -163,9 +172,9 @@ if the dump requires more volumes than the number of names given, the last file name will used for all remaining volumes after prompting for media changes. If the name of the file is of the form -.Dq host:file , +.Dq host:file or -.Dq user@host:file , +.Dq user@host:file .Nm writes to the named file on the remote host using .Xr rmt 8 . @@ -214,7 +223,9 @@ The default tape length is 2300 feet. Use the specified date as the starting time for the dump instead of the time determined from looking in .Pa /etc/dumpdates . -The format of date is the same as that of +The format of +.Ar date +is the same as that of .Xr ctime 3 . This option is useful for automated dump scripts that wish to dump over a specific period of time. @@ -253,7 +264,7 @@ The option causes .Nm to print out, for each file system in -.Pa /etc/dumpdates +.Pa /etc/dumpdates , the most recent dump date and level, and highlights those file systems that should be dumped. If the @@ -262,7 +273,9 @@ option is set, all other options are ignored, and .Nm exits immediately. .It Fl w -Is like W, but prints only those filesystems which need to be dumped. +Is like +.Fl W , +but prints only those filesystems which need to be dumped. .El .Pp .Nm Dump @@ -271,7 +284,7 @@ end of tape, end of dump, tape write error, tape open error or -disk read error (if there are more than a threshold of 32). +disk read error (if there is more than a threshold of 32). In addition to alerting all operators implied by the .Fl n key, @@ -370,7 +383,7 @@ will be used to determine the pathname of the remote program. .Sh FILES .Bl -tag -width /etc/dumpdates -compact -.It Pa /dev/rmt8 +.It Pa /dev/st0 default tape unit to dump to .It Pa /etc/dumpdates dump date records @@ -387,11 +400,17 @@ to find group .Sh DIAGNOSTICS Many, and verbose. .Pp -Dump exits with zero status on success. +.Nm Dump +exits with zero status on success. Startup errors are indicated with an exit code of 1; abnormal termination is indicated with an exit code of 3. .Sh BUGS -Fewer than 32 read errors on the filesystem are ignored. +It might be considered a bug that this version of dump can only handle ext2 +filesystems. Specifically, it does not work with FAT filesystems. +.Pp +Fewer than 32 read errors on the filesystem are ignored. If noticing +read errors is important, the output from dump can be parsed to look for lines +that contain the text 'read error'. .Pp Each reel requires a new process, so parent processes for reels already written just hang around until the entire tape @@ -402,7 +421,7 @@ with the .Fl W or .Fl w -options does not report filesystems that have never been recorded +option does not report filesystems that have never been recorded in .Pa /etc/dumpdates , even if listed in diff --git a/dump/dump.h b/dump/dump.h index ad48390..8424c71 100644 --- a/dump/dump.h +++ b/dump/dump.h @@ -95,6 +95,7 @@ ext2_filsys fs; struct fs *sblock; /* the file system super block */ char sblock_buf[MAXBSIZE]; #endif +long xferrate; /* averaged transfer rate of all volumes */ long dev_bsize; /* block size of underlying disk device */ int dev_bshift; /* log2(dev_bsize) */ int tp_bshift; /* log2(TP_BSIZE) */ @@ -104,15 +105,19 @@ int tp_bshift; /* log2(TP_BSIZE) */ #endif /* operator interface functions */ -void broadcast __P((char *message)); -void lastdump __P((int arg)); /* int should be char */ +void broadcast __P((const char *message)); +time_t do_stats __P((void)); +void lastdump __P((char arg)); void msg __P((const char *fmt, ...)); void msgtail __P((const char *fmt, ...)); -int query __P((char *question)); +int query __P((const char *question)); void quit __P((const char *fmt, ...)); void set_operators __P((void)); +#if defined(SIGINFO) +void statussig __P((int signo)); +#endif void timeest __P((void)); -time_t unctime __P((char *str)); +time_t unctime __P((const char *str)); /* mapping rouintes */ struct dinode; @@ -139,9 +144,9 @@ void close_rewind __P((void)); void dumpblock __P((daddr_t blkno, int size)); void startnewtape __P((int top)); void trewind __P((void)); -void writerec __P((char *dp, int isspcl)); +void writerec __P((const void *dp, int isspcl)); -__dead void Exit __P((int status)); +void Exit __P((int status)); void dumpabort __P((int signo)); void getfstab __P((void)); @@ -150,10 +155,14 @@ struct dinode *getino __P((ino_t inum)); /* rdump routines */ #ifdef RDUMP +int rmthost __P((const char *host)); +int rmtopen __P((const char *tape, int mode)); void rmtclose __P((void)); -int rmthost __P((char *host)); -int rmtopen __P((char *tape, int mode)); -int rmtwrite __P((char *buf, int count)); +int rmtread __P((char *buf, size_t count)); +int rmtwrite __P((const char *buf, size_t count)); +int rmtseek __P((int offset, int pos)); +struct mtget * rmtstatus __P((void)); +int rmtioctl __P((int cmd, int count)); #endif /* RDUMP */ void interrupt __P((int signo)); /* in case operator bangs on console */ @@ -162,7 +171,7 @@ void interrupt __P((int signo)); /* in case operator bangs on console */ * Exit status codes */ #define X_FINOK 0 /* normal exit */ -#define X_STARTUP 1 /* startup error */ +#define X_STARTUP 1 /* startup error */ #define X_REWRITE 2 /* restart writing from the check point */ #define X_ABORT 3 /* abort dump; don't attempt checkpointing */ @@ -173,9 +182,9 @@ void interrupt __P((int signo)); /* in case operator bangs on console */ #define DIALUP "ttyd" /* prefix for dialups */ #endif -struct fstab *fstabsearch __P((char *key)); /* search fs_file and fs_spec */ +struct fstab *fstabsearch __P((const char *key)); /* search fs_file and fs_spec */ #ifdef __linux__ -struct fstab *fstabsearchdir __P((char *key, char *dir)); /* search fs_file and fs_spec */ +struct fstab *fstabsearchdir __P((const char *key, char *dir)); /* search fs_file and fs_spec */ #endif #ifndef NAME_MAX diff --git a/dump/itime.c b/dump/itime.c index 441085f..a1b66f9 100644 --- a/dump/itime.c +++ b/dump/itime.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)itime.c 8.1 (Berkeley) 6/5/93"; #endif static const char rcsid[] = - "$Id: itime.c,v 1.2 1999/10/11 12:53:22 stelian Exp $"; + "$Id: itime.c,v 1.3 1999/10/11 12:59:18 stelian Exp $"; #endif /* not lint */ #include @@ -93,7 +93,7 @@ static int makedumpdate __P((struct dumpdates *, char *)); static void readdumptimes __P((FILE *)); void -initdumptimes() +initdumptimes(void) { FILE *df; @@ -125,8 +125,7 @@ initdumptimes() } static void -readdumptimes(df) - FILE *df; +readdumptimes(FILE *df) { register int i; register struct dumptime *dtwalk; @@ -153,7 +152,7 @@ readdumptimes(df) } void -getdumptime() +getdumptime(void) { register struct dumpdates *ddp; register int i; @@ -167,6 +166,12 @@ getdumptime() spcl.c_ddate = 0; lastlevel = '0'; + /* if we're not going to update dumpdates, there's no point in reading + it, particularly since /var might not be mounted... wait until here + to benefit from the initialization of variables needed by parent */ + if (uflag == 0) + return; + initdumptimes(); /* * Go find the entry with the same name for a lower increment @@ -189,7 +194,7 @@ getdumptime() } void -putdumptime() +putdumptime(void) { FILE *df; register struct dumpdates *dtwalk; @@ -250,9 +255,7 @@ putdumptime() } static void -dumprecout(file, what) - FILE *file; - struct dumpdates *what; +dumprecout(FILE *file, struct dumpdates *what) { if (fprintf(file, DUMPOUTFMT, @@ -265,14 +268,12 @@ dumprecout(file, what) int recno; static int -getrecord(df, ddatep) - FILE *df; - struct dumpdates *ddatep; +getrecord(FILE *df, struct dumpdates *ddatep) { char tbuf[BUFSIZ]; recno = 0; - if ( (fgets(tbuf, sizeof (tbuf), df)) != tbuf) + if (fgets(tbuf, sizeof (tbuf), df) == NULL) return(-1); recno++; if (makedumpdate(ddatep, tbuf) < 0) @@ -287,11 +288,9 @@ getrecord(df, ddatep) } static int -makedumpdate(ddp, tbuf) - struct dumpdates *ddp; - char *tbuf; +makedumpdate(struct dumpdates *ddp, char *tbuf) { - char un_buf[128]; + char un_buf[BUFSIZ]; (void) sscanf(tbuf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf); ddp->dd_ddate = unctime(un_buf); diff --git a/dump/main.c b/dump/main.c index c17684e..ca30a9c 100644 --- a/dump/main.c +++ b/dump/main.c @@ -2,7 +2,7 @@ * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit * Remy Card , 1994-1997 - * Stelian Pop , 1999 + * Stelian Pop , 1999 * */ @@ -50,7 +50,7 @@ static const char copyright[] = static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95"; #endif static const char rcsid[] = - "$Id: main.c,v 1.2 1999/10/11 12:53:22 stelian Exp $"; + "$Id: main.c,v 1.3 1999/10/11 12:59:18 stelian Exp $"; #endif /* not lint */ #include @@ -74,7 +74,7 @@ static const char rcsid[] = #include #include -#include +#include #include #include #include @@ -109,14 +109,13 @@ char *host = NULL; /* remote host (if any) */ char *__progname; #endif -static long numarg __P((char *, long, long)); +int maxbsize = 64*1024; /* XXX MAXBSIZE from sys/param.h */ +static long numarg __P((const char *, long, long)); static void obsolete __P((int *, char **[])); static void usage __P((void)); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { register ino_t ino; register int dirty; @@ -131,6 +130,7 @@ main(argc, argv) char directory[NAME_MAX]; char pathname[NAME_MAX]; #endif + time_t tnow; char labelstr[LBLSIZE]; spcl.c_date = 0; @@ -186,6 +186,12 @@ main(argc, argv) case 'b': /* blocks per tape write */ ntrec = numarg("number of blocks per write", 1L, 1000L); + if (ntrec > maxbsize/1024) { + msg("Please choose a blocksize <= %dKB\n", + maxbsize/1024); + exit(X_STARTUP); + } + bflag = 1; break; case 'c': /* Tape is cart. not 9-track */ @@ -246,11 +252,9 @@ main(argc, argv) } Tflag = 1; lastlevel = '?'; - argc--; - argv++; break; - case 'u': /* update /etc/dumpdates */ + case 'u': /* update dumpdates */ uflag = 1; break; @@ -348,8 +352,7 @@ main(argc, argv) * the special name missing the leading '/', * the file system name with or without the leading '/'. */ - dt = fstabsearch(disk); - if (dt != NULL) { + if ((dt = fstabsearch(disk)) != NULL) { disk = rawname(dt->fs_spec); (void)strncpy(spcl.c_dev, dt->fs_spec, NAMELEN); (void)strncpy(spcl.c_filesys, dt->fs_file, NAMELEN); @@ -391,7 +394,7 @@ main(argc, argv) spcl.c_level = level - '0'; spcl.c_type = TS_TAPE; if (!Tflag) - getdumptime(); /* /etc/dumpdates snarfed */ + getdumptime(); /* dumpdates snarfed */ msg("Date of this level %c dump: %s", level, #ifdef __linux @@ -474,6 +477,10 @@ main(argc, argv) nonodump = spcl.c_level < honorlevel; +#if defined(SIGINFO) + (void)signal(SIGINFO, statussig); +#endif + msg("mapping (Pass I) [regular files]\n"); #ifdef __linux__ if (directory[0] == 0) @@ -606,26 +613,38 @@ main(argc, argv) tend_writing - tstart_writing, spcl.c_tapea / (tend_writing - tstart_writing)); + tnow = do_stats(); putdumptime(); +#ifdef __linux__ + msg("DUMP: Date of this level %c dump: %s", level, + spcl.c_date == 0 ? "the epoch\n" : ctime4(&spcl.c_date)); +#else + msg("DUMP: Date of this level %c dump: %s", level, + spcl.c_date == 0 ? "the epoch\n" : ctime(&spcl.c_date)); +#endif + msg("DUMP: Date this dump completed: %s", ctime(&tnow)); + + msg("DUMP: Average transfer rate: %ld KB/s\n", xferrate / tapeno); + trewind(); broadcast("DUMP IS DONE!\7\7\n"); msg("DUMP IS DONE\n"); Exit(X_FINOK); /* NOTREACHED */ - exit(1); /* gcc - shut up */ + return 0; /* gcc - shut up */ } static void -usage() +usage(void) { fprintf(stderr, - "usage: dump [-0123456789ac" + "usage: %s [-0123456789ac" #ifdef KERBEROS "k" #endif "nu] [-B records] [-b blocksize] [-d density] [-f file]\n" " [-h level] [-s feet] [-T date] filesystem\n" - " dump [-W | -w]\n"); + " %s [-W | -w]\n", __progname, __progname); exit(X_STARTUP); } @@ -634,24 +653,21 @@ usage() * range (except that a vmax of 0 means unlimited). */ static long -numarg(meaning, vmin, vmax) - char *meaning; - long vmin, vmax; +numarg(const char *meaning, long vmin, long vmax) { char *p; long val; val = strtol(optarg, &p, 10); if (*p) - errx(1, "illegal %s -- %s", meaning, optarg); + errx(X_STARTUP, "illegal %s -- %s", meaning, optarg); if (val < vmin || (vmax && val > vmax)) - errx(1, "%s must be between %ld and %ld", meaning, vmin, vmax); + errx(X_STARTUP, "%s must be between %ld and %ld", meaning, vmin, vmax); return (val); } void -sig(signo) - int signo; +sig(int signo) { switch(signo) { case SIGALRM: @@ -677,8 +693,7 @@ sig(signo) } char * -rawname(cp) - char *cp; +rawname(char *cp) { #ifdef __linux__ return cp; @@ -704,9 +719,7 @@ rawname(cp) * getopt(3) will like. */ static void -obsolete(argcp, argvp) - int *argcp; - char **argvp[]; +obsolete(int *argcp, char **argvp[]) { int argc, flags; char *ap, **argv, *flagsp=NULL, **nargv, *p=NULL; @@ -723,7 +736,7 @@ obsolete(argcp, argvp) /* Allocate space for new arguments. */ if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL || (p = flagsp = malloc(strlen(ap) + 2)) == NULL) - err(1, NULL); + err(X_STARTUP, "malloc new args"); *nargv++ = *argv; argv += 2; @@ -742,7 +755,7 @@ obsolete(argcp, argvp) usage(); } if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL) - err(1, NULL); + err(X_STARTUP, "malloc arg"); nargv[0][0] = '-'; nargv[0][1] = *ap; (void)strcpy(&nargv[0][2], *argv); diff --git a/dump/optr.c b/dump/optr.c index c1ba8a9..96b829a 100644 --- a/dump/optr.c +++ b/dump/optr.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)optr.c 8.2 (Berkeley) 1/6/94"; #endif static const char rcsid[] = - "$Id: optr.c,v 1.2 1999/10/11 12:53:22 stelian Exp $"; + "$Id: optr.c,v 1.3 1999/10/11 12:59:19 stelian Exp $"; #endif /* not lint */ #include @@ -71,9 +71,9 @@ static const char rcsid[] = #include "dump.h" #include "pathnames.h" -void alarmcatch __P((/* int, int */)); +static void alarmcatch __P((int)); int datesort __P((const void *, const void *)); -static void sendmes __P((char *, char *)); +static void sendmes __P((const char *, const char *)); /* * Query the operator; This previously-fascist piece of code @@ -87,21 +87,23 @@ static void sendmes __P((char *, char *)); * that dump needs attention. */ static int timeout; -static char *attnmessage; /* attention message */ +static const char *attnmessage; /* attention message */ int -query(question) - char *question; +query(const char *question) { char replybuffer[64]; int back, errcount; FILE *mytty; + time_t firstprompt, when_answered; + + firstprompt = time(NULL); if ((mytty = fopen(_PATH_TTY, "r")) == NULL) quit("fopen on %s fails: %s\n", _PATH_TTY, strerror(errno)); attnmessage = question; timeout = 0; - alarmcatch(); + alarmcatch(0); back = -1; errcount = 0; do { @@ -128,18 +130,26 @@ query(question) if (signal(SIGALRM, sig) == SIG_IGN) signal(SIGALRM, SIG_IGN); (void) fclose(mytty); + when_answered = time(NULL); + /* + * Adjust the base for time estimates to ignore time we spent waiting + * for operator input. + */ + if (tstart_writing != 0) + tstart_writing += (when_answered - firstprompt); return(back); } -char lastmsg[100]; +char lastmsg[BUFSIZ]; /* * Alert the console operator, and enable the alarm clock to * sleep for 2 minutes in case nobody comes to satisfy dump */ -void -alarmcatch() +static void +alarmcatch(int signo) { + int save_errno = errno; if (notify == 0) { if (timeout == 0) (void) fprintf(stderr, @@ -158,14 +168,14 @@ alarmcatch() signal(SIGALRM, alarmcatch); (void) alarm(120); timeout = 1; + errno = save_errno; } /* * Here if an inquisitive operator interrupts the dump program */ void -interrupt(signo) - int signo; +interrupt(int signo) { msg("Interrupt received.\n"); if (query("Do you want to abort dump?")) @@ -183,7 +193,7 @@ struct group *gp; * Get the names from the group entry "operator" to notify. */ void -set_operators() +set_operators(void) { if (!notify) /*not going to notify*/ return; @@ -203,8 +213,7 @@ struct tm *localclock; * that the process control groups are not messed up */ void -broadcast(message) - char *message; +broadcast(const char *message) { time_t clock; FILE *f_utmp; @@ -259,11 +268,10 @@ broadcast(message) } static void -sendmes(tty, message) - char *tty, *message; +sendmes(const char *tty, const char *message) { char t[MAXPATHLEN], buf[BUFSIZ]; - register char *cp; + register const char *cp; int lmsg = 1; FILE *f_tty; @@ -281,7 +289,7 @@ DUMP: NEEDS ATTENTION: ", if (*cp == '\0') { if (lmsg) { cp = message; - if (*cp == '\0') + if (!(cp && *cp != '\0')) break; lmsg = 0; } else @@ -302,7 +310,7 @@ DUMP: NEEDS ATTENTION: ", time_t tschedule = 0; void -timeest() +timeest(void) { time_t tnow, deltat; @@ -321,7 +329,7 @@ timeest() } void -#if __STDC__ +#ifdef __STDC__ msg(const char *fmt, ...) #else msg(fmt, va_alist) @@ -335,7 +343,7 @@ msg(fmt, va_alist) #ifdef TDEBUG (void) fprintf(stderr, "pid=%d ", getpid()); #endif -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); @@ -343,12 +351,12 @@ msg(fmt, va_alist) (void) vfprintf(stderr, fmt, ap); (void) fflush(stdout); (void) fflush(stderr); - (void) vsprintf(lastmsg, fmt, ap); + (void) vsnprintf(lastmsg, sizeof(lastmsg), fmt, ap); va_end(ap); } void -#if __STDC__ +#ifdef __STDC__ msgtail(const char *fmt, ...) #else msgtail(fmt, va_alist) @@ -357,7 +365,7 @@ msgtail(fmt, va_alist) #endif { va_list ap; -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); @@ -367,7 +375,7 @@ msgtail(fmt, va_alist) } void -#if __STDC__ +#ifdef __STDC__ quit(const char *fmt, ...) #else quit(fmt, va_alist) @@ -381,7 +389,7 @@ quit(fmt, va_alist) #ifdef TDEBUG (void) fprintf(stderr, "pid=%d ", getpid()); #endif -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); @@ -398,9 +406,8 @@ quit(fmt, va_alist) * we don't actually do it */ -struct fstab * -allocfsent(fs) - register struct fstab *fs; +static struct fstab * +allocfsent(struct fstab *fs) { register struct fstab *new; @@ -423,7 +430,7 @@ struct pfstab { static struct pfstab *table; void -getfstab() +getfstab(void) { register struct fstab *fs; register struct pfstab *pf; @@ -460,8 +467,7 @@ getfstab() * The file name can omit the leading '/'. */ struct fstab * -fstabsearch(key) - char *key; +fstabsearch(const char *key) { register struct pfstab *pf; register struct fstab *fs; @@ -489,9 +495,7 @@ fstabsearch(key) #ifdef __linux__ struct fstab * -fstabsearchdir(key, directory) - char *key; - char *directory; +fstabsearchdir(const char *key, char *directory) { register struct pfstab *pf; register struct fstab *fs; @@ -526,8 +530,7 @@ fstabsearchdir(key, directory) * Tell the operator what to do */ void -lastdump(arg) - char arg; /* w ==> just what to do; W ==> most recent dumps */ +lastdump(char arg) /* w ==> just what to do; W ==> most recent dumps */ { register int i; register struct fstab *dt; @@ -569,8 +572,7 @@ lastdump(arg) } int -datesort(a1, a2) - const void *a1, *a2; +datesort(const void *a1, const void *a2) { struct dumpdates *d1 = *(struct dumpdates **)a1; struct dumpdates *d2 = *(struct dumpdates **)a2; diff --git a/dump/tape.c b/dump/tape.c index 9d57ddf..b48665e 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)tape.c 8.4 (Berkeley) 5/1/95"; #endif static const char rcsid[] = - "$Id: tape.c,v 1.2 1999/10/11 12:53:22 stelian Exp $"; + "$Id: tape.c,v 1.3 1999/10/11 12:59:19 stelian Exp $"; #endif /* not lint */ #ifdef __linux__ @@ -100,7 +100,8 @@ extern int cartridge; extern char *host; char *nexttape; -static int atomic __P((ssize_t (*)(), int, char *, int)); +static ssize_t atomic_read __P((int, void *, size_t)); +static ssize_t atomic_write __P((int, const void *, size_t)); static void doslave __P((int, int)); static void enslave __P((void)); static void flushtape __P((void)); @@ -138,16 +139,19 @@ struct slave *slp; char (*nextblock)[TP_BSIZE]; +static time_t tstart_volume; /* time of volume start */ +static int tapea_volume; /* value of spcl.c_tapea at volume start */ + int master; /* pid of master, for sending error signals */ int tenths; /* length of tape used per block written */ static int caught; /* have we caught the signal to proceed? */ static int ready; /* have we reached the lock point without having */ /* received the SIGUSR2 signal from the prev slave? */ -static jmp_buf jmpbuf; /* where to jump to if we are ready when the */ +static sigjmp_buf jmpbuf; /* where to jump to if we are ready when the */ /* SIGUSR2 arrives from the previous slave */ int -alloctape() +alloctape(void) { int pgoff = getpagesize() - 1; char *buf; @@ -191,14 +195,14 @@ alloctape() } void -writerec(dp, isspcl) - char *dp; - int isspcl; +writerec(const void *dp, int isspcl) { slp->req[trecno].dblk = (daddr_t)0; slp->req[trecno].count = 1; - *(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)dp; + /* XXX post increment triggers an egcs-1.1.2-12 bug on alpha/sparc */ + *(union u_spcl *)(*(nextblock)) = *(union u_spcl *)dp; + nextblock++; if (isspcl) lastspclrec = spcl.c_tapea; trecno++; @@ -208,9 +212,7 @@ writerec(dp, isspcl) } void -dumpblock(blkno, size) - daddr_t blkno; - int size; +dumpblock(daddr_t blkno, int size) { int avail, tpblks, dblkno; @@ -230,9 +232,8 @@ dumpblock(blkno, size) int nogripe = 0; -void -tperror(signo) - int signo; +static void +tperror(int signo) { if (pipeout) { @@ -252,16 +253,67 @@ tperror(signo) Exit(X_REWRITE); } -void -sigpipe(signo) - int signo; +static void +sigpipe(int signo) { quit("Broken pipe\n"); } +/* + * do_stats -- + * Update xferrate stats + */ +time_t +do_stats(void) +{ + time_t tnow, ttaken; + int blocks; + + (void)time(&tnow); + ttaken = tnow - tstart_volume; + blocks = spcl.c_tapea - tapea_volume; + msg("Volume %d completed at: %s", tapeno, ctime(&tnow)); + if (ttaken > 0) { + msg("Volume %d took %d:%02d:%02d\n", tapeno, + ttaken / 3600, (ttaken % 3600) / 60, ttaken % 60); + msg("Volume %d transfer rate: %ld KB/s\n", tapeno, + blocks / ttaken); + xferrate += blocks / ttaken; + } + return(tnow); +} + +#if defined(SIGINFO) +/* + * statussig -- + * information message upon receipt of SIGINFO + * (derived from optr.c::timeest()) + */ +void +statussig(int notused) +{ + time_t tnow, deltat; + char msgbuf[128]; + int save_errno = errno; + + if (blockswritten < 500) + return; + (void) time((time_t *) &tnow); + deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing)) + / blockswritten * tapesize; + (void)snprintf(msgbuf, sizeof(msgbuf), + "%3.2f%% done at %ld KB/s, finished in %d:%02d\n", + (blockswritten * 100.0) / tapesize, + (spcl.c_tapea - tapea_volume) / (tnow - tstart_volume), + (int)(deltat / 3600), (int)((deltat % 3600) / 60)); + write(STDERR_FILENO, msgbuf, strlen(msgbuf)); + errno = save_errno; +} +#endif + static void -flushtape() +flushtape(void) { int i, blks, got; long lastfirstrec; @@ -270,7 +322,7 @@ flushtape() slp->req[trecno].count = 0; /* Sentinel */ - if (atomic(write, slp->fd, (char *)slp->req, siz) != siz) + if (atomic_write( slp->fd, (char *)slp->req, siz) != siz) quit("error writing command pipe: %s\n", strerror(errno)); slp->sent = 1; /* we sent a request, read the response later */ @@ -281,7 +333,7 @@ flushtape() /* Read results back from next slave */ if (slp->sent) { - if (atomic(read, slp->fd, (char *)&got, sizeof got) + if (atomic_read( slp->fd, (char *)&got, sizeof got) != sizeof got) { perror(" DUMP: error reading command pipe in master"); dumpabort(0); @@ -298,7 +350,7 @@ flushtape() */ for (i = 0; i < SLAVES; i++) { if (slaves[i].sent) { - if (atomic(read, slaves[i].fd, + if (atomic_read( slaves[i].fd, (char *)&got, sizeof got) != sizeof got) { perror(" DUMP: error reading command pipe in master"); @@ -338,7 +390,7 @@ flushtape() } void -trewind() +trewind(void) { int f; int got; @@ -353,7 +405,7 @@ trewind() * fixme: punt for now. */ if (slaves[f].sent) { - if (atomic(read, slaves[f].fd, (char *)&got, sizeof got) + if (atomic_read( slaves[f].fd, (char *)&got, sizeof got) != sizeof got) { perror(" DUMP: error reading command pipe in master"); dumpabort(0); @@ -391,11 +443,12 @@ trewind() } void -close_rewind() +close_rewind(void) { time_t tstart_changevol, tend_changevol; trewind(); + (void)do_stats(); if (nexttape) return; #ifdef __linux__ @@ -422,7 +475,7 @@ close_rewind() } void -rollforward() +rollforward(void) { register struct req *p, *q, *prev; register struct slave *tslp; @@ -478,7 +531,7 @@ rollforward() lastspclrec = savedtapea - 1; } size = (char *)ntb - (char *)q; - if (atomic(write, slp->fd, (char *)q, size) != size) { + if (atomic_write( slp->fd, (char *)q, size) != size) { perror(" DUMP: error writing command pipe"); dumpabort(0); } @@ -525,7 +578,7 @@ rollforward() * worked ok, otherwise the tape is much too short! */ if (slp->sent) { - if (atomic(read, slp->fd, (char *)&got, sizeof got) + if (atomic_read( slp->fd, (char *)&got, sizeof got) != sizeof got) { perror(" DUMP: error reading command pipe in master"); dumpabort(0); @@ -564,8 +617,7 @@ rollforward() * everything continues as if nothing had happened. */ void -startnewtape(top) - int top; +startnewtape(int top) { int parentpid; int childpid; @@ -573,7 +625,7 @@ startnewtape(top) int waitpid; char *p; #ifdef __linux__ - void (*interrupt_save)(); + void (*interrupt_save) __P((int signo)); #else /* __linux__ */ #ifdef sunos void (*interrupt_save)(); @@ -584,6 +636,8 @@ startnewtape(top) interrupt_save = signal(SIGINT, SIG_IGN); parentpid = getpid(); + tapea_volume = spcl.c_tapea; + (void)time(&tstart_volume); restore_check_point: (void)signal(SIGINT, interrupt_save); @@ -696,6 +750,7 @@ restore_check_point: spcl.c_flags |= DR_NEWHEADER; writeheader((ino_t)slp->inode); spcl.c_flags &=~ DR_NEWHEADER; + msg("Volume %d started at: %s", tapeno, ctime(&tstart_volume)); if (tapeno > 1) msg("Volume %d begins with blocks from inode %d\n", tapeno, slp->inode); @@ -703,8 +758,7 @@ restore_check_point: } void -dumpabort(signo) - int signo; +dumpabort(int signo) { if (master != 0 && master != getpid()) @@ -721,8 +775,7 @@ dumpabort(signo) } void -Exit(status) - int status; +Exit(int status) { #ifdef TDEBUG @@ -734,18 +787,17 @@ Exit(status) /* * proceed - handler for SIGUSR2, used to synchronize IO between the slaves. */ -void -proceed(signo) - int signo; +static void +proceed(int signo) { if (ready) - longjmp(jmpbuf, 1); + siglongjmp(jmpbuf, 1); caught++; } void -enslave() +enslave(void) { int cmd[2]; #ifdef LINUX_FORK_BUG @@ -779,8 +831,12 @@ enslave() for (j = 0; j <= i; j++) (void) close(slaves[j].fd); signal(SIGINT, SIG_IGN); /* Master handles this */ +#if defined(SIGINFO) + signal(SIGINFO, SIG_IGN); +#endif + #ifdef LINUX_FORK_BUG - if (atomic(write, cmd[0], (char *) &i, sizeof i) + if (atomic_write( cmd[0], (char *) &i, sizeof i) != sizeof i) quit("master/slave protocol botched 3\n"); #endif @@ -796,12 +852,12 @@ enslave() * returned from fork() causes a SEGV in the child process */ for (i = 0; i < SLAVES; i++) - if (atomic(read, slaves[i].fd, (char *) &j, sizeof j) != sizeof j) + if (atomic_read( slaves[i].fd, (char *) &j, sizeof j) != sizeof j) quit("master/slave protocol botched 4\n"); #endif for (i = 0; i < SLAVES; i++) - (void) atomic(write, slaves[i].fd, + (void) atomic_write( slaves[i].fd, (char *) &slaves[(i + 1) % SLAVES].pid, sizeof slaves[0].pid); @@ -809,7 +865,7 @@ enslave() } void -killall() +killall(void) { register int i; @@ -828,12 +884,12 @@ killall() * get the lock back for the next cycle by swapping descriptors. */ static void -doslave(cmd, slave_number) - register int cmd; - int slave_number; +doslave(int cmd, int slave_number) { register int nread; - int nextslave, size, wrote, eot_count; + int nextslave, size, eot_count; + volatile int wrote = 0; + sigset_t sigset; #ifdef __linux__ errcode_t retval; #endif @@ -854,7 +910,7 @@ doslave(cmd, slave_number) /* * Need the pid of the next slave in the loop... */ - if ((nread = atomic(read, cmd, (char *)&nextslave, sizeof nextslave)) + if ((nread = atomic_read( cmd, (char *)&nextslave, sizeof nextslave)) != sizeof nextslave) { quit("master/slave protocol botched - didn't get pid of next slave.\n"); } @@ -862,7 +918,7 @@ doslave(cmd, slave_number) /* * Get list of blocks to dump, read the blocks into tape buffer */ - while ((nread = atomic(read, cmd, (char *)slp->req, reqsiz)) == reqsiz) { + while ((nread = atomic_read( cmd, (char *)slp->req, reqsiz)) == reqsiz) { register struct req *p = slp->req; for (trecno = 0; trecno < ntrec; @@ -871,7 +927,7 @@ doslave(cmd, slave_number) bread(p->dblk, slp->tblock[trecno], p->count * TP_BSIZE); } else { - if (p->count != 1 || atomic(read, cmd, + if (p->count != 1 || atomic_read( cmd, (char *)slp->tblock[trecno], TP_BSIZE) != TP_BSIZE) quit("master/slave protocol botched.\n"); @@ -928,14 +984,15 @@ doslave(cmd, slave_number) if (wrote < 0) { (void) kill(master, SIGUSR1); + sigemptyset(&sigset); for (;;) - (void) sigpause(0); + sigsuspend(&sigset); } else { /* * pass size of write back to master * (for EOT handling) */ - (void) atomic(write, cmd, (char *)&size, sizeof size); + (void) atomic_write( cmd, (char *)&size, sizeof size); } /* @@ -953,16 +1010,27 @@ doslave(cmd, slave_number) * or a write may not write all we ask if we get a signal, * loop until the count is satisfied (or error). */ -static int -atomic(func, fd, buf, count) - ssize_t (*func)(); - int fd; - char *buf; - int count; +static ssize_t +atomic_read(int fd, void *buf, size_t count) +{ + int got, need = count; + + while ((got = read(fd, buf, need)) > 0 && (need -= got) > 0) + (char *)buf += got; + return (got < 0 ? got : count - need); +} + +/* + * Since a read from a pipe may not return all we asked for, + * or a write may not write all we ask if we get a signal, + * loop until the count is satisfied (or error). + */ +static ssize_t +atomic_write(int fd, const void *buf, size_t count) { int got, need = count; - while ((got = (*func)(fd, buf, need)) > 0 && (need -= got) > 0) - buf += got; + while ((got = write(fd, buf, need)) > 0 && (need -= got) > 0) + (char *)buf += got; return (got < 0 ? got : count - need); } diff --git a/dump/traverse.c b/dump/traverse.c index 2928884..59ce524 100644 --- a/dump/traverse.c +++ b/dump/traverse.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)traverse.c 8.7 (Berkeley) 6/15/95"; #endif static const char rcsid[] = - "$Id: traverse.c,v 1.2 1999/10/11 12:53:22 stelian Exp $"; + "$Id: traverse.c,v 1.3 1999/10/11 12:59:19 stelian Exp $"; #endif /* not lint */ #include @@ -52,10 +52,11 @@ static const char rcsid[] = #ifdef __linux__ #include #include -#include +#include #include #define swab32(x) ext2fs_swab32(x) #else /* __linux__ */ +#define swab32(x) x #ifdef sunos #include @@ -96,7 +97,7 @@ typedef long fsizeT; #ifdef __linux__ static int searchdir __P((struct ext2_dir_entry *dp, int offset, int blocksize, char *buf, void *private)); -long long llseek(int fildes, long long offset, int whence); +loff_t llseek (int fd, loff_t offset, int origin); #else static int dirindir __P((ino_t ino, daddr_t blkno, int level, long *size)); static void dmpindir __P((ino_t ino, daddr_t blk, int level, fsizeT *size)); @@ -111,8 +112,7 @@ static int searchdir __P((ino_t ino, daddr_t blkno, long size, long filesize)); * hence the estimate may be high. */ long -blockest(dp) - register struct dinode *dp; +blockest(struct dinode *dp) { long blkest, sizeest; @@ -173,9 +173,7 @@ blockest(dp) * the directories in the filesystem. */ int -mapfiles(maxino, tapesize) - ino_t maxino; - long *tapesize; +mapfiles(ino_t maxino, long *tapesize) { register int mode; register ino_t ino; @@ -219,12 +217,7 @@ struct mapfile_context { }; static int -mapfilesindir(dirent, offset, blocksize, buf, private) - struct ext2_dir_entry *dirent; - int offset; - int blocksize; - char *buf; - void *private; +mapfilesindir(struct ext2_dir_entry *dirent, int offset, int blocksize, char *buf, void *private) { register struct dinode *dp; register int mode; @@ -270,10 +263,7 @@ mapfilesindir(dirent, offset, blocksize, buf, private) * the directories in the filesystem. */ int -mapfilesfromdir(maxino, tapesize, directory) - ino_t maxino; - long *tapesize; - char *directory; +mapfilesfromdir(ino_t maxino, long *tapesize, char *directory) { errcode_t retval; struct mapfile_context mfc; @@ -342,9 +332,7 @@ mapfilesfromdir(maxino, tapesize, directory) * pass using this algorithm. */ int -mapdirs(maxino, tapesize) - ino_t maxino; - long *tapesize; +mapdirs(ino_t maxino, long *tapesize) { register struct dinode *dp; register int isdir; @@ -409,11 +397,7 @@ mapdirs(maxino, tapesize) * require the directory to be dumped. */ static int -dirindir(ino, blkno, ind_level, filesize) - ino_t ino; - daddr_t blkno; - int ind_level; - long *filesize; +dirindir(ino_t ino, daddr_t blkno, int ind_level, long *filesize) { int ret = 0; register int i; @@ -450,12 +434,7 @@ dirindir(ino, blkno, ind_level, filesize) */ #ifdef __linux__ static int -searchdir(dp, offset, blocksize, buf, private) - struct ext2_dir_entry *dp; - int offset; - int blocksize; - char *buf; - void *private; +searchdir(struct ext2_dir_entry *dp, int offset, int blocksize, char *buf, void *private) { int *ret = (int *) private; @@ -483,11 +462,7 @@ searchdir(dp, offset, blocksize, buf, private) #else /* __linux__ */ static int -searchdir(ino, blkno, size, filesize) - ino_t ino; - daddr_t blkno; - register long size; - long filesize; +searchdir(ino_t ino, daddr_t blkno, long size, long filesize) { register struct direct *dp; register long loc, ret = 0; @@ -571,9 +546,7 @@ dumponeblock(ext2_filsys fs, blk_t *blocknr, int blockcnt, void *private) * Dump the contents of an inode to tape. */ void -dumpino(dp, ino) - register struct dinode *dp; - ino_t ino; +dumpino(struct dinode *dp, ino_t ino) { int cnt; fsizeT size; @@ -605,7 +578,7 @@ dumpino(dp, ino) obi.di_gen = dp->di_gen; memmove(&obi.di_db, &dp->di_db, (NDADDR + NIADDR) * sizeof(daddr_t)); if (dp->di_file_acl || dp->di_dir_acl) - warn("ACLs in inode #%d won't be dumped", ino); + warn("ACLs in inode #%ld won't be dumped", ino); memmove(&spcl.c_dinode, &obi, sizeof(obi)); #else /* __linux__ */ spcl.c_dinode = *dp; @@ -722,12 +695,7 @@ struct convert_dir_context { * size of the entry, and creates it in a temporary buffer */ static int -convert_dir(dirent, offset, blocksize, buf, private) - struct ext2_dir_entry *dirent; - int offset; - int blocksize; - char *buf; - void *private; +convert_dir(struct ext2_dir_entry *dirent, int offset, int blocksize, char *buf, void *private) { struct convert_dir_context *p; struct direct *dp; @@ -761,9 +729,7 @@ convert_dir(dirent, offset, blocksize, buf, private) * Dumps a directory to tape after converting it to the BSD format */ void -dumpdirino(dp, ino) - register struct dinode *dp; - ino_t ino; +dumpdirino(struct dinode *dp, ino_t ino) { fsizeT size; char buf[TP_BSIZE]; @@ -786,8 +752,8 @@ dumpdirino(dp, ino) ext2fs directory to avoid problems ;-) */ cdc.buf = (char *)malloc(dp->di_size * 2 * sizeof(char)); if (cdc.buf == NULL) - err(1, "Cannot allocate buffer to convert directory #%ld\n", - ino); + err(1, "Cannot allocate buffer to convert directory #%lu\n", + (unsigned long)ino); cdc.offset = 0; cdc.prev_offset = 0; cdc.bs = MIN(DIRBLKSIZ, TP_BSIZE); @@ -821,7 +787,7 @@ dumpdirino(dp, ino) obi.di_gen = dp->di_gen; memmove(&obi.di_db, &dp->di_db, (NDADDR + NIADDR) * sizeof(daddr_t)); if (dp->di_file_acl || dp->di_dir_acl) - warn("ACLs in inode #%d won't be dumped", ino); + warn("ACLs in inode #%ld won't be dumped", ino); memmove(&spcl.c_dinode, &obi, sizeof(obi)); #else /* __linux__ */ spcl.c_dinode = *dp; @@ -866,11 +832,7 @@ dumpdirino(dp, ino) * Read indirect blocks, and pass the data blocks to be dumped. */ static void -dmpindir(ino, blk, ind_level, size) - ino_t ino; - daddr_t blk; - int ind_level; - fsizeT *size; +dmpindir(ino_t ino, daddr_t blk, int ind_level, fsizeT *size) { int i, cnt; #ifdef __linux__ @@ -926,10 +888,7 @@ dmpindir(ino, blk, ind_level, size) * Collect up the data into tape record sized buffers and output them. */ void -blksout(blkp, frags, ino) - daddr_t *blkp; - int frags; - ino_t ino; +blksout(daddr_t *blkp, int frags, ino_t ino) { register daddr_t *bp; int i, j, count, blks, tbperdb; @@ -949,12 +908,14 @@ blksout(blkp, frags, ino) spcl.c_count = count - i; writeheader(ino); bp = &blkp[i / tbperdb]; - for (j = i; j < count; j += tbperdb, bp++) - if (*bp != 0) + for (j = i; j < count; j += tbperdb, bp++) { + if (*bp != 0) { if (j + tbperdb <= count) dumpblock(*bp, (int)sblock->fs_bsize); else dumpblock(*bp, (count - j) * TP_BSIZE); + } + } spcl.c_type = TS_ADDR; } } @@ -963,10 +924,7 @@ blksout(blkp, frags, ino) * Dump a map to the tape. */ void -dumpmap(map, type, ino) - char *map; - int type; - ino_t ino; +dumpmap(char *map, int type, ino_t ino) { register int i; char *cp; @@ -982,8 +940,7 @@ dumpmap(map, type, ino) * Write a header record to the dump tape. */ void -writeheader(ino) - ino_t ino; +writeheader(ino_t ino) { #ifdef __linux__ register __s32 sum, cnt, *lp; @@ -1017,8 +974,7 @@ writeheader(ino) #ifdef __linux__ struct dinode * -getino(inum) - ino_t inum; +getino(ino_t inum) { static struct dinode dinode; @@ -1028,8 +984,7 @@ getino(inum) } #else /* __linux__ */ struct dinode * -getino(inum) - ino_t inum; +getino(ino_t inum) { static daddr_t minino, maxino; static struct dinode inoblock[MAXINOPB]; @@ -1055,10 +1010,7 @@ int breaderrors = 0; #define BREADEMAX 32 void -bread(blkno, buf, size) - daddr_t blkno; - char *buf; - int size; +bread(daddr_t blkno, char *buf, int size) { int cnt, i; extern int errno; diff --git a/dump/unctime.c b/dump/unctime.c index d821b78..bd72453 100644 --- a/dump/unctime.c +++ b/dump/unctime.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)unctime.c 8.2 (Berkeley) 6/14/94"; #endif static const char rcsid[] = - "$Id: unctime.c,v 1.2 1999/10/11 12:53:23 stelian Exp $"; + "$Id: unctime.c,v 1.3 1999/10/11 12:59:19 stelian Exp $"; #endif /* not lint */ #include @@ -53,6 +53,17 @@ static const char rcsid[] = #include #endif +#include +#include + +#ifdef __linux__ +#include +#include +#include +#endif + +#include "dump.h" + /* * Convert a ctime(3) format string into a system format date. * Return the date thus calculated. @@ -71,12 +82,11 @@ static const char rcsid[] = #define E_SECOND 17 #define E_YEAR 20 -static int lookup __P((char *)); +static int lookup __P((const char *)); time_t -unctime(str) - char *str; +unctime(const char *str) { struct tm then; char dbuf[26]; @@ -99,10 +109,9 @@ static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; static int -lookup(str) - char *str; +lookup(const char *str) { - register char *cp, *cp2; + register const char *cp, *cp2; for (cp = months, cp2 = str; *cp != '\0'; cp += 3) if (strncmp(cp, cp2, 3) == 0) diff --git a/restore/Makefile.in b/restore/Makefile.in index dff9e1f..e032d18 100644 --- a/restore/Makefile.in +++ b/restore/Makefile.in @@ -3,7 +3,7 @@ srcdir= @srcdir@ @MCONFIG@ -CFLAGS= @CCOPTS@ -pipe $(DEFS) $(GINC) $(INC) @RESTOREDEBUG@ +CFLAGS= @CCOPTS@ -pipe $(OPT) $(DEFS) $(GINC) $(INC) @RESTOREDEBUG@ LDFLAGS:= $(LDFLAGS) @STATIC@ LIBS= $(GLIBS) -le2p DEPLIBS= ../compat/lib/libcompat.a @@ -15,7 +15,7 @@ SRCS= dirs.c interactive.c main.c restore.c symtab.c tape.c \ OBJS= dirs.o interactive.o main.o restore.o symtab.o tape.o \ utilities.o ../common/dumprmt.o MAN8= restore.8 -MLINKS= $(MANDIR)/restore.8 $(MANDIR)/rrestore.8 +MLINKS= restore.8 $(MANDIR)/rrestore.8 all:: $(PROG) diff --git a/restore/dirs.c b/restore/dirs.c index 9b564c2..30cec66 100644 --- a/restore/dirs.c +++ b/restore/dirs.c @@ -49,7 +49,7 @@ static char sccsid[] = "@(#)dirs.c 8.7 (Berkeley) 5/1/95"; #endif static const char rcsid[] = - "$Id: dirs.c,v 1.2 1999/10/11 12:53:23 stelian Exp $"; + "$Id: dirs.c,v 1.3 1999/10/11 12:59:19 stelian Exp $"; #endif /* not lint */ #include @@ -65,7 +65,7 @@ static const char rcsid[] = #endif /* __linux__ */ #include -#include +#include #include #include #include @@ -104,7 +104,7 @@ struct modeinfo { mode_t mode; uid_t uid; gid_t gid; - int flags; + unsigned int flags; }; /* @@ -147,7 +147,7 @@ static void dcvt __P((struct odirect *, struct direct *)); static void flushent __P((void)); static struct inotab *inotablookup __P((ino_t)); static RST_DIR *opendirfile __P((const char *)); -static void putdir __P((char *, long)); +static void putdir __P((char *, size_t)); static void putent __P((struct direct *)); static void rst_seekdir __P((RST_DIR *, long, long)); static long rst_telldir __P((RST_DIR *)); @@ -160,8 +160,7 @@ static struct direct *searchdir __P((ino_t, char *)); * directories on the tape. */ void -extractdirs(genmode) - int genmode; +extractdirs(int genmode) { register int i; #ifdef __linux__ @@ -173,37 +172,39 @@ extractdirs(genmode) struct direct nulldir; int fd; - vprintf(stdout, "Extract directories from tape\n"); - (void) sprintf(dirfile, "%s/rstdir%ld", tmpdir, dumpdate); + Vprintf(stdout, "Extract directories from tape\n"); + (void) snprintf(dirfile, sizeof(dirfile), "%s/rstdir%ld", tmpdir, + (long)dumpdate); if (command != 'r' && command != 'R') { - (void *) strcat(dirfile, "-XXXXXX"); + (void) strncat(dirfile, "-XXXXXX", + sizeof(dirfile) - strlen(dirfile)); fd = mkstemp(dirfile); } else fd = open(dirfile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (df = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); - warn("%s - cannot create directory temporary\nfopen", dirfile); - done(1); + err(1, "cannot create directory temporary %s", dirfile); } if (genmode != 0) { - (void) sprintf(modefile, "%s/rstmode%ld", tmpdir, dumpdate); + (void) snprintf(modefile, sizeof(modefile), "%s/rstmode%ld", tmpdir, (long)dumpdate); if (command != 'r' && command != 'R') { - (void *) strcat(modefile, "-XXXXXX"); + (void) strncat(modefile, "-XXXXXX", + sizeof(modefile) - strlen(modefile)); fd = mkstemp(modefile); } else fd = open(modefile, O_RDWR|O_CREAT|O_EXCL, 0666); if (fd == -1 || (mf = fdopen(fd, "w")) == NULL) { if (fd != -1) close(fd); - warn("%s - cannot create modefile\nfopen", modefile); - done(1); + err(1, "cannot create modefile %s", modefile); } } nulldir.d_ino = 0; nulldir.d_type = DT_DIR; nulldir.d_namlen = 1; - (void) strcpy(nulldir.d_name, "/"); + nulldir.d_name[0] = '/'; + nulldir.d_name[1] = '\0'; nulldir.d_reclen = DIRSIZ(0, &nulldir); for (;;) { curfile.name = ""; @@ -213,8 +214,7 @@ extractdirs(genmode) (void) fclose(df); dirp = opendirfile(dirfile); if (dirp == NULL) - fprintf(stderr, "opendirfile: %s\n", - strerror(errno)); + warn("opendirfile"); if (mf != NULL) (void) fclose(mf); i = dirlookup(dot); @@ -234,7 +234,7 @@ extractdirs(genmode) * skip over all the directories on the tape */ void -skipdirs() +skipdirs(void) { while (curfile.dip && (curfile.dip->di_mode & IFMT) == IFDIR) { @@ -247,10 +247,7 @@ skipdirs() * pname and pass them off to be processed. */ void -treescan(pname, ino, todo) - char *pname; - ino_t ino; - long (*todo) __P((char *, ino_t, int)); +treescan(char *pname, ino_t ino, long (*todo) __P((char *, ino_t, int))) { register struct inotab *itp; register struct direct *dp; @@ -275,10 +272,9 @@ treescan(pname, ino, todo) * begin search through the directory * skipping over "." and ".." */ - (void) strncpy(locname, pname, sizeof(locname) - 1); - locname[sizeof(locname) - 1] = '\0'; - (void) strncat(locname, "/", sizeof(locname) - strlen(locname)); - namelen = strlen(locname); + namelen = snprintf(locname, sizeof(locname), "%s/", pname); + if (namelen >= sizeof(locname)) + namelen = sizeof(locname) - 1; rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); dp = rst_readdir(dirp); /* "." */ if (dp != NULL && strcmp(dp->d_name, ".") == 0) @@ -298,8 +294,8 @@ treescan(pname, ino, todo) while (dp != NULL) { locname[namelen] = '\0'; if (namelen + dp->d_namlen >= sizeof(locname)) { - fprintf(stderr, "%s%s: name exceeds %d char\n", - locname, dp->d_name, sizeof(locname) - 1); + fprintf(stderr, "%s%s: name exceeds %ld char\n", + locname, dp->d_name, (long)sizeof(locname) - 1); } else { (void) strncat(locname, dp->d_name, (int)dp->d_namlen); treescan(locname, dp->d_ino, todo); @@ -314,8 +310,7 @@ treescan(pname, ino, todo) * Lookup a pathname which is always assumed to start from the ROOTINO. */ struct direct * -pathsearch(pathname) - const char *pathname; +pathsearch(const char *pathname) { ino_t ino; struct direct *dp; @@ -327,7 +322,7 @@ pathsearch(pathname) while (*path == '/') path++; dp = NULL; - while ((name = strsep(&path, "/")) != NULL && *name != '\0') { + while ((name = strsep(&path, "/")) != NULL && *name /* != NULL */) { if ((dp = searchdir(ino, name)) == NULL) return (NULL); ino = dp->d_ino; @@ -340,9 +335,7 @@ pathsearch(pathname) * Return its inode number if found, zero if it does not exist. */ static struct direct * -searchdir(inum, name) - ino_t inum; - char *name; +searchdir(ino_t inum, char *name) { register struct direct *dp; register struct inotab *itp; @@ -365,9 +358,7 @@ searchdir(inum, name) * Put the directory entries in the directory file */ static void -putdir(buf, size) - char *buf; - long size; +putdir(char *buf, size_t size) { struct direct cvtbuf; register struct odirect *odp; @@ -390,7 +381,7 @@ putdir(buf, size) dp->d_reclen, dp->d_namlen, dp->d_type); #endif if (Bcvt) - swabst((u_char *)"ls", (u_char *) dp); + swabst((u_char *)"is", (u_char *) dp); if (oldinofmt && dp->d_ino != 0) { #ifdef __linux__ if (Bcvt) @@ -422,19 +413,19 @@ putdir(buf, size) dp->d_reclen > i || dp->d_reclen < DIRSIZ(0, dp) || dp->d_namlen > NAME_MAX) { - vprintf(stdout, "Mangled directory: "); + Vprintf(stdout, "Mangled directory: "); if ((dp->d_reclen & 0x3) != 0) - vprintf(stdout, + Vprintf(stdout, "reclen not multiple of 4 "); if (dp->d_reclen < DIRSIZ(0, dp)) - vprintf(stdout, + Vprintf(stdout, "reclen less than DIRSIZ (%d < %d) ", dp->d_reclen, DIRSIZ(0, dp)); if (dp->d_namlen > NAME_MAX) - vprintf(stdout, + Vprintf(stdout, "reclen name too big (%d > %d) ", dp->d_namlen, NAME_MAX); - vprintf(stdout, "\n"); + Vprintf(stdout, "\n"); loc += i; continue; } @@ -457,8 +448,7 @@ long prev = 0; * add a new directory entry to a file. */ static void -putent(dp) - struct direct *dp; +putent(struct direct *dp) { dp->d_reclen = DIRSIZ(0, dp); if (dirloc + dp->d_reclen > DIRBLKSIZ) { @@ -467,7 +457,7 @@ putent(dp) (void) fwrite(dirbuf, 1, DIRBLKSIZ, df); dirloc = 0; } - memmove(dirbuf + dirloc, dp, (long)dp->d_reclen); + memmove(dirbuf + dirloc, dp, (size_t)dp->d_reclen); prev = dirloc; dirloc += dp->d_reclen; } @@ -476,7 +466,7 @@ putent(dp) * flush out a directory that is finished. */ static void -flushent() +flushent(void) { ((struct direct *)(dirbuf + prev))->d_reclen = DIRBLKSIZ - prev; (void) fwrite(dirbuf, (int)dirloc, 1, df); @@ -485,12 +475,10 @@ flushent() } static void -dcvt(odp, ndp) - register struct odirect *odp; - register struct direct *ndp; +dcvt(struct odirect *odp, struct direct *ndp) { - memset(ndp, 0, (long)(sizeof *ndp)); + memset(ndp, 0, (size_t)(sizeof *ndp)); ndp->d_ino = odp->d_ino; ndp->d_type = DT_UNKNOWN; (void) strncpy(ndp->d_name, odp->d_name, ODIRSIZ); @@ -506,9 +494,7 @@ dcvt(odp, ndp) * the desired seek offset into it. */ static void -rst_seekdir(dirp, loc, base) - register RST_DIR *dirp; - long loc, base; +rst_seekdir(RST_DIR *dirp, long loc, long base) { if (loc == rst_telldir(dirp)) @@ -526,8 +512,7 @@ rst_seekdir(dirp, loc, base) * get next entry in a directory. */ struct direct * -rst_readdir(dirp) - register RST_DIR *dirp; +rst_readdir(RST_DIR *dirp) { register struct direct *dp; @@ -536,7 +521,7 @@ rst_readdir(dirp) dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ); if (dirp->dd_size <= 0) { - dprintf(stderr, "error reading directory\n"); + Dprintf(stderr, "error reading directory\n"); return (NULL); } } @@ -547,7 +532,7 @@ rst_readdir(dirp) dp = (struct direct *)(dirp->dd_buf + dirp->dd_loc); if (dp->d_reclen == 0 || dp->d_reclen > DIRBLKSIZ + 1 - dirp->dd_loc) { - dprintf(stderr, "corrupted directory: bad reclen %d\n", + Dprintf(stderr, "corrupted directory: bad reclen %d\n", dp->d_reclen); return (NULL); } @@ -555,7 +540,7 @@ rst_readdir(dirp) if (dp->d_ino == 0 && strcmp(dp->d_name, "/") == 0) return (NULL); if (dp->d_ino >= maxino) { - dprintf(stderr, "corrupted directory: bad inum %d\n", + Dprintf(stderr, "corrupted directory: bad inum %d\n", dp->d_ino); continue; } @@ -567,8 +552,7 @@ rst_readdir(dirp) * Simulate the opening of a directory */ RST_DIR * -rst_opendir(name) - const char *name; +rst_opendir(const char *name) { struct inotab *itp; RST_DIR *dirp; @@ -587,8 +571,7 @@ rst_opendir(name) * In our case, there is nothing to do when closing a directory. */ void -rst_closedir(dirp) - RST_DIR *dirp; +rst_closedir(RST_DIR *dirp) { (void)close(dirp->dd_fd); @@ -600,8 +583,7 @@ rst_closedir(dirp) * Simulate finding the current offset in the directory. */ static long -rst_telldir(dirp) - RST_DIR *dirp; +rst_telldir(RST_DIR *dirp) { return ((long)lseek(dirp->dd_fd, (off_t)0, SEEK_CUR) - dirp->dd_size + dirp->dd_loc); @@ -611,8 +593,7 @@ rst_telldir(dirp) * Open a directory file. */ static RST_DIR * -opendirfile(name) - const char *name; +opendirfile(const char *name) { register RST_DIR *dirp; register int fd; @@ -632,17 +613,16 @@ opendirfile(name) * Set the mode, owner, and times for all new or changed directories */ void -setdirmodes(flags) - int flags; +setdirmodes(int flags) { FILE *mf; struct modeinfo node; struct entry *ep; char *cp; - vprintf(stdout, "Set directory mode, owner, and times.\n"); + Vprintf(stdout, "Set directory mode, owner, and times.\n"); if (command == 'r' || command == 'R') - (void) sprintf(modefile, "%s/rstmode%ld", tmpdir, dumpdate); + (void) snprintf(modefile, sizeof(modefile), "%s/rstmode%lu", tmpdir, (long)dumpdate); if (modefile[0] == '#') { panic("modefile not defined\n"); fprintf(stderr, "directory mode, owner, and times not set\n"); @@ -650,7 +630,7 @@ setdirmodes(flags) } mf = fopen(modefile, "r"); if (mf == NULL) { - fprintf(stderr, "fopen: %s\n", strerror(errno)); + warn("fopen"); fprintf(stderr, "cannot open mode file %s\n", modefile); fprintf(stderr, "directory mode, owner, and times not set\n"); return; @@ -696,9 +676,7 @@ setdirmodes(flags) * Generate a literal copy of a directory. */ int -genliteraldir(name, ino) - char *name; - ino_t ino; +genliteraldir(char *name, ino_t ino) { register struct inotab *itp; int ofile, dp, i, size; @@ -708,9 +686,7 @@ genliteraldir(name, ino) if (itp == NULL) panic("Cannot find directory inode %d named %s\n", ino, name); if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { - fprintf(stderr, "%s: ", name); - (void) fflush(stderr); - fprintf(stderr, "cannot create file: %s\n", strerror(errno)); + warn("%s: cannot create file\n", name); return (FAIL); } rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); @@ -718,18 +694,14 @@ genliteraldir(name, ino) for (i = itp->t_size; i > 0; i -= BUFSIZ) { size = i < BUFSIZ ? i : BUFSIZ; if (read(dp, buf, (int) size) == -1) { - fprintf(stderr, - "write error extracting inode %ld, name %s\n", - curfile.ino, curfile.name); - fprintf(stderr, "read: %s\n", strerror(errno)); - done(1); + warnx("write error extracting inode %lu, name %s\n", + (unsigned long)curfile.ino, curfile.name); + err(1, "read"); } if (!Nflag && write(ofile, buf, (int) size) == -1) { - fprintf(stderr, - "write error extracting inode %ld, name %s\n", - curfile.ino, curfile.name); - fprintf(stderr, "write: %s\n", strerror(errno)); - done(1); + warnx("write error extracting inode %lu, name %s\n", + (unsigned long)curfile.ino, curfile.name); + err(1, "write"); } } (void) close(dp); @@ -741,8 +713,7 @@ genliteraldir(name, ino) * Determine the type of an inode */ int -inodetype(ino) - ino_t ino; +inodetype(ino_t ino) { struct inotab *itp; @@ -757,14 +728,11 @@ inodetype(ino) * If requested, save its pertinent mode, owner, and time info. */ static struct inotab * -allocinotab(ino, dip, seekpt) - ino_t ino; #ifdef __linux__ - struct new_bsd_inode *dip; +allocinotab(ino_t ino, struct new_bsd_inode *dip, long seekpt) #else - struct dinode *dip; +allocinotab(ino_t ino, struct dinode *dip, long seekpt) #endif - long seekpt; { register struct inotab *itp; struct modeinfo node; @@ -802,8 +770,7 @@ allocinotab(ino, dip, seekpt) * Look up an inode in the table of directories */ static struct inotab * -inotablookup(ino) - ino_t ino; +inotablookup(ino_t ino) { register struct inotab *itp; @@ -817,14 +784,11 @@ inotablookup(ino) * Clean up and exit */ void -done(exitcode) - int exitcode; +cleanup(void) { - closemt(); if (modefile[0] != '#') (void) unlink(modefile); if (dirfile[0] != '#') (void) unlink(dirfile); - exit(exitcode); } diff --git a/restore/extern.h b/restore/extern.h index c2b88b9..8d8740b 100644 --- a/restore/extern.h +++ b/restore/extern.h @@ -39,16 +39,17 @@ * SUCH DAMAGE. * * @(#)extern.h 8.2 (Berkeley) 1/7/94 - * $Id: extern.h,v 1.2 1999/10/11 12:53:23 stelian Exp $ + * $Id: extern.h,v 1.3 1999/10/11 12:59:20 stelian Exp $ */ struct entry *addentry __P((char *, ino_t, int)); long addfile __P((char *, ino_t, int)); int addwhiteout __P((char *)); -void badentry __P((struct entry *, char *)); +void badentry __P((struct entry *, const char *)); void canon __P((char *, char *, int)); void checkrestore __P((void)); void closemt __P((void)); +void cleanup __P((void)); void comparefile __P((char *)); void compareleaves __P((void)); void createfiles __P((void)); @@ -58,7 +59,6 @@ long deletefile __P((char *, ino_t, int)); void deleteino __P((ino_t)); void delwhiteout __P((struct entry *)); ino_t dirlookup __P((const char *)); -__dead void done __P((int)); void dumpsymtable __P((char *, long)); void extractdirs __P((int)); int extractfile __P((char *)); @@ -68,7 +68,7 @@ void freeentry __P((struct entry *)); void freename __P((char *)); int genliteraldir __P((char *, ino_t)); char *gentempname __P((struct entry *)); -void getfile __P((void (*)(char *, long), void (*)(char *, long))); +void getfile __P((void (*)(char *, size_t), void (*)(char *, size_t))); void getvol __P((long)); void initsymtable __P((char *)); int inodetype __P((ino_t)); @@ -94,7 +94,7 @@ void removenode __P((struct entry *)); void removeoldleaves __P((void)); void removeoldnodes __P((void)); void renameit __P((char *, char *)); -int reply __P((char *)); +int reply __P((const char *)); RST_DIR *rst_opendir __P((const char *)); struct direct *rst_readdir __P((RST_DIR *)); void rst_closedir __P((RST_DIR *dirp)); @@ -110,12 +110,12 @@ void swabst __P((u_char *, u_char *)); void treescan __P((char *, ino_t, long (*)(char *, ino_t, int))); ino_t upperbnd __P((ino_t)); long verifyfile __P((char *, ino_t, int)); -void xtrnull __P((char *, long)); +void xtrnull __P((char *, size_t)); /* From ../dump/dumprmt.c */ void rmtclose __P((void)); -int rmthost __P((char *)); +int rmthost __P((const char *)); int rmtioctl __P((int, int)); -int rmtopen __P((char *, int)); -int rmtread __P((char *, int)); +int rmtopen __P((const char *, int)); +int rmtread __P((const char *, int)); int rmtseek __P((int, int)); diff --git a/restore/interactive.c b/restore/interactive.c index f98ff0f..de958bb 100644 --- a/restore/interactive.c +++ b/restore/interactive.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)interactive.c 8.5 (Berkeley) 5/1/95"; #endif static const char rcsid[] = - "$Id: interactive.c,v 1.2 1999/10/11 12:53:23 stelian Exp $"; + "$Id: interactive.c,v 1.3 1999/10/11 12:59:20 stelian Exp $"; #endif /* not lint */ #include @@ -60,13 +60,16 @@ static const char rcsid[] = #include #include -#include +#include +#include +#include #include #include #include #ifdef __linux__ #include +extern char * __progname; #endif #include "restore.h" @@ -111,7 +114,7 @@ static void printlist __P((char *, char *)); * Read and execute commands from the terminal. */ void -runcmdshell() +runcmdshell(void) { register struct entry *np; ino_t ino; @@ -168,7 +171,8 @@ loop: fprintf(stderr, "%s: not a directory\n", name); break; } - (void) strcpy(curdir, name); + (void) strncpy(curdir, name, sizeof(curdir)); + curdir[sizeof(curdir) - 1] = '\0'; break; /* * Delete elements from the extraction list. @@ -319,10 +323,7 @@ loop: * eliminate any embedded ".." components. */ static void -getcmd(curdir, cmd, name, size, ap) - char *curdir, *cmd, *name; - struct arglist *ap; - int size; +getcmd(char *curdir, char *cmd, char *name, int size, struct arglist *ap) { register char *cp; static char input[BUFSIZ]; @@ -340,7 +341,7 @@ getcmd(curdir, cmd, name, size, ap) * Read a command line and trim off trailing white space. */ do { - fprintf(stderr, "restore > "); + fprintf(stderr, "%s > ", __progname); (void) fflush(stderr); (void) fgets(input, BUFSIZ, terminal); } while (!feof(terminal) && input[0] == '\n'); @@ -408,8 +409,7 @@ retnext: * Strip off the next token of the input. */ static char * -copynext(input, output) - char *input, *output; +copynext(char *input, char *output) { register char *cp, *bp; char quote; @@ -458,9 +458,7 @@ copynext(input, output) * remove any embedded "." and ".." components. */ void -canon(rawname, canonname, len) - char *rawname, *canonname; - int len; +canon(char *rawname, char *canonname, int len) { register char *cp, *np; @@ -470,10 +468,8 @@ canon(rawname, canonname, len) (void) strcpy(canonname, "."); else (void) strcpy(canonname, "./"); - if (strlen(canonname) + strlen(rawname) >= len) { - fprintf(stderr, "canonname: not enough buffer space\n"); - done(1); - } + if (strlen(canonname) + strlen(rawname) >= len) + errx(1, "canonname: not enough buffer space"); (void) strcat(canonname, rawname); /* @@ -514,11 +510,9 @@ canon(rawname, canonname, len) * Do an "ls" style listing of a directory */ static void -printlist(name, basename) - char *name; - char *basename; +printlist(char *name, char *basename) { - register struct afile *fp, *list, *listp=NULL; + register struct afile *fp, *list, *listp = NULL; register struct direct *dp; struct afile single; RST_DIR *dirp; @@ -554,9 +548,9 @@ printlist(name, basename) fprintf(stderr, "%s:\n", name); entries = 0; listp = list; - (void) strncpy(locname, name, MAXPATHLEN); - (void) strncat(locname, "/", MAXPATHLEN); - namelen = strlen(locname); + namelen = snprintf(locname, sizeof(locname), "%s/", name); + if (namelen >= sizeof(locname)) + namelen = sizeof(locname) - 1; while ((dp = rst_readdir(dirp))) { if (dp == NULL) break; @@ -598,10 +592,7 @@ printlist(name, basename) * Read the contents of a directory. */ static void -mkentry(name, dp, fp) - char *name; - struct direct *dp; - register struct afile *fp; +mkentry(char *name, struct direct *dp, struct afile *fp) { char *cp; struct entry *np; @@ -661,13 +652,11 @@ mkentry(name, dp, fp) * Print out a pretty listing of a directory */ static void -formatf(list, nentry) - register struct afile *list; - int nentry; +formatf(struct afile *list, int nentry) { register struct afile *fp, *endlist; int width, bigino, haveprefix, havepostfix; - int i, j, w, precision=0, columns, lines; + int i, j, w, precision = 0, columns, lines; width = 0; haveprefix = 0; @@ -744,8 +733,7 @@ struct dirent { #endif /* __linux__ */ struct dirent * -glob_readdir(dirp) - RST_DIR *dirp; +glob_readdir(RST_DIR *dirp) { struct direct *dp; static struct dirent adirent; @@ -768,9 +756,7 @@ glob_readdir(dirp) * Return st_mode information in response to stat or lstat calls */ static int -glob_stat(name, stp) - const char *name; - struct stat *stp; +glob_stat(const char *name, struct stat *stp) { register struct direct *dp; @@ -789,8 +775,7 @@ glob_stat(name, stp) * Comparison routine for qsort. */ static int -fcmp(f1, f2) - register const void *f1, *f2; +fcmp(const void *f1, const void *f2) { return (strcmp(((struct afile *)f1)->fname, ((struct afile *)f2)->fname)); @@ -800,11 +785,13 @@ fcmp(f1, f2) * respond to interrupts */ void -onintr(signo) - int signo; +onintr(int signo) { + int save_errno = errno; + if (command == 'i' && runshell) longjmp(reset, 1); if (reply("restore interrupted, continue") == FAIL) - done(1); + exit(1); + errno = save_errno; } diff --git a/restore/main.c b/restore/main.c index e1e9790..f979560 100644 --- a/restore/main.c +++ b/restore/main.c @@ -50,7 +50,7 @@ static const char copyright[] = static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/4/95"; #endif static const char rcsid[] = - "$Id: main.c,v 1.2 1999/10/11 12:53:23 stelian Exp $"; + "$Id: main.c,v 1.3 1999/10/11 12:59:20 stelian Exp $"; #endif /* not lint */ #include @@ -67,7 +67,7 @@ static const char rcsid[] = #endif /* __linux__ */ #include -#include +#include #include #include #include @@ -95,9 +95,9 @@ ino_t maxino; time_t dumptime; time_t dumpdate; FILE *terminal; +char *tmpdir; int compare_ignore_not_found; char *filesys = NULL; -char *tmpdir = _PATH_TMP; #ifdef __linux__ char *__progname; @@ -107,13 +107,11 @@ static void obsolete __P((int *, char **[])); static void usage __P((void)); int -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { int ch; ino_t ino; - char *inputdev; + char *inputdev = _PATH_DEFTAPE; char *symtbl = "./restoresymtable"; char *p, name[MAXPATHLEN]; @@ -129,11 +127,17 @@ main(argc, argv) if ((inputdev = getenv("TAPE")) == NULL) inputdev = _PATH_DEFTAPE; + if ((tmpdir = getenv("TMPDIR")) == NULL) + tmpdir = _PATH_TMP; + if ((tmpdir = strdup(tmpdir)) == NULL) + err(1, "malloc tmpdir"); + for (p = tmpdir + strlen(tmpdir) - 1; p >= tmpdir && *p == '/'; p--) + ; obsolete(&argc, &argv); #ifdef KERBEROS -#define optlist "b:CcdDf:hikmNRrs:tTuvxy" +#define optlist "b:CcdD:f:hikmNRrs:tT:uvxy" #else -#define optlist "b:CcdDf:himNRrs:tTuvxy" +#define optlist "b:CcdD:f:himNRrs:tT:uvxy" #endif while ((ch = getopt(argc, argv, optlist)) != -1) switch(ch) { @@ -219,6 +223,8 @@ main(argc, argv) (void) signal(SIGTERM, SIG_IGN); setlinebuf(stderr); + atexit(cleanup); + setinput(inputdev); if (argc == 0) { @@ -233,21 +239,14 @@ main(argc, argv) case 'C': { struct stat stbuf; - vprintf(stdout, "Begin compare restore\n"); + Vprintf(stdout, "Begin compare restore\n"); compare_ignore_not_found = 0; setup(); printf("filesys = %s\n", filesys); - if (stat(filesys, &stbuf) < 0) { - fprintf(stderr, "cannot stat directory %s: %s\n", - filesys, strerror(errno)); - exit(1); - } else { - if (chdir(filesys) < 0) { - fprintf(stderr, "cannot cd to %s: %s\n", - filesys, strerror(errno)); - exit(1); - } - } + if (stat(filesys, &stbuf) < 0) + err(1, "cannot stat directory %s", filesys); + if (chdir(filesys) < 0) + err(1, "cannot cd to %s", filesys); compare_ignore_not_found = dumptime > 0; initsymtable((char *)0); extractdirs(0); @@ -275,11 +274,11 @@ main(argc, argv) /* * This is an incremental dump tape. */ - vprintf(stdout, "Begin incremental restore\n"); + Vprintf(stdout, "Begin incremental restore\n"); initsymtable(symtbl); extractdirs(1); removeoldleaves(); - vprintf(stdout, "Calculate node updates.\n"); + Vprintf(stdout, "Calculate node updates.\n"); treescan(".", ROOTINO, nodeupdates); findunreflinks(); removeoldnodes(); @@ -287,10 +286,10 @@ main(argc, argv) /* * This is a level zero dump tape. */ - vprintf(stdout, "Begin level 0 restore\n"); + Vprintf(stdout, "Begin level 0 restore\n"); initsymtable((char *)0); extractdirs(1); - vprintf(stdout, "Calculate extraction list.\n"); + Vprintf(stdout, "Calculate extraction list.\n"); treescan(".", ROOTINO, nodeupdates); } createleaves(symtbl); @@ -298,7 +297,7 @@ main(argc, argv) setdirmodes(FORCE); checkrestore(); if (dflag) { - vprintf(stdout, "Verify the directory structure\n"); + Vprintf(stdout, "Verify the directory structure\n"); treescan(".", ROOTINO, verifyfile); } dumpsymtable(symtbl, (long)1); @@ -354,13 +353,13 @@ main(argc, argv) checkrestore(); break; } - done(0); + exit(0); /* NOTREACHED */ - exit(1); /* gcc shut up */ + return 0; /* gcc shut up */ } static void -usage() +usage(void) { (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", "restore -i [-chkmuvy] [-b blocksize] [-f file] [-s fileno]", @@ -368,7 +367,7 @@ usage() "restore -R [-ckuvy] [-b blocksize] [-f file] [-s fileno]", "restore -x [-chkmuvy] [-b blocksize] [-f file] [-s fileno] [file ...]", "restore -t [-chkuvy] [-b blocksize] [-f file] [-s fileno] [file ...]"); - done(1); + exit(1); } /* @@ -377,12 +376,10 @@ usage() * getopt(3) will like. */ static void -obsolete(argcp, argvp) - int *argcp; - char **argvp[]; +obsolete(int *argcp, char **argvp[]) { int argc, flags; - char *ap, **argv, *flagsp=NULL, **nargv, *p=NULL; + char *ap, **argv, *flagsp = NULL, **nargv, *p = NULL; /* Setup. */ argv = *argvp; @@ -396,7 +393,7 @@ obsolete(argcp, argvp) /* Allocate space for new arguments. */ if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL || (p = flagsp = malloc(strlen(ap) + 2)) == NULL) - err(1, NULL); + err(1, "malloc args"); *nargv++ = *argv; argv += 2, argc -= 2; @@ -411,7 +408,7 @@ obsolete(argcp, argvp) usage(); } if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL) - err(1, NULL); + err(1, "malloc arg"); nargv[0][0] = '-'; nargv[0][1] = *ap; (void)strcpy(&nargv[0][2], *argv); diff --git a/restore/restore.8 b/restore/restore.8 index 667729b..676e3c4 100644 --- a/restore/restore.8 +++ b/restore/restore.8 @@ -30,7 +30,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)restore.8 8.4 (Berkeley) 5/1/95 -.\" $Id: restore.8,v 1.2 1999/10/11 12:53:24 stelian Exp $ +.\" $Id: restore.8,v 1.3 1999/10/11 12:59:20 stelian Exp $ .\" .Dd May 1, 1995 .Dt RESTORE 8 @@ -88,7 +88,7 @@ .in -\\n(iSu (The .Bx 4.3 -option syntax is implemented for backward compatibility, but +option syntax is implemented for backward compatibility but is not documented here.) .Sh DESCRIPTION The @@ -141,7 +141,8 @@ added to the extraction list (unless the .Fl h flag is specified on the command line). -Files that are on the extraction list are prepended with a ``*'' +Files that are on the extraction list are prepended with a +.Dq \&* when they are listed by .Ic ls . .It Ic \&cd Ar arg @@ -158,27 +159,28 @@ The most expedient way to extract most of the files from a directory is to add the directory to the extraction list and then delete those files that are not needed. .It Ic extract -All the files that are on the extraction list are extracted +All files on the extraction list are extracted from the dump. .Nm Restore will ask which volume the user wishes to mount. The fastest way to extract a few files is to -start with the last volume, and work towards the first volume. +start with the last volume and work towards the first volume. .It Ic help List a summary of the available commands. .It Ic \&ls Op Ar arg List the current or specified directory. -Entries that are directories are appended with a ``/''. +Entries that are directories are appended with a +.Dq \&* . Entries that have been marked for extraction are prepended with a ``*''. If the verbose -flag is set the inode number of each entry is also listed. +flag is set, the inode number of each entry is also listed. .It Ic pwd Print the full pathname of the current working directory. .It Ic quit Restore immediately exits, even if the extraction list is not empty. .It Ic setmodes -All the directories that have been added to the extraction list +All directories that have been added to the extraction list have their owner, modes, and times set; nothing is extracted from the dump. This is useful for cleaning up after a restore has been prematurely aborted. @@ -195,17 +197,17 @@ to print out information about each file as it is extracted. .El .It Fl R .Nm Restore -requests a particular tape of a multi volume set on which to restart +requests a particular tape of a multi-volume set on which to restart a full restore (see the .Fl r flag below). This is useful if the restore has been interrupted. .It Fl r -Restore (rebuild a file system). +Restore (rebuild) a file system. The target file system should be made pristine with .Xr newfs 8 , -mounted and the user +mounted, and the user .Xr cd Ns 'd into the pristine file system before starting the restoration of the initial level 0 backup. If the @@ -216,8 +218,8 @@ any necessary incremental backups on top of the level 0. The .Fl r flag precludes an interactive file extraction and can be -detrimental to one's health if not used carefully (not to mention -the disk). An example: +detrimental to one's health (not to mention the disk) if not used carefully. +An example: .Bd -literal -offset indent newfs /dev/rrp0g eagle mount /dev/rp0g /mnt @@ -246,7 +248,7 @@ such as size or block size. The names of the specified files are listed if they occur on the backup. If no file argument is given, -then the root directory is listed, +the root directory is listed, which results in the entire content of the backup being listed, unless the @@ -269,7 +271,7 @@ the directory is recursively extracted. The owner, modification time, and mode are restored (if possible). If no file argument is given, -then the root directory is extracted, +the root directory is extracted, which results in the entire content of the backup being extracted, unless the @@ -308,7 +310,7 @@ Read the backup from .Ar file may be a special device file like -.Pa /dev/rmt12 +.Pa /dev/st0 (a tape drive), .Pa /dev/rsd1c (a disk drive), @@ -317,7 +319,7 @@ or .Ql Fl (the standard input). If the name of the file is of the form -.Dq host:file , +.Dq host:file or .Dq user@host:file , .Nm restore @@ -378,7 +380,7 @@ Do not ask the user whether to abort the restore in the event of an error. Always try to skip over the bad block(s) and continue. .El .Sh DIAGNOSTICS -Complaints if it gets a read error. +Complains if it gets a read error. If .Fl y has been specified, or the user responds @@ -401,11 +403,12 @@ start with the last volume, and work towards the first volume. .Pp There are numerous consistency checks that can be listed by .Nm restore . -Most checks are self-explanatory or can ``never happen''. +Most checks are self-explanatory or can +.Dq never happen . Common errors are given below. .Pp .Bl -tag -width Ds -compact -.It Converting to new file system format. +.It Converting to new file system format A dump tape created from the old file system has been loaded. It is automatically converted to the new file system format. .Pp @@ -420,12 +423,12 @@ A file that was not listed in the directory showed up. This can occur when using a dump created on an active file system. .Pp .It Incremental dump too low -When doing incremental restore, +When doing an incremental restore, a dump that was written before the previous incremental dump, or that has too low an incremental level has been loaded. .Pp .It Incremental dump too high -When doing incremental restore, +When doing an incremental restore, a dump that does not begin its coverage where the previous incremental dump left off, or that has too high an incremental level has been loaded. @@ -435,9 +438,9 @@ or that has too high an incremental level has been loaded. .It Tape read error while trying to resynchronize A tape (or other media) read error has occurred. If a file name is specified, -then its contents are probably partially wrong. +its contents are probably partially wrong. If an inode is being skipped or the tape is trying to resynchronize, -then no extracted files have been corrupted, +no extracted files have been corrupted, though files may not be found on the tape. .Pp .It resync restore, skipped blocks @@ -447,7 +450,10 @@ may have to resynchronize itself. This message lists the number of blocks that were skipped over. .El .Sh ENVIRONMENT -.Bl -tag -width Fl +If the following environment variable exists it will be utilized by +.Nm restore : +.Pp +.Bl -tag -width "TMPDIR" -compact .It Ev TAPE If no -f option was specified, .Nm @@ -457,9 +463,16 @@ as the dump device. .Ev TAPE may be of the form .Qq tapename , -.Qq host:tapename , +.Qq host:tapename or .Qq user@host:tapename . +.It Ev TMPDIR +The directory given in +.Ev TMPDIR +will be used +instead of +.Pa /tmp +to store temporary files. .It Ev RMT The environment variable .Ev RMT @@ -468,14 +481,14 @@ will be used to determine the pathname of the remote program. .Sh FILES .Bl -tag -width "./restoresymtable" -compact -.It Pa /dev/rmt? +.It Pa /dev/st0 the default tape drive .It Pa /tmp/rstdir* -file containing directories on the tape. +file containing directories on the tape .It Pa /tmp/rstmode* -owner, mode, and time stamps for directories. +owner, mode, and time stamps for directories .It Pa \&./restoresymtable -information passed between incremental restores. +information passed between incremental restores .El .Sh SEE ALSO .Xr dump 8 , @@ -488,12 +501,36 @@ information passed between incremental restores. can get confused when doing incremental restores from dumps that were made on active file systems. .Pp -A level zero dump must be done after a full restore. -Because restore runs in user code, +A level 0 dump must be done after a full restore. +Because +.Nm restore +runs in user code, it has no control over inode allocation; thus a full dump must be done to get a new set of directories reflecting the new inode numbering, -even though the contents of the files is unchanged. +even though the content of the files is unchanged. +.Pp +The temporary files +.Pa /tmp/rstdir* +and +.Pa /tmp/rstmode* +are generated with a unique name based on the date of the dump +and the process ID (see +.Xr mktemp 3 ), +except when +.Fl r +or +.Fl R +is used. +Because +.Fl R +allows you to restart a +.Fl r +operation that may have been interrupted, the temporary files should +be the same across different processes. +In all other cases, the files are unique because it is possible to +have two different dumps started at the same time, and separate +operations shouldn't conflict with each other. .Pp To do a network restore, you have to run restore as root. This is due to the previous security history of dump and restore. (restore is diff --git a/restore/restore.c b/restore/restore.c index 773b709..f1986a4 100644 --- a/restore/restore.c +++ b/restore/restore.c @@ -44,12 +44,13 @@ static char sccsid[] = "@(#)restore.c 8.3 (Berkeley) 9/13/94"; #endif static const char rcsid[] = - "$Id: restore.c,v 1.2 1999/10/11 12:53:24 stelian Exp $"; + "$Id: restore.c,v 1.3 1999/10/11 12:59:20 stelian Exp $"; #endif /* not lint */ #include #ifdef __linux__ +#include #include #include #include @@ -74,17 +75,14 @@ static char *keyval __P((int)); * List entries on the tape. */ long -listfile(name, ino, type) - char *name; - ino_t ino; - int type; +listfile(char *name, ino_t ino, int type) { long descend = hflag ? GOOD : FAIL; if (TSTINO(ino, dumpmap) == 0) return (descend); - vprintf(stdout, "%s", type == LEAF ? "leaf" : "dir "); - fprintf(stdout, "%10ld\t%s\n", ino, name); + Vprintf(stdout, "%s", type == LEAF ? "leaf" : "dir "); + fprintf(stdout, "%10lu\t%s\n", (unsigned long)ino, name); return (descend); } @@ -93,23 +91,20 @@ listfile(name, ino, type) * Request that new entries be extracted. */ long -addfile(name, ino, type) - char *name; - ino_t ino; - int type; +addfile(char *name, ino_t ino, int type) { register struct entry *ep; long descend = hflag ? GOOD : FAIL; char buf[100]; if (TSTINO(ino, dumpmap) == 0) { - dprintf(stdout, "%s: not on the tape\n", name); + Dprintf(stdout, "%s: not on the tape\n", name); return (descend); } if (ino == WINO && command == 'i' && !vflag) return (descend); if (!mflag) { - (void) sprintf(buf, "./%lu", ino); + (void) snprintf(buf, sizeof(buf), "./%lu", (unsigned long)ino); name = buf; if (type == NODE) { (void) genliteraldir(name, ino); @@ -137,10 +132,7 @@ addfile(name, ino, type) */ /* ARGSUSED */ long -deletefile(name, ino, type) - char *name; - ino_t ino; - int type; +deletefile(char *name, ino_t ino, int type) { long descend = hflag ? GOOD : FAIL; struct entry *ep; @@ -178,14 +170,14 @@ static struct entry *removelist; * Remove directories from the lookup chains. */ void -removeoldleaves() +removeoldleaves(void) { register struct entry *ep, *nextep; register ino_t i, mydirino; - vprintf(stdout, "Mark entries to be removed.\n"); + Vprintf(stdout, "Mark entries to be removed.\n"); if ((ep = lookupino(WINO))) { - vprintf(stdout, "Delete whiteouts\n"); + Vprintf(stdout, "Delete whiteouts\n"); for ( ; ep != NULL; ep = nextep) { nextep = ep->e_links; mydirino = ep->e_parent->e_ino; @@ -211,7 +203,7 @@ removeoldleaves() if (TSTINO(i, usedinomap)) continue; for ( ; ep != NULL; ep = ep->e_links) { - dprintf(stdout, "%s: REMOVE\n", myname(ep)); + Dprintf(stdout, "%s: REMOVE\n", myname(ep)); if (ep->e_type == LEAF) { removeleaf(ep); freeentry(ep); @@ -235,10 +227,7 @@ removeoldleaves() * Renames are done at the same time. */ long -nodeupdates(name, ino, type) - char *name; - ino_t ino; - int type; +nodeupdates(char *name, ino_t ino, int type) { register struct entry *ep, *np, *ip; long descend = GOOD; @@ -304,7 +293,7 @@ nodeupdates(name, ino, type) removeleaf(np); freeentry(np); } else { - dprintf(stdout, "name/inode conflict, mktempname %s\n", + Dprintf(stdout, "name/inode conflict, mktempname %s\n", myname(np)); mktempname(np); } @@ -332,7 +321,7 @@ nodeupdates(name, ino, type) */ case INOFND|NAMEFND: ip->e_flags |= KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ip)); break; @@ -368,7 +357,7 @@ nodeupdates(name, ino, type) if (type == NODE) newnode(ep); ep->e_flags |= NEW|KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ep)); break; @@ -392,7 +381,7 @@ nodeupdates(name, ino, type) renameit(myname(ip), name); moveentry(ip, name); ip->e_flags |= KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ip)); break; } @@ -405,7 +394,7 @@ nodeupdates(name, ino, type) } ep = addentry(name, ino, type|LINK); ep->e_flags |= NEW; - dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, flagvalues(ep)); break; @@ -422,14 +411,14 @@ nodeupdates(name, ino, type) if (type == NODE) newnode(ep); ep->e_flags |= NEW|KEEP; - dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s|LINK\n", keyval(key), name, flagvalues(ep)); break; } if (type == LEAF && lookuptype != LINK) np->e_flags |= EXTRACT; np->e_flags |= KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(np)); break; @@ -453,7 +442,7 @@ nodeupdates(name, ino, type) } if (ip->e_type == LEAF) { /* changing from leaf to node */ - for (ip = lookupino(ino); ip != NULL; ip = ip->e_links) { + for ( ; ip != NULL; ip = ip->e_links) { if (ip->e_type != LEAF) badentry(ip, "NODE and LEAF links to same inode"); removeleaf(ip); @@ -471,7 +460,7 @@ nodeupdates(name, ino, type) ip = addentry(name, ino, type); } ip->e_flags |= NEW|KEEP; - dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, + Dprintf(stdout, "[%s] %s: %s\n", keyval(key), name, flagvalues(ip)); break; @@ -480,7 +469,7 @@ nodeupdates(name, ino, type) * Ignore it. */ case NAMEFND: - dprintf(stdout, "[%s] %s: Extraneous name\n", keyval(key), + Dprintf(stdout, "[%s] %s: Extraneous name\n", keyval(key), name); descend = FAIL; break; @@ -494,8 +483,8 @@ nodeupdates(name, ino, type) */ case NULL: if (compare_ignore_not_found) break; - fprintf(stderr, "%s: (inode %ld) not found on tape\n", - name, ino); + fprintf(stderr, "%s: (inode %lu) not found on tape\n", + name, (unsigned long)ino); break; /* @@ -525,8 +514,7 @@ nodeupdates(name, ino, type) * Calculate the active flags in a key. */ static char * -keyval(key) - int key; +keyval(int key) { static char keybuf[32]; @@ -547,19 +535,19 @@ keyval(key) * Find unreferenced link names. */ void -findunreflinks() +findunreflinks(void) { register struct entry *ep, *np; register ino_t i; - vprintf(stdout, "Find unreferenced names.\n"); + Vprintf(stdout, "Find unreferenced names.\n"); for (i = ROOTINO; i < maxino; i++) { ep = lookupino(i); if (ep == NULL || ep->e_type == LEAF || TSTINO(i, dumpmap) == 0) continue; for (np = ep->e_entries; np != NULL; np = np->e_sibling) { if (np->e_flags == 0) { - dprintf(stdout, + Dprintf(stdout, "%s: remove unreferenced name\n", myname(np)); removeleaf(np); @@ -575,7 +563,7 @@ findunreflinks() if (np->e_type == LEAF) { if (np->e_flags != 0) badentry(np, "unreferenced with flags"); - dprintf(stdout, + Dprintf(stdout, "%s: remove unreferenced name\n", myname(np)); removeleaf(np); @@ -595,12 +583,12 @@ findunreflinks() * time O(N). */ void -removeoldnodes() +removeoldnodes(void) { register struct entry *ep, **prev; long change; - vprintf(stdout, "Remove old nodes (directories).\n"); + Vprintf(stdout, "Remove old nodes (directories).\n"); do { change = 0; prev = &removelist; @@ -623,7 +611,7 @@ removeoldnodes() /* current copy of this file on disk. If do_compare is 0, then just */ /* make our caller think we did it--this is used to handle hard links */ /* to files and devices. */ -void +static void compare_entry(struct entry *ep, int do_compare) { if ((ep->e_flags & (NEW|EXTRACT)) == 0) @@ -636,7 +624,7 @@ compare_entry(struct entry *ep, int do_compare) * This is the routine used to compare files for the 'C' command. */ void -compareleaves() +compareleaves(void) { register struct entry *ep; ino_t first; @@ -669,8 +657,8 @@ compareleaves() * on the next incremental tape. */ if (first != curfile.ino) { - fprintf(stderr, "expected next file %ld, got %ld\n", - first, curfile.ino); + fprintf(stderr, "expected next file %ld, got %lu\n", + (long)first, (unsigned long)curfile.ino); skipfile(); goto next; } @@ -700,17 +688,16 @@ compareleaves() * Extract new leaves. */ void -createleaves(symtabfile) - char *symtabfile; +createleaves(char *symtabfile) { register struct entry *ep; ino_t first; long curvol; if (command == 'R') { - vprintf(stdout, "Continue extraction of new leaves\n"); + Vprintf(stdout, "Continue extraction of new leaves\n"); } else { - vprintf(stdout, "Extract new leaves.\n"); + Vprintf(stdout, "Extract new leaves.\n"); dumpsymtable(symtabfile, volno); } first = lowerbnd(ROOTINO); @@ -740,8 +727,8 @@ createleaves(symtabfile) * on the next incremental tape. */ if (first != curfile.ino) { - fprintf(stderr, "expected next file %ld, got %ld\n", - first, curfile.ino); + fprintf(stderr, "expected next file %ld, got %lu\n", + (long)first, (unsigned long)curfile.ino); skipfile(); goto next; } @@ -780,13 +767,13 @@ createleaves(symtabfile) * Efficiently extract a subset of the files on a tape. */ void -createfiles() +createfiles(void) { register ino_t first, next, last; register struct entry *ep; long curvol; - vprintf(stdout, "Extract requested files\n"); + Vprintf(stdout, "Extract requested files\n"); curfile.action = SKIP; getvol((long)1); skipmaps(); @@ -868,14 +855,14 @@ createfiles() * Add links. */ void -createlinks() +createlinks(void) { register struct entry *np, *ep; register ino_t i; char name[BUFSIZ]; if ((ep = lookupino(WINO))) { - vprintf(stdout, "Add whiteouts\n"); + Vprintf(stdout, "Add whiteouts\n"); for ( ; ep != NULL; ep = ep->e_links) { if ((ep->e_flags & NEW) == 0) continue; @@ -887,7 +874,7 @@ createlinks() ep->e_flags &= ~NEW; } } - vprintf(stdout, "Add links\n"); + Vprintf(stdout, "Add links\n"); for (i = ROOTINO; i < maxino; i++) { ep = lookupino(i); if (ep == NULL) @@ -912,18 +899,18 @@ createlinks() * that no temporary names remain. */ void -checkrestore() +checkrestore(void) { register struct entry *ep; register ino_t i; - vprintf(stdout, "Check the symbol table.\n"); + Vprintf(stdout, "Check the symbol table.\n"); for (i = WINO; i < maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { ep->e_flags &= ~KEEP; if (ep->e_type == NODE) ep->e_flags &= ~(NEW|EXISTED); - if (ep->e_flags != 0) + if (ep->e_flags /* != NULL */) badentry(ep, "incomplete operations"); } } @@ -934,10 +921,7 @@ checkrestore() * A paranoid check that things are as they should be. */ long -verifyfile(name, ino, type) - char *name; - ino_t ino; - int type; +verifyfile(char *name, ino_t ino, int type) { struct entry *np, *ep; long descend = GOOD; diff --git a/restore/restore.h b/restore/restore.h index dbb97e5..cbe17bd 100644 --- a/restore/restore.h +++ b/restore/restore.h @@ -71,6 +71,7 @@ extern time_t dumptime; /* time that this dump begins */ extern time_t dumpdate; /* time that this dump was made */ extern char command; /* opration being performed */ extern FILE *terminal; /* file descriptor for the terminal input */ +extern char *tmpdir; /* name of temp directory */ extern int oldinofmt; /* reading tape with old format inodes */ extern int Bcvt; /* need byte swapping on inodes and dirs */ extern int compare_ignore_not_found; @@ -78,7 +79,6 @@ extern int compare_ignore_not_found; /* so messages about "not found" files */ /* isn't seen. */ extern char *filesys; /* name of dumped filesystem */ -extern char *tmpdir; /* name of temp directory */ /* * Each file in the file system is described by one of these entries @@ -151,8 +151,8 @@ typedef struct rstdirdesc RST_DIR; #define SETINO(ino, map) \ map[(u_int)((ino) - 1) / NBBY] |= 1 << ((u_int)((ino) - 1) % NBBY) -#define dprintf if (dflag) fprintf -#define vprintf if (vflag) fprintf +#define Dprintf if (dflag) fprintf +#define Vprintf if (vflag) fprintf #define GOOD 1 #define FAIL 0 diff --git a/restore/symtab.c b/restore/symtab.c index 21beab7..27343d9 100644 --- a/restore/symtab.c +++ b/restore/symtab.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)symtab.c 8.3 (Berkeley) 4/28/95"; #endif static const char rcsid[] = - "$Id: symtab.c,v 1.2 1999/10/11 12:53:24 stelian Exp $"; + "$Id: symtab.c,v 1.3 1999/10/11 12:59:20 stelian Exp $"; #endif /* not lint */ /* @@ -68,6 +68,7 @@ static const char rcsid[] = #endif /* __linux__ */ #include +#include #include #include #include @@ -100,8 +101,7 @@ static void removeentry __P((struct entry *)); * Look up an entry by inode number */ struct entry * -lookupino(inum) - ino_t inum; +lookupino(ino_t inum) { register struct entry *ep; @@ -117,9 +117,7 @@ lookupino(inum) * Add an entry into the entry table */ static void -addino(inum, np) - ino_t inum; - struct entry *np; +addino(ino_t inum, struct entry *np) { struct entry **epp; @@ -139,8 +137,7 @@ addino(inum, np) * Delete an entry from the entry table */ void -deleteino(inum) - ino_t inum; +deleteino(ino_t inum) { register struct entry *next; struct entry **prev; @@ -163,8 +160,7 @@ deleteino(inum) * Look up an entry by name */ struct entry * -lookupname(name) - char *name; +lookupname(char *name) { register struct entry *ep; register char *np, *cp; @@ -193,8 +189,7 @@ lookupname(name) * Look up the parent of a pathname */ static struct entry * -lookupparent(name) - char *name; +lookupparent(char *name) { struct entry *ep; char *tailindex; @@ -216,15 +211,14 @@ lookupparent(name) * Determine the current pathname of a node or leaf */ char * -myname(ep) - register struct entry *ep; +myname(struct entry *ep) { register char *cp; static char namebuf[MAXPATHLEN]; for (cp = &namebuf[MAXPATHLEN - 2]; cp > &namebuf[ep->e_namlen]; ) { cp -= ep->e_namlen; - memmove(cp, ep->e_name, (long)ep->e_namlen); + memmove(cp, ep->e_name, (size_t)ep->e_namlen); if (ep == lookupino(ROOTINO)) return (cp); *(--cp) = '/'; @@ -244,17 +238,14 @@ static struct entry *freelist = NULL; * add an entry to the symbol table */ struct entry * -addentry(name, inum, type) - char *name; - ino_t inum; - int type; +addentry(char *name, ino_t inum, int type) { register struct entry *np, *ep; if (freelist != NULL) { np = freelist; freelist = np->e_next; - memset(np, 0, (long)sizeof(struct entry)); + memset(np, 0, sizeof(struct entry)); } else { np = (struct entry *)calloc(1, sizeof(struct entry)); if (np == NULL) @@ -295,8 +286,7 @@ addentry(name, inum, type) * delete an entry from the symbol table */ void -freeentry(ep) - register struct entry *ep; +freeentry(struct entry *ep) { register struct entry *np; ino_t inum; @@ -339,9 +329,7 @@ freeentry(ep) * Relocate an entry in the tree structure */ void -moveentry(ep, newname) - register struct entry *ep; - char *newname; +moveentry(struct entry *ep, char *newname) { struct entry *np; char *cp; @@ -369,8 +357,7 @@ moveentry(ep, newname) * Remove an entry in the tree structure */ static void -removeentry(ep) - register struct entry *ep; +removeentry(struct entry *ep) { register struct entry *np; @@ -415,8 +402,7 @@ static struct strhdr strtblhdr[allocsize(NAME_MAX) / STRTBLINCR]; * has an appropriate sized entry, and if not allocates a new one. */ char * -savename(name) - char *name; +savename(char *name) { struct strhdr *np; long len; @@ -443,8 +429,7 @@ savename(name) * appropriate free list. */ void -freename(name) - char *name; +freename(char *name) { struct strhdr *tp, *np; @@ -471,9 +456,7 @@ struct symtableheader { * dump a snapshot of the symbol table */ void -dumpsymtable(filename, checkpt) - char *filename; - long checkpt; +dumpsymtable(char *filename, long checkpt) { register struct entry *ep, *tep; register ino_t i; @@ -482,11 +465,11 @@ dumpsymtable(filename, checkpt) FILE *fd; struct symtableheader hdr; - vprintf(stdout, "Check pointing the restore\n"); + Vprintf(stdout, "Check pointing the restore\n"); if (Nflag) return; if ((fd = fopen(filename, "w")) == NULL) { - fprintf(stderr, "fopen: %s\n", strerror(errno)); + warn("fopen"); panic("cannot create save file %s for symbol table\n", filename); } @@ -509,7 +492,7 @@ dumpsymtable(filename, checkpt) stroff = 0; for (i = WINO; i <= maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { - memmove(tep, ep, (long)sizeof(struct entry)); + memmove(tep, ep, sizeof(struct entry)); tep->e_name = (char *)stroff; stroff += allocsize(ep->e_namlen); tep->e_parent = (struct entry *)ep->e_parent->e_index; @@ -547,7 +530,7 @@ dumpsymtable(filename, checkpt) hdr.ntrec = ntrec; (void) fwrite((char *)&hdr, sizeof(struct symtableheader), 1, fd); if (ferror(fd)) { - fprintf(stderr, "fwrite: %s\n", strerror(errno)); + warn("fwrite"); panic("output error to file %s writing symbol table\n", filename); } @@ -558,8 +541,7 @@ dumpsymtable(filename, checkpt) * Initialize a symbol table from a file */ void -initsymtable(filename) - char *filename; +initsymtable(char *filename) { char *base; long tblsize; @@ -570,7 +552,7 @@ initsymtable(filename) register long i; int fd; - vprintf(stdout, "Initialize symbol table.\n"); + Vprintf(stdout, "Initialize symbol table.\n"); if (filename == NULL) { entrytblsize = maxino / HASHFACTOR; entry = (struct entry **) @@ -582,11 +564,11 @@ initsymtable(filename) return; } if ((fd = open(filename, O_RDONLY, 0)) < 0) { - fprintf(stderr, "open: %s\n", strerror(errno)); + warn("open"); panic("cannot open symbol table file %s\n", filename); } if (fstat(fd, &stbuf) < 0) { - fprintf(stderr, "stat: %s\n", strerror(errno)); + warn("stat"); panic("cannot stat symbol table file %s\n", filename); } tblsize = stbuf.st_size - sizeof(struct symtableheader); @@ -595,7 +577,7 @@ initsymtable(filename) panic("cannot allocate space for symbol table\n"); if (read(fd, base, (int)tblsize) < 0 || read(fd, (char *)&hdr, sizeof(struct symtableheader)) < 0) { - fprintf(stderr, "read: %s\n", strerror(errno)); + warn("read"); panic("cannot read symbol table file %s\n", filename); } switch (command) { @@ -604,13 +586,9 @@ initsymtable(filename) * For normal continuation, insure that we are using * the next incremental tape */ - if (hdr.dumpdate != dumptime) { - if (hdr.dumpdate < dumptime) - fprintf(stderr, "Incremental tape too low\n"); - else - fprintf(stderr, "Incremental tape too high\n"); - done(1); - } + if (hdr.dumpdate != dumptime) + errx(1, "Incremental tape too %s", + (hdr.dumpdate < dumptime) ? "low" : "high"); break; case 'R': /* diff --git a/restore/tape.c b/restore/tape.c index 4ac6a25..9e1e28c 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -49,7 +49,7 @@ static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95"; #endif static const char rcsid[] = - "$Id: tape.c,v 1.2 1999/10/11 12:53:24 stelian Exp $"; + "$Id: tape.c,v 1.3 1999/10/11 12:59:21 stelian Exp $"; #endif /* not lint */ #include @@ -67,6 +67,7 @@ static const char rcsid[] = #include #include +#include #include #include #include @@ -92,7 +93,7 @@ static union u_spcl endoftapemark; static long blksread; /* blocks read since last header */ static long tpblksread = 0; /* TP_BSIZE blocks read */ static long tapesread; -static jmp_buf restart; +static sigjmp_buf restart; static int gettingfile = 0; /* restart has a valid frame */ static char *host = NULL; @@ -114,16 +115,18 @@ static void findtapeblksize __P((void)); static int gethead __P((struct s_spcl *)); static void readtape __P((char *)); static void setdumpnum __P((void)); +static u_int swabi __P((u_int)); static u_long swabl __P((u_long)); -static u_char *swablong __P((u_char *, int)); -static u_char *swabshort __P((u_char *, int)); +static u_char *swab64 __P((u_char *, int)); +static u_char *swab32 __P((u_char *, int)); +static u_char *swab16 __P((u_char *, int)); static void terminateinput __P((void)); -static void xtrfile __P((char *, long)); -static void xtrlnkfile __P((char *, long)); -static void xtrlnkskip __P((char *, long)); -static void xtrmap __P((char *, long)); -static void xtrmapskip __P((char *, long)); -static void xtrskip __P((char *, long)); +static void xtrfile __P((char *, size_t)); +static void xtrlnkfile __P((char *, size_t)); +static void xtrlnkskip __P((char *, size_t)); +static void xtrmap __P((char *, size_t)); +static void xtrmapskip __P((char *, size_t)); +static void xtrskip __P((char *, size_t)); static int readmapflag; @@ -131,8 +134,7 @@ static int readmapflag; * Set up an input source */ void -setinput(source) - char *source; +setinput(char *source) { FLUSHTAPEBUF(); if (bflag) @@ -147,7 +149,7 @@ setinput(source) source = strchr(host, ':'); *source++ = '\0'; if (rmthost(host) == 0) - done(1); + exit(1); } else #endif if (strcmp(source, "-") == 0) { @@ -157,30 +159,23 @@ setinput(source) */ terminal = fopen(_PATH_TTY, "r"); if (terminal == NULL) { - (void)fprintf(stderr, "cannot open %s: %s\n", - _PATH_TTY, strerror(errno)); + warn("cannot open %s", _PATH_TTY); terminal = fopen(_PATH_DEVNULL, "r"); - if (terminal == NULL) { - (void)fprintf(stderr, "cannot open %s: %s\n", - _PATH_DEVNULL, strerror(errno)); - done(1); - } + if (terminal == NULL) + err(1, "cannot open %s", _PATH_DEVNULL); } pipein++; } setuid(getuid()); /* no longer need or want root privileges */ magtape = strdup(source); - if (magtape == NULL) { - fprintf(stderr, "Cannot allocate space for magtape buffer\n"); - done(1); - } + if (magtape == NULL) + errx(1, "Cannot allocate space for magtape buffer"); } void -newtapebuf(size) - long size; +newtapebuf(long size) { - static tapebufsize = -1; + static int tapebufsize = -1; ntrec = size; if (size <= tapebufsize) @@ -188,10 +183,8 @@ newtapebuf(size) if (tapebuf != NULL) free(tapebuf); tapebuf = malloc(size * TP_BSIZE); - if (tapebuf == NULL) { - fprintf(stderr, "Cannot allocate space for tape buffer\n"); - done(1); - } + if (tapebuf == NULL) + errx(1, "Cannot allocate space for tape buffer"); tapebufsize = size; } @@ -200,12 +193,12 @@ newtapebuf(size) * that it actually is a dump tape. */ void -setup() +setup(void) { int i, j, *ip; struct stat stbuf; - vprintf(stdout, "Verify tape and initialize maps\n"); + Vprintf(stdout, "Verify tape and initialize maps\n"); #ifdef RRESTORE if (host) mt = rmtopen(magtape, 0); @@ -215,10 +208,8 @@ setup() mt = 0; else mt = open(magtape, O_RDONLY, 0); - if (mt < 0) { - fprintf(stderr, "%s: %s\n", magtape, strerror(errno)); - done(1); - } + if (mt < 0) + err(1, "%s", magtape); volno = 1; setdumpnum(); FLUSHTAPEBUF(); @@ -229,10 +220,8 @@ setup() blksread--; tpblksread--; cvtflag++; - if (gethead(&spcl) == FAIL) { - fprintf(stderr, "Tape is not a dump tape\n"); - done(1); - } + if (gethead(&spcl) == FAIL) + errx(1, "Tape is not a dump tape"); fprintf(stderr, "Converting to new file system format.\n"); } if (pipein) { @@ -253,43 +242,33 @@ setup() } dumptime = spcl.c_ddate; dumpdate = spcl.c_date; - if (stat(".", &stbuf) < 0) { - fprintf(stderr, "cannot stat .: %s\n", strerror(errno)); - done(1); - } + if (stat(".", &stbuf) < 0) + err(1, "cannot stat ."); if (stbuf.st_blksize > 0 && stbuf.st_blksize < TP_BSIZE ) fssize = TP_BSIZE; if (stbuf.st_blksize >= TP_BSIZE && stbuf.st_blksize <= MAXBSIZE) fssize = stbuf.st_blksize; - if (((fssize - 1) & fssize) != 0) { - fprintf(stderr, "bad block size %ld\n", fssize); - done(1); - } - if (spcl.c_volume != 1) { - fprintf(stderr, "Tape is not volume 1 of the dump\n"); - done(1); - } + if (((fssize - 1) & fssize) != 0) + errx(1, "bad block size %ld", fssize); + if (spcl.c_volume != 1) + errx(1, "Tape is not volume 1 of the dump"); if (gethead(&spcl) == FAIL) { - dprintf(stdout, "header read failed at %ld blocks\n", blksread); + Dprintf(stdout, "header read failed at %ld blocks\n", (long)blksread); panic("no header after volume mark!\n"); } findinode(&spcl); - if (spcl.c_type != TS_CLRI) { - fprintf(stderr, "Cannot find file removal list\n"); - done(1); - } + if (spcl.c_type != TS_CLRI) + errx(1, "Cannot find file removal list"); maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1; - dprintf(stdout, "maxino = %ld\n", maxino); + Dprintf(stdout, "maxino = %ld\n", maxino); map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); if (map == NULL) panic("no memory for active inode map\n"); usedinomap = map; curfile.action = USING; getfile(xtrmap, xtrmapskip); - if (spcl.c_type != TS_BITS) { - fprintf(stderr, "Cannot find file dump list\n"); - done(1); - } + if (spcl.c_type != TS_BITS) + errx(1, "Cannot find file dump list"); map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY)); if (map == (char *)NULL) panic("no memory for file dump list\n"); @@ -313,10 +292,9 @@ setup() * the user when only extracting a subset of the files. */ void -getvol(nextvol) - long nextvol; +getvol(long nextvol) { - long newvol=0, savecnt=0, wantnext=0, i; + long newvol = 0, savecnt = 0, wantnext = 0, i; union u_spcl tmpspcl; # define tmpbuf tmpspcl.s_spcl char buf[TP_BSIZE]; @@ -335,7 +313,7 @@ getvol(nextvol) savecnt = blksread; again: if (pipein) - done(1); /* pipes do not get a second chance */ + exit(1); /* pipes do not get a second chance */ if (command == 'R' || command == 'r' || curfile.action != SKIP) { newvol = nextvol; wantnext = 1; @@ -356,7 +334,7 @@ again: strcpy(buf, ": "); for (i = 1; i < 32; i++) if (tapesread & (1 << i)) { - fprintf(stderr, "%s%ld", buf, i); + fprintf(stderr, "%s%ld", buf, (long)i); strcpy(buf, ", "); } fprintf(stderr, "\n"); @@ -367,7 +345,7 @@ again: (void) fgets(buf, BUFSIZ, terminal); } while (!feof(terminal) && buf[0] == '\n'); if (feof(terminal)) - done(1); + exit(1); newvol = atoi(buf); if (newvol <= 0) { fprintf(stderr, @@ -379,13 +357,13 @@ again: return; } closemt(); - fprintf(stderr, "Mount tape volume %ld\n", newvol); + fprintf(stderr, "Mount tape volume %ld\n", (long)newvol); fprintf(stderr, "Enter ``none'' if there are no more tapes\n"); fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape); (void) fflush(stderr); (void) fgets(buf, BUFSIZ, terminal); if (feof(terminal)) - done(1); + exit(1); if (!strcmp(buf, "none\n")) { terminateinput(); return; @@ -411,7 +389,7 @@ gethdr: setdumpnum(); FLUSHTAPEBUF(); if (gethead(&tmpbuf) == FAIL) { - dprintf(stdout, "header read failed at %ld blocks\n", blksread); + Dprintf(stdout, "header read failed at %ld blocks\n", (long)blksread); fprintf(stderr, "tape is not dump tape\n"); volno = 0; goto again; @@ -443,8 +421,8 @@ gethdr: * If coming to this volume at random, skip to the beginning * of the next record. */ - dprintf(stdout, "read %ld recs, tape starts with %d\n", - tpblksread, tmpbuf.c_firstrec); + Dprintf(stdout, "read %ld recs, tape starts with %ld\n", + tpblksread, (long)tmpbuf.c_firstrec); if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) { if (!wantnext) { tpblksread = tmpbuf.c_firstrec; @@ -456,8 +434,8 @@ gethdr: * -1 since we've read the volume header */ i = tpblksread - tmpbuf.c_firstrec - 1; - dprintf(stderr, "Skipping %ld duplicate record%s.\n", - i, i > 1 ? "s" : ""); + Dprintf(stderr, "Skipping %ld duplicate record%s.\n", + (long)i, i > 1 ? "s" : ""); while (--i >= 0) readtape(buf); } @@ -477,7 +455,7 @@ gethdr: findinode(&spcl); if (gettingfile) { gettingfile = 0; - longjmp(restart, 1); + siglongjmp(restart, 1); } } @@ -485,7 +463,7 @@ gethdr: * Handle unexpected EOF. */ static void -terminateinput() +terminateinput(void) { if (gettingfile && curfile.action == USING) { @@ -498,7 +476,7 @@ terminateinput() curfile.ino = maxino; if (gettingfile) { gettingfile = 0; - longjmp(restart, 1); + siglongjmp(restart, 1); } } @@ -507,16 +485,14 @@ terminateinput() * appropriate one. */ static void -setdumpnum() +setdumpnum(void) { struct mtop tcom; if (dumpnum == 1 || volno != 1) return; - if (pipein) { - fprintf(stderr, "Cannot have multiple dumps on pipe input\n"); - done(1); - } + if (pipein) + errx(1, "Cannot have multiple dumps on pipe input"); tcom.mt_op = MTFSF; tcom.mt_count = dumpnum - 1; #ifdef RRESTORE @@ -525,11 +501,11 @@ setdumpnum() else #endif if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0) - fprintf(stderr, "ioctl MTFSF: %s\n", strerror(errno)); + warn("ioctl MTFSF"); } void -printdumpinfo() +printdumpinfo(void) { #ifdef __linux__ fprintf(stdout, "Dump date: %s", ctime4(&spcl.c_date)); @@ -548,18 +524,12 @@ printdumpinfo() } int -extractfile(name) - char *name; +extractfile(char *name) { - int flags; + unsigned int flags; mode_t mode; struct timeval timep[2]; struct entry *ep; -#ifdef __linux__ - int err; - uid_t uid; - gid_t gid; -#endif curfile.name = name; curfile.action = USING; @@ -584,7 +554,7 @@ extractfile(name) return (FAIL); case IFSOCK: - vprintf(stdout, "skipped socket %s\n", name); + Vprintf(stdout, "skipped socket %s\n", name); skipfile(); return (GOOD); @@ -596,33 +566,29 @@ extractfile(name) skipfile(); return (GOOD); } - vprintf(stdout, "extract file %s\n", name); + Vprintf(stdout, "extract file %s\n", name); return (genliteraldir(name, curfile.ino)); case IFLNK: + { uid_t luid = curfile.dip->di_uid; + gid_t lgid = curfile.dip->di_gid; + lnkbuf[0] = '\0'; pathlen = 0; -#ifdef __linux__ - uid = curfile.dip->di_uid; - gid = curfile.dip->di_gid; -#endif getfile(xtrlnkfile, xtrlnkskip); if (pathlen == 0) { - vprintf(stdout, + Vprintf(stdout, "%s: zero length symbolic link (ignored)\n", name); return (GOOD); } -#ifdef __linux__ - err = linkit(lnkbuf, name, SYMLINK); - if (err == GOOD) - (void) chown(name, uid, gid); - return (err); -#else - return (linkit(lnkbuf, name, SYMLINK)); -#endif + if (linkit(lnkbuf, name, SYMLINK) == FAIL) + return (FAIL); + (void) chown(name, luid, lgid); + return (GOOD); + } case IFIFO: - vprintf(stdout, "extract fifo %s\n", name); + Vprintf(stdout, "extract fifo %s\n", name); if (Nflag) { skipfile(); return (GOOD); @@ -630,8 +596,7 @@ extractfile(name) if (uflag && !Nflag) (void)unlink(name); if (mkfifo(name, mode) < 0) { - fprintf(stderr, "%s: cannot create fifo: %s\n", - name, strerror(errno)); + warn("%s: cannot create fifo", name); skipfile(); return (FAIL); } @@ -648,7 +613,7 @@ extractfile(name) case IFCHR: case IFBLK: - vprintf(stdout, "extract special file %s\n", name); + Vprintf(stdout, "extract special file %s\n", name); if (Nflag) { skipfile(); return (GOOD); @@ -656,8 +621,7 @@ extractfile(name) if (uflag) (void)unlink(name); if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) { - fprintf(stderr, "%s: cannot create special file: %s\n", - name, strerror(errno)); + warn("%s: cannot create special file", name); skipfile(); return (FAIL); } @@ -673,7 +637,7 @@ extractfile(name) return (GOOD); case IFREG: - vprintf(stdout, "extract file %s\n", name); + Vprintf(stdout, "extract file %s\n", name); if (Nflag) { skipfile(); return (GOOD); @@ -682,8 +646,7 @@ extractfile(name) (void)unlink(name); if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { - fprintf(stderr, "%s: cannot create file: %s\n", - name, strerror(errno)); + warn("%s: cannot create file", name); skipfile(); return (FAIL); } @@ -706,7 +669,7 @@ extractfile(name) * skip over bit maps on the tape */ void -skipmaps() +skipmaps(void) { while (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI) @@ -717,7 +680,7 @@ skipmaps() * skip over a file on the tape */ void -skipfile() +skipfile(void) { curfile.action = SKIP; @@ -731,15 +694,13 @@ skipfile() * to the skip function. */ void -getfile(fill, skip) - void (*fill) __P((char *, long)); - void (*skip) __P((char *, long)); +getfile(void (*fill) __P((char *, size_t)), void (*skip) __P((char *, size_t))) { register int i; - int curblk = 0; - quad_t size = spcl.c_dinode.di_size; - int last_write_was_hole = 0; - long origsize = size; + volatile int curblk = 0; + volatile quad_t size = spcl.c_dinode.di_size; + volatile int last_write_was_hole = 0; + quad_t origsize = size; static char clearedbuf[MAXBSIZE]; char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE]; char junk[TP_BSIZE]; @@ -756,14 +717,14 @@ loop: if (readmapflag || spcl.c_addr[i]) { readtape(&buf[curblk++][0]); if (curblk == fssize / TP_BSIZE) { - (*fill)((char *)buf, (long)(size > TP_BSIZE ? + (*fill)((char *)buf, (size_t)(size > TP_BSIZE ? fssize : (curblk - 1) * TP_BSIZE + size)); curblk = 0; last_write_was_hole = 0; } } else { if (curblk > 0) { - (*fill)((char *)buf, (long)(size > TP_BSIZE ? + (*fill)((char *)buf, (size_t)(size > TP_BSIZE ? curblk * TP_BSIZE : (curblk - 1) * TP_BSIZE + size)); curblk = 0; @@ -782,12 +743,12 @@ loop: if (gethead(&spcl) == GOOD && size > 0) { if (spcl.c_type == TS_ADDR) goto loop; - dprintf(stdout, + Dprintf(stdout, "Missing address (header) block for %s at %ld blocks\n", - curfile.name, blksread); + curfile.name, (long)blksread); } if (curblk > 0) { - (*fill)((char *)buf, (long)((curblk * TP_BSIZE) + size)); + (*fill)((char *)buf, (size_t)(curblk * TP_BSIZE) + size); last_write_was_hole = 0; } if (last_write_was_hole) { @@ -801,19 +762,14 @@ loop: * Write out the next block of a file. */ static void -xtrfile(buf, size) - char *buf; - long size; +xtrfile(char *buf, size_t size) { if (Nflag) return; - if (write(ofile, buf, (int) size) == -1) { - fprintf(stderr, - "write error extracting inode %ld, name %s\nwrite: %s\n", - curfile.ino, curfile.name, strerror(errno)); - done(1); - } + if (write(ofile, buf, (int) size) == -1) + err(1, "write error extracting inode %lu, name %s\nwrite", + (unsigned long)curfile.ino, curfile.name); } /* @@ -821,34 +777,25 @@ xtrfile(buf, size) */ /* ARGSUSED */ static void -xtrskip(buf, size) - char *buf; - long size; +xtrskip(char *buf, size_t size) { - if (lseek(ofile, size, SEEK_CUR) == -1) { - fprintf(stderr, - "seek error extracting inode %ld, name %s\nlseek: %s\n", - curfile.ino, curfile.name, strerror(errno)); - done(1); - } + if (lseek(ofile, (off_t)size, SEEK_CUR) == -1) + err(1, "seek error extracting inode %lu, name %s\nlseek", + (unsigned long)curfile.ino, curfile.name); } /* * Collect the next block of a symbolic link. */ static void -xtrlnkfile(buf, size) - char *buf; - long size; +xtrlnkfile(char *buf, size_t size) { pathlen += size; - if (pathlen > MAXPATHLEN) { - fprintf(stderr, "symbolic link name: %s->%s%s; too long %d\n", + if (pathlen > MAXPATHLEN) + errx(1, "symbolic link name: %s->%s%s; too long %d", curfile.name, lnkbuf, buf, pathlen); - done(1); - } (void) strcat(lnkbuf, buf); } @@ -857,23 +804,17 @@ xtrlnkfile(buf, size) */ /* ARGSUSED */ static void -xtrlnkskip(buf, size) - char *buf; - long size; +xtrlnkskip(char *buf, size_t size) { - fprintf(stderr, "unallocated block in symbolic link %s\n", - curfile.name); - done(1); + errx(1, "unallocated block in symbolic link %s", curfile.name); } /* * Collect the next block of a bit map. */ static void -xtrmap(buf, size) - char *buf; - long size; +xtrmap(char *buf, size_t size) { memmove(map, buf, size); @@ -885,9 +826,7 @@ xtrmap(buf, size) */ /* ARGSUSED */ static void -xtrmapskip(buf, size) - char *buf; - long size; +xtrmapskip(char *buf, size_t size) { panic("hole in map\n"); @@ -899,31 +838,26 @@ xtrmapskip(buf, size) */ /* ARGSUSED */ void -xtrnull(buf, size) - char *buf; - long size; +xtrnull(char *buf, size_t size) { return; } -int +static int do_cmpfiles(int fd_tape, int fd_disk, long size) { -#ifndef BUFSIZE -#define BUFSIZE 1024 -#endif static char buf_tape[BUFSIZ]; static char buf_disk[BUFSIZ]; - int n_tape; - int n_disk; + ssize_t n_tape; + ssize_t n_disk; while (size > 0) { - if ((n_tape = read(fd_tape, buf_tape, BUFSIZE)) < 1) { + if ((n_tape = read(fd_tape, buf_tape, sizeof(buf_tape))) < 1) { close(fd_tape), close(fd_disk); panic("do_cmpfiles: unexpected EOF[1]"); } - if ((n_disk = read(fd_disk, buf_disk, BUFSIZE)) < 1) { + if ((n_disk = read(fd_disk, buf_disk, sizeof(buf_tape))) < 1) { close(fd_tape), close(fd_disk); panic("do_cmpfiles: unexpected EOF[2]"); } @@ -931,7 +865,7 @@ do_cmpfiles(int fd_tape, int fd_disk, long size) close(fd_tape), close(fd_disk); panic("do_cmpfiles: sizes different!"); } - if (memcmp(buf_tape, buf_disk, n_tape) != 0) return (1); + if (memcmp(buf_tape, buf_disk, (size_t)n_tape) != 0) return (1); size -= n_tape; } return (0); @@ -940,6 +874,7 @@ do_cmpfiles(int fd_tape, int fd_disk, long size) /* for debugging compare problems */ #undef COMPARE_FAIL_KEEP_FILE +static #ifdef COMPARE_FAIL_KEEP_FILE /* return true if tapefile should be unlinked after compare */ int @@ -959,7 +894,7 @@ cmpfiles(char *tapefile, char *diskfile, struct stat *sbuf_disk) if (sbuf_disk->st_size != sbuf_tape.st_size) { fprintf(stderr, "%s: size changed from %ld to %ld.\n", - diskfile, sbuf_tape.st_size, sbuf_disk->st_size); + diskfile, (long)sbuf_tape.st_size, (long)sbuf_disk->st_size); #ifdef COMPARE_FAIL_KEEP_FILE return (0); #else @@ -989,7 +924,7 @@ cmpfiles(char *tapefile, char *diskfile, struct stat *sbuf_disk) if (!p) { panic("can't find / in %s\n", diskfile); } - sprintf(newname, "%s/debug/%s", tmpdir, p + 1); + snprintf(newname, sizeof(newname), "%s/debug/%s", tmpdir, p + 1); if (rename(tapefile, newname)) { panic("rename from %s to %s failed: %s\n", tapefile, newname, @@ -1014,11 +949,10 @@ cmpfiles(char *tapefile, char *diskfile, struct stat *sbuf_disk) #endif } -static char tmpfilename[128]; +static char tmpfilename[MAXPATHLEN]; void -comparefile(name) - char *name; +comparefile(char *name) { static char *tmpfile = NULL; int mode; @@ -1026,7 +960,7 @@ comparefile(name) int r; if ((r = lstat(name, &sb)) != 0) { - fprintf(stderr, "%s: does not exist (%d, %d).\n", name, r, errno); + warn("%s: does not exist (%d)", name, r); skipfile(); return; } @@ -1035,8 +969,8 @@ comparefile(name) curfile.action = USING; mode = curfile.dip->di_mode; - vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name, - sb.st_size, mode); + Vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name, + (long)sb.st_size, mode); if (sb.st_mode != mode) { fprintf(stderr, "%s: mode changed from 0%o to 0%o.\n", @@ -1100,10 +1034,10 @@ comparefile(name) fprintf(stderr, "%s: device changed from %d,%d to %d,%d.\n", name, - ((int)curfile.dip->di_rdev >> 8) & 0xf, - (int)curfile.dip->di_rdev & 0xf, - ((int)sb.st_rdev >> 8) & 0xf, - (int)sb.st_rdev & 0xf); + ((int)curfile.dip->di_rdev >> 8) & 0xff, + (int)curfile.dip->di_rdev & 0xff, + ((int)sb.st_rdev >> 8) & 0xff, + (int)sb.st_rdev & 0xff); } skipfile(); return; @@ -1111,7 +1045,7 @@ comparefile(name) case IFREG: if (tmpfile == NULL) { /* argument to mktemp() must not be in RO space: */ - sprintf(tmpfilename, "%s/restoreCXXXXXX", tmpdir); + snprintf(tmpfilename, sizeof(tmpfilename), "%s/restoreCXXXXXX", tmpdir); tmpfile = mktemp(&tmpfilename[0]); } if ((stat(tmpfile, &stemp) == 0) && (unlink(tmpfile) != 0)) { @@ -1141,14 +1075,13 @@ comparefile(name) * Handle read errors, and end of media. */ static void -readtape(buf) - char *buf; +readtape(char *buf) { - long rd, newvol, i; + ssize_t rd, newvol, i; int cnt, seek_failed; if (blkcnt < numtrec) { - memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE); + memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], TP_BSIZE); blksread++; tpblksread++; return; @@ -1171,7 +1104,7 @@ getmore: * If found, skip rest of buffer and start with the next. */ if (!pipein && numtrec < ntrec && i > 0) { - dprintf(stdout, "mid-media short read error.\n"); + Dprintf(stdout, "mid-media short read error.\n"); numtrec = ntrec; } /* @@ -1191,9 +1124,9 @@ getmore: * Short read. Process the blocks read. */ if (i % TP_BSIZE != 0) - vprintf(stdout, + Vprintf(stdout, "partial block read: %ld should be %ld\n", - i, ntrec * TP_BSIZE); + (long)i, ntrec * TP_BSIZE); numtrec = i / TP_BSIZE; } } @@ -1213,14 +1146,14 @@ getmore: fprintf(stderr, "restoring %s\n", curfile.name); break; case SKIP: - fprintf(stderr, "skipping over inode %ld\n", - curfile.ino); + fprintf(stderr, "skipping over inode %lu\n", + (unsigned long)curfile.ino); break; } if (!yflag && !reply("continue")) - done(1); + exit(1); i = ntrec * TP_BSIZE; - memset(tapebuf, 0, i); + memset(tapebuf, 0, (size_t)i); #ifdef RRESTORE if (host) seek_failed = (rmtseek(i, 1) < 0); @@ -1228,17 +1161,14 @@ getmore: #endif seek_failed = (lseek(mt, i, SEEK_CUR) == (off_t)-1); - if (seek_failed) { - fprintf(stderr, - "continuation failed: %s\n", strerror(errno)); - done(1); - } + if (seek_failed) + err(1, "continuation failed"); } /* * Handle end of tape. */ if (i == 0) { - vprintf(stdout, "End-of-tape encountered\n"); + Vprintf(stdout, "End-of-tape encountered\n"); if (!pipein) { newvol = volno + 1; volno = 0; @@ -1251,16 +1181,16 @@ getmore: panic("partial block read: %d should be %d\n", rd, ntrec * TP_BSIZE); terminateinput(); - memmove(&tapebuf[rd], &endoftapemark, (long)TP_BSIZE); + memmove(&tapebuf[rd], &endoftapemark, TP_BSIZE); } blkcnt = 0; - memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], (long)TP_BSIZE); + memmove(buf, &tapebuf[(blkcnt++ * TP_BSIZE)], TP_BSIZE); blksread++; tpblksread++; } static void -findtapeblksize() +findtapeblksize(void) { register long i; @@ -1269,27 +1199,23 @@ findtapeblksize() blkcnt = 0; #ifdef RRESTORE if (host) - i = rmtread(tapebuf, ntrec * TP_BSIZE); + i = rmtread(tapebuf, (size_t)(ntrec * TP_BSIZE)); else #endif - i = read(mt, tapebuf, ntrec * TP_BSIZE); + i = read(mt, tapebuf, (size_t)(ntrec * TP_BSIZE)); - if (i <= 0) { - fprintf(stderr, "tape read error: %s\n", strerror(errno)); - done(1); - } - if (i % TP_BSIZE != 0) { - fprintf(stderr, "Tape block size (%ld) %s (%d)\n", - i, "is not a multiple of dump block size", TP_BSIZE); - done(1); - } + if (i <= 0) + err(1, "tape read error"); + if (i % TP_BSIZE != 0) + errx(1, "Tape block size (%ld) is not a multiple of dump block size (%d)", + (long)i, TP_BSIZE); ntrec = i / TP_BSIZE; numtrec = ntrec; - vprintf(stdout, "Tape block size is %ld\n", ntrec); + Vprintf(stdout, "Tape block size is %ld\n", ntrec); } void -closemt() +closemt(void) { if (mt < 0) @@ -1309,10 +1235,9 @@ closemt() * If it is not any valid header, return an error. */ static int -gethead(buf) - struct s_spcl *buf; +gethead(struct s_spcl *buf) { - long i; + int32_t i; union { quad_t qval; int32_t val[2]; @@ -1325,14 +1250,14 @@ gethead(buf) int32_t c_ddate; int32_t c_volume; int32_t c_tapea; - u_short c_inumber; + u_int16_t c_inumber; int32_t c_magic; int32_t c_checksum; struct odinode { - unsigned short odi_mode; - u_short odi_nlink; - u_short odi_uid; - u_short odi_gid; + u_int16_t odi_mode; + u_int16_t odi_nlink; + u_int16_t odi_uid; + u_int16_t odi_gid; int32_t odi_size; int32_t odi_rdev; char odi_addr[36]; @@ -1348,24 +1273,21 @@ gethead(buf) if (!cvtflag) { readtape((char *)buf); if (buf->c_magic != NFS_MAGIC) { - if (swabl(buf->c_magic) != NFS_MAGIC) + if (swabi(buf->c_magic) != NFS_MAGIC) return (FAIL); if (!Bcvt) { - vprintf(stdout, "Note: Doing Byte swapping\n"); + Vprintf(stdout, "Note: Doing Byte swapping\n"); Bcvt = 1; } } if (checksum((int *)buf) == FAIL) return (FAIL); - if (Bcvt) { - swabst((u_char *)"8l4s31l", (u_char *)buf); - swabst((u_char *)"l",(u_char *) &buf->c_level); - swabst((u_char *)"2l",(u_char *) &buf->c_flags); - } + if (Bcvt) + swabst((u_char *)"8i4s31i528bi192b2i", (u_char *)buf); goto good; } readtape((char *)(&u_ospcl.s_ospcl)); - memset(buf, 0, (long)TP_BSIZE); + memset((char *)buf, 0, (long)TP_BSIZE); buf->c_type = u_ospcl.s_ospcl.c_type; buf->c_date = u_ospcl.s_ospcl.c_date; buf->c_ddate = u_ospcl.s_ospcl.c_ddate; @@ -1463,8 +1385,7 @@ good: * Check that a header is where it belongs and predict the next header */ static void -accthdr(header) - struct s_spcl *header; +accthdr(struct s_spcl *header) { static ino_t previno = 0x7fffffff; static int prevtype; @@ -1491,7 +1412,7 @@ accthdr(header) fprintf(stderr, "Used inodes map header"); break; case TS_INODE: - fprintf(stderr, "File header, ino %ld", previno); + fprintf(stderr, "File header, ino %lu", (unsigned long)previno); break; case TS_ADDR: fprintf(stderr, "File continuation header, ino %ld", previno); @@ -1521,8 +1442,7 @@ newcalc: * Complain if had to skip, and complain is set. */ static void -findinode(header) - struct s_spcl *header; +findinode(struct s_spcl *header) { static long skipcnt = 0; long i; @@ -1587,8 +1507,7 @@ findinode(header) } static int -checksum(buf) - register int *buf; +checksum(int *buf) { register int i, j; @@ -1602,27 +1521,27 @@ checksum(buf) /* What happens if we want to read restore tapes for a 16bit int machine??? */ do - i += swabl(*buf++); + i += swabi(*buf++); while (--j); } if (i != CHECKSUM) { - fprintf(stderr, "Checksum error %o, inode %ld file %s\n", i, - curfile.ino, curfile.name); + fprintf(stderr, "Checksum error %o, inode %lu file %s\n", i, + (unsigned long)curfile.ino, curfile.name); return(FAIL); } return(GOOD); } #ifdef RRESTORE -#if __STDC__ +#ifdef __STDC__ #include #else #include #endif void -#if __STDC__ +#ifdef __STDC__ msg(const char *fmt, ...) #else msg(fmt, va_alist) @@ -1631,7 +1550,7 @@ msg(fmt, va_alist) #endif { va_list ap; -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); @@ -1642,9 +1561,7 @@ msg(fmt, va_alist) #endif /* RRESTORE */ static u_char * -swabshort(sp, n) - register u_char *sp; - register int n; +swab16(u_char *sp, int n) { char c; @@ -1656,23 +1573,35 @@ swabshort(sp, n) } static u_char * -swablong(sp, n) - register u_char *sp; - register int n; +swab32(u_char *sp, int n) { char c; while (--n >= 0) { c = sp[0]; sp[0] = sp[3]; sp[3] = c; - c = sp[2]; sp[2] = sp[1]; sp[1] = c; + c = sp[1]; sp[1] = sp[2]; sp[2] = c; sp += 4; } return (sp); } +static u_char * +swab64(u_char *sp, int n) +{ + char c; + + while (--n >= 0) { + c = sp[0]; sp[0] = sp[7]; sp[7] = c; + c = sp[1]; sp[1] = sp[6]; sp[6] = c; + c = sp[2]; sp[2] = sp[5]; sp[5] = c; + c = sp[3]; sp[3] = sp[4]; sp[4] = c; + sp += 8; + } + return (sp); +} + void -swabst(cp, sp) - register u_char *cp, *sp; +swabst(u_char *cp, u_char *sp) { int n = 0; @@ -1686,13 +1615,19 @@ swabst(cp, sp) case 's': case 'w': case 'h': if (n == 0) n = 1; - sp = swabshort(sp, n); + sp = swab16(sp, n); + break; + + case 'i': + if (n == 0) + n = 1; + sp = swab32(sp, n); break; case 'l': if (n == 0) n = 1; - sp = swablong(sp, n); + sp = swab64(sp, n); break; default: /* Any other character, like 'b' counts as byte. */ @@ -1706,9 +1641,15 @@ swabst(cp, sp) } } +static u_int +swabi(u_int x) +{ + swabst((u_char *)"i", (u_char *)&x); + return (x); +} + static u_long -swabl(x) - u_long x; +swabl(u_long x) { swabst((u_char *)"l", (u_char *)&x); return (x); diff --git a/restore/utilities.c b/restore/utilities.c index c93c854..7c3bcd8 100644 --- a/restore/utilities.c +++ b/restore/utilities.c @@ -44,7 +44,7 @@ static char sccsid[] = "@(#)utilities.c 8.5 (Berkeley) 4/28/95"; #endif static const char rcsid[] = - "$Id: utilities.c,v 1.2 1999/10/11 12:53:25 stelian Exp $"; + "$Id: utilities.c,v 1.3 1999/10/11 12:59:21 stelian Exp $"; #endif /* not lint */ #include @@ -60,6 +60,7 @@ static const char rcsid[] = #endif /* __linux__ */ #include +#include #include #include #include @@ -75,8 +76,7 @@ static const char rcsid[] = * Insure that all the components of a pathname exist. */ void -pathcheck(name) - char *name; +pathcheck(char *name) { register char *cp; struct entry *ep; @@ -104,8 +104,7 @@ pathcheck(name) * Change a name to a unique temporary name. */ void -mktempname(ep) - register struct entry *ep; +mktempname(struct entry *ep) { char oldname[MAXPATHLEN]; @@ -123,8 +122,7 @@ mktempname(ep) * Generate a temporary name for an entry. */ char * -gentempname(ep) - struct entry *ep; +gentempname(struct entry *ep) { static char name[MAXPATHLEN]; struct entry *np; @@ -135,7 +133,7 @@ gentempname(ep) i++; if (np == NULL) badentry(ep, "not on ino list"); - (void) sprintf(name, "%s%ld%lu", TMPHDR, i, (u_long)ep->e_ino); + (void) snprintf(name, sizeof(name), "%s%ld%lu", TMPHDR, i, (unsigned long)ep->e_ino); return (name); } @@ -143,23 +141,20 @@ gentempname(ep) * Rename a file or directory. */ void -renameit(from, to) - char *from, *to; +renameit(char *from, char *to) { if (!Nflag && rename(from, to) < 0) { - fprintf(stderr, "warning: cannot rename %s to %s: %s\n", - from, to, strerror(errno)); + warn("cannot rename %s to %s", from, to); return; } - vprintf(stdout, "rename %s to %s\n", from, to); + Vprintf(stdout, "rename %s to %s\n", from, to); } /* * Create a new node (directory). */ void -newnode(np) - struct entry *np; +newnode(struct entry *np) { char *cp; @@ -170,18 +165,17 @@ newnode(np) if (!Nflag && mkdir(cp, 0777) < 0 && !uflag) { np->e_flags |= EXISTED; - fprintf(stderr, "warning: %s: %s\n", cp, strerror(errno)); + warn("%s", cp); return; } - vprintf(stdout, "Make node %s\n", cp); + Vprintf(stdout, "Make node %s\n", cp); } /* * Remove an old node (directory). */ void -removenode(ep) - register struct entry *ep; +removenode(struct entry *ep) { char *cp; @@ -193,18 +187,17 @@ removenode(ep) ep->e_flags &= ~TMPNAME; cp = myname(ep); if (!Nflag && rmdir(cp) < 0) { - fprintf(stderr, "warning: %s: %s\n", cp, strerror(errno)); + warn("%s", cp); return; } - vprintf(stdout, "Remove node %s\n", cp); + Vprintf(stdout, "Remove node %s\n", cp); } /* * Remove a leaf. */ void -removeleaf(ep) - register struct entry *ep; +removeleaf(struct entry *ep) { char *cp; @@ -216,19 +209,17 @@ removeleaf(ep) ep->e_flags &= ~TMPNAME; cp = myname(ep); if (!Nflag && unlink(cp) < 0) { - fprintf(stderr, "warning: %s: %s\n", cp, strerror(errno)); + warn("%s", cp); return; } - vprintf(stdout, "Remove leaf %s\n", cp); + Vprintf(stdout, "Remove leaf %s\n", cp); } /* * Create a link. */ int -linkit(existing, new, type) - char *existing, *new; - int type; +linkit(char *existing, char *new, int type) { /* if we want to unlink first, do it now so *link() won't fail */ @@ -237,9 +228,8 @@ linkit(existing, new, type) if (type == SYMLINK) { if (!Nflag && symlink(existing, new) < 0) { - fprintf(stderr, - "warning: cannot create symbolic link %s->%s: %s\n", - new, existing, strerror(errno)); + warn("cannot create symbolic link %s->%s", + new, existing); return (FAIL); } } else if (type == HARDLINK) { @@ -261,9 +251,8 @@ linkit(existing, new, type) } #endif if (ret < 0) { - fprintf(stderr, "warning: cannot create " - "hard link %s->%s: %s\n", - new, existing, strerror(errno)); + warn("warning: cannot create hard link %s->%s", + new, existing); return (FAIL); } } @@ -271,7 +260,7 @@ linkit(existing, new, type) panic("linkit: unknown type %d\n", type); return (FAIL); } - vprintf(stdout, "Create %s link %s->%s\n", + Vprintf(stdout, "Create %s link %s->%s\n", type == SYMLINK ? "symbolic" : "hard", new, existing); return (GOOD); } @@ -281,16 +270,14 @@ linkit(existing, new, type) * Create a whiteout. */ int -addwhiteout(name) - char *name; +addwhiteout(char *name) { if (!Nflag && mknod(name, S_IFWHT, 0) < 0) { - fprintf(stderr, "warning: cannot create whiteout %s: %s\n", - name, strerror(errno)); + warn("cannot create whiteout %s", name); return (FAIL); } - vprintf(stdout, "Create whiteout %s\n", name); + Vprintf(stdout, "Create whiteout %s\n", name); return (GOOD); } @@ -298,8 +285,7 @@ addwhiteout(name) * Delete a whiteout. */ void -delwhiteout(ep) - register struct entry *ep; +delwhiteout(struct entry *ep) { char *name; @@ -309,11 +295,10 @@ delwhiteout(ep) ep->e_flags &= ~TMPNAME; name = myname(ep); if (!Nflag && undelete(name) < 0) { - fprintf(stderr, "warning: cannot delete whiteout %s: %s\n", - name, strerror(errno)); + warn("cannot delete whiteout %s", name); return; } - vprintf(stdout, "Delete whiteout %s\n", name); + Vprintf(stdout, "Delete whiteout %s\n", name); } #endif @@ -321,8 +306,7 @@ delwhiteout(ep) * find lowest number file (above "start") that needs to be extracted */ ino_t -lowerbnd(start) - ino_t start; +lowerbnd(ino_t start) { register struct entry *ep; @@ -340,8 +324,7 @@ lowerbnd(start) * find highest number file (below "start") that needs to be extracted */ ino_t -upperbnd(start) - ino_t start; +upperbnd(ino_t start) { register struct entry *ep; @@ -359,9 +342,7 @@ upperbnd(start) * report on a badly formed entry */ void -badentry(ep, msg) - register struct entry *ep; - char *msg; +badentry(struct entry *ep, const char *msg) { fprintf(stderr, "bad entry: %s\n", msg); @@ -378,7 +359,7 @@ badentry(ep, msg) "next hashchain name: %s\n", myname(ep->e_next)); fprintf(stderr, "entry type: %s\n", ep->e_type == NODE ? "NODE" : "LEAF"); - fprintf(stderr, "inode number: %lu\n", (u_long)ep->e_ino); + fprintf(stderr, "inode number: %lu\n", (unsigned long)ep->e_ino); panic("flags: %s\n", flagvalues(ep)); } @@ -386,8 +367,7 @@ badentry(ep, msg) * Construct a string indicating the active flag bits of an entry. */ char * -flagvalues(ep) - register struct entry *ep; +flagvalues(struct entry *ep) { static char flagbuf[BUFSIZ]; @@ -412,8 +392,7 @@ flagvalues(ep) * Check to see if a name is on a dump tape. */ ino_t -dirlookup(name) - const char *name; +dirlookup(const char *name) { struct direct *dp; ino_t ino; @@ -429,8 +408,7 @@ dirlookup(name) * Elicit a reply. */ int -reply(question) - char *question; +reply(const char *question) { char c; @@ -450,14 +428,14 @@ reply(question) /* * handle unexpected inconsistencies */ -#if __STDC__ +#ifdef __STDC__ #include #else #include #endif void -#if __STDC__ +#ifdef __STDC__ panic(const char *fmt, ...) #else panic(fmt, va_alist) @@ -466,7 +444,7 @@ panic(fmt, va_alist) #endif { va_list ap; -#if __STDC__ +#ifdef __STDC__ va_start(ap, fmt); #else va_start(ap); @@ -478,6 +456,6 @@ panic(fmt, va_alist) if (reply("abort") == GOOD) { if (reply("dump core") == GOOD) abort(); - done(1); + exit(1); } } diff --git a/rmt/Makefile.in b/rmt/Makefile.in index 8cc2286..973d942 100644 --- a/rmt/Makefile.in +++ b/rmt/Makefile.in @@ -3,7 +3,7 @@ srcdir= @srcdir@ @MCONFIG@ -CFLAGS= @CCOPTS@ -pipe $(GINC) $(INC) $(DEFS) +CFLAGS= @CCOPTS@ -pipe $(OPT) $(GINC) $(INC) $(DEFS) LDFLAGS:= $(LDFLAGS) @STATIC@ LIBS= $(GLIBS) diff --git a/rmt/rmt.c b/rmt/rmt.c index b8cd3f6..92353af 100644 --- a/rmt/rmt.c +++ b/rmt/rmt.c @@ -50,7 +50,7 @@ static const char copyright[] = static char sccsid[] = "@(#)rmt.c 8.1 (Berkeley) 6/6/93"; #endif static const char rcsid[] = - "$Id: rmt.c,v 1.2 1999/10/11 12:53:25 stelian Exp $"; + "$Id: rmt.c,v 1.3 1999/10/11 12:59:21 stelian Exp $"; #endif /* not lint */ /* @@ -67,6 +67,12 @@ static const char rcsid[] = #include #include +#ifdef __linux__ +#include +#include +#include +#endif + int tape = -1; char *record; @@ -88,11 +94,9 @@ void error __P((int)); void getstring __P((char *)); int -main(argc, argv) - int argc; - char **argv; +main(int argc, char *argv[]) { - int rval; + int rval = 0; char c; int n, i, cc; @@ -218,9 +222,7 @@ ioerror: goto top; } -void -getstring(bp) - char *bp; +void getstring(char *bp) { int i; char *cp = bp; @@ -235,9 +237,7 @@ getstring(bp) } char * -checkbuf(record, size) - char *record; - int size; +checkbuf(char *record, int size) { if (size <= maxrecsize) @@ -257,8 +257,7 @@ checkbuf(record, size) } void -error(num) - int num; +error(int num) { DEBUG2("rmtd: E %d (%s)\n", num, strerror(num));