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 / fd3src / fd3.c next >
Encoding:
C/C++ Source or Header  |  1991-04-24  |  21.9 KB  |  1,283 lines

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