home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cenvi23.zip / DIR.CMM < prev    next >
Text File  |  1996-02-12  |  12KB  |  422 lines

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