Diffs to produce GNU tar version 1.11.1 from version 1.11. diff -rc2N tar-1.11/ChangeLog tar-1.11.1/ChangeLog *** tar-1.11/ChangeLog Wed Sep 9 16:14:05 1992 --- tar-1.11.1/ChangeLog Tue Sep 15 20:44:04 1992 *************** *** 1,2 **** --- 1,85 ---- + Tue Sep 15 14:49:48 1992 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * version.c: Released version 1.11.1. + + * Makefile (AUX): Added NEWS. + + * Makefile.in (rmt): Added $(LIBS). + * configure.in: Added tests for libraries needed on Solaris. + + * mangle.c (extract_mangle): Null terminate link name for + losing archives missing it. + + * Makefile.in: added target and rule for getdate.c: getdate.y; + some makes don't have one built in. + + Mon Sep 14 16:23:15 1992 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * tar.c (options, main): Advise use of --help rather than + +help. + + * create.c (write_long): Using hstat here is a Bad Idea, and + totally unnecessary at that. + + * list.c (read_header): Compute both signed and normal + checksums. + + * configure.in: Define BSD in the presence of /sdmach or + /../../mach. + + * diffarch.c, buffer.c: Declare valloc as void* rather than + char*. + + * Makefile.in: Don't install info files. + + * configure.in: Check for malloc was scrambled. + + * port.h: Undefine index and rindex if necessary; some + string.h's define them for us. + + * tar.c (addname): Missing braces after if. + * gnu.c (read_dir_file): Missing braces after if. + + * names.c: Add include of , + + * create.c (start_header): Set current_file_name so that + print_header (used for verbose create) works properly. + (dump_file): Set current_link_name when setting up symlink + and hardlink records. + + Fri Sep 11 01:05:52 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) + + * fnmatch.[ch]: New files. + * wildmat.c: File removed. + * tar.c: Include fnmatch.h and use fnmatch instead of wildmat. + * Makefile.in, makefile.pc: Replace wildmat.o(bj) with fnmatch. + + Thu Sep 10 23:19:30 1992 David J. MacKenzie (djm@nutrimat.gnu.ai.mit.edu) + + * buffer.c, tar.c: Remove redundant decls of getenv, rindex. + + * Makefile.in: Add uninstall target. + Define libdir instead of hardcoding /etc for installing rmt. + + Thu Sep 10 13:06:03 1992 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) + + * list.c (read_header): On second thought, that doesn't work + either, so just store the names in malloced areas. Sigh. + + * NEWS: New file. + * README: Removed things that belong in NEWS; point to it. + + * list.c (read_header): current_file_name and + current_link_name need to be set to the arrays in head rather + than header; header is the actual read buffer and will change. + + * extract.c (extract_archive): + * buffer.c (new_volume): `#' directives need to start in + column 1. + + Thu Sep 10 06:09:18 1992 Noah Friedman (friedman@nutrimat.gnu.ai.mit.edu) + + * level-0, level-1 (TAR_PART1): put --atime-preserve inside quotes. + Wed Sep 9 13:34:26 1992 Michael I Bushnell (mib@geech.gnu.ai.mit.edu) diff -rc2N tar-1.11/Makefile.in tar-1.11.1/Makefile.in *** tar-1.11/Makefile.in Wed Sep 9 16:12:31 1992 --- tar-1.11.1/Makefile.in Tue Sep 15 20:43:28 1992 *************** *** 16,21 **** # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - SHELL = /bin/sh - #### Start of system configuration section. #### --- 16,19 ---- *************** *** 88,91 **** --- 86,92 ---- bindir = $(exec_prefix)/bin + # Where to put the rmt executable. + libdir = /etc + # The directory to install the info files in. infodir = $(prefix)/info *************** *** 93,107 **** #### End of system configuration section. #### 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 malloc.c SRC3 = getopt1.c regex.c getdate.y SRCS = $(SRC1) $(SRC2) $(SRC3) OBJ1 = tar.o create.o extract.o buffer.o getoldopt.o update.o gnu.o mangle.o ! OBJ2 = version.o list.o names.o diffarch.o port.o wildmat.o getopt.o @MALLOC@ OBJ3 = getopt1.o regex.o getdate.o $(RTAPELIB) OBJS = $(OBJ1) $(OBJ2) $(OBJ3) ! AUX = README INSTALL COPYING ChangeLog Makefile.in makefile.pc \ configure configure.in \ ! tar.h pathmax.h port.h open3.h getopt.h regex.h \ rmt.h rmt.c rtapelib.c alloca.c \ msd_dir.h msd_dir.c tcexparg.c \ --- 94,110 ---- #### End of system configuration section. #### + SHELL = /bin/sh + 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 fnmatch.c getopt.c malloc.c SRC3 = getopt1.c regex.c getdate.y SRCS = $(SRC1) $(SRC2) $(SRC3) OBJ1 = tar.o create.o extract.o buffer.o getoldopt.o update.o gnu.o mangle.o ! OBJ2 = version.o list.o names.o diffarch.o port.o fnmatch.o getopt.o @MALLOC@ OBJ3 = getopt1.o regex.o getdate.o $(RTAPELIB) OBJS = $(OBJ1) $(OBJ2) $(OBJ3) ! AUX = README INSTALL NEWS COPYING ChangeLog Makefile.in makefile.pc \ configure configure.in \ ! tar.h fnmatch.h pathmax.h port.h open3.h getopt.h regex.h \ rmt.h rmt.c rtapelib.c alloca.c \ msd_dir.h msd_dir.c tcexparg.c \ *************** *** 109,113 **** # tar.texinfo tar.info* texinfo.tex \ ! all: @PROGS@ # tar.info .c.o: --- 112,117 ---- # tar.texinfo tar.info* texinfo.tex \ ! all: @PROGS@ ! # tar.info .c.o: *************** *** 118,122 **** rmt: rmt.c ! $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(srcdir)/rmt.c tar.info: tar.texinfo --- 122,126 ---- rmt: rmt.c ! $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(srcdir)/rmt.c $(LIBS) tar.info: tar.texinfo *************** *** 125,134 **** install: all $(INSTALL_PROGRAM) tar $(bindir)/$(binprefix)tar ! -test ! -f rmt || $(INSTALL_PROGRAM) rmt /etc/rmt ! $(INSTALL_DATA) $(srcdir)/tar.info* $(infodir) $(OBJS): tar.h pathmax.h port.h testpad.h regex.o buffer.o tar.o: regex.h # getdate.y has 8 shift/reduce conflicts. --- 129,148 ---- install: all $(INSTALL_PROGRAM) tar $(bindir)/$(binprefix)tar ! -test ! -f rmt || $(INSTALL_PROGRAM) rmt $(libdir)/rmt ! # for file in $(srcdir)/tar.info*; \ ! # do $(INSTALL_DATA) $$file $(infodir)/$$file; \ ! # done ! ! uninstall: ! rm -f $(bindir)/$(binprefix)tar $(infodir)/tar.info* ! -rm -f $(libdir)/rmt $(OBJS): tar.h pathmax.h port.h testpad.h regex.o buffer.o tar.o: regex.h + tar.o fnmatch.o: fnmatch.h + getdate.c: getdate.y + yacc getdate.y + mv y.tab.c getdate.c # getdate.y has 8 shift/reduce conflicts. diff -rc2N tar-1.11/NEWS tar-1.11.1/NEWS *** tar-1.11/NEWS --- tar-1.11.1/NEWS Mon Sep 14 15:39:21 1992 *************** *** 0 **** --- 1,86 ---- + Current Version: 1.11. + + User-visible changes since 1.10: + + o Many bug fixes + + o Now uses GNU standard configure, generated by Autoconf. + + o Long options now use `--'; use of `+' is deprecated and support for it + will eventually be removed. + + o New option --null causes filenames read by -T to be null-terminated, + and causes -C to be ignored. + + o New option --remove-files deletes files (but not directories) after + they are added to the archive. + + o New option --ignore-failed-read prevents read-errors from affecting + the exit status. + + o New option --checkpoint prints occasional messages as the tape is + being read or written. + + o New option --show-omitted-dirs prints the names of directories + omitted from the archive. + + o Some tape drives which use a non-standard method of indicating + end-of-tape now work correctly with multi-tape archives. + + o --volno-file: Read the volume number used in prompting the user (but + not in recording volume ID's on the archive) from a file. + + o When using --multi-volume, you can now give multiple -f arguments; + the various tape drives will get used in sequence and then wrap + around to the beginning. + + o Remote archive names no longer have to be in /dev: any file with a + `:' is interpreted as remote. If new option --force-local is given, + then even archive files with a `:' are considered local. + + o New option --atime-preserve restores (if possible) atimes to their + original values after dumping the file. + + o No longer does tar confusingly dump "." when you don't tell it what + to dump. + + o When extracting directories, tar now correctly restores their + modification and access times. + + o Longnames support is redone differently--long name info directly + precedes the long-named file or link in the archive, so you no + longer have to wait for the extract to hit the end of the tape for + long names to work. + + + ================== + + 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. diff -rc2N tar-1.11/README tar-1.11.1/README *** tar-1.11/README Wed Sep 9 14:36:27 1992 --- tar-1.11.1/README Tue Sep 15 20:35:34 1992 *************** *** 1,8 **** Hey! Emacs! Yo! This is -*- Text -*- !!! ! This GNU tar 1.11. Please send bug reports, etc., to bug-gnu-utils@prep.ai.mit.edu. This is a beta-test release. Please try it out. After bug reports are processed for this release, version ! 1.12 will be released. GNU tar is based heavily on John Gilmore's public domain tar, but with --- 1,9 ---- Hey! Emacs! Yo! This is -*- Text -*- !!! ! This GNU tar 1.11.1. Please send bug reports, etc., to bug-gnu-utils@prep.ai.mit.edu. This is a beta-test release. Please try it out. After bug reports are processed for this release, version ! 1.12 will be released. This release includes only bugfixes past ! version 1.11, most of which are fairly important. GNU tar is based heavily on John Gilmore's public domain tar, but with *************** *** 13,32 **** This distribution also includes rmt, the remote tape server (which ! must reside in /etc). The mt program is in the GNU cpio distribution. See the file INSTALL for compilation and installation instructions for Unix. makefile.pc is a makefile for Turbo C 2.0 on MS-DOS. ! 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 want to do incremental dumps, use the distributed backup scripts. They are what we use at the FSF to do all our backups. Most ! importantly, do not use +incremental (-G) or +after-date (-N) or ! +newer-mtime to do incremental dumps. The only option that works ! correctly for this purpose is +listed-incremental. (When extracting ! incremental dumps, use +incremental (-G).) There is no tar manual in this release. The old manual has too many --- 14,36 ---- This distribution also includes rmt, the remote tape server (which ! normally must reside in /etc). The mt tape drive control program is ! in the GNU cpio distribution. See the file INSTALL for compilation and installation instructions for Unix. + See the file NEWS for information on all that is new in this version + of tar. makefile.pc is a makefile for Turbo C 2.0 on MS-DOS. ! Various people have been having problems using floppies on a NeXT. In ! order to have them work right, you need to kill the automounting ! program which tries to monut floppies as soon as they are added. If you want to do incremental dumps, use the distributed backup scripts. They are what we use at the FSF to do all our backups. Most ! importantly, do not use --incremental (-G) or --after-date (-N) or ! --newer-mtime to do incremental dumps. The only option that works ! correctly for this purpose is --listed-incremental. (When extracting ! incremental dumps, use --incremental (-G).) There is no tar manual in this release. The old manual has too many *************** *** 33,86 **** problems to make it usable. A new manual will appear in version 1.12. ! User-visible changes since 1.10: ! ! o Many bug fixes ! ! o Now uses GNU standard configure, generated by Autoconf. ! ! o Long options now use `--'; use of `+' is deprecated and support for it ! will eventually be removed. ! ! o New option --null causes filenames read by -T to be null-terminated, ! and causes -C to be ignored. ! ! o New option --remove-files deletes files (but not directories) after ! they are added to the archive. ! ! o New option --ignore-failed-read prevents read-errors from affecting ! the exit status. ! ! o New option --checkpoint prints occasional messages as the tape is ! being read or written. ! ! o New option --show-omitted-dirs prints the names of directories ! omitted from the archive. ! ! o Some tape drives which use a non-standard method of indicating ! end-of-tape now work correctly with multi-tape archives. ! ! o --volno-file: Read the volume number used in prompting the user (but ! not in recording volume ID's on the archive) from a file. ! ! o When using --multi-volume, you can now give multiple -f arguments; ! the various tape drives will get used in sequence and then wrap ! around to the beginning. ! ! o Remote archive names no longer have to be in /dev: any file with a ! `:' is interpreted as remote. If new option --force-local is given, ! then even archive files with a `:' are considered local. ! ! o New option --atime-preserve restores (if possible) atimes to their ! original values after dumping the file. ! ! o No longer does tar confusingly dump "." when you don't tell it what ! to dump. ! ! o When extracting directories, tar now correctly restores their ! modification and access times. ! ! o Longnames support is redone differently--long name info directly ! precedes the long-named file or link in the archive, so you no ! longer have to wait for the extract to hit the end of the tape for ! long names to work. --- 37,47 ---- problems to make it usable. A new manual will appear in version 1.12. ! If your system needs to link with -lPW to get alloca, but has ! rename in the C library (so HAVE_RENAME is defined), -lPW might ! give you an incorrect version of rename. On HP-UX this manifests ! itself as an undefined data symbol called "Error" when linking cp, ln, ! and mv. If this happens, use `ar x' to extract alloca.o from libPW.a ! and `ar rc' to put it in a library liballoca.a, and put that in LIBS ! instead of -lPW. This problem does not occur when using gcc, which ! has alloca built in. diff -rc2N tar-1.11/backup-specs tar-1.11.1/backup-specs *** tar-1.11/backup-specs Thu Apr 30 03:12:57 1992 --- tar-1.11.1/backup-specs Wed Sep 9 17:06:13 1992 *************** *** 2,6 **** # User name of administrator of backups. ! ADMINISTRATOR=backup-reports # Hour at which backups are normally done. --- 2,6 ---- # User name of administrator of backups. ! ADMINISTRATOR=friedman # Hour at which backups are normally done. *************** *** 42,46 **** albert:/fs/gd2 nutrimat:/fs/gp ! kropotkin:/fs/gp2 albert:/fs/mailer albert:/ --- 42,46 ---- albert:/fs/gd2 nutrimat:/fs/gp ! nutrimat:/fs/gp2 albert:/fs/mailer albert:/ *************** *** 57,64 **** gnu:/usr ernst:/usr1 ! wookumz:/usr/gnu/emacs-tape ! wookumz:/usr/gnu/lang-tape ! geech:/usr/gnu/util-tape ! churchy:/usr/gnu/exper-tape" # List of individual files to be dumped. --- 57,61 ---- gnu:/usr ernst:/usr1 ! nutrimat:/fs/dist" # List of individual files to be dumped. diff -rc2N tar-1.11/buffer.c tar-1.11.1/buffer.c *** tar-1.11/buffer.c Tue Sep 8 16:09:06 1992 --- tar-1.11.1/buffer.c Mon Sep 14 16:56:39 1992 *************** *** 74,78 **** never return this status! */ ! char *valloc(); void writeerror(); --- 74,78 ---- never return this status! */ ! void *valloc(); void writeerror(); *************** *** 1260,1264 **** extern int now_verifying; extern char TTY_NAME[]; - char *getenv(); static int looped = 0; --- 1260,1263 ---- *************** *** 1338,1344 **** case '!': ! #ifdef __MSDOS__ spawnl(P_WAIT,getenv("COMSPEC"),"-",0); ! #else /* JF this needs work! */ switch(fork()) { --- 1337,1343 ---- case '!': ! #ifdef __MSDOS__ spawnl(P_WAIT,getenv("COMSPEC"),"-",0); ! #else /* JF this needs work! */ switch(fork()) { *************** *** 1356,1360 **** break; } ! #endif break; } --- 1355,1359 ---- break; } ! #endif break; } diff -rc2N tar-1.11/configure tar-1.11.1/configure *** tar-1.11/configure Wed Sep 9 13:47:36 1992 --- tar-1.11.1/configure Tue Sep 15 20:29:09 1992 *************** *** 610,616 **** echo checking for BSD ! test -f /vmunix && DEFS="$DEFS -DBSD42=1" echo checking for HP-UX ! test -f /hp-ux && test -f /vmunix || MALLOC=malloc.o echo checking for Xenix --- 610,616 ---- echo checking for BSD ! ( test -f /vmunix || test -f /sdmach || test -f /../../mach ) && DEFS="$DEFS -DBSD42=1" echo checking for HP-UX ! test -f /hp-ux && test ! -f /vmunix && MALLOC=malloc.o echo checking for Xenix *************** *** 636,639 **** --- 636,643 ---- esac fi + + echo checking for Solaris libraries + test -f /lib/libsocket.a && LIBS="$LIBS -lsocket" + test -f /lib/libnsl.a && LIBS="$LIBS -lnsl" if test -n "$prefix"; then diff -rc2N tar-1.11/configure.in tar-1.11.1/configure.in *** tar-1.11/configure.in Wed Sep 9 13:47:27 1992 --- tar-1.11.1/configure.in Tue Sep 15 20:10:45 1992 *************** *** 44,51 **** AC_ALLOCA echo checking for BSD ! test -f /vmunix && AC_DEFINE(BSD42) echo checking for HP-UX ! test -f /hp-ux && test -f /vmunix || MALLOC=malloc.o AC_SUBST(MALLOC) AC_XENIX_DIR AC_OUTPUT(Makefile) --- 44,55 ---- AC_ALLOCA echo checking for BSD ! ( test -f /vmunix || test -f /sdmach || test -f /../../mach ) && AC_DEFINE(BSD42) echo checking for HP-UX ! test -f /hp-ux && test ! -f /vmunix && MALLOC=malloc.o AC_SUBST(MALLOC) AC_XENIX_DIR + echo checking for Solaris libraries + test -f /lib/libsocket.a && LIBS="$LIBS -lsocket" + test -f /lib/libnsl.a && LIBS="$LIBS -lnsl" + AC_OUTPUT(Makefile) diff -rc2N tar-1.11/create.c tar-1.11.1/create.c *** tar-1.11/create.c Tue Sep 8 15:53:02 1992 --- tar-1.11.1/create.c Mon Sep 14 17:19:28 1992 *************** *** 311,314 **** --- 311,315 ---- if (link_name - lp->name >= NAMSIZ) write_long (link_name, LF_LONGLINK); + current_link_name = link_name; hstat.st_size = 0; *************** *** 611,618 **** if (size >= NAMSIZ) write_long (buf, LF_LONGLINK); - buf[NAMSIZ - 1] = '\0'; - if (size >= NAMSIZ) - size = NAMSIZ - 1; hstat.st_size = 0; /* Force 0 size on symlink */ header = start_header(p, &hstat); --- 612,617 ---- if (size >= NAMSIZ) write_long (buf, LF_LONGLINK); + current_link_name = buf; hstat.st_size = 0; /* Force 0 size on symlink */ header = start_header(p, &hstat); *************** *** 622,626 **** goto badfile; } ! strcpy (header->header.arch_linkname, buf); header->header.linkflag = LF_SYMLINK; finish_header(header); /* Nothing more to do to it */ --- 621,626 ---- goto badfile; } ! strncpy (header->header.arch_linkname, buf, NAMSIZ); ! header->header.arch_linkname[NAMSIZ - 1] = '\0'; header->header.linkflag = LF_SYMLINK; finish_header(header); /* Nothing more to do to it */ *************** *** 1200,1203 **** --- 1200,1204 ---- } } + current_file_name = name; strncpy(header->header.arch_name, name, NAMSIZ); header->header.arch_name[NAMSIZ-1] = '\0'; *************** *** 1345,1353 **** int bufsize; union record *header; ! /* Link name won't fit, so we write ! an LF_LONGLINK record. */ ! hstat.st_size = size; ! header = start_header ("././@LongLink", &hstat); header->header.linkflag = type; finish_header (header); --- 1346,1356 ---- int bufsize; union record *header; + struct stat foo; ! ! bzero (&foo, sizeof foo); ! foo.st_size = size; ! ! header = start_header ("././@LongLink", &foo); header->header.linkflag = type; finish_header (header); diff -rc2N tar-1.11/diffarch.c tar-1.11.1/diffarch.c *** tar-1.11/diffarch.c Tue Sep 8 16:12:15 1992 --- tar-1.11.1/diffarch.c Mon Sep 14 16:56:54 1992 *************** *** 52,56 **** #endif ! extern char *valloc(); extern union record *head; /* Points to current tape header */ --- 52,56 ---- #endif ! extern void *valloc(); extern union record *head; /* Points to current tape header */ diff -rc2N tar-1.11/extract.c tar-1.11.1/extract.c *** tar-1.11/extract.c Tue Sep 8 16:09:11 1992 --- tar-1.11.1/extract.c Tue Sep 15 19:54:58 1992 *************** *** 56,59 **** --- 56,65 ---- #if defined(_POSIX_VERSION) #include + #else + struct utimbuf + { + long actime; + long modtime; + }; #endif *************** *** 139,143 **** int fd, check, namelen, written, openflag; long size; ! time_t acc_upd_times[2]; register int skipcrud; register int i; --- 145,149 ---- int fd, check, namelen, written, openflag; long size; ! struct utimbuf acc_upd_times; register int skipcrud; register int i; *************** *** 294,298 **** goto extract_file; } ! #ifdef O_CTG /* * Contiguous files (on the Masscomp) have to specify --- 300,304 ---- goto extract_file; } ! #ifdef O_CTG /* * Contiguous files (on the Masscomp) have to specify *************** *** 305,311 **** hstat.st_mode, hstat.st_size); else ! #endif { ! #ifdef NO_OPEN3 /* * On raw V7 we won't let them specify -k (f_keep), but --- 311,317 ---- hstat.st_mode, hstat.st_size); else ! #endif { ! #ifdef NO_OPEN3 /* * On raw V7 we won't let them specify -k (f_keep), but *************** *** 316,320 **** : head->header.name) + skipcrud, hstat.st_mode); ! #else /* * With 3-arg open(), we can do this up right. --- 322,326 ---- : head->header.name) + skipcrud, hstat.st_mode); ! #else /* * With 3-arg open(), we can do this up right. *************** *** 322,326 **** fd = open(skipcrud + current_file_name, openflag, hstat.st_mode); ! #endif } --- 328,332 ---- fd = open(skipcrud + current_file_name, openflag, hstat.st_mode); ! #endif } *************** *** 483,491 **** /* fixme if f_gnudump should set ctime too, but how? */ if(f_gnudump) ! acc_upd_times[0]=hstat.st_atime; ! else acc_upd_times[0] = now; /* Accessed now */ ! acc_upd_times[1] = hstat.st_mtime; /* Mod'd */ if (utime(skipcrud + current_file_name, ! acc_upd_times) < 0) { msg_perror("couldn't change access and modification times of %s",skipcrud + current_file_name); } --- 489,498 ---- /* fixme if f_gnudump should set ctime too, but how? */ if(f_gnudump) ! acc_upd_times.actime=hstat.st_atime; ! else ! acc_upd_times.actime = now; /* Accessed now */ ! acc_upd_times.modtime = hstat.st_mtime; /* Mod'd */ if (utime(skipcrud + current_file_name, ! &acc_upd_times) < 0) { msg_perror("couldn't change access and modification times of %s",skipcrud + current_file_name); } *************** *** 793,797 **** void restore_saved_dir_info () { ! time_t acc_upd_times[2]; struct saved_dir_info *tmp; --- 800,804 ---- void restore_saved_dir_info () { ! struct utimbuf acc_upd_times; struct saved_dir_info *tmp; *************** *** 800,807 **** /* fixme if f_gnudump should set ctime too, but how? */ if(f_gnudump) ! acc_upd_times[0]=saved_dir_info_head -> atime; ! else acc_upd_times[0] = now; /* Accessed now */ ! acc_upd_times[1] = saved_dir_info_head -> mtime; /* Mod'd */ ! if (utime(saved_dir_info_head -> path, acc_upd_times) < 0) { msg_perror("couldn't change access and modification times of %s", saved_dir_info_head -> path); --- 807,815 ---- /* fixme if f_gnudump should set ctime too, but how? */ if(f_gnudump) ! acc_upd_times.actime=saved_dir_info_head -> atime; ! else ! acc_upd_times.actime = now; /* Accessed now */ ! acc_upd_times.modtime = saved_dir_info_head -> mtime; /* Mod'd */ ! if (utime(saved_dir_info_head -> path, &acc_upd_times) < 0) { msg_perror("couldn't change access and modification times of %s", saved_dir_info_head -> path); diff -rc2N tar-1.11/fnmatch.c tar-1.11.1/fnmatch.c *** tar-1.11/fnmatch.c --- tar-1.11.1/fnmatch.c Fri Sep 11 00:37:48 1992 *************** *** 0 **** --- 1,173 ---- + /* Copyright (C) 1991, 1992 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. If + not, write to the Free Software Foundation, Inc., 675 Mass Ave, + Cambridge, MA 02139, USA. */ + + #include + #include "fnmatch.h" + + #if !defined(__GNU_LIBRARY__) && !defined(STDC_HEADERS) + extern int errno; + #endif + + #if !__STDC__ + #define const + #endif + + /* Match STRING against the filename pattern PATTERN, returning zero if + it matches, nonzero if not. */ + int + fnmatch (pattern, string, flags) + const char *pattern; + const char *string; + int flags; + { + register const char *p = pattern, *n = string; + register char c; + + if ((flags & ~__FNM_FLAGS) != 0) + { + errno = EINVAL; + return -1; + } + + while ((c = *p++) != '\0') + { + switch (c) + { + case '?': + if (*n == '\0') + return FNM_NOMATCH; + else if ((flags & FNM_PATHNAME) && *n == '/') + return FNM_NOMATCH; + else if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) + return FNM_NOMATCH; + break; + + case '\\': + if (!(flags & FNM_NOESCAPE)) + c = *p++; + if (*n != c) + return FNM_NOMATCH; + break; + + case '*': + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) + if (((flags & FNM_PATHNAME) && *n == '/') || + (c == '?' && *n == '\0')) + return FNM_NOMATCH; + + if (c == '\0') + return 0; + + { + char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; + for (--p; *n != '\0'; ++n) + if ((c == '[' || *n == c1) && + fnmatch (p, n, flags & ~FNM_PERIOD) == 0) + return 0; + return FNM_NOMATCH; + } + + case '[': + { + /* Nonzero if the sense of the character class is inverted. */ + register int not; + + if (*n == '\0') + return FNM_NOMATCH; + + if ((flags & FNM_PERIOD) && *n == '.' && + (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) + return FNM_NOMATCH; + + not = (*p == '!' || *p == '^'); + if (not) + ++p; + + c = *p++; + for (;;) + { + register char cstart = c, cend = c; + + if (!(flags & FNM_NOESCAPE) && c == '\\') + cstart = cend = *p++; + + if (c == '\0') + /* [ (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + + if ((flags & FNM_PATHNAME) && c == '/') + /* [/] can never match. */ + return FNM_NOMATCH; + + if (c == '-' && *p != ']') + { + cend = *p++; + if (!(flags & FNM_NOESCAPE) && cend == '\\') + cend = *p++; + if (cend == '\0') + return FNM_NOMATCH; + c = *p++; + } + + if (*n >= cstart && *n <= cend) + goto matched; + + if (c == ']') + break; + } + if (!not) + return FNM_NOMATCH; + break; + + matched:; + /* Skip the rest of the [...] that already matched. */ + while (c != ']') + { + if (c == '\0') + /* [... (unterminated) loses. */ + return FNM_NOMATCH; + + c = *p++; + if (!(flags & FNM_NOESCAPE) && c == '\\') + /* 1003.2d11 is unclear if this is right. %%% */ + ++p; + } + if (not) + return FNM_NOMATCH; + } + break; + + default: + if (c != *n) + return FNM_NOMATCH; + } + + ++n; + } + + if (*n == '\0' || ((flags & FNM_TARPATH) && *n == '/')) + return 0; + + return FNM_NOMATCH; + } diff -rc2N tar-1.11/fnmatch.h tar-1.11.1/fnmatch.h *** tar-1.11/fnmatch.h --- tar-1.11.1/fnmatch.h Fri Sep 11 00:36:41 1992 *************** *** 0 **** --- 1,61 ---- + /* Copyright (C) 1991, 1992 Free Software Foundation, Inc. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; see the file COPYING.LIB. If + not, write to the Free Software Foundation, Inc., 675 Mass Ave, + Cambridge, MA 02139, USA. */ + + #ifndef _FNMATCH_H + + #define _FNMATCH_H 1 + + #ifdef __cplusplus + extern "C" + { + #endif + + #if defined (__cplusplus) || (defined (__STDC__) && __STDC__) + #undef __P + #define __P(args) args + #else /* Not C++ or ANSI C. */ + #undef __P + #define __P(args) () + #undef const + #define const + #endif /* C++ or ANSI C. */ + + /* Bits set in the FLAGS argument to `fnmatch'. */ + #define FNM_PATHNAME (1 << 0)/* No wildcard can ever match `/'. */ + #define FNM_NOESCAPE (1 << 1)/* Backslashes don't quote special chars. */ + #define FNM_PERIOD (1 << 2)/* Leading `.' is matched only explicitly. */ + #define FNM_TARPATH (1 << 4)/* Ignore `/...' after a match. */ + #define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD|FNM_TARPATH) + + #if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_BSD_SOURCE) + #define FNM_FILE_NAME FNM_PATHNAME + #endif + + /* Value returned by `fnmatch' if STRING does not match PATTERN. */ + #define FNM_NOMATCH 1 + + /* Match STRING against the filename pattern PATTERN, + returning zero if it matches, FNM_NOMATCH if not. */ + extern int fnmatch __P ((const char *__pattern, const char *__string, + int __flags)); + + #ifdef __cplusplus + } + + #endif + + #endif /* fnmatch.h */ diff -rc2N tar-1.11/getdate.y tar-1.11.1/getdate.y *** tar-1.11/getdate.y Tue Sep 1 17:57:48 1992 --- tar-1.11.1/getdate.y Mon Sep 14 16:41:02 1992 *************** *** 32,40 **** --- 32,53 ---- #include + /* The code at the top of get_date which figures out the offset of the + current time zone checks various CPP symbols to see if special + tricks are need, but defaults to using the gettimeofday system call. + Include if that will be used. */ + + #if !defined (USG) && !defined (sgi) && !defined (__386BSD__) + #include + #endif + #if defined(vms) + #include #include + #else + #include + #if defined(USG) || !defined(HAVE_FTIME) /* *************** *** 48,59 **** --- 61,80 ---- short dstflag; /* Field not used */ }; + #else + #include + #endif /* defined(USG) && !defined(HAVE_FTIME) */ + #if defined(BSD4_2) || defined(BSD4_1C) #include #else + #if defined(_AIX) + #include + #endif #include #endif /* defined(BSD4_2) */ + #endif /* defined(vms) */ *************** *** 851,855 **** ftz.timezone = 0; #else /* neither sgi nor 386BSD */ ! #ifdef USG extern time_t timezone; --- 872,876 ---- ftz.timezone = 0; #else /* neither sgi nor 386BSD */ ! #if defined (USG) extern time_t timezone; *************** *** 860,864 **** gettimeofday (&tv, &tz); ! ftz.timezone = (int) tz.tz_minuteswest / 60; #endif /* neither sgi nor 386BSD nor USG */ #endif /* neither sgi nor 386BSD */ --- 881,885 ---- gettimeofday (&tv, &tz); ! ftz.timezone = (int) tz.tz_minuteswest; #endif /* neither sgi nor 386BSD nor USG */ #endif /* neither sgi nor 386BSD */ diff -rc2N tar-1.11/getopt.h tar-1.11.1/getopt.h *** tar-1.11/getopt.h Tue Aug 18 17:33:49 1992 --- tar-1.11.1/getopt.h Fri Sep 11 10:41:55 1992 *************** *** 95,99 **** --- 95,106 ---- #if __STDC__ + #if defined(__GNU_LIBRARY__) + /* Many other libraries have conflicting prototypes for getopt, with + differences in the consts, in stdlib.h. To avoid compilation + errors, only prototype getopt for the GNU C library. */ extern int getopt (int argc, char *const *argv, const char *shortopts); + #else /* not __GNU_LIBRARY__ */ + extern int getopt (); + #endif /* not __GNU_LIBRARY__ */ extern int getopt_long (int argc, char *const *argv, const char *shortopts, const struct option *longopts, int *longind); diff -rc2N tar-1.11/getpagesize.h tar-1.11.1/getpagesize.h *** tar-1.11/getpagesize.h Thu Feb 19 16:15:35 1987 --- tar-1.11.1/getpagesize.h Tue Sep 15 20:13:03 1992 *************** *** 7,10 **** --- 7,18 ---- #ifndef HAVE_GETPAGESIZE + #ifdef _POSIX_VERSION + #include + #endif + + #ifdef _SC_PAGESIZE + #define getpagesize() sysconf(_SC_PAGESIZE) + #else + #include *************** *** 21,24 **** --- 29,33 ---- #endif /* no NBPG */ #endif /* no EXEC_PAGESIZE */ + #endif /* no _SC_PAGESIZE */ #endif /* not HAVE_GETPAGESIZE */ diff -rc2N tar-1.11/gnu.c tar-1.11.1/gnu.c *** tar-1.11/gnu.c Tue Sep 8 15:52:57 1992 --- tar-1.11.1/gnu.c Mon Sep 14 16:38:21 1992 *************** *** 127,133 **** if(gnu_dumpfile[0]!='/') { #if defined(__MSDOS__) || defined(USG) || defined(_POSIX_VERSION) ! if(!getcwd(path,PATH_MAX)) msg("Couldn't get current directory."); exit(EX_SYSTEM); #else char *getwd(); --- 127,134 ---- if(gnu_dumpfile[0]!='/') { #if defined(__MSDOS__) || defined(USG) || defined(_POSIX_VERSION) ! if(!getcwd(path,PATH_MAX)) { msg("Couldn't get current directory."); exit(EX_SYSTEM); + } #else char *getwd(); diff -rc2N tar-1.11/level-0 tar-1.11.1/level-0 *** tar-1.11/level-0 Wed Sep 9 14:14:52 1992 --- tar-1.11.1/level-0 Thu Sep 10 06:09:01 1992 *************** *** 48,52 **** 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 --volno-file=$VOLNO_FILE" --atime-preserve # Make sure the log file did not already exist. Create it. --- 48,52 ---- 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 --volno-file=$VOLNO_FILE --atime-preserve" # Make sure the log file did not already exist. Create it. diff -rc2N tar-1.11/level-1 tar-1.11.1/level-1 *** tar-1.11/level-1 Wed Sep 9 14:15:02 1992 --- tar-1.11.1/level-1 Thu Sep 10 06:09:13 1992 *************** *** 44,48 **** 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 --volno-file=$VOLNO_FILE" --atime-preserve # Make sure the log file did not already exist. Create it. --- 44,48 ---- 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 --volno-file=$VOLNO_FILE --atime-preserve" # Make sure the log file did not already exist. Create it. diff -rc2N tar-1.11/list.c tar-1.11.1/list.c *** tar-1.11/list.c Tue Sep 8 16:22:38 1992 --- tar-1.11.1/list.c Mon Sep 14 17:04:03 1992 *************** *** 290,294 **** { register int i; ! register long sum, recsum; register char *p; register union record *header; --- 290,294 ---- { register int i; ! register long sum, signed_sum, recsum; register char *p; register union record *header; *************** *** 298,301 **** --- 298,302 ---- int size, written; static char *next_long_name, *next_long_link; + char *name; recurse: *************** *** 315,318 **** --- 316,320 ---- * e.g. V7. */ + signed_sum += *p; sum += 0xFF & *p++; } *************** *** 320,325 **** --- 322,331 ---- /* Adjust checksum to count the "chksum" field as blanks. */ for (i = sizeof(header->header.chksum); --i >= 0;) + { sum -= 0xFF & header->header.chksum[i]; + signed_sum -= (char) header->header.chksum[i]; + } sum += ' '* sizeof header->header.chksum; + signed_sum += ' ' * sizeof header->header.chksum; if (sum == 8*' ') { *************** *** 331,335 **** } ! if (sum != recsum) return 0; --- 337,341 ---- } ! if (sum != recsum && signed_sum != recsum) return 0; *************** *** 377,386 **** else { ! current_file_name = (next_long_name ! ? next_long_name ! : header->header.arch_name); ! current_link_name = (next_long_link ! ? next_long_link ! : header->header.arch_linkname); next_long_link = next_long_name = 0; return 1; --- 383,402 ---- else { ! name = (next_long_name ! ? next_long_name ! : head->header.arch_name); ! if (current_file_name) ! free (current_file_name); ! current_file_name = malloc (strlen (name) + 1); ! strcpy (current_file_name, name); ! ! name = (next_long_link ! ? next_long_link ! : head->header.arch_linkname); ! if (current_link_name) ! free (current_link_name); ! current_link_name = malloc (strlen (name) + 1); ! strcpy (current_link_name, name); ! next_long_link = next_long_name = 0; return 1; diff -rc2N tar-1.11/makefile.pc tar-1.11.1/makefile.pc *** tar-1.11/makefile.pc Sat Jul 27 22:29:06 1991 --- tar-1.11.1/makefile.pc Fri Sep 11 01:03:40 1992 *************** *** 31,35 **** OBJ1 = tar.obj create.obj extract.obj buffer.obj getoldopt.obj update.obj gnu.obj mangle.obj ! OBJ2 = version.obj list.obj names.obj diffarch.obj port.obj wildmat.obj getopt.obj OBJ3 = getopt1.obj regex.obj getdate.obj alloca.obj tcexparg.obj msd_dir.obj OBJS = $(OBJ1) $(OBJ2) $(OBJ3) --- 31,35 ---- OBJ1 = tar.obj create.obj extract.obj buffer.obj getoldopt.obj update.obj gnu.obj mangle.obj ! OBJ2 = version.obj list.obj names.obj diffarch.obj port.obj fnmatch.obj getopt.obj OBJ3 = getopt1.obj regex.obj getdate.obj alloca.obj tcexparg.obj msd_dir.obj OBJS = $(OBJ1) $(OBJ2) $(OBJ3) *************** *** 52,55 **** --- 52,57 ---- clean: $(RM) errs *.obj tar testpad testpad.h + + mostlyclean: clean distclean: clean diff -rc2N tar-1.11/malloc.c tar-1.11.1/malloc.c *** tar-1.11/malloc.c Wed Sep 9 03:26:28 1992 --- tar-1.11.1/malloc.c Tue Sep 15 00:57:33 1992 *************** *** 1,107 **** /* dynamic memory allocation for GNU. ! Copyright (C) 1985, 1987 Free Software Foundation, Inc. ! NO WARRANTY - BECAUSE THIS PROGRAM IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY - NO WARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT - WHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC, - RICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE THIS PROGRAM "AS IS" - WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, - BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY - AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE - DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR - CORRECTION. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M. - STALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY - WHO MAY MODIFY AND REDISTRIBUTE THIS PROGRAM AS PERMITTED BELOW, BE - LIABLE TO YOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR - OTHER SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE - USE OR INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR - DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR - A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) THIS - PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH - DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. - - GENERAL PUBLIC LICENSE TO COPY - - 1. You may copy and distribute verbatim copies of this source file - as you receive it, in any medium, provided that you conspicuously and - appropriately publish on each copy a valid copyright notice "Copyright - (C) 1985 Free Software Foundation, Inc."; and include following the - copyright notice a verbatim copy of the above disclaimer of warranty - and of this License. You may charge a distribution fee for the - physical act of transferring a copy. - - 2. You may modify your copy or copies of this source file or - any portion of it, and copy and distribute such modifications under - the terms of Paragraph 1 above, provided that you also do the following: - - a) cause the modified files to carry prominent notices stating - that you changed the files and the date of any change; and - - b) cause the whole of any work that you distribute or publish, - that in whole or in part contains or is a derivative of this - program or any part thereof, to be licensed at no charge to all - third parties on terms identical to those contained in this - License Agreement (except that you may choose to grant more extensive - warranty protection to some or all third parties, at your option). - - c) You may charge a distribution fee for the physical act of - transferring a copy, and you may at your option offer warranty - protection in exchange for a fee. - - Mere aggregation of another unrelated program with this program (or its - derivative) on a volume of a storage or distribution medium does not bring - the other program under the scope of these terms. - - 3. You may copy and distribute this program (or a portion or derivative - of it, under Paragraph 2) in object code or executable form under the terms - of Paragraphs 1 and 2 above provided that you also do one of the following: - - a) accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of - Paragraphs 1 and 2 above; or, - - b) accompany it with a written offer, valid for at least three - years, to give any third party free (except for a nominal - shipping charge) a complete machine-readable copy of the - corresponding source code, to be distributed under the terms of - Paragraphs 1 and 2 above; or, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form alone.) - - For an executable file, complete source code means all the source code for - all modules it contains; but, as a special exception, it need not include - source code for modules which are standard libraries that accompany the - operating system on which the executable file runs. - - 4. You may not copy, sublicense, distribute or transfer this program - except as expressly provided under this License Agreement. Any attempt - otherwise to copy, sublicense, distribute or transfer this program is void and - your rights to use the program under this License agreement shall be - automatically terminated. However, parties who have received computer - software programs from you with this License Agreement will not have - their licenses terminated so long as such parties remain in full compliance. - - 5. If you wish to incorporate parts of this program into other free - programs whose distribution conditions are different, write to the Free - Software Foundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet - worked out a simple rule that can be stated here, but we will often permit - this. We will be guided by the two goals of preserving the free status of - all derivatives of our free software and of promoting the sharing and reuse of - software. - - - In other words, you are welcome to use, share and improve this program. - You are forbidden to forbid anyone else to use, share and improve - what you give them. Help stamp out software-hoarding! */ - - /* * @(#)nmalloc.c 1 (Caltech) 2/21/82 --- 1,19 ---- /* dynamic memory allocation for GNU. ! Copyright (C) 1985, 1987, 1992 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. */ /* * @(#)nmalloc.c 1 (Caltech) 2/21/82 *************** *** 139,143 **** * nmalloc[i] is the difference between the number of mallocs and frees * for a given block size. ! #endif MSTATS */ --- 51,55 ---- * nmalloc[i] is the difference between the number of mallocs and frees * for a given block size. ! #endif */ diff -rc2N tar-1.11/mangle.c tar-1.11.1/mangle.c *** tar-1.11/mangle.c Wed Sep 2 15:31:50 1992 --- tar-1.11.1/mangle.c Tue Sep 15 20:20:47 1992 *************** *** 238,241 **** --- 238,242 ---- nam1end=index(nam1end,' '); } + *nam1end = '\0'; un_quote_string(nam1); un_quote_string(nam1end+4); diff -rc2N tar-1.11/names.c tar-1.11.1/names.c *** tar-1.11/names.c Tue Jul 16 01:45:05 1991 --- tar-1.11.1/names.c Tue Sep 15 19:58:17 1992 *************** *** 1,4 **** /* Look up user and/or group names. ! Copyright (C) 1988 Free Software Foundation This file is part of GNU Tar. --- 1,4 ---- /* Look up user and/or group names. ! Copyright (C) 1988, 1992 Free Software Foundation This file is part of GNU Tar. *************** *** 31,34 **** --- 31,35 ---- #ifndef NONAMES /* Whole module goes away if NONAMES defined. Otherwise... */ + #include #include #include *************** *** 59,63 **** --- 60,66 ---- { struct passwd *pw; + #ifndef HAVE_GETPWUID extern struct passwd *getpwuid (); + #endif if (uid != saveuid) { *************** *** 98,102 **** --- 101,107 ---- { struct group *gr; + #ifndef HAVE_GETGRGID extern struct group *getgrgid (); + #endif if (gid != savegid) { diff -rc2N tar-1.11/port.h tar-1.11.1/port.h *** tar-1.11/port.h Wed Sep 9 13:34:19 1992 --- tar-1.11.1/port.h Tue Sep 15 19:59:51 1992 *************** *** 99,102 **** --- 99,108 ---- #include #endif + #ifdef index + #undef index + #endif + #ifdef rindex + #undef rindex + #endif #define index strchr #define rindex strrchr diff -rc2N tar-1.11/regex.c tar-1.11.1/regex.c *** tar-1.11/regex.c Tue Aug 25 17:14:13 1992 --- tar-1.11.1/regex.c Fri Sep 11 00:57:41 1992 *************** *** 1,4 **** /* Extended regular expression matching and search library, ! version 0.9. (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) --- 1,4 ---- /* Extended regular expression matching and search library, ! version 0.10. (Implements POSIX draft P10003.2/D11.2, except for internationalization features.) *************** *** 27,33 **** #define _GNU_SOURCE ! /* POSIX.1 says that might need . We also need ! it for regex.h. And Emacs needs it in some cases, so unconditionally ! include it. */ #include --- 27,31 ---- #define _GNU_SOURCE ! /* We need this for `regex.h', and perhaps for the Emacs include files. */ #include *************** *** 46,69 **** #else /* not emacs */ ! #ifdef HAVE_UNISTD_H ! #include ! #endif ! ! #if defined (USG) || defined (POSIX) || defined (STDC_HEADERS) ! #ifndef BSTRING #include ! #define bcopy(s,d,n) memcpy ((d), (s), (n)) ! #define bcmp(s1,s2,n) memcmp ((s1), (s2), (n)) ! #define bzero(s,n) memset ((s), 0, (n)) ! #endif /* not BSTRING */ ! #endif /* USG or POSIX or STDC_HEADERS */ #ifdef STDC_HEADERS #include ! #else /* not STDC_HEADERS */ char *malloc (); char *realloc (); ! #endif /* not STDC_HEADERS */ /* Define the syntax stuff for \<, \>, etc. */ --- 44,66 ---- #else /* not emacs */ ! /* We used to test for `BSTRING' here, but only GCC and Emacs define ! `BSTRING', as far as I know, and neither of them use this code. */ ! #if USG || STDC_HEADERS #include ! #define bcmp(s1, s2, n) memcmp ((s1), (s2), (n)) ! #define bcopy(s, d, n) memcpy ((d), (s), (n)) ! #define bzero(s, n) memset ((s), 0, (n)) ! #else ! #include ! #endif #ifdef STDC_HEADERS #include ! #else char *malloc (); char *realloc (); ! #endif + /* Define the syntax stuff for \<, \>, etc. */ *************** *** 81,85 **** /* How many characters in the character set. */ ! #define CHAR_SET_SIZE 256 static char re_syntax_table[CHAR_SET_SIZE]; --- 78,82 ---- /* How many characters in the character set. */ ! #define CHAR_SET_SIZE 256 static char re_syntax_table[CHAR_SET_SIZE]; *************** *** 290,294 **** /* Like on_failure_jump, but pushes a placeholder instead of the ! current string position. */ on_failure_keep_string_jump, --- 287,291 ---- /* Like on_failure_jump, but pushes a placeholder instead of the ! current string position when executed. */ on_failure_keep_string_jump, *************** *** 317,332 **** push_dummy_failure, ! /* Used like on_failure_jump except has to succeed n times; The ! two-byte relative address following it is useless until then. ! The address is followed by two more bytes containing n. */ succeed_n, ! /* Similar to jump, but jump n times only; also the ! relative address following is in turn followed by yet two ! more bytes containing n. */ jump_n, ! /* Set the following relative location (two bytes) to the ! subsequent (two-byte) number. */ set_number_at, --- 314,328 ---- push_dummy_failure, ! /* Followed by two-byte relative address and two-byte number n. ! After matching N times, jump to the address upon failure. */ succeed_n, ! /* Followed by two-byte relative address, and two-byte number n. ! Jump to the address N times, then fail. */ jump_n, ! /* Set the following two-byte relative address to the ! subsequent two-byte number. The address *includes* the two ! bytes of number. */ set_number_at, *************** *** 397,401 **** #undef EXTRACT_NUMBER #define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) ! #endif #endif /* DEBUG */ --- 393,397 ---- #undef EXTRACT_NUMBER #define EXTRACT_NUMBER(dest, src) extract_number (&dest, src) ! #endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ *************** *** 422,428 **** #ifndef EXTRACT_MACROS #undef EXTRACT_NUMBER_AND_INCR ! #define EXTRACT_NUMBER_AND_INCR(dest, src) \ extract_number_and_incr (&dest, &src) ! #endif #endif /* DEBUG */ --- 418,424 ---- #ifndef EXTRACT_MACROS #undef EXTRACT_NUMBER_AND_INCR ! #define EXTRACT_NUMBER_AND_INCR(dest, src) \ extract_number_and_incr (&dest, &src) ! #endif /* not EXTRACT_MACROS */ #endif /* DEBUG */ *************** *** 707,711 **** printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated); ! if (bufp->fastmap_accurate) { printf ("fastmap: "); --- 703,707 ---- printf ("%d bytes used/%d bytes allocated.\n", bufp->used, bufp->allocated); ! if (bufp->fastmap_accurate && bufp->fastmap) { printf ("fastmap: "); *************** *** 716,725 **** printf ("regs_alloc: %d\t", bufp->regs_allocated); printf ("can_be_null: %d\t", bufp->can_be_null); ! printf ("syntax: %d\n", bufp->syntax); printf ("no_sub: %d\t", bufp->no_sub); printf ("not_bol: %d\t", bufp->not_bol); printf ("not_eol: %d\t", bufp->not_eol); ! printf ("newline_anchor: %d\n", bufp->newline_anchor); ! /* What about printing the translate table? */ } --- 712,721 ---- printf ("regs_alloc: %d\t", bufp->regs_allocated); printf ("can_be_null: %d\t", bufp->can_be_null); ! printf ("newline_anchor: %d\n", bufp->newline_anchor); printf ("no_sub: %d\t", bufp->no_sub); printf ("not_bol: %d\t", bufp->not_bol); printf ("not_eol: %d\t", bufp->not_eol); ! printf ("syntax: %d\n", bufp->syntax); ! /* Perhaps we should print the translate table? */ } *************** *** 766,773 **** #endif /* not DEBUG */ ! /* Set by re_set_syntax to the current regexp syntax to recognize. Can ! also be assigned to more or less arbitrarily. Since we use this as a ! collection of bits, declaring it unsigned maximizes portability. */ ! reg_syntax_t obscure_syntax = 0; --- 762,769 ---- #endif /* not DEBUG */ ! /* Set by `re_set_syntax' to the current regexp syntax to recognize. Can ! also be assigned to arbitrarily: each pattern buffer stores its own ! syntax, so it can be changed between regex compilations. */ ! reg_syntax_t re_syntax_options = RE_SYNTAX_EMACS; *************** *** 783,789 **** reg_syntax_t syntax; { ! reg_syntax_t ret = obscure_syntax; ! obscure_syntax = syntax; return ret; } --- 779,785 ---- reg_syntax_t syntax; { ! reg_syntax_t ret = re_syntax_options; ! re_syntax_options = syntax; return ret; } *************** *** 814,821 **** /* Subroutine declarations and macros for regex_compile. */ ! static void store_jump (), insert_jump (), store_jump_n (), ! insert_jump_n (), insert_op_2 (); ! static boolean at_endline_op_p (), group_in_compile_stack (); /* Fetch the next character in the uncompiled pattern---translating it --- 810,817 ---- /* Subroutine declarations and macros for regex_compile. */ ! static void store_op1 (), store_op2 (); ! static void insert_op1 (), insert_op2 (); static boolean at_endline_op_p (), group_in_compile_stack (); + static reg_errcode_t compile_range (); /* Fetch the next character in the uncompiled pattern---translating it *************** *** 858,862 **** /* Make sure we have one more byte of buffer space and then add C to it. */ ! #define PAT_PUSH(c) \ do { \ GET_BUFFER_SPACE (1); \ --- 854,858 ---- /* Make sure we have one more byte of buffer space and then add C to it. */ ! #define BUF_PUSH(c) \ do { \ GET_BUFFER_SPACE (1); \ *************** *** 866,870 **** /* Ensure we have two more bytes of buffer space and then append C1 and C2. */ ! #define PAT_PUSH_2(c1, c2) \ do { \ GET_BUFFER_SPACE (2); \ --- 862,866 ---- /* Ensure we have two more bytes of buffer space and then append C1 and C2. */ ! #define BUF_PUSH_2(c1, c2) \ do { \ GET_BUFFER_SPACE (2); \ *************** *** 874,879 **** ! /* As with PAT_PUSH_2, except for three bytes. */ ! #define PAT_PUSH_3(c1, c2, c3) \ do { \ GET_BUFFER_SPACE (3); \ --- 870,875 ---- ! /* As with BUF_PUSH_2, except for three bytes. */ ! #define BUF_PUSH_3(c1, c2, c3) \ do { \ GET_BUFFER_SPACE (3); \ *************** *** 884,890 **** ! /* This is not an arbitrary limit: the arguments to the opcodes which ! represent offsets into the pattern are two bytes long. So if 2^16 ! bytes turns out to be too small, many things would have to change. */ #define MAX_BUF_SIZE (1L << 16) --- 880,904 ---- ! /* Store a jump with opcode OP at LOC to location TO. We store a ! relative address offset by the three bytes the jump itself occupies. */ ! #define STORE_JUMP(op, loc, to) \ ! store_op1 (op, loc, (to) - (loc) - 3) ! ! /* Likewise, for a two-argument jump. */ ! #define STORE_JUMP2(op, loc, to, arg) \ ! store_op2 (op, loc, (to) - (loc) - 3, arg) ! ! /* Like `STORE_JUMP', but for inserting. Assume `b' is the buffer end. */ ! #define INSERT_JUMP(op, loc, to) \ ! insert_op1 (op, loc, (to) - (loc) - 3, b) ! ! /* Like `STORE_JUMP2', but for inserting. Assume `b' is the buffer end. */ ! #define INSERT_JUMP2(op, loc, to, arg) \ ! insert_op2 (op, loc, (to) - (loc) - 3, arg, b) ! ! ! /* This is not an arbitrary limit: the arguments which represent offsets ! into the pattern are two bytes long. So if 2^16 bytes turns out to ! be too small, many things would have to change. */ #define MAX_BUF_SIZE (1L << 16) *************** *** 964,968 **** /* Set the bit for character C in a list. */ ! #define SET_LIST_BIT(c) (b[(c) / BYTEWIDTH] |= 1 << ((c) % BYTEWIDTH)) --- 978,984 ---- /* Set the bit for character C in a list. */ ! #define SET_LIST_BIT(c) \ ! (b[((unsigned char) (c)) / BYTEWIDTH] \ ! |= 1 << (((unsigned char) c) % BYTEWIDTH)) *************** *** 984,1009 **** } - - /* Read the endpoint of a range from the uncompiled pattern and set the - corresponding bits in the compiled pattern. */ - - #define DO_RANGE \ - { \ - int end; \ - int this_char = ((const unsigned char *) p)[-2]; \ - \ - if (p == pend) \ - return REG_ERANGE; \ - PATFETCH (end); \ - if (syntax & RE_NO_EMPTY_RANGES && this_char > end) \ - return REG_ERANGE; \ - while (this_char <= end) \ - { \ - SET_LIST_BIT (TRANSLATE (this_char)); \ - this_char++; \ - } \ - } - - #define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ --- 1000,1003 ---- *************** *** 1016,1021 **** || STREQ (string, "cntrl") || STREQ (string, "blank")) ! /* regex_compile compiles PATTERN (of length SIZE) according to SYNTAX. ! Returns one of error codes defined in regex.h, or zero for success. Assumes the `allocated' (and perhaps `buffer') and `translate' --- 1010,1015 ---- || STREQ (string, "cntrl") || STREQ (string, "blank")) ! /* `regex_compile' compiles PATTERN (of length SIZE) according to SYNTAX. ! Returns one of error codes defined in `regex.h', or zero for success. Assumes the `allocated' (and perhaps `buffer') and `translate' *************** *** 1041,1045 **** --- 1035,1044 ---- struct re_pattern_buffer *bufp; { + /* We fetch characters from PATTERN here. Even though PATTERN is + `char *' (i.e., signed), we declare these variables as unsigned, so + they can be reliably used as array indices. */ register unsigned char c, c1; + + /* A random tempory spot in PATTERN. */ const char *p1; *************** *** 1068,1079 **** unsigned char *laststart = 0; - /* Place in the uncompiled pattern (i.e., the {) to - which to go back if the interval is invalid. */ - const char *beg_interval; /* The `{'. */ - const char *following_left_brace; - /* Address of beginning of regexp, or inside of last group. */ unsigned char *begalt; ! /* Address of the place where a forward jump should go to the end of the containing expression. Each alternative of an `or' -- except the --- 1067,1077 ---- unsigned char *laststart = 0; /* Address of beginning of regexp, or inside of last group. */ unsigned char *begalt; ! ! /* Place in the uncompiled pattern (i.e., the {) to ! which to go back if the interval is invalid. */ ! const char *beg_interval; ! /* Address of the place where a forward jump should go to the end of the containing expression. Each alternative of an `or' -- except the *************** *** 1127,1133 **** { if (bufp->buffer) ! { /* EXTEND_BUFFER loses when bufp->allocated is 0. This loses if ! buffer's address is bogus, but that is the user's ! responsibility. */ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); } --- 1125,1131 ---- { if (bufp->buffer) ! { /* If zero allocated, but buffer is non-null, try to realloc ! enough space. This loses if buffer's address is bogus, but ! that is the user's responsibility. */ RETALLOC (bufp->buffer, INIT_BUF_SIZE, unsigned char); } *************** *** 1168,1172 **** least one byte before the ^.) */ || (!(syntax & RE_NEWLINE_ORDINARY) && p[-2] == '\n')) ! PAT_PUSH (begline); else goto normal_char; --- 1166,1170 ---- least one byte before the ^.) */ || (!(syntax & RE_NEWLINE_ORDINARY) && p[-2] == '\n')) ! BUF_PUSH (begline); else goto normal_char; *************** *** 1185,1189 **** /* Otherwise, depends on what's next. */ || at_endline_op_p (p, pend, syntax)) ! PAT_PUSH (endline); else goto normal_char; --- 1183,1187 ---- /* Otherwise, depends on what's next. */ || at_endline_op_p (p, pend, syntax)) ! BUF_PUSH (endline); else goto normal_char; *************** *** 1277,1281 **** assert (p - 1 > pattern); ! /* Get the space for the jump. */ GET_BUFFER_SPACE (3); --- 1275,1279 ---- assert (p - 1 > pattern); ! /* Allocate the space for the jump. */ GET_BUFFER_SPACE (3); *************** *** 1289,1293 **** && !(syntax & RE_DOT_NEWLINE)) { /* We have .*\n. */ ! store_jump (b, jump, laststart); keep_string_p = true; } --- 1287,1291 ---- && !(syntax & RE_DOT_NEWLINE)) { /* We have .*\n. */ ! STORE_JUMP (jump, b, laststart); keep_string_p = true; } *************** *** 1294,1298 **** else /* Anything else. */ ! store_jump (b, maybe_pop_jump, laststart - 3); /* We've added more stuff to the buffer. */ --- 1292,1296 ---- else /* Anything else. */ ! STORE_JUMP (maybe_pop_jump, b, laststart - 3); /* We've added more stuff to the buffer. */ *************** *** 1303,1309 **** end of the buffer after this jump is inserted. */ GET_BUFFER_SPACE (3); ! insert_jump (keep_string_p ? on_failure_keep_string_jump : on_failure_jump, ! laststart, b + 3, b); pending_exact = 0; b += 3; --- 1301,1307 ---- end of the buffer after this jump is inserted. */ GET_BUFFER_SPACE (3); ! INSERT_JUMP (keep_string_p ? on_failure_keep_string_jump : on_failure_jump, ! laststart, b + 3); pending_exact = 0; b += 3; *************** *** 1317,1321 **** we hit that loop. */ GET_BUFFER_SPACE (3); ! insert_jump (dummy_failure_jump, laststart, laststart + 6, b); b += 3; } --- 1315,1319 ---- we hit that loop. */ GET_BUFFER_SPACE (3); ! INSERT_JUMP (dummy_failure_jump, laststart, laststart + 6); b += 3; } *************** *** 1326,1330 **** case '.': laststart = b; ! PAT_PUSH (anychar); break; --- 1324,1328 ---- case '.': laststart = b; ! BUF_PUSH (anychar); break; *************** *** 1332,1348 **** case '[': { ! boolean just_had_a_char_class = false; if (p == pend) return REG_EBRACK; ! /* Ensure that we have enough space to push an entire ! charset: the opcode, the byte count, and the bitmap. */ ! while (b - bufp->buffer + 2 + (1 << BYTEWIDTH) / BYTEWIDTH ! > bufp->allocated) ! EXTEND_BUFFER (); laststart = b; ! PAT_PUSH (*p == '^' ? charset_not : charset); if (*p == '^') p++; --- 1330,1346 ---- case '[': { ! boolean had_char_class = false; if (p == pend) return REG_EBRACK; ! /* Ensure that we have enough space to push a charset: the ! opcode, the length count, and the bitset; 34 bytes in all. */ ! GET_BUFFER_SPACE (34); laststart = b; ! /* We test `*p == '^' twice, instead of using an if ! statement, so we only need one BUF_PUSH. */ ! BUF_PUSH (*p == '^' ? charset_not : charset); if (*p == '^') p++; *************** *** 1352,1356 **** /* Push the number of bytes in the bitmap. */ ! PAT_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); /* Clear the whole map. */ --- 1350,1354 ---- /* Push the number of bytes in the bitmap. */ ! BUF_PUSH ((1 << BYTEWIDTH) / BYTEWIDTH); /* Clear the whole map. */ *************** *** 1387,1391 **** /* Look ahead to see if it's a range when the last thing was a character class. */ ! if (just_had_a_char_class && c == '-' && *p != ']') return REG_ERANGE; --- 1385,1389 ---- /* Look ahead to see if it's a range when the last thing was a character class. */ ! if (had_char_class && c == '-' && *p != ']') return REG_ERANGE; *************** *** 1399,1403 **** && *p != ']') { ! DO_RANGE; } --- 1397,1403 ---- && *p != ']') { ! reg_errcode_t ret ! = compile_range (&p, pend, translate, syntax, b); ! if (ret != REG_NOERROR) return ret; } *************** *** 1404,1409 **** else if (p[0] == '-' && p[1] != ']') { /* This handles ranges made up of characters only. */ ! PATFETCH (c1); /* The `-'. */ ! DO_RANGE; } --- 1404,1414 ---- else if (p[0] == '-' && p[1] != ']') { /* This handles ranges made up of characters only. */ ! reg_errcode_t ret; ! ! /* Move past the `-'. */ ! PATFETCH (c1); ! ! ret = compile_range (&p, pend, translate, syntax, b); ! if (ret != REG_NOERROR) return ret; } *************** *** 1474,1478 **** SET_LIST_BIT (ch); } ! just_had_a_char_class = true; } else --- 1479,1483 ---- SET_LIST_BIT (ch); } ! had_char_class = true; } else *************** *** 1483,1487 **** SET_LIST_BIT ('['); SET_LIST_BIT (':'); ! just_had_a_char_class = false; } } --- 1488,1492 ---- SET_LIST_BIT ('['); SET_LIST_BIT (':'); ! had_char_class = false; } } *************** *** 1488,1492 **** else { ! just_had_a_char_class = false; SET_LIST_BIT (c); } --- 1493,1497 ---- else { ! had_char_class = false; SET_LIST_BIT (c); } *************** *** 1518,1522 **** case '\n': if (syntax & RE_NEWLINE_ALT) ! goto handle_bar; else goto normal_char; --- 1523,1527 ---- case '\n': if (syntax & RE_NEWLINE_ALT) ! goto handle_alt; else goto normal_char; *************** *** 1525,1529 **** case '|': if (syntax & RE_NO_BK_VBAR) ! goto handle_bar; else goto normal_char; --- 1530,1534 ---- case '|': if (syntax & RE_NO_BK_VBAR) ! goto handle_alt; else goto normal_char; *************** *** 1589,1593 **** { COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; ! PAT_PUSH_3 (start_memory, regnum, 0); } --- 1594,1598 ---- { COMPILE_STACK_TOP.inner_group_offset = b - bufp->buffer + 2; ! BUF_PUSH_3 (start_memory, regnum, 0); } *************** *** 1613,1620 **** { /* Push a dummy failure point at the end of the alternative for a possible future ! pop_failure_jump to pop. See comments at `push_dummy_failure' in `re_match_2'. */ ! PAT_PUSH (push_dummy_failure); ! store_jump (fixup_alt_jump, jump_past_alt, b - 1); } --- 1618,1628 ---- { /* Push a dummy failure point at the end of the alternative for a possible future ! `pop_failure_jump' to pop. See comments at `push_dummy_failure' in `re_match_2'. */ ! BUF_PUSH (push_dummy_failure); ! ! /* We allocated space for this jump when we assigned ! to `fixup_alt_jump', in the `handle_alt' case below. */ ! STORE_JUMP (jump_past_alt, fixup_alt_jump, b - 1); } *************** *** 1652,1656 **** *inner_group_loc = regnum - this_group_regnum; ! PAT_PUSH_3 (stop_memory, this_group_regnum, regnum - this_group_regnum); } --- 1660,1664 ---- *inner_group_loc = regnum - this_group_regnum; ! BUF_PUSH_3 (stop_memory, this_group_regnum, regnum - this_group_regnum); } *************** *** 1662,1669 **** if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) goto normal_backslash; ! handle_bar: if (syntax & RE_LIMITED_OPS) goto normal_char; /* Disallow empty alternatives if RE_NO_EMPTY_ALTS is set. Caveat: can't detect if the vbar is followed by a --- 1670,1679 ---- if (syntax & RE_LIMITED_OPS || syntax & RE_NO_BK_VBAR) goto normal_backslash; ! handle_alt: if (syntax & RE_LIMITED_OPS) goto normal_char; + #if 0 + /* Nobody needs to disallow empty alternatives any more. */ /* Disallow empty alternatives if RE_NO_EMPTY_ALTS is set. Caveat: can't detect if the vbar is followed by a *************** *** 1672,1676 **** the rest. */ if ((syntax & RE_NO_EMPTY_ALTS) ! && (!laststart || p == pend || (*p == '$' && p + 1 == pend) || ((syntax & RE_NO_BK_PARENS) --- 1682,1687 ---- the rest. */ if ((syntax & RE_NO_EMPTY_ALTS) ! && (!laststart ! || p == pend || (*p == '$' && p + 1 == pend) || ((syntax & RE_NO_BK_PARENS) *************** *** 1678,1681 **** --- 1689,1693 ---- : (p + 1 < pend && p[0] == '\\' && p[1] == ')')))) return REG_BADPAT; + #endif /* Insert before the previous alternative a jump which *************** *** 1682,1686 **** jumps to this alternative if the former fails. */ GET_BUFFER_SPACE (3); ! insert_jump (on_failure_jump, begalt, b + 6, b); pending_exact = 0; b += 3; --- 1694,1698 ---- jumps to this alternative if the former fails. */ GET_BUFFER_SPACE (3); ! INSERT_JUMP (on_failure_jump, begalt, b + 6); pending_exact = 0; b += 3; *************** *** 1703,1707 **** if (fixup_alt_jump) ! store_jump (fixup_alt_jump, jump_past_alt, b); /* Mark and leave space for a jump after this alternative, --- 1715,1719 ---- if (fixup_alt_jump) ! STORE_JUMP (jump_past_alt, fixup_alt_jump, b); /* Mark and leave space for a jump after this alternative, *************** *** 1728,1739 **** handle_interval: { ! /* If got here, then intervals must be allowed. */ ! /* For intervals, at least (most) this many matches must ! be made. */ int lower_bound = -1, upper_bound = -1; ! beg_interval = p - 1; /* The `{'. */ ! following_left_brace = NULL; if (p == pend) --- 1740,1749 ---- handle_interval: { ! /* If got here, then the syntax allows intervals. */ ! /* At least (most) this many matches must be made. */ int lower_bound = -1, upper_bound = -1; ! beg_interval = p - 1; if (p == pend) *************** *** 1752,1757 **** if (upper_bound < 0) upper_bound = RE_DUP_MAX; } ! ! if (upper_bound < 0) upper_bound = lower_bound; --- 1762,1767 ---- if (upper_bound < 0) upper_bound = RE_DUP_MAX; } ! else ! /* Interval such as `{1}' => match exactly once. */ upper_bound = lower_bound; *************** *** 1793,1860 **** } ! /* If upper_bound is zero, don't want to succeed at all; ! jump from laststart to b + 3, which will be the end of ! the buffer after this jump is inserted. */ if (upper_bound == 0) { GET_BUFFER_SPACE (3); ! insert_jump (jump, laststart, b + 3, b); b += 3; } ! /* Otherwise, after lower_bound number of succeeds, jump ! to after the jump_n which will be inserted at ! the end of the buffer, and insert that ! jump_n. */ else ! { /* Set to 5 if only one repetition is allowed and ! hence no jump_n is inserted at the current ! end of the buffer. Otherwise, need 10 bytes total ! for the succeed_n and the jump_n. */ ! unsigned slots_needed = upper_bound == 1 ? 5 : 10; ! ! GET_BUFFER_SPACE (slots_needed); ! /* Initialize the succeed_n to n, even though it will ! be set by its attendant set_number_at, because ! re_compile_fastmap will need to know it. Jump to ! what the end of buffer will be after inserting ! this succeed_n and possibly appending a ! jump_n. */ ! insert_jump_n (succeed_n, laststart, b + slots_needed, ! b, lower_bound); ! b += 5; /* Just increment for the succeed_n here. */ ! ! ! /* More than one repetition is allowed, so put in at ! the end of the buffer a backward jump from b to the ! succeed_n we put in above. By the time we've gotten ! to this jump when matching, we'll have matched once ! already, so jump back only upper_bound - 1 times. */ if (upper_bound > 1) ! { ! store_jump_n (b, jump_n, laststart, ! upper_bound - 1); b += 5; ! /* When hit this when matching, reset the ! preceding jump_n's n to upper_bound - 1. */ ! PAT_PUSH (set_number_at); ! ! /* Only need to get space for the numbers. */ ! GET_BUFFER_SPACE (4); ! STORE_NUMBER_AND_INCR (b, -5); ! STORE_NUMBER_AND_INCR (b, upper_bound - 1); } - - /* When hit this when matching, set the succeed_n's n. */ - GET_BUFFER_SPACE (5); - insert_op_2 (set_number_at, laststart, b, 5, lower_bound); - b += 5; } pending_exact = 0; beg_interval = NULL; - - if (following_left_brace) - goto normal_char; } break; --- 1803,1882 ---- } ! /* If the upper bound is zero, don't want to succeed at ! all; jump from `laststart' to `b + 3', which will be ! the end of the buffer after we insert the jump. */ if (upper_bound == 0) { GET_BUFFER_SPACE (3); ! INSERT_JUMP (jump, laststart, b + 3); b += 3; } ! /* Otherwise, we have a nontrivial interval. When ! we're all done, the pattern will look like: ! set_number_at ! set_number_at ! succeed_n ! ! jump_n ! (The upper bound and `jump_n' are omitted if ! `upper_bound' is 1, though.) */ else ! { /* If the upper bound is > 1, we need to insert ! more at the end of the loop. */ ! unsigned nbytes = 10 + (upper_bound > 1) * 10; ! ! GET_BUFFER_SPACE (nbytes); ! ! /* Initialize lower bound of the `succeed_n', even ! though it will be set during matching by its ! attendant `set_number_at' (inserted next), ! because `re_compile_fastmap' needs to know. ! Jump to the `jump_n' we might insert below. */ ! INSERT_JUMP2 (succeed_n, laststart, ! b + 5 + (upper_bound > 1) * 5, ! lower_bound); ! b += 5; ! ! /* Code to initialize the lower bound. Insert ! before the `succeed_n'. The `5' is the last two ! bytes of this `set_number_at', plus 3 bytes of ! the following `succeed_n'. */ ! insert_op2 (set_number_at, laststart, 5, lower_bound, b); ! b += 5; ! if (upper_bound > 1) ! { /* More than one repetition is allowed, so ! append a backward jump to the `succeed_n' ! that starts this interval. ! ! When we've reached this during matching, ! we'll have matched the interval once, so ! jump back only `upper_bound - 1' times. */ ! STORE_JUMP2 (jump_n, b, laststart + 5, ! upper_bound - 1); b += 5; ! /* The location we want to set is the second ! parameter of the `jump_n'; that is `b-2' as ! an absolute address. `laststart' will be ! the `set_number_at' we're about to insert; ! `laststart+3' the number to set, the source ! for the relative address. But we are ! inserting into the middle of the pattern -- ! so everything is getting moved up by 5. ! Conclusion: (b - 2) - (laststart + 3) + 5, ! i.e., b - laststart. ! ! We insert this at the beginning of the loop ! so that if we fail during matching, we'll ! reinitialize the bounds. */ ! insert_op2 (set_number_at, laststart, b - laststart, ! upper_bound - 1, b); ! b += 5; } } pending_exact = 0; beg_interval = NULL; } break; *************** *** 1880,1884 **** operators. rms says this is ok. --karl */ case '=': ! PAT_PUSH (at_dot); break; --- 1902,1906 ---- operators. rms says this is ok. --karl */ case '=': ! BUF_PUSH (at_dot); break; *************** *** 1886,1890 **** laststart = b; PATFETCH (c); ! PAT_PUSH_2 (syntaxspec, syntax_spec_code[c]); break; --- 1908,1912 ---- laststart = b; PATFETCH (c); ! BUF_PUSH_2 (syntaxspec, syntax_spec_code[c]); break; *************** *** 1892,1896 **** laststart = b; PATFETCH (c); ! PAT_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); break; #endif /* emacs */ --- 1914,1918 ---- laststart = b; PATFETCH (c); ! BUF_PUSH_2 (notsyntaxspec, syntax_spec_code[c]); break; #endif /* emacs */ *************** *** 1899,1903 **** case 'w': laststart = b; ! PAT_PUSH (wordchar); break; --- 1921,1925 ---- case 'w': laststart = b; ! BUF_PUSH (wordchar); break; *************** *** 1905,1909 **** case 'W': laststart = b; ! PAT_PUSH (notwordchar); break; --- 1927,1931 ---- case 'W': laststart = b; ! BUF_PUSH (notwordchar); break; *************** *** 1910,1934 **** case '<': ! PAT_PUSH (wordbeg); break; case '>': ! PAT_PUSH (wordend); break; case 'b': ! PAT_PUSH (wordbound); break; case 'B': ! PAT_PUSH (notwordbound); break; case '`': ! PAT_PUSH (begbuf); break; case '\'': ! PAT_PUSH (endbuf); break; --- 1932,1956 ---- case '<': ! BUF_PUSH (wordbeg); break; case '>': ! BUF_PUSH (wordend); break; case 'b': ! BUF_PUSH (wordbound); break; case 'B': ! BUF_PUSH (notwordbound); break; case '`': ! BUF_PUSH (begbuf); break; case '\'': ! BUF_PUSH (endbuf); break; *************** *** 1960,1964 **** laststart = b; ! PAT_PUSH_2 (duplicate, c1); break; --- 1982,1986 ---- laststart = b; ! BUF_PUSH_2 (duplicate, c1); break; *************** *** 2008,2016 **** laststart = b; ! PAT_PUSH_2 (exactn, 0); pending_exact = b - 1; } ! PAT_PUSH (c); (*pending_exact)++; break; --- 2030,2038 ---- laststart = b; ! BUF_PUSH_2 (exactn, 0); pending_exact = b - 1; } ! BUF_PUSH (c); (*pending_exact)++; break; *************** *** 2022,2026 **** if (fixup_alt_jump) ! store_jump (fixup_alt_jump, jump_past_alt, b); if (!COMPILE_STACK_EMPTY) --- 2044,2048 ---- if (fixup_alt_jump) ! STORE_JUMP (jump_past_alt, fixup_alt_jump, b); if (!COMPILE_STACK_EMPTY) *************** *** 2043,2148 **** } /* regex_compile */ ! /* Subroutines for regex_compile. */ ! ! /* Store a jump of the form . ! Store in the location FROM a jump operation to jump to relative ! address FROM - TO. OPCODE is the opcode to store. */ ! ! static void ! store_jump (from, op, to) ! unsigned char *from, *to; ! re_opcode_t op; ! { ! from[0] = (unsigned char) op; ! STORE_NUMBER (from + 1, to - (from + 3)); ! } ! ! ! /* Open up space before char FROM, and insert a jump to TO. ! CURRENT_END gives the end of the storage not in use, so we know ! how much data to copy up. OP is the opcode of the jump to insert. ! If you call this function, you must zero out pending_exact. */ static void ! insert_jump (op, from, to, current_end) ! re_opcode_t op; ! unsigned char *from, *to, *current_end; { ! register unsigned char *pfrom = current_end; /* Copy from here... */ ! register unsigned char *pto = current_end + 3; /* ...to here. */ ! ! while (pfrom != from) ! *--pto = *--pfrom; ! ! store_jump (from, op, to); } ! /* Store a jump of the form . ! ! Store in the location FROM a jump operation to jump to relative ! address FROM - TO. OPCODE is the opcode to store, N is a number the ! jump uses, say, to decide how many times to jump. ! ! If you call this function, you must zero out pending_exact. */ static void ! store_jump_n (from, op, to, n) ! unsigned char *from, *to; ! re_opcode_t op; ! unsigned n; { ! from[0] = (unsigned char) op; ! STORE_NUMBER (from + 1, to - (from + 3)); ! STORE_NUMBER (from + 3, n); } ! /* Similar to insert_jump, but handles a jump which needs an extra ! number to handle minimum and maximum cases. Open up space at ! location FROM, and insert there a jump to TO. CURRENT_END gives the ! end of the storage in use, so we know how much data to copy up. OP is ! the opcode of the jump to insert. - If you call this function, you must zero out pending_exact. */ - static void ! insert_jump_n (op, from, to, current_end, n) ! re_opcode_t op; ! unsigned char *from, *to, *current_end; ! unsigned n; { ! register unsigned char *pfrom = current_end; ! register unsigned char *pto = current_end + 5; ! while (pfrom != from) *--pto = *--pfrom; ! store_jump_n (from, op, to, n); } ! /* Open up space at location THERE, and insert operation OP followed by ! NUM_1 and NUM_2. CURRENT_END gives the end of the storage in use, so ! we know how much data to copy up. ! ! If you call this function, you must zero out pending_exact. */ static void ! insert_op_2 (op, there, current_end, num_1, num_2) ! re_opcode_t op; ! unsigned char *there, *current_end; ! int num_1, num_2; { ! register unsigned char *pfrom = current_end; ! register unsigned char *pto = current_end + 5; ! while (pfrom != there) *--pto = *--pfrom; ! ! there[0] = (unsigned char) op; ! STORE_NUMBER (there + 1, num_1); ! STORE_NUMBER (there + 3, num_2); } --- 2065,2133 ---- } /* regex_compile */ ! /* Subroutines for `regex_compile'. */ ! /* Store OP at LOC followed by two-byte integer parameter ARG. */ static void ! store_op1 (op, loc, arg) ! re_opcode_t op; ! unsigned char *loc; ! int arg; { ! *loc = (unsigned char) op; ! STORE_NUMBER (loc + 1, arg); } ! /* Like `store_op1', but for two two-byte parameters ARG1 and ARG2. */ static void ! store_op2 (op, loc, arg1, arg2) ! re_opcode_t op; ! unsigned char *loc; ! int arg1, arg2; { ! *loc = (unsigned char) op; ! STORE_NUMBER (loc + 1, arg1); ! STORE_NUMBER (loc + 3, arg2); } ! /* Copy the bytes from LOC to END to open up three bytes of space at LOC ! for OP followed by two-byte integer parameter ARG. */ static void ! insert_op1 (op, loc, arg, end) ! re_opcode_t op; ! unsigned char *loc; ! int arg; ! unsigned char *end; { ! register unsigned char *pfrom = end; ! register unsigned char *pto = end + 3; ! while (pfrom != loc) *--pto = *--pfrom; ! store_op1 (op, loc, arg); } ! /* Like `insert_op1', but for two two-byte parameters ARG1 and ARG2. */ static void ! insert_op2 (op, loc, arg1, arg2, end) ! re_opcode_t op; ! unsigned char *loc; ! int arg1, arg2; ! unsigned char *end; { ! register unsigned char *pfrom = end; ! register unsigned char *pto = end + 5; ! while (pfrom != loc) *--pto = *--pfrom; ! ! store_op2 (op, loc, arg1, arg2); } *************** *** 2224,2227 **** --- 2209,2267 ---- return false; } + + + /* Read the ending character of a range (in a bracket expression) from the + uncompiled pattern *P_PTR (which ends at PEND). We assume the + starting character is in `P[-2]'. (`P[-1]' is the character `-'.) + Then we set the translation of all bits between the starting and + ending characters (inclusive) in the compiled pattern B. + + Return an error code. + + We use these short variable names so we can use the same macros as + `regex_compile' itself. */ + + static reg_errcode_t + compile_range (p_ptr, pend, translate, syntax, b) + const char **p_ptr, *pend; + char *translate; + reg_syntax_t syntax; + unsigned char *b; + { + unsigned this_char; + + const char *p = *p_ptr; + + /* Even though the pattern is a signed `char *', we need to fetch into + `unsigned char's. Reason: if the high bit of the pattern character + is set, the range endpoints will be negative if we fetch into a + signed `char *'. */ + unsigned char range_end; + unsigned char range_start = p[-2]; + + if (p == pend) + return REG_ERANGE; + + PATFETCH (range_end); + + /* Have to increment the pointer into the pattern string, so the + caller isn't still at the ending character. */ + (*p_ptr)++; + + /* If the start is after the end, the range is empty. */ + if (range_start > range_end) + return syntax & RE_NO_EMPTY_RANGES ? REG_ERANGE : REG_NOERROR; + + /* Here we see why `this_char' has to be larger than an `unsigned + char' -- the range is inclusive, so if `range_end' == 0xff + (assuming 8-bit characters), we would otherwise go into an infinite + loop, since all characters <= 0xff. */ + for (this_char = range_start; this_char <= range_end; this_char++) + { + SET_LIST_BIT (TRANSLATE (this_char)); + } + + return REG_NOERROR; + } /* Failure stack declarations and macros; both re_compile_fastmap and *************** *** 2385,2389 **** } \ \ ! DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ PUSH_FAILURE_ITEM (lowest_active_reg); \ \ --- 2425,2429 ---- } \ \ ! DEBUG_PRINT2 (" Pushing low active reg: %d\n", lowest_active_reg);\ PUSH_FAILURE_ITEM (lowest_active_reg); \ \ *************** *** 2637,2640 **** --- 2677,2681 ---- case on_failure_jump: + case on_failure_keep_string_jump: handle_on_failure_jump: EXTRACT_NUMBER_AND_INCR (j, p); *************** *** 3000,3005 **** Assumes `string1' exists, so use in conjunction with AT_STRINGS_BEG (). */ #define LETTER_P(d) \ ! (SYNTAX ((d) == end1 ? *string2 : (d) == string2 - 1 ? *(end1 - 1) : *(d))\ ! == Sword) /* Test if the character before D and the one at D differ with respect --- 3041,3046 ---- Assumes `string1' exists, so use in conjunction with AT_STRINGS_BEG (). */ #define LETTER_P(d) \ ! (SYNTAX ((d) == end1 ? *string2 \ ! : (d) == string2 - 1 ? *(end1 - 1) : *(d)) == Sword) /* Test if the character before D and the one at D differ with respect *************** *** 3011,3032 **** /* Free everything we malloc. */ #ifdef REGEX_MALLOC ! #define FREE_NONNULL(var) if (var) free (var) #define FREE_VARIABLES() \ do { \ ! FREE_NONNULL (fail_stack.stack); \ ! FREE_NONNULL (regstart); \ ! FREE_NONNULL (regend); \ ! FREE_NONNULL (old_regstart); \ ! FREE_NONNULL (old_regend); \ ! FREE_NONNULL (reg_info); \ ! FREE_NONNULL (best_regstart); \ ! FREE_NONNULL (best_regend); \ ! reg_info = NULL; \ ! fail_stack.stack = NULL; \ ! regstart = regend = old_regstart = old_regend \ ! = best_regstart = best_regend = NULL; \ } while (0) #else /* not REGEX_MALLOC */ ! #define FREE_VARIABLES() /* As nothing, since we use alloca. */ #endif /* not REGEX_MALLOC */ --- 3052,3071 ---- /* Free everything we malloc. */ #ifdef REGEX_MALLOC ! #define FREE_VAR(var) if (var) free (var); var = NULL #define FREE_VARIABLES() \ do { \ ! FREE_VAR (fail_stack.stack); \ ! FREE_VAR (regstart); \ ! FREE_VAR (regend); \ ! FREE_VAR (old_regstart); \ ! FREE_VAR (old_regend); \ ! FREE_VAR (best_regstart); \ ! FREE_VAR (best_regend); \ ! FREE_VAR (reg_info); \ ! FREE_VAR (reg_dummy); \ ! FREE_VAR (reg_info_dummy); \ } while (0) #else /* not REGEX_MALLOC */ ! #define FREE_VARIABLES() /* As nothing, since we are using alloca. */ #endif /* not REGEX_MALLOC */ *************** *** 3191,3197 **** old_regstart = REGEX_TALLOC (num_regs, const char *); old_regend = REGEX_TALLOC (num_regs, const char *); - reg_info = REGEX_TALLOC (num_regs, register_info_type); best_regstart = REGEX_TALLOC (num_regs, const char *); best_regend = REGEX_TALLOC (num_regs, const char *); reg_dummy = REGEX_TALLOC (num_regs, const char *); reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); --- 3230,3236 ---- old_regstart = REGEX_TALLOC (num_regs, const char *); old_regend = REGEX_TALLOC (num_regs, const char *); best_regstart = REGEX_TALLOC (num_regs, const char *); best_regend = REGEX_TALLOC (num_regs, const char *); + reg_info = REGEX_TALLOC (num_regs, register_info_type); reg_dummy = REGEX_TALLOC (num_regs, const char *); reg_info_dummy = REGEX_TALLOC (num_regs, register_info_type); *************** *** 3198,3202 **** if (!(regstart && regend && old_regstart && old_regend && reg_info ! && best_regstart && best_regend)) { FREE_VARIABLES (); --- 3237,3241 ---- if (!(regstart && regend && old_regstart && old_regend && reg_info ! && best_regstart && best_regend && reg_dummy && reg_info_dummy)) { FREE_VARIABLES (); *************** *** 3204,3207 **** --- 3243,3257 ---- } } + #ifdef REGEX_MALLOC + else + { + /* We must initialize all our variables to NULL, so that + `FREE_VARIABLES' doesn't try to free them. Too bad this isn't + Lisp, so we could have a list of variables. As it is, */ + regstart = regend = old_regstart = old_regend = best_regstart + = best_regend = reg_dummy = NULL; + reg_info = reg_info_dummy = (register_info_type *) NULL; + } + #endif /* REGEX_MALLOC */ /* The starting position is bogus. */ *************** *** 3301,3304 **** --- 3351,3356 ---- match_end = d; + DEBUG_PRINT1 ("\nSAVING match as best so far.\n"); + for (mcnt = 1; mcnt < num_regs; mcnt++) { *************** *** 3454,3458 **** ! /* Match anything but possibly a newline or a null. */ case anychar: DEBUG_PRINT1 ("EXECUTING anychar.\n"); --- 3506,3510 ---- ! /* Match any character except possibly a newline or a null. */ case anychar: DEBUG_PRINT1 ("EXECUTING anychar.\n"); *************** *** 3465,3468 **** --- 3517,3521 ---- SET_REGS_MATCHED (); + DEBUG_PRINT2 (" Matched `%d'.\n", *d); d++; break; *************** *** 3480,3484 **** c = TRANSLATE (*d); /* The character to match. */ ! if (c < (unsigned char) (*p * BYTEWIDTH) && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; --- 3533,3539 ---- c = TRANSLATE (*d); /* The character to match. */ ! /* Cast to `unsigned' instead of `unsigned char' in case the ! bit list is a full 32 bytes long. */ ! if (c < (unsigned) (*p * BYTEWIDTH) && p[1 + c / BYTEWIDTH] & (1 << (c % BYTEWIDTH))) not = !not; *************** *** 3744,3748 **** if (!bufp->not_bol) break; } ! else if (d[-1] == '\n' && bufp->newline_anchor) { break; --- 3799,3803 ---- if (!bufp->not_bol) break; } ! else if (d[-1] == '\n' && bufp->newline_anchor) { break; *************** *** 3788,3805 **** /* on_failure_keep_string_jump is used to optimize `.*\n'. It pushes NULL as the value for the string on the stack. Then ! pop_failure_point will keep the current value for the string, ! instead of restoring it. To see why, consider matching ! `foo\nbar' against `.*\n'. The .* matches the foo; then the ! . fails against the \n. But the next thing we want to do is ! match the \n against the \n; if we restored the string value, ! we would be back at the foo. Because this is used only in specific cases, we don't need to ! go through the hassle of checking all the things that ! on_failure_jump does, to make sure the right things get saved ! on the stack. Hence we don't share its code. The only ! reason to push anything on the stack at all is that otherwise ! we would have to change anychar's code to do something ! besides goto fail in this case; that seems worse than this. */ case on_failure_keep_string_jump: DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); --- 3843,3860 ---- /* on_failure_keep_string_jump is used to optimize `.*\n'. It pushes NULL as the value for the string on the stack. Then ! `pop_failure_point' will keep the current value for the ! string, instead of restoring it. To see why, consider ! matching `foo\nbar' against `.*\n'. The .* matches the foo; ! then the . fails against the \n. But the next thing we want ! to do is match the \n against the \n; if we restored the ! string value, we would be back at the foo. Because this is used only in specific cases, we don't need to ! check all the things that `on_failure_jump' does, to make ! sure the right things get saved on the stack. Hence we don't ! share its code. The only reason to push anything on the ! stack at all is that otherwise we would have to change ! `anychar's code to do something besides goto fail in this ! case; that seems worse than this. */ case on_failure_keep_string_jump: DEBUG_PRINT1 ("EXECUTING on_failure_keep_string_jump"); *************** *** 4044,4048 **** { mcnt--; ! STORE_NUMBER(p + 2, mcnt); goto unconditional_jump; } --- 4099,4103 ---- { mcnt--; ! STORE_NUMBER (p + 2, mcnt); goto unconditional_jump; } *************** *** 4296,4300 **** *lowest_active_reg = (unsigned) POP_FAILURE_ITEM (); ! DEBUG_PRINT2 (" Popping low active reg: %d\n", *lowest_active_reg); for (this_reg = *highest_active_reg; this_reg >= *lowest_active_reg; --- 4351,4355 ---- *lowest_active_reg = (unsigned) POP_FAILURE_ITEM (); ! DEBUG_PRINT2 (" Popping low active reg: %d\n", *lowest_active_reg); for (this_reg = *highest_active_reg; this_reg >= *lowest_active_reg; *************** *** 4605,4609 **** bufp->newline_anchor = 1; ! ret = regex_compile (pattern, length, obscure_syntax, bufp); return re_error_msg[(int) ret]; --- 4660,4664 ---- bufp->newline_anchor = 1; ! ret = regex_compile (pattern, length, re_syntax_options, bufp); return re_error_msg[(int) ret]; *************** *** 4649,4654 **** re_comp_buf.newline_anchor = 1; ! ret = regex_compile (s, strlen (s), obscure_syntax, &re_comp_buf); return (char *) re_error_msg[(int) ret]; } --- 4704,4710 ---- re_comp_buf.newline_anchor = 1; ! ret = regex_compile (s, strlen (s), re_syntax_options, &re_comp_buf); + /* Yes, we're discarding `const' here. */ return (char *) re_error_msg[(int) ret]; } diff -rc2N tar-1.11/regex.h tar-1.11.1/regex.h *** tar-1.11/regex.h Sun Aug 23 02:52:19 1992 --- tar-1.11.1/regex.h Fri Sep 11 07:46:59 1992 *************** *** 1,4 **** /* Definitions for data structures and routines for the regular ! expression library, version 0.9. Copyright (C) 1985, 89, 90, 91, 92 Free Software Foundation, Inc. --- 1,4 ---- /* Definitions for data structures and routines for the regular ! expression library, version 0.10a. Copyright (C) 1985, 89, 90, 91, 92 Free Software Foundation, Inc. *************** *** 46,50 **** /* If this bit is set, then ^ and $ are always anchors (outside bracket ! expressions). If this bit is not set, then it depends: ^ is an anchor if it is at the beginning of a regular --- 46,50 ---- /* If this bit is set, then ^ and $ are always anchors (outside bracket ! expressions, of course). If this bit is not set, then it depends: ^ is an anchor if it is at the beginning of a regular *************** *** 52,60 **** $ is an anchor if it is at the end of a regular expression, or before a close-group or an alternation operator. This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because ! POSIX now says that the behavior of * etc. in leading positions is ! undefined. We have already implemented a previous draft which ! made those constructs invalid, so we may as well not change the code ! back. */ #define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) --- 52,60 ---- $ is an anchor if it is at the end of a regular expression, or before a close-group or an alternation operator. + This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because ! POSIX draft 11.2 says that * etc. in leading positions is undefined. ! We already implemented a previous draft which made those constructs ! invalid, though, so we haven't changed the code back. */ #define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) *************** *** 68,81 **** /* If this bit is set, then *, +, ?, and { cannot be first in an re or ! immediately after an alternation or begin-group operator. ! Furthermore, alternation cannot be first or last in an re, or ! immediately follow another alternation or begin-group. */ #define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) ! /* If this bit is set, then . matches a newline. If not set, then it doesn't. */ #define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) ! /* If this bit is set, then period doesn't match a null. If not set, then it does. */ #define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) --- 68,79 ---- /* If this bit is set, then *, +, ?, and { cannot be first in an re or ! immediately after an alternation or begin-group operator. */ #define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) ! /* If this bit is set, then . matches newline. If not set, then it doesn't. */ #define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) ! /* If this bit is set, then . doesn't match NUL. If not set, then it does. */ #define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) *************** *** 90,94 **** #define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) ! /* If this bit is set, +, ? and | aren't recognized as operators. If not set, they are. */ #define RE_LIMITED_OPS (RE_INTERVALS << 1) --- 88,92 ---- #define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) ! /* If this bit is set, +, ? and | aren't recognized as operators. If not set, they are. */ #define RE_LIMITED_OPS (RE_INTERVALS << 1) *************** *** 99,109 **** /* If this bit is set, newline in the pattern is an ordinary character. ! If not set, newline before ^ or after $ allows the ^ or $ to be an ! anchor. */ #define RE_NEWLINE_ORDINARY (RE_NEWLINE_ALT << 1) ! /* If this bit is not set, then \{ and \} defines an interval, ! and { and } are literals. ! If set, then { and } defines an interval, and \{ and \} are literals. */ #define RE_NO_BK_BRACES (RE_NEWLINE_ORDINARY << 1) --- 97,106 ---- /* If this bit is set, newline in the pattern is an ordinary character. ! If not set, a ^ after a newline or $ before might be an anchor. */ #define RE_NEWLINE_ORDINARY (RE_NEWLINE_ALT << 1) ! /* If this bit is set, then `{...}' defines an interval, and \{ and \} ! are literals. ! If not set, then `\{...\}' defines an interval. */ #define RE_NO_BK_BRACES (RE_NEWLINE_ORDINARY << 1) *************** *** 112,118 **** #define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) ! /* If this bit is set, then back references (i.e., \) are not ! recognized. ! If not set, then they are. */ #define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) --- 109,114 ---- #define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) ! /* If this bit is set, then \ matches . ! If not set, then \ is a back-reference. */ #define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) *************** *** 121,140 **** #define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - /* If this bit is set, then you can't have empty alternatives. - If not set, then you can. */ - #define RE_NO_EMPTY_ALTS (RE_NO_BK_VBAR << 1) - /* If this bit is set, then you can't have empty groups. If not set, then you can. */ ! #define RE_NO_EMPTY_GROUPS (RE_NO_EMPTY_ALTS << 1) ! /* If this bit is set, then an ending range point has to collate higher ! than or equal to the starting range point. ! If not set, then when the ending range point collates higher than the ! starting range point, we consider such a range to be empty. */ #define RE_NO_EMPTY_RANGES (RE_NO_EMPTY_GROUPS << 1) ! /* If this bit is set, then all back references must refer to a preceding ! subexpression. If not set, then a back reference to a nonexistent subexpression is treated as literal characters. */ --- 117,132 ---- #define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) /* If this bit is set, then you can't have empty groups. If not set, then you can. */ ! #define RE_NO_EMPTY_GROUPS (RE_NO_BK_VBAR << 1) ! /* If this bit is set, then an ending range point collating higher ! than the starting range point, as in [z-a], is invalid. ! If not set, then when ending range point collates higher than the ! starting range point, the range is ignored. */ #define RE_NO_EMPTY_RANGES (RE_NO_EMPTY_GROUPS << 1) ! /* If this bit is set, then \ where the pattern has no preceding ! th subexpression is invalid. If not set, then a back reference to a nonexistent subexpression is treated as literal characters. */ *************** *** 141,147 **** #define RE_NO_MISSING_BK_REF (RE_NO_EMPTY_RANGES << 1) ! /* If this bit is set, then Regex considers an unmatched close-group ! operator to be the ordinary character parenthesis. ! If not set, then an unmatched close-group operator is invalid. */ #define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_MISSING_BK_REF << 1) --- 133,138 ---- #define RE_NO_MISSING_BK_REF (RE_NO_EMPTY_RANGES << 1) ! /* If this bit is set, then an unmatched ) is ordinary. ! If not set, then an unmatched ) is invalid. */ #define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_MISSING_BK_REF << 1) *************** *** 150,159 **** stored in the pattern buffer, so changing this does not affect already-compiled regexps. */ ! extern reg_syntax_t obscure_syntax; ! ! ! /* Define combinations of the above bits for the standard possibilities. ! (The [[[ comments delimit what gets put into the Texinfo file.) */ /* [[[begin syntaxes]]] */ #define RE_SYNTAX_EMACS 0 --- 141,149 ---- stored in the pattern buffer, so changing this does not affect already-compiled regexps. */ ! extern reg_syntax_t re_syntax_options; ! /* Define combinations of the above bits for the standard possibilities. ! (The [[[ comments delimit what gets put into the Texinfo file, so ! don't delete them!) */ /* [[[begin syntaxes]]] */ #define RE_SYNTAX_EMACS 0 *************** *** 161,168 **** #define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ ! | RE_NEWLINE_ORDINARY | RE_NO_BK_PARENS \ ! | RE_NO_BK_REFS | RE_NO_BK_VAR \ ! | RE_NO_EMPTY_ALTS | RE_NO_EMPTY_RANGES \ ! | RE_UNMATCHED_RIGHT_PAREN_ORD) #define RE_SYNTAX_POSIX_AWK \ --- 151,157 ---- #define RE_SYNTAX_AWK \ (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ ! | RE_NEWLINE_ORDINARY | RE_NO_BK_PARENS \ ! | RE_NO_BK_REFS | RE_NO_BK_VAR \ ! | RE_NO_EMPTY_RANGES | RE_UNMATCHED_RIGHT_PAREN_ORD) #define RE_SYNTAX_POSIX_AWK \ *************** *** 170,198 **** #define RE_SYNTAX_GREP \ ! (RE_BK_PLUS_QM | RE_NEWLINE_ALT) #define RE_SYNTAX_EGREP \ ! (RE_CONTEXT_INDEP_ANCHORS | RE_CONTEXT_INDEP_OPS \ ! | RE_NEWLINE_ALT | RE_NO_BK_PARENS | RE_NO_BK_VBAR) #define RE_SYNTAX_POSIX_BASIC \ ! (RE_CHAR_CLASSES | RE_DOT_NEWLINE \ ! | RE_DOT_NOT_NULL | RE_INTERVALS | RE_LIMITED_OPS \ ! | RE_NEWLINE_ORDINARY | RE_NO_EMPTY_RANGES | RE_NO_MISSING_BK_REF) #define RE_SYNTAX_POSIX_EXTENDED \ ! (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ ! | RE_CONTEXT_INVALID_OPS | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ ! | RE_INTERVALS | RE_NEWLINE_ORDINARY | RE_NO_BK_BRACES \ ! | RE_NO_BK_PARENS | RE_NO_BK_REFS | RE_NO_BK_VBAR \ ! | RE_NO_EMPTY_ALTS | RE_NO_EMPTY_GROUPS | RE_NO_EMPTY_RANGES \ | RE_UNMATCHED_RIGHT_PAREN_ORD) /* [[[end syntaxes]]] */ ! /* Maximum number of duplicates an interval can allow. */ ! #define RE_DUP_MAX ((1 << 15) - 1) ! /* POSIX `cflags' bits (i.e., information for regcomp). */ /* If this bit is set, then use extended regular expression syntax. --- 159,215 ---- #define RE_SYNTAX_GREP \ ! (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ ! | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ ! | RE_NEWLINE_ALT) #define RE_SYNTAX_EGREP \ ! (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ ! | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ ! | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ ! | RE_NO_BK_VBAR) ! ! #define RE_SYNTAX_POSIX_EGREP \ ! (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES) ! ! /* Syntax bits common to both basic and extended POSIX regex syntax. */ ! #define _RE_SYNTAX_POSIX_COMMON \ ! (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ ! | RE_INTERVALS | RE_NEWLINE_ORDINARY | RE_NO_EMPTY_RANGES) #define RE_SYNTAX_POSIX_BASIC \ ! (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_NO_MISSING_BK_REF) + /* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes + RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this + isn't minimal, since other operators, such as \`, aren't disabled. */ + #define RE_SYNTAX_POSIX_MINIMAL_BASIC \ + (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS | RE_NO_MISSING_BK_REF) + #define RE_SYNTAX_POSIX_EXTENDED \ ! (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ ! | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ ! | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ ! | RE_NO_EMPTY_GROUPS | RE_UNMATCHED_RIGHT_PAREN_ORD) ! ! /* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INVALID_OPS ! replaces RE_CONTEXT_INDEP_OPS and RE_NO_BK_REFS is added. */ ! #define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ ! (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ ! | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ ! | RE_NO_BK_PARENS | RE_NO_BK_REFS \ ! | RE_NO_BK_VBAR | RE_NO_EMPTY_GROUPS \ | RE_UNMATCHED_RIGHT_PAREN_ORD) /* [[[end syntaxes]]] */ ! /* Maximum number of duplicates an interval can allow. Some systems ! (erroneously) define this in other header files, but we want our ! value, so remove any previous define. */ ! #ifdef RE_DUP_MAX ! #undef RE_DUP_MAX ! #endif ! #define RE_DUP_MAX ((1 << 15) - 1) ! /* POSIX `cflags' bits (i.e., information for `regcomp'). */ /* If this bit is set, then use extended regular expression syntax. *************** *** 369,383 **** /* Declarations for routines. */ #if __STDC__ ! /* Sets the current syntax to SYNTAX. You can also simply assign to the ! `obscure_syntax' variable. */ ! extern reg_syntax_t re_set_syntax (reg_syntax_t syntax); /* Compile the regular expression PATTERN, with length LENGTH ! and syntax given by the global `obscure_syntax', into the buffer BUFFER. Return NULL if successful, and an error string if not. */ ! extern const char *re_compile_pattern (const char *pattern, int length, ! struct re_pattern_buffer *buffer); --- 386,414 ---- /* Declarations for routines. */ + /* To avoid duplicating every routine declaration -- once with a + prototype (if we are ANSI), and once without (if we aren't) -- we + use the following macro to declare argument types. This + unfortunately clutters up the declarations a bit, but I think it's + worth it. + + We also have to undo `const' if we are not ANSI. */ + #if __STDC__ + #define _RE_ARGS(args) args + #else + #define _RE_ARGS(args) () + #define const + #endif ! /* Sets the current default syntax to SYNTAX, and return the old syntax. ! You can also simply assign to the `re_syntax_options' variable. */ ! extern reg_syntax_t re_set_syntax _RE_ARGS ((reg_syntax_t syntax)); /* Compile the regular expression PATTERN, with length LENGTH ! and syntax given by the global `re_syntax_options', into the buffer BUFFER. Return NULL if successful, and an error string if not. */ ! extern const char *re_compile_pattern ! _RE_ARGS ((const char *pattern, int length, ! struct re_pattern_buffer *buffer)); *************** *** 385,389 **** accelerate searches. Return 0 if successful and -2 if was an internal error. */ ! extern int re_compile_fastmap (struct re_pattern_buffer *buffer); --- 416,420 ---- accelerate searches. Return 0 if successful and -2 if was an internal error. */ ! extern int re_compile_fastmap _RE_ARGS ((struct re_pattern_buffer *buffer)); *************** *** 393,400 **** match, or -2 for an internal error. Also return register information in REGS (if REGS and BUFFER->no_sub are nonzero). */ ! extern int re_search (struct re_pattern_buffer *buffer, ! const char *string, int length, ! int start, int range, ! struct re_registers *regs); --- 424,430 ---- match, or -2 for an internal error. Also return register information in REGS (if REGS and BUFFER->no_sub are nonzero). */ ! extern int re_search ! _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, ! int length, int start, int range, struct re_registers *regs)); *************** *** 401,410 **** /* Like `re_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ ! extern int re_search_2 (struct re_pattern_buffer *buffer, ! const char *string1, int length1, ! const char *string2, int length2, ! int start, int range, ! struct re_registers *regs, ! int stop); --- 431,438 ---- /* Like `re_search', but search in the concatenation of STRING1 and STRING2. Also, stop searching at index START + STOP. */ ! extern int re_search_2 ! _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, ! int length1, const char *string2, int length2, ! int start, int range, struct re_registers *regs, int stop)); *************** *** 411,426 **** /* Like `re_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ ! extern int re_match (struct re_pattern_buffer *buffer, ! const char *string, int length, ! int start, struct re_registers *regs); /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ ! extern int re_match_2 (struct re_pattern_buffer *buffer, ! const char *string1, int length1, ! const char *string2, int length2, ! int start, ! struct re_registers *regs, ! int stop); --- 439,452 ---- /* Like `re_search', but return how many characters in STRING the regexp in BUFFER matched, starting at position START. */ ! extern int re_match ! _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string, ! int length, int start, struct re_registers *regs)); /* Relates to `re_match' as `re_search_2' relates to `re_search'. */ ! extern int re_match_2 ! _RE_ARGS ((struct re_pattern_buffer *buffer, const char *string1, ! int length1, const char *string2, int length2, ! int start, struct re_registers *regs, int stop)); *************** *** 437,480 **** PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ ! extern void re_set_registers (struct re_pattern_buffer *buffer, ! struct re_registers *regs, ! unsigned num_regs, ! regoff_t *starts, ! regoff_t *ends); /* 4.2 bsd compatibility. */ ! extern char *re_comp (const char *); ! extern int re_exec (const char *); ! ! /* POSIX compatibility. */ ! extern int regcomp (regex_t *preg, const char *pattern, int cflags); ! extern int regexec (const regex_t *preg, const char *string, size_t nmatch, ! regmatch_t pmatch[], int eflags); ! extern size_t regerror (int errcode, const regex_t *preg, char *errbuf, ! size_t errbuf_size); ! extern void regfree (regex_t *preg); ! ! #else /* not __STDC__ */ ! ! /* Support old C compilers. */ ! #define const ! ! extern reg_syntax_t re_set_syntax (); ! extern char *re_compile_pattern (); ! extern int re_search (), re_search_2 (); ! extern int re_match (), re_match_2 (); ! extern void re_set_registers (); ! ! /* 4.2 BSD compatibility. */ ! extern char *re_comp (); ! extern int re_exec (); /* POSIX compatibility. */ ! extern int regcomp (); ! extern int regexec (); ! extern size_t regerror (); ! extern void regfree (); - #endif /* not __STDC__ */ #endif /* not __REGEXP_LIBRARY_H__ */ --- 463,484 ---- PATTERN_BUFFER will allocate its own register data, without freeing the old data. */ ! extern void re_set_registers ! _RE_ARGS ((struct re_pattern_buffer *buffer, struct re_registers *regs, ! unsigned num_regs, regoff_t *starts, regoff_t *ends)); /* 4.2 bsd compatibility. */ ! extern char *re_comp _RE_ARGS ((const char *)); ! extern int re_exec _RE_ARGS ((const char *)); /* POSIX compatibility. */ ! extern int regcomp _RE_ARGS ((regex_t *preg, const char *pattern, int cflags)); ! extern int regexec ! _RE_ARGS ((const regex_t *preg, const char *string, size_t nmatch, ! regmatch_t pmatch[], int eflags)); ! extern size_t regerror ! _RE_ARGS ((int errcode, const regex_t *preg, char *errbuf, ! size_t errbuf_size)); ! extern void regfree _RE_ARGS ((regex_t *preg)); #endif /* not __REGEXP_LIBRARY_H__ */ diff -rc2N tar-1.11/rmt.c tar-1.11.1/rmt.c *** tar-1.11/rmt.c Sun Jul 19 02:13:30 1992 --- tar-1.11.1/rmt.c Tue Sep 15 20:06:58 1992 *************** *** 253,257 **** #ifdef SO_RCVBUF while (size > 1024 && ! setsockopt(0, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size)) < 0) size -= 1024; #else --- 253,257 ---- #ifdef SO_RCVBUF while (size > 1024 && ! setsockopt(0, SOL_SOCKET, SO_RCVBUF, (char *)&size, sizeof (size)) < 0) size -= 1024; #else diff -rc2N tar-1.11/tar.c tar-1.11.1/tar.c *** tar-1.11/tar.c Thu Sep 3 14:26:06 1992 --- tar-1.11.1/tar.c Mon Sep 14 17:31:38 1992 *************** *** 28,31 **** --- 28,32 ---- #include "getopt.h" #include "regex.h" + #include "fnmatch.h" /* *************** *** 104,108 **** void options(); char *un_quote_string(); - int wildmat(); #ifndef S_ISLNK --- 105,108 ---- *************** *** 281,285 **** case CMD_NONE: msg("you must specify exactly one of the r, c, t, x, or d options\n"); ! fprintf(stderr,"For more information, type ``%s +help''.\n",tar); exit(EX_ARGSBAD); } --- 281,285 ---- case CMD_NONE: msg("you must specify exactly one of the r, c, t, x, or d options\n"); ! fprintf(stderr,"For more information, type ``%s --help''.\n",tar); exit(EX_ARGSBAD); } *************** *** 617,621 **** case '?': badopt: ! msg("Unknown option. Use '%s +help' for a complete list of options.", tar); exit(EX_ARGSBAD); --- 617,621 ---- case '?': badopt: ! msg("Unknown option. Use '%s --help' for a complete list of options.", tar); exit(EX_ARGSBAD); *************** *** 974,980 **** char *path = ck_malloc(PATH_MAX); #if defined(__MSDOS__) || defined(USG) || defined(_POSIX_VERSION) ! if(!getcwd(path,PATH_MAX)) msg("Couldn't get current directory."); exit(EX_SYSTEM); #else char *getwd(); --- 974,981 ---- char *path = ck_malloc(PATH_MAX); #if defined(__MSDOS__) || defined(USG) || defined(_POSIX_VERSION) ! if(!getcwd(path,PATH_MAX)) { msg("Couldn't get current directory."); exit(EX_SYSTEM); + } #else char *getwd(); *************** *** 1063,1067 **** /* Regular expressions (shell globbing, actually). */ if (nlp->regexp) { ! if (wildmat(p, nlp->name)) { nlp->found = 1; /* Remember it matched */ if(f_startfile) { --- 1064,1068 ---- /* Regular expressions (shell globbing, actually). */ if (nlp->regexp) { ! if (fnmatch(nlp->name, p, FNM_TARPATH) == 0) { nlp->found = 1; /* Remember it matched */ if(f_startfile) { *************** *** 1173,1177 **** /* Regular expressions */ if (nlp->regexp) { ! if (wildmat(p, nlp->name)) return nlp; /* We got a match */ continue; --- 1174,1178 ---- /* Regular expressions */ if (nlp->regexp) { ! if (fnmatch(nlp->name, p, FNM_TARPATH) == 0) return nlp; /* We got a match */ continue; *************** *** 1341,1345 **** FILE *fp; char buf[1024]; - extern char *rindex(); if(strcmp(file, "-")) --- 1342,1345 ---- *************** *** 1385,1389 **** for(n=0;n - Date: 27 Nov 86 00:06:40 GMT - - There have been several regular-expression subroutines and one or two - filename-globbing routines in mod.sources. They handle lots of - complicated patterns. This small piece of code handles the *?[]\ - wildcard characters the way the standard Unix(tm) shells do, with the - addition that "[!.....]" is an inverse character class -- it matches - any character not in the range ".....". Read the comments for more - info. - - For my application, I had first ripped off a copy of the "glob" routine - from within the find source, but that code is bad news: it recurses - on every character in the pattern. I'm putting this replacement in the - public domain. It's small, tight, and iterative. Compile with -DTEST - to get a test driver. After you're convinced it works, install in - whatever way is appropriate for you. - - I would like to hear of bugs, but am not interested in additions; if I - were, I'd use the code I mentioned above. - */ - /* - ** Do shell-style pattern matching for ?, \, [], and * characters. - ** Might not be robust in face of malformed patterns; e.g., "foo[a-" - ** could cause a segmentation violation. - ** - ** Written by Rich $alz, mirror!rs, Wed Nov 26 19:03:17 EST 1986. - */ - - /* - * Modified 6Nov87 by John Gilmore (hoptoad!gnu) to return a "match" - * if the pattern is immediately followed by a "/", as well as \0. - * This matches what "tar" does for matching whole subdirectories. - * - * The "*" code could be sped up by only recursing one level instead - * of two for each trial pattern, perhaps, and not recursing at all - * if a literal match of the next 2 chars would fail. - */ - #define TRUE 1 - #define FALSE 0 - - int wildmat(); - - static int - Star(s, p) - register char *s; - register char *p; - { - while (wildmat(s, p) == FALSE) - if (*++s == '\0') - return(FALSE); - return(TRUE); - } - - - int - wildmat(s, p) - register char *s; - register char *p; - { - register int last; - register int matched; - register int reverse; - - for ( ; *p; s++, p++) - switch (*p) { - case '\\': - /* Literal match with following character; fall through. */ - p++; - default: - if (*s != *p) - return(FALSE); - continue; - case '?': - /* Match anything. */ - if (*s == '\0') - return(FALSE); - continue; - case '*': - /* Trailing star matches everything. */ - return(*++p ? Star(s, p) : TRUE); - case '[': - /* [!....] means inverse character class. */ - if (reverse = p[1] == '!') - p++; - for (last = 0400, matched = FALSE; *++p && *p != ']'; last = *p) - /* This next line requires a good C compiler. */ - if (*p == '-' ? *s <= *++p && *s >= last : *s == *p) - matched = TRUE; - if (matched == reverse) - return(FALSE); - continue; - } - - /* For "tar" use, matches that end at a slash also work. --hoptoad!gnu */ - return(*s == '\0' || *s == '/'); - } - - - #ifdef TEST - #include - - extern char *gets(); - - - main() - { - char pattern[80]; - char text[80]; - - while (TRUE) { - printf("Enter pattern: "); - if (gets(pattern) == NULL) - break; - while (TRUE) { - printf("Enter text: "); - if (gets(text) == NULL) - exit(0); - if (text[0] == '\0') - /* Blank line; go back and get a new pattern. */ - break; - printf(" %d\n", wildmat(text, pattern)); - } - } - exit(0); - } - #endif /* TEST */ --- 0 ----