home *** CD-ROM | disk | FTP | other *** search
/ The Pier Shareware 6 / The_Pier_Shareware_Number_6_(The_Pier_Exchange)_(1995).iso / 024 / psi110g.zip / DIRUTIL.C < prev    next >
C/C++ Source or Header  |  1994-08-26  |  22KB  |  908 lines

  1. /* dirutil.c - MS-DOS directory reading routines
  2.  *
  3.  * Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
  4.  * Directory sorting by Mike Chepponis, K3MC
  5.  * New version using regs.h by Russell Nelson.
  6.  * Rewritten for Turbo-C 2.0 routines by Phil Karn, KA9Q 25 March 89
  7.  *
  8.  * Added path filter functions and applied to dodir
  9.  * also used by ftpcli.c, added current directory
  10.  * storage capability (11/92 WA3DSP)
  11.  * Bugfixes in the above by WG7J, WA7TAS
  12.  */
  13.   
  14. #ifndef UNIX
  15. #include <dir.h>
  16. #include <dos.h>
  17. #else
  18. #include <sys/stat.h>
  19. /* There are at least FOUR variants of statfs()... we handle SCO and Linux */
  20. #ifdef M_UNIX
  21. #include <sys/statfs.h>
  22. #define f_bavail f_bfree
  23. #else
  24. #include <sys/vfs.h>
  25. #endif /* M_UNIX */
  26. #endif /* UNIX */
  27. #include <ctype.h>
  28. #ifndef UNIX
  29. #include <io.h>
  30. #endif
  31. #include "global.h"
  32. #include "proc.h"
  33. #include "session.h"
  34. #include "dirutil.h"
  35. #include "commands.h"
  36.   
  37. #ifdef CALLSERVER
  38. #include <string.h>
  39. #include <alloc.h>
  40. extern char *CDROM; /* buckbook.c: defines CDROM drive letter e.g. "s:"  */
  41. #endif
  42.   
  43. struct dirsort {
  44.     struct dirsort *next;
  45.     struct ffblk de;
  46. };
  47. #define NULLSORT (struct dirsort *)0
  48.   
  49. static void commas __ARGS((char *dest));
  50. static int fncmp __ARGS((char *a, char *b));
  51. static void format_fname_full __ARGS((FILE *file,struct ffblk *sbuf,int full,
  52. int n));
  53. static void free_clist __ARGS((struct dirsort *this));
  54.   
  55. #ifdef  notdef
  56. static int getdir_nosort __ARGS((char *path,int full,FILE *file));
  57. #endif
  58. static void print_free_space __ARGS((char *path,FILE *file,int n));
  59.   
  60. extern void crunch __ARGS((char *buf,char *path));
  61.   
  62. #define REGFILE (FA_DIREC)
  63.   
  64. #define insert_ptr(list,new)    (new->next = list,list = new)
  65.   
  66.   
  67. /* Create a directory listing in a temp file and return the resulting file
  68.  * descriptor. If full == 1, give a full listing; else return just a list
  69.  * of names.
  70.  */
  71. FILE *
  72. dir(path,full)
  73. char *path;
  74. int full;
  75. {
  76.     FILE *fp;
  77.   
  78.     if((fp = tmpfile()) != NULLFILE){
  79.         getdir(path,full,fp);
  80.         rewind(fp);
  81.     }
  82.     return fp;
  83. }
  84.   
  85. /* find the first or next file and lowercase it. */
  86. int
  87. nextname(command, name, sbuf)
  88. int command;
  89. char *name;
  90. struct ffblk *sbuf;
  91. {
  92.     int found;
  93.   
  94.     switch(command){
  95.         case 0:
  96.             found = findfirst(name,sbuf,REGFILE);
  97.             break;
  98.         default:
  99.             found = findnext(sbuf);
  100.     }
  101.     found = found == 0;
  102. #ifndef UNIX
  103.     if(found)
  104.         strlwr(sbuf->ff_name);
  105. #endif
  106.   
  107.     return found;
  108. }
  109.   
  110. /* wildcard filename lookup */
  111. int
  112. filedir(name,times,ret_str)
  113. char *name;
  114. int times;
  115. char *ret_str;
  116. {
  117.     static struct ffblk sbuf;
  118.     int rval;
  119.   
  120.     switch(times){
  121.         case 0:
  122.             rval = findfirst(name,&sbuf,REGFILE);
  123.             break;
  124.         default:
  125.             rval = findnext(&sbuf);
  126.             break;
  127.     }
  128.     if(rval == -1){
  129.         ret_str[0] = '\0';
  130.     } else {
  131.         /* Copy result to output */
  132.         strcpy(ret_str, sbuf.ff_name);
  133.     }
  134.     return rval;
  135. }
  136. /* do a directory list to the stream
  137.  * full = 0 -> short form, 1 is long
  138. */
  139. int
  140. getdir(path,full,file)
  141. char *path;
  142. int full;
  143. FILE *file;
  144. {
  145.     struct ffblk *sbuf;
  146.     int command = 0;
  147.     int n = 0;
  148.     struct dirsort *head, *here, *new;
  149.   
  150.     sbuf = mallocw(sizeof *sbuf);
  151.     path = wildcardize(path);
  152.   
  153.     head = NULLSORT;        /* No head of chain yet... */
  154.     for(;;){
  155.         if (!nextname(command, path, sbuf))
  156.             break;
  157.         command = 1;    /* Got first one already... */
  158.         if (sbuf->ff_name[0] == '.')     /* drop "." and ".." */
  159. #ifdef UNIX
  160.             if (sbuf->ff_name[1] == '\0' || (sbuf->ff_name[1] == '.' &&
  161.                 sbuf->ff_name[2] == '\0'))
  162. #endif
  163.                 continue;
  164.   
  165.         new = (struct dirsort *) mallocw(sizeof(struct dirsort));
  166.         memcpy(&new->de, sbuf, sizeof *sbuf); /* Copy contents of directory entry struct */
  167.   
  168.         /* insert it into the list */
  169.         if (!head || fncmp(new->de.ff_name, head->de.ff_name) < 0) {
  170.             insert_ptr(head, new);
  171.         } else {
  172.             register struct dirsort *this;
  173.             for (this = head;
  174.                 this->next != NULLSORT;
  175.                 this = this->next)
  176.                 if (fncmp(new->de.ff_name, this->next->de.ff_name) < 0)
  177.                     break;
  178.             insert_ptr(this->next, new);
  179.         }
  180.     } /* infinite FOR loop */
  181.   
  182.     for (here = head; here; here = here->next)
  183.         format_fname_full(file,&here->de,full,++n);
  184.   
  185.     /* Give back all the memory we temporarily needed... */
  186.     free_clist(head);
  187.     free(sbuf);
  188.   
  189.     if(full)
  190.         print_free_space(path, file, n);
  191.   
  192.     return 0;
  193. }
  194.   
  195. static int
  196. fncmp(a,b)
  197. register char *a, *b;
  198. {
  199.     int i;
  200.   
  201.     for(;;){
  202.         if (*a == '.')
  203.             return -1;
  204.         if (*b == '.')
  205.             return 1;
  206.         if ((i = *a - *b++) != 0)
  207.             return i;
  208.         if (!*a++)
  209.             return -1;
  210.     }
  211. }
  212.   
  213.   
  214. #if defined DIRSESSION || defined FTPSESSION
  215.   
  216. extern int morecmd();
  217. /* List directory to console */
  218. int
  219. dircmd(argc,argv,p)
  220. int argc;
  221. char *argv[];
  222. void *p;
  223. {
  224.     char *path;
  225.     FILE *fp;
  226.     char **margv;
  227.     char tmpname[80];
  228.   
  229.     path=strdup(make_dir_path(argc,argv[1],Command->curdirs->dir));
  230.     margv = (char **)callocw(2,sizeof(char *));
  231.     tmpnam(tmpname);
  232.     fp = fopen(tmpname,WRITE_TEXT);
  233.     getdir(path,1,fp);
  234.     free(path);
  235.     fclose(fp);
  236.     margv[1] = strdup(tmpname);
  237.     morecmd(2,margv,p);
  238.     free(margv[1]);
  239.     free(margv);
  240.     unlink(tmpname);
  241.     return 0;
  242. }
  243. #endif  /* DIRSESSION || FTPSESSION */
  244.   
  245. #ifdef DIRSESSION
  246.   
  247. int
  248. dodir(argc,argv,p)
  249. int argc;
  250. char *argv[];
  251. void *p;
  252. {
  253.     char **pargv;
  254.     int i;
  255.   
  256.     if(Curproc->input == Command->input) {
  257.         /* Make private copy of argv and args,
  258.          * spawn off subprocess and return.
  259.          */
  260.         pargv = (char **)callocw(argc,sizeof(char *));
  261.         for(i=0;i<argc;i++)
  262.             pargv[i] = strdup(argv[i]);
  263.         newproc("dir",512,(void (*)__ARGS((int,void*,void*)))dircmd,argc,(void *)pargv,p,1);
  264.     } else
  265.         dircmd(argc,argv,p);
  266.     return 0;
  267. }
  268.   
  269. #endif /* DIRSESSION */
  270.   
  271. /*
  272.  * Return a string with commas every 3 positions.
  273.  * the original string is replace with the string with commas.
  274.  *
  275.  * The caller must be sure that there is enough room for the resultant
  276.  * string.
  277.  *
  278.  *
  279.  * k3mc 4 Dec 87
  280.  */
  281. static void
  282. commas(dest)
  283. char *dest;
  284. {
  285.     char *src, *core;       /* Place holder for malloc */
  286.     unsigned cc;            /* The comma counter */
  287.     unsigned len;
  288.   
  289.     len = strlen(dest);
  290.     /* Make a copy, so we can muck around */
  291.     core = src = strdup(dest);
  292.   
  293.     cc = (len-1)%3 + 1;     /* Tells us when to insert a comma */
  294.   
  295.     while(*src != '\0'){
  296.         *dest++ = *src++;
  297.         if( ((--cc) == 0) && *src ){
  298.             *dest++ = ','; cc = 3;
  299.         }
  300.     }
  301.     free(core);
  302.     *dest = '\0';
  303. }
  304.   
  305. /* fix up the filename so that it contains the proper wildcard set */
  306. char *
  307. wildcardize(path)
  308. char *path;
  309. {
  310. #ifdef UNIX
  311.     static
  312. #endif
  313.     struct ffblk sbuf;
  314. #ifdef UNIX
  315.     static char ourpath[1024];
  316. #else
  317.     static char ourpath[64];
  318. #endif
  319.   
  320.     /* Root directory is a special case */
  321.     if(path == NULLCHAR ||
  322.         *path == '\0' ||
  323.         strcmp(path,"\\") == 0 ||
  324.     strcmp(path,"/") == 0) {
  325. #ifdef UNIX
  326.         strcpy(ourpath,"/*");
  327. #else
  328.         strcpy(ourpath,"/*.*");
  329. #endif
  330.         return ourpath;
  331.     }
  332.   
  333. #ifdef MSDOS
  334.     /* MSDOS Root directory can also have a drive letter prefix */
  335.     if(isalpha(*path) &&
  336.         (strcmp(path+1,":\\") == 0 || strcmp(path+1,":/") == 0) ) {
  337.             sprintf(ourpath,"%c:/*.*", *path);
  338.             return ourpath;
  339.     }
  340. #endif
  341.   
  342. #ifdef CALLSERVER
  343.     if  (CDROM != NULLCHAR && strcmp(path, CDROM) == 0)  {
  344. #ifdef UNIX
  345.         sprintf(ourpath, "%s/*", CDROM);
  346. #else
  347.         sprintf(ourpath, "%s/*.*", CDROM);
  348. #endif
  349.         return ourpath;
  350.     }
  351. #endif
  352.   
  353.     /* if they gave the name of a subdirectory, append \*.* to it */
  354.     if (nextname(0, path, &sbuf) &&
  355.         (sbuf.ff_attrib & FA_DIREC) &&
  356.     !nextname(1, path, &sbuf)) {
  357.   
  358.         /* if there isn't enough room, give up -- it's invalid anyway */
  359. #ifdef UNIX
  360.         if (strlen(path) + 2 > sizeof(ourpath) - 1) return path;
  361. #else
  362.         if (strlen(path) + 4 > sizeof(ourpath) - 1) return path;
  363. #endif
  364.         strcpy(ourpath, path);
  365. #ifdef UNIX
  366.         strcat(ourpath, "/*");
  367. #else
  368.         strcat(ourpath, "/*.*");
  369. #endif
  370.         return ourpath;
  371.     }
  372. #ifdef UNIX
  373.     findlast(&sbuf);
  374. #endif
  375.   
  376.     return path;
  377. }
  378.   
  379. static void
  380. format_fname_full(file, sbuf, full, n)
  381. FILE *file;
  382. struct ffblk *sbuf;
  383. int full, n;
  384. {
  385. #ifdef UNIX
  386.     static char line_buf[1025];
  387.     static char cbuf[1025];
  388. #else
  389.     char line_buf[50];              /* for long dirlist */
  390.     char cbuf[20];                  /* for making line_buf */
  391. #endif
  392.   
  393.     strcpy(cbuf,sbuf->ff_name);
  394.     if(sbuf->ff_attrib & FA_DIREC) strcat(cbuf, "/");
  395.     if (full) {
  396.         /* Long form, give other info too */
  397.         sprintf(line_buf,"%-13s",cbuf);
  398.         if(sbuf->ff_attrib & FA_DIREC)
  399.             strcat(line_buf,"           ");/* 11 spaces */
  400.         else {
  401.             sprintf(cbuf,"%ld",sbuf->ff_fsize);
  402.             commas(cbuf);
  403.             sprintf(line_buf+strlen(line_buf),"%10s ",cbuf);
  404.         }
  405.         sprintf(line_buf+strlen(line_buf),"%2d:%02d %2d/%02d/%02d%s",
  406. #ifdef UNIX
  407.         sbuf->ff_ftime.tm_hour, sbuf->ff_ftime.tm_min,
  408.         sbuf->ff_ftime.tm_mon + 1, sbuf->ff_ftime.tm_mday,
  409.         sbuf->ff_ftime.tm_year,
  410. #else
  411.         (sbuf->ff_ftime >> 11) & 0x1f,        /* hour */
  412.         (sbuf->ff_ftime >> 5) & 0x3f, /* minute */
  413.         (sbuf->ff_fdate >> 5) & 0xf,  /* month */
  414.         (sbuf->ff_fdate ) & 0x1f,             /* day */
  415.         (sbuf->ff_fdate >> 9) + 80,   /* year */
  416. #endif
  417.         (n & 1) ? "   " : "\n");
  418.         fputs(line_buf,file);
  419.     } else {
  420.         fputs(cbuf,file);
  421.         fputs("\n",file);
  422.     }
  423. }
  424. /* Provide additional information only on DIR */
  425. static void
  426. print_free_space(path, file, n)
  427. char *path;
  428. FILE *file;
  429. int n;
  430. {
  431.     unsigned long free_bytes, total_bytes;
  432.     char s_free[25], s_total[25]; /* Changed to accomodate big disks - WA7TAS */
  433.     char cbuf[20];
  434. #ifdef UNIX
  435.     char *pbuf;
  436.     struct statfs vfsb;
  437.     char *cp;
  438.   
  439.     pbuf = mallocw(1024);
  440.     strcpy(pbuf, path);
  441.     if ((cp = strrchr(pbuf, '/')) == 0)
  442.         strcat(pbuf, "/.");
  443.     else
  444.     {
  445.         *++cp = '.';
  446.         *++cp = '\0';
  447.     }
  448. #ifdef M_UNIX
  449.     statfs(pbuf, &vfsb, sizeof vfsb, 0);
  450. #else
  451.     statfs(pbuf, &vfsb);
  452. #endif
  453.     free_bytes = vfsb.f_bsize * vfsb.f_bavail;
  454.     total_bytes = vfsb.f_bsize * vfsb.f_blocks;
  455. #else /* UNIX */
  456.     struct dfree dtable;
  457.     unsigned long bpcl;
  458.     char resolved[80];      /* may need as little as 67 */
  459.     union REGS regs;
  460.     struct SREGS sregs;
  461.     int drive;
  462.     char drivex[3];
  463.   
  464.     if(_osmajor>=3) {
  465.         /* do an undocumented call to find which drive this name resolves to */
  466.         /*  this call does *NOT* work in dos <3.0 */
  467.         /* Note: this can yield a path like: \\machine\path  , EVEN FOR A CDROM,
  468.            in which case we use the dos 2.0 method ... N5KNX */
  469.         regs.x.si = FP_OFF(path);
  470.         sregs.ds = FP_SEG(path);
  471.         regs.x.di = FP_OFF(resolved);
  472.         sregs.es = FP_SEG(resolved);
  473.         regs.h.ah = 0x60;
  474.         intdosx(®s,®s,&sregs);
  475.         if (regs.x.cflag || (resolved[1] != ':'))
  476.             drive = -1;
  477.         else drive = resolved[0] - '@';
  478.     }
  479.     if (_osmajor < 3 || drive == -1) {
  480.         /* use a method that works for dos < 3.0 */
  481.         drivex[0]=0;
  482.         for(drive=0;drive<strlen(path);drive++)
  483.             path[drive]=toupper(path[drive]);
  484.         fnsplit(path,drivex,NULL,NULL,NULL);
  485.         if(drivex[0])
  486.             drive = drivex[0] - '@';
  487.         else
  488.             drive = 0;
  489.     }
  490.   
  491.     /* Find disk free space */
  492.     getdfree(drive,&dtable);
  493.   
  494.  /* Changed to accomodate big disks - WA7TAS */
  495.     bpcl = (unsigned long)dtable.df_bsec * (unsigned long)dtable.df_sclus;
  496.     free_bytes  = (unsigned long)dtable.df_avail * bpcl;
  497.     total_bytes = (unsigned long)dtable.df_total * bpcl;
  498. #endif /* UNIX */
  499.   
  500.     if(n & 1)
  501.         fputs("\n",file);
  502.   
  503.     sprintf(s_free,"%lu",free_bytes);
  504.     commas(s_free);
  505.     sprintf(s_total,"%lu",total_bytes);
  506.     commas(s_total);
  507.   
  508.     if(n)
  509.         sprintf(cbuf,"%d",n);
  510.     else
  511.         strcpy(cbuf,"No");
  512.   
  513.     fprintf(file,"%s file%s. %s bytes free. Disk size %s bytes.\n",
  514.     cbuf,(n==1? "":"s"),s_free,s_total);
  515. }
  516. static void
  517. free_clist(this)
  518. struct dirsort *this;
  519. {
  520.     struct dirsort *next;
  521.   
  522.     while (this != NULLSORT) {
  523.         next = this->next;
  524.         free(this);
  525.         this = next;
  526.     }
  527. }
  528. #ifdef  notdef
  529. static int
  530. getdir_nosort(path,full,file)
  531. char *path;
  532. int full;
  533. FILE *file;
  534. {
  535.     struct ffblk sbuf;
  536.     int command;
  537.     int n = 0;      /* Number of directory entries */
  538.   
  539. /*      path = wildcardize(path); */
  540.     command = 0;
  541.     while(nextname(command, path, &sbuf)){
  542.         command = 1;    /* Got first one already... */
  543.         if (sbuf.ff_name[0] == '.')     /* drop "." and ".." */
  544.             continue;
  545.         format_fname_full(file, &sbuf, full, ++n);
  546.     }
  547.     if(full)
  548.         print_free_space(path, file, n);
  549.     return 0;
  550. }
  551. #endif
  552.   
  553. /* Translate those %$#@!! backslashes to proper form */
  554. void
  555. undosify(s)
  556. char *s;
  557. {
  558.     while(*s != '\0'){
  559.         if(*s == '\\')
  560.             *s = '/';
  561.         s++;
  562.     }
  563. }
  564.   
  565. char *
  566. make_dir_path(int count,char * arg,char * curdir)
  567. {
  568.     char path[128], *q;
  569.   
  570.     undosify(arg);
  571.     undosify(curdir);
  572.     if (count>=2) {
  573.         q=arg;
  574.         q+=strlen(arg)-1;
  575.         if (*q=='/' || *q==':') {
  576.             strcpy(path,arg);
  577. #ifdef UNIX
  578.             strcat(path,"*");
  579. #else
  580.             strcat(path,"*.*");
  581. #endif
  582.         } else
  583.             strcpy(path,arg);
  584.     } else {
  585. #ifdef UNIX
  586.         strcpy(path,"*");
  587. #else
  588.         strcpy(path,"*.*");
  589. #endif
  590.     }
  591.     return (make_fname(curdir,path));
  592. }
  593.   
  594. char*
  595. make_fname(char * curdir, char * fname)
  596. {
  597.     char *p;
  598.     static char new_name[128];
  599.   
  600.     strcpy(new_name,curdir);
  601.     undosify(fname);
  602. #ifdef UNIX
  603.     if (fname[0]=='/') {
  604. #else
  605.         if (fname[0]=='/' || (strchr(fname,':') != NULLCHAR) ) {
  606. #endif
  607.             return fname;
  608.         } else {
  609.             p=new_name;
  610.             p+=strlen(p)-1;
  611.             if (*p=='/')
  612.                 *p='\0';
  613.             crunch(new_name,fname);
  614.             return new_name;
  615.         }
  616.     }
  617.   
  618. /* Check Drive/Directory for validity - 1=OK, 0=NOGOOD */
  619.   
  620.     int
  621.     dir_ok(char * newpath,struct cur_dirs * dirs)
  622.     {
  623.         char *a, curpath[128];
  624.         char buf[128],fullpath[128];
  625.         int result;
  626. #ifndef UNIX
  627.         int drive=dirs->drv;
  628. #endif
  629.   
  630.         undosify(newpath);
  631. #ifndef UNIX
  632.         a=newpath;
  633.         if ((*(a+1)==':') && (isalpha(*a))){
  634.             drive=toupper(*a)-'@';
  635.             strcpy(buf,a+2);
  636.             if (dirs->curdir[drive]==NULLCHAR) {
  637.                 if(!getcurdir(drive,curpath)) {
  638.                     undosify(curpath);
  639.                     sprintf(fullpath,"%c:/%s",drive+'@',curpath);
  640.                     dirs->curdir[drive]=strdup(fullpath);
  641.                     dirs->drv=drive;
  642.                     dirs->dir=dirs->curdir[drive];
  643.                 }
  644.             }
  645.         } else {
  646.             strcpy(buf,newpath);
  647.         }
  648.   
  649.         if((a=dirs->curdir[drive])!=NULLCHAR) {
  650.             if ((*(a+1)==':') && (isalpha(*a))){
  651.                 if (*(a+2)=='/')
  652.                     strcpy(curpath,a+3);
  653.                 else
  654.                     strcpy(curpath,a+2);
  655.             } else {
  656.                 strcpy(curpath,a);
  657.             }
  658.         } else {
  659.             strcpy(curpath,"");
  660.         }
  661. #endif
  662.   
  663.         if (*buf!='/') {
  664.             crunch(curpath,buf);
  665.         } else {
  666.             strcpy(curpath,buf+1);
  667.         }
  668.         a=curpath;
  669. #ifdef UNIX
  670.         sprintf(fullpath,"%s%s",(*a!='/' ? "/" : ""),curpath);
  671. #else
  672.         sprintf(fullpath,"%c:%s%s",drive+'@',(*a!='/' ? "/" : ""),curpath);
  673. #endif
  674.   
  675.         if((result=access(fullpath,0)+1)==1) {
  676. #ifdef UNIX
  677.             free(dirs->dir);
  678.             dirs->dir = strdup(fullpath);
  679. #else
  680.             if(dirs->curdir[drive])
  681.                 free(dirs->curdir[drive]);
  682.             dirs->curdir[drive]=strdup(fullpath);
  683.             dirs->drv=drive;
  684.             dirs->dir=dirs->curdir[drive];
  685. #endif
  686.         }
  687.         return result;
  688.     }
  689.   
  690.     char *
  691.     init_dirs(struct cur_dirs * dirs)
  692.     {
  693. #ifdef UNIX
  694.         dirs->dir = getcwd(NULL, 1024);
  695.         return dirs->dir;
  696. #else
  697.         char buf[128],fullpath[128];
  698.         int x,drive;
  699.   
  700.         for(x=0;x<=26;x++)
  701.             dirs->curdir[x]='\0';
  702.   
  703.         drive=getdisk()+1;
  704.         getcurdir(drive,buf);
  705.         undosify(buf);
  706.         sprintf(fullpath,"%c:/%s",drive+'@',buf);
  707.         dirs->curdir[drive]=strdup(fullpath);
  708.         dirs->drv=drive;
  709.         dirs->dir=dirs->curdir[drive];
  710.         return dirs->curdir[drive];
  711. #endif
  712.     }
  713.   
  714.     void
  715.     free_dirs(struct cur_dirs * dirs)
  716.     {
  717. #ifdef UNIX
  718.         free(dirs->dir);
  719. #else
  720.         int x;
  721.   
  722.         for(x=0;x<=26;x++) {
  723.             if (dirs->curdir[x])
  724.                 free(dirs->curdir[x]);
  725.         }
  726. #endif
  727.     }
  728.   
  729. #ifdef  MSDOS
  730. /* Valid characters in a DOS filename matrix */
  731.     static unsigned char doschars[] = {
  732.         0x00, 0x00, 0x00, 0x00, 0xfa, 0x23, 0xff, 0x03,
  733.         0xff, 0xff, 0xff, 0xc7, 0xff, 0xff, 0xff, 0x6f,
  734.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  735.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  736.     };
  737.   
  738.     int
  739.     dosfnchr(ch)
  740.     int ch;
  741.     {
  742.         int i, j;
  743.   
  744.         i = (ch & 0xf8) >> 3;
  745.         j = doschars[i] & (1 << (ch & 0x07));
  746.         return j;
  747.     }
  748. #endif
  749.   
  750. #ifdef DOSCMD
  751. /* Standard commands called from main */
  752.     int
  753.     dodelete(argc,argv,p)
  754.     int argc;
  755.     char *argv[];
  756.     void *p;
  757.     {
  758.         int i;
  759.         char fname[128];
  760.   
  761.         for(i=1;i < argc; i++){
  762.             strcpy(fname,make_fname(Command->curdirs->dir,argv[i]));
  763.             if(unlink(fname) == -1){
  764.                 tprintf("Can't delete %s: %s\n",fname,sys_errlist[errno]);
  765.             }
  766.         }
  767.         return 0;
  768.     }
  769.   
  770.     int
  771.     dorename(argc,argv,p)
  772.     int argc;
  773.     char *argv[];
  774.     void *p;
  775.     {
  776.         char fname1[128];
  777.         char fname2[128];
  778.   
  779.         strcpy(fname1,make_fname(Command->curdirs->dir,argv[1]));
  780.         strcpy(fname2,make_fname(Command->curdirs->dir,argv[2]));
  781.         if(rename(fname1,fname2) == -1)
  782.             tprintf("Can't rename: %s\n",sys_errlist[errno]);
  783.         return 0;
  784.     }
  785.   
  786.     int
  787.     docopy(argc,argv,p)
  788.     int argc;
  789.     char *argv[];
  790.     void *p;
  791.     {
  792.         FILE *old, *new;
  793.         int ch;
  794.         unsigned char count;
  795.         char fname[128];
  796.   
  797.         strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
  798.         if((old = fopen(fname,"rb")) == NULL) {
  799.             tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
  800.             return 1;
  801.         }
  802.         strcpy(fname,make_fname(Command->curdirs->dir,argv[2]));
  803.         if((new = fopen(fname,"wb")) == NULL) {
  804.             tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
  805.             fclose(old);
  806.             return 1;
  807.         }
  808.     /* Now go copy */
  809.         count = 0;
  810.         while((ch = fgetc(old)) != EOF) {
  811.             fputc(ch,new);
  812.             if(!(++count))      /* be polite to other users */
  813.                 pwait(NULL);
  814.         }
  815.         fclose(old);
  816.         fclose(new);
  817.         return 0;
  818.     }
  819.   
  820. /* Change working directory */
  821.     int
  822.     docd(argc,argv,p)
  823.     int argc;
  824.     char *argv[];
  825.     void *p;
  826.     {
  827.         if(argc > 1){
  828.             if (!dir_ok(argv[1],Command->curdirs)) {
  829.                 tprintf("Invalid Drive/Directory - %s\n",argv[1]);
  830.                 return 1;
  831.             }
  832.         }
  833.         tprintf("Local Directory - %s\n",Command->curdirs->dir);
  834.         return 0;
  835.     }
  836.   
  837. /* Create directory */
  838.     int
  839.     domkd(argc,argv,p)
  840.     int argc;
  841.     char *argv[];
  842.     void *p;
  843.     {
  844.         char path[128];
  845.   
  846.         strcpy(path,make_fname(Command->curdirs->dir,argv[1]));
  847.   
  848. #ifdef UNIX
  849.         if(mkdir(path, 0777) == -1)
  850. #else
  851.             if(mkdir(path) == -1)
  852. #endif
  853.                 tprintf("Can't make %s: %s\n",path,sys_errlist[errno]);
  854.         return 0;
  855.     }
  856.   
  857. /* Remove directory */
  858.     int
  859.     dormd(argc,argv,p)
  860.     int argc;
  861.     char *argv[];
  862.     void *p;
  863.     {
  864.         char path[128];
  865.   
  866.         strcpy(path,make_fname(Command->curdirs->dir,argv[1]));
  867.         if(rmdir(path) == -1)
  868.             tprintf("Can't remove %s: %s\n",path,sys_errlist[errno]);
  869.         return 0;
  870.     }
  871.   
  872. #ifdef PRINTEROK
  873. int
  874. doprint(argc,argv,p)
  875. int argc;
  876. char *argv[];
  877. void *p;
  878. {
  879.     FILE *old, *new;
  880.     int ch;
  881.     unsigned char count;
  882.     char fname[128];
  883.  
  884.     strcpy(fname,make_fname(Command->curdirs->dir,argv[1]));
  885.     if((old = fopen(fname,"rb")) == NULL) {
  886.     tprintf("Can't open %s: %s\n",fname,sys_errlist[errno]);
  887.     return 1;
  888.     }
  889.     if((new = fopen("prn","wb")) == NULL) {
  890.     tprintf("Can't open printer: %s\n",sys_errlist[errno]);
  891.     fclose(old);
  892.     return 1;
  893.     }
  894.     /* Now go copy */
  895.     count = 0;
  896.     while((ch = fgetc(old)) != EOF) {
  897.     fputc(ch,new);
  898.     if(!(++count))      /* be polite to other users */
  899.         pwait(NULL);
  900.     }
  901.     fclose(old);
  902.     fclose(new);
  903.     return 0;
  904. }
  905. #endif
  906. #endif /* DOSCMD */
  907.   
  908.