*** empty log message ***

This commit is contained in:
François Pinard
1994-11-16 02:56:34 +00:00
parent c9477c3e7b
commit c086e08a4b
6 changed files with 265 additions and 231 deletions

16
README
View File

@@ -21,9 +21,9 @@ 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.
I've gotten conflicting reports about what should be done to solve the
problems, and we have no way to test it ourselves.
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
@@ -34,3 +34,13 @@ 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.
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.

View File

@@ -1,4 +1,4 @@
# Makefile for GNU tar on MS-DOS using Turbo C 2.0.
# Makefile for GNU tar on MS-DOS.
# Copyright (C) 1991 Free Software Foundation, Inc.
# This program is free software; you can redistribute it and/or modify
@@ -15,18 +15,14 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
CC = tcc
CC = bcc
RM = rm -f
MODEL = m
DEFS = -DNONAMES -DNO_REMOTE -DNO_MTIO -DSTDC_HEADERS -m$(MODEL) -Dmain=_main
DEFS = -DNONAMES -DNO_REMOTE -DSTDC_HEADERS=1 -m$(MODEL) -Dmain=_main
LIBS =
DEF_AR_FILE = tar.out
DEFBLOCKING = 20
CFLAGS = -I. $(DEFS) \
-DDEF_AR_FILE="$(DEF_AR_FILE)" \
-DDEFBLOCKING=$(DEFBLOCKING)
CFLAGS = $(DEFS)
LDFLAGS = -m$(MODEL)
OBJ1 = tar.obj create.obj extract.obj buffer.obj getoldopt.obj update.obj gnu.obj mangle.obj
@@ -43,6 +39,11 @@ tar: testpad.h getdate.c $(OBJS)
.c.obj:
$(CC) -c $(CFLAGS) $<
# For some reason, Borland C++ 3.1 chokes on this file when given
# the full set of -D options.
getoldopt.obj: getoldopt.c
$(CC) -c -m$(MODEL) -DSTDC_HEADERS getoldopt.c
testpad.h: testpad.exe
testpad

View File

