home *** CD-ROM | disk | FTP | other *** search
- /* ***********************************************************************
- ** NTREE - The search for a better tree program has ended **
- ** Version 2.4.0 [OS/2 and DOS versions] **
- ** A hack by Mitch Lichtenberg **
- ** Modified for OS/2 by Lester Waters **
- ** Note that this cannot be a bimodal application [yet] since **
- ** the emulation of the directory handles doesn't work right **
- ** when doing lots of recursion (more than 2 levels deep). **
- ** Main module File: NTREE.C **
- *********************************************************************** */
-
- /* +-------------------------------------------------------------------+
- | Defines: |
- | |
- | OS2 - Builds version for use under OS/2. |
- | If not defined, then DOS is assumed. |
- +-------------------------------------------------------------------+ */
-
-
- #include <stdio.h>
- #include <string.h>
- #include <signal.h>
- #include <errno.h>
-
- #ifdef OS2
- #include <error.h>
- extern int far pascal DOSFINDFIRST();
- extern int far pascal DOSFINDNEXT();
- extern int far pascal DOSFINDCLOSE();
- extern int far pascal DOSSETVERIFY();
- extern int far pascal DOSQVERIFY();
- extern int far pascal DOSSETFILEMODE();
- #endif
-
- extern int docopyfile();
- unsigned int curdrive();
- unsigned int clussize();
-
-
- /* +-------------------------------------------------------------------+
- | Constants |
- +-------------------------------------------------------------------+ */
-
- #define switchp(x) ((*x) == '/')
-
- #define FREADONLY 0x01
- #define FHIDDEN 0x02
- #define FSYSTEM 0x04
- #define FLABEL 0x08
- #define FDIRECTORY 0x10
- #define FARCHIVE 0x20
-
- /*
- * switch masks
- */
- #define SFILES 0x0001
- #define SHIDDEN 0x0002
- #define SVERIFY 0x0004
- #define SQUERY 0x0008
- #define SDELETE 0x0010
- #define SARC 0x0020
- #define SUPDATE 0x0040
- #define SREALLY 0x0080
- #define SDATE 0x0100
- #define SOVER 0x0200
- #define SCALL 0x0400
- #define SCOPY 0x0800
- #define SDIR 0x1000
- #define STOTAL 0x2000
- #define SBAT 0x4000
- #define SINFO 0x8000
-
- #define SQUIET 0x0001 /* sw. word 2 */
- #define SSILENT 0x0002 /* sw. word 2 */
- #define SDEBUG 0x8000 /* sw. word 2 */
-
- #ifndef ERROR_ACCESS_DENIED
- #define ERROR_ACCESS_DENIED 0x0005
- #endif
-
- /* +-------------------------------------------------------------------+
- | Structures |
- +-------------------------------------------------------------------+ */
-
- typedef unsigned char byte;
- typedef unsigned int word;
- typedef unsigned long dword;
-
- typedef struct FileDate {
- unsigned int second : 5;
- unsigned int minute : 6;
- unsigned int hour : 5;
- unsigned int day : 5;
- unsigned int month : 4;
- unsigned int year : 7;
- } FILEDATE;
-
- typedef struct cons {
- char *str;
- int num;
- } CONS;
-
- typedef struct btree {
- char *name; /* name of node */
- char *subname; /* name of just this file */
- struct btree *child; /* children */
- struct btree *sibling; /* brothers */
- } BTREE;
-
- #ifdef OS2
- typedef struct FileName {
- FILEDATE fd; /* this is an OS/2 type DTA */
- unsigned int adate;
- unsigned int atime;
- unsigned int wdate;
- unsigned int wtime;
- unsigned long filesize;
- unsigned long filealloc;
- unsigned int attribute;
- unsigned char namelen;
- unsigned char name[64];
- } FILENAME;
-
- #else
- typedef struct FileName { /* this is a DTA for DOS */
- char reserved[21];
- byte attribute;
- FILEDATE fd;
- dword filesize;
- char name[14];
- } FILENAME;
- #endif
-
-
- /* +-------------------------------------------------------------------+
- | global variables |
- +-------------------------------------------------------------------+ */
-
- FILENAME workname;
-
- #ifndef OS2
- FILENAME *dossetdta();
- #endif
-
- int oldverify = 0;
-
- int fncount = 0;
-
- unsigned int dircount;
- unsigned int filecount;
-
- unsigned long total;
- unsigned long clus;
- unsigned long fclus;
- unsigned long allocunit;
-
- char inwildcard[20];
- char infnam[64];
- char outfnam[64];
- char ncallstr[64];
- char dbcallstr[64];
- char dacallstr[64];
- char rawoutfnam[64];
-
- int inlen,outlen;
-
- char temp[64];
- char temp2[64];
-
- word switches = 0;
- word switches2 = 0;
-
- word verbose = 1; /* 1 means write to stdout */
- word showerr = 1; /* 1 means write to stderr */
-
- #ifdef OS2
- char *version = "NTREE version 2.4 [OS/2 version]\n";
- #else
- char *version = "NTREE version 2.4 [DOS version]\n";
- #endif
-
- CONS switchnames[] = {
- {"A",SFILES}, /* enumerate all files */
- {"H",SHIDDEN}, /* hidden too */
- {"V",SVERIFY}, /* turn on verify */
- {"Q",SQUERY}, /* query mode on */
- {"D",SDELETE}, /* delete tree */
- {"ARC",SARC}, /* use ARC to save tree */
- {"U",SUPDATE}, /* update (don't do files already done) */
- {"YES",SREALLY}, /* don't ask for confirmation */
- {"DATE",SDATE}, /* copy only if source has later date */
- {"O",SOVER}, /* overwrite dest */
- {"C",SCOPY}, /* needed for copy op */
- {"DIR",SDIR}, /* display <DIR> for directories*/
- {"T",STOTAL}, /* total space */
- {"BAT",SBAT}, /* don't do system commands just echo */
- {"I",SINFO}, /* file info too */
- {NULL,NULL}};
-
- CONS switchnames2[] = {
- {"QUIET",SQUIET}, /* don't write to stdout */
- {"SILENT",SSILENT}, /* don't write anywhere */
- {"DEBUG", SDEBUG}, /* enable debugging messages */
- {NULL,NULL}};
-
- extern unsigned int errno;
-
- /* +-------------------------------------------------------------------+
- | main(argc,argv) |
- | the beginning of the world |
- +-------------------------------------------------------------------+ */
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int a,b;
- char *x,*y;
- BTREE *t;
- BTREE *maketree();
- int inthndlr();
-
-
- fprintf(stderr,version);
-
- if (argc < 2) usage();
-
- strcpy(ncallstr,"");
- strcpy(dacallstr,"");
- strcpy(dbcallstr,"");
-
- a = 1;
- argv++;
- while (a < argc) {
- if (strcmpi(*argv,"/CALL") == 0) {
- a++; argv++;
- strcpy(ncallstr,*argv);
- switches |= SCALL | SFILES;
- a++; argv++;
- continue;
- }
- if (strcmpi(*argv,"/BEFORE") == 0) {
- a++; argv++;
- strcpy(dbcallstr,*argv);
- switches |= SCALL;
- a++; argv++;
- continue;
- }
- if (strcmpi(*argv,"/AFTER") == 0) {
- a++; argv++;
- strcpy(dacallstr,*argv);
- switches |= SCALL;
- a++; argv++;
- continue;
- }
- if (switchp(*argv)) setswitches(*argv);
- else switch (fncount) {
- case 0: strcpy(infnam,*argv); fncount++; break;
- case 1: strcpy(outfnam,*argv); fncount++; break;
- case 2: fatalerr("Incorrect number of parameters");
- }
- a++; argv++;
- }
-
- /* now, process input file name into wildcard */
- strcpy(inwildcard,"*.*"); /* default */
-
- strupr(infnam);
- if (!strchr(infnam,'\\')) {
- if (infnam[1] == ':') {
- getdir(infnam[0]-'@',temp);
- strcpy(temp2,infnam+2);
- pathize(temp,temp2,infnam);
- }
- else {
- getcwd(temp,80);
- strcpy(temp2,infnam);
- pathize(temp,temp2,infnam);
- }
- }
-
-
- x = strchr(infnam,'?');
- y = strchr(infnam,'*'); /* find first of either of these */
- if (x > y) y = x;
- if (y) {
- while (y >= infnam) {
- if (*y == '\\') break;
- if (*y == ':') break;
- y--;
- }
- y++; /* now y points to start of wildcard */
-
- x = strtok(y,"/");
- if (y != infnam) strcpy(inwildcard,x);
- *y = '\0'; /* zap end of string */
- y = strtok(NULL,""); /* get rest of switches */
- }
- else {
- if (x = strchr(infnam,'/')) {
- *x = '\0';
- y = x+1;
- }
- }
-
- if (y) {
- sprintf(temp,"/%s",y);
- setswitches(temp);
- }
-
-
- x = strchr(outfnam,'?');
- y = strchr(outfnam,'*'); /* find first of either of these */
- if (x && y && (x > y)) y = x;
- if (x && !y) y = x;
- if (y) {
- while (y >= outfnam) {
- if (*y == '\\') break;
- if (*y == ':') break;
- y--;
- }
- y++; /* now y points to start of wildcard */
-
- y = strtok(y,"/"); /* get switches */
- *y = '\0';
- y = strtok(NULL,""); /* get rest of switches */
- }
- else {
- if (x = strchr(outfnam,'/')) {
- *x = '\0';
- y = x+1;
- }
- }
-
- if (y) {
- sprintf(temp,"/%s",y);
- setswitches(temp);
- }
-
- if ((strlen(infnam) == 2) && (infnam[1] == ':')) {
- strupr(infnam);
- getdir((*infnam) - '@',infnam);
- }
- if ((strlen(outfnam) == 2) && (outfnam[1] == ':')) {
- strupr(outfnam);
- getdir((*outfnam) - '@',outfnam);
- }
-
- y = infnam+strlen(infnam)-1; if (*y != '\\') strcat(infnam,"\\");
- y = outfnam+strlen(outfnam)-1; if (*y != '\\') strcat(outfnam,"\\");
-
- if (strcmp(infnam,".\\") == 0) {
- getdir(curdrive(),infnam);
- strcat(infnam,"\\");
- }
- if (strcmp(outfnam,".\\") == 0) {
- getdir(curdrive(),outfnam);
- strcat(outfnam,"\\");
- }
-
-
- strcpy(rawoutfnam,outfnam);
- rmslash(rawoutfnam);
-
- if (switches2 & SDEBUG)
- { printf("Before fixup():\n");
- printf("Input filename: %s\n",infnam);
- printf("output filename: %s\n",outfnam);
- };
-
- fixup(infnam); /* add current drive & dir */
- fixup(outfnam);
-
- inlen = strlen(infnam);
- outlen = strlen(outfnam);
-
- if (switches2 & SDEBUG)
- { printf("After fixup():\n");
- printf("Input filename: %s\n",infnam);
- printf("output filename: %s\n",outfnam);
- printf("wildcard string: %s\n",inwildcard);
- printf("switch masks: %04X %04X\n",switches, switches2);
- };
-
- signal(SIGINT,inthndlr);
-
- #ifdef OS2
- DOSQVERIFY((int far *) &oldverify);
- if (switches & SVERIFY) DOSSETVERIFY(1);
- #else
- oldverify = getverify();
- if (switches & SVERIFY) setverify(1);
- #endif
-
- /* switch implicants */
-
- if (switches & SDELETE) switches |= SFILES;
- if (switches & SCOPY) switches |= SFILES;
- if (switches & STOTAL) switches |= SFILES;
- if (switches & SINFO) switches |= SFILES;
- if (switches & SDATE) switches |= SOVER;
-
-
- b = (switches & (SCOPY | SDELETE | SARC | STOTAL | SCALL));
- a = 0;
- while (b) {
- if (b & 1) a++;
- b >>= 1;
- }
- if (a > 1) fatalerr("Cannot do more than one command at a time");
-
- if (switches2 & SQUIET) verbose = 0;
- if (switches2 & SSILENT) verbose = showerr = 0;
-
- if (switches & SCOPY) tcopy();
- else if (switches & SDELETE) tdelete();
- else if (switches & SARC) tarchive();
- else if (switches & STOTAL) ttotal();
- else if (switches & SCALL) tcall();
- else tdisplay();
-
-
- }
-
-
- /* +-------------------------------------------------------------------+
- | setswitches(cp) |
- | sets switches from string ptr |
- +-------------------------------------------------------------------+ */
- setswitches(cp)
- char *cp;
- {
- static char *brk = "/";
- char *tok;
- int a;
-
- tok = strtok(cp,brk);
- while (tok) {
- a = assoc(tok,switchnames);
- if (a == 0) {
- a = assoc(tok,switchnames2);
- if (a == 0) fatalerr("Unrecognized switch: %s",tok);
- else switches2 |= a;
- }
- else switches |= a;
- tok = strtok(NULL,brk);
- }
- }
-
-
- /* +-------------------------------------------------------------------+
- | fixup(string) |
- | Fixes up dir/path spec to be fully formed |
- +-------------------------------------------------------------------+ */
- fixup(str)
- char *str;
- {
- char nstr[70];
- char buf[70];
-
- strupr(str);
- if (*str == '\\') { /* just add directory */
- sprintf(nstr,"%c:%s",curdrive()+'@',str);
- strcpy(str,nstr);
- return;
- }
- if ((*(str+1) == ':') && (*(str+2) != '\\')) { /* add directory */
- getdir((*str) - '@',buf);
- sprintf(nstr,"%c:\\%s\\%s",*str,buf+3,str+2);
- strcpy(str,nstr);
- return;
- }
- if ((*(str+1) != ':') && (*str != '\\')) { /* add drive & dir */
- getdir(curdrive(),buf);
- sprintf(nstr,"%c:\\%s\\%s",curdrive()+'@',buf+3,str);
- strcpy(str,nstr);
- return;
- }
- }
-
- /* +-------------------------------------------------------------------+
- | fatalerr(a,b,c,d,e) |
- | die with fatal error |
- +-------------------------------------------------------------------+ */
- fatalerr(a,b,c,d,e)
- unsigned char *a, *b, *c, *d, *e;
- {
- fprintf(stderr,"ntree: ");
- fprintf(stderr,a,b,c,d,e);
- fprintf(stderr,"\n");
- exit(1);
- }
-
-
- /* +-------------------------------------------------------------------+
- | printerr(a,b,c,d,e) |
- | print an error message |
- +-------------------------------------------------------------------+ */
- printerr(a,b,c,d,e)
- unsigned char *a, *b, *c, *d, *e;
- {
- fprintf(stderr,"ntree: ");
- fprintf(stderr,a,b,c,d,e);
- fprintf(stderr,"\n");
- }
-
-
- /* +-------------------------------------------------------------------+
- | assoc(str,lst) |
- | finds string in list |
- +-------------------------------------------------------------------+ */
- assoc(str,lst)
- char *str;
- CONS *lst;
- {
- while (lst->str) {
- if (strcmpi(lst->str,str) == 0) return lst->num;
- lst++;
- }
- return 0;
- }
-
-
- /* +-------------------------------------------------------------------+
- | dotree(path) |
- | returns BTREE starting at path |
- +-------------------------------------------------------------------+ */
- BTREE *dotree(path)
- char *path;
- {
- BTREE *node = NULL;
- BTREE *list = NULL;
- FILENAME fns;
- char npath[64]; /* path with wildcard */
- char rpath[64]; /* recursive call path */
- static char *stars = "*.*";
- int status;
- int attrib = FDIRECTORY;
- #ifdef OS2
- FILENAME far *fnsptr = &fns;
- unsigned int handle = 0xFFFF;
- int number = 1;
- #endif
-
- #ifndef OS2
- dossetdta(&fns);
- #endif
- strcpy(npath,path);
- strcat(npath,stars);
-
- if (switches & SHIDDEN) attrib |= FHIDDEN;
-
- #ifdef OS2
- status = DOSFINDFIRST((char far *) npath,
- (int far *) &handle,
- FDIRECTORY,
- fnsptr,
- sizeof(struct FileName),
- (int far *) &number,
- 0L);
- #else
- status = dosfindfirst(npath, FDIRECTORY);
- #endif
-
-
- while (status == 0) {
- if ((fns.attribute & FDIRECTORY) &&
- (fns.name[0] != '.')) { /* add to tree */
- node = (BTREE *) calloc(1,sizeof(BTREE));
- node->sibling = list;
- list = node;
- strcpy(rpath,path);
- strcat(rpath,fns.name);
- strcat(rpath,"\\");
- node->subname = strdup(fns.name);
- node->name = strdup(rpath);
- node->child = dotree(rpath);
- }
- #ifdef OS2
- status = DOSFINDNEXT( handle,
- fnsptr,
- sizeof(struct FileName),
- (int far *) &number);
- if (status == ERROR_INVALID_HANDLE)
- { printf("ntree: Invalid handle %u in DOSFINDNEXT()\n",
- handle);
- exit(1);
- };
- #else
- dossetdta(&fns);
- status = dosfindnext();
- #endif
- }
-
- #ifdef OS2
- DOSFINDCLOSE(handle);
- #endif
- return list;
- }
-
-
-
- /* +-------------------------------------------------------------------+
- | maketree(path) |
- | Returns btree for path, including starting dir |
- +-------------------------------------------------------------------+ */
- BTREE *maketree(path)
- char *path;
- {
- BTREE *btree;
- int flg = 0;
-
- btree = (BTREE *) calloc(1,sizeof(BTREE));
- btree->name = strdup(path);
- btree->sibling = NULL;
- btree->child = dotree(path);
- return btree;
- }
-
-
- /* +-------------------------------------------------------------------+
- | rmslash(str) |
- | removes last char of string if it is a backslash |
- +-------------------------------------------------------------------+ */
- rmslash(str)
- char *str;
- {
- int len;
-
- len = strlen(str);
- if ((len == 3) && (str[1] == ':') && (str[2] == '\\')) return;
- if (len == 0) return;
- len--;
- if (str[len] == '\\') str[len] = '\0';
- }
-
-
- /* +-------------------------------------------------------------------+
- | pathize(dir,name,path) |
- | makes a good pathname |
- +-------------------------------------------------------------------+ */
- pathize(dir,name,path)
- char *dir;
- char *name;
- char *path;
- {
- int len;
-
- strcpy(path,dir);
- len = strlen(path);
- if (len && (path[len-1] == '\\')) path[len-1] = '\0';
- if (*name != '\\') strcat(path,"\\");
- strcat(path,name);
- }
-
-
- /* +-------------------------------------------------------------------+
- | fexist(name,attrib) |
- | test for file exist (returns attrib if yes |
- +-------------------------------------------------------------------+ */
- fexist(name,attrib)
- char *name;
- int attrib;
- {
- int status;
- int handle = 0x0001;
- int number = 0x0001;
- #ifndef OS2
- FILENAME *olddta;
- #endif
-
- #ifdef OS2
- status = DOSFINDFIRST((char far *) name,
- (int far *) &handle,
- attrib,
- (FILENAME far *) &workname,
- sizeof(struct FileName),
- (int far *) &number,
- 0L);
- #else
- olddta = dossetdta(&workname);
- status = dosfindfirst(name, attrib);
- #endif
-
- if (status == 0) return (workname.attribute | 0x8000);
-
- return 0;
- }
-
-
-
- /* +-------------------------------------------------------------------+
- | subtreep(a,b) |
- | returns 1 if a and b are subtrees of one another |
- +-------------------------------------------------------------------+ */
- subtreep(a,b)
- char *a,*b;
- {
- if (strncmp(a,b,strlen(a)) == 0) return 1;
- if (strncmp(a,b,strlen(b)) == 0) return 1;
- return 0;
- }
-
-
- /* +-------------------------------------------------------------------+
- | rootdirp(str) |
- | returns 1 if str describes a root directory |
- +-------------------------------------------------------------------+ */
- rootdirp(str)
- char *str;
- {
- if (strcmp(str+1,":\\") == 0) return 1;
- if (strcmp(str,"\\") == 0) return 1;
- return 0;
- }
-
-
-
- /* +-------------------------------------------------------------------+
- | printdir(t,fnam) |
- | prints a dir file name |
- +-------------------------------------------------------------------+ */
- printdir(t,fnam)
- BTREE *t;
- char *fnam;
- {
- char newname[64];
-
- strcpy(newname,fnam);
- rmslash(newname);
- if (switches & SDIR) printf("%s\t<DIR>\n",newname);
- else if (!(switches & SFILES)) printf("%s\n",newname);
-
- if (switches & SINFO) dircount++;
- }
-
-
- /* +-------------------------------------------------------------------+
- | printname(t,str,fns) |
- | prints filename |
- +-------------------------------------------------------------------+ */
- printname(t,str,fns)
- BTREE *t;
- char *str;
- FILENAME *fns;
- {
- char fooname[64];
-
- strcpy(fooname,str);
- rmslash(fooname);
- if (switches & SINFO) {
- filecount++;
- total += fns->filesize;
- clus += fns->filesize / allocunit;
- fclus += fns->filesize / 512L;
-
- if ((fns->filesize % allocunit) != 0) clus++;
- if ((fns->filesize % 512L) != 0) fclus++;
-
- printf("%-50.50s %8lu %02d-%02d-%02d %02d:%02d\n",
- str,fns->filesize,fns->fd.month+1,fns->fd.day,
- fns->fd.year+1980,fns->fd.hour,fns->fd.minute);
- }
- else {
- puts(fooname);
- }
-
- }
-
-
- /* +-------------------------------------------------------------------+
- | enumfiles(path,t,fn) |
- | enumerate all files on path |
- +-------------------------------------------------------------------+ */
- enumfiles(path,t,fn)
- char *path;
- BTREE *t;
- int (*fn)();
- {
- FILENAME fns;
- int status;
- int attrib = 0;
- char npath[64];
- char nfile[64];
- #ifdef OS2
- FILENAME far *fnsptr = &fns;
- unsigned int handle = 0xFFFF;
- unsigned int number = 1;
- #endif
-
- strcpy(npath,path);
- strcat(npath,inwildcard);
-
- if (switches & SHIDDEN) attrib |= FHIDDEN;
-
- #ifdef OS2
- status = DOSFINDFIRST((char far *) npath,
- (int far *) &handle,
- attrib,
- fnsptr,
- sizeof(struct FileName),
- (int far *) &number,
- 0L);
- #else
- dossetdta(&fns);
- status = dosfindfirst(npath, attrib);
- #endif
-
- while (status == 0) {
- strcpy(nfile,path);
- strcat(nfile,fns.name);
- if (fns.name[0] != '.') if (fn) (*fn)(t,nfile,&fns);
- #ifdef OS2
- status = DOSFINDNEXT( handle,
- fnsptr,
- sizeof(struct FileName),
- (int far *) &number);
- #else
- dossetdta(&fns);
- status = dosfindnext();
- #endif
- }
- }
-
-
-
- /* +-------------------------------------------------------------------+
- | maptree(tree,prefn,postfn,namefn) |
- | map out contents of b-tree |
- +-------------------------------------------------------------------+ */
- maptree(tree,prefn,postfn,namefn)
- BTREE *tree;
- int (*prefn)();
- int (*postfn)();
- int (*namefn)();
- {
- int i;
-
- if (!tree) return;
-
- while (tree) {
- if (prefn) (*prefn)(tree,tree->name);
- if (switches & SFILES) {
- enumfiles(tree->name,tree,namefn);
- }
- if (tree->child) maptree(tree->child,prefn,postfn,namefn);
- if (postfn) (*postfn)(tree,tree->name);
- tree = tree->sibling;
- }
- }
-
-
- /* +-------------------------------------------------------------------+
- | zapdir(name) |
- | delete directory |
- +-------------------------------------------------------------------+ */
- zapdir(t,name)
- BTREE *t;
- char *name;
- {
- char newname[64];
-
- strcpy(newname,name);
- rmslash(newname);
- if (rootdirp(name)) return; /* don't delete root dir */
- if (verbose) printf("Deleting directory: %s\n",newname);
- if (rmdir(newname) != 0) {
- if (showerr) fprintf(stderr,"Could not delete directory: %s\n",newname);
- }
- }
-
-
- /* +-------------------------------------------------------------------+
- | zapfile(t,name,fns) |
- | delete file |
- +-------------------------------------------------------------------+ */
- zapfile(t,name,fns)
- BTREE *t;
- char *name;
- FILENAME *fns;
- {
- if (!doquery("Delete file %s? (Y/N/A/Q): ",name)) return;
- if (verbose) printf("Deleting file: %s\n",name);
- if (unlink(name) != 0) {
- if (showerr) fprintf(stderr,"Could not delete file: %s\n",name);
- }
- }
-
-
- /* +-------------------------------------------------------------------+
- | copydir(t,name) |
- | copy directory (prefn) |
- +-------------------------------------------------------------------+ */
- copydir(t,name)
- BTREE *t;
- char *name;
- {
- char newdir[64];
-
- strcpy(newdir,outfnam);
- strcat(newdir,name+inlen);
- if (rootdirp(newdir)) return;
- rmslash(newdir);
- if (fexist(newdir,FDIRECTORY)) {
- #ifdef PAUL_DOESNT_LIKE_THIS
- printf("Directory already exists: %s\n",newdir);
- #endif
- return;
- }
- if (verbose) printf("Creating directory: %s\n",newdir);
- if (mkdir(newdir) != 0) {
- if (errno != EACCES) fatalerr("Could not create directory: %s\n",newdir);
- #ifdef PAUL_DOESNT_LIKE_THIS
- else printf("Directory already exists: %s\n",newdir);
- #endif
- }
-
- }
-
-
- /* +-------------------------------------------------------------------+
- | copyfile(t,name,fns) |
- | namefn for copy file |
- +-------------------------------------------------------------------+ */
- copyfile(t,name,fns)
- BTREE *t;
- char *name;
- FILENAME *fns;
- {
- char newname[64];
- int attr;
- int newatt;
-
-
- if (switches & SUPDATE) {
- if (!(fns->attribute & FARCHIVE)) return;
- #ifdef OS2
- DOSSETFILEMODE( (char far *) name,
- fns->attribute & ~FARCHIVE,
- 0L);
- #else
- doschmod(name,fns->attribute & ~FARCHIVE);
- #endif
- newatt = fns->attribute & ~FARCHIVE;
- }
- else newatt = fns->attribute;
-
- strcpy(newname,outfnam);
- strcat(newname,name+inlen);
-
- attr = fexist(newname,0);
-
- if (switches & SDATE) {
- if (cmpdate(&(fns->fd),&(workname.fd)) != 1) return;
- }
-
- if (!doquery("Copy file %s? (Y/N/A/Q): ",name)) return;
-
- if (attr && (!(switches & SOVER))) {
- if (verbose) printf("File already exists: %s\n",newname);
- return;
- }
- if (attr & FREADONLY) {
- if (verbose) printf("File is read-only: %s\n",newname);
- return;
- }
-
- if (verbose) printf("Copying %s to %s\n",name,newname);
-
- switch (docopyfile(name,newname))
- { case 0: break;
- case 1: {
- if (errno = ERROR_ACCESS_DENIED)
- printerr("access to source file %s denied",name);
- else
- fatalerr("could not open source file: %s",name);
- }
- case 2: {
- if (errno = ERROR_ACCESS_DENIED)
- printerr("access to output file %s denied",newname);
- else
- fatalerr("could not open destination file: %s",newname);
- }
- case 3: fatalerr("could not read source file: %s",name);
- case 4: fatalerr("could not write destination file: %s",newname);
- case 5: fatalerr("could not allocate memory for copy");
- }
-
- #ifdef OS2
- DOSSETFILEMODE( (char far *) newname,
- newatt,
- 0L);
- #else
- doschmod(newname,newatt);
- #endif
- }
-
- /* +-------------------------------------------------------------------+
- | totaldir(t,name) |
- | totals directories |
- +-------------------------------------------------------------------+ */
- totaldir(t,name)
- BTREE *t;
- char *name;
- {
- dircount++;
- }
-
- /* +-------------------------------------------------------------------+
- | totalfile(t,name,fns) |
- | totals all files |
- +-------------------------------------------------------------------+ */
- totalfile(t,name,fns)
- BTREE *t;
- char *name;
- FILENAME *fns;
- {
- filecount++;
- total += fns->filesize;
- clus += fns->filesize / allocunit;
- fclus += fns->filesize / 512L;
-
- if ((fns->filesize % allocunit) != 0) clus++;
- if ((fns->filesize % 512L) != 0) fclus++;
- }
-
-
-
-
-
- /* +-------------------------------------------------------------------+
- | arcdir(name) |
- | archive directory |
- +-------------------------------------------------------------------+ */
- arcdir(t,name)
- BTREE *t;
- char *name;
- {
- char olddir[64];
- char arcname[64];
- char cmd[128];
- char *x;
- char *y;
- int cancel = 0;
-
- getcwd(olddir,64); /* get current drive/dir */
- strcpy(arcname,name); /* temp */
- rmslash(arcname);
- changedir(arcname); /* change to this new dir */
- if (verbose) printf("Now working on directory: %s\n",arcname);
-
- if (strcmp(infnam,name) == 0) strcpy(arcname,rawoutfnam); /* reached end */
- else {
- sprintf(arcname,"..\\%s.ARC",t->subname);
- }
-
- if (!cancel) {
- if (fexist(arcname,0)) {
- if (verbose) printf("Deleting old archive %s\n",arcname);
- unlink(arcname);
- }
- sprintf(cmd,"arc a %s %s *.arc",arcname,inwildcard);
- if (verbose) {
- fputs(cmd,stdout);
- fputc('\n',stdout);
- }
- system(cmd);
- }
-
- changedir(olddir);
- }
-
-
-
-
- /* +-------------------------------------------------------------------+
- | tdisplay() |
- | Display tree using given switches |
- +-------------------------------------------------------------------+ */
- tdisplay()
- {
- BTREE *t;
-
- if (fncount == 0) fatalerr("pathname missing for tree display");
- if (fncount != 1) fatalerr("incorrect number of pathnames");
-
- t = maketree(infnam); /* at least this one */
-
- allocunit = (unsigned long) clussize((*infnam) - '@');
- total = 0L;
- clus = 0L;
- fclus = 0L;
- dircount = 0;
- filecount = 0;
-
- maptree(t,printdir,NULL,printname);
-
- if (switches & SINFO) sayinfo();
- }
-
-
-
- /* +-------------------------------------------------------------------+
- | tdelete() |
- | delete all entries in tree |
- +-------------------------------------------------------------------+ */
- tdelete()
- {
- BTREE *t;
- char line[40];
-
- if (!(switches & SREALLY)) {
- fprintf(stderr,"Are you sure you want to delete %s%s? [NO]: ",
- infnam,inwildcard);
- while (1) {
- *line = '\0';
- gets(line);
- strupr(line);
- if (strcmp(line,"YES") == 0) break;
- if (strlen(line) == 0) fatalerr("abort");
- if (strcmp(line,"NO") == 0) fatalerr("abort");
- fprintf(stderr,"\nYou must type YES to delete the tree\nAre you sure? [NO]:");
- }
- }
-
- t = maketree(infnam);
-
- maptree(t,NULL,zapdir,zapfile);
- }
-
-
- /* +-------------------------------------------------------------------+
- | tarchive() |
- | archive all tree entries |
- +-------------------------------------------------------------------+ */
- tarchive()
- {
- BTREE *t;
-
- if (fncount != 2) usage();
-
- t = maketree(infnam);
-
- maptree(t,NULL,arcdir,NULL);
-
- }
-
- /* +-------------------------------------------------------------------+
- | tcopy() |
- | copy all entries in tree |
- +-------------------------------------------------------------------+ */
- tcopy()
- {
- BTREE *t;
-
- if (fncount != 2) {
- fprintf(stderr,"must supply two pathnames");
- usage();
- }
-
- if (subtreep(infnam,outfnam)) fatalerr("Trees are not disjoint: %s, %s\n",infnam,outfnam);
-
- t = maketree(infnam);
-
- maptree(t,copydir,NULL,copyfile);
-
- }
-
-
-
- /* +-------------------------------------------------------------------+
- | ttotal() |
- | totals all space in tree |
- +-------------------------------------------------------------------+ */
- ttotal()
- {
- BTREE *t;
-
- if (fncount != 1) usage();
-
- t = maketree(infnam);
-
- allocunit = (unsigned long) clussize((*infnam) - '@');
- total = 0L;
- clus = 0L;
- fclus = 0L;
- dircount = 0;
- filecount = 0;
-
- maptree(t,totaldir,NULL,totalfile);
-
- sayinfo();
- }
-
-
- /* +-------------------------------------------------------------------+
- | sayinfo() |
- | prints out drive info |
- +-------------------------------------------------------------------+ */
-
- sayinfo()
- {
- printf("Tree %s%s contains %d files in %d directories,\n",
- infnam,inwildcard,filecount,dircount);
- printf("%lu bytes (%luK)\n",total,(unsigned long) (total / 1024L));
- printf("%lu clusters for drive %c: (%luK)\n",
- clus,*infnam,(unsigned long) (clus * allocunit)/1024L);
- printf("%lu clusters for floppy drive: (%luK)\n",
- fclus,(unsigned long) (fclus * 512L)/1024L);
-
- }
-
- /* +-------------------------------------------------------------------+
- | mexpand(template,buf,dirname,fns) |
- | macroexpand |
- +-------------------------------------------------------------------+ */
- mexpand(template,buf,dirname,fns)
- char *template;
- char *buf;
- char *dirname;
- FILENAME *fns;
- {
- char *cp;
-
- cp = template;
-
- while (*cp) {
- if (*cp != '$') {
- *buf = *cp;
- cp++; buf++;
- continue;
- }
- cp++;
- if (!*cp) break;
- switch (*cp++) {
- case '$': *buf++ = '$'; break;
- case 's':
- case 'S': strcpy(buf,dirname);
- buf += strlen(dirname);
- break;
- case 'd':
- case 'D':
- strcpy(buf,outfnam);
- strcat(buf,dirname+inlen);
- buf += strlen(buf);
- break;
- case 'b':
- case 'B':
- if (fns) {
- sprintf(buf,"%lu",fns->filesize);
- buf += strlen(buf);
- }
- break;
- case 'g':
- case 'G': *buf++ = '>'; break;
- case 'l':
- case 'L': *buf++ = '<'; break;
- case 'p':
- case 'P': *buf++ = '|'; break;
- case 'q':
- case 'Q': *buf++ = '"'; break;
- case 'f':
- case 'F':
- if (fns) {
- strcpy(buf,fns->name);
- buf += strlen(buf);
- }
- break;
- case 'c':
- case 'C': getcwd(buf,80);
- buf += strlen(buf);
- break;
-
- default:
- *buf++ = '$';
- *buf++ = *(cp-1);
- break;
- }
- }
- *buf = '\0';
- }
-
-
-
- /* +-------------------------------------------------------------------+
- | bcalldir(t,name) |
- | do call with before directory string |
- +-------------------------------------------------------------------+ */
- bcalldir(t,name)
- BTREE *t;
- char *name;
- {
- char newname[64];
- char cmd[128];
-
- if (strlen(dbcallstr) == 0) return;
-
- strcpy(newname,name);
- rmslash(newname);
-
- mexpand(dbcallstr,cmd,newname,NULL);
-
- if (switches & SBAT) {
- fputs(cmd,stdout);
- fputc('\n',stdout);
- }
- else {
- if (verbose) {
- fputs(cmd,stderr);
- fputc('\n',stderr);
- }
- system(cmd);
- }
-
- }
-
- /* +-------------------------------------------------------------------+
- | acalldir(t,name) |
- | do call after directory string |
- +-------------------------------------------------------------------+ */
- acalldir(t,name)
- BTREE *t;
- char *name;
- {
- char newname[64];
- char cmd[128];
-
- if (strlen(dacallstr) == 0) return;
-
- strcpy(newname,name);
- rmslash(newname);
-
- mexpand(dacallstr,cmd,newname,NULL);
-
- if (switches & SBAT) {
- fputs(cmd,stdout);
- fputc('\n',stdout);
- }
- else {
- if (verbose) {
- fputs(cmd,stderr);
- fputc('\n',stderr);
- }
- system(cmd);
- }
- }
-
-
- /* +-------------------------------------------------------------------+
- | callfile(t,name,fns) |
- | do call after directory string |
- +-------------------------------------------------------------------+ */
- callfile(t,name,fns)
- BTREE *t;
- char *name;
- FILENAME *fns;
- {
- char cmd[128];
-
- if (strlen(ncallstr) == 0) return;
-
- mexpand(ncallstr,cmd,name,fns);
-
- if (switches & SBAT) {
- fputs(cmd,stdout);
- fputc('\n',stdout);
- }
- else {
- if (verbose) {
- fputs(cmd,stderr);
- fputc('\n',stderr);
- }
- system(cmd);
- }
- }
-
-
-
-
- /* +-------------------------------------------------------------------+
- | tcall() |
- | call function in tree |
- +-------------------------------------------------------------------+ */
- tcall()
- {
- BTREE *t;
-
- t = maketree(infnam);
-
- maptree(t,bcalldir,acalldir,callfile);
- }
-
-
- /* +-------------------------------------------------------------------+
- | inthndlr() |
- | handles ctrl-break interrupt |
- +-------------------------------------------------------------------+ */
- inthndlr()
- {
- #ifdef OS2
- DOSSETVERIFY(oldverify);
- #else
- setverify(oldverify);
- #endif
- fatalerr("interrupted via Ctrl-Break");
- }
-
-
- /* +-------------------------------------------------------------------+
- | doquery(ques,file) |
- | does query, returns 1 if YES, 0 if no |
- +-------------------------------------------------------------------+ */
- doquery(ques,file)
- char *ques;
- char *file;
- {
- if (!(switches & SQUERY)) return 1;
-
- printf(ques,file);
- while (1) {
- switch (getchar()) {
- case 'y':
- case 'Y': printf("YES\n"); return 1;
- case 'n':
- case 'N': printf("NO\n"); return 0;
- case 'q':
- case 'Q': printf("QUIT\n");
- #ifdef OS2
- DOSSETVERIFY(oldverify);
- #else
- setverify(oldverify);
- #endif
- fatalerr("exit");
- case 'a':
- case 'A': printf("ALL\n");
- switches &= ~SQUERY;
- return 1;
- default: break;
- }
- }
- }
-
-
- /* +-------------------------------------------------------------------+
- | usage() |
- | does ntree usage |
- +-------------------------------------------------------------------+ */
- usage()
- {
- fprintf(stderr,"Usage: ntree {/sw/sw..} path1{wildcard}{/sw/sw..} {path2{/sw/sw..}} \"call\"");
- fprintf(stderr,"\n");
- fprintf(stderr,"\tntree/C path1{wild} path2 Copy tree\n");
- fprintf(stderr,"\tntree/D path1{wild} Delete tree\n");
- fprintf(stderr,"\tntree/ARC path1{wild} arcname Archive via ARC\n");
- fprintf(stderr,"\tntree/T path1{wild} Total space used\n");
- fprintf(stderr,"\tntree path1{wild} Directory display\n");
- fprintf(stderr,"\tntree path1{wild} path2 /call \"macro\" /before \"macro\" /after \"macro\"\n");
- fprintf(stderr,"\tmacros: $s=source, $d=dest, $g=>, $l=<, $p=|, $c=current dir\n");
- fprintf(stderr,"\t $f=filename, $b=filesize, $$=$, $q=\"\n");
- fprintf(stderr,"\n\tSwitches:\n");
- fprintf(stderr,"\t /A Enumerate files and directories\n");
- fprintf(stderr,"\t /H Include hidden files\n");
- fprintf(stderr,"\t /V Set verify switch ON\n");
- fprintf(stderr,"\t /U (for copy) Copy files with archive bit on\n");
- fprintf(stderr,"\t /DATE (for copy) Copy files with later date\n");
- fprintf(stderr,"\t /O (for copy) Copy files and overwrite destination\n");
- fprintf(stderr,"\t /Q (copy/del) Query before copy or delete\n");
- fprintf(stderr,"\t /YES (copy/del) Don't ask any questions..just do it\n");
- fprintf(stderr,"\t /DIR (display) Display <DIR> for directories\n");
- fprintf(stderr,"\t /BAT (call) Don't do commands, just echo to stdout\n");
- fprintf(stderr,"\t /QUIET Don't write informative messages to stdout\n");
- fprintf(stderr,"\t /SILENT Don't write messages or errors anywhere!\n");
- exit(1);
- }
-
-
- /* +-------------------------------------------------------------------+
- | cmpdate(d1,d2) |
- | compares two filedates |
- +-------------------------------------------------------------------+ */
- int cmpdate(d1,d2)
- FILEDATE *d1;
- FILEDATE *d2;
- {
- if (d1->year > d2->year) return 1;
- if (d1->year < d2->year) return -1;
- if (d1->month > d2->month) return 1;
- if (d1->month < d2->month) return -1;
- if (d1->day > d2->day) return 1;
- if (d1->day < d2->day) return -1;
- if (d1->hour > d2->hour) return 1;
- if (d1->hour < d2->hour) return -1;
- if (d1->second > d2->second) return 1;
- if (d1->second < d2->second) return -1;
- return 0;
- }
-
-
- #ifdef OS2
- /*
- +-------------------------------------------------------------------------+
- | curdrive() |
- | Return the current drive (1=A, 2=B, 3=C, etc.) |
- +-------------------------------------------------------------------------+
- */
- unsigned int curdrive()
- {
- extern int far pascal DOSQCURDISK();
- unsigned int drivenumber;
- unsigned long drivemap;
- unsigned int result;
-
- result = DOSQCURDISK( (int far *) &drivenumber,
- (long far *) &drivemap);
-
- return ( result ? 0xFFFF : drivenumber);
- }
- #endif
-
- #ifdef OS2
- /*
- +-------------------------------------------------------------------------+
- | getdir(drive,buf) |
- | Get the current directory for the specified drive and place it |
- | into buf. Note that the drive letter and colon are preappended to |
- | the contents of buf. 'drive' is an integer with a meaning as |
- | follows: 0 = default drive; 1 = A; 2 = B; 3 = C; etc. |
- +-------------------------------------------------------------------------+
- */
- int getdir(drive, buf)
- unsigned int drive;
- unsigned char *buf;
- {
- extern int far pascal DOSQCURDIR();
- int buflen = 64; /* assume buffer is at least 64 bytes long */
- int result;
-
- sprintf(buf, "%c:\\", drive+64);
- result = DOSQCURDIR( drive,
- (char far *) (buf+3),
- (int far *) &buflen);
- return result;
- }
- #endif
-
- #ifdef OS2
- /*
- +-------------------------------------------------------------------------+
- | changedir(dir) |
- | Change the current drive and directory. |
- +-------------------------------------------------------------------------+
- */
- int changedir(dir)
- unsigned char *dir;
- {
- extern int far pascal DOSCHDIR();
- extern int far pascal DOSSELECTDISK();
- int result;
-
- result = DOSCHDIR((char far *) dir, 0L);
-
- /* now check and see if a drive letter was specified */
- if ((dir[1] == ':') && (result == 0))
- result = DOSSELECTDISK(dir[0] - '@');
-
- return result;
- }
- #endif
-
- #ifdef OS2
- /*
- +-------------------------------------------------------------------------+
- | clussize(drive) |
- | Return the clustersize for the specified drive. The 'drive' |
- | paramater is 0 for the default, 1=A, 2=B, 3=C, etc. |
- +-------------------------------------------------------------------------+
- */
- unsigned int clussize(drive)
- unsigned int drive;
- {
- extern int far pascal DOSQFSINFO();
- struct FSinfo {
- unsigned long filesystemid;
- unsigned long sectorsperunit;
- unsigned long allocunits;
- unsigned long availallocunits;
- unsigned int bytespersector;
- } fsinfo;
-
- DOSQFSINFO( drive,
- 1,
- (struct FSinfo far *) &fsinfo,
- sizeof(struct FSinfo));
-
- return ((unsigned int) fsinfo.sectorsperunit * fsinfo.bytespersector);
-
- }
- #endif
-
- #ifdef CDOCOPY
- /* D E B U G use only */
- /* docopyfile(from, to) Copy a file */
- int docopyfile(from, to)
- unsigned char *from;
- unsigned char *to;
- {
- printf("docopyfile(%s,%s)\n", from, to);
- return 0;
- }
- #endif
-
-
-