home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World Komputer 1999 mARCH
/
PCWK3A99.iso
/
Archiwiz
/
Tar320
/
SOURCES.ZIP
/
STORE.C
< prev
next >
Wrap
Text File
|
1994-07-22
|
7KB
|
290 lines
/* store.c - storying files into (tape) archive
* This is the part of the Tar program (see file tar.c)
* Author: T.V.Shaporev
* Creation date 14 Dec 1990
*/
#include <stdio.h>
#include "sysup.h"
#include "nodedef.h"
#include "modern.h"
#include "define.h"
char longname[] = "Tar: \'%s\' name too long%s";
#ifdef unix
# ifdef sun
# ifndef STDDIR
# define STDDIR
# endif
# include <dirent.h>
# define DIRENT struct dirent
# define namelen(d) strlen((d)->d_name)
# endif
# ifdef i386
# ifndef STDDIR
# define STDDIR
# endif
# include <dirent.h>
# define DIRENT struct dirent
# define namelen(d) strlen((d)->d_name)
# else
# ifdef M_XENIX
# ifndef STDDIR
# define STDDIR
# endif
# include <sys/ndir.h>
# define DIRENT DIR
# define namelen(d) ((d)->d_namlen)
# endif
# endif
#endif
#ifdef UNIX
# ifndef STDDIR
# include <sys/dir.h>
# endif
#endif
#ifdef MSDOS
# include <string.h>
# ifdef __TURBOC__
# include <dir.h>
# else
# include <direct.h>
# endif
# include <io.h>
#else
int strlen();
char *strcpy(), *strcat(), *strncpy();
int open(), read(), close();
# ifdef RMKDIR
int rmdir();
# endif
long lseek();
#endif
#define dotname(n) ((n)[0]=='.' && ((n)[1]=='\0'||((n)[1]=='.'&&(n)[2]=='\0')))
void proctl __ARGS__(( char *, long ));
void procts __ARGS__(( char *, short, char ));
void prcsum __ARGS__(( register header * ));
void newhead __ARGS__(( char *, long ));
char *deleft __ARGS__(( char * ));
void nullblock(h)
header *h;
{
register i; for (i=0; i<BLKSIZE/sizeof(int); i++) *((int *)h + i) = 0;
}
void proctl(dest, l)
char dest[]; long l;
{
register int i;
dest[i = 11] = ' ';
do dest[--i] = ((char)l & 7) | '0'; while (i>0 && (l>>=3)!=0);
while (i>0) dest[--i] = ' ';
}
void procts(dest, s, suffix)
char dest[]; short s; char suffix;
{
register int i;
dest[7] = 0;
dest[i = 6] = suffix;
do dest[--i] = (s & 7) | '0'; while (i>0 && (s>>=3)!=0);
while (i>0) dest[--i] = ' ';
}
void prcsum(h)
register header *h;
{
register i;
/* for the sake of compatibility */
for (i=0; i<8; i++) (h->m.chksum)[i] = ' ';
procts(h->m.chksum, headsum(h), 0);
}
void newhead(filename, filesize)
char *filename;
long filesize;
{
nullblock(hblock = steptape());
procts(hblock->m.mode, (short)st.st_mode & 07777, ' ');
procts(hblock->m.uid, (short)st.st_uid, ' ');
procts(hblock->m.gid, (short)st.st_gid, ' ');
proctl(hblock->m.size, filesize);
proctl(hblock->m.mtime, st.st_mtime);
(void)strncpy(hblock->m.name, filename, MAXTNAME);
}
char *deleft(p)
register char *p;
{
#ifdef MSDOS
if (deldrv && p[1] == ':' &&
(p[0]>='A' && p[0]<='Z' || p[0]>='a' && p[0]<='z'))
p += 2;
#endif
if (dslash && *p == '/') ++p;
return p;
}
void store(fname)
char *fname;
{
register i; register j;
register unsigned m;
static level = 0;
#ifdef UNIX
register char *p;
# ifdef STDDIR
register DIR *d0; register DIRENT *dp;
# else
register char *q; struct direct d_buf; int infile;
# endif
#endif
#ifdef MSDOS
register k;
struct ffblk ff;
#endif
if (cbreak) done(EXIT); ++level;
if (strlen(fname) > MAXTNAME) {
(void)fprintf(myout, longname, fname, "\n");
goto end;
}
#ifdef MSDOS
i = FALSE;
for (j=strlen(fname); j>0 && fname[j-1]!='/' && fname[j-1]!=':'; j--) {
if (fname[j-1]=='?' || fname[j-1]=='*') i = TRUE;
}
if (i) {
k = findfirst(fname, &ff, filemask);
while (k==0 && dotname(ff.ff_name)) k = findnext(&ff);
if (k) {
if (level < 2) (void)fprintf(myout,"Tar: can\'t find \'%s\'\n",fname);
goto end;
}
do {
takename(fname+j, ff.ff_name);
store(fname);
} while (findnext(&ff) == 0);
goto end;
}
#endif
for (i=0; i<xcnt; i++) {
if (fmatch(xarg[i], fname)) goto end;
}
if (stat(fname, &st) < 0) {
(void)fprintf(myout, "Tar: can\'t handle \'%s\'\n", fname);
goto end;
}
if ((m = st.st_mode & S_IFMT) == S_IFDIR) {
if (nonest && level > 1) goto end;
#ifdef UNIX
if (p_flag) {/* save directory & permissions */
newhead((p = deleft(fname)), 0L);
if ((j = strlen(p)) < MAXTNAME-1) {
hblock->m.name[j+1] = '\0';
} else {
j = MAXTNAME-1;
}
hblock->m.name[j] = '/';
prcsum(hblock);
}
# ifdef STDDIR
if ((d0 = opendir(fname)) == NULL) {
(void)fprintf(myout, "Tar: can\'t open directory \'%s\'\n", fname);
goto end;
}
fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
for (dp=readdir(d0); dp; dp=readdir(d0)) {
j = namelen(dp);
if (j==0 ||
(j==1 && (dp->d_name)[0]=='.') ||
(j==2 && (dp->d_name)[0]=='.' && (dp->d_name[1])=='.'))
continue;
for (i=0; i<j; i++) p[i] = (dp->d_name)[i];
p[j] = 0;
store(fname);
}
closedir(d0);
# else
if ((infile = open(fname, O_RDONLY)) < 0) {
(void)fprintf(myout, "Tar: can\'t open file \'%s\'\n", fname);
goto end;
}
fname[i = strlen(fname)] = '/'; *(p = ++i + fname) = 0;
i = 0;
while (read(infile, (char*)&d_buf, sizeof(d_buf)) > 0 && !cbreak) {
if (d_buf.d_ino!=0 && !dotname(d_buf.d_name)) {
q = p;
for (j=0; j<DIRSIZ; j++) *q++ = d_buf.d_name[j];
*q = '\0';
(void)close(infile); /* need this file handler */
store(fname);
*p = '\0';
infile = open(fname, O_RDONLY);
(void)lseek(infile, (long)(sizeof(d_buf) * (i+1)), 0);
}
++i;
}
# endif
if (y_flag) {
# ifdef RMKDIR
if (rmdir(fname) != 0) {
(void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
}
# else
if (bincall("rmdir", fname) == -1) {
(void)fprintf(myout, "Tar: fault run rmdir!\n");
}
# endif
}
#endif
#ifdef MSDOS
j = strlen(fname);
strcpy(fname+j, "/*.*");
store(fname);
if (y_flag) {
fname[j] = 0;
if (rmdir(fname) != 0) {
(void)fprintf(myout, "Tar: can\'t remove \'%s\'\n", fname);
}
}
#endif
} else if (m == S_IFREG) {
savefile(fname);
} else {
#ifdef UNIX
p = deleft(fname);
if (w_flag && !okwork('a', ' ', &st, fname)) goto end;
if (v_flag) (void)fprintf(myout, "a %s\n", p);
if (m == S_IFCHR || m == S_IFBLK || m == S_IFIFO) {
newhead(p, 0L);
if (m == S_IFIFO) {
hblock->m.filetype = TF_QUE;
} else {
hblock->m.filetype = m == S_IFBLK ? TF_BLK : TF_CHR;
procts(hblock->x.devmajor, major(st.st_rdev), ' ');
procts(hblock->x.devminor, minor(st.st_rdev), ' ');
}
prcsum(hblock);
} else
#endif
(void)fprintf(myout, "Tar: \'%s\' not a file\n", fname);
}
end: --level;
}