home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-386-Vol-2of3.iso / c / csh4.zip / LS.C < prev    next >
C/C++ Source or Header  |  1985-09-03  |  6KB  |  301 lines

  1. #include <stdio.h>
  2.  
  3. typedef struct
  4. {
  5.     char attribute;
  6.     unsigned file_time;
  7.     unsigned file_date;
  8.     long file_size;
  9.     char file_name[13];
  10. } file_desc;
  11.  
  12. typedef struct
  13. {
  14.     char dos_reserved[21];
  15.     file_desc file;
  16. } fcb;
  17.  
  18. #define maxfiles 128 
  19.  
  20. char printbuf[256];
  21. int mode = 0x10;
  22. file_desc *getfirst(),*getnext();
  23. char *index(), *rindex();
  24. int verbose=0,column=4,recurse=0;
  25. int quiet = 0;
  26. long time();
  27. short year;
  28.  
  29. do_return(result)
  30. {
  31.     verbose = quiet = recurse = 0;
  32.     column = 4;
  33.     return result;
  34. }
  35. ls(argc,argv)
  36. char *argv[];
  37. {
  38.     int noargs;
  39.     char *current;
  40.     char namebuf[128];
  41.     /*
  42.      * get current time
  43.      */
  44.     year = (int)((time(NULL) >> 25) & 0x7F) + 80;
  45.     /*
  46.      * set up a default search name
  47.      */
  48.     if (noargs = (argc == 1))
  49.         argc++;
  50.     while(--argc)
  51.     {
  52.         if (noargs)
  53.             current = "*.*";
  54.         else
  55.             current = *(++argv);    /* get current file name */
  56.         if (*current == '-')
  57.         {
  58.             ++current;    /* point past - */
  59.             while (*current)
  60.             {
  61.                 switch (*current++)
  62.                 {
  63.                 case 'l':
  64.                 case 'L':
  65.                     verbose = 1;
  66.                     if (column != 1)
  67.                         column = 2;
  68.                     if (quiet)
  69.                     {
  70.                         fprintf(stderr,"ls : verbose and quiet conflict\n");
  71.                         do_return(-1);
  72.                     }
  73.                     break;
  74.                 case 'q':
  75.                 case 'Q':
  76.                     quiet = 1;
  77.                     if (verbose)
  78.                     {
  79.                         fprintf(stderr,"ls : quiet and verbose conflict\n");
  80.                         do_return(-1);
  81.                     }
  82.                     break;
  83.                 case 'c':
  84.                 case 'C':
  85.                     column = 1;
  86.                     break;
  87.                 case 'a':
  88.                 case 'A':
  89.                     mode = 0x2 + 0x4 + 0x10;
  90.                     break;
  91.                 case 'r':
  92.                 case 'R':
  93.                     recurse = 1;
  94.                     mode = 0x2 + 0x4 + 0x10;
  95.                     break;
  96.                 default:
  97.                     break;
  98.                 }
  99.             }
  100.             /* if we're down to one argument after looking at all the
  101.                switches, we need to set noargs to true */
  102.             if (noargs = (argc == 1))
  103.                 argc++;
  104.             continue;
  105.         }
  106.         /* if no wild cards, look for directory and drive names */
  107.         if ( NULL == index(current,'?') && NULL == index(current,'*'))
  108.         {
  109.             if (getfirst(current)->attribute & 0x10)
  110.             {
  111.                 strcpy(namebuf,current);
  112.                 strcat(namebuf,"\\*.*");
  113.                 current = namebuf;
  114.             } 
  115.             /* look for drive names */
  116.             else if (current[strlen(current)-1] == ':' && 
  117.                         !current[strlen(current)])
  118.             {
  119.                 strcpy(namebuf,current);
  120.                 strcat(namebuf,"\\*.*");
  121.                 current = namebuf;
  122.             }
  123.         }
  124.         do_dir(current);
  125.     }
  126.     do_return( 0);
  127. }
  128.  
  129. do_dir(current)
  130.     char *current;
  131. {
  132.     file_desc files[maxfiles];    /* as many as we'll likely need */
  133.     file_desc *curr_file,*getnext();
  134.     unsigned int ftime,date;
  135.     int i,j,col;
  136.     int files_cmp();
  137.     long total = 0;
  138.     char atts[4]; /* drw */
  139.     /* look for match */
  140.     i = 0;
  141.     if (!(curr_file = getfirst(current)))
  142.     {
  143.         printf(stderr,"ls : no files matching %s\n",current);
  144.         return;    
  145.     }
  146.     files[i++] = *curr_file;
  147.     /* get all matching */
  148.     while ((curr_file = getnext()) && i < maxfiles)
  149.         files[i++] = *curr_file;    
  150.     if (i > 1)
  151.         qsort(files,i,sizeof(file_desc),files_cmp);
  152.     if (!quiet)
  153.     {
  154.         write(1,"\r\n",2);
  155.         write(1,current,strlen(current));
  156.         write(1,"\r\n",2);
  157.     }
  158.     col = 1;
  159.     for (j = 0; j < i; j++)
  160.     {
  161.         register char *c = files[j].file_name;
  162.         if (*c == '.')
  163.             continue;    /* filter out . and .. */
  164.         while (*c)
  165.         {
  166.             *c = tolower(*c);
  167.             c++;
  168.         }
  169.         if (verbose)
  170.         {
  171.             register char att = files[j].attribute;
  172.             register int fyear;
  173.             fyear = ((files[j].file_date >> 9) & 0x7F)+80; 
  174.             atts[3] = 0;    /* terminate string */
  175.             atts[0] = att & 0x10 ? 'd' : '-';
  176.             atts[1] = att & 2 ? '-' : 'r';
  177.             atts[2] = att & 1 ? '-' : 'w';
  178.             if (atts[0] == 'd')
  179.             {
  180.                 register int k;
  181.                 sprintf(printbuf,"%s %s\\",atts,files[j].file_name);
  182.                 write(1,printbuf,strlen(printbuf));
  183.                 k = 12 - strlen(files[j].file_name)+7;
  184.                 while(k--)
  185.                     write(1," ",1);
  186.  
  187.             }
  188.             else
  189.             {
  190.                 total += files[j].file_size;
  191.                 sprintf(printbuf,"%s %-12s %-6ld ",atts,files[j].file_name,
  192.                         files[j].file_size);
  193.                 write(1,printbuf,strlen(printbuf));
  194.             }
  195.             ftime = files[j].file_time;
  196.             date = files[j].file_date;
  197.             if (year == fyear)
  198.             {
  199.                 sprintf(printbuf,"%02d/%02d %02d:%02d ",
  200.                     ((date >> 5) & 0x0F),    /* month */
  201.                     date & 0x1F,        /* day    */
  202.                     (ftime >> 11) & 0x1F,        /* hours */
  203.                     (ftime >> 5) & 0x3F);        /* minutes */
  204.                 write(1,printbuf,strlen(printbuf));
  205.             }
  206.             else
  207.             {
  208.                 sprintf(printbuf,"%02d/%02d       ",
  209.                     ((date >> 5) & 0x0F),    /* month */
  210.                     fyear,                    /* file year */
  211.                     (ftime >> 11) & 0x1F,        /* hours */
  212.                     (ftime >> 5) & 0x3F);        /* minutes */
  213.                 write(1,printbuf,strlen(printbuf));
  214.             }
  215.         }
  216.         else
  217.         {
  218.             if (files[j].attribute & 0x10)
  219.             {
  220.                 register int k;
  221.                 sprintf(printbuf,"%s\\",files[j].file_name);
  222.                 write(1,printbuf,strlen(printbuf));
  223.                 k = 16 - strlen(files[j].file_name);
  224.                 while(--k)
  225.                     write(1," ",1);
  226.  
  227.             }
  228.             else
  229.             {
  230.                 sprintf(printbuf,"%-13s   ",files[j].file_name);
  231.                 write(1,printbuf,strlen(printbuf));
  232.             }
  233.         }
  234.         if (col == column)
  235.         {
  236.             col = 1;
  237.             write(1,"\r\n",2);
  238.         }
  239.         else
  240.             col++;
  241.     }
  242.     write(1,"\r\n",2);
  243.     if (verbose)
  244.     {
  245.         sprintf(printbuf,"%ld bytes in %d files\r\n",total,i);
  246.         write(1,printbuf,strlen(printbuf));
  247.     }
  248.     if (recurse)
  249.         for (j = 0; j < i; j++)
  250.         {
  251.             /* we've got a subdirectory */
  252.             if (files[j].attribute & 0x10 && files[j].file_name[0] != '.')
  253.             {
  254.                 char *path;
  255.                 char dirname[48];
  256.                 if (!strcmp(current,"*.*"))
  257.                     dirname[0] = '\0';
  258.                 else
  259.                     strcpy(dirname,current);
  260.                 if (path = rindex(dirname,'\\'))
  261.                     *(++path) = '\0';
  262.                 strcat(dirname,files[j].file_name);    /* get name */
  263.                 strcat(dirname,"\\*.*");
  264.                 do_dir(dirname);
  265.             }
  266.         }
  267. }
  268.  
  269. files_cmp(a,b)
  270.     file_desc *a,*b;
  271. {
  272.     return strcmp(a->file_name,b->file_name);
  273. }
  274.  
  275. fcb tmp;
  276.  
  277. file_desc *getfirst(fname)
  278.     char *fname;
  279. {
  280.     register int result;
  281.     /* set the disk transfer address */
  282.     bdos(0x1A,&tmp);
  283.     result = bdos(0x4E,fname,mode);
  284.     /* make the find first call */
  285.     if(2 == result || 18 == result)
  286.         return NULL;
  287.     return &(tmp.file);
  288. }
  289.  
  290. file_desc *getnext()
  291. {
  292.     register int result;
  293.     /* set the disk transfer address */
  294.     bdos(0x1A,&tmp);
  295.     result = bdos(0x4f,0,0);
  296.     /* make the find next call */
  297.     if (18 == result)
  298.         return NULL;
  299.     return &(tmp.file);
  300. }
  301.