From b45f51d61e911ac8a040bef1efda6afd82261e03 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Mon, 11 Oct 1999 12:53:05 +0000 Subject: [PATCH] Version 0.4b5. --- CHANGES | 17 +++ COPYRIGHT | 3 +- KNOWNBUGS | 4 + MAINTAINERS | 13 ++ README | 2 +- THANKS | 3 + TODO | 10 +- common/dumprmt.c | 131 +++++++++++++------ compat/include/bsdcompat.h | 4 +- compat/include/err.h | 10 +- compat/include/fstab.h | 3 +- compat/include/glob.h | 5 +- compat/include/pathnames.h | 5 +- compat/include/protocols/dumprestore.h | 29 +++-- compat/include/tzfile.h | 158 ----------------------- compat/lib/err.c | 172 +++++++++++++++---------- compat/lib/fstab.c | 5 +- compat/lib/glob.c | 91 +++++++------ config.h.in | 12 ++ config.sub | 2 +- configure | 2 +- configure.in | 2 +- dump.lsm | 10 +- dump/dump.8 | 142 ++++++++++++++------ dump/dump.h | 11 +- dump/itime.c | 9 +- dump/main.c | 168 ++++++++++++++++-------- dump/optr.c | 27 ++-- dump/tape.c | 127 ++++++++++++------ dump/traverse.c | 73 ++++++++--- dump/unctime.c | 14 +- restore/dirs.c | 101 ++++++++------- restore/extern.h | 12 +- restore/interactive.c | 66 +++++----- restore/main.c | 65 +++++++--- restore/restore.8 | 57 ++++++-- restore/restore.c | 51 +++++--- restore/restore.h | 6 +- restore/symtab.c | 36 ++++-- restore/tape.c | 166 ++++++++++++++---------- restore/utilities.c | 53 ++++++-- rmt/rmt.8 | 8 +- rmt/rmt.c | 24 +++- 43 files changed, 1142 insertions(+), 767 deletions(-) create mode 100644 MAINTAINERS delete mode 100644 compat/include/tzfile.h diff --git a/CHANGES b/CHANGES index 301bf72..db2f470 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,20 @@ +Changes between versions 0.4b4 and 0.4b5 +======================================== + +1. Integrated the changes from FreeBSD-3.1-RELEASE + (mostly bug fixes, buffer overruns, dump has now an "automatic + tape length calculation" flag, dump/restore can use kerberos now + (this is NOT tested), use environment variables for TAPE and + RMT etc.). + +2. Integrated three RedHat patches ("glibc", "kernel" and "bread" patches) + +3. Corrected a bug in restore when using 'C' option with multi-volumes + tapes (files splited accros two tapes give "size changed" errors + when comparing). + +4. Corrected the long standing bug when dumping multiple tapes. + This works for me, needs further testing. Changes between versions 0.4b3 and 0.4b4 ======================================== diff --git a/COPYRIGHT b/COPYRIGHT index ce4bd12..c46bebd 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ diff --git a/KNOWNBUGS b/KNOWNBUGS index 61d3a3e..4776dca 100644 --- a/KNOWNBUGS +++ b/KNOWNBUGS @@ -5,7 +5,11 @@ Known bugs and limitations of the dump/restore port resynchronizing itself on a multi-volume dump. Thus, some files are not restored. + Update: this is fixed in 4.0b5, needs succes reports! + 2. I have tried to minimize changes in the BSD source and some parts may look ugly. dump/tape.c is really awfull but this is pure BSD code :-) Maybe, I should replace it with a simpler and cleaner version. + +3. Kerberos mode is _NOT_ tested. diff --git a/MAINTAINERS b/MAINTAINERS new file mode 100644 index 0000000..f8428a6 --- /dev/null +++ b/MAINTAINERS @@ -0,0 +1,13 @@ +The dump and restore backup suit was ported to Linux's Second +Extended File System by Rémy Card + +He was the maintainer of the initial versions of dump (up and +including 0.4b4, released in january 1997). + +I decided to continue the developpement and release a new version. +Rémy didn't respond to any mail I sent to him, so I have +promoted myself as the new maintainer :) + +So, starting with 0.4b5, the new maintainer is me, +Stelian Pop . + diff --git a/README b/README index 24b7fc5..63d4f10 100644 --- a/README +++ b/README @@ -6,4 +6,4 @@ See the file INSTALL for installation instructions. If you encounter problems with the dump and restore backup suite, -please contact me (card@Linux.EU.Org) and send me a detailled bug report. +please contact the maintainers and send them a detailled bug report. diff --git a/THANKS b/THANKS index 1ffb24a..4d5ed14 100644 --- a/THANKS +++ b/THANKS @@ -12,6 +12,9 @@ filesystems. David Frey (the Debian dump maintainer) and the people from Red Hat Software provided lots of patches. +Stelian Pop is now the current maintainer (since +dump-0.4b5). + 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): diff --git a/TODO b/TODO index 03a2efc..33b773f 100644 --- a/TODO +++ b/TODO @@ -1,13 +1,7 @@ -1. Fix the multi-volume problem (is there one after all?, I could not - reproduce it and some people told me that multi-volume dumps were Ok). - -2. Make dump honor the no-dump attribute on directories. Currently, it +1. Make dump honor the no-dump attribute on directories. Currently, it honours it only on files. This means that a directory flagged with the no-dump attribute will be dumped if it contains a file without the no-dump flag. -3. Change the way rdump and rrestore call rmt. Currently, rcmd() is used - but it may be better to call rsh. I have to look at the GNU tar code. - -4. Make dump able to backup several directories and/or files in one +2. Make dump able to backup several directories and/or files in one invocation, like the SunOS version. diff --git a/common/dumprmt.c b/common/dumprmt.c index cdb79c1..da71748 100644 --- a/common/dumprmt.c +++ b/common/dumprmt.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,17 +40,25 @@ */ #ifndef lint -static char sccsid[] = "@(#)dumprmt.c 8.2 (Berkeley) 4/28/95"; +#if 0 +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 $"; #endif /* not lint */ +#ifdef __linux__ +#include +#include +#endif #include #include -#include #include #include #ifdef __linux__ #include #include +#include #else #ifdef sunos #include @@ -61,15 +70,15 @@ static char sccsid[] = "@(#)dumprmt.c 8.2 (Berkeley) 4/28/95"; #endif #include +#include +#include #include #include #include -#include #include #include -#include #include #ifdef __STDC__ #include @@ -98,7 +107,12 @@ static int rmtgetb __P((void)); static void rmtgetconn __P((void)); static void rmtgets __P((char *, int)); static int rmtreply __P((char *)); +#ifdef KERBEROS +int krcmd __P((char **, int /*u_short*/, char *, char *, int *, char *)); +#endif +static int errfd = -1; +extern int dokerberos; extern int ntrec; /* blocking factor on tape */ int @@ -121,41 +135,79 @@ rmthost(host) static void rmtconnaborted() { + msg("Lost connection to remote host.\n"); + if (errfd != -1) { + fd_set r; + struct timeval t; + + FD_ZERO(&r); + FD_SET(errfd, &r); + t.tv_sec = 0; + t.tv_usec = 0; + if (select(errfd + 1, &r, NULL, NULL, &t)) { + int i; + char buf[2048]; + + if ((i = read(errfd, buf, sizeof(buf) - 1)) > 0) { + buf[i] = '\0'; + msg("on %s: %s%s", rmtpeer, buf, + buf[i - 1] == '\n' ? "" : "\n"); + } + } + } - errx(1, "Lost connection to remote host."); + exit(X_ABORT); } void rmtgetconn() { register char *cp; + register const char *rmt; static struct servent *sp = NULL; static struct passwd *pwd = NULL; -#ifdef notdef - static int on = 1; -#endif char *tuser; int size; - int maxseg; + int throughput; + int on; if (sp == NULL) { - sp = getservbyname("shell", "tcp"); - if (sp == NULL) - errx(1, "shell/tcp: unknown service"); + sp = getservbyname(dokerberos ? "kshell" : "shell", "tcp"); + if (sp == NULL) { + msg("%s/tcp: unknown service\n", + dokerberos ? "kshell" : "shell"); + exit(X_STARTUP); + } pwd = getpwuid(getuid()); - if (pwd == NULL) - errx(1, "who are you?"); + if (pwd == NULL) { + msg("who are you?\n"); + exit(X_STARTUP); + } } if ((cp = strchr(rmtpeer, '@')) != NULL) { tuser = rmtpeer; *cp = '\0'; if (!okname(tuser)) - exit(1); + exit(X_STARTUP); rmtpeer = ++cp; } else tuser = pwd->pw_name; - rmtape = rcmd(&rmtpeer, (u_short)sp->s_port, pwd->pw_name, tuser, - _PATH_RMT, (int *)0); + if ((rmt = getenv("RMT")) == NULL) + rmt = _PATH_RMT; + msg(""); +#ifdef KERBEROS + if (dokerberos) + rmtape = krcmd(&rmtpeer, sp->s_port, tuser, rmt, &errfd, + (char *)0); + else +#endif + rmtape = rcmd(&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); + return; + } + (void)fprintf(stderr, "Connection to %s established.\n", rmtpeer); size = ntrec * TP_BSIZE; if (size > 60 * 1024) /* XXX */ size = 60 * 1024; @@ -165,15 +217,13 @@ rmtgetconn() setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0) size -= TP_BSIZE; (void)setsockopt(rmtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)); - maxseg = 1024; - if (setsockopt(rmtape, IPPROTO_TCP, TCP_MAXSEG, - &maxseg, sizeof (maxseg)) < 0) - perror("TCP_MAXSEG setsockopt"); - -#ifdef notdef + throughput = IPTOS_THROUGHPUT; + if (setsockopt(rmtape, IPPROTO_IP, IP_TOS, + &throughput, sizeof(throughput)) < 0) + perror("IP_TOS:IPTOS_THROUGHPUT setsockopt"); + on = 1; if (setsockopt(rmtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0) perror("TCP_NODELAY setsockopt"); -#endif } static int @@ -186,7 +236,7 @@ okname(cp0) for (cp = cp0; *cp; cp++) { c = *cp; if (!isascii(c) || !(isalnum(c) || c == '_' || c == '-')) { - warnx("invalid user name: %s", cp0); + msg("invalid user name %s\n", cp0); return (0); } } @@ -200,7 +250,7 @@ rmtopen(tape, mode) { char buf[256]; - (void)sprintf(buf, "O%s\n%d\n", tape, mode); + (void)snprintf(buf, sizeof (buf), "O%.226s\n%d\n", tape, mode); rmtstate = TS_OPEN; return (rmtcall(tape, buf)); } @@ -222,19 +272,16 @@ rmtread(buf, count) { char line[30]; int n, i, cc; - extern errno; - (void)sprintf(line, "R%d\n", count); + (void)snprintf(line, sizeof (line), "R%d\n", count); n = rmtcall("read", line); - if (n < 0) { - errno = n; - return (-1); - } + if (n < 0) + /* rmtcall() properly sets errno for us on errors. */ + return (n); for (i = 0; i < n; i += cc) { cc = read(rmtape, buf+i, n - i); - if (cc <= 0) { + if (cc <= 0) rmtconnaborted(); - } } return (n); } @@ -246,7 +293,7 @@ rmtwrite(buf, count) { char line[30]; - (void)sprintf(line, "W%d\n", count); + (void)snprintf(line, sizeof (line), "W%d\n", count); write(rmtape, line, strlen(line)); write(rmtape, buf, count); return (rmtreply("write")); @@ -258,7 +305,7 @@ rmtwrite0(count) { char line[30]; - (void)sprintf(line, "W%d\n", count); + (void)snprintf(line, sizeof (line), "W%d\n", count); write(rmtape, line, strlen(line)); } @@ -284,7 +331,7 @@ rmtseek(offset, pos) { char line[80]; - (void)sprintf(line, "L%d\n%d\n", offset, pos); + (void)snprintf(line, sizeof (line), "L%d\n%d\n", offset, pos); return (rmtcall("seek", line)); } @@ -312,7 +359,7 @@ rmtioctl(cmd, count) if (count < 0) return (-1); - (void)sprintf(buf, "I%d\n%d\n", cmd, count); + (void)snprintf(buf, sizeof (buf), "I%d\n%d\n", cmd, count); return (rmtcall("ioctl", buf)); } @@ -332,15 +379,15 @@ rmtreply(cmd) { register char *cp; char code[30], emsg[BUFSIZ]; + extern int errno; rmtgets(code, sizeof (code)); if (*code == 'E' || *code == 'F') { rmtgets(emsg, sizeof (emsg)); msg("%s: %s", cmd, emsg); - if (*code == 'F') { + errno = atoi(code + 1); + if (*code == 'F') rmtstate = TS_CLOSED; - return (-1); - } return (-1); } if (*code != 'A') { diff --git a/compat/include/bsdcompat.h b/compat/include/bsdcompat.h index c697cab..a29421e 100644 --- a/compat/include/bsdcompat.h +++ b/compat/include/bsdcompat.h @@ -1,11 +1,13 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ #include +#include #define __dead volatile diff --git a/compat/include/err.h b/compat/include/err.h index 6b23d13..8e168d5 100644 --- a/compat/include/err.h +++ b/compat/include/err.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -38,6 +39,7 @@ * 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_ @@ -58,12 +60,18 @@ __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/fstab.h b/compat/include/fstab.h index 5b00e7a..f479edc 100644 --- a/compat/include/fstab.h +++ b/compat/include/fstab.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ diff --git a/compat/include/glob.h b/compat/include/glob.h index 5cb9c54..d32114e 100644 --- a/compat/include/glob.h +++ b/compat/include/glob.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -77,14 +78,12 @@ typedef struct { #define GLOB_NOCHECK 0x0010 /* Return pattern itself if nothing matches. */ #define GLOB_NOSORT 0x0020 /* Don't sort. */ -/* #ifndef _POSIX_SOURCE */ #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. */ -/* #endif */ #define GLOB_NOSPACE (-1) /* Malloc call failed. */ #define GLOB_ABEND (-2) /* Unignored error. */ diff --git a/compat/include/pathnames.h b/compat/include/pathnames.h index a4f4267..0bcf788 100644 --- a/compat/include/pathnames.h +++ b/compat/include/pathnames.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -46,4 +47,4 @@ #define _PATH_DTMP "/etc/dtmp" #define _PATH_DUMPDATES "/etc/dumpdates" #define _PATH_LOCK "/tmp/dumplockXXXXXX" -#define _PATH_RMT "rmt" +#define _PATH_RMT "/etc/rmt" /* path on remote host */ diff --git a/compat/include/protocols/dumprestore.h b/compat/include/protocols/dumprestore.h index ef74c39..72e999a 100644 --- a/compat/include/protocols/dumprestore.h +++ b/compat/include/protocols/dumprestore.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -45,8 +46,8 @@ * @(#)dumprestore.h 8.2 (Berkeley) 1/21/94 */ -#ifndef _DUMPRESTORE_H_ -#define _DUMPRESTORE_H_ +#ifndef _PROTOCOLS_DUMPRESTORE_H_ +#define _PROTOCOLS_DUMPRESTORE_H_ /* * TP_BSIZE is the size of file blocks on the dump tapes. @@ -74,29 +75,29 @@ union u_spcl { char dummy[TP_BSIZE]; struct s_spcl { - __s32 c_type; /* record type (see below) */ - __u32 c_date; /* date of this dump */ - __u32 c_ddate; /* date of previous dump */ - __s32 c_volume; /* dump volume number */ + int32_t c_type; /* record type (see below) */ + time_t c_date; /* date of this dump */ + time_t c_ddate; /* date of previous dump */ + int32_t c_volume; /* dump volume number */ daddr_t c_tapea; /* logical block of this record */ ino_t c_inumber; /* number of inode */ - __s32 c_magic; /* magic number (see above) */ - __s32 c_checksum; /* record checksum */ + int32_t c_magic; /* magic number (see above) */ + int32_t c_checksum; /* record checksum */ #ifdef __linux__ struct new_bsd_inode c_dinode; #else struct dinode c_dinode; /* ownership and mode of inode */ #endif - __s32 c_count; /* number of valid c_addr entries */ + int32_t c_count; /* number of valid c_addr entries */ char c_addr[TP_NINDIR]; /* 1 => data; 0 => hole in inode */ char c_label[LBLSIZE]; /* dump label */ - __s32 c_level; /* level of this dump */ + int32_t c_level; /* level of this dump */ char c_filesys[NAMELEN]; /* name of dumpped file system */ char c_dev[NAMELEN]; /* name of dumpped device */ char c_host[NAMELEN]; /* name of dumpped host */ - __s32 c_flags; /* additional information */ - __s32 c_firstrec; /* first record on volume */ - __s32 c_spare[32]; /* reserved for future uses */ + int32_t c_flags; /* additional information */ + int32_t c_firstrec; /* first record on volume */ + int32_t c_spare[32]; /* reserved for future uses */ } s_spcl; } u_spcl; #define spcl u_spcl.s_spcl diff --git a/compat/include/tzfile.h b/compat/include/tzfile.h deleted file mode 100644 index a9f934c..0000000 --- a/compat/include/tzfile.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Ported to Linux's Second Extended File System as part of the - * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 - * - */ - -/* - * Copyright (c) 1988, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Arthur David Olson of the National Cancer Institute. - * - * 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. - * - * @(#)tzfile.h 8.1 (Berkeley) 6/2/93 - */ - -#ifndef _TZFILE_H_ -#define _TZFILE_H_ - -/* - * Information about time zone files. - */ - /* Time zone object file directory */ -#define TZDIR "/usr/share/zoneinfo" -#define TZDEFAULT "/etc/localtime" -#define TZDEFRULES "posixrules" - -/* -** Each file begins with. . . -*/ - -struct tzhead { - char tzh_reserved[24]; /* reserved for future use */ - char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ - char tzh_leapcnt[4]; /* coded number of leap seconds */ - char tzh_timecnt[4]; /* coded number of transition times */ - char tzh_typecnt[4]; /* coded number of local time types */ - char tzh_charcnt[4]; /* coded number of abbr. chars */ -}; - -/* -** . . .followed by. . . -** -** tzh_timecnt (char [4])s coded transition times a la time(2) -** tzh_timecnt (unsigned char)s types of local time starting at above -** tzh_typecnt repetitions of -** one (char [4]) coded GMT offset in seconds -** one (unsigned char) used to set tm_isdst -** one (unsigned char) that's an abbreviation list index -** tzh_charcnt (char)s '\0'-terminated zone abbreviations -** tzh_leapcnt repetitions of -** one (char [4]) coded leap second transition times -** one (char [4]) total correction after above -** tzh_ttisstdcnt (char)s indexed by type; if TRUE, transition -** time is standard time, if FALSE, -** transition time is wall clock time -** if absent, transition times are -** assumed to be wall clock time -*/ - -/* -** In the current implementation, "tzset()" refuses to deal with files that -** exceed any of the limits below. -*/ - -/* -** The TZ_MAX_TIMES value below is enough to handle a bit more than a -** year's worth of solar time (corrected daily to the nearest second) or -** 138 years of Pacific Presidential Election time -** (where there are three time zone transitions every fourth year). -*/ -#define TZ_MAX_TIMES 370 - -#define NOSOLAR /* 4BSD doesn't currently handle solar time */ - -#ifndef NOSOLAR -#define TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */ -#else -#define TZ_MAX_TYPES 10 /* Maximum number of local time types */ -#endif - -#define TZ_MAX_CHARS 50 /* Maximum number of abbreviation characters */ - -#define TZ_MAX_LEAPS 50 /* Maximum number of leap second corrections */ - -#define SECSPERMIN 60 -#define MINSPERHOUR 60 -#define HOURSPERDAY 24 -#define DAYSPERWEEK 7 -#define DAYSPERNYEAR 365 -#define DAYSPERLYEAR 366 -#define SECSPERHOUR (SECSPERMIN * MINSPERHOUR) -#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) -#define MONSPERYEAR 12 - -#define TM_SUNDAY 0 -#define TM_MONDAY 1 -#define TM_TUESDAY 2 -#define TM_WEDNESDAY 3 -#define TM_THURSDAY 4 -#define TM_FRIDAY 5 -#define TM_SATURDAY 6 - -#define TM_JANUARY 0 -#define TM_FEBRUARY 1 -#define TM_MARCH 2 -#define TM_APRIL 3 -#define TM_MAY 4 -#define TM_JUNE 5 -#define TM_JULY 6 -#define TM_AUGUST 7 -#define TM_SEPTEMBER 8 -#define TM_OCTOBER 9 -#define TM_NOVEMBER 10 -#define TM_DECEMBER 11 - -#define TM_YEAR_BASE 1900 - -#define EPOCH_YEAR 1970 -#define EPOCH_WDAY TM_THURSDAY - -/* -** Accurate only for the past couple of centuries; -** that will probably do. -*/ - -#define isleap(y) (((y) % 4) == 0 && ((y) % 100) != 0 || ((y) % 400) == 0) - -#endif /* !_TZFILE_H_ */ diff --git a/compat/lib/err.c b/compat/lib/err.c index 71aaadc..13fefaf 100644 --- a/compat/lib/err.c +++ b/compat/lib/err.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -36,11 +37,13 @@ * 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_SCCS) && !defined(lint) -static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ +#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 @@ -48,34 +51,43 @@ static char sccsid[] = "@(#)err.c 8.1 (Berkeley) 6/4/93"; #include #include -#ifdef __STDC__ #include -#else -#include -#endif #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 -#ifdef __STDC__ err(int eval, const char *fmt, ...) -#else -err(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif { va_list ap; -#if __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif - verr(eval, fmt, ap); + verrc(eval, errno, fmt, ap); va_end(ap); } #endif @@ -87,36 +99,49 @@ verr(eval, fmt, ap) const char *fmt; va_list ap; { - int sverrno; + 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 - sverrno = errno; - (void)fprintf(stderr, "%s: ", __progname); +#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) { - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, ": "); + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); } - (void)fprintf(stderr, "%s\n", strerror(sverrno)); + fprintf(err_file, "%s\n", strerror(code)); + if (err_exit) + err_exit(eval); exit(eval); } #endif #ifndef HAVE_ERRX __dead void -#if __STDC__ errx(int eval, const char *fmt, ...) -#else -errx(eval, fmt, va_alist) - int eval; - const char *fmt; - va_dcl -#endif { va_list ap; -#if __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif verrx(eval, fmt, ap); va_end(ap); } @@ -129,31 +154,25 @@ verrx(eval, fmt, ap) const char *fmt; va_list ap; { - (void)fprintf(stderr, "%s: ", __progname); + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", __progname); if (fmt != NULL) - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); + if (err_exit) + err_exit(eval); exit(eval); } #endif #ifndef HAVE_WARN void -#if __STDC__ warn(const char *fmt, ...) -#else -warn(fmt, va_alist) - const char *fmt; - va_dcl -#endif { va_list ap; -#if __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif - vwarn(fmt, ap); + vwarnc(errno, fmt, ap); va_end(ap); } #endif @@ -164,34 +183,45 @@ vwarn(fmt, ap) const char *fmt; va_list ap; { - int sverrno; + 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 - sverrno = errno; - (void)fprintf(stderr, "%s: ", __progname); +#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) { - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, ": "); + vfprintf(err_file, fmt, ap); + fprintf(err_file, ": "); } - (void)fprintf(stderr, "%s\n", strerror(sverrno)); + fprintf(err_file, "%s\n", strerror(code)); } #endif #ifndef HAVE_WARNX void -#ifdef __STDC__ warnx(const char *fmt, ...) -#else -warnx(fmt, va_alist) - const char *fmt; - va_dcl -#endif { va_list ap; -#ifdef __STDC__ va_start(ap, fmt); -#else - va_start(ap); -#endif vwarnx(fmt, ap); va_end(ap); } @@ -203,9 +233,11 @@ vwarnx(fmt, ap) const char *fmt; va_list ap; { - (void)fprintf(stderr, "%s: ", __progname); + if (err_file == 0) + err_set_file((FILE *)0); + fprintf(err_file, "%s: ", __progname); if (fmt != NULL) - (void)vfprintf(stderr, fmt, ap); - (void)fprintf(stderr, "\n"); + vfprintf(err_file, fmt, ap); + fprintf(err_file, "\n"); } #endif diff --git a/compat/lib/fstab.c b/compat/lib/fstab.c index 0cd2250..0b51de5 100644 --- a/compat/lib/fstab.c +++ b/compat/lib/fstab.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -112,7 +113,7 @@ int fstabscan() struct fstab * getfsent() { - if (!_fs_fp && !setfsent() || !fstabscan()) + if ((!_fs_fp && !setfsent()) || !fstabscan()) return((struct fstab *)NULL); return(&_fs_fstab); } diff --git a/compat/lib/glob.c b/compat/lib/glob.c index ba6f22f..7725dde 100644 --- a/compat/lib/glob.c +++ b/compat/lib/glob.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -65,7 +66,7 @@ static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; * GLOB_TILDE: * expand ~user/foo to the /home/dir/of/user/foo * GLOB_BRACE: - * expand {1,2}{a,b} to 1a 1b 2a 2b + * expand {1,2}{a,b} to 1a 1b 2a 2b * gl_matchc: * Number of matches in the current invocation of glob. */ @@ -147,7 +148,7 @@ 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 *, 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 *)); @@ -180,7 +181,7 @@ glob(pattern, flags, errfunc, pglob) bufend = bufnext + MAXPATHLEN; if (flags & GLOB_QUOTE) { /* Protect the quoted characters. */ - while (bufnext < bufend && (c = *patnext++) != EOS) + while (bufnext < bufend && (c = *patnext++) != EOS) if (c == QUOTE) { if ((c = *patnext++) == EOS) { c = QUOTE; @@ -191,8 +192,8 @@ glob(pattern, flags, errfunc, pglob) else *bufnext++ = c; } - else - while (bufnext < bufend && (c = *patnext++) != EOS) + else + while (bufnext < bufend && (c = *patnext++) != EOS) *bufnext++ = c; *bufnext = EOS; @@ -253,7 +254,7 @@ static int globexp2(ptr, pattern, pglob, rv) 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 */ @@ -281,7 +282,7 @@ static int globexp2(ptr, pattern, pglob, rv) 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 */ @@ -306,7 +307,7 @@ static int globexp2(ptr, pattern, pglob, rv) /* Append the current string */ for (lm = ls; (pl < pm); *lm++ = *pl++) continue; - /* + /* * Append the rest of the pattern after the * closing brace */ @@ -337,36 +338,49 @@ static int globexp2(ptr, pattern, pglob, rv) * expand tilde from the passwd file. */ static const Char * -globtilde(pattern, patbuf, pglob) +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; + Char *b, *eb; if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; - /* Copy up to the end of the string or / */ - for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH; - *h++ = *p++) + /* + * 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 and then trying the password file + /* + * handle a plain ~ or ~/ by expanding $HOME first if + * we're not running setuid or setgid) and then trying + * the password file */ - if ((h = getenv("HOME")) == NULL) { - if ((pwd = getpwuid(getuid())) == NULL) - return pattern; - else + 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 { @@ -380,16 +394,17 @@ globtilde(pattern, patbuf, pglob) } /* Copy the home directory */ - for (b = patbuf; *h; *b++ = *h++) + for (b = patbuf; b < eb && *h; *b++ = *h++) continue; - + /* Append the rest of the pattern */ - while ((*b++ = *p++) != EOS) + while (b < eb && (*b++ = *p++) != EOS) continue; + *b = EOS; return patbuf; } - + /* * The main glob() routine: compiles the pattern (optionally processing @@ -407,7 +422,8 @@ glob0(pattern, pglob) int c, err, oldpathc; Char *bufnext, patbuf[MAXPATHLEN+1]; - qpatnext = globtilde(pattern, patbuf, pglob); + qpatnext = globtilde(pattern, patbuf, sizeof(patbuf) / sizeof(Char), + pglob); oldpathc = pglob->gl_pathc; bufnext = patbuf; @@ -447,7 +463,7 @@ glob0(pattern, pglob) break; case STAR: pglob->gl_flags |= GLOB_MAGCHAR; - /* collapse adjacent stars to one, + /* collapse adjacent stars to one, * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) @@ -467,17 +483,17 @@ glob0(pattern, pglob) return(err); /* - * If there was no match we are going to append the pattern + * 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) || + 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)) + else if (!(pglob->gl_flags & GLOB_NOSORT)) qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, pglob->gl_pathc - oldpathc, sizeof(char *), compare); return(0); @@ -526,7 +542,7 @@ glob2(pathbuf, pathend, pattern, pglob) *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) && @@ -579,7 +595,7 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob) *pathend = EOS; errno = 0; - + if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { @@ -605,7 +621,7 @@ glob3(pathbuf, pathend, pattern, restpattern, pglob) /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; - for (sc = (u_char *) dp->d_name, dc = pathend; + for (sc = (u_char *) dp->d_name, dc = pathend; (*dc++ = *sc++) != EOS;) continue; if (!match(pathend, pattern, restpattern)) { @@ -651,7 +667,7 @@ globextend(path, pglob) const Char *p; newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); - pathv = pglob->gl_pathv ? + pathv = pglob->gl_pathv ? realloc((char *)pglob->gl_pathv, newsize) : malloc(newsize); if (pathv == NULL) @@ -675,7 +691,6 @@ globextend(path, pglob) return(copy == NULL ? GLOB_NOSPACE : 0); } - /* * pattern matching function for filenames. Each occurrence of the * * pattern causes a recursion level. @@ -693,7 +708,7 @@ match(name, pat, patend) case M_ALL: if (pat == patend) return(1); - do + do if (match(name, pat, patend)) return(1); while (*name++ != EOS); @@ -832,7 +847,7 @@ g_Ctoc(str, buf) } #ifdef DEBUG -static void +static void qprintf(str, s) const char *str; register Char *s; diff --git a/config.h.in b/config.h.in index 817ce66..47b9199 100644 --- a/config.h.in +++ b/config.h.in @@ -12,6 +12,9 @@ /* 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 @@ -21,17 +24,26 @@ /* 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 diff --git a/config.sub b/config.sub index 93371be..124029d 100755 --- a/config.sub +++ b/config.sub @@ -422,7 +422,7 @@ case $basic_machine in # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium basic_machine=i586-intel ;; - pentium-* | p5-* | p6-*) + pentium-* | p5-* | p6-* | i686-* ) # We don't have specific support for the Intel Pentium (p6) followon yet, so just call it a Pentium basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` ;; diff --git a/configure b/configure index 53be0bb..a7f0137 100755 --- a/configure +++ b/configure @@ -1522,7 +1522,7 @@ 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 errx verr verrx vwarn vwarnx warn warnx realpath +for ac_func in err errc errx verr verrc verrx vwarn vwarnc vwarnx warn warnc warnx realpath do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:1529: checking for $ac_func" >&5 diff --git a/configure.in b/configure.in index 3ef741e..d0d3509 100644 --- a/configure.in +++ b/configure.in @@ -219,7 +219,7 @@ fi dnl dnl Check for library functions dnl -AC_CHECK_FUNCS(err errx verr verrx vwarn vwarnx warn warnx realpath) +AC_CHECK_FUNCS(err errc errx verr verrc verrx vwarn vwarnc vwarnx warn warnc warnx realpath) dnl dnl Check for types diff --git a/dump.lsm b/dump.lsm index 6aadaf4..19363f2 100644 --- a/dump.lsm +++ b/dump.lsm @@ -1,18 +1,18 @@ Begin3 Title: dump and restore for Ext2fs -Version: 0.4b4 -Entered-date: 17JAN97 +Version: 0.4b5 +Entered-date: 22SEP99 Description: Port of the 4.4BSD dump and restore backup suite Keywords: backup, filesystem, Ext2fs Author: University of California, Berkeley -Maintained-by: card@Linux.EU.Org (Remy Card) +Maintained-by: pop@captimark.fr (Stelian Pop) Primary-site: tsx-11.mit.edu /pub/linux/ALPHA/ext2fs - 126kB dump-0.4b4.tar.gz + 132kB dump-0.4b5.tar.gz 627 dump.lsm Alternate-site: Original-site: ftp.freebsd.org /pub/bsd-sources/4.4BSD-Lite2/sbin dump/* restore/* -Platforms: linux 2.0.x, e2fsprogs 1.06 +Platforms: linux 2.0.x, linux 2.2.x, e2fsprogs 1.14 Copying-policy: BSD End diff --git a/dump/dump.8 b/dump/dump.8 index fae652b..495f541 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 acknowledgement: +.\" must display the following acknowledgment: .\" 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,6 +31,7 @@ .\" SUCH DAMAGE. .\" .\" @(#)dump.8 8.3 (Berkeley) 5/1/95 +.\" $Id: dump.8,v 1.2 1999/10/11 12:53:21 stelian Exp $ .\" .Dd May 1, 1995 .Dt DUMP 8 @@ -40,22 +41,24 @@ .Nd filesystem backup .Sh SYNOPSIS .Nm dump -.Op Fl 0123456789cnu +.Op Fl 0123456789acknu .Op Fl B Ar records .Op Fl b Ar blocksize .Op Fl d Ar density .Op Fl f Ar file .Op Fl h Ar level +.Op Fl L Ar label .Op Fl s Ar feet .Op Fl T Ar date .Ar filesystem .Nm dump -.Op Fl 0123456789cnu +.Op Fl 0123456789acknu .Op Fl B Ar records .Op Fl b Ar blocksize .Op Fl d Ar density .Op Fl f Ar file .Op Fl h Ar level +.Op Fl L Ar label .Op Fl s Ar feet .Op Fl T Ar date .Ar directory @@ -80,7 +83,11 @@ 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. +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) each volume is of a fixed size; @@ -90,7 +97,7 @@ By default, the same output file name is used for each volume after prompting the operator to change media. .Pp The following options are supported by -.Nm dump : +.Nm Ns : .Bl -tag -width Ds .It Fl 0\-9 Dump levels. @@ -103,17 +110,35 @@ A level number above 0, incremental backup, tells dump to copy all files new or modified since the -last dump of the same or lower level. -The default level is 9. +last dump of any lower level. +The default level is 0. .It Fl B Ar records -The number of dump records per volume. +The number of 1 KB blocks per volume. This option overrides the calculation of tape size based on length and density. +.It Fl a +.Dq auto-size . +Bypass all tape length considerations, and enforce writing +until an end-of-media indication is returned. This fits best +for most modern tape drives. Use of this option is particularly +recommended when appending to an existing tape, or using a tape +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. .It Fl c -Modify the calculation of the default density and tape size to be more -appropriate for cartridge tapes. +Change the defaults for use with a cartridge tape drive, with a density +of 8000 bpi, and a length of 1700 feet. +.It Fl h Ar level +Honor the user +.Dq nodump +flag +.Dp Dv UF_NODUMP +only for dumps at or above the given +.Ar level . +The default honor level is 1, +so that incremental backups omit such files +but full backups retain them. .It Fl d Ar density Set tape density to .Ar density . @@ -127,7 +152,7 @@ like .Pa /dev/rmt12 (a tape drive), .Pa /dev/rsd1c -(a disk drive), +(a floppy disk drive), an ordinary file, or .Ql Fl @@ -141,22 +166,36 @@ If the name of the file is of the form .Dq host:file , or .Dq user@host:file , -.Nm dump +.Nm writes to the named file on the remote host using .Xr rmt 8 . -.It Fl h Ar level -Honor the user -.Dq nodump -flag -.Dp Dv UF_NODUMP -only for dumps at or above the given -.Ar level . -The default honor level is 1, -so that incremental backups omit such files -but full backups retain them. +The default path name of the remote +.Xr rmt 8 +program is +.\" rmt path, is the path on the remote host +.Pa /etc/rmt ; +this can be overridden by the environment variable +.Ev RMT . +.It Fl k +Use Kerberos authentication to talk to remote tape servers. (Only +available if this option was enabled when +.Nm +was compiled.) +.It Fl L Ar label +The user-supplied text string +.Ar label +is placed into the dump header, where tools like +.Xr restore 8 +and +.Xr file 1 +can access it. +Note that this label is limited +to be at most LBLSIZE (currently 16) characters, which must include +the terminating +.Ql \e0 . .It Fl n Whenever -.Nm dump +.Nm requires operator attention, notify all operators in the group .Dq operator @@ -166,7 +205,7 @@ by means similar to a Attempt to calculate the amount of tape needed at a particular density. If this amount is exceeded, -.Nm dump +.Nm prompts for a new tape. It is recommended to be a bit conservative on this option. The default tape length is 2300 feet. @@ -212,7 +251,7 @@ and The .Fl W option causes -.Nm dump +.Nm to print out, for each file system in .Pa /etc/dumpdates the most recent dump date and level, @@ -220,7 +259,7 @@ and highlights those file systems that should be dumped. If the .Fl W option is set, all other options are ignored, and -.Nm dump +.Nm exits immediately. .It Fl w Is like W, but prints only those filesystems which need to be dumped. @@ -236,15 +275,15 @@ disk read error (if there are more than a threshold of 32). In addition to alerting all operators implied by the .Fl n key, -.Nm dump +.Nm interacts with the operator on .Em dump's control terminal at times when -.Nm dump +.Nm can no longer proceed, or if something is grossly wrong. All questions -.Nm dump +.Nm poses .Em must be answered by typing @@ -254,10 +293,10 @@ or appropriately. .Pp Since making a dump involves a lot of time and effort for full dumps, -.Nm dump +.Nm checkpoints itself at the start of each tape volume. If writing that volume fails for some reason, -.Nm dump +.Nm will, with operator permission, restart itself from the checkpoint @@ -272,7 +311,7 @@ the time to the tape change. The output is verbose, so that others know that the terminal controlling -.Nm dump +.Nm is busy, and will be for some time. .Pp @@ -309,6 +348,26 @@ used, also on a cyclical basis. .Pp After several months or so, the daily and weekly tapes should get rotated out of the dump cycle and fresh tapes brought in. +.Sh ENVIRONMENT +.Bl -tag -width Fl +.It Ev TAPE +If no -f option was specified, +.Nm +will use the device specified via +.Ev TAPE +as the dump device. +.Ev TAPE +may be of the form +.Qq tapename , +.Qq host:tapename , +or +.Qq user@host:tapename . +.It Ev RMT +The environment variable +.Ev RMT +will be used to determine the pathname of the remote +.Xr rmt 8 +program. .Sh FILES .Bl -tag -width /etc/dumpdates -compact .It Pa /dev/rmt8 @@ -322,10 +381,9 @@ to find group .Em operator .El .Sh SEE ALSO +.Xr fstab 5 , .Xr restore 8 , -.Xr rmt 8 , -.Xr dump 5 , -.Xr fstab 5 +.Xr rmt 8 .Sh DIAGNOSTICS Many, and verbose. .Pp @@ -351,14 +409,22 @@ even if listed in .Pa /etc/fstab . .Pp It would be nice if -.Nm dump +.Nm knew about the dump sequence, kept track of the tapes scribbled on, told the operator which tape to mount when, and provided more assistance for the operator running .Xr restore . +.Pp +.Nm Dump +cannot do remote backups without being run as root, due to its +security history. This will be fixed in a later version of +.Bx Free . +Presently, it works if you set it setuid (like it used to be), but this +might constitute a security risk. .Sh HISTORY A -.Nm dump -command appeared in Version 6 AT&T UNIX. +.Nm +command appeared in +.At v6 . diff --git a/dump/dump.h b/dump/dump.h index 73882dc..ad48390 100644 --- a/dump/dump.h +++ b/dump/dump.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -81,13 +82,14 @@ long tsize; /* tape size in 0.1" units */ long asize; /* number of 0.1" units written on current tape */ int etapes; /* estimated number of tapes */ int nonodump; /* if set, do not honor UF_NODUMP user flags */ +int unlimited; /* if set, write to end of medium */ int notify; /* notify operator flag */ int blockswritten; /* number of blocks written on current tape */ int tapeno; /* current tape number */ time_t tstart_writing; /* when started writing the first tape block */ +time_t tend_writing; /* after writing the last tape block */ #ifdef __linux__ -time_t tend_writing; /* after writing the last tape block */ ext2_filsys fs; #else struct fs *sblock; /* the file system super block */ @@ -123,7 +125,7 @@ int mapdirs __P((ino_t maxino, long *tapesize)); /* file dumping routines */ void blksout __P((daddr_t *blkp, int frags, ino_t ino)); -void bread __P((daddr_t blkno, char *buf, int size)); +void bread __P((daddr_t blkno, char *buf, int size)); void dumpino __P((struct dinode *dp, ino_t ino)); #ifdef __linux__ void dumpdirino __P((struct dinode *dp, ino_t ino)); @@ -160,6 +162,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_REWRITE 2 /* restart writing from the check point */ #define X_ABORT 3 /* abort dump; don't attempt checkpointing */ @@ -238,7 +241,7 @@ extern char *strncpy(); extern char *strcat(); extern time_t time(); extern void endgrent(); -extern __dead void exit(); +extern void exit(); extern off_t lseek(); extern const char *strerror(); #endif diff --git a/dump/itime.c b/dump/itime.c index f83459c..441085f 100644 --- a/dump/itime.c +++ b/dump/itime.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,7 +40,11 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include @@ -48,6 +53,7 @@ static char sccsid[] = "@(#)itime.c 8.1 (Berkeley) 6/5/93"; #include #include #include +#include #else #ifdef sunos #include @@ -68,7 +74,6 @@ static char sccsid[] = "@(#)itime.c 8.1 (Berkeley) 6/5/93"; #ifdef __STDC__ #include #include -#include #endif #ifdef __linux__ diff --git a/dump/main.c b/dump/main.c index c09e6b8..c17684e 100644 --- a/dump/main.c +++ b/dump/main.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,13 +40,17 @@ */ #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1980, 1991, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include @@ -70,7 +75,6 @@ static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95"; #include #include -#include #include #include #include @@ -93,9 +97,10 @@ static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/1/95"; int notify = 0; /* notify operator flag */ int blockswritten = 0; /* number of blocks written on current tape */ int tapeno = 0; /* current tape number */ -int density = 0; /* density in bytes/0.1" */ +int density = 0; /* density in bytes/0.1" " <- this is for hilit19 */ int ntrec = NTREC; /* # tape blocks in each tape record */ int cartridge = 0; /* Assume non-cartridge tape */ +int dokerberos = 0; /* Use Kerberos authentication */ long dev_bsize = 1; /* recalculated below */ long blocksperfile; /* output blocks per file */ char *host = NULL; /* remote host (if any) */ @@ -114,7 +119,7 @@ main(argc, argv) char *argv[]; { register ino_t ino; - register int dirty; + register int dirty; register struct dinode *dp; register struct fstab *dt; register char *map; @@ -126,6 +131,7 @@ main(argc, argv) char directory[NAME_MAX]; char pathname[NAME_MAX]; #endif + char labelstr[LBLSIZE]; spcl.c_date = 0; #ifdef __linux__ @@ -141,29 +147,45 @@ main(argc, argv) #endif tsize = 0; /* Default later, based on 'c' option for cart tapes */ - tape = _PATH_DEFTAPE; + if ((tape = getenv("TAPE")) == NULL) + tape = _PATH_DEFTAPE; dumpdates = _PATH_DUMPDATES; temp = _PATH_DTMP; + strcpy(labelstr, "none"); /* XXX safe strcpy. */ if (TP_BSIZE / DEV_BSIZE == 0 || TP_BSIZE % DEV_BSIZE != 0) quit("TP_BSIZE must be a multiple of DEV_BSIZE\n"); level = '0'; + if (argc < 2) usage(); obsolete(&argc, &argv); - while ((ch = getopt(argc, argv, "0123456789B:b:cd:f:h:ns:T:uWw")) != -1) switch (ch) { +#ifdef KERBEROS +#define optstring "0123456789aB:b:cd:f:h:kL:ns:T:uWw" +#else +#define optstring "0123456789aB:b:cd:f:h:L:ns:T:uWw" +#endif + while ((ch = getopt(argc, argv, optstring)) != -1) +#undef optstring + switch (ch) { /* dump level */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': level = ch; break; + case 'a': /* `auto-size', Write to EOM. */ + unlimited = 1; + break; + case 'B': /* blocks per output file */ - blocksperfile = numarg("blocks per file", 1L, 0L); + blocksperfile = numarg("number of blocks per file", + 1L, 0L); break; case 'b': /* blocks per tape write */ - ntrec = numarg("blocks per write", 1L, 1000L); + ntrec = numarg("number of blocks per write", + 1L, 1000L); break; case 'c': /* Tape is cart. not 9-track */ @@ -184,6 +206,29 @@ main(argc, argv) honorlevel = numarg("honor level", 0L, 10L); break; +#ifdef KERBEROS + case 'k': + dokerberos = 1; + break; +#endif + + case 'L': + /* + * Note that although there are LBLSIZE characters, + * the last must be '\0', so the limit on strlen() + * is really LBLSIZE-1. + */ + strncpy(labelstr, optarg, LBLSIZE); + labelstr[LBLSIZE-1] = '\0'; + if (strlen(optarg) > LBLSIZE-1) { + msg( + "WARNING Label `%s' is larger than limit of %d characters.\n", + optarg, LBLSIZE-1); + msg("WARNING: Using truncated label `%s'.\n", + labelstr); + } + break; + case 'n': /* notify operators */ notify = 1; break; @@ -197,10 +242,13 @@ main(argc, argv) if (spcl.c_ddate < 0) { (void)fprintf(stderr, "bad time \"%s\"\n", optarg); - exit(X_ABORT); + exit(X_STARTUP); } Tflag = 1; lastlevel = '?'; + argc--; + argv++; + break; case 'u': /* update /etc/dumpdates */ uflag = 1; @@ -209,7 +257,7 @@ main(argc, argv) case 'W': /* what to do */ case 'w': lastdump(ch); - exit(0); /* do nothing else */ + exit(X_FINOK); /* do nothing else */ default: usage(); @@ -219,7 +267,7 @@ main(argc, argv) if (argc < 1) { (void)fprintf(stderr, "Must specify disk or filesystem\n"); - exit(X_ABORT); + exit(X_STARTUP); } disk = *argv++; argc--; @@ -228,12 +276,12 @@ main(argc, argv) while (argc--) (void)fprintf(stderr, " %s", *argv++); (void)fprintf(stderr, "\n"); - exit(X_ABORT); + exit(X_STARTUP); } if (Tflag && uflag) { (void)fprintf(stderr, "You cannot use the T and u flags together.\n"); - exit(X_ABORT); + exit(X_STARTUP); } if (strcmp(tape, "-") == 0) { pipeout++; @@ -242,7 +290,7 @@ main(argc, argv) if (blocksperfile) blocksperfile = blocksperfile / ntrec * ntrec; /* round down */ - else { + else if (!unlimited) { /* * Determine how to default tape size and density * @@ -251,6 +299,7 @@ main(argc, argv) * 9-track 6250 bpi (625 bytes/.1") 2300 ft. * cartridge 8000 bpi (100 bytes/.1") 1700 ft. * (450*4 - slop) + * hilit19 hits again: " */ if (density == 0) density = cartridge ? 100 : 160; @@ -263,11 +312,15 @@ main(argc, argv) tape = strchr(host, ':'); *tape++ = '\0'; #ifdef RDUMP + if (index(tape, '\n')) { + (void)fprintf(stderr, "invalid characters in tape\n"); + exit(X_STARTUP); + } if (rmthost(host) == 0) - exit(X_ABORT); + exit(X_STARTUP); #else (void)fprintf(stderr, "remote dump not enabled\n"); - exit(X_ABORT); + exit(X_STARTUP); #endif } (void)setuid(getuid()); /* rmthost() is the only reason to be setuid */ @@ -331,7 +384,9 @@ main(argc, argv) NAMELEN); } #endif - (void)strcpy(spcl.c_label, "none"); + spcl.c_dev[NAMELEN-1]='\0'; + spcl.c_filesys[NAMELEN-1]='\0'; + (void)strncpy(spcl.c_label, labelstr, sizeof(spcl.c_label) - 1); (void)gethostname(spcl.c_host, NAMELEN); spcl.c_level = level - '0'; spcl.c_type = TS_TAPE; @@ -357,6 +412,7 @@ main(argc, argv) msgtail("to %s on host %s\n", tape, host); else msgtail("to %s\n", tape); + msg("Label: %s\n", labelstr); #ifdef __linux__ retval = ext2fs_open(disk, 0, 0, 0, unix_io_manager, &fs); @@ -364,16 +420,16 @@ main(argc, argv) com_err(disk, retval, "while opening filesystem"); if (retval == EXT2_ET_REV_TOO_HIGH) printf ("Get a newer version of dump!\n"); - exit(X_ABORT); + exit(X_STARTUP); } if (fs->super->s_rev_level > DUMP_CURRENT_REV) { com_err(disk, retval, "while opening filesystem"); printf ("Get a newer version of dump!\n"); - exit(X_ABORT); + exit(X_STARTUP); } if ((diskfd = open(disk, O_RDONLY)) < 0) { msg("Cannot open %s\n", disk); - exit(X_ABORT); + exit(X_STARTUP); } sync(); dev_bsize = DEV_BSIZE; @@ -390,7 +446,7 @@ main(argc, argv) #else /* __linux __*/ if ((diskfd = open(disk, O_RDONLY)) < 0) { msg("Cannot open %s\n", disk); - exit(X_ABORT); + exit(X_STARTUP); } sync(); sblock = (struct fs *)sblock_buf; @@ -404,7 +460,6 @@ main(argc, argv) tp_bshift = ffs(TP_BSIZE) - 1; if (TP_BSIZE != (1 << tp_bshift)) quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE); - spcl.c_flags |= DR_NEWINODEFMT; #ifdef FS_44INODEFMT if (sblock->fs_inodefmt >= FS_44INODEFMT) spcl.c_flags |= DR_NEWINODEFMT; @@ -434,7 +489,7 @@ main(argc, argv) anydirskipped = mapdirs(maxino, &tapesize); } - if (pipeout) { + if (pipeout || unlimited) { tapesize += 10; /* 10 trailer blocks */ msg("estimated %ld tape blocks.\n", tapesize); } else { @@ -447,28 +502,28 @@ main(argc, argv) the end of each block written, and not in mid-block. Assume no erroneous blocks; this can be compensated for with an artificially low tape size. */ - fetapes = - ( tapesize /* blocks */ + fetapes = + ( (double) tapesize /* blocks */ * TP_BSIZE /* bytes/block */ - * (1.0/density) /* 0.1" / byte */ + * (1.0/density) /* 0.1" / byte " */ + - tapesize /* blocks */ + (double) tapesize /* blocks */ * (1.0/ntrec) /* streaming-stops per block */ - * 15.48 /* 0.1" / streaming-stop */ - ) * (1.0 / tsize ); /* tape / 0.1" */ + * 15.48 /* 0.1" / streaming-stop " */ + ) * (1.0 / tsize ); /* tape / 0.1" " */ } else { /* Estimate number of tapes, for old fashioned 9-track tape */ int tenthsperirg = (density == 625) ? 3 : 7; fetapes = - ( tapesize /* blocks */ + ( (double) tapesize /* blocks */ * TP_BSIZE /* bytes / block */ - * (1.0/density) /* 0.1" / byte */ + * (1.0/density) /* 0.1" / byte " */ + - tapesize /* blocks */ + (double) tapesize /* blocks */ * (1.0/ntrec) /* IRG's / block */ - * tenthsperirg /* 0.1" / IRG */ - ) * (1.0 / tsize ); /* tape / 0.1" */ + * tenthsperirg /* 0.1" / IRG " */ + ) * (1.0 / tsize ); /* tape / 0.1" " */ } etapes = fetapes; /* truncating assignment */ etapes++; @@ -484,7 +539,8 @@ main(argc, argv) * Allocate tape buffer. */ if (!alloctape()) - quit("can't allocate tape buffers - try a smaller blocking factor.\n"); + quit( + "can't allocate tape buffers - try a smaller blocking factor.\n"); startnewtape(1); (void)time((time_t *)&(tstart_writing)); @@ -532,18 +588,16 @@ main(argc, argv) (void)dumpino(dp, ino); } -#ifdef __linux__ (void)time((time_t *)&(tend_writing)); -#endif spcl.c_type = TS_END; for (i = 0; i < ntrec; i++) writeheader(maxino - 1); if (pipeout) - msg("DUMP: %ld tape blocks\n",spcl.c_tapea); + msg("DUMP: %ld tape blocks\n", spcl.c_tapea); else msg("DUMP: %ld tape blocks on %d volumes(s)\n", spcl.c_tapea, spcl.c_volume); -#ifdef __linux__ + /* report dump performance, avoid division through zero */ if (tend_writing - tstart_writing == 0) msg("finished in less than a second\n"); @@ -551,22 +605,28 @@ main(argc, argv) msg("finished in %d seconds, throughput %d KBytes/sec\n", tend_writing - tstart_writing, spcl.c_tapea / (tend_writing - tstart_writing)); -#endif + putdumptime(); trewind(); broadcast("DUMP IS DONE!\7\7\n"); msg("DUMP IS DONE\n"); Exit(X_FINOK); /* NOTREACHED */ + exit(1); /* gcc - shut up */ } static void usage() { - - (void)fprintf(stderr, "usage: dump [-0123456789cnu] [-B records] [-b blocksize] [-d density] [-f file]\n [-h level] [-s feet] [-T date] filesystem\n"); - (void)fprintf(stderr, " dump [-W | -w]\n"); - exit(1); + fprintf(stderr, + "usage: dump [-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"); + exit(X_STARTUP); } /* @@ -629,18 +689,19 @@ rawname(cp) if (dp == NULL) return (NULL); *dp = '\0'; - (void)strcpy(rawbuf, cp); + (void)strncpy(rawbuf, cp, MAXPATHLEN - 1); + rawbuf[MAXPATHLEN-1] = '\0'; *dp = '/'; - (void)strcat(rawbuf, "/r"); - (void)strcat(rawbuf, dp + 1); + (void)strncat(rawbuf, "/r", MAXPATHLEN - 1 - strlen(rawbuf)); + (void)strncat(rawbuf, dp + 1, MAXPATHLEN - 1 - strlen(rawbuf)); return (rawbuf); #endif /* __linux__ */ } /* * obsolete -- - * Change set of key letters and ordered arguments into something - * getopt(3) will like. + * Change set of key letters and ordered arguments into something + * getopt(3) will like. */ static void obsolete(argcp, argvp) @@ -648,7 +709,7 @@ obsolete(argcp, argvp) char **argvp[]; { int argc, flags; - char *ap, **argv, *flagsp, **nargv, *p; + char *ap, **argv, *flagsp=NULL, **nargv, *p=NULL; /* Setup. */ argv = *argvp; @@ -677,7 +738,8 @@ obsolete(argcp, argvp) case 's': case 'T': if (*argv == NULL) { - warnx("option requires an argument -- %c", *ap); usage(); + warnx("option requires an argument -- %c", *ap); + usage(); } if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL) err(1, NULL); @@ -704,7 +766,7 @@ obsolete(argcp, argvp) } /* Copy remaining arguments. */ - while (*nargv++ = *argv++); + while ((*nargv++ = *argv++)); /* Update argument count. */ *argcp = nargv - *argvp - 1; diff --git a/dump/optr.c b/dump/optr.c index 4d23242..c1ba8a9 100644 --- a/dump/optr.c +++ b/dump/optr.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,7 +40,11 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include @@ -49,26 +54,18 @@ static char sccsid[] = "@(#)optr.c 8.2 (Berkeley) 1/6/94"; #include #include #include -#include #include -#ifdef __STDC__ #include #include #include -#endif -#include -#ifdef __STDC__ #include -#endif #include -#ifndef __STDC__ -#include -#endif #ifdef __linux__ #include #include #include +#include #endif #include "dump.h" @@ -184,7 +181,7 @@ struct group *gp; /* * Get the names from the group entry "operator" to notify. - */ + */ void set_operators() { @@ -265,13 +262,13 @@ static void sendmes(tty, message) char *tty, *message; { - char t[50], buf[BUFSIZ]; + char t[MAXPATHLEN], buf[BUFSIZ]; register char *cp; int lmsg = 1; FILE *f_tty; (void) strcpy(t, _PATH_DEV); - (void) strcat(t, tty); + (void) strncat(t, tty, sizeof t - strlen(_PATH_DEV) - 1); if ((f_tty = fopen(t, "w")) != NULL) { setbuf(f_tty, buf); @@ -313,7 +310,7 @@ timeest() if (tnow >= tschedule) { tschedule = tnow + 300; if (blockswritten < 500) - return; + return; deltat = tstart_writing - tnow + (1.0 * (tnow - tstart_writing)) / blockswritten * tapesize; @@ -559,7 +556,7 @@ lastdump(arg) dt = fstabsearch(dtwalk->dd_name); dumpme = (dt != NULL && dt->fs_freq != 0 && - dtwalk->dd_ddate < tnow - (dt->fs_freq * SECSPERDAY)); + dtwalk->dd_ddate < tnow - (dt->fs_freq * 86400)); if (arg != 'w' || dumpme) (void) printf( "%c %8s\t(%6s) Last dump: Level %c, Date %s\n", diff --git a/dump/tape.c b/dump/tape.c index ce15056..9d57ddf 100644 --- a/dump/tape.c +++ b/dump/tape.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,9 +40,17 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ +#ifdef __linux__ +#include +#include +#endif #include #include #include @@ -80,7 +89,6 @@ int write(), read(); #include #endif #include "dump.h" -#include "pathnames.h" int writesize; /* size of malloc()ed buffer for tape */ long lastspclrec = -1; /* tape block number of last written header */ @@ -92,7 +100,7 @@ extern int cartridge; extern char *host; char *nexttape; -static int atomic __P((int (*)(), int, char *, int)); +static int atomic __P((ssize_t (*)(), int, char *, int)); static void doslave __P((int, int)); static void enslave __P((void)); static void flushtape __P((void)); @@ -153,7 +161,7 @@ alloctape() * repositioning after stopping, i.e, streaming mode, where the gap is * variable, 0.30" to 0.45". The gap is maximal when the tape stops. */ - if (blocksperfile == 0) + if (blocksperfile == 0 && !unlimited) tenths = writesize / density + (cartridge ? 16 : density == 625 ? 5 : 8); /* @@ -321,7 +329,7 @@ flushtape() asize += tenths; blockswritten += ntrec; blocksthisvol += ntrec; - if (!pipeout && (blocksperfile ? + if (!pipeout && !unlimited && (blocksperfile ? (blocksthisvol >= blocksperfile) : (asize > tsize))) { close_rewind(); startnewtape(0); @@ -337,12 +345,12 @@ trewind() for (f = 0; f < SLAVES; f++) { /* - * Drain the results, but unlike EOT we DO (or should) care - * what the return values were, since if we detect EOT after - * we think we've written the last blocks to the tape anyway, + * Drain the results, but unlike EOT we DO (or should) care + * what the return values were, since if we detect EOT after + * we think we've written the last blocks to the tape anyway, * we have to replay those blocks with rollforward. * - * fixme: punt for now. + * fixme: punt for now. */ if (slaves[f].sent) { if (atomic(read, slaves[f].fd, (char *)&got, sizeof got) @@ -385,9 +393,16 @@ trewind() void close_rewind() { + time_t tstart_changevol, tend_changevol; + trewind(); if (nexttape) return; +#ifdef __linux__ + (void)time4(&(tstart_changevol)); +#else + (void)time((time_t *)&(tstart_changevol)); +#endif if (!nogripe) { msg("Change Volumes: Mount volume #%d\n", tapeno+1); broadcast("CHANGE DUMP VOLUMES!\7\7\n"); @@ -397,6 +412,13 @@ close_rewind() dumpabort(0); /*NOTREACHED*/ } +#ifdef __linux__ + (void)time4(&(tend_changevol)); +#else + (void)time((time_t *)&(tend_changevol)); +#endif + if ((tstart_changevol != (time_t)-1) && (tend_changevol != (time_t)-1)) + tstart_writing += (tend_changevol - tstart_changevol); } void @@ -406,13 +428,17 @@ rollforward() register struct slave *tslp; int i, size, savedtapea, got; union u_spcl *ntb, *otb; +#ifdef __linux__ + int blks; + long lastfirstrec; +#endif tslp = &slaves[SLAVES]; ntb = (union u_spcl *)tslp->tblock[1]; /* - * Each of the N slaves should have requests that need to - * be replayed on the next tape. Use the extra slave buffers - * (slaves[SLAVES]) to construct request lists to be sent to + * Each of the N slaves should have requests that need to + * be replayed on the next tape. Use the extra slave buffers + * (slaves[SLAVES]) to construct request lists to be sent to * each slave in turn. */ for (i = 0; i < SLAVES; i++) { @@ -420,7 +446,7 @@ rollforward() otb = (union u_spcl *)slp->tblock; /* - * For each request in the current slave, copy it to tslp. + * For each request in the current slave, copy it to tslp. */ prev = NULL; @@ -457,6 +483,9 @@ rollforward() dumpabort(0); } slp->sent = 1; +#ifdef __linux__ + lastfirstrec = slp->firstrec; +#endif if (++slp >= &slaves[SLAVES]) slp = &slaves[0]; @@ -464,8 +493,8 @@ rollforward() if (prev->dblk != 0) { /* - * If the last one was a disk block, make the - * first of this one be the last bit of that disk + * If the last one was a disk block, make the + * first of this one be the last bit of that disk * block... */ q->dblk = prev->dblk + @@ -473,7 +502,7 @@ rollforward() ntb = (union u_spcl *)tslp->tblock; } else { /* - * It wasn't a disk block. Copy the data to its + * It wasn't a disk block. Copy the data to its * new location in the buffer. */ q->dblk = 0; @@ -484,7 +513,11 @@ rollforward() slp->req[0] = *q; nextblock = slp->tblock; if (q->dblk == 0) +#ifdef __linux__ + *(union u_spcl *)(*(nextblock)++) = *(union u_spcl *)tslp->tblock; +#else nextblock++; +#endif trecno = 1; /* @@ -503,6 +536,22 @@ rollforward() quit("EOT detected at start of the tape!\n"); } } + +#ifdef __linux__ + blks = 0; + if (spcl.c_type != TS_END) { + for (i = 0; i < spcl.c_count; i++) + if (spcl.c_addr[i] != 0) + blks++; + } + + slp->firstrec = lastfirstrec + ntrec; + slp->count = lastspclrec + blks + 1 - spcl.c_tapea; + slp->inode = curino; + asize += tenths; + blockswritten += ntrec; + blocksthisvol += ntrec; +#endif } /* @@ -571,7 +620,7 @@ restore_check_point: case X_FINOK: msg("Child %d finishes X_FINOK\n", childpid); break; - case X_ABORT: + case X_ABORT: msg("Child %d finishes X_ABORT\n", childpid); break; case X_REWRITE: @@ -621,7 +670,7 @@ restore_check_point: while ((tapefd = (host ? rmtopen(tape, 2) : pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0) #else - while ((tapefd = (pipeout ? 1 : + while ((tapefd = (pipeout ? 1 : open(tape, O_WRONLY|O_CREAT, 0666))) < 0) #endif { @@ -636,7 +685,7 @@ restore_check_point: blocksthisvol = 0; if (top) newtape++; /* new tape signal */ - spcl.c_count = slp->count; + spcl.c_count = slp->count; /* * measure firstrec in TP_BSIZE units since restore doesn't * know the correct ntrec value... @@ -671,7 +720,7 @@ dumpabort(signo) Exit(X_ABORT); } -__dead void +void Exit(status) int status; { @@ -751,7 +800,6 @@ enslave() quit("master/slave protocol botched 4\n"); #endif - /* write pid of next slave to each slave */ for (i = 0; i < SLAVES; i++) (void) atomic(write, slaves[i].fd, (char *) &slaves[(i + 1) % SLAVES].pid, @@ -766,8 +814,10 @@ killall() register int i; for (i = 0; i < SLAVES; i++) - if (slaves[i].pid > 0) + if (slaves[i].pid > 0) { (void) kill(slaves[i].pid, SIGKILL); + slaves[i].sent = 0; + } } /* @@ -788,9 +838,6 @@ doslave(cmd, slave_number) errcode_t retval; #endif -#ifdef TDEBUG - msg("slave %d, pid %d\n", slave_number, getpid()); -#endif /* * Need our own seek pointer. */ @@ -825,7 +872,7 @@ doslave(cmd, slave_number) p->count * TP_BSIZE); } else { if (p->count != 1 || atomic(read, cmd, - (char *)slp->tblock[trecno], + (char *)slp->tblock[trecno], TP_BSIZE) != TP_BSIZE) quit("master/slave protocol botched.\n"); } @@ -839,6 +886,7 @@ doslave(cmd, slave_number) caught = 0; /* Try to write the data... */ + wrote = 0; eot_count = 0; size = 0; @@ -852,9 +900,9 @@ doslave(cmd, slave_number) wrote = write(tapefd, slp->tblock[0]+size, writesize-size); #ifdef WRITEDEBUG - msg("slave %d wrote %d\n", slave_number, wrote); + printf("slave %d wrote %d\n", slave_number, wrote); #endif - if (wrote < 0) + if (wrote < 0) break; if (wrote == 0) eot_count++; @@ -862,19 +910,23 @@ doslave(cmd, slave_number) } #ifdef WRITEDEBUG - if (size != writesize) - msg("slave %d only wrote %d out of %d bytes and gave up.\n", + if (size != writesize) + printf("slave %d only wrote %d out of %d bytes and gave up.\n", slave_number, size, writesize); #endif + /* + * Handle ENOSPC as an EOT condition. + */ + if (wrote < 0 && errno == ENOSPC) { + wrote = 0; + eot_count++; + } + if (eot_count > 0) size = 0; - /* - * fixme: Pyramids running OSx return ENOSPC - * at EOT on 1/2 inch drives. - */ - if (size < 0) { + if (wrote < 0) { (void) kill(master, SIGUSR1); for (;;) (void) sigpause(0); @@ -884,7 +936,7 @@ doslave(cmd, slave_number) * (for EOT handling) */ (void) atomic(write, cmd, (char *)&size, sizeof size); - } + } /* * If partial write, don't want next slave to go. @@ -903,7 +955,8 @@ doslave(cmd, slave_number) */ static int atomic(func, fd, buf, count) - int (*func)(), fd; + ssize_t (*func)(); + int fd; char *buf; int count; { diff --git a/dump/traverse.c b/dump/traverse.c index ccc03f7..2928884 100644 --- a/dump/traverse.c +++ b/dump/traverse.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,17 +40,21 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include -#include #include #ifdef __linux__ #include #include #include #include +#define swab32(x) ext2fs_swab32(x) #else /* __linux__ */ #ifdef sunos #include @@ -88,14 +93,13 @@ typedef quad_t fsizeT; typedef long fsizeT; #endif -#ifndef __linux__ -static int dirindir __P((ino_t ino, daddr_t blkno, int level, long *size)); -#endif -static void dmpindir __P((ino_t ino, daddr_t blk, int level, fsizeT *size)); #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); #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)); static int searchdir __P((ino_t ino, daddr_t blkno, long size, long filesize)); #endif @@ -343,10 +347,13 @@ mapdirs(maxino, tapesize) long *tapesize; { register struct dinode *dp; - register int i, isdir; + register int isdir; register char *map; register ino_t ino; +#ifndef __linux + register int i; long filesize; +#endif int ret, change = 0; isdir = 0; /* XXX just to get gcc to shut up */ @@ -357,12 +364,11 @@ mapdirs(maxino, tapesize) isdir >>= 1; if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap)) continue; -#ifdef __linux__ dp = getino(ino); +#ifdef __linux__ ret = 0; ext2fs_dir_iterate(fs, ino, 0, NULL, searchdir, (void *) &ret); #else /* __linux__ */ - dp = getino(ino); filesize = dp->di_size; for (ret = 0, i = 0; filesize > 0 && i < NDADDR; i++) { if (dp->di_db[i] != 0) @@ -569,12 +575,14 @@ dumpino(dp, ino) register struct dinode *dp; ino_t ino; { - int ind_level, cnt; + int cnt; fsizeT size; char buf[TP_BSIZE]; struct old_bsd_inode obi; #ifdef __linux__ struct block_context bc; +#else + int ind_level; #endif if (newtape) { @@ -676,7 +684,7 @@ dumpino(dp, ino) else cnt = howmany(dp->di_size, sblock->fs_fsize); blksout(&dp->di_db[0], cnt, ino); - if ((size = ((int)dp->di_size) - NDADDR * sblock->fs_bsize) <= 0) + if ((size = dp->di_size - NDADDR * sblock->fs_bsize) <= 0) return; #ifdef __linux__ bc.max = NINDIR(sblock) * EXT2_FRAGS_PER_BLOCK(fs->super); @@ -865,10 +873,31 @@ dmpindir(ino, blk, ind_level, size) fsizeT *size; { int i, cnt; +#ifdef __linux__ + int max; + blk_t *swapme; +#endif daddr_t idblk[MAXNINDIR]; - if (blk != 0) + if (blk != 0) { bread(fsbtodb(sblock, blk), (char *)idblk, (int) sblock->fs_bsize); +#ifdef __linux__ + /* + * My RedHat 4.0 system doesn't have these flags; I haven't + * upgraded e2fsprogs yet + */ +#if defined(EXT2_FLAG_SWAP_BYTES) + if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || + (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)) { +#endif + max = sblock->fs_bsize >> 2; + swapme = (blk_t *) idblk; + for (i = 0; i < max; i++, swapme++) + *swapme = swab32(*swapme); +#if defined(EXT2_FLAG_SWAP_BYTES) + } +#endif +#endif else memset(idblk, 0, (int)sblock->fs_bsize); if (ind_level <= 0) { @@ -959,7 +988,7 @@ writeheader(ino) #ifdef __linux__ register __s32 sum, cnt, *lp; #else - register long sum, cnt, *lp; + register int32_t sum, cnt, *lp; #endif spcl.c_inumber = ino; @@ -968,13 +997,13 @@ writeheader(ino) #ifdef __linux__ lp = (__s32 *)&spcl; #else - lp = (long *)&spcl; + lp = (int32_t *)&spcl; #endif sum = 0; #ifdef __linux__ cnt = sizeof(union u_spcl) / (4 * sizeof(__s32)); #else - cnt = sizeof(union u_spcl) / (4 * sizeof(long)); + cnt = sizeof(union u_spcl) / (4 * sizeof(int32_t)); #endif while (--cnt >= 0) { sum += *lp++; @@ -1022,24 +1051,25 @@ getino(inum) * Error recovery is attempted at most BREADEMAX times before seeking * consent from the operator to continue. */ -int breaderrors = 0; +int breaderrors = 0; #define BREADEMAX 32 void bread(blkno, buf, size) daddr_t blkno; char *buf; - int size; + int size; { int cnt, i; extern int errno; loop: #ifdef __linux__ - if (ext2_llseek(diskfd, ((ext2_loff_t)blkno << dev_bshift), 0) != + if (llseek(diskfd, ((ext2_loff_t)blkno << dev_bshift), 0) != ((ext2_loff_t)blkno << dev_bshift)) #else - if ((int)lseek(diskfd, ((off_t)blkno << dev_bshift), 0) == -1) + if (lseek(diskfd, ((off_t)blkno << dev_bshift), 0) != + ((off_t)blkno << dev_bshift)) #endif msg("bread: lseek fails\n"); if ((cnt = read(diskfd, buf, size)) == size) @@ -1081,10 +1111,11 @@ loop: memset(buf, 0, size); for (i = 0; i < size; i += dev_bsize, buf += dev_bsize, blkno++) { #ifdef __linux__ - if (ext2_llseek(diskfd, ((ext2_loff_t)blkno << dev_bshift), 0) != + if (llseek(diskfd, ((ext2_loff_t)blkno << dev_bshift), 0) != ((ext2_loff_t)blkno << dev_bshift)) #else - if ((int)lseek(diskfd, ((off_t)blkno << dev_bshift), 0) == -1) + if (lseek(diskfd, ((off_t)blkno << dev_bshift), 0) != + ((off_t)blkno << dev_bshift)) #endif msg("bread: lseek2 fails!\n"); if ((cnt = read(diskfd, buf, (int)dev_bsize)) == dev_bsize) diff --git a/dump/unctime.c b/dump/unctime.c index eccc509..d821b78 100644 --- a/dump/unctime.c +++ b/dump/unctime.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,22 +40,19 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ -#include - -#include #include #ifdef __STDC__ #include #include #endif -#ifndef __P -#include -#endif - /* * Convert a ctime(3) format string into a system format date. * Return the date thus calculated. diff --git a/restore/dirs.c b/restore/dirs.c index 78285ad..9b564c2 100644 --- a/restore/dirs.c +++ b/restore/dirs.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -44,13 +45,16 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include #include #include -#include #ifdef __linux__ #include @@ -58,10 +62,10 @@ static char sccsid[] = "@(#)dirs.c 8.7 (Berkeley) 5/1/95"; #else /* __linux__ */ #include #include -#include #endif /* __linux__ */ #include +#include #include #include #include @@ -86,8 +90,8 @@ static char sccsid[] = "@(#)dirs.c 8.7 (Berkeley) 5/1/95"; struct inotab { struct inotab *t_next; ino_t t_ino; - long t_seekpt; - long t_size; + int32_t t_seekpt; + int32_t t_size; }; static struct inotab *inotab[HASHSIZE]; @@ -110,8 +114,8 @@ struct modeinfo { #define DIRBLKSIZ 1024 struct rstdirdesc { int dd_fd; - long dd_loc; - long dd_size; + int32_t dd_loc; + int32_t dd_size; char dd_buf[DIRBLKSIZ]; }; @@ -121,9 +125,9 @@ struct rstdirdesc { static long seekpt; static FILE *df, *mf; static RST_DIR *dirp; -static char dirfile[32] = "#"; /* No file */ -static char modefile[32] = "#"; /* No file */ -static char dot[2] = "."; /* So it can be modified */ +static char dirfile[MAXPATHLEN] = "#"; /* No file */ +static char modefile[MAXPATHLEN] = "#"; /* No file */ +static char dot[2] = "."; /* So it can be modified */ /* * Format of old style directories. @@ -167,32 +171,37 @@ extractdirs(genmode) #endif struct inotab *itp; struct direct nulldir; + int fd; vprintf(stdout, "Extract directories from tape\n"); - (void) sprintf(dirfile, "%s/rstdir%d", tmpdir, dumpdate); - df = fopen(dirfile, "w"); - if (df == NULL) { - fprintf(stderr, - "restore: %s - cannot create directory temporary\n", - dirfile); - fprintf(stderr, "fopen: %s\n", strerror(errno)); + (void) sprintf(dirfile, "%s/rstdir%ld", tmpdir, dumpdate); + if (command != 'r' && command != 'R') { + (void *) strcat(dirfile, "-XXXXXX"); + 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); } if (genmode != 0) { - (void) sprintf(modefile, "%s/rstmode%d", tmpdir, dumpdate); - mf = fopen(modefile, "w"); - if (mf == NULL) { - fprintf(stderr, - "restore: %s - cannot create modefile \n", - modefile); - fprintf(stderr, "fopen: %s\n", strerror(errno)); + (void) sprintf(modefile, "%s/rstmode%ld", tmpdir, dumpdate); + if (command != 'r' && command != 'R') { + (void *) strcat(modefile, "-XXXXXX"); + 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); } } nulldir.d_ino = 0; -#ifdef __linux__ nulldir.d_type = DT_DIR; -#endif nulldir.d_namlen = 1; (void) strcpy(nulldir.d_name, "/"); nulldir.d_reclen = DIRSIZ(0, &nulldir); @@ -234,7 +243,7 @@ skipdirs() } /* - * Recursively find names and inumbers of all files in subtree + * Recursively find names and inumbers of all files in subtree * pname and pass them off to be processed. */ void @@ -266,8 +275,9 @@ treescan(pname, ino, todo) * begin search through the directory * skipping over "." and ".." */ - (void) strncpy(locname, pname, MAXPATHLEN); - (void) strncat(locname, "/", MAXPATHLEN); + (void) strncpy(locname, pname, sizeof(locname) - 1); + locname[sizeof(locname) - 1] = '\0'; + (void) strncat(locname, "/", sizeof(locname) - strlen(locname)); namelen = strlen(locname); rst_seekdir(dirp, itp->t_seekpt, itp->t_seekpt); dp = rst_readdir(dirp); /* "." */ @@ -287,9 +297,9 @@ treescan(pname, ino, todo) */ while (dp != NULL) { locname[namelen] = '\0'; - if (namelen + dp->d_namlen >= MAXPATHLEN) { + if (namelen + dp->d_namlen >= sizeof(locname)) { fprintf(stderr, "%s%s: name exceeds %d char\n", - locname, dp->d_name, MAXPATHLEN); + locname, dp->d_name, sizeof(locname) - 1); } else { (void) strncat(locname, dp->d_name, (int)dp->d_namlen); treescan(locname, dp->d_ino, todo); @@ -317,7 +327,7 @@ pathsearch(pathname) while (*path == '/') path++; dp = NULL; - while ((name = strsep(&path, "/")) != NULL && *name /* != NULL */) { + while ((name = strsep(&path, "/")) != NULL && *name != '\0') { if ((dp = searchdir(ino, name)) == NULL) return (NULL); ino = dp->d_ino; @@ -482,9 +492,7 @@ dcvt(odp, ndp) memset(ndp, 0, (long)(sizeof *ndp)); ndp->d_ino = odp->d_ino; -#ifdef __linux__ ndp->d_type = DT_UNKNOWN; -#endif (void) strncpy(ndp->d_name, odp->d_name, ODIRSIZ); ndp->d_namlen = strlen(ndp->d_name); ndp->d_reclen = DIRSIZ(0, ndp); @@ -507,7 +515,7 @@ rst_seekdir(dirp, loc, base) return; loc -= base; if (loc < 0) - fprintf(stderr, "bad seek pointer to rst_seekdir %d\n", loc); + fprintf(stderr, "bad seek pointer to rst_seekdir %ld\n", loc); (void) lseek(dirp->dd_fd, base + (loc & ~(DIRBLKSIZ - 1)), SEEK_SET); dirp->dd_loc = loc & (DIRBLKSIZ - 1); if (dirp->dd_loc != 0) @@ -525,7 +533,7 @@ rst_readdir(dirp) for (;;) { if (dirp->dd_loc == 0) { - dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, + dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ); if (dirp->dd_size <= 0) { dprintf(stderr, "error reading directory\n"); @@ -539,9 +547,8 @@ 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" - "dd_loc = %d, dd_size = %d\n", - dp->d_reclen, dirp->dd_loc, dirp->dd_size); + dprintf(stderr, "corrupted directory: bad reclen %d\n", + dp->d_reclen); return (NULL); } dirp->dd_loc += dp->d_reclen; @@ -632,9 +639,15 @@ setdirmodes(flags) struct modeinfo node; struct entry *ep; char *cp; - + vprintf(stdout, "Set directory mode, owner, and times.\n"); - (void) sprintf(modefile, "%s/rstmode%d", tmpdir, dumpdate); + if (command == 'r' || command == 'R') + (void) sprintf(modefile, "%s/rstmode%ld", tmpdir, dumpdate); + if (modefile[0] == '#') { + panic("modefile not defined\n"); + fprintf(stderr, "directory mode, owner, and times not set\n"); + return; + } mf = fopen(modefile, "r"); if (mf == NULL) { fprintf(stderr, "fopen: %s\n", strerror(errno)); @@ -706,14 +719,14 @@ genliteraldir(name, ino) size = i < BUFSIZ ? i : BUFSIZ; if (read(dp, buf, (int) size) == -1) { fprintf(stderr, - "write error extracting inode %d, name %s\n", + "write error extracting inode %ld, name %s\n", curfile.ino, curfile.name); fprintf(stderr, "read: %s\n", strerror(errno)); done(1); } if (!Nflag && write(ofile, buf, (int) size) == -1) { fprintf(stderr, - "write error extracting inode %d, name %s\n", + "write error extracting inode %ld, name %s\n", curfile.ino, curfile.name); fprintf(stderr, "write: %s\n", strerror(errno)); done(1); @@ -803,7 +816,7 @@ inotablookup(ino) /* * Clean up and exit */ -__dead void +void done(exitcode) int exitcode; { diff --git a/restore/extern.h b/restore/extern.h index 54b37ab..c2b88b9 100644 --- a/restore/extern.h +++ b/restore/extern.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -38,26 +39,29 @@ * SUCH DAMAGE. * * @(#)extern.h 8.2 (Berkeley) 1/7/94 + * $Id: extern.h,v 1.2 1999/10/11 12:53:23 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 canon __P((char *, char *)); +void canon __P((char *, char *, int)); void checkrestore __P((void)); void closemt __P((void)); +void comparefile __P((char *)); +void compareleaves __P((void)); void createfiles __P((void)); void createleaves __P((char *)); -void compareleaves __P((void)); void createlinks __P((void)); 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 *)); -void comparefile __P((char *)); void findunreflinks __P((void)); char *flagvalues __P((struct entry *)); void freeentry __P((struct entry *)); diff --git a/restore/interactive.c b/restore/interactive.c index c7b730b..f98ff0f 100644 --- a/restore/interactive.c +++ b/restore/interactive.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,11 +40,14 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include -#include #include #ifdef __linux__ @@ -52,7 +56,6 @@ static char sccsid[] = "@(#)interactive.c 8.5 (Berkeley) 5/1/95"; #else /* __linux__ */ #include #include -#include #endif /* __linux__ */ #include @@ -98,7 +101,7 @@ struct arglist { static char *copynext __P((char *, char *)); static int fcmp __P((const void *, const void *)); static void formatf __P((struct afile *, int)); -static void getcmd __P((char *, char *, char *, struct arglist *)); +static void getcmd __P((char *, char *, char *, int, struct arglist *)); struct dirent *glob_readdir __P((RST_DIR *dirp)); static int glob_stat __P((const char *, struct stat *)); static void mkentry __P((char *, struct direct *, struct afile *)); @@ -125,7 +128,7 @@ runcmdshell() arglist.glob.gl_closedir = (void *)rst_closedir; arglist.glob.gl_lstat = glob_stat; arglist.glob.gl_stat = glob_stat; - canon("/", curdir); + canon("/", curdir, sizeof(curdir)); loop: if (setjmp(reset) != 0) { if (arglist.freeglob != 0) { @@ -137,7 +140,7 @@ loop: volno = 0; } runshell = 1; - getcmd(curdir, cmd, name, &arglist); + getcmd(curdir, cmd, name, sizeof(name), &arglist); switch (cmd[0]) { /* * Add elements to the extraction list. @@ -316,9 +319,10 @@ loop: * eliminate any embedded ".." components. */ static void -getcmd(curdir, cmd, name, ap) +getcmd(curdir, cmd, name, size, ap) char *curdir, *cmd, *name; struct arglist *ap; + int size; { register char *cp; static char input[BUFSIZ]; @@ -356,7 +360,8 @@ getcmd(curdir, cmd, name, ap) * If no argument, use curdir as the default. */ if (*cp == '\0') { - (void) strcpy(name, curdir); + (void) strncpy(name, curdir, size); + name[size - 1] = '\0'; return; } nextarg = cp; @@ -373,16 +378,14 @@ getnext: * If it is an absolute pathname, canonicalize it and return it. */ if (rawname[0] == '/') { - canon(rawname, name); + canon(rawname, name, size); } else { /* * For relative pathnames, prepend the current directory to * it then canonicalize and return it. */ - (void) strcpy(output, curdir); - (void) strcat(output, "/"); - (void) strcat(output, rawname); - canon(output, name); + snprintf(output, sizeof(output), "%s/%s", curdir, rawname); + canon(output, name, size); } if (glob(name, GLOB_ALTDIRFUNC, NULL, &ap->glob) < 0) fprintf(stderr, "%s: out of memory\n", ap->cmd); @@ -392,7 +395,8 @@ getnext: ap->argcnt = ap->glob.gl_pathc; retnext: - strcpy(name, ap->glob.gl_pathv[ap->glob.gl_pathc - ap->argcnt]); + strncpy(name, ap->glob.gl_pathv[ap->glob.gl_pathc - ap->argcnt], size); + name[size - 1] = '\0'; if (--ap->argcnt == 0) { ap->freeglob = 0; globfree(&ap->glob); @@ -438,7 +442,7 @@ copynext(input, output) */ quote = *cp++; while (*cp != quote && *cp != '\0') - *bp++ = *cp++ /* | 0200 */; + *bp++ = *cp++ | 0200; if (*cp++ == '\0') { fprintf(stderr, "missing %c\n", quote); cp--; @@ -451,11 +455,12 @@ copynext(input, output) /* * Canonicalize file names to always start with ``./'' and - * remove any imbedded "." and ".." components. + * remove any embedded "." and ".." components. */ void -canon(rawname, canonname) +canon(rawname, canonname, len) char *rawname, *canonname; + int len; { register char *cp, *np; @@ -465,6 +470,11 @@ canon(rawname, canonname) (void) strcpy(canonname, "."); else (void) strcpy(canonname, "./"); + if (strlen(canonname) + strlen(rawname) >= len) { + fprintf(stderr, "canonname: not enough buffer space\n"); + done(1); + } + (void) strcat(canonname, rawname); /* * Eliminate multiple and trailing '/'s @@ -508,7 +518,7 @@ printlist(name, basename) char *name; char *basename; { - register struct afile *fp, *list, *listp; + register struct afile *fp, *list, *listp=NULL; register struct direct *dp; struct afile single; RST_DIR *dirp; @@ -531,8 +541,7 @@ printlist(name, basename) } } else { entries = 0; -/* while ((dp = rst_readdir(dirp)) && (dp->d_ino != 0)) */ - while (dp = rst_readdir(dirp)) + while ((dp = rst_readdir(dirp))) entries++; rst_closedir(dirp); list = (struct afile *)malloc(entries * sizeof(struct afile)); @@ -548,7 +557,7 @@ printlist(name, basename) (void) strncpy(locname, name, MAXPATHLEN); (void) strncat(locname, "/", MAXPATHLEN); namelen = strlen(locname); - while (dp = rst_readdir(dirp)) { + while ((dp = rst_readdir(dirp))) { if (dp == NULL) break; if (!dflag && TSTINO(dp->d_ino, dumpmap) == 0) @@ -609,12 +618,6 @@ mkentry(name, dp, fp) fp->prefix = '*'; else fp->prefix = ' '; -#if 0 - if (inodetype(dp->d_ino) == NODE) - fp->postfix = '/'; - else - fp->postfix = ' '; -#else /* __linux__ */ switch(dp->d_type) { default: @@ -651,7 +654,6 @@ mkentry(name, dp, fp) fp->postfix = ' '; break; } -#endif /* __linux__ */ return; } @@ -665,7 +667,7 @@ formatf(list, nentry) { register struct afile *fp, *endlist; int width, bigino, haveprefix, havepostfix; - int i, j, w, precision, columns, lines; + int i, j, w, precision=0, columns, lines; width = 0; haveprefix = 0; @@ -700,7 +702,7 @@ formatf(list, nentry) for (j = 0; j < columns; j++) { fp = &list[j * lines + i]; if (vflag) { - fprintf(stderr, "%*d ", precision, fp->fnum); + fprintf(stderr, "%*ld ", precision, fp->fnum); fp->len += precision + 1; } if (haveprefix) { @@ -757,11 +759,7 @@ glob_readdir(dirp) if (dp == NULL) return (NULL); adirent.d_fileno = dp->d_ino; -#ifdef __linux__ adirent.d_namlen = dp->d_namlen; -#else - adirent.d_namlen = dp->d_namlen & 0xff; -#endif memmove(adirent.d_name, dp->d_name, dp->d_namlen + 1); return (&adirent); } diff --git a/restore/main.c b/restore/main.c index 6f4098d..e1e9790 100644 --- a/restore/main.c +++ b/restore/main.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,34 +40,36 @@ */ #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1983, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include -#include #include +#include #ifdef __linux__ #include #include +#include +#include #else /* __linux__ */ #include -#include #endif /* __linux__ */ #include #include -#include -#include #include #include -#include #include #ifdef __linux__ @@ -80,6 +83,8 @@ static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/4/95"; int bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0; int hflag = 1, mflag = 1, Nflag = 0; +int uflag = 0; +int dokerberos = 0; char command = '\0'; long dumpnum = 1; long volno = 0; @@ -108,19 +113,29 @@ main(argc, argv) { int ch; ino_t ino; - char *inputdev = _PATH_DEFTAPE; + char *inputdev; char *symtbl = "./restoresymtable"; char *p, name[MAXPATHLEN]; - if (argc < 2) - usage(); + /* Temp files should *not* be readable. We set permissions later. */ + (void) umask(077); #ifdef __linux__ __progname = argv[0]; #endif + if (argc < 2) + usage(); + + if ((inputdev = getenv("TAPE")) == NULL) + inputdev = _PATH_DEFTAPE; obsolete(&argc, &argv); - while ((ch = getopt(argc, argv, "b:CcdD:f:himNRrs:tT:vxy")) != EOF) +#ifdef KERBEROS +#define optlist "b:CcdDf:hikmNRrs:tTuvxy" +#else +#define optlist "b:CcdDf:himNRrs:tTuvxy" +#endif + while ((ch = getopt(argc, argv, optlist)) != -1) switch(ch) { case 'b': /* Change default tape blocksize. */ @@ -149,6 +164,11 @@ main(argc, argv) case 'h': hflag = 0; break; +#ifdef KERBEROS + case 'k': + dokerberos = 1; + break; +#endif case 'C': case 'i': case 'R': @@ -175,6 +195,9 @@ main(argc, argv) if (dumpnum <= 0) errx(1, "dump number must be greater than 0"); break; + case 'u': + uflag = 1; + break; case 'v': vflag = 1; break; @@ -301,7 +324,7 @@ main(argc, argv) extractdirs(0); initsymtable((char *)0); while (argc--) { - canon(*argv++, name); + canon(*argv++, name, sizeof(name)); ino = dirlookup(name); if (ino == 0) continue; @@ -316,7 +339,7 @@ main(argc, argv) extractdirs(1); initsymtable((char *)0); while (argc--) { - canon(*argv++, name); + canon(*argv++, name, sizeof(name)); ino = dirlookup(name); if (ino == 0) continue; @@ -333,16 +356,18 @@ main(argc, argv) } done(0); /* NOTREACHED */ + exit(1); /* gcc shut up */ } static void usage() { (void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n\t%s\n", - "restore -i [-chmvy] [-b blocksize] [-f file] [-s fileno]", - "restore -r [-cvy] [-b blocksize] [-f file] [-s fileno]", - "restore -R [-cvy] [-b blocksize] [-f file] [-s fileno]", - "restore -x [-chmvy] [-b blocksize] [-f file] [-s fileno] [file ...]", "restore -t [-chvy] [-b blocksize] [-f file] [-s fileno] [file ...]"); + "restore -i [-chkmuvy] [-b blocksize] [-f file] [-s fileno]", + "restore -r [-ckuvy] [-b blocksize] [-f file] [-s fileno]", + "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); } @@ -357,7 +382,7 @@ obsolete(argcp, argvp) char **argvp[]; { int argc, flags; - char *ap, **argv, *flagsp, **nargv, *p; + char *ap, **argv, *flagsp=NULL, **nargv, *p=NULL; /* Setup. */ argv = *argvp; @@ -374,7 +399,7 @@ obsolete(argcp, argvp) err(1, NULL); *nargv++ = *argv; - argv += 2; + argv += 2, argc -= 2; for (flags = 0; *ap; ++ap) { switch (*ap) { @@ -410,7 +435,7 @@ obsolete(argcp, argvp) } /* Copy remaining arguments. */ - while (*nargv++ = *argv++); + while ((*nargv++ = *argv++)); /* Update argument count. */ *argcp = nargv - *argvp - 1; diff --git a/restore/restore.8 b/restore/restore.8 index 785a6c3..667729b 100644 --- a/restore/restore.8 +++ b/restore/restore.8 @@ -30,6 +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 $ .\" .Dd May 1, 1995 .Dt RESTORE 8 @@ -40,7 +41,7 @@ .Sh SYNOPSIS .Nm restore .Fl C -.Op Fl cvy +.Op Fl ckvy .Op Fl b Ar blocksize .Op Fl D Ar filesystem .Op Fl f Ar file @@ -48,28 +49,28 @@ .Op Fl T Ar directory .Nm restore .Fl i -.Op Fl chmNvy +.Op Fl chkmNuvy .Op Fl b Ar blocksize .Op Fl f Ar file .Op Fl s Ar fileno .Op Fl T Ar directory .Nm restore .Fl R -.Op Fl cNvy +.Op Fl ckNuvy .Op Fl b Ar blocksize .Op Fl f Ar file .Op Fl s Ar fileno .Op Fl T Ar directory .Nm restore .Fl r -.Op Fl cNvy +.Op Fl ckNuvy .Op Fl b Ar blocksize .Op Fl f Ar file .Op Fl s Ar fileno .Op Fl T Ar directory .Nm restore .Fl t -.Op Fl chvy +.Op Fl chkNuvy .Op Fl b Ar blocksize .Op Fl f Ar file .Op Fl s Ar fileno @@ -77,7 +78,7 @@ .Op file ... .Nm restore .Fl x -.Op Fl chmNvy +.Op Fl chkmNuvy .Op Fl b Ar blocksize .Op Fl f Ar file .Op Fl s Ar fileno @@ -284,12 +285,12 @@ If the .Fl b option is not specified, .Nm restore -tries to determine the block size dynamically. +tries to determine the media block size dynamically. .It Fl c Normally, .Nm restore will try to determine dynamically whether the dump was made from an -old (pre-4.4) or new format file sytem. The +old (pre-4.4) or new format file system. The .Fl c flag disables this check, and only allows reading a dump in the old format. @@ -323,6 +324,12 @@ or reads from the named file on the remote host using .Xr rmt 8 . .Pp +.It Fl k +Use Kerberos authentication when contacting the remote tape server. +(Only available if this options was enabled when +.Nm restore +was compiled.) +.Pp .It Fl h Extract the actual directory, rather than the files that it references. @@ -350,6 +357,13 @@ flag allows the user to specify a directory to use for the storage of temporary files. The default value is /tmp. This flag is most useful when restoring files after having booted from a floppy. There might be little or no space on the floppy filesystem, but another source of space might exist. +.It Fl u +When creating certain types of files, restore may generate a warning +diagnostic if they already exist in the target directory. +To prevent this, the +.Fl u +(unlink) flag causes restore to remove old entries before attempting +to create new ones. .It Fl v Normally .Nm restore @@ -432,6 +446,26 @@ After a dump read error, may have to resynchronize itself. This message lists the number of blocks that were skipped over. .El +.Sh ENVIRONMENT +.Bl -tag -width Fl +.It Ev TAPE +If no -f option was specified, +.Nm +will use the device specified via +.Ev TAPE +as the dump device. +.Ev TAPE +may be of the form +.Qq tapename , +.Qq host:tapename , +or +.Qq user@host:tapename . +.It Ev RMT +The environment variable +.Ev RMT +will be used to determine the pathname of the remote +.Xr rmt 8 +program. .Sh FILES .Bl -tag -width "./restoresymtable" -compact .It Pa /dev/rmt? @@ -445,8 +479,8 @@ information passed between incremental restores. .El .Sh SEE ALSO .Xr dump 8 , -.Xr newfs 8 , .Xr mount 8 , +.Xr newfs 8 , .Xr mkfs 8 , .Xr rmt 8 .Sh BUGS @@ -460,6 +494,11 @@ 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. +.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 +written to be setuid root, but we are not certain all bugs are gone +from the restore code - run setuid at your own risk.) .Sh HISTORY The .Nm restore diff --git a/restore/restore.c b/restore/restore.c index 533ae5b..773b709 100644 --- a/restore/restore.c +++ b/restore/restore.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,11 +40,14 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include -#include #ifdef __linux__ #include @@ -80,7 +84,7 @@ listfile(name, ino, type) if (TSTINO(ino, dumpmap) == 0) return (descend); vprintf(stdout, "%s", type == LEAF ? "leaf" : "dir "); - fprintf(stdout, "%10d\t%s\n", ino, name); + fprintf(stdout, "%10ld\t%s\n", ino, name); return (descend); } @@ -105,7 +109,7 @@ addfile(name, ino, type) if (ino == WINO && command == 'i' && !vflag) return (descend); if (!mflag) { - (void) sprintf(buf, "./%u", ino); + (void) sprintf(buf, "./%lu", ino); name = buf; if (type == NODE) { (void) genliteraldir(name, ino); @@ -153,7 +157,7 @@ deletefile(name, ino, type) return (descend); } -/* +/* * The following four routines implement the incremental * restore algorithm. The first removes old entries, the second * does renames and calculates the extraction list, the third @@ -162,7 +166,7 @@ deletefile(name, ino, type) * * Directories cannot be immediately deleted, as they may have * other files in them which need to be moved out first. As - * directories to be deleted are found, they are put on the + * directories to be deleted are found, they are put on the * following deletion list. After all deletions and renames * are done, this list is actually deleted. */ @@ -180,7 +184,7 @@ removeoldleaves() register ino_t i, mydirino; vprintf(stdout, "Mark entries to be removed.\n"); - if (ep = lookupino(WINO)) { + if ((ep = lookupino(WINO))) { vprintf(stdout, "Delete whiteouts\n"); for ( ; ep != NULL; ep = nextep) { nextep = ep->e_links; @@ -247,7 +251,7 @@ nodeupdates(name, ino, type) # define MODECHG 0x8 /* mode of inode changed */ /* - * This routine is called once for each element in the + * This routine is called once for each element in the * directory hierarchy, with a full path name. * The "type" value is incorrectly specified as LEAF for * directories that are not on the dump tape. @@ -438,7 +442,7 @@ nodeupdates(name, ino, type) * that we need to rename, so we delete it from the symbol * table, and put it on the list to be deleted eventually. * Conversely if a directory is to be created, it must be - * done immediately, rather than waiting until the + * done immediately, rather than waiting until the * extraction phase. */ case ONTAPE|INOFND|MODECHG: @@ -449,8 +453,12 @@ nodeupdates(name, ino, type) } if (ip->e_type == LEAF) { /* changing from leaf to node */ - removeleaf(ip); - freeentry(ip); + for (ip = lookupino(ino); ip != NULL; ip = ip->e_links) { + if (ip->e_type != LEAF) + badentry(ip, "NODE and LEAF links to same inode"); + removeleaf(ip); + freeentry(ip); + } ip = addentry(name, ino, type); newnode(ip); } else { @@ -468,7 +476,7 @@ nodeupdates(name, ino, type) break; /* - * A hard link to a diirectory that has been removed. + * A hard link to a directory that has been removed. * Ignore it. */ case NAMEFND: @@ -486,7 +494,7 @@ nodeupdates(name, ino, type) */ case NULL: if (compare_ignore_not_found) break; - fprintf(stderr, "%s: (inode %d) not found on tape\n", + fprintf(stderr, "%s: (inode %ld) not found on tape\n", name, ino); break; @@ -509,7 +517,7 @@ nodeupdates(name, ino, type) default: panic("[%s] %s: impossible state\n", keyval(key), name); break; - } + } return (descend); } @@ -615,6 +623,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 compare_entry(struct entry *ep, int do_compare) { if ((ep->e_flags & (NEW|EXTRACT)) == 0) @@ -660,7 +669,7 @@ compareleaves() * on the next incremental tape. */ if (first != curfile.ino) { - fprintf(stderr, "expected next file %d, got %d\n", + fprintf(stderr, "expected next file %ld, got %ld\n", first, curfile.ino); skipfile(); goto next; @@ -726,12 +735,12 @@ createleaves(symtabfile) /* * If we find files on the tape that have no corresponding * directory entries, then we must have found a file that - * was created while the dump was in progress. Since we have + * was created while the dump was in progress. Since we have * no name for it, we discard it knowing that it will be * on the next incremental tape. */ if (first != curfile.ino) { - fprintf(stderr, "expected next file %d, got %d\n", + fprintf(stderr, "expected next file %ld, got %ld\n", first, curfile.ino); skipfile(); goto next; @@ -744,7 +753,7 @@ createleaves(symtabfile) /* * If the file is to be extracted, then the old file must * be removed since its type may change from one leaf type - * to another (eg "file" to "character special"). + * to another (e.g. "file" to "character special"). */ if ((ep->e_flags & EXTRACT) != 0) { removeleaf(ep); @@ -754,7 +763,7 @@ createleaves(symtabfile) ep->e_flags &= ~(NEW|EXTRACT); /* * We checkpoint the restore after every tape reel, so - * as to simplify the amount of work re quired by the + * as to simplify the amount of work required by the * 'R' command. */ next: @@ -865,7 +874,7 @@ createlinks() register ino_t i; char name[BUFSIZ]; - if (ep = lookupino(WINO)) { + if ((ep = lookupino(WINO))) { vprintf(stdout, "Add whiteouts\n"); for ( ; ep != NULL; ep = ep->e_links) { if ((ep->e_flags & NEW) == 0) @@ -914,7 +923,7 @@ checkrestore() ep->e_flags &= ~KEEP; if (ep->e_type == NODE) ep->e_flags &= ~(NEW|EXISTED); - if (ep->e_flags /* != NULL */) + if (ep->e_flags != 0) badentry(ep, "incomplete operations"); } } diff --git a/restore/restore.h b/restore/restore.h index 1cef2d9..dbb97e5 100644 --- a/restore/restore.h +++ b/restore/restore.h @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -54,13 +55,14 @@ extern int dflag; /* print out debugging info */ extern int hflag; /* restore heirarchies */ extern int mflag; /* restore by name instead of inode number */ extern int Nflag; /* do not write the disk */ +extern int uflag; /* unlink symlink targets */ extern int vflag; /* print out actions taken */ extern int yflag; /* always try to recover from tape errors */ /* * Global variables */ extern char *dumpmap; /* map of inodes on this dump tape */ -extern char *usedinomap; /* map of inodes to be deleted */ +extern char *usedinomap; /* map of inodes that are in use on this fs */ extern ino_t maxino; /* highest numbered inode in this file system */ extern long dumpnum; /* location of the dump on this tape */ extern long volno; /* current volume being read */ diff --git a/restore/symtab.c b/restore/symtab.c index d9d9a2e..21beab7 100644 --- a/restore/symtab.c +++ b/restore/symtab.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,7 +40,11 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ /* @@ -167,8 +172,11 @@ lookupname(name) cp = name; for (ep = lookupino(ROOTINO); ep != NULL; ep = ep->e_entries) { - for (np = buf; *cp != '/' && *cp != '\0'; ) + for (np = buf; *cp != '/' && *cp != '\0' && + np < &buf[sizeof(buf)]; ) *np++ = *cp++; + if (np == &buf[sizeof(buf)]) + break; *np = '\0'; for ( ; ep != NULL; ep = ep->e_sibling) if (strcmp(ep->e_name, buf) == 0) @@ -227,7 +235,7 @@ myname(ep) } /* - * Unused symbol table entries are linked together on a freelist + * Unused symbol table entries are linked together on a free list * headed by the following pointer. */ static struct entry *freelist = NULL; @@ -271,7 +279,7 @@ addentry(name, inum, type) if (type & LINK) { ep = lookupino(inum); if (ep == NULL) - panic("link to non-existant name\n"); + panic("link to non-existent name\n"); np->e_ino = inum; np->e_links = ep->e_links; ep->e_links = np; @@ -383,12 +391,12 @@ removeentry(ep) /* * Table of unused string entries, sorted by length. - * + * * Entries are allocated in STRTBLINCR sized pieces so that names * of similar lengths can use the same entry. The value of STRTBLINCR * is chosen so that every entry has at least enough space to hold * a "struct strtbl" header. Thus every entry can be linked onto an - * apprpriate free list. + * appropriate free list. * * NB. The macro "allocsize" below assumes that "struct strhdr" * has a size that is a power of two. @@ -439,7 +447,7 @@ freename(name) char *name; { struct strhdr *tp, *np; - + tp = &strtblhdr[strlen(name) / STRTBLINCR]; np = (struct strhdr *)name; np->next = tp->next; @@ -450,13 +458,13 @@ freename(name) * Useful quantities placed at the end of a dumped symbol table. */ struct symtableheader { - long volno; - long stringsize; - long entrytblsize; + int32_t volno; + int32_t stringsize; + int32_t entrytblsize; time_t dumptime; time_t dumpdate; ino_t maxino; - long ntrec; + int32_t ntrec; }; /* @@ -484,10 +492,10 @@ dumpsymtable(filename, checkpt) } clearerr(fd); /* - * Assign indicies to each entry + * Assign indices to each entry * Write out the string entries */ - for (i = WINO; i < maxino; i++) { + for (i = WINO; i <= maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { ep->e_index = mynum++; (void) fwrite(ep->e_name, sizeof(char), @@ -499,7 +507,7 @@ dumpsymtable(filename, checkpt) */ tep = &temp; stroff = 0; - for (i = WINO; i < maxino; i++) { + for (i = WINO; i <= maxino; i++) { for (ep = lookupino(i); ep != NULL; ep = ep->e_links) { memmove(tep, ep, (long)sizeof(struct entry)); tep->e_name = (char *)stroff; diff --git a/restore/tape.c b/restore/tape.c index b00c4bb..4ac6a25 100644 --- a/restore/tape.c +++ b/restore/tape.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -44,12 +45,15 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include #include -#include #include #include @@ -80,7 +84,7 @@ static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95"; static long fssize = MAXBSIZE; static int mt = -1; static int pipein = 0; -static char magtape[BUFSIZ]; +static char *magtape; static int blkcnt; static int numtrec; static char *tapebuf; @@ -121,6 +125,8 @@ static void xtrmap __P((char *, long)); static void xtrmapskip __P((char *, long)); static void xtrskip __P((char *, long)); +static int readmapflag; + /* * Set up an input source */ @@ -163,7 +169,11 @@ setinput(source) pipein++; } setuid(getuid()); /* no longer need or want root privileges */ - (void) strcpy(magtape, source); + magtape = strdup(source); + if (magtape == NULL) { + fprintf(stderr, "Cannot allocate space for magtape buffer\n"); + done(1); + } } void @@ -247,10 +257,12 @@ setup() fprintf(stderr, "cannot stat .: %s\n", strerror(errno)); done(1); } - if (stbuf.st_blksize > 0 && stbuf.st_blksize <= MAXBSIZE) + 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 %d\n", fssize); + fprintf(stderr, "bad block size %ld\n", fssize); done(1); } if (spcl.c_volume != 1) { @@ -258,7 +270,7 @@ setup() done(1); } if (gethead(&spcl) == FAIL) { - dprintf(stdout, "header read failed at %d blocks\n", blksread); + dprintf(stdout, "header read failed at %ld blocks\n", blksread); panic("no header after volume mark!\n"); } findinode(&spcl); @@ -267,7 +279,7 @@ setup() done(1); } maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1; - dprintf(stdout, "maxino = %d\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"); @@ -297,14 +309,14 @@ setup() * Prompt user to load a new dump volume. * "Nextvol" is the next suggested volume to use. * This suggested volume is enforced when doing full - * or incremental restores, but can be overrridden by + * or incremental restores, but can be overridden by * the user when only extracting a subset of the files. */ void getvol(nextvol) long nextvol; { - long newvol, savecnt, wantnext, i; + long newvol=0, savecnt=0, wantnext=0, i; union u_spcl tmpspcl; # define tmpbuf tmpspcl.s_spcl char buf[TP_BSIZE]; @@ -327,7 +339,7 @@ again: if (command == 'R' || command == 'r' || curfile.action != SKIP) { newvol = nextvol; wantnext = 1; - } else { + } else { newvol = 0; wantnext = 0; } @@ -344,7 +356,7 @@ again: strcpy(buf, ": "); for (i = 1; i < 32; i++) if (tapesread & (1 << i)) { - fprintf(stderr, "%s%d", buf, i); + fprintf(stderr, "%s%ld", buf, i); strcpy(buf, ", "); } fprintf(stderr, "\n"); @@ -367,7 +379,7 @@ again: return; } closemt(); - fprintf(stderr, "Mount tape volume %d\n", newvol); + fprintf(stderr, "Mount tape volume %ld\n", newvol); fprintf(stderr, "Enter ``none'' if there are no more tapes\n"); fprintf(stderr, "otherwise enter tape name (default: %s) ", magtape); (void) fflush(stderr); @@ -399,7 +411,7 @@ gethdr: setdumpnum(); FLUSHTAPEBUF(); if (gethead(&tmpbuf) == FAIL) { - dprintf(stdout, "header read failed at %d blocks\n", blksread); + dprintf(stdout, "header read failed at %ld blocks\n", blksread); fprintf(stderr, "tape is not dump tape\n"); volno = 0; goto again; @@ -431,7 +443,7 @@ gethdr: * If coming to this volume at random, skip to the beginning * of the next record. */ - dprintf(stdout, "read %ld recs, tape starts with %ld\n", + dprintf(stdout, "read %ld recs, tape starts with %d\n", tpblksread, tmpbuf.c_firstrec); if (tmpbuf.c_type == TS_TAPE && (tmpbuf.c_flags & DR_NEWHEADER)) { if (!wantnext) { @@ -444,7 +456,7 @@ gethdr: * -1 since we've read the volume header */ i = tpblksread - tmpbuf.c_firstrec - 1; - dprintf(stderr, "Skipping %d duplicate record%s.\n", + dprintf(stderr, "Skipping %ld duplicate record%s.\n", i, i > 1 ? "s" : ""); while (--i >= 0) readtape(buf); @@ -510,7 +522,7 @@ setdumpnum() #ifdef RRESTORE if (host) rmtioctl(MTFSF, dumpnum - 1); - else + else #endif if (ioctl(mt, (int)MTIOCTOP, (char *)&tcom) < 0) fprintf(stderr, "ioctl MTFSF: %s\n", strerror(errno)); @@ -609,22 +621,23 @@ extractfile(name) return (linkit(lnkbuf, name, SYMLINK)); #endif - case IFCHR: - case IFBLK: - vprintf(stdout, "extract special file %s\n", name); + case IFIFO: + vprintf(stdout, "extract fifo %s\n", name); if (Nflag) { skipfile(); return (GOOD); } - if (mknod(name, mode, (int)curfile.dip->di_rdev) < 0) { - fprintf(stderr, "%s: cannot create special file: %s\n", + if (uflag && !Nflag) + (void)unlink(name); + if (mkfifo(name, mode) < 0) { + fprintf(stderr, "%s: cannot create fifo: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } (void) chown(name, curfile.dip->di_uid, curfile.dip->di_gid); (void) chmod(name, mode); -#ifdef __linux__ +#ifdef __linux__ (void) fsetflags(name, flags); #else (void) chflags(name, flags); @@ -633,14 +646,17 @@ extractfile(name) utimes(name, timep); return (GOOD); - case IFIFO: - vprintf(stdout, "extract fifo %s\n", name); + case IFCHR: + case IFBLK: + vprintf(stdout, "extract special file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } - if (mkfifo(name, mode) < 0) { - fprintf(stderr, "%s: cannot create fifo: %s\n", + 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)); skipfile(); return (FAIL); @@ -662,6 +678,8 @@ extractfile(name) skipfile(); return (GOOD); } + if (uflag) + (void)unlink(name); if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) { fprintf(stderr, "%s: cannot create file: %s\n", @@ -735,7 +753,7 @@ getfile(fill, skip) gettingfile++; loop: for (i = 0; i < spcl.c_count; i++) { - if (spcl.c_addr[i]) { + if (readmapflag || spcl.c_addr[i]) { readtape(&buf[curblk++][0]); if (curblk == fssize / TP_BSIZE) { (*fill)((char *)buf, (long)(size > TP_BSIZE ? @@ -756,7 +774,7 @@ loop: } if ((size -= TP_BSIZE) <= 0) { for (i++; i < spcl.c_count; i++) - if (spcl.c_addr[i]) + if (readmapflag || spcl.c_addr[i]) readtape(junk); break; } @@ -765,11 +783,11 @@ loop: if (spcl.c_type == TS_ADDR) goto loop; dprintf(stdout, - "Missing address (header) block for %s at %d blocks\n", + "Missing address (header) block for %s at %ld blocks\n", curfile.name, blksread); } if (curblk > 0) { - (*fill)((char *)buf, (curblk * TP_BSIZE) + size); + (*fill)((char *)buf, (long)((curblk * TP_BSIZE) + size)); last_write_was_hole = 0; } if (last_write_was_hole) { @@ -792,7 +810,7 @@ xtrfile(buf, size) return; if (write(ofile, buf, (int) size) == -1) { fprintf(stderr, - "write error extracting inode %d, name %s\nwrite: %s\n", + "write error extracting inode %ld, name %s\nwrite: %s\n", curfile.ino, curfile.name, strerror(errno)); done(1); } @@ -810,7 +828,7 @@ xtrskip(buf, size) if (lseek(ofile, size, SEEK_CUR) == -1) { fprintf(stderr, - "seek error extracting inode %d, name %s\nlseek: %s\n", + "seek error extracting inode %ld, name %s\nlseek: %s\n", curfile.ino, curfile.name, strerror(errno)); done(1); } @@ -897,7 +915,6 @@ do_cmpfiles(int fd_tape, int fd_disk, long size) #endif static char buf_tape[BUFSIZ]; static char buf_disk[BUFSIZ]; - int left = size; int n_tape; int n_disk; @@ -941,7 +958,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 %d to %d.\n", + "%s: size changed from %ld to %ld.\n", diskfile, sbuf_tape.st_size, sbuf_disk->st_size); #ifdef COMPARE_FAIL_KEEP_FILE return (0); @@ -1015,9 +1032,10 @@ comparefile(name) } curfile.name = name; + curfile.action = USING; mode = curfile.dip->di_mode; - vprintf(stdout, "comparing %s (size: %d, mode: 0%o)\n", name, + vprintf(stdout, "comparing %s (size: %ld, mode: 0%o)\n", name, sb.st_size, mode); if (sb.st_mode != mode) { @@ -1084,8 +1102,8 @@ comparefile(name) name, ((int)curfile.dip->di_rdev >> 8) & 0xf, (int)curfile.dip->di_rdev & 0xf, - (sb.st_rdev >> 8) & 0xf, - sb.st_rdev & 0xf); + ((int)sb.st_rdev >> 8) & 0xf, + (int)sb.st_rdev & 0xf); } skipfile(); return; @@ -1174,7 +1192,7 @@ getmore: */ if (i % TP_BSIZE != 0) vprintf(stdout, - "partial block read: %d should be %d\n", + "partial block read: %ld should be %ld\n", i, ntrec * TP_BSIZE); numtrec = i / TP_BSIZE; } @@ -1195,7 +1213,7 @@ getmore: fprintf(stderr, "restoring %s\n", curfile.name); break; case SKIP: - fprintf(stderr, "skipping over inode %d\n", + fprintf(stderr, "skipping over inode %ld\n", curfile.ino); break; } @@ -1261,13 +1279,13 @@ findtapeblksize() done(1); } if (i % TP_BSIZE != 0) { - fprintf(stderr, "Tape block size (%d) %s (%d)\n", + fprintf(stderr, "Tape block size (%ld) %s (%d)\n", i, "is not a multiple of dump block size", TP_BSIZE); done(1); } ntrec = i / TP_BSIZE; numtrec = ntrec; - vprintf(stdout, "Tape block size is %d\n", ntrec); + vprintf(stdout, "Tape block size is %ld\n", ntrec); } void @@ -1297,32 +1315,32 @@ gethead(buf) long i; union { quad_t qval; - long val[2]; + int32_t val[2]; } qcvt; union u_ospcl { char dummy[TP_BSIZE]; struct s_ospcl { - long c_type; - long c_date; - long c_ddate; - long c_volume; - long c_tapea; + int32_t c_type; + int32_t c_date; + int32_t c_ddate; + int32_t c_volume; + int32_t c_tapea; u_short c_inumber; - long c_magic; - long c_checksum; + 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; - long odi_size; - long odi_rdev; + int32_t odi_size; + int32_t odi_rdev; char odi_addr[36]; - long odi_atime; - long odi_mtime; - long odi_ctime; + int32_t odi_atime; + int32_t odi_mtime; + int32_t odi_ctime; } c_dinode; - long c_count; + int32_t c_count; char c_addr[256]; } s_ospcl; } u_ospcl; @@ -1339,12 +1357,15 @@ gethead(buf) } if (checksum((int *)buf) == FAIL) return (FAIL); - if (Bcvt) + 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); + } goto good; } readtape((char *)(&u_ospcl.s_ospcl)); - memset((char *)buf, 0, (long)TP_BSIZE); + memset(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; @@ -1391,6 +1412,7 @@ good: qcvt.val[0] = i; buf->c_dinode.di_size = qcvt.qval; } + readmapflag = 0; switch (buf->c_type) { @@ -1401,8 +1423,11 @@ good: */ buf->c_inumber = 0; buf->c_dinode.di_size = buf->c_count * TP_BSIZE; - for (i = 0; i < buf->c_count; i++) - buf->c_addr[i]++; + if (buf->c_count > TP_NINDIR) + readmapflag = 1; + else + for (i = 0; i < buf->c_count; i++) + buf->c_addr[i]++; break; case TS_TAPE: @@ -1422,7 +1447,7 @@ good: break; } /* - * If we are restoring a filesystem with old format inodes, + * If we are restoring a filesystem with old format inodes, * copy the uid/gid to the new location. */ if (oldinofmt) { @@ -1466,24 +1491,24 @@ accthdr(header) fprintf(stderr, "Used inodes map header"); break; case TS_INODE: - fprintf(stderr, "File header, ino %d", previno); + fprintf(stderr, "File header, ino %ld", previno); break; case TS_ADDR: - fprintf(stderr, "File continuation header, ino %d", previno); + fprintf(stderr, "File continuation header, ino %ld", previno); break; case TS_END: fprintf(stderr, "End of tape header"); break; } if (predict != blksread - 1) - fprintf(stderr, "; predicted %d blocks, got %d blocks", + fprintf(stderr, "; predicted %ld blocks, got %ld blocks", predict, blksread - 1); fprintf(stderr, "\n"); newcalc: blks = 0; if (header->c_type != TS_END) for (i = 0; i < header->c_count; i++) - if (header->c_addr[i] != 0) + if (readmapflag || header->c_addr[i] != 0) blks++; predict = blks; blksread = 0; @@ -1556,7 +1581,8 @@ findinode(header) } } while (header->c_type == TS_ADDR); if (skipcnt > 0) - fprintf(stderr, "resync restore, skipped %d blocks\n", skipcnt); + fprintf(stderr, "resync restore, skipped %ld blocks\n", + skipcnt); skipcnt = 0; } @@ -1575,13 +1601,13 @@ checksum(buf) } else { /* What happens if we want to read restore tapes for a 16bit int machine??? */ - do + do i += swabl(*buf++); while (--j); } - + if (i != CHECKSUM) { - fprintf(stderr, "Checksum error %o, inode %d file %s\n", i, + fprintf(stderr, "Checksum error %o, inode %ld file %s\n", i, curfile.ino, curfile.name); return(FAIL); } @@ -1656,7 +1682,7 @@ swabst(cp, sp) case '5': case '6': case '7': case '8': case '9': n = (n * 10) + (*cp++ - '0'); continue; - + case 's': case 'w': case 'h': if (n == 0) n = 1; diff --git a/restore/utilities.c b/restore/utilities.c index 54b7dc1..c93c854 100644 --- a/restore/utilities.c +++ b/restore/utilities.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,7 +40,11 @@ */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ #include @@ -56,7 +61,6 @@ static char sccsid[] = "@(#)utilities.c 8.5 (Berkeley) 4/28/95"; #include #include -#include #include #include @@ -78,7 +82,7 @@ pathcheck(name) struct entry *ep; char *start; - start = strrchr(name, '/'); + start = strchr(name, '/'); if (start == 0) return; for (cp = start; *cp != '\0'; cp++) { @@ -131,7 +135,7 @@ gentempname(ep) i++; if (np == NULL) badentry(ep, "not on ino list"); - (void) sprintf(name, "%s%d%d", TMPHDR, i, ep->e_ino); + (void) sprintf(name, "%s%ld%lu", TMPHDR, i, (u_long)ep->e_ino); return (name); } @@ -163,7 +167,8 @@ newnode(np) badentry(np, "newnode: not a node"); cp = myname(np); if (command == 'C') return; - if (!Nflag && mkdir(cp, 0777) < 0) { + + if (!Nflag && mkdir(cp, 0777) < 0 && !uflag) { np->e_flags |= EXISTED; fprintf(stderr, "warning: %s: %s\n", cp, strerror(errno)); return; @@ -226,6 +231,10 @@ linkit(existing, new, type) int type; { + /* if we want to unlink first, do it now so *link() won't fail */ + if (uflag && !Nflag) + (void)unlink(new); + if (type == SYMLINK) { if (!Nflag && symlink(existing, new) < 0) { fprintf(stderr, @@ -234,11 +243,29 @@ linkit(existing, new, type) return (FAIL); } } else if (type == HARDLINK) { - if (!Nflag && link(existing, new) < 0) { - fprintf(stderr, - "warning: cannot create hard link %s->%s: %s\n", - new, existing, strerror(errno)); - return (FAIL); + int ret; + + if (!Nflag && (ret = link(existing, new)) < 0) { + +#ifndef __linux__ + struct stat s; + + /* + * Most likely, the schg flag is set. Clear the + * flags and try again. + */ + if (stat(existing, &s) == 0 && s.st_flags != 0 && + chflags(existing, 0) == 0) { + ret = link(existing, new); + chflags(existing, s.st_flags); + } +#endif + if (ret < 0) { + fprintf(stderr, "warning: cannot create " + "hard link %s->%s: %s\n", + new, existing, strerror(errno)); + return (FAIL); + } } } else { panic("linkit: unknown type %d\n", type); @@ -251,7 +278,7 @@ linkit(existing, new, type) #ifndef __linux__ /* - * Create a whiteout + * Create a whiteout. */ int addwhiteout(name) @@ -351,7 +378,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: %ld\n", ep->e_ino); + fprintf(stderr, "inode number: %lu\n", (u_long)ep->e_ino); panic("flags: %s\n", flagvalues(ep)); } @@ -390,7 +417,7 @@ dirlookup(name) { struct direct *dp; ino_t ino; - + ino = ((dp = pathsearch(name)) == NULL) ? 0 : dp->d_ino; if (ino == 0 || TSTINO(ino, dumpmap) == 0) diff --git a/rmt/rmt.8 b/rmt/rmt.8 index 7bee3db..8f9d0df 100644 --- a/rmt/rmt.8 +++ b/rmt/rmt.8 @@ -29,7 +29,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)rmt.8 8.3 (Berkeley) 12/11/93 +.\" @(#)rmt.8 8.3 (Berkeley) 6/1/94 .\" .Dd June 1, 1994 .Dt RMT 8 @@ -52,7 +52,7 @@ or call. .Pp The -.Nm rmt +.Nm program accepts requests specific to the manipulation of magnetic tapes, performs the commands, then responds with a status indication. All responses are in @@ -152,7 +152,7 @@ If .Ar count exceeds the size of the data buffer (10 kilobytes), it is truncated to the data buffer size. -.Nm rmt +.Nm Rmt then performs the requested .Xr read 2 and responds with @@ -198,7 +198,7 @@ sent (in binary). .Sm on .Pp Any other command causes -.Nm rmt +.Nm to exit. .Sh DIAGNOSTICS All responses are of the form described above. diff --git a/rmt/rmt.c b/rmt/rmt.c index 74116b0..b8cd3f6 100644 --- a/rmt/rmt.c +++ b/rmt/rmt.c @@ -1,7 +1,8 @@ /* * Ported to Linux's Second Extended File System as part of the * dump and restore backup suit - * Remy Card , 1994, 1995, 1996 + * Remy Card , 1994-1997 + * Stelian Pop , 1999 * */ @@ -39,13 +40,17 @@ */ #ifndef lint -static char copyright[] = +static const char copyright[] = "@(#) Copyright (c) 1983, 1993\n\ The Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint +#if 0 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 $"; #endif /* not lint */ /* @@ -111,7 +116,12 @@ top: getstring(device); getstring(mode); DEBUG2("rmtd: O %s %s\n", device, mode); - tape = open(device, atoi(mode)); + /* + * XXX the rmt protocol does not provide a means to + * specify the permission bits; allow rw for everyone, + * as modified by the users umask + */ + tape = open(device, atoi(mode), 0666); if (tape < 0) goto ioerror; goto respond; @@ -188,6 +198,12 @@ top: goto top; } + case 'V': /* version */ + getstring(op); + DEBUG1("rmtd: V %s\n", op); + rval = 2; + goto respond; + default: DEBUG1("rmtd: garbage command %c\n", c); exit(3); @@ -246,6 +262,6 @@ error(num) { DEBUG2("rmtd: E %d (%s)\n", num, strerror(num)); - (void)sprintf(resp, "E%d\n%s\n", num, strerror(num)); + (void)snprintf(resp, sizeof(resp), "E%d\n%s\n", num, strerror(num)); (void)write(1, resp, strlen(resp)); } -- 2.39.2