home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
CMDS
/
dback.lzh
/
dback.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-03-06
|
18KB
|
655 lines
/*
** Dback <from dir> <to dir>
** Copies all files in range of files to another disc
** (in the same way as dsave),
** - creating directories where needed
** - overwriting old versions of files
** - going recursively down the tree.
** optionally will merely list files instead of copying them.
**
** options are:
** -b = <num>k as for copy
** -d = backup selected directory
** -e = execute
** -f = omit files with suffix
** -k = do not copy OS9Boot files
** -l = no recursion
** -p = pause before implementing
** -s = start copying at file
** -t = terminate copying at file
** -v = verify, as for copy
** -? = report usage
** Defaults
** source directory (default curr)
** target directory (default /d0)
**
** copyright 1991 by Cowen Software Ltd
** 23 Bristol Ave, Levenshulme, Manchester,
** GB-M19 3NU, England, UK
** released to the public domain for non-commercial use
**
*/
#include <stdio.h>
#include <modes.h>
#include <ctype.h>
#include <direct.h>
extern int os9forkc();
extern int errno;
extern char **environ;
#define TRUE 1
#define FALSE 0
#define trace FALSE
#define FNSIZ 132
#define dirlength 300
#define comlength 600
#define maxf 20
char *fptr[maxf];
int flen[maxf];
int numf = 0;
int i;
char dext[] = "_bak";
char dextflag;
char eflag = FALSE; /* execute */
char bflag = FALSE; /* buffer specified*/
char pflag = FALSE; /* pause specified*/
char kflag = FALSE; /* omit /h0/os9boot */
char lflag = FALSE; /* not recursive */
char sflag = FALSE; /* start specified*/
char tflag = FALSE; /* terminate specified*/
char srcflag = FALSE; /* source specified*/
char tarflag = FALSE; /* target specified*/
char vflag = FALSE; /* verify specified*/
char *sptr;
char *tptr;
char *tarptr;
char *srcptr;
char *bptr;
char *vptr;
/* defaults */
char bdef[] = "-b=4k";
char sdef[] = " ";
char tdef[] = "~";
char srcdef[] = ".";
char tardef[] = "/d0";
char voff[] = " ";
char von[] = "-v";
char slash[] = "/";
int dnum = 0,
dind = 0;
char *dptr[50];
char relpath[dirlength];
int rlen,
srclen,
tarlen;
struct fildes srcdb;
struct fildes tardb;
char srcpath[comlength];
char tarpath[comlength];
char filename[32]; /* holds each file name */
char *copyblk[] = { "copy","-r",0,0,0,0,0};
char *delblk[] = { "del",0,0};
int portfd;
char env[] = "/term";
main(argc,argv)
int argc;
char **argv;
{
char *p;
char *portptr;
int tarfd;
int x;
portptr = getenv("PORT");
#if trace
fprintf(stderr,"portptr = %s \n",portptr);
fflush(stderr);
#endif
if (portptr == NULL) portfd = 0;
else portfd = open(portptr, S_IREAD);
if (portfd == -1) error("can't open port",0);
#if trace
fprintf(stderr,"params: = %d \n",argc);
fflush(stderr);
#endif
getflags(argc,argv);
if (numf > 0) for (x=0;x<numf;x++)
flen[x] = strlen(fptr[x]);
while ( (--argc) )
{
if (*(p = *++argv) != '-')
{
if (!srcflag) { srcptr = p; srcflag = TRUE; continue;}
if (!tarflag) { tarptr = p; tarflag = TRUE; continue;}
error("Too many parameters",0);
}
}
if ( (dnum > 0) & (sflag | tflag) )
error("Sorry, you can't use -d with -s or -t",0);
if (sflag == FALSE) sptr = sdef;
if (tflag == FALSE) tptr = tdef;
if (bflag == FALSE) bptr = bdef;
if (srcflag == FALSE) srcptr = srcdef;
if (tarflag == FALSE) tarptr = tardef;
if (vflag == FALSE) vptr = voff; else vptr = von;
copyblk[4] = bptr;
if (vflag) copyblk[5] = vptr;
if (pflag) confirm();
if ( (tarfd = open(tarptr,S_IFDIR + S_IREAD) ) == -1)
error ("Can't open directory ",tarptr);
close(tarfd);
srclen = strlen(srcptr);
tarlen = strlen(tarptr);
#if trace
fprintf(stderr,"bptr=%s vptr=%s sptr=%s tptr=%s srcptr=%s tarptr=%s \n",
bptr, vptr, sptr, tptr, srcptr, tarptr);
fflush(stderr);
#endif
if (dnum == 0) dodees("");
if (dnum > 0) while (dnum > dind) dodees(dptr[dind++]);
}
dodees(thisdee)
char *thisdee;
{
int srcfd;
#if trace
fprintf(stderr,"dodees (entry); thisdee %s;\n",thisdee);
fflush(stderr);
#endif
strcpy(relpath,thisdee);
strcpy(tarpath, tarptr);
strcpy(srcpath, srcptr);
if (dnum > 0) { strcat(tarpath, slash);
strcat(srcpath, slash);
}
strcat(tarpath, relpath);
strcat(srcpath, relpath);
fprintf(stderr,"Backing up %s/%s to %s/%s onto %s\n",
srcpath,sptr,srcpath,tptr,tarpath);
if ( (srcfd = open(srcpath,S_IFDIR + S_IREAD) ) == -1)
error ("Can't open directory ",srcpath);
donext(srcfd);
close(srcfd);
#if trace
fprintf(stderr,"dodees(end) srcfd=%d \n",srcfd);
fflush(stderr);
#endif
}
donext(srcfd,rellen)
int srcfd; /* dir path no*/
/* This procedure is called for each directory
which is to be copied.
Initially it checks the target directory exists, and if not
it tries to create it. Then it opens the directory, and
reads all files in it.
Each valid file is passed to checkfile for processing
NOTE the file name as given on entry has each
filename in turn appended to it, then the original length restored
this means that we must check to see if the tree of directories
has got too long, and overflowed the dirname buffer.
*/
{
struct dirent dirbuf; /* single dir ent read buf */
int tarfd;
int rply;
int rellen; /* length of relname */
int filelen;
rellen = strlen(relpath);
#if trace
fprintf(stderr,"donext srcfd = %d; rellen = %d \n",srcfd,rellen);
fflush(stderr);
#endif
if (rellen + 1 > dirlength) error("pathname too long",0);
if (rellen + tarlen + 1 > comlength ) error( "target path too long",0);
if (rellen > 0) { strcat(relpath, slash);
rellen++;
}
if ( (tarfd = open(tarpath,S_IFDIR + S_IREAD) ) == -1)
{
printf("makdir %s\n",tarpath);
if (eflag) {
makdir (tarpath,S_IFDIR,
S_IREAD+S_IWRITE+S_IOREAD+S_IOWRITE);
if ( (tarfd = open(tarpath,S_IFDIR + S_IREAD) ) == -1)
error ("Can't open file ",tarpath);
}
}
if (tarfd != -1) close(tarfd);
while(rply = read(srcfd, &dirbuf, sizeof(dirbuf))) /* now copy names */
{
#if trace
fprintf(stderr,"donext(read) relpath=%s, rply = %d, dirbuf = %32s\n",
relpath, rply, &dirbuf);
fflush(stderr);
#endif
if (rply != sizeof(dirbuf)) error("error reading directory",0);
relpath[rellen] = '\0'; /* restore original length*/
strhcpy(filename, &dirbuf);
filename[28] = '\0'; /* shouldn't be needed
but I am a pessimist */
#if trace
fprintf(stderr,"filename = %d %d %d %s \n",
filename[0],filename[1],filename[2],filename);
fflush(stderr);
#endif
if (filename[0] == 0) continue;
if (strcmp(filename,".") == 0) continue;
if (strcmp(filename,"..") == 0) continue;
filelen = strlen(filename);
if ( (rellen + filelen + 1) > dirlength)
error ("Partial path is too long",relpath);
if ( (rellen + filelen + 1 + srclen) > comlength)
error ("Source directory path is too long",srcpath);
if ( (rellen + filelen + 1 + tarlen) > comlength)
error ("Target path is too long", tarpath);
strcat(relpath,filename); /* stick the next element
rlen = strlen(relpath); on to the rel path*/
strcpy(srcpath, srcptr);
strcat(srcpath, slash);
strcat(srcpath, relpath);
srclen = strlen(srcpath);
#if trace
fprintf(stderr,"donext(while) relpath=%s,srcpath=%s,tarpath=%s\n",
relpath, srcpath, tarpath);
fflush(stderr);
#endif
if (strcmp(relpath, sptr) < 0) continue;
if (strcmp(relpath, tptr) >= 0) continue;
strcpy(tarpath, tarptr);
strcat(tarpath, slash);
strcat(tarpath, relpath);
tarlen = strlen(tarpath);
checkfile(); /* check this file */
}
#if trace
fprintf(stderr,"donext(end) \n");
fflush(stderr);
#endif
}
checkfile()
/* now check each file, as follows
1, try to open it as a file, if that fails try as a directory,
in checkdir.
2, otherwise look at the file details, if the file is already backed
up, do nothing, otherwise back it up.
*/
{
int srcfd;
int x;
#if trace
fprintf(stderr,"checkfile (entry); srcpath %s; tarpath %s\n",srcpath,tarpath);
fflush(stderr);
#endif
srcfd = open(srcpath, S_IREAD);
if (srcfd == -1) {checkdir(); return;}
x = _gs_gfd(srcfd,&srcdb,sizeof(srcdb));
if (x == -1) { fprintf(stderr,"FD Read Fail %d on %s",errno,srcpath);
error("aborting",0);
}
close(srcfd);
if (checkdate() ) copyfile();
}
checkdate()
/* returns false if it's a suffix to omit
else opens target files, and checks dates,
returns true if
1, target does not exist
2. source has later date than target
3, source and target have different file sizes
*/
{
int x;
int tarfd;
#if trace
fprintf(stderr,"numf=%d; tarpath= %s; tarlen=%d;",numf,tarpath,tarlen);
fprintf(stderr,"fptr[0]=%s; flen[0]=%d\n",fptr[0],flen[0]);
fflush(stderr);
#endif
if (numf > 0) for (x=0;x<numf;x++)
if ( ! strucmp (fptr[x],&tarpath[tarlen-flen[x]]) )
return(FALSE);
tarfd = open(tarpath, S_IREAD);
if (tarfd == -1 ) return(TRUE);
x = _gs_gfd(tarfd,&tardb,sizeof(tardb));
if (x == -1) { fprintf(stderr,"FD Read Fail %d on %s",errno,tarpath);
error("aborting",0);
}
close(tarfd);
#if trace
fprintf(stderr,"size- src: %d, tar: %d\n",srcdb.fd_fsize[0],tardb.fd_fsize[0]);
fflush(stderr);
#endif
if (strncmp(srcdb.fd_fsize,tardb.fd_fsize,4) > 0 ) return (TRUE);
if (strncmp(srcdb.fd_date,tardb.fd_date,5) > 0 ) return (TRUE);
return(FALSE);
}
checkdir()
/* try to open as a directory, if it is one then pass it back to donext.
*/
{
int srcfd;
#if trace
fprintf(stderr,"checkdir (entry); srcpath %s;\n",srcpath);
fflush(stderr);
#endif
srcfd = open(srcpath,S_IFDIR + S_IREAD);
if (srcfd == -1) { fprintf(stderr,"Open Fail %d on %s \n",errno,srcpath);
fflush(stderr); return;
}
if ( !lflag ) donext(srcfd);
close(srcfd);
#if trace
fprintf(stderr,"checkdir(end) srcfd=%d \n",srcfd);
fflush(stderr);
#endif
}
copyfile()
/* Now we have a file to copy - copy it if eflag or just
list it.
*/
{
int pid;
unsigned status;
if (kflag & (strucmp(filename,"OS9BOOT") == 0 ) ) return;
printf("copy -r %s %s %s %s\n", bptr,vptr,srcpath,tarpath);
if (eflag)
{
copyblk[2] = srcpath;
copyblk[3] = tarpath;
pid = os9exec(os9forkc,copyblk[0],copyblk,environ,0,0,3);
if (pid < 0) error("Can't create copy process",0);
wait(&status);
if (status != 0)
{ fprintf(stderr,"\ncan't copy %s to %s\n",srcpath, tarpath);
fprintf(stderr,"Deleting %s\n", tarpath);
delblk[1] = tarpath;
pid = os9exec(os9forkc,delblk[0],delblk,environ,0,0,3);
if (pid < 0) error("Can't create delete process",0);
wait(&status);
if (status != 0) error("Delete Failed!!!",0);
else error("Deleted OK",0);
}
}
}
getflags(carg,varg)
int carg;
char **varg;
{
char *p, c;
while ( (--carg) )
{
if (*(p = *++varg) == '-')
{
while (c = *++p)
{
switch (c)
{
case '?' :
help();
break;
case 'e' : /*execute*/
eflag = TRUE;
break;
case 'l' :
lflag = TRUE; /* not recursive*/
break;
case 'p' : /* pause */
pflag = TRUE;
break;
case 'v' :
vflag = TRUE; /* verify */
break;
case 'k' :
kflag = TRUE; /* omit /h0/os9boot */
break;
case 'd' : /* selected dirs */
if (dnum >= 49) error("Too many -d 's",0);
while(*++p == ' ');
if (*p++ != '=') error ("no suffix for -d option",0);
if (*p == '\0') error("null suffix for -d option",0);
dptr[dnum++] = p;
while (c = *p) p++; /* skip past extension name */
p--; /* and point to the closing null */
break;
case 'f' :
dextflag = FALSE;
while(*++p == ' ');
if (*p++ != '=') dextflag = TRUE;
else if (*p == '\0') dextflag = TRUE;
if (numf >= maxf) error("Too many -f parameters",0);
if (dextflag) fptr[numf++] = dext;
else fptr[numf++] = p;
while (c = *p) p++; /* skip past extension name */
p--; /* and point to the closing null */
break;
case 'b' :
bptr = p;
*(--bptr) = '-';
while(*++p == ' ');
if (*p++ != '=') error ("no suffix for -b option",0);
if (*p == '\0') error ("null suffix for -b option",0);
if (bflag) error("Too many -b parameters",0);
bflag = TRUE;
while (c = *p) p++; /* skip past extension name */
p--; /* and point to the closing null */
break;
case 's' :
while(*++p == ' ');
if (*p++ != '=') error ("no suffix for -s option",0);
if (*p == '\0') error ("null suffix for -s option",0);
if (sflag) error("Too many -s parameters",0);
sflag = TRUE;
sptr = p;
while (c = *p) p++; /* skip past extension name */
p--; /* and point to the closing null */
break;
case 't' :
while(*++p == ' ');
if (*p++ != '=') error ("no suffix for -t option",0);
if (*p == '\0') error ("null suffix for -t option",0);
if (tflag) error("Too many -t parameters",0);
tflag = TRUE;
tptr = p;
while (c = *p) p++; /* skip past extension name */
p--; /* and point to the closing null */
break;
default :
help();
break;
}
}
}
}
}
confirm()
{
char keypress;
#if trace
fprintf(stderr,"portfd = %d \n",portfd);
fflush(stderr);
#endif
do { fprintf(stderr,"Continue? ");
fflush(stderr);
read(portfd,&keypress,1);
fprintf(stderr,"\n");
fflush(stderr);
keypress = toupper(keypress);
if (keypress == 'N') exit(1);
}
while (keypress != 'Y');
pflag = FALSE;
}
error(s1, s2)
char *s1, *s2;
/*
** write the two strings passed and then a <cr>
*/
{
if (s1)
fprintf(stderr, "%s", s1 );
if (s2)
fprintf(stderr, "%s", s2 );
fprintf(stderr, "\n");
fflush(stderr);
exit (1);
}
help()
/*
** provide usage info for this srcpath
*/
{
fprintf(stderr, "Usage: Dback [-options] <fromdir> <todir> [-options]\n" );
fprintf(stderr, " -b=<no>k= copy buffer \n" );
fprintf(stderr, " -d=file = backup selected directory \n" );
fprintf(stderr, " -e = execute \n" );
fprintf(stderr, " -f=xxx = omit files suffixed xxx (default:_BAK)\n" );
fprintf(stderr, " -k = omit OS9Boot files \n" );
fprintf(stderr, " -l = no recursion\n" );
fprintf(stderr, " -p = pause before copying \n" );
fprintf(stderr, " -s=file = start copying at \n" );
fprintf(stderr, " -t=file = terminate copying at \n" );
fprintf(stderr, " -v = verify \n" );
fprintf(stderr, " -? = report help \n" );
fprintf(stderr, "Defaults \n" );
fprintf(stderr, " source directory (default = . ) \n" );
fprintf(stderr, " target directory (default = /d0) \n" );
fprintf(stderr, "\n");
fflush(stderr);
exit (0);
}