home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / snip9707.zip / CHMOD.C < prev    next >
C/C++ Source or Header  |  1997-07-05  |  6KB  |  228 lines

  1. /* +++Date last modified: 05-Jul-1997 */
  2.  
  3. /*
  4. **  CHMOD.C - Retrieve or change a DOS file's attributes
  5. **
  6. **  public domain demo by Bob Stout
  7. **
  8. **  Notes: To expand command line arguments with wildcards,
  9. **         TC/TC++/BC++  - Link in WILDARGS.OBJ.
  10. **         MSC/QC        - Link in SETARGV.OBJ.
  11. **         ZTC/C++       - Link in _MAINx.OBJ, where 'x' is the memory model.
  12. **
  13. **         Allows file list(s) using standard "@file_list_name" convention.
  14. */
  15.  
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <dos.h>
  19. #include <ctype.h>
  20. #include <string.h>
  21.  
  22. #define LAST_CHAR(s) (s)[strlen(s)-1]
  23.  
  24. #if defined(__TURBOC__)
  25.  #include <io.h>
  26.  #define FAR far
  27. #else
  28.  #include <stdarg.h>
  29.  
  30.  #define TOBOOL(x) (!(!(x)))
  31.  #define FAR _far
  32.  
  33.  #if (defined(_MSC_VER) && (_MSC_VER >= 700)) || (defined(__SC__))
  34.   /* Make FP_xxx macros lvalues as in older versions */
  35.   #undef FP_SEG
  36.   #undef FP_OFF
  37.   #define FP_SEG(fp)    ((unsigned)((unsigned long)(fp) >> 16))
  38.   #define FP_OFF(fp)    ((unsigned)(fp && 0xffff))
  39.  #endif
  40.  
  41.  int _chmod(const char *path, int func, ...)
  42.  {
  43.        union REGS regs;
  44.        struct SREGS sregs;
  45.        int atr = 0;
  46.        va_list args;
  47.  
  48.        if (0 != (func = TOBOOL(func)))
  49.        {
  50.             va_start(args, func);
  51.             atr = va_arg(args, int);
  52.        }
  53.        regs.x.ax = 0x4300 + func;
  54.        regs.x.dx = FP_OFF((char FAR *)path);
  55.        regs.x.cx = atr;
  56.        segread(&sregs);
  57.        sregs.ds  = FP_SEG((char FAR *)path);
  58.        intdosx(®s, ®s, &sregs);
  59.        if (regs.x.cflag)
  60.             return -1;
  61.        if (func)
  62.             return atr;
  63.        else return regs.x.cx;
  64.  }
  65.  
  66.  #ifndef FA_RDONLY
  67.   #define FA_RDONLY _A_RDONLY
  68.  #endif
  69.  
  70.  #ifndef FA_HIDDEN
  71.   #define FA_HIDDEN _A_HIDDEN
  72.  #endif
  73.  
  74.  #ifndef FA_SYSTEM
  75.   #define FA_SYSTEM _A_SYSTEM
  76.  #endif
  77.  
  78.  #ifndef FA_ARCH
  79.   #define FA_ARCH   _A_ARCH
  80.  #endif
  81.  
  82.  #ifndef FA_LABEL
  83.   #define FA_LABEL  _A_VOLID
  84.  #endif
  85.  
  86.  #ifndef FA_DIREC
  87.   #define FA_DIREC  _A_SUBDIR
  88.  #endif
  89. #endif
  90.  
  91. int attrib,                   /* Set up new attributes here             */
  92.     atr_setmask = 0,
  93.     atr_clrmask = -1,
  94.     flag = 0;                 /* Passed as func to _chmod()             */
  95.  
  96. void usage(void)              /* Tell 'em they messed up                */
  97. {
  98.       puts("Usage: CHMOD file [file [...file] [+switches] [-switches]");
  99.       puts("Where switches are one or more of:");
  100.       puts("    A: Archive");
  101.       puts("    R: Read only");
  102.       puts("    H: Hidden");
  103.       puts("    S: System");
  104.       puts("File lists may be specified with \"@file_list_name\"");
  105.       puts("With no switches, diplays current attributes.");
  106.       puts("Displayed attributes are as above plus:");
  107.       puts("    D: Subdirectory");
  108.       puts("    V: Volume label");
  109.       exit(1);
  110. }
  111.  
  112. void setattr(char atr)        /* Set bits in attribute                  */
  113. {
  114.       switch (toupper(atr))
  115.       {
  116.       case 'A':
  117.             atr_setmask |= FA_ARCH;
  118.             break;
  119.       case 'R':
  120.             atr_setmask |= FA_RDONLY;
  121.             break;
  122.       case 'S':
  123.             atr_setmask |= FA_SYSTEM;
  124.             break;
  125.       case 'H':
  126.             atr_setmask |= FA_HIDDEN;
  127.             break;
  128.       default:
  129.             usage();
  130.       }
  131. }
  132.  
  133. void clrattr(char atr)        /* Clear bits in attribute                */
  134. {
  135.       switch (toupper(atr))
  136.       {
  137.       case 'A':
  138.             atr_clrmask &= ~FA_ARCH;
  139.             break;
  140.       case 'R':
  141.             atr_clrmask &= ~FA_RDONLY;
  142.             break;
  143.       case 'S':
  144.             atr_clrmask &= ~FA_SYSTEM;
  145.             break;
  146.       case 'H':
  147.             atr_clrmask &= ~FA_HIDDEN;
  148.             break;
  149.       default:
  150.             usage();
  151.       }
  152. }
  153.  
  154. void show_atr(char *path)
  155. {
  156.       char astr[7], *ptr;
  157.  
  158.       if (-1 == (attrib = _chmod(strupr(path), 0)))
  159.       {
  160. ATR_ERR:    printf("\aCHMOD: Error! (file: %s)", path);
  161.             exit(-1);
  162.       }
  163.       attrib |= atr_setmask;
  164.       attrib &= atr_clrmask;
  165.       if (-1 == (attrib = _chmod(path, flag, attrib)))
  166.             goto ATR_ERR;
  167.       ptr = astr;
  168.       *ptr++ = (char)((attrib & FA_ARCH)   ? 'A' : '.');
  169.       *ptr++ = (char)((attrib & FA_RDONLY) ? 'R' : '.');
  170.       *ptr++ = (char)((attrib & FA_SYSTEM) ? 'S' : '.');
  171.       *ptr++ = (char)((attrib & FA_HIDDEN) ? 'H' : '.');
  172.       *ptr++ = (char)((attrib & FA_DIREC)  ? 'D' : '.');
  173.       *ptr++ = (char)((attrib & FA_LABEL)  ? 'V' : '.');
  174.       *ptr = '\0';
  175.       printf("%-15s %s\n", path, astr);
  176. }
  177.  
  178. int main (int argc, char *argv[])
  179. {
  180.       int i, j;
  181.  
  182.       if (2 > argc)
  183.             usage();
  184.       for (i = 1; i < argc; ++i)    /* Build attribute masks            */
  185.       {
  186.             switch (*argv[i])
  187.             {
  188.             case '+':
  189.                   for (j = 1; argv[i][j]; ++j)
  190.                         setattr(argv[i][j]);
  191.                   flag = 1;
  192.                   break;
  193.             case '-':
  194.                   for (j = 1; argv[i][j]; ++j)
  195.                         clrattr(argv[i][j]);
  196.                   flag = 1;
  197.                   break;
  198.             default:
  199.                   break;            /* Assume it's a file name          */
  200.             }
  201.       }
  202.       for (i = 1; i < argc; ++i)    /* Scan filenames                   */
  203.       {
  204.             if (strchr("+-", *argv[i]))
  205.                   continue;
  206.             if ('@' == *argv[i])
  207.             {
  208.                   FILE *fp;
  209.                   char buf[256], *ptr = &argv[i][1];
  210.  
  211.                   if (NULL == (fp = fopen(ptr, "r")))
  212.                   {
  213.                         printf("\aCHMOD: Error opening %s\n", ptr);
  214.                         return -1;
  215.                   }
  216.                   while (NULL != fgets(buf, 255, fp))
  217.                   {
  218.                         while ('\n' == LAST_CHAR(buf))     /* Strip '\n'*/
  219.                               LAST_CHAR(buf) = '\0';
  220.                         show_atr(buf);
  221.                   }
  222.                   fclose(fp);
  223.             }
  224.             else  show_atr(argv[i]);
  225.       }
  226.       return 0;
  227. }
  228.