Skip to content
Browse files

Release 1.10 as of 1991-07-01

  • Loading branch information...
1 parent a3dc3a3 commit 49c6ca70ef6a8a073b5e8b21814648a6ae73a77a @pinard committed Jul 1, 2009
Showing with 4,204 additions and 204 deletions.
  1. +262 −0 ChangeLog
  2. +92 −23 Makefile
  3. +47 −6 README
  4. +54 −0 backup-specs
  5. +37 −18 buffer.c
  6. +35 −8 create.c
  7. +2 −2 extract.c
  8. +16 −2 getdate.y
  9. +13 −13 getopt.c
  10. +1 −1 getopt.h
  11. +1 −1 getopt1.c
  12. +26 −1 gnu.c
  13. +143 −0 level-0
  14. +145 −0 level-1
  15. +2 −2 list.c
  16. +14 −6 port.c
  17. +2,783 −0 regex.c
  18. +257 −0 regex.h
  19. +41 −12 rtape_lib.c
  20. +28 −0 rtape_server.c
  21. +125 −34 tar.c
  22. +18 −3 tar.h
  23. +1 −1 tar.texinfo
  24. +60 −0 testpad.c
  25. +1 −71 version.c
View
262 ChangeLog
@@ -1,3 +1,195 @@
+Mon Jul 1 14:14:06 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * Release of version 1.10; appropriate changes to README.
+
+ * create.c: Removed printf's about sparse files.
+
+ * Fix a misplaced quote in level-0 and change some >& into
+ 2>&1.
+
+Fri Jun 21 23:04:31 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * list.c (skip_extended_headers): Userec was being called in
+ the wrong place.
+
+Thu Jun 20 19:10:35 1991 David J. MacKenzie (djm at geech.gnu.ai.mit.edu)
+
+ * tar.h: Use ANSI prototypes for msg and msg_perror if
+ STDC_MSG is defined, even if BSD42 is also.
+
+ * Makefile: Replace DESTDIR with bindir.
+ (install): Don't install tar.texinfo. There's no standard
+ place for texinfo files, and /usr/local/man is inappropriate.
+ Add TAGS, distclean, and realclean targets and SHELL= line.
+
+ * version.c: Move old change history to bottom of ChangeLog.
+
+Wed Jun 12 12:43:58 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * rtape_lib.c (__rmt_write): #ifdef should reference
+ SIGNAL_VOID, not USG.
+
+Wed Jun 5 14:57:11 1991 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
+
+ * tar.c (name_match, addname): Ugly hack to handle -C without
+ any files specified.
+ tar.h (struct name): New field for ugly hack.
+
+Mon Jun 3 14:46:46 1991 Michael I Bushnell (mib@geech.gnu.ai.mit.edu)
+
+ * testpad.c: New file to determine if we need special padding
+ in struct header in tar.h.
+
+ * tar.h (struct header): include padding if necessary, include
+ testpad.h.
+
+ * Makefile: rules to create testpad.h, etc.
+
+Wed May 22 16:02:35 1991 Michael I Bushnell (mib@churchy.gnu.ai.mit.edu)
+
+ * tar.c (options): -L takes an argument.
+
+ * rtape_lib.c (__rmt_open): add /usr/bin/nsh to the list of
+ remote shell programs.
+
+ * create.c: define MAXPATHLEN if we don't get it from a system
+ header file.
+
+ * create.c (deal_with_sparse): return a real return value if
+ we can't open the file.
+
+ * tar.c (long_options): +newer takes an argument.
+ (describe): fix printing in various trivial ways
+
+Tue May 21 17:15:19 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * tar.c (long_options): +get and +concatentate don't require arguments
+
+Mon May 20 15:55:30 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * create.c (write_eot): Don't try and write an EOF if we are
+ already at one.
+
+ * port.c (strstr): Looking for null string should return zero.
+
+Sun May 19 22:30:10 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * tar.c (options): -l doesn't take an argument
+
+ * Makefile: minor fix for SGI 4D defines from torda@scum.ethz.ch
+
+ * rtape_server.c (main.c): Suggested mod for 386/AIX from
+ Minh Tran-Le. I'm suspicious about this one.
+
+ * create.c (dump_file): Mods from Minh Tran-Le for hidden
+ files on AIX.
+ gnu.c (collect_and_sort_name, get_dir_contents): AIX hidden file mod.
+
+ * tar.c: (name_next): Mod from David Taylor to allow -C inside
+ a file list given to -T.
+
+ * Makefile: Comment describing presence of USE_REXEC.
+
+ * extract.c (extract_archive, case LF_SPARSE): zero check for
+ last element on numbytes needs to look at value after
+ converted from octal.
+
+ * port.c: Don't always demand strstr, check for HAVE_STRSTR
+ instead.
+ Makefile: Comment describing presence of HAVE_STRSTR option.
+
+Sun May 19 18:39:48 1991 David J. MacKenzie (djm at churchy.gnu.ai.mit.edu)
+
+ * port.c (get_date): Renamed from getdate, to avoid SVR4 conflict.
+ * tar.c: Call get_date instead of getdate.
+
+Fri May 10 02:58:17 1991 Noah Friedman (friedman at nutrimat)
+
+ * tar.c: added "\n\" to the end of some documentation strings
+ where they were left off.
+
+Thu May 9 17:28:54 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * Makefile: added level-0, level-1, and backup-specs to AUX.
+ * version.c: changed to 1.10 beta.
+ * README: updated for 1.10 beta release.
+
+Tue Apr 2 12:04:54 1991 Michael I Bushnell (mib at godwin)
+
+ * create.c (dump_file): HPUX's st_blocks is in 1024 byte units
+ instead of 512 like the rest of the world, so I special cased
+ it.
+ * tar.c: Undo Noah's changes.
+
+Mon Apr 1 17:49:28 1991 Noah Friedman (friedman at wookumz.gnu.ai.mit.edu)
+
+ (This ought to be temporary until things are fixed properly. )
+
+ * tar.c: (struct option long_options): flag for "sparse" zero if
+ compiling under hpux.
+ tar.c: (functon options): case 'S' is a no-op if compiling under
+ hpux.
+
+Sat Mar 30 12:20:41 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * tar.h: new variable tape_length.
+
+ * tar.c (options): add new option +tape-length / -L.
+
+ * buffer.c (fl_write): Turn #ifdef TEST code for limited tape
+ length on always, for tape-length option.
+
+ * create.c (dump_file): avoid apollo lossage where S_IFIFO == S_IFSOCK.
+
+ * buffer.c: include regex.h
+ * buffer.c (fl_read, open_archive): Use regex routines for
+ volume header match.
+ * xmalloc.c: removed file; wasn't necessary.
+ * tar.c: (main) use ck_malloc instead of xmalloc.
+
+Thu Mar 28 04:05:05 1991 Noah Friedman (friedman at goldman)
+
+ * regex.c, regex.o: New links.
+ * tar.c: include regex.h.
+ * Makefile (OBJ2): Add regex.o.
+ (regex.o, tar.o): Depend on regex.h
+ (SRC2, AUX): Add the new files.
+
+Sat Mar 23 15:39:42 1991 Noah Friedman (friedman at wookumz.gnu.ai.mit.edu)
+
+ * Makefile: added default flags and options for compiling under
+ hpux.
+
+ * Added files alloca.c and xmalloc.c
+
+Sat Mar 23 14:35:31 1991 Michael I Bushnell (mib at geech.gnu.ai.mit.edu)
+
+ * port.c: Define WANT_VALLOC in HPUX.
+
+Fri Mar 15 06:20:15 1991 David J. MacKenzie (djm at geech.ai.mit.edu)
+
+ * rtape_lib.c: If USG and not HAVE_MTIO, define NO_RMTIOCTL
+ automatically.
+ (_rmt_rexec): Temporarily re-open stdin and stdout to
+ /dev/tty, to guarantee that rexec() can prompt and read the
+ login name and password from the user.
+ From pascal@cnam.cnam.fr (Pascal Meheut).
+ * Makefile: Mention -DUSE_REXEC.
+
+Fri Mar 8 20:15:11 1991 Michael I Bushnell (mib at wookumz.ai.mit.edu)
+
+ * tar.h, Makefile: Makefile CPP macro HAVE_SIZE_T might be
+ useful for some people.
+
+ * gnu.c: lstat->stat define where appropriate
+
+ * buffer.c (fl_write): keep track of amount written for +totals.
+ * tar.c, tar.h: set flag f_totals from +totals option
+ * tar.h (f_totals, tot_written): new variables
+ * tar.c (main): print total written with CMD_CREATE
+
+ * tar.c (main): return appropriate exit status
+
Thu Jan 17 00:50:21 1991 David J. MacKenzie (djm at apple-gunkies)
* port.c: Remove a spurious `+' between functions (a remnant
@@ -121,6 +313,8 @@ Thu Oct 25 16:03:58 EDT 1990 Jay Fenlason (hack@ai.mit.edu)
Tue Oct 16 11:04:52 EDT 1990 Jay Fenlason (hack@ai.mit.edu)
+ 1.09 New -G file implementation of gnu-dump stuff.
+
* tar.c (name_add) Get the calls to ck_realloc and ck_malloc right.
Thu Oct 11 11:23:38 EDT 1990 Jay Fenlason (hack@ai.mit.edu)
@@ -369,6 +563,8 @@ Mon Feb 5 14:29:21 EST 1990 Jay Fenlason (hack@wookumz)
Fri Jan 26 16:11:20 EST 1990 Jay Fenlason (hack@wookumz)
+ 1.08 Sparse file support added. Also various other features.
+
* diffarch.c (compare_chunk) Include correct arguments in
a call to fprintf() for an error msg.
(compare_chunks, compare_dir) First argument is a long, not an int.
@@ -628,6 +824,72 @@ Thu Aug 24 10:09:38 EDT 1989 Joy Kendall (jak at spiff)
* tar.c: added long-named options to make tar compatible with
getopt_long, changed Makefile.
+
+... ... .. ..:..:.. ... .... Jay Fenlason (hack@ai.mit.edu)
+
+ 1.07 New version to go on beta tape with GCC 1.35
+ Better USG support. Also support for __builtin_alloca
+ if we're compiling with GCC.
+ diffarch.c: Include the correct header files so MTIOCTOP
+ is defined.
+ tar.c: Don't print the verbose list of options unless
+ given -help. The list of options is *way* too long.
+
+ 1.06 Use STDC_MSG if __STDC__ defined
+ ENXIO meand end-of-volume in archive (for the UNIX PC)
+ Added break after volume-header case (line 440) extract.c
+ Added patch from arnold@unix.cc.emory.edu to rtape_lib.c
+ Added f_absolute_paths option.
+ Deleted refereces to UN*X manual sections (dump(8), etc)
+ Fixed to not core-dump on illegal options
+ Modified msg_perror to call perror("") instead of perror(0)
+ patch so -X - works
+ Fixed tar.c so 'tar cf - -C dir' doesn't core-dump
+ tar.c (name_match): Fixed to chdir() to the appropriate
+ directory if the matching name's change_dir is set. This
+ makes tar xv -C foo {files} work.
+
+ 1.05 A fix to make confirm() work when the archive is on stdin
+ include 'extern FILE *msg_file;' in pr_mkdir(), and fix
+ tar.h to work with __STDC__
+
+ Added to port.c: mkdir() ftruncate() Removed: lstat()
+ Fixed -G to work with -X
+ Another fix to tar.texinfo
+ Changed tar.c to say argv[0]":you must specify exactly ...
+ buffer.c: modified child_open() to keep tar from hanging when
+ it is done reading/writing a compressed archive
+ added fflush(msg_file) before printing error messages
+ create.c: fixed to make link_names non-absolute
+
+ 1.04 Added functions msg() and msg_perror() Modified all the
+ files to call them. Also checked that all (I hope)
+ calls to msg_perror() have a valid errno value
+ (modified anno() to leave errno alone), etc
+ Re-fixed the -X option. This time for sure. . .
+ re-modified the msg stuff. flushed anno() completely
+ Modified the directory stuff so it should work on sysV boxes
+ added ftime() to getdate.y
+ Fixed un_quote_string() so it won't wedge on \" Also fixed
+ \ddd (like \123, etc)
+ More fixes to tar.texinfo
+
+ 1.03 Fixed buffer.c so 'tar tzf NON_EXISTENT_FILE' returns an error
+ message instead of hanging forever
+ More fixes to tar.texinfo
+
+ 1.02 Fixed tar.c so 'tar -h' and 'tar -v' don't cause core dump
+ Also fixed the 'usage' message to be more up-to-date.
+ Fixed diffarch.c so verify should compile without MTIOCTOP
+ defined
+
+ 1.01 Fixed typoes in tar.texinfo
+ Fixed a bug in the #define for rmtcreat()
+ Fixed the -X option to not call realloc() of 0.
+
+ Version 1.00: version.c added. -version option added
+ Installed new version of the remote-tape library
+ Added -help option
Local Variables:
mode: indented-text
View
115 Makefile
@@ -1,7 +1,12 @@
# Makefile for GNU tar program.
-#
+
+SHELL = /bin/sh
+
# In order to disable remote-tape support, add -DNO_REMOTE to the
# appropriate DEFS line, and remove rtape_lib.* from LOCAL_{SRC,OBJ}
+# For Ultrix 3.1, you will have to compile rtape_lib.c with -DUSG.
+# Add -DUSE_REXEC to use rexec for remote tape operations
+# instead of forking rsh or remsh.
#
# If tar fails to properly print error msgs, or core-dumps doing same,
# you may need to change which version of msg...() you are using.
@@ -14,11 +19,20 @@
# Some non-BSD systems may have to add -DNEED_TZSET in order to have getdate.y
# compile correctly.
#
+# If you have a system V system which defines size_t, add -DHAVE_SIZE_T.
+# If you have a system which defines strstr, add -DHAVE_STRSTR.
+#
+# If you can't use remote tar with the rmt library, you can still get
+# some stuff to work right by adding -DUSE_REXEC.
+#
+# Some people's systems define a prototype for signal handlers which
+# require them to be declared as void. If you get such problems in
+# rtape_lib, function command, then define -DSIGNAL_VOID.
+#
# getdate.y has 8 shift/reduce conflicts.
#
# In addition to setting DEFS appropriately for your system, you might
-# have to hand edit the #defines and #undefs in port.c and rtape_lib.c.
-# For Ultrix 3.1, you will have to compile rtape_lib.c with -DUSG
+# have to hand edit the #defines and #undefs in port.c.
#
## GNU version
@@ -33,8 +47,8 @@
#DEFBLOCKING = 20
#O = o
-# Berserkeley version
-#CC=ngcc
+## Berserkeley version
+CC=gcc
DEFS = -DBSD42
LOCAL_SRC = getdate.y rtape_lib.c
LOCAL_OBJ = getdate.$O rtape_lib.$O
@@ -46,6 +60,46 @@ DEF_AR_FILE = \"/dev/rmt8\"
DEFBLOCKING = 20
O = o
+## Ultrix
+#CC=gcc
+#DEFS = -DBSD42 -DSIGNAL_VOID
+#LOCAL_SRC = getdate.y rtape_lib.c
+#LOCAL_OBJ = getdate.$O rtape_lib.$O
+#LDFLAGS =
+#LIBS =
+#LINT = lint
+#LINTFLAGS = -abchx
+#DEF_AR_FILE = \"/dev/rmt8\"
+#DEFBLOCKING = 20
+#O = o
+
+# HPUX 7.0 version
+#DEFS = -DBSD42 -Dhpux -DVARARGS_MSG
+#LOCAL_SRC = getdate.y rtape_lib.c
+#LOCAL_OBJ = getdate.$O rtape_lib.$O alloca.$O
+#LDFLAGS =
+#LIBS = -lBSD
+#LINT = lint
+#LINTFLAGS = -abchx
+#DEF_AR_FILE = \"/dev/rct/c3d0s2\"
+#DEFBLOCKING = 20
+#O = o
+
+# IBM AIX version -- this saves "hidden" directories, but doesn't restore
+# them as hidden. Add -Di386 for a PS/2. If you don't have GCC, turn it off.
+# Some people think you need -lbsd, some don't. Dunno.
+#CC=gcc
+#DEFS= -DUSG -Daix -DSTDC_MSG -DHAVE_MTIO -DHAVE_SIZE_T -DSIGNAL_VOID
+#LOCAL_SRC = getdate.y rtape_lib.c
+#LOCAL_OBJ = getdate.$O rtape_lib.$O
+#LDFLAGS =
+#LIBS = -lbsd
+#LINT = lint
+#LINTFLAGS = -p
+#DEF_AR_FILE = \"/dev/rmt0\"
+#DEFBLOCKING = 20
+#O = o
+
# USG version
# Add -DNDIR to DEFS if your system uses ndir.h instead of dirent.h
# Add -DDIRECT to DEFS if your system uses 'struct direct' instead of
@@ -56,7 +110,7 @@ O = o
# external variable `daylight'.
# Add -lndir to LIBS if your ndir routines aren't in libc.a
# Add -lPW to LIBS if you don't compile with gcc (to get alloca)
-#DEFS = -DUSG #-DNDIR -DDIRECT -DHAVE_MTIO
+#DEFS = -DUSG -DSIGNAL_VOID #-DNDIR -DDIRECT -DHAVE_MTIO
#LOCAL_SRC = getdate.y rtape_lib.c
#LOCAL_OBJ = getdate.$O rtape_lib.$O
#LDFLAGS =
@@ -68,7 +122,7 @@ O = o
#O = o
# UniSoft's Uniplus SVR2 with NFS
-#DEFS = -DUSG -DUNIPLUS -DNFS -DSVR2
+#DEFS = -DUSG -DUNIPLUS -DNFS -DSVR2 -DSIGNAL_VOID
#LOCAL_SRC = getdate.y rtape_lib.c
#LOCAL_OBJ = getdate.$O rtape_lib.$O
#LDFLAGS =
@@ -137,11 +191,11 @@ O = o
#LDFLAGS =
#LIBS =
#DEF_AR_FILE = \"-\"
-#DEFBLOCKING = 8 /* No good reason for this, change at will */
+#DEFBLOCKING = 8 # No good reason for this, change at will
#O = s
# Xenix version
-#DEFS = -DUSG -DXENIX
+#DEFS = -DUSG -DXENIX -DSIGNAL_VOID
#LOCAL_SRC = getdate.y rtape_lib.c
#LOCAL_OBJ = getdate.$O rtape_lib.$O
#LDFLAGS =
@@ -153,11 +207,12 @@ O = o
#O = o
# SGI 4D version
+# You will need to define NEED_TZSET in getdate.y
#DEFS = -DUSG -I/usr/include/bsd
#LOCAL_SRC = getdate.y rtape_lib.c
#LOCAL_OBJ = getdate.$O rtape_lib.$O
#LDFLAGS =
-#LIBS =
+#LIBS = -lxmalloc
#LINT = lint
#LINTFLAGS = -p
#DEF_AR_FILE = \"/dev/tape\"
@@ -182,30 +237,37 @@ SUBSRC=
SUBOBJ=
# Destination directory and installation program for make install
-DESTDIR = /usr/local
+bindir = /usr/local/gnubin
INSTALL = cp
RM = rm -f
SRC1 = tar.c create.c extract.c buffer.c getoldopt.c update.c gnu.c mangle.c
-SRC2 = version.c list.c names.c diffarch.c port.c wildmat.c getopt.c getopt1.c
+SRC2 = version.c list.c names.c diffarch.c port.c wildmat.c getopt.c getopt1.c regex.c
SRC3 = $(LOCAL_SRC) $(SUBSRC)
SRCS = $(SRC1) $(SRC2) $(SRC3)
OBJ1 = tar.$O create.$O extract.$O buffer.$O getoldopt.$O list.$O update.$O
-OBJ2 = version.$O names.$O diffarch.$O port.$O wildmat.$O getopt.$O getopt1.$O
+OBJ2 = version.$O names.$O diffarch.$O port.$O wildmat.$O getopt.$O getopt1.$O regex.$O
OBJ3 = gnu.$O mangle.$O $(LOCAL_OBJ) $(SUBOBJ)
OBJS = $(OBJ1) $(OBJ2) $(OBJ3)
# AUX = README PORTING Makefile TODO tar.h port.h open3.h \
# msd_dir.h msd_dir.c
AUX = README COPYING ChangeLog Makefile tar.texinfo tar.h port.h open3.h \
- rmt.h msd_dir.h msd_dir.c rtape_server.c rtape_lib.c getdate.y getopt.h
+ rmt.h msd_dir.h msd_dir.c rtape_server.c rtape_lib.c getdate.y \
+ getopt.h regex.h level-0 level-1 backup-specs testpad.c
all: tar rmt
tar: $(OBJS)
$(CC) $(LDFLAGS) -o tar $(COPTS) $(OBJS) $(LIBS)
rmt: rtape_server.c
- $(CC) $(CFLAGS) -o rmt rtape_server.c
+ $(CC) $(CFLAGS) $(LDFLAGS) -o rmt rtape_server.c
+
+testpad.h: testpad
+ testpad > testpad.h
+
+testpad: testpad.o
+ $(CC) -o testpad testpad.o
# command is too long for Messy-Dos (128 char line length limit) so
# this kludge is used...
@@ -215,27 +277,33 @@ rmt: rtape_server.c
# @$(RM) command
install: all
- $(RM) $(DESTDIR)/bin/tar
- $(INSTALL) tar $(DESTDIR)/bin/tar
- $(INSTALL) tar.texinfo $(DESTDIR)/man/tar.texinfo
+ $(RM) $(bindir)/tar
+ $(INSTALL) tar $(bindir)/tar
$(INSTALL) rmt /etc/rmt
lint: $(SRCS)
$(LINT) $(LINTFLAGS) $(ALLDEFS) $(SRCS)
+TAGS: $(SRCS)
+ etags $(SRCS)
+
clean:
- $(RM) errs $(OBJS) tar rmt
+ $(RM) errs $(OBJS) tar rmt testpad.o testpad testpad.h
+
+distclean: clean
+
+realclean: clean
shar: $(SRCS) $(AUX)
shar $(SRCS) $(AUX) | compress > tar-`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q version.c`.shar.Z
dist: $(SRC1) $(SRC2) $(AUX)
echo tar-`sed -e '/version_string/!d' -e 's/[^0-9.]*\([0-9.]*\).*/\1/' -e q < version.c` > .fname
+ -rm -rf `cat .fname`
mkdir `cat .fname`
-
ln $(SRC1) $(SRC2) $(AUX) `cat .fname`
- tar cvhZf `cat .fname`.tar.Z `cat .fname`
- -rm -r `cat .fname` .fname
+ tar chZf `cat .fname`.tar.Z `cat .fname`
+ -rm -rf `cat .fname` .fname
tar.zoo: $(SRCS) $(AUX)
-mkdir tmp.dir
@@ -244,4 +312,5 @@ tar.zoo: $(SRCS) $(AUX)
/' $$X > tmp.dir/$$X ; done
cd tmp.dir ; zoo aM ../tar.zoo *
-rmdir tmp.dir
-
+
+$(OBJS): tar.h port.h testpad.h
View
53 README
@@ -1,9 +1,50 @@
-This is GNU tar. It is based heavily on John Gilmore's public domain tar,
-but with added features. See tar.texinfo for details.
+This GNU tar 1.10. Please send bug reports, etc., to
+bug-gnu-utils@prep.ai.mit.edu.
-In order to correctly handle renamed directories, the Incremental option has
-been extensively re-designed.
+This is GNU tar. It is based heavily on John Gilmore's public domain
+tar, but with added features. The manual is currently being written.
+An old manual, surely riddled with errors, is in tar.texinfo. Please
+don't send in bug reports about that manual. In particular, the
+mechanism for doing incremental dumps has been significantly changed.
+
+The mt program is in the GNU cpio distribution.
+
+Various people have been having problems using floppies on a NeXT.
+I've gotten conflicting reports about what should be done to solve the
+problems, and we have no way to test it ourselves. If you don't have
+"rename" in your C library, you will need to find an implementation.
+I'm not sure if I want to roll in the GNU implementation into tar.
+
+ -mib
+
+User-visible changes since 1.09:
+
+Filename to -G is optional. -C works right.
+Names +newer and +newer-mtime work right.
+
+-g is now +incremental
+-G is now +listed-incremental
+
+Sparse files now work correctly.
+
++volume is now called +label.
+
++exclude now takes a filename argument, and +exclude-from does what
++exclude used to do.
+
+Exit status is now correct.
+
++totals keeps track of total I/O and prints it when tar exits.
+
+When using +label with +extract, the label is now a regexp.
+
+New option +tape-length (-L) does multi-volume handling like BSD dump:
+you tell tar how big the tape is and it will prompt at that point
+instead of waiting for a write error.
+
+New backup scripts level-0 and level-1 which might be useful to
+people. They use a file "backup-specs" for information, and shouldn't
+need local modification. These are what we use to do all our backups
+at the FSF.
-Please send bug reports, etc to hack@ai.mit.edu.
- hack
View
54 backup-specs
@@ -0,0 +1,54 @@
+# site-specific parameters for file system backup.
+
+# User name of administrator of backups.
+ADMINISTRATOR=friedman
+
+# Hour at which backups are normally done.
+# This should be a number from 0 to 23.
+BACKUP_HOUR=1
+
+# Device to use for dumping. It should be on the host
+# on which the dump scripts are run.
+TAPE_FILE=/dev/nrsmt0
+
+# Command to obtain status of tape drive, including error count.
+# On some tape drives there may not be such a command;
+# then simply use `TAPE_STATUS=false'.
+TAPE_STATUS="mts -t $TAPE_FILE"
+
+# Blocking factor to use for writing the dump.
+BLOCKING=124
+
+# List of file systems to be dumped.
+# Actually, any directory may be used,
+# but if it has subdirectories on other file systems,
+# they are not included.
+
+# The host name specifies which host to run tar on.
+# It should normally be the host that actually has the file system.
+# If GNU tar is not installed on that machine,
+# then you can specify some other host which can access
+# the file system through NFS.
+# Although these are arranged one per line, that is not mandatory.
+# It does not work to use # for comments within the string.
+BACKUP_DIRS="
+ albert:/fs/fsf
+ apple-gunkies:/gd
+ albert:/fs/gd2
+ godwin:/fs/gp
+ geech:/usr/jla
+ churchy:/usr/roland
+ albert:/
+ albert:/usr
+ apple-gunkies:/
+ apple-gunkies:/usr
+ ernst:/usr1
+ gnu:/
+ gnu:/usr
+ godwin:/
+ apple-gunkies:/com/mailer/gnu
+ apple-gunkies:/com/archive/gnu"
+
+# List of individual files to be dumped.
+# These should be accesible from the machine on which the dump is run.
+BACKUP_FILES="/com/mailer/aliases /com/mailer/league*[a-z]"
View
55 buffer.c
@@ -53,6 +53,7 @@ extern int errno;
#include "tar.h"
#include "port.h"
#include "rmt.h"
+#include "regex.h"
/* Either stdout or stderr: The thing we write messages (standard msgs, not
errors) to. Stdout unless we're writing a pipe, in which case stderr */
@@ -582,24 +583,34 @@ open_archive(reading)
if(f_volhdr) {
union record *head;
+#if 0
char *ptr;
if(f_multivol) {
ptr=malloc(strlen(f_volhdr)+20);
sprintf(ptr,"%s Volume %d",f_volhdr,1);
} else
ptr=f_volhdr;
+#endif
head=findrec();
if(!head) {
- msg("Archive not labelled %s",ptr);
+ msg("Archive not labelled to match %s",f_volhdr);
exit(EX_BADVOL);
}
+ if (re_match (label_pattern, head->header.name,
+ strlen (head->header.name), 0, 0) < 0) {
+ msg ("Volume mismatch! %s!=%s", f_volhdr,
+ head->header.name);
+ exit (EX_BADVOL);
+ }
+#if 0
if(strcmp(ptr,head->header.name)) {
msg("Volume mismatch! %s!=%s",ptr,head->header.name);
exit(EX_BADVOL);
}
if(ptr!=f_volhdr)
free(ptr);
+#endif
}
} else if(f_volhdr) {
bzero((void *)ar_block,RECORDSIZE);
@@ -650,24 +661,20 @@ fl_write()
{
int err;
int copy_back;
-#ifdef TEST
- static long test_written = 0;
-#endif
+ static long bytes_written = 0;
-#ifdef TEST
- if(test_written>=30720) {
+ if(tape_length && bytes_written >= tape_length * 1024) {
errno = ENOSPC;
err = 0;
} else
-#endif
- err = rmtwrite(archive, ar_block->charptr,(int) blocksize);
+ err = rmtwrite(archive, ar_block->charptr,(int) blocksize);
if(err!=blocksize && !f_multivol)
writeerror(err);
+ else if (f_totals)
+ tot_written += blocksize;
-#ifdef TEST
if(err>0)
- test_written+=err;
-#endif
+ bytes_written+=err;
if (err == blocksize) {
if(f_multivol) {
if(!save_name) {
@@ -697,9 +704,7 @@ fl_write()
if(new_volume(0)<0)
return;
-#ifdef TEST
- test_written=0;
-#endif
+ bytes_written=0;
if(f_volhdr && real_s_name[0]) {
copy_back=2;
ar_block-=2;
@@ -738,10 +743,11 @@ fl_write()
err = rmtwrite(archive, ar_block->charptr,(int) blocksize);
if(err!=blocksize)
writeerror(err);
+ else if (f_totals)
+ tot_written += blocksize;
+
-#ifdef TEST
- test_written = blocksize;
-#endif
+ bytes_written = blocksize;
if(copy_back) {
ar_block+=copy_back;
bcopy((void *)(ar_block+blocking-copy_back),
@@ -897,17 +903,30 @@ fl_read()
if(head->header.linkflag==LF_VOLHDR) {
if(f_volhdr) {
+#if 0
char *ptr;
ptr=(char *)malloc(strlen(f_volhdr)+20);
sprintf(ptr,"%s Volume %d",f_volhdr,volno);
+#endif
+ if (re_match (label_pattern, head->header.name,
+ strlen (head->header.name),
+ 0, 0) < 0) {
+ msg("Volume mismatch! %s!=%s",f_volhdr,
+ head->header.name);
+ --volno;
+ goto try_volume;
+ }
+
+#if 0
if(strcmp(ptr,head->header.name)) {
msg("Volume mismatch! %s!=%s",ptr,head->header.name);
--volno;
free(ptr);
goto try_volume;
}
free(ptr);
+#endif
}
if(f_verbose)
fprintf(msg_file,"Reading %s",head->header.name);
@@ -1206,7 +1225,7 @@ int type;
if (f_run_script_at_end)
system(info_script);
else for(;;) {
- fprintf(msg_file,"Prepare volume #%d and hit return: ",volno);
+ fprintf(msg_file,"\007Prepare volume #%d and hit return: ",volno);
fflush(msg_file);
if(fgets(inbuf,sizeof(inbuf),read_file)==0) {
fprintf(msg_file,"EOF? What does that mean?");
View
43 create.c
@@ -28,7 +28,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <sys/stat.h>
#include <stdio.h>
-
#ifndef V7
#include <fcntl.h>
#endif
@@ -89,6 +88,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#define O_BINARY 0
#endif
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
#include "tar.h"
#include "port.h"
@@ -231,7 +234,13 @@ dump_file (p, curdev)
* symbolic links. Otherwise, use lstat (which, on non-4.2
* systems, is #define'd to stat anyway.
*/
+#ifdef AIX
+ if (0 != f_follow_links ?
+ statx (p, &hstat, STATSIZE, STX_HIDDEN):
+ statx (p, &hstat, STATSIZE, STX_HIDDEN|STX_LINK))
+#else
if (0 != f_follow_links? stat(p, &hstat): lstat(p, &hstat))
+#endif /* AIX */
{
badperror:
msg_perror("can't add file %s",p);
@@ -240,6 +249,17 @@ dump_file (p, curdev)
return;
}
+#ifdef AIX
+ if (S_ISHIDDEN (hstat.st_mode)) {
+ char *new = (char *)allocate (strlen (p) + 2);
+ if (new) {
+ strcpy (new, p);
+ strcat (new, "@");
+ p = new;
+ }
+ }
+#endif /* AIX */
+
/* See if we only want new files, and check if this one is too old to
put in the archive. */
if( f_new_files
@@ -370,11 +390,14 @@ dump_file (p, curdev)
* at least one of those records in the file is just
* a useless hole.
*/
+#ifdef hpux /* Nice of HPUX to gratuitiously change it, huh? - mib */
+ if (hstat.st_size - (hstat.st_blocks * 1024) > 1024 ) {
+#else
if (hstat.st_size - (hstat.st_blocks * RECORDSIZE) > RECORDSIZE) {
+#endif
int filesize = hstat.st_size;
register int i;
- printf("File is sparse: %s\n", p);
header = start_header(p, &hstat);
if (header == NULL)
goto badfile;
@@ -417,8 +440,6 @@ dump_file (p, curdev)
*/
find_new_file_size(&filesize, upperbound);
- printf("File %s is now size %d\n",
- p, filesize);
hstat.st_size = filesize;
to_oct((long) filesize, 1+12,
header->header.size);
@@ -754,12 +775,15 @@ dump_file (p, curdev)
goto easy;
#endif
+/* Avoid screwy apollo lossage where S_IFIFO == S_IFSOCK */
+#if ((_ISP__M68K == 0) && (_ISP__A88K == 0))
#ifdef S_IFIFO
case S_IFIFO: /* Fifo special file */
type = LF_FIFO;
goto easy;
#endif
+#endif
#ifdef S_IFSOCK
case S_IFSOCK: /* Socket pretend its a fifo? */
@@ -933,7 +957,7 @@ deal_with_sparse(name, header, nulls_at_end)
* so just return.
*/
if ((fd = open(name, O_RDONLY)) < 0)
- return;
+ return 0;
init_sparsearray();
clear_buffer(buf);
@@ -1269,7 +1293,10 @@ write_eot()
void bzero();
p = findrec();
- bufsize = endofrecs()->charptr - p->charptr;
- bzero(p->charptr, bufsize);
- userec(p);
+ if (p)
+ {
+ bufsize = endofrecs()->charptr - p->charptr;
+ bzero(p->charptr, bufsize);
+ userec(p);
+ }
}
View
4 extract.c
@@ -198,12 +198,12 @@ extract_archive()
sp_array_size = 10;
sparsearray = (struct sp_array *) malloc(sp_array_size * sizeof(struct sp_array));
for (i = 0; i < SPARSE_IN_HDR; i++) {
- if (!head->header.sp[i].numbytes)
- break;
sparsearray[i].offset =
from_oct(1+12, head->header.sp[i].offset);
sparsearray[i].numbytes =
from_oct(1+12, head->header.sp[i].numbytes);
+ if (!sparsearray[i].numbytes)
+ break;
}
/* end_nulls = from_oct(1+12, head->header.ending_blanks);*/
View
18 getdate.y
@@ -14,6 +14,20 @@
/* SUPPRESS 287 on yaccpar_sccsid *//* Unusd static variable */
/* SUPPRESS 288 on yyerrlab *//* Label unused */
+#ifdef __GNUC__
+#define alloca __builtin_alloca
+#else
+#ifdef sparc
+#include <alloca.h>
+#else
+#ifdef _AIX /* for Bison */
+#pragma alloca
+#else
+char *alloca ();
+#endif
+#endif
+#endif
+
#include <stdio.h>
#include <ctype.h>
@@ -785,7 +799,7 @@ yylex()
time_t
-getdate(p, now)
+get_date(p, now)
char *p;
struct timeb *now;
{
@@ -868,7 +882,7 @@ main(ac, av)
(void)printf("Enter date, or blank line to exit.\n\t> ");
(void)fflush(stdout);
while (gets(buff) && buff[0]) {
- d = getdate(buff, (struct timeb *)NULL);
+ d = get_date(buff, (struct timeb *)NULL);
if (d == -1)
(void)printf("Bad format - couldn't convert.\n");
else
View
26 getopt.c
@@ -3,7 +3,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
+ the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
@@ -44,34 +44,34 @@
#ifdef sparc
#include <alloca.h>
#else
+#ifdef _AIX
+#pragma alloca
+#else
char *alloca ();
+#endif
#endif /* sparc */
#endif /* not __GNUC__ */
#if defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
#include <stdlib.h>
-#include <string.h>
-#define bcopy(s, d, n) memcpy ((d), (s), (n))
-#define index strchr
#else /* STDC_HEADERS or __GNU_LIBRARY__ */
+char *getenv ();
+char *malloc ();
+#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
-#ifdef USG
+#if defined(USG) || defined(STDC_HEADERS) || defined(__GNU_LIBRARY__)
#include <string.h>
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define index strchr
-#else /* USG */
+#else /* USG or STDC_HEADERS or __GNU_LIBRARY__ */
#ifdef VMS
#include <string.h>
-#else
+#else /* VMS */
#include <strings.h>
#endif /* VMS */
/* Declaring bcopy causes errors on systems whose declarations are different.
- If the declaration is omitted, everything works fine. rms. */
-#endif /* USG */
-
-char *getenv ();
-char *malloc ();
-#endif /* STDC_HEADERS or __GNU_LIBRARY__ */
+ If the declaration is omitted, everything works fine. */
+#endif /* USG or STDC_HEADERS or __GNU_LIBRARY__ */
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
View
2 getopt.h
@@ -3,7 +3,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
+ the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
View
2 getopt1.c
@@ -3,7 +3,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 1, or (at your option)
+ the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
View
27 gnu.c
@@ -39,6 +39,13 @@
#define MAXPATHLEN 1024
#endif
+/*
+ * If there are no symbolic links, there is no lstat(). Use stat().
+ */
+#ifndef S_IFLNK
+#define lstat stat
+#endif
+
#ifdef __STDC__
#define VOIDSTAR void *
#else
@@ -229,7 +236,11 @@ collect_and_sort_names()
continue;
}
+#ifdef AIX
+ if (statx (n->name, &statbuf, STATSIZE, STX_HIDDEN|STX_LINK))
+#else
if(lstat(n->name,&statbuf)<0) {
+#endif /* AIX */
msg_perror("can't stat %s",n->name);
continue;
}
@@ -331,13 +342,27 @@ int device;
namebuf=ck_realloc(namebuf,bufsiz+2);
}
(void) strcpy(namebuf+len,d->d_name);
- if (0 != f_follow_links? stat(namebuf, &hs): lstat(namebuf, &hs)) {
+#ifdef AIX
+ if (0 != f_follow_links?
+ statx(namebuf, &hs, STATSIZE, STX_HIDDEN):
+ statx(namebuf, &hs, STATSIZE, STX_HIDDEN|STX_LINK))
+#else
+ if (0 != f_follow_links? stat(namebuf, &hs): lstat(namebuf, &hs))
+#endif
+ {
msg_perror("can't stat %s",namebuf);
continue;
}
if( (f_local_filesys && device!=hs.st_dev)
|| (f_exclude && check_exclude(namebuf)))
add_buffer(the_buffer,"N",1);
+#ifdef AIX
+ else if (S_ISHIDDEN (hs.st_mode)) {
+ add_buffer (the_buffer, "D", 1);
+ strcat (d->d_name, "A");
+ d->d_namlen++;
+ }
+#endif /* AIX */
else if((hs.st_mode&S_IFMT)==S_IFDIR) {
if(dp=get_dir(namebuf)) {
if( dp->dev!=hs.st_dev
View
143 level-0
@@ -0,0 +1,143 @@
+#!/bin/sh
+#
+# Run this script as root on the machine that has the tape drive, to make a
+# full dump.
+#
+# If you give `now' as an argument, the dump is done immediately.
+# Otherwise, it waits until 1am, or until the hour given as argument.
+# Specify the hour as a number from 0 to 23.
+#
+# You must edit the file `backup-specs' to set the parameters for your site.
+
+if [ ! -w / ]; then
+ echo The backup must be run as root,
+ echo or else some files will fail to be dumped.
+ exit 1
+else
+ false
+fi
+
+# This is undesirable -- rms.
+# rsh albert /usr/local/adm/motd-backup-start
+
+# Get the values of BACKUP_DIRS and BACKUP_FILES, and other variables.
+. ./backup-specs
+
+# Maybe sleep until around specified or default hour.
+#
+if [ "$1" != "now" ]; then
+ if [ "$1"x != x ]; then
+ spec=$1
+ else
+ spec=$BACKUP_HOUR
+ fi
+ pausetime=`date | awk '{hr=substr($4,1,2);\\
+ mn=substr($4,4,2);\\
+ if((hr+0)<spec)\\
+ print 3600*(spec-hr)-60*mn;\\
+ else\\
+ print 3600*(spec+(24-hr))-60*mn; }' spec=$spec`
+ clear
+ cat ./dont_touch
+ sleep $pausetime
+fi
+
+# start doing things
+
+here=`pwd`
+LOGFILE=log-`date | awk '{print $2 "-" $3 "-" $6}'`-full
+HOST=`hostname | sed 's/\..*//'`
+TAR_PART1="/usr/local/bin/tar -c +multi-volume +one-file-system +block=$BLOCKING +sparse"
+#TAR_PART1="/usr/local/bin/tar -c +multi-volume +one-file-system +block=$BLOCKING "
+
+# Make sure the log file did not already exist. Create it.
+
+if [ -f $LOGFILE ] ; then
+ echo Log file $LOGFILE already exists.
+ exit 1
+else
+ touch $LOGFILE
+fi
+
+mt -f $TAPE_FILE rewind
+
+set $BACKUP_DIRS
+while [ $# -ne 0 ] ; do
+ host=`echo $1 | sed 's/:.*$//'`
+ fs=`echo $1 | sed 's/^.*://'`
+ date=`date`
+ fsname=`echo $1 | sed 's/\//:/g'`
+
+ TAR_PART2="+listed=/etc/tar-backup/temp.level-0"
+ TAR_PART3="+label='Full backup of $fs on $host at $date' -C $fs ."
+
+ echo Backing up $1 at $date | tee -a $LOGFILE
+
+ # Actually back things up.
+
+ if [ $HOST != $host ] ; then
+ rsh $host "mkdir /etc/tar-backup 2>&1/dev/null; \
+ rm -f /etc/tar-backup/temp.level-0; \
+ $TAR_PART1 -f $HOST:$TAPE_FILE $TAR_PART2 $TAR_PART3" \
+ 2>&1 | tee -a $LOGFILE
+ else
+ mkdir /etc/tar-backup 2>&1/dev/null
+ rm -f /etc/tar-backup/temp.level-0
+# Using `sh -c exec' causes nested quoting and shell substitution
+# to be handled here in the same way rsh handles it.
+ sh -c "exec $TAR_PART1 -f $TAPE_FILE $TAR_PART2 $TAR_PART3" 2>&1 | tee -a $LOGFILE
+ fi
+ if [ $? -ne 0 ] ; then
+ echo Backup of $1 failed. | tee -a $LOGFILE
+ # I'm assuming that the tar will have written an empty
+ # file to the tape, otherwise I should do a cat here.
+ else
+ if [ $HOST != $host ] ; then
+ rsh $host mv -f /etc/tar-backup/temp.level-0 /etc/tar-backup/$fsname.level-0 2>&1 | tee -a $LOGFILE
+ else
+ mv -f /etc/tar-backup/temp.level-0 /etc/tar-backup/$fsname.level-0 2>&1 | tee -a $LOGFILE
+ fi
+ fi
+ $TAPE_STATUS | tee -a $LOGFILE
+ sleep 60
+ shift
+done
+
+# Dump any individual files requested.
+
+if [ x != "x$BACKUP_FILES" ] ; then
+ date=`date`
+
+ TAR_PART2="+listed=/etc/tar-backup/temp.level-0"
+ TAR_PART3="+label='Full backup of miscellaneous files at $date'"
+
+ mkdir /etc/tar-backup 2>&1/dev/null
+ rm -f /etc/tar-backup/temp.level-0
+
+ echo Backing up miscellaneous files at $date | tee -a $LOGFILE
+# Using `sh -c exec' causes nested quoting and shell substitution
+# to be handled here in the same way rsh handles it.
+ sh -c "exec $TAR_PART1 -f $TAPE_FILE $TAR_PART2 $TAR_PART3 \
+ $BACKUP_FILES" 2>&1 | tee -a $LOGFILE
+ if [ $? -ne 0 ] ; then
+ echo Backup of miscellaneous files failed. | tee -a $LOGFILE
+ # I'm assuming that the tar will have written an empty
+ # file to the tape, otherwise I should do a cat here.
+ else
+ mv -f /etc/tar-backup/temp.level-0 /etc/tar-backup/misc.level-0 2>&1 | tee -a $LOGFILE
+ fi
+ $TAPE_STATUS | tee -a $LOGFILE
+else
+ echo No miscellaneous files specified | tee -a $LOGFILE
+ false
+fi
+
+mt -f $TAPE_FILE rewind
+mt -f $TAPE_FILE offl
+
+echo Sending the dump log to $ADMINISTRATOR
+cat $LOGFILE | sed -f logfile.sed > $LOGFILE.tmp
+/usr/ucb/mail -s "Results of backup on `date`" $ADMINISTRATOR < $LOGFILE.tmp
+
+# This is undesirable -- rms.
+#rsh albert /usr/local/adm/motd-backup-done &
View
145 level-1
@@ -0,0 +1,145 @@
+#!/bin/sh
+#
+# Run this script as root on the machine that has the tape drive, to make a
+# level-1 dump containing all files changed since the last full dump.
+#
+# If you give `now' as an argument, the dump is done immediately.
+# Otherwise, it waits until 1am.
+#
+# You must edit the file `backup-specs' to set the parameters for your site.
+
+if [ ! -w / ]; then
+ echo The backup must be run as root,
+ echo or else some files will fail to be dumped.
+ exit 1
+else
+ false
+fi
+
+# Get the values of BACKUP_DIRS and BACKUP_FILES, and other variables.
+. ./backup-specs
+
+# Maybe sleep until around specified or default hour.
+#
+if [ "$1" != "now" ]; then
+ if [ "$1"x != x ]; then
+ spec=$1
+ else
+ spec=$BACKUP_HOUR
+ fi
+ pausetime=`date | awk '{hr=substr($4,1,2);\\
+ mn=substr($4,4,2);\\
+ if((hr+0)<spec)\\
+ print 3600*(spec-hr)-60*mn;\\
+ else\\
+ print 3600*(spec+(24-hr))-60*mn; }' spec=$spec`
+ clear
+ cat ./dont_touch
+ sleep $pausetime
+fi
+
+# start doing things
+
+here=`pwd`
+LOGFILE=log-`date | awk '{print $2 "-" $3 "-" $6}'`-level-1
+HOST=`hostname | sed 's/\..*//'`
+TAR_PART1="/usr/local/bin/tar -c +multi-volume +one-file-system +block=$BLOCKING +sparse"
+#TAR_PART1="/usr/local/bin/tar -c +multi-volume +one-file-system +block=$BLOCKING "
+
+# Make sure the log file did not already exist. Create it.
+
+if [ -f $LOGFILE ] ; then
+ echo Log file $LOGFILE already exists.
+ exit 1
+else
+ touch $LOGFILE
+fi
+
+mt -f $TAPE_FILE rewind
+
+set $BACKUP_DIRS
+while [ $# -ne 0 ] ; do
+ host=`echo $1 | sed 's/:.*$//'`
+ fs=`echo $1 | sed 's/^.*://'`
+ date=`date`
+ fsname=`echo $1 | sed 's/\//:/g'`
+
+# This filename must be absolute; it is opened on the machine that runs tar.
+ TAR_PART2="+listed=/etc/tar-backup/temp.level-1"
+ TAR_PART3="+label='level 1 backup of $fs on $host at $date' -C $fs ."
+
+ echo Backing up $1 at $date | tee -a $LOGFILE
+ echo Last full dump on this filesystem: | tee -a $LOGFILE
+
+ if [ $HOST != $host ] ; then
+ rsh $host "ls -l /etc/tar-backup/$fsname.level-0; \
+ cp /etc/tar-backup/$fsname.level-0 /etc/tar-backup/temp.level-1" \
+ 2>&1 | tee -a $LOGFILE
+ else
+ ls -l /etc/tar-backup/$fsname.level-0 2>&1 | tee -a $LOGFILE
+ cp /etc/tar-backup/$fsname.level-0 /etc/tar-backup/temp.level-1 2>&1 | tee -a $LOGFILE
+ fi
+
+ # Actually back things up.
+
+ if [ $HOST != $host ] ; then
+ rsh $host $TAR_PART1 -f $HOST:$TAPE_FILE $TAR_PART2 $TAR_PART3 2>&1 | tee -a $LOGFILE
+ else
+# Using `sh -c exec' causes nested quoting and shell substitution
+# to be handled here in the same way rsh handles it.
+ sh -c "exec $TAR_PART1 -f $TAPE_FILE $TAR_PART2 $TAR_PART3" 2>&1 | tee -a $LOGFILE
+ fi
+ if [ $? -ne 0 ] ; then
+ echo Backup of $1 failed. | tee -a $LOGFILE
+ # I'm assuming that the tar will have written an empty
+ # file to the tape, otherwise I should do a cat here.
+ else
+ if [ $HOST != $host ] ; then
+ rsh $host mv -f /etc/tar-backup/temp.level-1 /etc/tar-backup/$fsname.level-1 2>&1 | tee -a $LOGFILE
+ else
+ mv -f /etc/tar-backup/temp.level-1 /etc/tar-backup/$fsname.level-1 2>&1 | tee -a $LOGFILE
+ fi
+ fi
+ $TAPE_STATUS | tee -a $LOGFILE
+ sleep 60
+ shift
+done
+
+# Dump any individual files requested.
+
+if [ x != "x$BACKUP_FILES" ] ; then
+ date=`date`
+ TAR_PART2="+listed=/etc/tar-backup/temp.level-1"
+ TAR_PART3="+label='Incremental backup of miscellaneous files at $date'"
+
+ echo Backing up miscellaneous files at $date | tee -a $LOGFILE
+ echo Last full dump of these files: | tee -a $LOGFILE
+ ls -l /etc/tar-backup/misc.level-0 2>&1 | tee -a $LOGFILE
+
+ rm -f /etc/tar-backup/temp.level-1 2>&1 | tee -a $LOGFILE
+ cp /etc/tar-backup/misc.level-0 /etc/tar-backup/temp.level-1 2>&1 | tee -a $LOGFILE
+
+ echo Backing up miscellaneous files at $date | tee -a $LOGFILE
+# Using `sh -c exec' causes nested quoting and shell substitution
+# to be handled here in the same way rsh handles it.
+ sh -c "exec $TAR_PART1 -f $TAPE_FILE $TAR_PART2 $TAR_PART3 \
+ $BACKUP_FILES" 2>&1 | tee -a $LOGFILE
+ if [ $? -ne 0 ] ; then
+ echo Backup of miscellaneous files failed. | tee -a $LOGFILE
+ # I'm assuming that the tar will have written an empty
+ # file to the tape, otherwise I should do a cat here.
+ else
+ mv -f /etc/tar-backup/temp.level-1 /etc/tar-backup/misc.level-1 2>&1 | tee -a $LOGFILE
+ fi
+ $TAPE_STATUS | tee -a $LOGFILE
+else
+ echo No miscellaneous files specified | tee -a $LOGFILE
+ false
+fi
+
+mt -f $TAPE_FILE rewind
+mt -f $TAPE_FILE offl
+
+echo Sending the dump log to $ADMINISTRATOR
+cat $LOGFILE | sed -f logfile.sed > $LOGFILE.tmp
+/usr/ucb/mail -s "Results of backup on `date`" $ADMINISTRATOR < $LOGFILE.tmp
View
4 list.c
@@ -675,11 +675,11 @@ skip_extended_headers()
for (;;) {
exhdr = findrec();
if (!exhdr->ext_hdr.isextended) {
- userec(exhdr);
+ userec(exhdr);
break;
}
+ userec (exhdr);
}
- userec(exhdr);
}
/*
View
20 port.c
@@ -65,7 +65,7 @@ extern long baserec;
/* JF: modified so all configuration information can appear here, instead of
being scattered through the file. Add all the machine-dependent #ifdefs
here */
-#undef WANT_DUMB_GETDATE/* WANT_DUMB_GETDATE --> getdate() */
+#undef WANT_DUMB_GET_DATE/* WANT_DUMB_GET_DATE --> get_date() */
#undef WANT_VALLOC /* WANT_VALLOC --> valloc() */
#undef WANT_MKDIR /* WANT_MKDIR --> mkdir() rmdir() */
#undef WANT_STRING /* WANT_STRING --> index() bcopy() bzero() bcmp() */
@@ -102,6 +102,10 @@ extern long baserec;
#endif
+#ifdef hpux
+#define WANT_VALLOC
+#endif
+
#ifdef MINIX
#define WANT_BZERO
#endif
@@ -127,7 +131,9 @@ char TTY_NAME[] ="/dev/tty";
#define WANT_UTILS
#define WANT_CK_PIPE
+#ifndef HAVE_STRSTR
#define WANT_STRSTR
+#endif
#if (!defined(STDC_MSG) && !defined(DOPRNT_MSG) && !defined(VARARGS_MSG) && !defined(LOSING_MSG))
#ifdef BSD42
@@ -150,19 +156,19 @@ char TTY_NAME[] ="/dev/tty";
/* End of system-dependent #ifdefs */
-#ifdef WANT_DUMB_GETDATE
-/* JF a getdate() routine takes a date/time/etc and turns it into a time_t */
+#ifdef WANT_DUMB_GET_DATE
+/* JF a get_date() routine takes a date/time/etc and turns it into a time_t */
/* This one is a quick hack I wrote in about five minutes to see if the N
option works. Someone should replace it with one that works */
-/* This getdate takes an arg of the form mm/dd/yyyy hh:mm:ss and turns it
+/* This get_date takes an arg of the form mm/dd/yyyy hh:mm:ss and turns it
into a time_t . Its not well tested or anything. . . */
-/* In general, you should use the getdate() supplied in getdate.y */
+/* In general, you should use the get_date() supplied in getdate.y */
#define OFF_FROM GMT 18000 /* Change for your time zone! */
time_t
-getdate(str)
+get_date(str)
char *str;
{
int month,day,year,hour,minute,second;
@@ -1106,6 +1112,8 @@ char *wanted;
register char firstc;
extern int strcmp();
+ if (*wanted == '\0')
+ return (char *)0;
/*
* The odd placement of the two tests is so "" is findable.
* Also, we inline the first char for speed.
View
2,783 regex.c
2,783 additions, 0 deletions not shown because the diff is too large. Please use a local Git client to view these changes.
View
257 regex.h
@@ -0,0 +1,257 @@
+/* Definitions for data structures callers pass the regex library.
+
+ Copyright (C) 1985, 1989-90 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+
+#ifdef __GNUC__
+ #pragma once
+#endif
+
+#ifndef __REGEXP_LIBRARY
+#define __REGEXP_LIBRARY
+
+/* Define number of parens for which we record the beginnings and ends.
+ This affects how much space the `struct re_registers' type takes up. */
+#ifndef RE_NREGS
+#define RE_NREGS 10
+#endif
+
+#define BYTEWIDTH 8
+
+
+/* Maximum number of duplicates an interval can allow. */
+#define RE_DUP_MAX ((1 << 15) - 1)
+
+
+/* This defines the various regexp syntaxes. */
+extern int obscure_syntax;
+
+
+/* The following bits are used in the obscure_syntax variable to choose among
+ alternative regexp syntaxes. */
+
+/* If this bit is set, plain parentheses serve as grouping, and backslash
+ parentheses are needed for literal searching.
+ If not set, backslash-parentheses are grouping, and plain parentheses
+ are for literal searching. */
+#define RE_NO_BK_PARENS 1
+
+/* If this bit is set, plain | serves as the `or'-operator, and \| is a
+ literal.
+ If not set, \| serves as the `or'-operator, and | is a literal. */
+#define RE_NO_BK_VBAR (1 << 1)
+
+/* If this bit is not set, plain + or ? serves as an operator, and \+, \? are
+ literals.
+ If set, \+, \? are operators and plain +, ? are literals. */
+#define RE_BK_PLUS_QM (1 << 2)
+
+/* If this bit is set, | binds tighter than ^ or $.
+ If not set, the contrary. */
+#define RE_TIGHT_VBAR (1 << 3)
+
+/* If this bit is set, then treat newline as an OR operator.
+ If not set, treat it as a normal character. */
+#define RE_NEWLINE_OR (1 << 4)
+
+/* If this bit is set, then special characters may act as normal
+ characters in some contexts. Specifically, this applies to:
+ ^ -- only special at the beginning, or after ( or |;
+ $ -- only special at the end, or before ) or |;
+ *, +, ? -- only special when not after the beginning, (, or |.
+ If this bit is not set, special characters (such as *, ^, and $)
+ always have their special meaning regardless of the surrounding
+ context. */
+#define RE_CONTEXT_INDEP_OPS (1 << 5)
+
+/* If this bit is not set, then \ before anything inside [ and ] is taken as
+ a real \.
+ If set, then such a \ escapes the following character. This is a
+ special case for awk. */
+#define RE_AWK_CLASS_HACK (1 << 6)
+
+/* If this bit is set, then \{ and \} or { and } serve as interval operators.
+ If not set, then \{ and \} and { and } are treated as literals. */
+#define RE_INTERVALS (1 << 7)
+
+/* If this bit is not set, then \{ and \} serve as interval operators and
+ { and } are literals.
+ If set, then { and } serve as interval operators and \{ and \} are
+ literals. */
+#define RE_NO_BK_CURLY_BRACES (1 << 8)
+
+/* If this bit is set, then character classes are supported; they are:
+ [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:],
+ [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+ If not set, then character classes are not supported. */
+#define RE_CHAR_CLASSES (1 << 9)
+
+/* If this bit is set, then the dot re doesn't match a null byte.
+ If not set, it does. */
+#define RE_DOT_NOT_NULL (1 << 10)
+
+/* If this bit is set, then [^...] doesn't match a newline.
+ If not set, it does. */
+#define RE_HAT_NOT_NEWLINE (1 << 11)
+
+/* If this bit is set, back references are recognized.
+ If not set, they aren't. */
+#define RE_NO_BK_REFS (1 << 12)
+
+/* If this bit is set, back references must refer to a preceding
+ subexpression. If not set, a back reference to a nonexistent
+ subexpression is treated as literal characters. */
+#define RE_NO_EMPTY_BK_REF (1 << 13)
+
+/* If this bit is set, bracket expressions can't be empty.
+ If it is set, they can be empty. */
+#define RE_NO_EMPTY_BRACKETS (1 << 14)
+
+/* If this bit is set, then *, +, ? and { cannot be first in an re or
+ immediately after a |, or a (. Furthermore, a | cannot be first or
+ last in an re, or immediately follow another | or a (. Also, a ^
+ cannot appear in a nonleading position and a $ cannot appear in a
+ nontrailing position (outside of bracket expressions, that is). */
+#define RE_CONTEXTUAL_INVALID_OPS (1 << 15)
+
+/* If this bit is set, then +, ? and | aren't recognized as operators.
+ If it's not, they are. */
+#define RE_LIMITED_OPS (1 << 16)
+
+/* If this bit is set, then an ending range point has to collate higher
+ or equal to the starting range point.
+ If it's not set, then when the ending range point collates higher
+ than the starting range point, the range is just considered empty. */
+#define RE_NO_EMPTY_RANGES (1 << 17)
+
+/* If this bit is set, then a hyphen (-) can't be an ending range point.
+ If it isn't, then it can. */
+#define RE_NO_HYPHEN_RANGE_END (1 << 18)
+
+
+/* Define combinations of bits for the standard possibilities. */
+#define RE_SYNTAX_POSIX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS)
+#define RE_SYNTAX_AWK (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS | RE_AWK_CLASS_HACK)
+#define RE_SYNTAX_EGREP (RE_NO_BK_PARENS | RE_NO_BK_VBAR \
+ | RE_CONTEXT_INDEP_OPS | RE_NEWLINE_OR)
+#define RE_SYNTAX_GREP (RE_BK_PLUS_QM | RE_NEWLINE_OR)
+#define RE_SYNTAX_EMACS 0
+#define RE_SYNTAX_POSIX_BASIC (RE_INTERVALS | RE_BK_PLUS_QM \
+ | RE_CHAR_CLASSES | RE_DOT_NOT_NULL \
+ | RE_HAT_NOT_NEWLINE | RE_NO_EMPTY_BK_REF \
+ | RE_NO_EMPTY_BRACKETS | RE_LIMITED_OPS \
+ | RE_NO_EMPTY_RANGES | RE_NO_HYPHEN_RANGE_END)
+
+#define RE_SYNTAX_POSIX_EXTENDED (RE_INTERVALS | RE_NO_BK_CURLY_BRACES \
+ | RE_NO_BK_VBAR | RE_NO_BK_PARENS \
+ | RE_HAT_NOT_NEWLINE | RE_CHAR_CLASSES \
+ | RE_NO_EMPTY_BRACKETS | RE_CONTEXTUAL_INVALID_OPS \
+ | RE_NO_BK_REFS | RE_NO_EMPTY_RANGES \
+ | RE_NO_HYPHEN_RANGE_END)
+
+
+/* This data structure is used to represent a compiled pattern. */
+
+struct re_pattern_buffer
+ {
+ char *buffer; /* Space holding the compiled pattern commands. */
+ long allocated; /* Size of space that `buffer' points to. */
+ long used; /* Length of portion of buffer actually occupied */
+ char *fastmap; /* Pointer to fastmap, if any, or zero if none. */
+ /* re_search uses the fastmap, if there is one,
+ to skip over totally implausible characters. */
+ char *translate; /* Translate table to apply to all characters before
+ comparing, or zero for no translation.
+ The translation is applied to a pattern when it is
+ compiled and to data when it is matched. */
+ char fastmap_accurate;
+ /* Set to zero when a new pattern is stored,
+ set to one when the fastmap is updated from it. */
+ char can_be_null; /* Set to one by compiling fastmap
+ if this pattern might match the null string.
+ It does not necessarily match the null string
+ in that case, but if this is zero, it cannot.
+ 2 as value means can match null string
+ but at end of range or before a character
+ listed in the fastmap. */
+ };
+
+
+/* search.c (search_buffer) needs this one value. It is defined both in
+ regex.c and here. */
+#define RE_EXACTN_VALUE 1
+
+
+/* Structure to store register contents data in.
+
+ Pass the address of such a structure as an argument to re_match, etc.,
+ if you want this information back.
+
+ For i from 1 to RE_NREGS - 1, start[i] records the starting index in
+ the string of where the ith subexpression matched, and end[i] records
+ one after the ending index. start[0] and end[0] are analogous, for
+ the entire pattern. */
+
+struct re_registers
+ {
+ int start[RE_NREGS];
+ int end[RE_NREGS];
+ };
+
+
+
+#ifdef __STDC__
+
+extern char *re_compile_pattern (char *, int, struct re_pattern_buffer *);
+/* Is this really advertised? */
+extern void re_compile_fastmap (struct re_pattern_buffer *);
+extern int re_search (struct re_pattern_buffer *, char*, int, int, int,
+ struct re_registers *);
+extern int re_search_2 (struct re_pattern_buffer *, char *, int,
+ char *, int, int, int,
+ struct re_registers *, int);
+extern int re_match (struct re_pattern_buffer *, char *, int, int,
+ struct re_registers *);
+extern int re_match_2 (struct re_pattern_buffer *, char *, int,
+ char *, int, int, struct re_registers *, int);
+
+/* 4.2 bsd compatibility. */
+extern char *re_comp (char *);
+extern int re_exec (char *);
+
+#else /* !__STDC__ */
+
+extern char *re_compile_pattern ();
+/* Is this really advertised? */
+extern void re_compile_fastmap ();
+extern int re_search (), re_search_2 ();
+extern int re_match (), re_match_2 ();
+
+/* 4.2 bsd compatibility. */
+extern char *re_comp ();
+extern int re_exec ();
+
+#endif /* __STDC__ */
+
+
+#ifdef SYNTAX_TABLE
+extern char *re_syntax_table;
+#endif
+
+#endif /* !__REGEXP_LIBRARY */
View
53 rtape_lib.c
@@ -69,15 +69,11 @@ static char *RCSid = "$Header: /usr/src/local/usr.lib/librmt/RCS/rmtlib.c,v 1.7
* Fred Fish, with some additional work by Arnold Robbins.
*/
-/*
- * MAXUNIT --- Maximum number of remote tape file units
- *
- * READ --- Return the number of the read side file descriptor
- * WRITE --- Return the number of the write side file descriptor
- */
+/* Use -DUSE_REXEC for rexec code, courtesy of Dan Kegel, srs!dan */
-/* #define RMTIOCTL 1 Use -DNO_RMTIOCTL to disable rmtioctl() calls */
-/* #define USE_REXEC 1 /* rexec code courtesy of Dan Kegel, srs!dan */
+#if defined(USG) && !defined(HAVE_MTIO)
+#define NO_RMTIOCTL
+#endif
#include <stdio.h>
#include <signal.h>
@@ -97,8 +93,16 @@ static char *RCSid = "$Header: /usr/src/local/usr.lib/librmt/RCS/rmtlib.c,v 1.7
#include <sys/stat.h>
#define BUFMAGIC 64 /* a magic number for buffer sizes */
+
+/*
+ * MAXUNIT --- Maximum number of remote tape file units
+ */
#define MAXUNIT 4
+/*
+ * READ --- Return the number of the read side file descriptor
+ * WRITE --- Return the number of the write side file descriptor
+ */
#define READ(fd) (Ctp[fd][0])
#define WRITE(fd) (Ptc[fd][1])
@@ -133,7 +137,7 @@ int fildes;
char *buf;
{
register int blen;
-#ifdef USG
+#ifdef SIGNAL_VOID
void (*pstat)();
#else
int (*pstat)();
@@ -258,6 +262,21 @@ char *host;
char *user; /* may be NULL */
{
struct servent *rexecserv;
+ int save_stdin = dup(fileno(stdin));
+ int save_stdout = dup(fileno(stdout));
+ int tape_fd; /* Return value. */
+
+ /*
+ * When using cpio -o < filename, stdin is no longer the tty.
+ * But the rexec subroutine reads the login and the passwd on stdin,
+ * to allow remote execution of the command.
+ * So, reopen stdin and stdout on /dev/tty before the rexec and
+ * give them back their original value after.
+ */
+ if (freopen("/dev/tty", "r", stdin) == NULL)
+ freopen("/dev/null", "r", stdin);
+ if (freopen("/dev/tty", "w", stdout) == NULL)
+ freopen("/dev/null", "w", stdout);
rexecserv = getservbyname("exec", "tcp");
if (NULL == rexecserv) {
@@ -266,8 +285,14 @@ char *user; /* may be NULL */
}
if ((user != NULL) && *user == '\0')
user = (char *) NULL;
- return rexec (&host, rexecserv->s_port, user, NULL,
- "/etc/rmt", (int *)NULL);
+ tape_fd = rexec (&host, rexecserv->s_port, user, NULL,
+ "/etc/rmt", (int *)NULL);
+ fclose(stdin);
+ fdopen(save_stdin, "r");
+ fclose(stdout);
+ fdopen(save_stdout, "w");
+
+ return tape_fd;
}
#endif /* USE_REXEC */
@@ -395,6 +420,8 @@ int bias;
"/etc/rmt", (char *) 0);
execl("/usr/bsd/rsh", "rsh", system, "-l", login,
"/etc/rmt", (char *)0);
+ execl("/usr/bin/nsh", "nsh", system, "-l", login,
+ "/etc/rmt", (char *)0);
}
else
{
@@ -406,6 +433,8 @@ int bias;
"/etc/rmt", (char *) 0);
execl("/usr/bsd/rsh", "rsh", system,
"/etc/rmt", (char *) 0);
+ execl("/usr/bin/nsh", "nsh", system,
+ "/etc/rmt", (char *)0);
}
/*
@@ -496,7 +525,7 @@ char *buf;
unsigned int nbyte;
{
char buffer[BUFMAGIC];
-#ifdef USG
+#ifdef SIGNAL_VOID
void (*pstat)();
#else
int (*pstat)();
View
28 rtape_server.c
@@ -37,6 +37,10 @@ static char sccsid[] = "@(#)rmt.c 5.4 (Berkeley) 6/29/88";
#include <sys/mtio.h>
#include <errno.h>
+#if defined (i386) && defined (AIX)
+#include <fcntl.h>
+#endif
+
int tape = -1;
char *record;
@@ -85,7 +89,31 @@ main(argc, argv)
(void) close(tape);
getstring(device); getstring(mode);
DEBUG2("rmtd: O %s %s\n", device, mode);
+#if defined (i386) && defined (AIX)
+ /* This is alleged to fix a byte ordering problem. */
+ /* I'm quite suspicious if it's right. -- mib */
+ {
+ int oflag = atoi (mode);
+ int nflag = 0;
+ if ((oflag & 3) == 0)
+ nflag |= O_RDONLY;
+ if (oflag & 1)
+ nflag |= O_WRONLY;
+ if (oflag & 2)
+ nflag |= O_RDWR;
+ if (oflag & 0x0008)
+ nflag |= O_APPEND;
+ if (oflag & 0x0200)
+ nflag |= O_CREAT;
+ if (oflag & 0x0400)
+ nflag |= O_TRUNC;
+ if (oflag & 0x0800)
+ nflag |= O_EXCL;
+ tape = open (device, nflag, 0666);
+ }
+#else
tape = open(device, atoi(mode),0666);
+#endif
if (tape < 0)
goto ioerror;
goto respond;
View
159 tar.c
@@ -31,6 +31,7 @@ anyone else from sharing it farther. Help stamp out software hoarding!
#include <sys/types.h> /* Needed for typedefs in tar.h */
#include <sys/stat.h> /* JF */
#include "getopt.h"
+#include "regex.h"
#ifdef USG
#define rindex strrchr
@@ -101,7 +102,7 @@ extern void update_archive();
extern void junk_archive();
/* JF */
-extern time_t getdate();
+extern time_t get_date();
time_t new_time;
@@ -143,11 +144,11 @@ struct option long_options[] =
{"create", 0, 0, 'c'},
{"append", 0, 0, 'r'},
{"extract", 0, 0, 'x'},
- {"get", 1, 0, 'x'},
+ {"get", 0, 0, 'x'},
{"list", 0, 0, 't'},
{"update", 0, 0, 'u'},
{"catenate", 0, 0, 'A'},
- {"concatenate", 1, 0, 'A'},
+ {"concatenate", 0, 0, 'A'},
{"compare", 0, 0, 'd'},
{"diff", 0, 0, 'd'},
{"delete", 0, 0, 14},
@@ -163,7 +164,8 @@ struct option long_options[] =
{"block-size", 1, 0, 'b'},
{"version", 0, 0, 11},
{"verbose", 0, 0, 'v'},
-
+ {"totals", 0, &f_totals, 1},
+
{"read-full-blocks", 0, &f_reblock, 1},
{"starting-file", 1, 0, 'K'},
{"to-stdout", 0, &f_exstdout, 1},
@@ -178,7 +180,7 @@ struct option long_options[] =
{"same-owner", 0, &f_do_chown, 1},
{"preserve-order", 0, &f_sorted_names, 1},
- {"newer", 0, 0, 'N'},
+ {"newer", 1, 0, 'N'},
{"after-date", 1, 0, 'N'},
{"newer-mtime", 1, 0, 13},
{"incremental", 0, 0, 'G'},
@@ -197,6 +199,7 @@ struct option long_options[] =
{"compress", 0, &f_compress, 1},
{"compress-block", 0, &f_compress, 2},
{"sparse", 0, &f_sparse_files, 1},
+ {"tape-length", 1, 0, 'L'},
{0, 0, 0, 0}
};
@@ -211,6 +214,7 @@ main(argc, argv)
extern char version_string[];
tar = argv[0]; /* JF: was "tar" Set program name */
+ errors = 0;
options(argc, argv);
@@ -228,13 +232,46 @@ main(argc, argv)
break;
case CMD_CREATE:
create_archive();
+ if (f_totals)
+ fprintf (stderr, "Total bytes written: %d\n", tot_written);
break;
case CMD_EXTRACT:
+ if (f_volhdr) {
+ char *err;
+ label_pattern = (struct re_pattern_buffer *)
+ ck_malloc (sizeof *label_pattern);
+ err = re_compile_pattern (f_volhdr, strlen (f_volhdr),
+ label_pattern);
+ if (err) {
+ fprintf (stderr,"Bad regular expression: %s\n",
+ err);
+ errors++;
+ break;
+ }
+
+ }
extr_init();
read_and(extract_archive);
break;
case CMD_LIST:
+ if (f_volhdr) {
+ char *err;
+ label_pattern = (struct re_pattern_buffer *)
+ ck_malloc (sizeof *label_pattern);
+ err = re_compile_pattern (f_volhdr, strlen (f_volhdr),
+ label_pattern);
+ if (err) {
+ fprintf (stderr,"Bad regular expression: %s\n",
+ err);
+ errors++;
+ break;
+ }
+ }
read_and(list_archive);
+#if 0
+ if (!errors)
+ errors = different;
+#endif
break;
case CMD_DIFF:
diff_init();
@@ -248,7 +285,7 @@ main(argc, argv)
fprintf(stderr,"For more information, type ``%s +help''.\n",tar);
exit(EX_ARGSBAD);
}
- exit(0);
+ exit(errors);
/* NOTREACHED */
}
@@ -272,7 +309,7 @@ options(argc, argv)
/* Parse options */
while ((c = getoldopt(argc, argv,
- "-01234567Ab:BcC:df:F:g:GhikK:lmMN:oOpPrRsStT:uvV:wWxX:zZ",
+ "-01234567Ab:BcC:df:F:g:GhikK:lL:mMN:oOpPrRsStT:uvV:wWxX:zZ",
long_options, &ind)) != EOF) {
switch (c) {
case 0: /* long options that set a single flag */
@@ -444,6 +481,10 @@ options(argc, argv)
f_local_filesys++;
break;
+ case 'L':
+ tape_length = intconv (optarg);
+ f_multivol++;
+ break;
case 'm':
f_modified++;
break;
@@ -458,7 +499,7 @@ options(argc, argv)
case 'N': /* Only write files newer than X */
get_newer:
f_new_files++;
- new_time=getdate(optarg,(struct timeb *)0);
+ new_time=get_date(optarg,(struct timeb *)0);
break;
case 'o': /* Generate old archive */
@@ -573,14 +614,17 @@ describe()
{
msg("choose one of the following:");
fputs("\
--A, +catenate append tar files to an archive\n\
+-A, +catenate,\n\
+ +concatenate append tar files to an archive\n\
-c, +create create a new archive\n\
--d, +diff find differences between archive and file system\n\
- +delete delete from the archive (not for use on mag tapes!)\n\
+-d, +diff,\n\
+ +compare find differences between archive and file system\n\
++delete delete from the archive (not for use on mag tapes!)\n\
-r, +append append files to the end of an archive\n\
-t, +list list the contents of an archive\n\
-u, +update only append files that are newer than copy in archive\n\
--x, +extract extract files from an archive\n",stderr);
+-x, +extract,\n\
+ +get extract files from an archive\n",stderr);
fprintf(stderr, "\
Other options:\n\
@@ -591,34 +635,46 @@ Other options:\n\
", stderr); /* KLUDGE */ fprintf(stderr, "\
-f, +file [HOSTNAME:]F use archive file or device F (default %s)\n",
DEF_AR_FILE); fputs("\
--G, +incremental F create/list/extract GNU-format incremental backup\n\
+-F, +info-script F run script at end of each tape (implies -M)\n\
+-G, +incremental create/list/extract old GNU-format incremental backup\n\
+-g, +listed-incremental F create/list/extract new GNU-format incremental backup\n\
-h, +dereference don't dump symlinks; dump the files they point to\n\
-i, +ignore-zeros ignore blocks of zeros in archive (normally mean EOF)\n\
-k, +keep-old-files keep existing files; don't overwrite them from archive\n\
-K, +starting-file FILE begin at FILE in the archive\n\
-l, +one-file-system stay in local file system when creating an archive\n\
+-L, +tape-length LENGTH change tapes after writing LENGTH\n\
", stderr); /* KLUDGE */ fputs("\
-m, +modification-time don't extract file modified time\n\
-M, +multi-volume create/list/extract multi-volume archive\n\
--N, +after-date DATE only store files newer than DATE\n\
--o, +old-archive write a V7 format archive, rather than ANSI format\n\
+-N, +after-date DATE,\n\
+ +newer DATE only store files newer than DATE\n\
+-o, +old-archive,\n\
+ +portability write a V7 format archive, rather than ANSI format\n\
-O, +to-stdout extract files to standard output\n\
--p, +same-permissions extract all protection information\n\
+-p, +same-permissions,\n\
+ +preserve-permissions extract all protection information\n\
-P, +absolute-paths don't strip leading `/'s from file names\n\
+preserve like -p -s\n\
", stderr); /* KLUDGE */ fputs("\
-R, +record-number show record number within archive with each message\n\
--s, +same-order list of names to extract is sorted to match archive\n\
+-s, +same-order,\n\
+ +preserve-order list of names to extract is sorted to match archive\n\
++same-order create extracted files with the same ownership \n\
-S, +sparse handle sparse files efficiently\n\
-T, +files-from F get names to extract or create from file F\n\
++totals print total bytes written with +create\n\
-v, +verbose verbosely list files processed\n\
-V, +label NAME create archive with volume name NAME\n\
+version print tar program version number\n\
--w, +interactive ask for confirmation for every action\n\
+-w, +interactive,\n\
+ +confirmation ask for confirmation for every action\n\
", stderr); /* KLUDGE */ fputs("\
-W, +verify attempt to verify the archive after writing it\n\
--X, +exclude FILE exclude files listed in FILE\n\
--z, -Z, +compress filter the archive through compress\n\
+-X, +exclude FILE exclude file FILE\n\
++exclude-from FILE exclude files listed in FILE\n\
+-z, -Z, +compress,\n\
+ +uncompress filter the archive through compress\n\
-[0-7][lmh] specify drive and density\n\
", stderr);
}
@@ -678,6 +734,7 @@ name_next(c)
static buffer_siz;
register char *p;
register char *q = 0;
+ register char *q2 = 0;
extern char *un_quote_string();
if(buffer_siz==0) {
@@ -731,6 +788,16 @@ name_next(c)
*q-- = '\0'; /* Zap the newline */
while (q > p && *q == '/') /* Zap trailing /s */
*q-- = '\0';
+ if (c && !q2 && p[0] == '-' && p[1] == 'C' && p[2] == '\0') {
+ q2 = p;
+ goto tryagain;
+ }
+ if (q2) {
+ if (chdir (p) < 0)
+ msg_perror ("Can't chdir to %s", p);
+ q2 = 0;
+ goto tryagain;
+ }
if(f_exclude && check_exclude(p))
goto tryagain;
return un_quote_string(p);
@@ -818,7 +885,7 @@ addname(name)
if(name[0]=='-' && name[1]=='C' && name[2]=='\0') {
chdir_name=name_next(0);
name=name_next(0);
- if(!name) {
+ if(!chdir_name) {
msg("Missing file name after -C");
exit(EX_ARGSBAD);
}
@@ -842,27 +909,44 @@ addname(name)
}
}
- i = strlen(name);
- /*NOSTRICT*/
- p = (struct name *)malloc((unsigned)(sizeof(struct name) + i));
+ if (name)
+ {
+ i = strlen(name);
+ /*NOSTRICT*/
+ p = (struct name *)malloc((unsigned)(sizeof(struct name) + i));
+ }
+ else
+ p = (struct name *)malloc ((unsigned)(sizeof (struct name)));
if (!p) {
- msg("cannot allocate mem for name '%s'.",name);
- exit(EX_SYSTEM);
+ if (name)
+ msg("cannot allocate mem for name '%s'.",name);
+ else
+ msg("cannot allocate mem for chdir record.");
+ exit(EX_SYSTEM);
}
p->next = (struct name *)NULL;
- p->length = i;
- strncpy(p->name, name, i);
- p->name[i] = '\0'; /* Null term */
+ if (name)
+ {
+ p->fake = 0;
+ p->length = i;