home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Source Code / Visual Basic Source Code.iso / vbsource / cenvid / dir.cmm < prev    next >
Encoding:
Text File  |  1995-10-11  |  9.9 KB  |  391 lines

  1. /*
  2.  * dir.cmm
  3.  *
  4.  * This .CMM file implements a DOS-like DIR command.
  5.  */
  6.  
  7. #include "Netware.lib"
  8.  
  9. usage()
  10. {
  11.   printf("Use the DIR command to list the files and subdirectories.\n");
  12.   printf("Syntax:\n");
  13.   printf("  DIR [drive:][path][filename][/W or /F][/P][/A][/B][/O][/R][/S][/L]\n");
  14.   printf("where:\n");
  15.   printf("  drive:/path/filename   Specifies directories and files to list.\n");
  16.   printf("  /W                     Displays directory listing horizontally.\n");
  17.   printf("  /F                     Displays fully-qualified file names.\n");
  18.   printf("  /P                     Pauses after each screen of information.\n");
  19.   printf("  /A                     Displays specified attributes.\n");
  20.   printf("  /B                     Displays file name and extension.\n");
  21.   printf("  /O                     Orders the display by specified fields.\n");
  22.   printf("  /S                     Displays all subdirectories.\n");
  23.   printf("  /L                     Displays directory info in lower-case.\n");
  24.   exit(EXIT_FAILURE);
  25. }
  26.  
  27. /* ---------------------------------------------------------------------- */
  28.  
  29.  
  30. height = ScreenSize().row;
  31. width = ScreenSize().col;
  32.  
  33. attributes = 0x3f & ~( _A_HIDDEN | _A_SYSTEM );
  34. must = 0;
  35. ltr = "RHSEDA";
  36. wide = FALSE;
  37. pause = FALSE;
  38. fully = FALSE;
  39. bare = FALSE;
  40. lower = FALSE;
  41. recursive = FALSE;
  42. dir[0] = "";
  43. it = 1;
  44.  
  45. dirfirst = 0;   // 1 = true, -1 = last
  46. sortflag = ' ';
  47. sortminus = 0;
  48.  
  49. /* ---------------------------------------------------------------------- */
  50.  
  51. //
  52. // We set the attributes we are looking for based on the given string
  53. // which lists attribute bits.
  54. //
  55. set_attributes(a)
  56. {
  57. // The user will specify the attributes.
  58.   for( i=0;i<strlen(a);i++ )
  59.     {
  60.       if( (j = strchr(ltr,toupper(a[i])))==NULL )
  61.     {
  62.       printf("Illegal attribute %c\n",a[i]);
  63.       exit(EXIT_FAILURE);
  64.     }
  65.       attributes |= (1<<(j-ltr));
  66.       must |= (1<<(j-ltr));
  67.     }
  68. }
  69.  
  70. //
  71. // Examine and save the sort field.
  72. //
  73. set_sort(aa)
  74. {
  75.   dirfirst = 0;
  76.   sortflag = 'N';
  77.   sortminus = 1;
  78.  
  79.   a = strupr(aa);
  80.  
  81.   while( a[0] )
  82.     {
  83.       minus = 0;
  84.       if( a[0]=='-' )
  85.         {
  86.           minus = 1;
  87.           a++;
  88.         }
  89.       if( a[0]=='G' )
  90.         {
  91.           dirfirst = minus?-1:1;
  92.         } else {
  93.           if( strchr("NEDS",a[0])==NULL )
  94.             {
  95.               printf("Sort by [N]ame, [E]xtension, [D]ate, or [S]ize only.\n");
  96.               exit(EXIT_FAILURE);
  97.             }
  98.           sortminus = minus?-1:1;
  99.           sortflag = a[0];
  100.         }
  101.       a++;
  102.     }
  103. }
  104.  
  105. /* ---------------------------------------------------------------------- */
  106.  
  107. parse_command_line(argc,argv)
  108. {
  109.   for( i=1;i<argc;i++ )
  110.     {
  111.       if( argv[i][0]=='-' || argv[i][0]=='/' )
  112.     {
  113.       switch( toupper(argv[i][1]) )
  114.         {
  115.         default: usage();
  116.         case 'W':
  117.           if( fully )
  118.         {
  119.           fully = FALSE;
  120.           printf("WARNING: /f param previously encountered overriden.\n");
  121.         }
  122.           wide = TRUE; break;
  123.         case 'F':
  124.           if( wide )
  125.         {
  126.           wide = FALSE;
  127.           printf("WARNING: /w param previously encountered overriden.\n");
  128.         }
  129.           fully = TRUE; break;
  130.         case 'P': pause = TRUE; break;
  131.         case 'B': bare = TRUE; break;
  132.         case 'A': set_attributes(argv[i]+2); break;
  133.         case 'O': set_sort(argv[i]+2); break;
  134.         case 'L': lower = TRUE; break;
  135.         case 'S': recursive = TRUE; break;
  136.         }
  137.     } else {
  138.           if( it )
  139.             {
  140.               dir[0] = argv[i]; it = 0;
  141.             } else {
  142.               dir[GetArraySpan(dir)+1] = argv[i];
  143.             }
  144.     }
  145.     }
  146.   if( bare && wide ) bare = FALSE;
  147. }
  148.  
  149. /* ---------------------------------------------------------------------- */
  150.  
  151. compare_directory(elem1,elem2)
  152. {
  153.   if( dirfirst )
  154.     {
  155.       if( dirfirst && (elem1.attrib & _A_SUBDIR)!=(elem2.attrib & _A_SUBDIR) )
  156.         {
  157.           return dirfirst * ((elem1.attrib&_A_SUBDIR)?-1:1);
  158.         }
  159.     }
  160.  
  161.   if( sortflag==' ' ) return 0;
  162.   switch( sortflag )
  163.     {
  164.     default:
  165.       printf("Internal error - illegal sorting character.\n"); exit(EXIT_FAILURE);
  166.     case 'N': return sortminus * stricmp(elem1.name,elem2.name);
  167.     case 'E': return sortminus *
  168.       stricmp(SplitFileName(elem1.name).ext,SplitFileName(elem2.name).ext);
  169.     case 'D':
  170.       ret = 0;
  171.       if( elem1.Write>elem2.Write ) ret = -1;
  172.       if( elem1.Write<elem2.Write ) ret = 1;
  173.       return sortminus * ret;
  174.     case 'S':
  175.       ret = 0;
  176.       if( elem1.size>elem2.size ) ret = -1;
  177.       if( elem1.size<elem2.size ) ret = 1;
  178.       return sortminus * ret;
  179.     }
  180. }
  181.  
  182. sort_directory(dirarray)
  183. {
  184.   if( dirarray && (dirfirst || sortflag!=' ') )
  185.     {
  186.       qsort(dirarray,"compare_directory");
  187.     }
  188. }
  189.  
  190. /* ---------------------------------------------------------------------- */
  191.  
  192. //
  193. // Stringize the number, inserting appropriate commas.
  194. //
  195. comma(value)
  196. {
  197.    tmp = ""; SetArraySpan(tmp,32);
  198.    sprintf( tmp, "%d", value );
  199.  
  200.    j = strlen( tmp );
  201.    len = i = j + j / 3;
  202.  
  203.    ret[ i ] = '\0';
  204.    for( ; j >= 0; i--, j-- )
  205.      {
  206.        if( (len-i) % 4 == 0 && i > 0 && i != len )
  207.      ret[ i-- ] = ',';
  208.  
  209.        ret[ i ] = tmp[ j ];
  210.      }
  211.    return( ret+i+1 );
  212. }
  213.  
  214. get_directory(whatdir,files,bytes)
  215. {
  216.   files = 0; bytes = 0;
  217.   lines = 0; column =0;
  218.  
  219.   dirarray = Directory(whatdir,FALSE,attributes,must);
  220.   sort_directory(dirarray);
  221.  
  222.   if( dirarray!=NULL && !fully && !bare )
  223.     {
  224.       printf("\nDirectory of %s\n\n",whatdir); lines += 3;
  225.     }
  226.  
  227.   for( i=0;dirarray!=NULL && i<=GetArraySpan(dirarray);i++ )
  228.       {
  229.     if( !(dirarray[i].attrib&_A_SUBDIR) )
  230.       {
  231.         bytes += dirarray[i].size;
  232.         files ++;
  233.       }
  234.  
  235.         filestruct = SplitFileName(dirarray[i].name);
  236.     sprintf(filename,"%s%s",filestruct.name,filestruct.ext);
  237.     if( lower ) strlwr(filename);
  238.     if( lower ) strlwr(dirarray[i].name);
  239.  
  240. // Bare takes precedence over fully
  241.     if( bare )
  242.       {
  243.         printf("%s\n",filename);
  244.         goto scroll;
  245.       }
  246.  
  247.     if( fully )
  248.       {
  249.         printf("%s\n",dirarray[i].name);
  250.         goto scroll;
  251.       }
  252.  
  253.     if( wide )
  254.       {
  255.         column+=16;
  256.         if( column>width )
  257.           {
  258. // if the column exactly matches, we are already on the next line
  259.         if( column-16>width ) printf("\n");
  260.         lines++; column = 16;
  261.           }
  262.  
  263.         if( dirarray[i].attrib&_A_SUBDIR )
  264.           {
  265.         sprintf(filename,"[%s%s]",filestruct.name,filestruct.ext);
  266.         if( lower ) strlwr(filename);
  267.           }
  268.         printf("%-16s",filename);
  269.         goto maybe_pause;
  270.       }
  271.     printf("%-20s ",filename);
  272.  
  273.     ltr = "RHSEDA";
  274.  
  275.     sprintf(datetime,"%s",ctime(dirarray[i].Write));
  276. // strip the annoying newline.
  277.     datetime[strlen(datetime)-1] = '\0';
  278.  
  279.     for( j=0;j<6;j++ )
  280.       attribs[j] = (dirarray[i].attrib & (1<<j))? ltr[j] : ' ';
  281.  
  282.         if( defined(_NWNLM_) )
  283.           {
  284.             owner = ""; SetArraySpan(owner,256);
  285.             undefine(junk);
  286.             if( NLMLink("GetBinderyObjectName", dirarray[i].uid, owner, junk ) )
  287.               strcpy( owner, "FALSE owner.");
  288.           }
  289.  
  290.     if( dirarray[i].attrib & _A_SUBDIR )
  291.       {
  292.             if( defined(_NWNLM_) )
  293.               {
  294.                 printf("  <DIR> [%s ] %s  %s",attribs,datetime,owner);
  295.               } else {
  296.                 printf("  <DIR> [%s] %s",attribs,datetime);
  297.               }
  298.       } else {
  299.             if( defined(_NWNLM_) )
  300.               {
  301.                 printf("%7d [%s%c] %s  %s",dirarray[i].size,
  302.                        attribs,(dirarray[i].attrib & _A_TRANS)?'T':'_',
  303.                        datetime,owner);
  304.               } else {
  305.                 printf("%7d [%s] %s",dirarray[i].size,attribs,datetime);
  306.               }
  307.       }
  308.     printf("\n");
  309.  
  310.       scroll:
  311.     ++lines;
  312.       maybe_pause:
  313.     if( pause && lines>=height-1 )
  314.       {
  315.             if( defined(_NWNLM_) )
  316.               {
  317.                 if( NLMLink("PressEscapeToQuit") ) break;
  318.               } else {
  319.                 printf("Press escape to quit or any other key to continue...");
  320.                 fflush(stdout);
  321.                 if( getch()=='\x1b' ) break;
  322.                 printf("\r                                                    \r");
  323.                 fflush(stdout);
  324.               }
  325.         lines = 0;
  326.       }
  327.       }
  328.  
  329.    if( wide ) printf("\n");
  330.  
  331.    if( !bare && !fully && files )
  332.      {
  333.       printf("\n        %s byte%s in %d file%s\n",
  334.          comma(bytes),(bytes==1)?"":"s",files,(files==1)?"":"s");
  335.      }
  336.    if( recursive )
  337.      {
  338.        namestruct = SplitFileName(whatdir);
  339.        sprintf(newdir,"%s*.*",namestruct.dir);
  340.        dirarray = Directory(newdir,FALSE,0x3f);
  341.  
  342.        for( i=0;dirarray!=NULL && i<=GetArraySpan(dirarray);i++ )
  343.      {
  344.        if( dirarray[i].attrib&_A_SUBDIR )
  345.          {
  346.                sprintf(newdir,"%s%c%s%s",
  347.                        newdir = dirarray[i].name,
  348.                        strchr(namestruct.dir,'/')?'/':'\\',
  349.                        namestruct.name,namestruct.ext);
  350.            get_directory(newdir,files2,bytes2);
  351.            bytes += bytes2;
  352.            files += files2;
  353.          }
  354.      }
  355.      }
  356. }
  357.  
  358. main(argc,argv)
  359. {
  360. // First thing to do is parse the command line.
  361.  
  362.   parse_command_line(argc,argv);
  363.  
  364.   files = 0; bytes = 0;
  365.  
  366.   for( i=0;i<=GetArraySpan(dir);i++ )
  367.     {
  368.       files = Directory(dir[i]);
  369.       if( files && GetarraySpan(files)==0 && (files[0].attrib & _A_SUBDIR) )
  370.         strcat(dir[i],defined(_NWNLM_)?"/":"\\");
  371.  
  372.       s = strlen(dir[i]);
  373.       if( s && dir[i][s-1]==':' )
  374.         {
  375.           strcat(dir[i],defined(_NWNLM_)?"/":"\\"); s++;
  376.         }
  377.       if( s && (dir[i][s-1]=='/' || dir[i][s-1]=='\\') ) strcat(dir[i],"*.*");
  378.       if( s==0 ) dir[i] = "*.*";
  379.  
  380.       strcpy(full_path,dir[i]);
  381.  
  382.       files1 = 0; bytes1 = 0;
  383.       get_directory(full_path,files1,bytes1);
  384.       files += files1; bytes += bytes1;
  385.     }
  386.  
  387.    if( (GetArraySpan(dir)>0 || recursive) && !bare && !fully && files > 0 )
  388.       printf("\nTotal files listed:\n        %s byte%s in %d file%s\n",
  389.          comma(bytes),(bytes==1)?"":"s",files,(files==1)?"":"s");
  390. }
  391.