@@ -19,11 +19,11 @@
#ifndef NULL
# define NULL 0
#endif /* NULL */
#endif /* NULL */
#ifndef MAXPATHLEN
# define MAXPATHLEN 255
#endif /* MAXPATHLEN */
#endif /* MAXPATHLEN */
/* attribute stuff */
#define A_RONLY 0x01
@@ -43,178 +43,187 @@
#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;
typedef struct
{
char d_buf[21];
char d_attribute;
unsigned short d_time;
unsigned short d_date;
long d_size;
char d_name[13];
}
static char *getdirent();
static void mysetdta();
static void free_dircontents();
Dta_buf;
static Dta_buf dtabuf;
static Dta_buf *dtapnt = &dtabuf;
static union REGS reg, nreg;
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;
static struct SREGS sreg;
#endif
DIR *
opendir(name)
char *name;
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;
struct stat statb;
DIR *dirp;
char c;
char *s;
struct _dircontents *dp;
char nbuf[MAXPATHLEN + 1];
return dirp;
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;
closedir (dirp)
DIR *dirp;
{
free_dircontents(dirp->dd_contents);
free((char *) dirp);
free_dircontents (dirp->dd_contents);
free ((char *) dirp);
}
struct dirent *
readdir(dirp)
DIR *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++;
static struct dirent dp;
return &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;
seekdir (dirp, off)
DIR *dirp;
long off;
{
long i = off;
struct _dircontents *dp;
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;
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;
telldir (dirp)
DIR *dirp;
{
return dirp->dd_loc;
return dirp->dd_loc;
}
static void
free_dircontents(dp)
struct _dircontents *dp;
static void
free_dircontents (dp)
struct _dircontents *dp;
{
struct _dircontents *odp;
struct _dircontents *odp;
while (dp) {
if (dp->_d_entry)
free(dp->_d_entry);
dp = (odp = dp)->_d_next;
free((char *) 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;
static char *
getdirent (dir)
char *dir;
{
if (dir != (char *) NULL) { /* get first entry */
reg.h.ah = DOSI_FINDF;
reg.h.cl = ATTRIBUTES;
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);
reg.x.dx = FP_OFF (dir);
sreg.ds = FP_SEG (dir);
#else
reg.x.dx = (unsigned) dir;
reg.x.dx = (unsigned) dir;
#endif
} else { /* get next entry */
reg.h.ah = DOSI_FINDN;
}
else
{ /* get next entry */
reg.h.ah = DOSI_FINDN;
#if defined(M_I86LM)
reg.x.dx = FP_OFF(dtapnt);
sreg.ds = FP_SEG(dtapnt);
reg.x.dx = FP_OFF (dtapnt);
sreg.ds = FP_SEG (dtapnt);
#else
reg.x.dx = (unsigned) dtapnt;
reg.x.dx = (unsigned) dtapnt;
#endif
}
}
#if defined(M_I86LM)
intdosx(&reg, &nreg, &sreg);
intdosx (&reg, &nreg, &sreg);
#else
intdos(&reg, &nreg);
intdos (&reg, &nreg);
#endif
if (nreg.x.cflag)
return (char *) NULL;
if (nreg.x.cflag)
return (char *) NULL;
return dtabuf.d_name;
return dtabuf.d_name;
}
static void
mysetdta()
static void
mysetdta ()
{
reg.h.ah = DOSI_SDTA;
reg.h.ah = DOSI_SDTA;
#if defined(M_I86LM)
reg.x.dx = FP_OFF(dtapnt);
sreg.ds = FP_SEG(dtapnt);
intdosx(&reg, &nreg, &sreg);
reg.x.dx = FP_OFF (dtapnt);
sreg.ds = FP_SEG (dtapnt);
intdosx (&reg, &nreg, &sreg);
#else
reg.x.dx = (int) dtapnt;
intdos(&reg, &nreg);
reg.x.dx = (int) dtapnt;
intdos (&reg, &nreg);
#endif
}

View File

@@ -15,27 +15,30 @@ 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 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;
};
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;
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();
extern DIR *opendir ();
extern struct dirent *readdir ();
extern void seekdir ();
extern long telldir ();
extern void closedir ();

View File

@@ -22,7 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*
* This file should be modified for non-unix systems to do something
* reasonable.
*/
*/
#include <sys/types.h>
#include "tar.h"
@@ -34,13 +34,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <pwd.h>
#include <grp.h>
static int saveuid = -993;
static char saveuname[TUNMLEN];
static int my_uid = -993;
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;
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 )
@@ -54,85 +54,96 @@ static int my_gid = -993;
* pages" code, roughly doubling the program size. Thanks guys.
*/
void
finduname(uname, uid)
char uname[TUNMLEN];
int uid;
finduname (uname, uid)
char uname[TUNMLEN];
int uid;
{
struct passwd *pw;
struct passwd *pw;
#ifndef HAVE_GETPWUID
extern struct passwd *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);
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];
finduid (uname)
char uname[TUNMLEN];
{
struct passwd *pw;
extern struct passwd *getpwnam();
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;
}
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;
}
return saveuid;
else
{
saveuid = myuid;
}
}
return saveuid;
}
void
findgname(gname, gid)
char gname[TGNMLEN];
int gid;
findgname (gname, gid)
char gname[TGNMLEN];
int gid;
{
struct group *gr;
struct group *gr;
#ifndef HAVE_GETGRGID
extern struct group *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);
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];
findgid (gname)
char gname[TUNMLEN];
{
struct group *gr;
extern struct group *getgrnam();
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;
}
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;
}
return savegid;
else
{
savegid = mygid;
}
}
return savegid;
}
#endif

View File

@@ -22,7 +22,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
* 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.
* 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
@@ -38,9 +38,9 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
*/
/* 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 */
#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. */
/*
@@ -50,13 +50,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
* it defined.
*/
#ifndef O_NDELAY
#define O_NDELAY 4 /* don't block on opening devices that would
#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 */
#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
/*