From e4b2fc0bd9c12311a49a7e08a779988664ecb3fe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Pinard?= Date: Wed, 16 Nov 1994 02:56:30 +0000 Subject: [PATCH] *** empty log message *** --- README | 54 +----------- src/makefile.pc | 2 +- src/msd_dir.c | 220 ++++++++++++++++++++++++++++++++++++++++++++++++ src/msd_dir.h | 41 +++++++++ src/names.c | 138 ++++++++++++++++++++++++++++++ src/open3.h | 67 +++++++++++++++ 6 files changed, 469 insertions(+), 53 deletions(-) create mode 100644 src/msd_dir.c create mode 100644 src/msd_dir.h create mode 100644 src/names.c create mode 100644 src/open3.h diff --git a/README b/README index ac4f0df..4e43435 100644 --- a/README +++ b/README @@ -15,6 +15,8 @@ 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. +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. @@ -32,55 +34,3 @@ incremental dumps, use +incremental (-G).) There is no tar manual in this release. The old manual has too many 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. - diff --git a/src/makefile.pc b/src/makefile.pc index 64a5a79..5a4f141 100644 --- a/src/makefile.pc +++ b/src/makefile.pc @@ -30,7 +30,7 @@ CFLAGS = -I. $(DEFS) \ LDFLAGS = -m$(MODEL) 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 +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) diff --git a/src/msd_dir.c b/src/msd_dir.c new file mode 100644 index 0000000..a902d70 --- /dev/null +++ b/src/msd_dir.c @@ -0,0 +1,220 @@ +/* + * @(#)msd_dir.c 1.4 87/11/06 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1897 + */ + +#include +#include +#include "msd_dir.h" +#ifndef __TURBOC__ +#include +#else +#include +#endif +#include +#include + +#ifndef NULL +# define NULL 0 +#endif /* NULL */ + +#ifndef MAXPATHLEN +# define MAXPATHLEN 255 +#endif /* MAXPATHLEN */ + +/* attribute stuff */ +#define A_RONLY 0x01 +#define A_HIDDEN 0x02 +#define A_SYSTEM 0x04 +#define A_LABEL 0x08 +#define A_DIR 0x10 +#define A_ARCHIVE 0x20 + +/* dos call values */ +#define DOSI_FINDF 0x4e +#define DOSI_FINDN 0x4f +#define DOSI_SDTA 0x1a + +#define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL) +/* #define ATTRIBUTES (A_DIR | A_HIDDEN | A_SYSTEM) */ +#define ATTRIBUTES (A_RONLY | A_SYSTEM | A_DIR) + +/* what find first/next calls look use */ +typedef struct { + char d_buf[21]; + char d_attribute; + unsigned short d_time; + unsigned short d_date; + long d_size; + char d_name[13]; +} Dta_buf; + +static char *getdirent(); +static void mysetdta(); +static void free_dircontents(); + +static Dta_buf dtabuf; +static Dta_buf *dtapnt = &dtabuf; +static union REGS reg, nreg; + +#if defined(M_I86LM) +static struct SREGS sreg; +#endif + +DIR * +opendir(name) + char *name; +{ + struct stat statb; + DIR *dirp; + char c; + char *s; + struct _dircontents *dp; + char nbuf[MAXPATHLEN + 1]; + + if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR) + return (DIR *) NULL; + if (Newisnull(dirp, DIR)) + return (DIR *) NULL; + if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/') + (void) strcat(strcpy(nbuf, name), "\\*.*"); + else + (void) strcat(strcpy(nbuf, name), "*.*"); + dirp->dd_loc = 0; + mysetdta(); + dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL; + if ((s = getdirent(nbuf)) == (char *) NULL) + return dirp; + do { + if (Newisnull(dp, struct _dircontents) || (dp->_d_entry = + malloc((unsigned) (strlen(s) + 1))) == (char *) NULL) + { + if (dp) + free((char *) dp); + free_dircontents(dirp->dd_contents); + return (DIR *) NULL; + } + if (dirp->dd_contents) + dirp->dd_cp = dirp->dd_cp->_d_next = dp; + else + dirp->dd_contents = dirp->dd_cp = dp; + (void) strcpy(dp->_d_entry, s); + dp->_d_next = (struct _dircontents *) NULL; + } while ((s = getdirent((char *) NULL)) != (char *) NULL); + dirp->dd_cp = dirp->dd_contents; + + return dirp; +} + +void +closedir(dirp) + DIR *dirp; +{ + free_dircontents(dirp->dd_contents); + free((char *) dirp); +} + +struct dirent * +readdir(dirp) + DIR *dirp; +{ + static struct dirent dp; + + if (dirp->dd_cp == (struct _dircontents *) NULL) + return (struct dirent *) NULL; + dp.d_namlen = dp.d_reclen = + strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry)); + strlwr(dp.d_name); /* JF */ + dp.d_ino = 0; + dirp->dd_cp = dirp->dd_cp->_d_next; + dirp->dd_loc++; + + return &dp; +} + +void +seekdir(dirp, off) + DIR *dirp; + long off; +{ + long i = off; + struct _dircontents *dp; + + if (off < 0) + return; + for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next) + ; + dirp->dd_loc = off - (i + 1); + dirp->dd_cp = dp; +} + +long +telldir(dirp) + DIR *dirp; +{ + return dirp->dd_loc; +} + +static void +free_dircontents(dp) + struct _dircontents *dp; +{ + struct _dircontents *odp; + + while (dp) { + if (dp->_d_entry) + free(dp->_d_entry); + dp = (odp = dp)->_d_next; + free((char *) odp); + } +} + +static char * +getdirent(dir) + char *dir; +{ + if (dir != (char *) NULL) { /* get first entry */ + reg.h.ah = DOSI_FINDF; + reg.h.cl = ATTRIBUTES; +#if defined(M_I86LM) + reg.x.dx = FP_OFF(dir); + sreg.ds = FP_SEG(dir); +#else + reg.x.dx = (unsigned) dir; +#endif + } else { /* get next entry */ + reg.h.ah = DOSI_FINDN; +#if defined(M_I86LM) + reg.x.dx = FP_OFF(dtapnt); + sreg.ds = FP_SEG(dtapnt); +#else + reg.x.dx = (unsigned) dtapnt; +#endif + } +#if defined(M_I86LM) + intdosx(®, &nreg, &sreg); +#else + intdos(®, &nreg); +#endif + if (nreg.x.cflag) + return (char *) NULL; + + return dtabuf.d_name; +} + +static void +mysetdta() +{ + reg.h.ah = DOSI_SDTA; +#if defined(M_I86LM) + reg.x.dx = FP_OFF(dtapnt); + sreg.ds = FP_SEG(dtapnt); + intdosx(®, &nreg, &sreg); +#else + reg.x.dx = (int) dtapnt; + intdos(®, &nreg); +#endif +} diff --git a/src/msd_dir.h b/src/msd_dir.h new file mode 100644 index 0000000..f953133 --- /dev/null +++ b/src/msd_dir.h @@ -0,0 +1,41 @@ +/* + * @(#)msd_dir.h 1.4 87/11/06 Public Domain. + * + * A public domain implementation of BSD directory routines for + * MS-DOS. Written by Michael Rendell ({uunet,utai}michael@garfield), + * August 1897 + */ + +#define rewinddir(dirp) seekdir(dirp, 0L) + +#define MAXNAMLEN 12 + +#ifdef __TURBOC__ +typedef int ino_t; +typedef int dev_t; +#endif + +struct dirent { + ino_t d_ino; /* a bit of a farce */ + int d_reclen; /* more farce */ + int d_namlen; /* length of d_name */ + char d_name[MAXNAMLEN + 1]; /* garentee null termination */ +}; + +struct _dircontents { + char *_d_entry; + struct _dircontents *_d_next; +}; + +typedef struct _dirdesc { + int dd_id; /* uniquely identify each open directory */ + long dd_loc; /* where we are in directory entry is this */ + struct _dircontents *dd_contents; /* pointer to contents of dir */ + struct _dircontents *dd_cp; /* pointer to current position */ +} DIR; + +extern DIR *opendir(); +extern struct dirent *readdir(); +extern void seekdir(); +extern long telldir(); +extern void closedir(); diff --git a/src/names.c b/src/names.c new file mode 100644 index 0000000..acd7857 --- /dev/null +++ b/src/names.c @@ -0,0 +1,138 @@ +/* Look up user and/or group names. + Copyright (C) 1988, 1992 Free Software Foundation + +This file is part of GNU Tar. + +GNU Tar 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. + +GNU Tar 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 GNU Tar; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * Look up user and/or group names. + * + * This file should be modified for non-unix systems to do something + * reasonable. + */ + +#include +#include "tar.h" +#include "port.h" + +#ifndef NONAMES +/* Whole module goes away if NONAMES defined. Otherwise... */ +#include +#include +#include + +static int saveuid = -993; +static char saveuname[TUNMLEN]; +static int my_uid = -993; + +static int savegid = -993; +static char savegname[TGNMLEN]; +static int my_gid = -993; + +#define myuid ( my_uid < 0? (my_uid = getuid()): my_uid ) +#define mygid ( my_gid < 0? (my_gid = getgid()): my_gid ) + +/* + * Look up a user or group name from a uid/gid, maintaining a cache. + * FIXME, for now it's a one-entry cache. + * FIXME2, the "-993" is to reduce the chance of a hit on the first lookup. + * + * This is ifdef'd because on Suns, it drags in about 38K of "yellow + * pages" code, roughly doubling the program size. Thanks guys. + */ +void +finduname(uname, uid) + char uname[TUNMLEN]; + int uid; +{ + struct passwd *pw; +#ifndef HAVE_GETPWUID + extern struct passwd *getpwuid (); +#endif + + if (uid != saveuid) { + saveuid = uid; + saveuname[0] = '\0'; + pw = getpwuid(uid); + if (pw) + strncpy(saveuname, pw->pw_name, TUNMLEN); + } + strncpy(uname, saveuname, TUNMLEN); +} + +int +finduid(uname) + char uname[TUNMLEN]; +{ + struct passwd *pw; + extern struct passwd *getpwnam(); + + if (uname[0] != saveuname[0] /* Quick test w/o proc call */ + || 0!=strncmp(uname, saveuname, TUNMLEN)) { + strncpy(saveuname, uname, TUNMLEN); + pw = getpwnam(uname); + if (pw) { + saveuid = pw->pw_uid; + } else { + saveuid = myuid; + } + } + return saveuid; +} + + +void +findgname(gname, gid) + char gname[TGNMLEN]; + int gid; +{ + struct group *gr; +#ifndef HAVE_GETGRGID + extern struct group *getgrgid (); +#endif + + if (gid != savegid) { + savegid = gid; + savegname[0] = '\0'; + (void)setgrent(); + gr = getgrgid(gid); + if (gr) + strncpy(savegname, gr->gr_name, TGNMLEN); + } + (void) strncpy(gname, savegname, TGNMLEN); +} + + +int +findgid(gname) + char gname[TUNMLEN]; +{ + struct group *gr; + extern struct group *getgrnam(); + + if (gname[0] != savegname[0] /* Quick test w/o proc call */ + || 0!=strncmp(gname, savegname, TUNMLEN)) { + strncpy(savegname, gname, TUNMLEN); + gr = getgrnam(gname); + if (gr) { + savegid = gr->gr_gid; + } else { + savegid = mygid; + } + } + return savegid; +} +#endif diff --git a/src/open3.h b/src/open3.h new file mode 100644 index 0000000..9ea2b4f --- /dev/null +++ b/src/open3.h @@ -0,0 +1,67 @@ +/* Defines for Sys V style 3-argument open call. + Copyright (C) 1988 Free Software Foundation + +This file is part of GNU Tar. + +GNU Tar 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. + +GNU Tar 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 GNU Tar; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* + * open3.h -- #defines for the various flags for the Sys V style 3-argument + * open() call. On BSD or System 5, the system already has this in an + * include file. This file is needed for V7 and MINIX systems for the + * benefit of open3() in port.c, a routine that emulates the 3-argument + * call using system calls available on V7/MINIX. + * + * This file is needed by PD tar even if we aren't using the + * emulator, since the #defines for O_WRONLY, etc. are used in + * a couple of places besides the open() calls, (e.g. in the assignment + * to openflag in extract.c). We just #include this rather than + * #ifdef them out. + * + * Written 6/10/87 by rmtodd@uokmax (Richard Todd). + * + * The names have been changed by John Gilmore, 31 July 1987, since + * Richard called it "bsdopen", and really this change was introduced in + * AT&T Unix systems before BSD picked it up. + */ + +/* Only one of the next three should be specified */ +#define O_RDONLY 0 /* only allow read */ +#define O_WRONLY 1 /* only allow write */ +#define O_RDWR 2 /* both are allowed */ + +/* The rest of these can be OR-ed in to the above. */ +/* + * O_NDELAY isn't implemented by the emulator. It's only useful (to tar) on + * systems that have named pipes anyway; it prevents tar's hanging by + * opening a named pipe. We #ifndef it because some systems already have + * it defined. + */ +#ifndef O_NDELAY +#define O_NDELAY 4 /* don't block on opening devices that would + * block on open -- ignored by emulator. */ +#endif +#define O_CREAT 8 /* create file if needed */ +#define O_EXCL 16 /* file cannot already exist */ +#define O_TRUNC 32 /* truncate file on open */ +#define O_APPEND 64 /* always write at end of file -- ignored by emul */ + +#ifdef EMUL_OPEN3 +/* + * make emulation transparent to rest of file -- redirect all open() calls + * to our routine + */ +#define open open3 +#endif -- 2.45.2