home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 455.lha / finddisk_v3.1 / fd3src / fd3.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-12-10  |  22.2 KB  |  1,272 lines

  1.  
  2. /*                            FindDisk3.1
  3.  
  4.      Author      : Ross MacGregor
  5.      Date        : 10/04/88
  6.      Last Update : 13/08/89
  7.      Comments    : This is a public domain program.
  8.  
  9.  
  10.      DiskList stored in compacted form:
  11.  
  12.      below: { unskrunched } => { skrunched }
  13.             [] is a byte of memory
  14.  
  15.      * compacts strings of spaces
  16.          { [$20] [$20] [$20] [$20] [$20] } => { [SKRUNCHAR] [SKRUNOFFS 5] }
  17.          { [$20] [$20] } => { [$20] [$20] }
  18.  
  19.      * the STARTSTR is compacted
  20.          { STARTSTR } => { [STARTCHAR] }
  21.  
  22. */
  23.  
  24. #include <functions.h>
  25. #include <exec/types.h>
  26. #include <exec/nodes.h>
  27. #include <exec/lists.h>
  28. #include <exec/libraries.h>
  29. #include <exec/ports.h>
  30. #include <exec/interrupts.h>
  31. #include <exec/io.h>
  32. #include <exec/memory.h>
  33. #include <libraries/dos.h>
  34. #include <libraries/dosextens.h>
  35. #include <libraries/filehandler.h>
  36.  
  37. #define DISP_LINES 23
  38.  
  39. #define CP_BUFF 1024L    /* Buffer size for the file copy function */
  40.  
  41. /* This indicates the start line of a dir listing, and
  42.    it MUST have the name of the disk on the same line.  */
  43.  
  44. #define STARTSTR  "Directory of "
  45.  
  46. /* Special character used to compact the spaces in DiskList */
  47. #define SKRUNCHAR 1
  48. #define SKRUNOFFS 10
  49.  
  50. /* Special characters used to replace the STARTSTR & XnSTR in DiskList  */
  51. #define STARTCHAR  2
  52.  
  53. /* Lines in the stored dir listing array */
  54. #define NUMLINES 25
  55.  
  56. /* Max length of the lines read in */
  57. #define LINELEN  170
  58. #define MAXBUF   LINELEN-1
  59.  
  60. #define MAXPATHLEN 80
  61.  
  62. /*--------------------- Global Variables ------------------------*/
  63.  
  64. struct FileHandle *fdl, *ftmp;
  65. struct FileHandle *confh;
  66.  
  67. char *tempdl="ram:TempDL";
  68.  
  69. char *dltemp="ram:DiskList";
  70. char *dldisk="df0:FindDisk/DiskList";
  71. char *sdir_pat="df0:";
  72.  
  73. char *outofmem="Out of Memory.";
  74. char *cutoff=" - - (no more lines available) - - \n";
  75.  
  76. char dlpath[MAXPATHLEN+1];
  77. char buffer[LINELEN];
  78.  
  79. /* finddisk uses this */
  80. char dirlist[NUMLINES][LINELEN];
  81.  
  82. int con_print_line, last_startchar, disp_list;
  83. char *errorstr;
  84. char *nullstr="";
  85.  
  86. /* function error indicator */
  87. int fcnerr;
  88.  
  89. /* global main arguments */
  90. int glargc;
  91. char **glargv;
  92.  
  93. extern char strbuf[];
  94. extern int  subdir, shdsp;
  95.  
  96. /*------------ dynamic structure for coping DL to memory -------------*/
  97.  
  98. /* Blocks of memory for storing the disklist */
  99. #define BUFBLKS 20
  100. #define BLKSIZE 10000
  101.  
  102. char *bufferblock[BUFBLKS],*bufptr=NULL;
  103. int bufcount=-1, chrcount=BLKSIZE+1;
  104. void init_bufblks(), free_bufblks();
  105.  
  106.  
  107.  
  108. /*------------ dynamic structure for listing the volume names --------*/
  109. /*                   used in recursive do_ls call also                */
  110.  
  111. struct disk
  112. {
  113.   char name[LINELEN];
  114.   struct disk *next;
  115. };
  116. struct disk *firstdisk,*diskptr;
  117.  
  118. #define INIT_DISKNAMES firstdisk=diskptr=NULL
  119. #define FREE_DISKNAMES free_disknames()
  120.  
  121. void free_disknames();
  122.  
  123. /*----------------------------------------------------------------------*/
  124.  
  125. char *strstr(), *strtoupper(), *getstr();
  126. char *skrunch(), *getenv(), *firstchar();
  127. void tocon(), unskrunch(), get_dlpath();
  128. struct FileHandle *opendl(), *opentmp();
  129.  
  130. char *strchr(), *malloc();
  131. extern struct FileHandle *Open();
  132.  
  133.  
  134. int update(), remove(), loaddl(), savedl(), sdir(), newdl();
  135.  
  136. void finddisk_free(), update_free(), remove_free(), ls_free();
  137.  
  138.  
  139. char *getenv(fullpath,var)
  140.   char *fullpath, *var;
  141. {
  142.   struct FileLock *lock,*Lock();
  143.   struct FileHandle *fh;
  144.   char *buffer;
  145.   int  len;
  146.  
  147.   if( lock=Lock(fullpath,(long)ACCESS_READ) )
  148.   {
  149.     UnLock(lock);
  150.     if( !(fh=Open(fullpath,(long)MODE_OLDFILE)) )
  151.       return var;
  152.     if( !(buffer=(char *)malloc(MAXPATHLEN+1)) )
  153.     {
  154.       errorstr=outofmem;
  155.       Close(fh);
  156.       return var;
  157.     }
  158.     len=Read(fh,buffer,(long)MAXPATHLEN);
  159.     Close(fh);
  160.     *(buffer+len)='\0';
  161.     return buffer;
  162.   }
  163.   return var;
  164. }
  165.  
  166. tmpsize()
  167. {
  168.   int size;
  169.   if( !(ftmp=opentmp((long)MODE_OLDFILE)) )
  170.   {
  171.     errorstr=nullstr;
  172.     return 0;
  173.   }
  174.   size=Read(ftmp,buffer,(long)MAXBUF);
  175.   Close(ftmp);
  176.   return size;
  177. }
  178.  
  179. #define finddisk_cleanup(x) { finddisk_free(); return x; }
  180. finddisk()
  181. {
  182.   int thisone=0, line=0;
  183.   int i;
  184.  
  185.   if( !(fdl=opendl((long)MODE_OLDFILE)) )
  186.     return 1;
  187.  
  188.   confh=0;
  189.  
  190.   /* Converts non-case sensitive keywords to upper case */
  191.   for(i=1; i<glargc; i++)
  192.     if( *glargv[i]!='!' )
  193.       strtoupper(glargv[i]);
  194.  
  195.   con_print_line=0;
  196.   disp_list=1;
  197.  
  198.   /* get line of DiskList */
  199.   while( getstr(buffer,fdl)!=NULL && disp_list)
  200.   {
  201.     /* first checks for a startchar of a dirlist */
  202.     if( strchr(buffer,(char)STARTCHAR) )
  203.     {
  204.        if( thisone )
  205.        {
  206.          last_startchar=con_print_line;
  207.          if( printdir(&line) )
  208.            finddisk_cleanup(1);
  209.          thisone=0;
  210.        }
  211.  
  212.        line=1;
  213.     }
  214.  
  215.  
  216.     if( line )
  217.     {
  218.  
  219.        /* Copies the line in buffer to the stored dirlist */
  220.        strncpy(dirlist[line-1],buffer,MAXBUF);
  221.  
  222.        if( ++line > NUMLINES )
  223.          line--;
  224.  
  225.        /* Checks for given keywords */
  226.        if( thisone==0 )
  227.          thisone=chkmatch(buffer);
  228.     }/* if(line) */
  229.  
  230.   } /* while( get next buffer) */
  231.   if( fcnerr )
  232.   {
  233.     fcnerr=0;
  234.     finddisk_cleanup(2);
  235.   }
  236.  
  237.   if( !disp_list )
  238.     while( getstr(buffer,fdl)!=NULL);
  239.   else
  240.   {
  241.     if( thisone )
  242.       if( printdir(&line) )
  243.         finddisk_cleanup(3);
  244.  
  245.     if( con_print_line )
  246.     {
  247.       fputstr("[ Quit ]",confh);
  248.       Read(confh,buffer,5L);
  249.     }
  250.   }
  251.  
  252.   finddisk_cleanup(0)
  253. }
  254.  
  255. void finddisk_free()
  256. {
  257.   Close(fdl);
  258.   if( confh )
  259.     Close(confh);
  260. }
  261.  
  262.  
  263. printdir(line)
  264.   int *line;
  265. {
  266.   int i;
  267.  
  268.   if( !confh )
  269.     if( (confh=Open("CON:0/0/640/200/FindDisk3.1",(long)MODE_OLDFILE))==0)
  270.     {
  271.        errorstr=(" Could not open display window.");
  272.        return 1;
  273.     }
  274.  
  275.   /* print the directory */
  276.   (*line)--;
  277.   for(i=0; i<*line; i++)
  278.     if( shdsp && i )
  279.     {
  280.       if( chkmatch(dirlist[i]) )
  281.         unskrunch(dirlist[i]);
  282.     }
  283.     else
  284.       unskrunch(dirlist[i]);
  285.  
  286.   /* if at the end of the dirlist array- prints 'cut off' */
  287.   if( *line==NUMLINES-1 )
  288.     tocon(cutoff);
  289.  
  290.   return 0;
  291. }
  292.  
  293.  
  294. chkmatch(buffer)
  295.   char *buffer;
  296. {
  297.   int i, kase;
  298.   char *p;
  299.  
  300.   for(i=1; i<glargc; i++)
  301.   {
  302.     if( *glargv[i]=='!' )
  303.     {
  304.       p=glargv[i]+1;
  305.       kase=1;
  306.     }
  307.     else
  308.     {
  309.       p=glargv[i];
  310.       kase=0;
  311.     }
  312.     if( !strstr(buffer,p,kase) )
  313.       return 0;
  314.   }
  315.   return 1;
  316. }
  317.  
  318.  
  319. void tocon(s)
  320.   char *s;
  321. {
  322.   char inp[5];
  323.  
  324.   if( ++con_print_line>=DISP_LINES )
  325.   {
  326.     fputstr("[ More... ]",confh);
  327.     Read(confh,inp,5L);
  328.     inp[5]='\0';
  329.     if( strchr(inp,'q') )
  330.       disp_list=0;
  331.     fputstr("\013\033[K\015",confh);
  332.     con_print_line-=last_startchar;
  333.   }
  334.   fputstr(s,confh);
  335. }
  336.  
  337.  
  338. #define update_cleanup(x)  { update_free(); return x; }
  339.  
  340. update()
  341. {
  342.   int  i;
  343.  
  344.   if( !(fdl=opendl((long)MODE_OLDFILE)) )
  345.     return 1;
  346.  
  347.   if( !(ftmp=opentmp((long)MODE_OLDFILE)) )
  348.   {
  349.     Close(fdl);
  350.     return 0;
  351.   }
  352.  
  353.   INIT_DISKNAMES;
  354.   init_bufblks();
  355.  
  356.   /* finds the disks names in TempDL */
  357.   while( getstr(buffer,ftmp) !=NULL )
  358.   {
  359.       if( strstr(buffer,STARTSTR,1) )
  360.       {
  361.          skrunch(buffer);
  362.          if( storename(buffer) )
  363.            update_cleanup(3)
  364.       }
  365.   }
  366.   if( fcnerr )
  367.   {
  368.     fcnerr=0;
  369.     update_cleanup(10)
  370.   }
  371.  
  372.   if( storedl() )
  373.     update_cleanup(4)
  374.  
  375.   Seek(ftmp,0L,(long)OFFSET_BEGINNING);
  376.  
  377.   /* store TempDL in memory */
  378.   while( getstr(buffer,ftmp) !=NULL )
  379.     if( store( skrunch(buffer) ) )
  380.       update_cleanup(5)
  381.   if( fcnerr )
  382.   {
  383.     fcnerr=0;
  384.     update_cleanup(6);
  385.   }
  386.  
  387.   Close(fdl);
  388.   if( !(fdl=opendl((long)MODE_NEWFILE)) )
  389.   {
  390.     Close(ftmp);
  391.     FREE_DISKNAMES;
  392.     free_bufblks();
  393.     return 6;
  394.   }
  395.  
  396.   /* write the in memory disklist to the one in ram: */
  397.   for(i=0; i<=bufcount; i++)
  398.     if( fputstr(bufferblock[i],fdl) )
  399.       update_cleanup(8)
  400.  
  401.   Close(ftmp);
  402.   if( !(ftmp=opentmp((long)MODE_NEWFILE)) )
  403.     update_cleanup(7)
  404.  
  405.   update_free();
  406.   return 0;
  407. }
  408.  
  409. void update_free()
  410. {
  411.   Close(fdl);
  412.   Close(ftmp);
  413.   FREE_DISKNAMES;
  414.   free_bufblks();
  415. }
  416.  
  417.  
  418. #define remove_cleanup(x)  { remove_free(); return x; }
  419.  
  420. remove()
  421. {
  422.   int i;
  423.   char *p;
  424.  
  425.   if( *(p=firstchar(strbuf))=='\0' )
  426.      return 1;
  427.  
  428.   if( !(fdl=opendl((long)MODE_OLDFILE)) )
  429.     return 2;
  430.  
  431.   INIT_DISKNAMES;
  432.   init_bufblks();
  433.  
  434.   /* finds the disk name in DiskList */
  435.   while( getstr(buffer,fdl) !=NULL )
  436.   {
  437.       if( strstr(buffer,p,1) )
  438.       {
  439.          if( storename(buffer) )
  440.            remove_cleanup(3)
  441.       }
  442.   }
  443.   if( fcnerr )
  444.   {
  445.     fcnerr=0;
  446.     remove_cleanup(4);
  447.   }
  448.  
  449.   Seek(fdl,0L,(long)OFFSET_BEGINNING);
  450.  
  451.   if( storedl() )
  452.     remove_cleanup(4)
  453.  
  454.   Close(fdl);
  455.   if( !(fdl=opendl((long)MODE_NEWFILE)) )
  456.   {
  457.     FREE_DISKNAMES;
  458.     free_bufblks();
  459.     return 5;
  460.   }
  461.  
  462.   /* write the in memory disklist to the one in ram: */
  463.   for(i=0; i<=bufcount; i++)
  464.     if( fputstr(bufferblock[i],fdl) )
  465.       remove_cleanup(6)
  466.  
  467.   remove_free();
  468.   return 0;
  469. }
  470.  
  471. void remove_free()
  472. {
  473.   Close(fdl);
  474.   FREE_DISKNAMES;
  475.   free_bufblks();
  476. }
  477.  
  478.  
  479. /* loads the DiskList into memory but leaves out the directories in the
  480.    diskname list, pointed to by firstdisk */
  481. storedl()
  482. {
  483.   int storeit=1;  /* saving this directory */
  484.  
  485.   /* doesn't store directories that are in the temp file */
  486.   while( getstr(buffer,fdl) !=NULL )
  487.   {
  488.       if( strchr(buffer,(char)STARTCHAR) )
  489.       {
  490.          storeit=1;
  491.          diskptr=firstdisk;
  492.          while(diskptr)
  493.          {
  494.            if( strstr(buffer,diskptr->name,1) )
  495.            {
  496.              storeit=0;
  497.              break;
  498.            }
  499.            diskptr=diskptr->next;
  500.          }
  501.       }
  502.  
  503.       if(storeit)
  504.        if( store(buffer) )
  505.          return 1;
  506.   }
  507.  
  508.   if( fcnerr )
  509.   {
  510.     fcnerr=0;
  511.     return 2;
  512.   }
  513.   return 0;
  514. }
  515.  
  516. /* must be used in the WHILE( GETSTR()!=NULL) fashion */
  517. char *getstr(line,f)
  518.   char *line;
  519.   struct FileHandle *f;
  520. {
  521.   static char *buffer, *bufptr;
  522.   static int  last_read;
  523.   int len, n=MAXBUF;
  524.   char temp, *p, empty='\0';
  525.  
  526.   if( !buffer )
  527.   {
  528.     if( (buffer=(char *)AllocMem((long)CP_BUFF+1,0L))==0)
  529.     {
  530.        errorstr=outofmem;
  531.        fcnerr=1;
  532.        return (char *)0;
  533.     }
  534.     bufptr=∅
  535.   }
  536.  
  537.   while(1)
  538.     if( p=strchr(bufptr,'\n') )
  539.     {
  540.       temp=*(++p);
  541.       *p='\0';
  542.       strncpy(line,bufptr,n);
  543.       *p=temp;
  544.       bufptr=p;
  545.       return line;
  546.     }
  547.     else
  548.     {
  549.       strncpy(line,bufptr,n);
  550.       len=strlen(line);
  551.       n-=len;
  552.       line+=len;
  553.  
  554.       if( last_read )
  555.       {
  556.         FreeMem(buffer,CP_BUFF);
  557.         buffer=0;
  558.         last_read=0;
  559.         return (char *)0;
  560.       }
  561.       else
  562.         if( (len=Read(f,buffer,CP_BUFF)) <1 )
  563.           last_read=1;
  564.         else
  565.         {
  566.           last_read= len!=CP_BUFF;
  567.           bufptr=buffer;
  568.           *(buffer+len)='\0';
  569.         }
  570.     }
  571. }
  572.  
  573.  
  574. /* Saves the name of a disk in a linked list structure */
  575. storename(buffer)
  576.  char *buffer;
  577. {
  578.   if( diskptr==NULL )
  579.   {
  580.     if( (firstdisk=(struct disk *)malloc(sizeof(struct disk)) )==NULL)
  581.     {
  582.       errorstr=outofmem;
  583.       return 1;
  584.     }
  585.     diskptr=firstdisk;
  586.     strncpy(diskptr->name,buffer,MAXBUF);
  587.     diskptr->next=NULL;
  588.   }
  589.   else
  590.   {
  591.     if( (diskptr->next=(struct disk *)malloc(sizeof(struct disk)) )==NULL)
  592.     {
  593.       errorstr=outofmem;
  594.       return 2;
  595.     }
  596.     diskptr=diskptr->next;
  597.     strncpy(diskptr->name,buffer,MAXBUF);
  598.     diskptr->next=NULL;
  599.   }
  600.  
  601.   return 0;
  602. }
  603.  
  604. void free_disknames()
  605. {
  606.   struct disk *p;
  607.  
  608.   while(firstdisk)
  609.   {
  610.     p=firstdisk->next;
  611.     free(firstdisk);
  612.     firstdisk=p;
  613.   }
  614. }
  615.  
  616.  
  617. /* prints line to confh unskrunched */
  618. /* format  [BYTE]=>   [SKRUNCHAR] [# of spaces ]   */
  619.  
  620. void unskrunch(line)
  621.   char *line;
  622. {
  623.   char output[LINELEN], *p;
  624.   int i;
  625.  
  626.   p=output;
  627.   while(*line)
  628.   {
  629.     switch((int)*line)
  630.     {
  631.       case SKRUNCHAR : line++;
  632.                        for(i=SKRUNOFFS; i<(int)*line; i++)
  633.                          *(p++)=' ';
  634.                        break;
  635.  
  636.       case STARTCHAR : strncpy(p,STARTSTR,MAXBUF);
  637.                        p+=strlen(STARTSTR);
  638.                        break;
  639.  
  640.       default : *(p++)=*line;
  641.     }
  642.  
  643.     line++;
  644.   }
  645.   *p='\0';
  646.   tocon(output);
  647. }
  648.  
  649.  
  650. char *skrunch(line)
  651.   char *line;
  652. {
  653.   char skbuf[LINELEN],*p;
  654.   int  spaces=0;
  655.  
  656.   /* first tokenizes the STARTSTR/XnSTR if in line */
  657.  
  658.   tokenize(line,STARTSTR,STARTCHAR);
  659.  
  660.   /* this is the compaction of >2 spaces */
  661.   p=skbuf;
  662.   while( *line )
  663.   {
  664.     if( *line==' ' )
  665.       spaces++;
  666.     else
  667.     {
  668.       if( spaces )
  669.         if( spaces>2 )
  670.         {
  671.           *(p++)=(char)SKRUNCHAR;
  672.           *(p++)=(char)(spaces+SKRUNOFFS);
  673.           spaces=0;
  674.         }
  675.         else
  676.         {
  677.           *(p++)=' ';
  678.           if( spaces>1 ) *(p++)=' ';
  679.           spaces=0;
  680.         }
  681.  
  682.       *p=*line;
  683.       p++;
  684.     }
  685.     line++;
  686.   }
  687.   *p='\0';
  688.   strncpy(buffer,skbuf,MAXBUF);
  689.   return buffer;
  690. }
  691.  
  692.  
  693. /* will tokenize first occurance of STR in LINE */
  694. tokenize(line,str,chr)
  695.   char *line,*str;
  696.   int  chr;
  697. {
  698.   char *p,*q;
  699.  
  700.   if( p=strstr(line,str,1) )
  701.   {
  702.     q=p+strlen(str);
  703.     *p=(char)chr;
  704.     strncpy(p+1,q,MAXBUF);
  705.     return 1;
  706.   }
  707.   return 0;
  708. }
  709.  
  710.  
  711.  
  712. /* Uses:  chrcount bufcount bufferblock[] bufptr */
  713. /* stores line to memory */
  714. store(buffer)
  715.   char *buffer;
  716. {
  717.   int i;
  718.  
  719.   i=strlen(buffer);
  720.   chrcount+=i;
  721.   if( chrcount>=BLKSIZE )
  722.   {
  723.     *bufptr='\0';
  724.     chrcount=i;
  725.     if( (++bufcount)>=BUFBLKS )
  726.     {
  727.       errorstr=" DiskList too big.";
  728.       return 1;
  729.     }
  730.  
  731.     if( (bufferblock[bufcount]=(char *)malloc(BLKSIZE) )==NULL)
  732.     {
  733.        errorstr=outofmem;
  734.        return 2;
  735.     }
  736.  
  737.     bufptr=bufferblock[bufcount];
  738.   }
  739.  
  740.   strncpy(bufptr,buffer,MAXBUF);
  741.   bufptr+=i;
  742.  
  743.   return 0;
  744. }
  745.  
  746. void init_bufblks()
  747. {
  748.   bufptr=NULL;
  749.   bufcount=-1;
  750.   chrcount=BLKSIZE+1;
  751. }
  752.  
  753. void free_bufblks()
  754. {
  755.   int i;
  756.  
  757.   for(i=1; i<=bufcount; i++)
  758.     free(bufferblock[i]);
  759. }
  760.  
  761.  
  762. void get_dlpath()
  763. {
  764.   struct FileLock *lock,*Lock();
  765.  
  766.   dlpath[MAXPATHLEN]='\0';
  767.  
  768.   if( lock=Lock(dltemp,(long)ACCESS_READ) )
  769.   {
  770.     strncpy(dlpath,dltemp,MAXPATHLEN);
  771.     UnLock(lock);
  772.   }
  773.   else
  774.     strncpy(dlpath,dldisk,MAXPATHLEN);
  775. }
  776.  
  777. struct FileHandle *opendl(mode)
  778.   long mode;
  779. {
  780.   struct FileHandle *fdl;
  781.  
  782.   if( (fdl=Open(dlpath,mode))==NULL)
  783.   {
  784.     errorstr="Can't open DiskList.";
  785.     return 0;
  786.   }
  787.   return fdl;
  788. }
  789.  
  790.  
  791. #define MODE_APPEND 1000L
  792.  
  793. struct FileHandle *opentmp(mode)
  794.   long mode;
  795. {
  796.   struct FileHandle *ftmp;
  797.   struct FileLock *lock,*Lock();
  798.   int    seek=0;
  799.  
  800.   if( mode==MODE_APPEND)
  801.   {
  802.     if( lock=Lock(tempdl,(long)ACCESS_READ) )
  803.     {
  804.       UnLock(lock);
  805.       mode=(long)MODE_OLDFILE;
  806.       seek=1;
  807.     }
  808.     else
  809.       mode=(long)MODE_NEWFILE;
  810.   }
  811.  
  812.   if( (ftmp=Open(tempdl,mode))==NULL)
  813.   {
  814.     errorstr=" Can't open TempDL.";
  815.     return 0;
  816.   }
  817.  
  818.   if( seek )
  819.     Seek(ftmp,0L,(long)OFFSET_END);
  820.  
  821.   return ftmp;
  822. }
  823.  
  824.  
  825. sdir()
  826. {
  827.   char *p;
  828.  
  829.   if( *(p=firstchar(strbuf))=='\0' )
  830.     p=sdir_pat;
  831.  
  832.   if( !(ftmp=opentmp(MODE_APPEND)) )
  833.     return 1;
  834.  
  835.   if( do_ls(p,ftmp,subdir) )
  836.   {
  837.     Close(ftmp);
  838.     return 2;
  839.   }
  840.   Close(ftmp);
  841.   return 0;
  842. }
  843.  
  844.  
  845. #define ls_cleanup(x) { ls_free(lock,f_info); return x; }
  846.  
  847. do_ls(pat,fh,recur)
  848.   char *pat;
  849.   struct FileHandle *fh;
  850.   int recur;
  851. {
  852.   struct FileLock *lock=NULL, *Lock();
  853.   struct FileInfoBlock *f_info;
  854.  
  855.   char *s, *tempstr;
  856.   int  slen, isadir, col, patchg=0, firstrun=1;
  857.   char *spaces1, *spaces2;
  858.   struct disk *nextdir;
  859.   char basename[80], tempname[80];
  860.  
  861.  
  862.   /* strings of 18 & 36 spaces for formatting output */
  863.   /*       012345678901234567                        */
  864.   spaces1="                  ";
  865.   /*       0123456789012345678901234567890123456     */
  866.   spaces2="                                     ";
  867.  
  868.   INIT_DISKNAMES;
  869.   nextdir=NULL;
  870.  
  871.   strncpy(tempname,"/",2);
  872.   tempstr=tempname+1;
  873.  
  874.   if((f_info=(struct FileInfoBlock *)
  875.      AllocMem((long)sizeof(struct FileInfoBlock),0L))==0)
  876.   {
  877.     errorstr=outofmem;
  878.     FREE_DISKNAMES;
  879.     return 1;
  880.   }
  881.  
  882.   do
  883.   {
  884.     if( firstdisk )
  885.     {
  886.  
  887.       while( *(nextdir->name)=='/' )
  888.       {
  889.         strncpy(basename,(nextdir->name)+1,79);
  890.         strncpy(basename+strlen(basename),"/",2);
  891.         nextdir=nextdir->next;
  892.         if( !nextdir )
  893.           ls_cleanup(0)
  894.       }
  895.       strncpy(tempname+1,basename,78);
  896.       slen=strlen(tempname);
  897.       strncpy(tempname+slen,nextdir->name,79-slen);
  898.       if( storename(tempname) )
  899.         ls_cleanup(1);
  900.       pat=tempname+1;
  901.     }
  902.  
  903.     do
  904.     {
  905.       if( firstrun )
  906.       {
  907.         if(patchg==1)
  908.         {
  909.           patchg=2;
  910.           strncpy(tempstr,f_info->fib_FileName,78);
  911.           slen=strlen(tempstr);
  912.           tempstr[slen]=':';
  913.           strncpy(tempstr+slen+1,s+4,78-slen);
  914.           pat=tempstr;
  915.         }
  916.         else if( strchr(pat,':')<strchr(pat,'\0')-1 )
  917.         {
  918.           patchg=2;
  919.           if( !(strncmp(pat,"df0:",4) && strncmp(pat,"df1:",4)) )
  920.           {
  921.             patchg=1;
  922.             strncpy(tempstr,pat,4);
  923.             *(tempstr+4)='\0';
  924.             s=pat;
  925.             pat=tempstr;
  926.           }
  927.         }
  928.       }
  929.  
  930.       if((lock=Lock(pat,(long)ACCESS_READ))==0)
  931.         ls_cleanup(2)
  932.  
  933.       if((Examine(lock,f_info))==0)
  934.         ls_cleanup(3)
  935.     }
  936.     while( patchg==1 );
  937.     firstrun=0;
  938.  
  939.     if( fputstr(STARTSTR,fh) )
  940.       ls_cleanup(4)
  941.     if( firstdisk )
  942.     {
  943.       fputstr(tempname+1,fh);
  944.       fputstr ("\n",fh);
  945.     }
  946.     else
  947.     {
  948.       if( patchg )
  949.       {
  950.         patchg=0;
  951.         if( fputstr(pat,fh) )
  952.           ls_cleanup(5)
  953.         fputstr ("\n",fh);
  954.         strcpy(basename,pat,79);
  955.         slen=strlen(basename);
  956.         basename[slen++]='/';
  957.         basename[slen]='\0';
  958.  
  959.       }
  960.       else
  961.       {
  962.         if( fputstr(f_info->fib_FileName,fh) )
  963.           ls_cleanup(6)
  964.         fputstr (":\n",fh);
  965.         strncpy(basename,f_info->fib_FileName,78);
  966.         slen=strlen(basename);
  967.         basename[slen++]=':';
  968.         basename[slen]='\0';
  969.       }
  970.     }
  971.     col=0;
  972.  
  973.     while( (ExNext(lock,f_info))!=0)
  974.     {
  975.       s=f_info->fib_FileName;
  976.       slen=strlen(s);
  977.       isadir= (f_info->fib_DirEntryType>0);
  978.  
  979.       if((col == 3) && slen >18) {
  980.            fputstr("\n",fh);
  981.            col = 0;
  982.       }
  983.  
  984.       if (isadir)
  985.         fputstr ("\033[33m ",fh);
  986.       else
  987.         fputstr (" ",fh);
  988.  
  989.       if (slen >18) {
  990.          if( fputstr(s,fh) )
  991.            ls_cleanup(7)
  992.          col += 2;
  993.          if( fputstr(spaces2+slen,fh) )
  994.            ls_cleanup(8)
  995.       }
  996.       else {
  997.          if( fputstr(s,fh) )
  998.            ls_cleanup(9)
  999.          if( fputstr(spaces1+slen,fh) )
  1000.            ls_cleanup(10)
  1001.          col++;
  1002.       }
  1003.  
  1004.       if( isadir && recur )
  1005.         if(storename(s))
  1006.           ls_cleanup(1);
  1007.  
  1008.       if (isadir)
  1009.         fputstr("\033[0m",fh);
  1010.  
  1011.       if (col > 3) {
  1012.          fputstr("\n",fh);
  1013.          col = 0;
  1014.       }
  1015.  
  1016.     }
  1017.     fputstr("\n",fh);
  1018.     if( col )
  1019.       fputstr("\n",fh);
  1020.  
  1021.     UnLock(lock);
  1022.     lock=NULL;
  1023.  
  1024.     if( nextdir )
  1025.       nextdir=nextdir->next;
  1026.     else
  1027.       nextdir=firstdisk;
  1028.   }
  1029.   while( nextdir );
  1030.  
  1031.   ls_free(lock,f_info);
  1032.   return 0;
  1033. }
  1034.  
  1035. void ls_free(lock,f_info)
  1036.   struct FileLock *lock;
  1037.   struct FileInfoBlock *f_info;
  1038.  
  1039. {
  1040.   if( lock )
  1041.     UnLock(lock);
  1042.   FreeMem(f_info,(long)sizeof(struct FileInfoBlock));
  1043.   FREE_DISKNAMES;
  1044. }
  1045.  
  1046.  
  1047. fputstr(str,fh)
  1048.   char *str;
  1049.   struct FileHandle *fh;
  1050. {
  1051.    long len;
  1052.    len=(long)strlen(str);
  1053.    if( Write(fh,str,len)==len)
  1054.      return 0;
  1055.    return 1;
  1056. }
  1057.  
  1058.  
  1059. savedl()
  1060. {
  1061.   if( update() )
  1062.     return 1;
  1063.  
  1064.   if( strcmp(dlpath,dldisk) )
  1065.   {
  1066.     if( copy(dlpath,dldisk) )
  1067.       return 2;
  1068.     DeleteFile(dlpath);
  1069.     strncpy(dlpath,dldisk,MAXPATHLEN);
  1070.     DeleteFile(tempdl);
  1071.   }
  1072.   return 0;
  1073. }
  1074.  
  1075. loaddl()
  1076. {
  1077.   if( strcmp(dltemp,dlpath) )
  1078.     if( copy(dlpath,dltemp) )
  1079.       return 1;
  1080.   strncpy(dlpath,dltemp,MAXPATHLEN);
  1081.   return 0;
  1082. }
  1083.  
  1084. newdl()
  1085. {
  1086.   struct FileHandle *fh;
  1087.  
  1088.   if( fh=Open(dlpath,(long)MODE_NEWFILE) )
  1089.   {
  1090.     Close(fh);
  1091.     return 0;
  1092.   }
  1093.   return 1;
  1094. }
  1095.  
  1096. copy(src,dest)
  1097.   char *src,*dest;
  1098. {
  1099.   struct FileHandle *sfh,*dfh;
  1100.   char *buffer;
  1101.   int  len;
  1102.  
  1103.   if((sfh=Open(src,(long)MODE_OLDFILE))==0)
  1104.     return 1;
  1105.  
  1106.   if((dfh=Open(dest,(long)MODE_NEWFILE))==0)
  1107.   {
  1108.     Close(sfh);
  1109.     return 2;
  1110.   }
  1111.   if( (buffer=(char *)AllocMem(CP_BUFF,0L))==0)
  1112.   {
  1113.     Close(sfh);
  1114.     Close(dfh);
  1115.     errorstr=outofmem;
  1116.     return 3;
  1117.   }
  1118.  
  1119.   do
  1120.   {
  1121.     len=Read(sfh,buffer,CP_BUFF);
  1122.     Write(dfh,buffer,(long)len);
  1123.   }
  1124.   while( len!=0 );
  1125.  
  1126.   FreeMem(buffer,CP_BUFF);
  1127.  
  1128.   Close(sfh);
  1129.   Close(dfh);
  1130.   return 0;
  1131. }
  1132.  
  1133. char *firstchar(s)
  1134.   char *s;
  1135. {
  1136.   while(*s==' ')
  1137.     s++;
  1138.   return s;
  1139. }
  1140.  
  1141. /*   OK, this is not quite a true strstr() with case switch.
  1142.      The sub string must be in upper case if kase=0 (?!sorry)    */
  1143. char *strstr(string,sub,kase)
  1144.   char *string,*sub;
  1145.   int  kase;
  1146. {
  1147.   int length;
  1148.   char copstr[MAXBUF], *str;
  1149.  
  1150.   /* string copied so it will not be converted to upper case */
  1151.   strncpy(copstr,string,MAXBUF);
  1152.   str=copstr;
  1153.  
  1154.   length=strlen(sub);
  1155.  
  1156.   if( kase )
  1157.     str=strchr(str,*sub);
  1158.   else
  1159.     str=strchr(strtoupper(str),*sub);
  1160.  
  1161.   while( str )
  1162.   {
  1163.     if( strncmp(str,sub,length) )
  1164.       str++;
  1165.     else
  1166.       return string+(str-copstr);
  1167.  
  1168.     str=strchr(str,*sub);
  1169.   }
  1170.   return NULL;
  1171. }
  1172.  
  1173. char *strtoupper(s)
  1174.   char *s;
  1175. {
  1176.     register char *p = s;
  1177.  
  1178.     while(*p)
  1179.     {
  1180.        *p = toupper(*p);
  1181.        p++;
  1182.     }
  1183.     return(s);
  1184. }
  1185.  
  1186.  
  1187. /* Following lifted from ...*/
  1188.  
  1189. /* misc.c
  1190.  *      Misc. subroutines that like to live together...
  1191.  *
  1192.  * Phillip Lindsay (c) 1987 Commodore-Amiga - This code may be freely used
  1193.  * as long as the copyright notice is left intact.
  1194.  */
  1195.  
  1196. /* btoc() takes a pointer to a BSTR and converts it to a
  1197.  * C string.
  1198.  */
  1199. char *btoc(bstring)
  1200. CPTR bstring;
  1201. {
  1202.  register UBYTE len,count,*cstring=NULL;
  1203.  
  1204.  if (bstring) {
  1205.     cstring = (UBYTE *) bstring;
  1206.     len = cstring[0];
  1207.     for(count=0;count < len;count++)
  1208.         cstring[count] = cstring[count+1];
  1209.  
  1210.     cstring[count] = '\0';
  1211.  }
  1212.  return((char *)cstring);
  1213. }
  1214.  
  1215. /*
  1216.  * memcpy() - fast "C" byte memory copy.
  1217.  */
  1218. VOID memcpy(source,dest,size)
  1219. UBYTE *source,*dest;
  1220. ULONG size;
  1221. {
  1222.     register UBYTE  *msource=source,
  1223.                     *mdest=dest;
  1224.     register ULONG  msize=size;
  1225.  
  1226.     if (msize) {
  1227.         do { *mdest++ = *msource++; } while(--msize);
  1228.     }
  1229.  
  1230. }
  1231.  
  1232. /*
  1233.  *  find a dos node in the system device list
  1234.  *
  1235.  */
  1236. struct DeviceNode *finddosnode(lookfor)
  1237. char    *lookfor;
  1238. {
  1239.     extern   struct DosLibrary *DOSBase;
  1240.              struct RootNode   *rnode;
  1241.              struct DosInfo    *dinfo;
  1242.     register struct DeviceNode *dnode;
  1243.     register char              *bname;
  1244.     char                        name2[81];
  1245.     BOOL                        found = FALSE;
  1246.  
  1247.     rnode   = (struct RootNode *)  DOSBase->dl_Root;        /* find root node */
  1248.     dinfo   = (struct DosInfo  *)  BADDR(rnode->rn_Info);   /* now dos info   */
  1249.  
  1250.     Forbid();
  1251.  
  1252.     for(dnode = (struct DeviceNode *) BADDR(dinfo->di_DevInfo); ( dnode ) ;
  1253.       dnode = (struct DeviceNode *) BADDR(dnode->dn_Next))
  1254.     {
  1255.         bname = (char *) BADDR(dnode->dn_Name);
  1256.         memcpy(bname, name2, (ULONG)( bname[0] + 1 ) );
  1257.  
  1258.         if ( !( strcmp( lookfor, strtoupper(btoc(name2)) ) ) ) {
  1259.             found   =   TRUE;
  1260.             break;
  1261.         }
  1262.  
  1263.     }
  1264.  
  1265.     Permit();
  1266.  
  1267.     return dnode;       /* NULL if not found */
  1268. }
  1269.  
  1270. /* end of misc.c */
  1271.  
  1272.