home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 183_01 / chmod.c < prev    next >
Text File  |  1984-01-28  |  9KB  |  232 lines

  1.  
  2.  /***********************************************************************/
  3.  /* chmod - exercise CHMOD DOS function call (#43)                      */
  4.  /***********************************************************************/
  5.  /* (c) copyright Jerry M. Carlin 8/14/1983                             */
  6.  /* permission given to use or distribute so long as no money charged.  */
  7.  /* If questions, call 415-680-7590.                                    */
  8.  /***********************************************************************/
  9.  
  10.  /*#define DEBUG 1*/
  11.  
  12. #include "stdio.h"
  13.  
  14. #define CARRY  1        /* 8086 flags carry bit */
  15. #define FCALL  0x21     /* function call int per DOS 2.0 manual pg D-2 */
  16.  
  17. #define CHMOD  0x43     /* DOS 2.0 Change File Mode pg D-39 */
  18. #define SETDTA 0x1A     /* Set Disk Transfer Address pg D-26 */
  19. #define FFIRST 0x4E     /* DOS 2.0 Find First File pg D-49 */
  20. #define FNEXT  0x4F     /* DOS 2.0 Find Next File pg D-50 */
  21.  
  22.  /* file attributes from DOS 2.0 manual page C-4 */
  23.  
  24. #define RO     01       /* read only */
  25. #define HIDE   02       /* hidden file */
  26. #define SYS    04       /* system file */
  27. #define VOLLBL 08       /* special volume label - in first 11 bytes */
  28. #define SUBDIR 0x10     /* defines a subdirectory */
  29. #define ARCHV  0x20     /* archive bit */
  30.  
  31. char *index();
  32.  
  33. struct regval {
  34.         unsigned ax,bx,cx,dx,si,di,ds,es;
  35. } iregs, oregs, fileregs;
  36.  
  37. struct segreg {
  38.         unsigned cs,ss,sds,ses;
  39. } sr;
  40.  
  41. main(ac,av)
  42. int ac;
  43. char *av[];
  44. {
  45.         char attr[9];           /* file attributes */
  46.         int flags;              /* 8086 flag register */
  47.         char buff[128];         /* disk I/O buffer */
  48.         char fullname[128];     /* full file name including drive and dir */
  49.         char ddprefix[120];     /* drive and directory info */
  50.         int i;
  51.  
  52.         bdos(SETDTA,buff);      /* Set Data Transfer Address */
  53.         iregs.ax = 17152;       /* set ah = 43 */
  54.         segread(&sr);           /* get stack & data seg regs */
  55.         iregs.ds = sr.sds;
  56.         iregs.es = sr.ses;
  57.         fileregs.ds = iregs.ds;
  58.         fileregs.es = iregs.es;
  59.         fileregs.ax = 0x4E00;                   /* find first */
  60.         fileregs.cx = HIDE | SYS | SUBDIR;      /* allow any file */
  61.  
  62.         if (strcmp(av[1],"help") == 0 || strcmp(av[1],"?") == 0 || ac == 1)
  63.         {
  64.                 printf("\nchmod [-[r][h][s][a]] filename.ext ");
  65.                 printf("[filename.ext...]\n");
  66.                 printf("\nUse the '-' option to set file modes. Omit");
  67.                 printf(" the '-' option for mode display.\nA dash by ");
  68.                 printf(" itself (chmod - filename) sets normal mode.\n\n");
  69.                 printf("Settable flags:\n  r = read only\n");
  70.                 printf("  h = hidden\n  s = system");
  71.                 printf("\n  a = archive\n\nAny flag not set will be reset.");
  72.                 printf(" This means that if you do not, \nfor example, set");
  73.                 printf(" read-only the file will be write enabled.\n\n");
  74.                 printf("DOS global filename chars '*' and '?' may be used.\n");
  75.                 printf("\nMode display includes 'w' for write ok and ");
  76.                 printf("'d' for a subdirectory.\n\n");
  77.                 exit(0);
  78.         }
  79.         if (av[1][0] == '-')    /* set mode */
  80.         {
  81.                 iregs.ax |= 1;  /* set update bit */
  82.                 iregs.cx = 0;
  83.                 if (index(av[1],'r') != 0 || index(av[1],'R') != 0)
  84.                         iregs.cx |= RO;
  85.                 if (index(av[1],'h') != 0 || index(av[1],'H') != 0)
  86.                         iregs.cx |= HIDE;
  87.                 if (index(av[1],'s') != 0 || index(av[1],'S') != 0)
  88.                         iregs.cx |= SYS;
  89.                 if (index(av[1],'a') != 0 || index(av[1],'A') != 0)
  90.                         iregs.cx |= ARCHV;
  91. #ifdef DEBUG
  92.                 printf("fun code =%x\n",iregs.ax);
  93.                 printf("set mode =%x\n",iregs.cx);
  94. #endif
  95.                 ++av;   /* skip over set mode word */
  96.                 --ac;
  97.                 while (--ac > 0)
  98.                 {
  99.                         fileregs.dx = *++av;
  100.                         flags = sysint(FCALL,&fileregs,&oregs);
  101.                         if (oregs.ax)
  102.                         {
  103.                                 perror(fileregs.dx,oregs.ax);
  104.                                 continue;
  105.                         }
  106.                         buildp(*av,ddprefix);
  107.                         while (oregs.ax == 0)
  108.                         {
  109.                                 strcpy(fullname,ddprefix);
  110.                                 strcat(fullname,buff+30);
  111.                                 iregs.dx = fullname;
  112.                                 flags = sysint(FCALL,&iregs,&oregs);
  113.                                 if (flags & CARRY)
  114.                                         perror(iregs.dx,oregs.ax);
  115.                                 oregs.ax = bdos(FNEXT,0) & 0xff;
  116.                         }
  117.                 }
  118.                 exit(0);
  119.         }
  120.  
  121.  /**********************************/
  122.  /* else report on current setting */
  123.  /**********************************/
  124.  
  125.         while (--ac > 0)
  126.         {
  127.                 fileregs.dx = *++av;
  128.                 flags = sysint(FCALL,&fileregs,&oregs);   /* Find First */
  129.                 if (oregs.ax)
  130.                 {
  131.                         perror(fileregs.dx,oregs.ax);
  132.                         continue;
  133.                 }
  134.                 i = 0;
  135.                 buildp(*av,ddprefix);
  136.                 while (i == 0)
  137.                 {
  138.                         strcpy(fullname,ddprefix);
  139.                         strcat(fullname,buff+30);       /* see pg D-49 */
  140.                         iregs.dx = fullname;            /* next file */
  141.                         flags = sysint(FCALL,&iregs,&oregs);
  142. #ifdef DEBUG
  143.                         printf("file     = %s\n",iregs.dx);
  144.                         printf("err code = %x\n",oregs.ax);
  145.                         printf("8086flags= %x\n",flags);
  146.                         printf("mode byte= %d\n",oregs.cx);
  147. #endif
  148.                         if (flags & CARRY)
  149.                         {
  150.                                 perror(iregs.dx,oregs.ax);
  151.                                 break;
  152.                         }
  153.                         if (oregs.cx & RO)
  154.                                 attr[0] = 'r';
  155.                         else
  156.                                 attr[0] = 'w';
  157.                         if (oregs.cx & HIDE)
  158.                                 attr[1] = 'h';
  159.                         else
  160.                                 attr[1] = '-';
  161.                         if (oregs.cx & SYS)
  162.                                 attr[2] = 's';
  163.                         else
  164.                                 attr[2] = '-';
  165.                         if (oregs.cx & SUBDIR)
  166.                                 attr[3] = 'd';
  167.                         else
  168.                                 attr[3] = '-';
  169.                         if (oregs.cx & ARCHV)
  170.                                 attr[4] = 'a';
  171.                         else
  172.                                 attr[4] = '-';
  173.                         attr[5] = '\0';
  174.                         printf("%s %s\n",attr,iregs.dx);
  175.                         i = bdos(FNEXT,0) & 0xff;  /* Find Next */
  176.                 }
  177.         }
  178.         exit(0);
  179. }
  180.  
  181.  /*****************************************************************/
  182.  /* print error - see error return table DOS 2.0 Manual page D-14 */
  183.  /*****************************************************************/
  184.  
  185. perror(s,code)
  186. char *s;
  187. unsigned code;
  188. {
  189.         printf("chmod: File %s",s);
  190.         switch(code) {
  191.         case 2:
  192.         case 18: /* perror called with 18 if bad filename entered */
  193.                 printf(" not found.\n");
  194.                 break;
  195.         case 3:
  196.                 printf(". Path not found.\n");
  197.                 break;
  198.         case 5:
  199.                 printf(". Access denied.\n");
  200.                 break;
  201.         default:
  202.                 printf(". DOS error code %u returned.\n",code);
  203.         }
  204.         return;
  205. }
  206.  
  207.  /********************************************************/
  208.  /* build prefix str containing drive and directory info */
  209.  /* needed since FFIRST DTA does not store this info     */
  210.  /********************************************************/
  211.  
  212. buildp(fullname,ddprefix)
  213. char *fullname; /* full path name (input) */
  214. char *ddprefix; /* drive and directory info */
  215. {
  216. #ifdef DEBUG
  217.         char *savep;
  218.         savep = ddprefix;
  219. #endif
  220.         while ((index(fullname,':') != 0) || (index(fullname,'\\') != 0))
  221.                 *ddprefix++ = *fullname++;
  222.         *ddprefix = '\0';
  223. #ifdef DEBUG
  224.         printf("Prefix=%s\n",savep);
  225. #endif
  226. }
  227. 
  228.  
  229. fix++ = *fullname++;
  230.         *ddprefix = '\0';
  231. #ifdef DEBUG
  232.         pri