home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 579a.lha / FindDisk_v3.3 / src.LZH / src / fd2src / fd2.c next >
Encoding:
C/C++ Source or Header  |  1991-04-24  |  20.8 KB  |  1,203 lines

  1.  
  2. /*                            FindDisk2.3
  3.  
  4.      Author      : Ross MacGregor
  5.      Date        : 27/10/88
  6.      Last Update : 23 Apr 91
  7.      Comments    : This is a public domain program.
  8.  
  9.  
  10.      DiskList storein 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 <string.h>
  26.  
  27. #include <exec/types.h>
  28. #include <exec/nodes.h>
  29. #include <exec/lists.h>
  30. #include <exec/libraries.h>
  31. #include <exec/ports.h>
  32. #include <exec/interrupts.h>
  33. #include <exec/io.h>
  34. #include <exec/memory.h>
  35. #include <libraries/dos.h>
  36. #include <libraries/dosextens.h>
  37.  
  38.  
  39. /* lattice may want smaller strings */
  40.  
  41. #define HELPTEXT1  "\nFindDisk2.3:\n\
  42. FD -l             ; Loads DiskList to ram:\n\
  43. FD -s             ; Saves DiskList back to disk (first doing an update)\n\
  44. FD -d  [path]     ; Saves dir listing to ram:TempDL\n\
  45. FD -a  [path]     ; Saves listing with all sub-directories included\n\
  46. FD -u             ; Updates the DiskList with TempDL\n\
  47. FD -n             ; Creates a new (empty) DiskList\n"
  48.  
  49. #define HELPTEXT2  "FD -r  diskname   ; Removes directory from DiskList matching 'diskname'\n\
  50. FD text1 [textn]  ; Lists disk dir with a line containing text1 to textn\n\
  51.   FD text           ; Case insensitive scan for text\n\
  52.   FD !text          ; Case sensitive scan for for text\n"
  53.  
  54. #define HELPTEXT3 "\nEnvironment Variables: (= default setting)\n\
  55.   DLDISK  =  FindDisk:Disklist (Disk storage location/name)\n\
  56.   DLTEMP  =  ram:DiskList (Ram storage location/name)\n\
  57.   DLDRIVE =  df0: (Captures dir of this drive)\n\n"
  58.  
  59.  
  60. #define CP_BUFF 10000L    /* Buffer size for the file copy function */
  61.  
  62.  
  63. /* This indicates the start line of a dir listing, and
  64.    it MUST have the name of the disk on the same line.  */
  65.  
  66. #define STARTSTR  "Directory of "
  67.  
  68.  
  69. /* Special character used to compact the spaces in DiskList */
  70. #define SKRUNCHAR 1
  71. #define SKRUNOFFS 10
  72.  
  73. /* Special characters used to replace the STARTSTR */
  74. #define STARTCHAR  2
  75.  
  76. /* Lines in the stored dir listing array */
  77. #define NUMLINES 25
  78.  
  79. /* Max length of the lines read in */
  80. #define LINELEN  170L
  81. #define MAXBUF   169L
  82.  
  83. BPTR fdl, ftmp;
  84. BPTR confh;
  85.  
  86. char *tempdl="ram:TempDL";
  87.  
  88. char *dltemp="ram:DiskList", *dldisk="FindDisk:DiskList";
  89. char *sdir_pat="df0:";
  90.  
  91. #define MAXPATHLEN 80
  92.  
  93. char *dlpath;
  94. char buffer[LINELEN];
  95.  
  96. /* global main arguments */
  97. int glargc;
  98. char **glargv;
  99.  
  100. /* function error indicator */
  101. int fcnerr;
  102.  
  103. char *outofmem="Out of Memory Error.\n";
  104. char *cutoff=" - - (no more lines available) - -\n";
  105.  
  106. /* finddisk uses this */
  107. char dirlist[NUMLINES][LINELEN];
  108.  
  109.  
  110. /*------------ dynamic structure for coping DL to memory -------------*/
  111.  
  112. /* Blocks of memory for storing the disklist */
  113. #define BLKSIZE 4096L
  114.  
  115. struct mem_block
  116. {
  117.   char buffer[BLKSIZE+1];
  118.   struct mem_block *next;
  119. };
  120.  
  121. struct mem_block *mem_blocks, *cur_mem_block;
  122. char *mem_block_ptr;
  123. int chrcount;
  124. void init_bufblks(), free_bufblks();
  125. int  write_bufblks(BPTR fd);
  126.  
  127. /*------------ dynamic structure for listing the volume names --------*/
  128. /*                   used in recursive do_ls call also                */
  129.  
  130. struct disk
  131. {
  132.   char name[LINELEN];
  133.   struct disk *next;
  134. };
  135. struct disk *firstdisk,*diskptr;
  136.  
  137. #define INIT_DISKNAMES firstdisk=diskptr=NULL
  138. #define FREE_DISKNAMES free_disknames()
  139.  
  140. void free_disknames();
  141.  
  142. /*----------------------------------------------------------------------*/
  143.  
  144. char *mystrstr(), *strtoupper(), *getstr();
  145. void putstr();
  146.  
  147. char *skrunch(), *getenv();
  148. void unskrunch(), get_dlpath();
  149.  
  150. BPTR opendl(), opentmp();
  151. char *getenv();
  152. void get_dlpath();
  153.  
  154. void finddisk();
  155. void print_dir_if(int thisone,int line);
  156.  
  157. int update(), remove(), loaddl(), savedl(), sdir(), newdl();
  158.  
  159. void update_free(), ls_free(), remove_free();
  160.  
  161. char *strchr(), *malloc();
  162.  
  163. void main(argc,argv)
  164.   int argc;
  165.   char *argv[];
  166. {
  167.  
  168.   glargv=argv;
  169.   glargc=argc;
  170.  
  171.   if( (confh=Output())==NULL )
  172.     exit(1);
  173.  
  174.   if( argc==1)
  175.   {
  176.     putstr(HELPTEXT1);
  177.     putstr(HELPTEXT2);
  178.     putstr(HELPTEXT3);
  179.     exit(0);
  180.   }
  181.  
  182.   dldisk=getenv("env:dldisk",dldisk);
  183.   dltemp=getenv("env:dltemp",dltemp);
  184.   sdir_pat=getenv("env:dldrive",sdir_pat);
  185.   get_dlpath();
  186.  
  187.   if( *argv[1]=='-' )
  188.   {
  189.     switch( *(argv[1]+1) )
  190.     {
  191.        case 'd':  if( sdir(0) )
  192.                     putstr("SaveDir failed!\n");
  193.                   break;
  194.  
  195.        case 'a':  if( sdir(1) )
  196.                     putstr("SaveDir failed!\n");
  197.                   break;
  198.  
  199.        case 's':  if( savedl() )
  200.                     putstr("SaveDL failed!\n");
  201.                   break;
  202.  
  203.        case 'l':  if( loaddl() )
  204.                     putstr("LoadDL failed!\n");
  205.                   break;
  206.  
  207.        case 'u':  if( update() )
  208.                     putstr("Update failed!\n");
  209.                   break;
  210.  
  211.        case 'r':  if( remove() )
  212.                     putstr("Remove failed!\n");
  213.                   break;
  214.  
  215.        case 'n':  if( newdl() )
  216.                     putstr("Empty DiskList created (Save if in RAM).\n");
  217.                   break;
  218.  
  219.        default :  putstr("Unknown Option.\n");
  220.     }
  221.   }
  222.   else finddisk();
  223.  
  224. }
  225.  
  226.  
  227. char *getenv(fullpath,var)
  228.   char *fullpath, *var;
  229. {
  230.   BPTR lock;
  231.   BPTR fh;
  232.   char *buffer;
  233.   int  len;
  234.  
  235.   if( lock=Lock(fullpath,(long)ACCESS_READ) )
  236.   {
  237.     UnLock(lock);
  238.     if( !(fh=Open(fullpath,(long)MODE_OLDFILE)) )
  239.       return var;
  240.     if( !(buffer=(char *)malloc(MAXPATHLEN+1)) )
  241.     {
  242.       putstr(outofmem);
  243.       Close(fh);
  244.       return var;
  245.     }
  246.     len=Read(fh,buffer,(long)MAXPATHLEN);
  247.     Close(fh);
  248.     *(buffer+len)='\0';
  249.     return buffer;
  250.   }
  251.   return var;
  252. }
  253.  
  254.  
  255. void finddisk()
  256. {
  257.   int  kase=0, thisone=0, line=0;
  258.   int i;
  259.   char *p;
  260.  
  261.   if( !(fdl=opendl((long)MODE_OLDFILE)) )
  262.     return;
  263.  
  264.   /* Converts non-case sensitive keywords to upper case */
  265.   for(i=1; i<glargc; i++)
  266.     if( *glargv[i]!='!' )
  267.       strtoupper(glargv[i]);
  268.  
  269.   /* get line of DiskList */
  270.   while( getstr(buffer,fdl) !=NULL )
  271.   {
  272.  
  273.     /* first checks for a startchar of a dirlist */
  274.     if( strchr(buffer,(char)STARTCHAR) )
  275.     {
  276.        print_dir_if(thisone,line);
  277.        thisone=0;
  278.        line=1;
  279.     }
  280.  
  281.     if( line )
  282.     {
  283.        /* Copies the line in buffer to the stored dirlist */
  284.        strcpy(dirlist[line-1],buffer);
  285.  
  286.        if( ++line > NUMLINES )
  287.          line--;
  288.  
  289.        /* Checks for given keywords */
  290.        if( thisone==0 )
  291.          for(i=1; i<glargc; i++)
  292.          {
  293.            if( *glargv[i]=='!' )
  294.            {
  295.              p=glargv[i]+1;
  296.              kase=1;
  297.            }
  298.            else
  299.            {
  300.              p=glargv[i];
  301.              kase=0;
  302.            }
  303.  
  304.            if( mystrstr(buffer,p,kase) )
  305.              thisone=1;
  306.            else
  307.            {
  308.              thisone=0;
  309.              break;
  310.            }
  311.          }
  312.  
  313.     }/* if(line) */
  314.  
  315.   } /* while( get next buffer) */
  316.  
  317.   print_dir_if(thisone,line);
  318.  
  319.   Close(fdl);
  320. }
  321.  
  322. void print_dir_if(int thisone,int line)
  323. {
  324.   int i;
  325.  
  326.   if( thisone )
  327.   {
  328.         line--;
  329.         for(i=0; i<line; i++)
  330.           unskrunch(dirlist[i]);
  331.  
  332.         /* if at the end of the dirlist array- prints 'cut off' */
  333.         if( line==NUMLINES-1 )
  334.           putstr(cutoff);
  335.   }
  336. }
  337.  
  338.  
  339.  
  340. #define update_cleanup(x)  { update_free(); return x; }
  341.  
  342. update()
  343. {
  344.   int  i;
  345.  
  346.   if( !(fdl=opendl((long)MODE_OLDFILE)) )
  347.     return 1;
  348.  
  349.   if( !(ftmp=opentmp((long)MODE_OLDFILE)) )
  350.   {
  351.     Close(fdl);
  352.     return 0;
  353.   }
  354.  
  355.   INIT_DISKNAMES;
  356.   init_bufblks();
  357.  
  358.   /* finds the disks names in TempDL */
  359.   while( getstr(buffer,ftmp) !=NULL )
  360.   {
  361.       if( mystrstr(buffer,STARTSTR,1) )
  362.       {
  363.          skrunch(buffer);
  364.          if( storename(buffer) )
  365.            update_cleanup(3)
  366.       }
  367.   }
  368.   if( fcnerr )
  369.     update_cleanup(10)
  370.  
  371.   if( storedl() )
  372.     update_cleanup(4)
  373.  
  374.   Seek(ftmp,0L,(long)OFFSET_BEGINNING);
  375.  
  376.   /* store TempDL in memory */
  377.   while( getstr(buffer,ftmp) !=NULL )
  378.     if( store( skrunch(buffer) ) )
  379.       update_cleanup(5)
  380.   if( fcnerr )
  381.     update_cleanup(6);
  382.  
  383.   Close(fdl);
  384.   if( !(fdl=opendl((long)MODE_NEWFILE)) )
  385.   {
  386.     Close(ftmp);
  387.     FREE_DISKNAMES;
  388.     free_bufblks();
  389.     return 7;
  390.   }
  391.  
  392.   /* write the in memory disklist to the one in ram: */
  393.     if( write_bufblks(fdl) )
  394.       update_cleanup(8)
  395.  
  396.   Close(ftmp);
  397.   if( !(ftmp=opentmp((long)MODE_NEWFILE)) )
  398.     update_cleanup(9)
  399.  
  400.   update_free();
  401.   return 0;
  402. }
  403.  
  404. void update_free()
  405. {
  406.   Close(fdl);
  407.   Close(ftmp);
  408.   FREE_DISKNAMES;
  409.   free_bufblks();
  410. }
  411.  
  412.  
  413.  
  414.  
  415. #define remove_cleanup(x)  { remove_free(); return x; }
  416.  
  417. remove()
  418. {
  419.   int i;
  420.  
  421.   if( !(fdl=opendl((long)MODE_OLDFILE)) )
  422.     return 2;
  423.  
  424.   INIT_DISKNAMES;
  425.   init_bufblks();
  426.  
  427.   /* finds the disk name in DiskList */
  428.   while( getstr(buffer,fdl) !=NULL )
  429.   {
  430.       if( mystrstr(buffer,glargv[2],1) )
  431.       {
  432.          if( storename(buffer) )
  433.            remove_cleanup(3)
  434.       }
  435.   }
  436.   if( fcnerr )
  437.     remove_cleanup(4);
  438.  
  439.   Seek(fdl,0L,(long)OFFSET_BEGINNING);
  440.  
  441.   if( storedl() )
  442.     remove_cleanup(5)
  443.  
  444.   Close(fdl);
  445.   if( !(fdl=opendl((long)MODE_NEWFILE)) )
  446.   {
  447.     FREE_DISKNAMES;
  448.     free_bufblks();
  449.     return 6;
  450.   }
  451.  
  452.   /* write the in memory disklist to the one in ram: */
  453.   if( write_bufblks(fdl) )
  454.       remove_cleanup(7)
  455.  
  456.   remove_free();
  457.   return 0;
  458. }
  459.  
  460.  
  461. void remove_free()
  462. {
  463.   Close(fdl);
  464.   FREE_DISKNAMES;
  465.   free_bufblks();
  466. }
  467.  
  468.  
  469.  
  470. /* loads the DiskList into memory but leaves out the directories in the
  471.    diskname list, pointed to by firstdisk */
  472. storedl()
  473. {
  474.   int storeit=1;  /* saving this directory */
  475.  
  476.   /* doesn't store directories that are in the temp file */
  477.   while( getstr(buffer,fdl) !=NULL )
  478.   {
  479.       if( strchr(buffer,(char)STARTCHAR) )
  480.       {
  481.          storeit=1;
  482.          diskptr=firstdisk;
  483.          while(diskptr)
  484.          {
  485.            if( mystrstr(buffer,diskptr->name,1) )
  486.            {
  487.              storeit=0;
  488.              break;
  489.            }
  490.            diskptr=diskptr->next;
  491.          }
  492.       }
  493.  
  494.       if(storeit)
  495.        if( store(buffer) )
  496.          return 1;
  497.   }
  498.  
  499.   return fcnerr;
  500. }
  501.  
  502.  
  503.  
  504. /* Saves the name of a disk in a linked list structure */
  505. storename(buffer)
  506.  char *buffer;
  507. {
  508.   if( diskptr==NULL )
  509.   {
  510.     if( (firstdisk=(struct disk *)malloc(sizeof(struct disk)) )==NULL)
  511.     {
  512.       putstr(outofmem);
  513.       return 1;
  514.     }
  515.     diskptr=firstdisk;
  516.     strcpy(diskptr->name,buffer);
  517.     diskptr->next=NULL;
  518.   }
  519.   else
  520.   {
  521.     if( (diskptr->next=(struct disk *)malloc(sizeof(struct disk)) )==NULL)
  522.     {
  523.       putstr(outofmem);
  524.       return 2;
  525.     }
  526.     diskptr=diskptr->next;
  527.     strcpy(diskptr->name,buffer);
  528.     diskptr->next=NULL;
  529.   }
  530.  
  531.   return 0;
  532. }
  533.  
  534. void free_disknames()
  535. {
  536.   struct disk *p;
  537.  
  538.   while(firstdisk)
  539.   {
  540.     p=firstdisk->next;
  541.     free(firstdisk);
  542.     firstdisk=p;
  543.   }
  544. }
  545.  
  546.  
  547. /* prints line to stdout unskrunched */
  548. /* format  [BYTE]=>   [SKRUNCHAR] [# of spaces ]   */
  549.  
  550. void unskrunch(line)
  551.   char *line;
  552. {
  553.   char output[LINELEN], *p;
  554.   int i;
  555.  
  556.   p=output;
  557.   while(*line)
  558.   {
  559.     switch((int)*line)
  560.     {
  561.       case SKRUNCHAR : line++;
  562.                        for(i=SKRUNOFFS; i<(int)*line; i++)
  563.                          *(p++)=' ';
  564.                        break;
  565.  
  566.       case STARTCHAR : strcpy(p,STARTSTR);
  567.                        p+=strlen(STARTSTR);
  568.                        break;
  569.  
  570.       default : *(p++)=*line;
  571.     }
  572.  
  573.     line++;
  574.   }
  575.   *p='\0';
  576.   putstr(output);
  577. }
  578.  
  579.  
  580. char *skrunch(line)
  581.   char *line;
  582. {
  583.   char skbuf[LINELEN],*p;
  584.   int  spaces=0;
  585.  
  586.   /* first tokenizes the STARTSTR/XnSTR if in line */
  587.  
  588.   tokenize(line,STARTSTR,STARTCHAR);
  589.  
  590.   /* this is the compaction of >2 spaces */
  591.   p=skbuf;
  592.   while( *line )
  593.   {
  594.     if( *line==' ' )
  595.       spaces++;
  596.     else
  597.     {
  598.       if( spaces )
  599.         if( spaces>2 )
  600.         {
  601.           *(p++)=(char)SKRUNCHAR;
  602.           *(p++)=(char)(spaces+SKRUNOFFS);
  603.           spaces=0;
  604.         }
  605.         else
  606.         {
  607.           *(p++)=' ';
  608.           if( spaces>1 ) *(p++)=' ';
  609.           spaces=0;
  610.         }
  611.  
  612.       *p=*line;
  613.       p++;
  614.     }
  615.     line++;
  616.   }
  617.   *p='\0';
  618.   strcpy(buffer,skbuf);
  619.   return buffer;
  620. }
  621.  
  622.  
  623. /* will tokenize first occurance of STR in LINE */
  624. tokenize(line,str,chr)
  625.   char *line,*str;
  626.   int  chr;
  627. {
  628.   char *p,*q;
  629.  
  630.   if( p=mystrstr(line,str,1) )
  631.   {
  632.     q=p+strlen(str);
  633.     *p=(char)chr;
  634.     strcpy(p+1,q);
  635.     return 1;
  636.   }
  637.   return 0;
  638. }
  639.  
  640.  
  641.  
  642. /* stores line to memory */
  643. store(buffer)
  644.   char *buffer;
  645. {
  646.   struct mem_block *p;
  647.   int i;
  648.  
  649.   i=strlen(buffer);
  650.   chrcount+=i;
  651.  
  652.   if( chrcount>=BLKSIZE )
  653.   {
  654.     if( mem_block_ptr )
  655.       *mem_block_ptr='\0';
  656.     chrcount=i;
  657.  
  658.     if( (p=(struct mem_block *)malloc(sizeof(struct mem_block)) )==NULL)
  659.     {
  660.        putstr(outofmem);
  661.        return 2;
  662.     }
  663.  
  664.     p->next=NULL;
  665.  
  666.     if( mem_blocks )
  667.       cur_mem_block->next=p;
  668.     else
  669.       mem_blocks=p;
  670.     cur_mem_block=p;
  671.  
  672.     mem_block_ptr=cur_mem_block->buffer;
  673.   }
  674.  
  675.   strcpy(mem_block_ptr,buffer);
  676.   mem_block_ptr+=i;
  677.  
  678.   return 0;
  679. }
  680.  
  681. write_bufblks(BPTR fd)
  682. {
  683.   struct mem_block *p;
  684.  
  685.   p=mem_blocks;
  686.   while(p)
  687.   {
  688.     if( fputstr(p->buffer,fd) )
  689.       return 1;
  690.     p=p->next;
  691.   }
  692.  
  693.   return 0;
  694. }
  695.  
  696.  
  697. void init_bufblks()
  698. {
  699.   mem_block_ptr=NULL;
  700.   chrcount=BLKSIZE+1;
  701.   cur_mem_block=NULL;
  702.   mem_blocks=NULL;
  703. }
  704.  
  705. void free_bufblks()
  706. {
  707.   struct mem_block *p,*next;
  708.  
  709.   p=mem_blocks;
  710.   while(p)
  711.   {
  712.     next=p->next;
  713.     free(p);
  714.     p=next;
  715.   }
  716. }
  717.  
  718.  
  719. /*   OK, this is not quite a true strstr() with case switch.
  720.      The sub string must be in upper case if kase=0 (?!sorry)    */
  721.  
  722. char *mystrstr(str,sub,kase)
  723.   char *str,*sub;
  724.   int  kase;
  725. {
  726.   int length;
  727.  
  728.   length=strlen(sub);
  729.  
  730.   if( kase )
  731.     str=strchr(str,*sub);
  732.   else
  733.     str=strchr(strtoupper(str),*sub);
  734.  
  735.   while( str )
  736.   {
  737.     if( strncmp(str,sub,length) )
  738.       str++;
  739.     else
  740.       return str;
  741.  
  742.     str=strchr(str,*sub);
  743.   }
  744.  
  745.   return NULL;
  746. }
  747.  
  748. char *strtoupper(s)
  749.   char *s;
  750. {
  751.     register char *p = s;
  752.  
  753.     while(*p)
  754.     {
  755.        *p = toupper(*p);
  756.        p++;
  757.     }
  758.     return(s);
  759. }
  760.  
  761. void get_dlpath()
  762. {
  763.   BPTR lock;
  764.  
  765.   if( lock=Lock(dltemp,(long)ACCESS_READ) )
  766.   {
  767.     dlpath=dltemp;
  768.     UnLock(lock);
  769.   }
  770.   else
  771.     dlpath=dldisk;
  772. }
  773.  
  774. BPTR opendl(mode)
  775.   long mode;
  776. {
  777.   BPTR fdl;
  778.  
  779.   if( (fdl=Open(dlpath,mode))==NULL)
  780.   {
  781.     putstr("Error: Could not open DiskList\n");
  782.     return 0;
  783.   }
  784.   return fdl;
  785. }
  786.  
  787.  
  788. #define MODE_APPEND 1000L
  789.  
  790. BPTR opentmp(mode)
  791.   long mode;
  792. {
  793.   BPTR ftmp;
  794.   BPTR lock;
  795.   int    seek=0;
  796.  
  797.   if( mode==MODE_APPEND)
  798.   {
  799.     if( lock=Lock(tempdl,(long)ACCESS_READ) )
  800.     {
  801.       UnLock(lock);
  802.       mode=(long)MODE_OLDFILE;
  803.       seek=1;
  804.     }
  805.     else
  806.       mode=(long)MODE_NEWFILE;
  807.   }
  808.  
  809.   if( (ftmp=Open(tempdl,mode))==NULL)
  810.   {
  811.     putstr("Error: Could not open RAM:TempDL\n");
  812.     return 0;
  813.   }
  814.  
  815.   if( seek )
  816.     Seek(ftmp,0L,(long)OFFSET_END);
  817.  
  818.   return ftmp;
  819. }
  820.  
  821.  
  822. sdir(recur)
  823.   int recur;
  824. {
  825.   char *p;
  826.  
  827.  
  828.   if( glargc>2 )
  829.     p=glargv[2];
  830.   else
  831.     p=sdir_pat;
  832.  
  833.   if( !(ftmp=opentmp(MODE_APPEND)) )
  834.     return 1;
  835.  
  836.   if( do_ls(p,ftmp,recur) )
  837.   {
  838.     Close(ftmp);
  839.     return 2;
  840.   }
  841.   Close(ftmp);
  842.   return 0;
  843. }
  844.  
  845.  
  846. #define ls_cleanup(x) { ls_free(lock,f_info); return x; }
  847.  
  848. do_ls(pat,fh,recur)
  849.   char *pat;
  850.   BPTR fh;
  851.   int recur;
  852. {
  853.   BPTR lock=NULL;
  854.   struct FileInfoBlock *f_info;
  855.  
  856.   char *s, *tempstr;
  857.   int  slen, isadir, col, patchg=0, firstrun=1;
  858.   char *spaces1, *spaces2;
  859.   struct disk *nextdir;
  860.   char basename[80], tempname[80];
  861.  
  862.  
  863.   /* strings of 18 & 36 spaces for formatting output */
  864.   /*       012345678901234567                        */
  865.   spaces1="                  ";
  866.   /*       0123456789012345678901234567890123456     */
  867.   spaces2="                                     ";
  868.  
  869.   INIT_DISKNAMES;
  870.   nextdir=NULL;
  871.  
  872.   strcpy(tempname,"/");
  873.   tempstr=tempname+1;
  874.  
  875.   if((f_info=(struct FileInfoBlock *)
  876.      AllocMem((long)sizeof(struct FileInfoBlock),0L))==0)
  877.   {
  878.     putstr(outofmem);
  879.     FREE_DISKNAMES;
  880.     return 1;
  881.   }
  882.  
  883.   do
  884.   {
  885.     if( firstdisk )
  886.     {
  887.       while( nextdir && *(nextdir->name)=='/' )
  888.       {
  889.         strncpy(basename,(nextdir->name)+1,78);
  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.         strncpy(basename,pat,79L);
  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.   BPTR 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. void putstr(str)
  1047.   char *str;
  1048. {
  1049.     Write(confh,str,(long)strlen(str));
  1050. }
  1051.  
  1052.  
  1053. fputstr(str,fh)
  1054.   char *str;
  1055.   BPTR fh;
  1056. {
  1057.    long len;
  1058.    len=(long)strlen(str);
  1059.    if( Write(fh,str,len)==len)
  1060.      return 0;
  1061.    return 1;
  1062. }
  1063.  
  1064. /* must be used in the WHILE( GETSTR()!=NULL) fashion */
  1065. char *getstr(line,f)
  1066.   char *line;
  1067.   BPTR f;
  1068. {
  1069.   static char *buffer, *bufptr;
  1070.   static int  last_read;
  1071.   int len, n=MAXBUF;
  1072.   char temp, *p, empty='\0';
  1073.  
  1074.   if( !buffer )
  1075.   {
  1076.     if( (buffer=(char *)AllocMem((long)CP_BUFF+1,0L))==0)
  1077.     {
  1078.        putstr(outofmem);
  1079.        fcnerr=1;
  1080.        return (char *)0;
  1081.     }
  1082.     bufptr=∅
  1083.   }
  1084.  
  1085.   while(1)
  1086.     if( p=strchr(bufptr,'\n') )
  1087.     {
  1088.       temp=*(++p);
  1089.       *p='\0';
  1090.       strncpy(line,bufptr,n);
  1091.       *p=temp;
  1092.       bufptr=p;
  1093.       return line;
  1094.     }
  1095.     else
  1096.     {
  1097.       strncpy(line,bufptr,n);
  1098.       len=strlen(line);
  1099.       n-=len;
  1100.       line+=len;
  1101.  
  1102.       if( last_read )
  1103.       {
  1104.         FreeMem(buffer,CP_BUFF+1);
  1105.         buffer=0;
  1106.         last_read=0;
  1107.         return (char *)0;
  1108.       }
  1109.       else
  1110.         if( (len=Read(f,buffer,CP_BUFF)) <1 )
  1111.           last_read=1;
  1112.         else
  1113.         {
  1114.           last_read= len!=CP_BUFF;
  1115.           bufptr=buffer;
  1116.           *(buffer+len)='\0';
  1117.         }
  1118.     }
  1119. }
  1120.  
  1121. savedl()
  1122. {
  1123.   if( update() )
  1124.     return 1;
  1125.  
  1126.   if( strcmp(dlpath,dldisk) )
  1127.   {
  1128.     if( copy(dlpath,dldisk) )
  1129.       return 1;
  1130.     DeleteFile(dlpath);
  1131.     DeleteFile(tempdl);
  1132.   }
  1133.   return 0;
  1134. }
  1135.  
  1136. loaddl()
  1137. {
  1138.   if( strcmp(dltemp,dlpath) )
  1139.     if( copy(dlpath,dltemp) )
  1140.       return 1;
  1141.   return 0;
  1142. }
  1143.  
  1144. newdl()
  1145. {
  1146.   BPTR fh;
  1147.  
  1148.   putstr("Are you sure? ");
  1149.   Read(confh,buffer,LINELEN);
  1150.  
  1151.   if( *buffer=='y' )
  1152.   {
  1153.     if( fh=Open(dlpath,(long)MODE_NEWFILE) )
  1154.     {
  1155.       Close(fh);
  1156.       return 0;
  1157.     }
  1158.     return 1;
  1159.   }
  1160.   return 0;
  1161. }
  1162.  
  1163. copy(src,dest)
  1164.   char *src,*dest;
  1165. {
  1166.   BPTR sfh,dfh;
  1167.   char *buffer;
  1168.   int  len;
  1169.  
  1170.   if((sfh=Open(src,(long)MODE_OLDFILE))==0)
  1171.     return 1;
  1172.  
  1173.   if((dfh=Open(dest,(long)MODE_NEWFILE))==0)
  1174.   {
  1175.     Close(sfh);
  1176.     return 2;
  1177.   }
  1178.   if( (buffer=(char *)AllocMem(CP_BUFF,0L))==0)
  1179.   {
  1180.     Close(sfh);
  1181.     Close(dfh);
  1182.     putstr(outofmem);
  1183.     return 3;
  1184.   }
  1185.  
  1186.   do
  1187.   {
  1188.     len=Read(sfh,buffer,CP_BUFF);
  1189.     Write(dfh,buffer,(long)len);
  1190.   }
  1191.   while( len!=0 );
  1192.  
  1193.   FreeMem(buffer,CP_BUFF);
  1194.  
  1195.   Close(sfh);
  1196.   Close(dfh);
  1197.   return 0;
  1198. }
  1199.  
  1200.  
  1201.  
  1202.  
  1203.