home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource3
/
183_01
/
chmod.c
< prev
next >
Wrap
Text File
|
1984-01-28
|
9KB
|
232 lines
/***********************************************************************/
/* chmod - exercise CHMOD DOS function call (#43) */
/***********************************************************************/
/* (c) copyright Jerry M. Carlin 8/14/1983 */
/* permission given to use or distribute so long as no money charged. */
/* If questions, call 415-680-7590. */
/***********************************************************************/
/*#define DEBUG 1*/
#include "stdio.h"
#define CARRY 1 /* 8086 flags carry bit */
#define FCALL 0x21 /* function call int per DOS 2.0 manual pg D-2 */
#define CHMOD 0x43 /* DOS 2.0 Change File Mode pg D-39 */
#define SETDTA 0x1A /* Set Disk Transfer Address pg D-26 */
#define FFIRST 0x4E /* DOS 2.0 Find First File pg D-49 */
#define FNEXT 0x4F /* DOS 2.0 Find Next File pg D-50 */
/* file attributes from DOS 2.0 manual page C-4 */
#define RO 01 /* read only */
#define HIDE 02 /* hidden file */
#define SYS 04 /* system file */
#define VOLLBL 08 /* special volume label - in first 11 bytes */
#define SUBDIR 0x10 /* defines a subdirectory */
#define ARCHV 0x20 /* archive bit */
char *index();
struct regval {
unsigned ax,bx,cx,dx,si,di,ds,es;
} iregs, oregs, fileregs;
struct segreg {
unsigned cs,ss,sds,ses;
} sr;
main(ac,av)
int ac;
char *av[];
{
char attr[9]; /* file attributes */
int flags; /* 8086 flag register */
char buff[128]; /* disk I/O buffer */
char fullname[128]; /* full file name including drive and dir */
char ddprefix[120]; /* drive and directory info */
int i;
bdos(SETDTA,buff); /* Set Data Transfer Address */
iregs.ax = 17152; /* set ah = 43 */
segread(&sr); /* get stack & data seg regs */
iregs.ds = sr.sds;
iregs.es = sr.ses;
fileregs.ds = iregs.ds;
fileregs.es = iregs.es;
fileregs.ax = 0x4E00; /* find first */
fileregs.cx = HIDE | SYS | SUBDIR; /* allow any file */
if (strcmp(av[1],"help") == 0 || strcmp(av[1],"?") == 0 || ac == 1)
{
printf("\nchmod [-[r][h][s][a]] filename.ext ");
printf("[filename.ext...]\n");
printf("\nUse the '-' option to set file modes. Omit");
printf(" the '-' option for mode display.\nA dash by ");
printf(" itself (chmod - filename) sets normal mode.\n\n");
printf("Settable flags:\n r = read only\n");
printf(" h = hidden\n s = system");
printf("\n a = archive\n\nAny flag not set will be reset.");
printf(" This means that if you do not, \nfor example, set");
printf(" read-only the file will be write enabled.\n\n");
printf("DOS global filename chars '*' and '?' may be used.\n");
printf("\nMode display includes 'w' for write ok and ");
printf("'d' for a subdirectory.\n\n");
exit(0);
}
if (av[1][0] == '-') /* set mode */
{
iregs.ax |= 1; /* set update bit */
iregs.cx = 0;
if (index(av[1],'r') != 0 || index(av[1],'R') != 0)
iregs.cx |= RO;
if (index(av[1],'h') != 0 || index(av[1],'H') != 0)
iregs.cx |= HIDE;
if (index(av[1],'s') != 0 || index(av[1],'S') != 0)
iregs.cx |= SYS;
if (index(av[1],'a') != 0 || index(av[1],'A') != 0)
iregs.cx |= ARCHV;
#ifdef DEBUG
printf("fun code =%x\n",iregs.ax);
printf("set mode =%x\n",iregs.cx);
#endif
++av; /* skip over set mode word */
--ac;
while (--ac > 0)
{
fileregs.dx = *++av;
flags = sysint(FCALL,&fileregs,&oregs);
if (oregs.ax)
{
perror(fileregs.dx,oregs.ax);
continue;
}
buildp(*av,ddprefix);
while (oregs.ax == 0)
{
strcpy(fullname,ddprefix);
strcat(fullname,buff+30);
iregs.dx = fullname;
flags = sysint(FCALL,&iregs,&oregs);
if (flags & CARRY)
perror(iregs.dx,oregs.ax);
oregs.ax = bdos(FNEXT,0) & 0xff;
}
}
exit(0);
}
/**********************************/
/* else report on current setting */
/**********************************/
while (--ac > 0)
{
fileregs.dx = *++av;
flags = sysint(FCALL,&fileregs,&oregs); /* Find First */
if (oregs.ax)
{
perror(fileregs.dx,oregs.ax);
continue;
}
i = 0;
buildp(*av,ddprefix);
while (i == 0)
{
strcpy(fullname,ddprefix);
strcat(fullname,buff+30); /* see pg D-49 */
iregs.dx = fullname; /* next file */
flags = sysint(FCALL,&iregs,&oregs);
#ifdef DEBUG
printf("file = %s\n",iregs.dx);
printf("err code = %x\n",oregs.ax);
printf("8086flags= %x\n",flags);
printf("mode byte= %d\n",oregs.cx);
#endif
if (flags & CARRY)
{
perror(iregs.dx,oregs.ax);
break;
}
if (oregs.cx & RO)
attr[0] = 'r';
else
attr[0] = 'w';
if (oregs.cx & HIDE)
attr[1] = 'h';
else
attr[1] = '-';
if (oregs.cx & SYS)
attr[2] = 's';
else
attr[2] = '-';
if (oregs.cx & SUBDIR)
attr[3] = 'd';
else
attr[3] = '-';
if (oregs.cx & ARCHV)
attr[4] = 'a';
else
attr[4] = '-';
attr[5] = '\0';
printf("%s %s\n",attr,iregs.dx);
i = bdos(FNEXT,0) & 0xff; /* Find Next */
}
}
exit(0);
}
/*****************************************************************/
/* print error - see error return table DOS 2.0 Manual page D-14 */
/*****************************************************************/
perror(s,code)
char *s;
unsigned code;
{
printf("chmod: File %s",s);
switch(code) {
case 2:
case 18: /* perror called with 18 if bad filename entered */
printf(" not found.\n");
break;
case 3:
printf(". Path not found.\n");
break;
case 5:
printf(". Access denied.\n");
break;
default:
printf(". DOS error code %u returned.\n",code);