|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 3549 (0xddd)
Types: TextFile
Notes: UNIX file
Names: »chmod.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »cmd/chmod.c«
/*
* Chmod -- change the mode of
* files (both symbolic and octal)
* I really don't like the syntax though.
*/
#include <stdio.h>
#include <sys/stat.h>
/* Masks by types of permissions */
#define AEXEC (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6))
#define AREAD (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6))
#define AWRITE (S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6))
#define ASUID (S_ISUID|S_ISGID)
#define ATEXT S_ISVTX
/* Masks by types of users */
#define AOWN (S_ISUID|S_ISVTX|S_IREAD|S_IWRITE|S_IEXEC)
#define AGRP (S_ISGID|S_ISVTX|(S_IREAD>>3)|(S_IWRITE>>3)|(S_IEXEC>>3))
#define AOTH (S_ISVTX|(S_IREAD>>6)|(S_IWRITE>>6)|(S_IEXEC>>6))
#define AALL (AOWN|AGRP|AOTH)
short int uid;
char stickwarn[] = "\
chmod: Warning: non-super user may not set sticky bit\n\
";
main(argc, argv)
char *argv[];
{
register int i;
register char *fn;
int status = 0;
if (argc < 3)
usage();
uid = getuid();
for (i=2; i<argc; i++) {
fn = argv[i];
if (chmod(fn, readmode(argv[1], fn)) < 0) {
perror(fn);
status = 2;
}
}
exit (status);
}
/*
* Read in the symbolic mode and
* set the variables `who', `op',
* and `mode'.
* Knows about the old octal modes as well.
*/
readmode(s, file)
register char *s;
char *file;
{
register int c;
register int mode;
register int op;
register int m1, m2;
struct stat sb;
mode = 0;
if (*s>='0' && *s<='7') {
while (*s != '\0') {
if (*s<'0' || *s>'7')
omusage();
mode = (mode<<3) | *s++-'0';
}
checkmode(mode);
return (mode);
}
sb.st_mode = 0;
stat(file, &sb);
mode = sb.st_mode;
newsym:
m1 = 0;
for (;;) {
switch (*s++) {
case 'u':
m1 |= AOWN;
continue;
case 'g':
m1 |= AGRP;
continue;
case 'o':
m1 |= AOTH;
continue;
case 'a':
m1 |= AALL;
continue;
default:
s--;
break;
}
break;
}
if (m1 == 0) {
m1 = AALL&~getumask();
}
newop:
if ((c = *s++)=='=' || c=='+' || c=='-')
op = c;
else
smusage();
m2 = 0;
for (;;) {
switch (*s++) {
case 'r':
m2 |= AREAD;
continue;
case 'w':
m2 |= AWRITE;
continue;
case 'x':
m2 |= AEXEC;
continue;
case 's':
m2 |= ASUID;
continue;
case 't':
m2 |= ATEXT;
continue;
case 'u':
m2 |= mrepl(mode&AOWN);
continue;
case 'g':
m2 |= mrepl((mode&AGRP)<<3);
continue;
case 'o':
m2 |= mrepl((mode&AOTH)<<6);
continue;
default:
s--;
break;
}
break;
}
switch (op) {
case '-':
mode &= ~(m1&m2);
break;
case '+':
mode |= m1&m2;
break;
case '=':
mode = (mode&~m1) | (m1&m2);
break;
}
if (*s == '\0') {
checkmode(mode);
return (mode);
}
if (*s=='+' || *s=='-' || *s=='=')
goto newop;
if (*s++ == ',')
goto newsym;
smusage();
}
/*
* Get the value of the umask setting.
*/
getumask()
{
register int omask;
omask = umask(0);
umask(omask);
return (omask);
}
/*
* Check the mode to see if any problem
* bits are on. For now, this is
* S_ISVTX for non-super-users.
*/
checkmode(mode)
register int mode;
{
static int beenhere;
if (!beenhere && uid!=0 && mode&S_ISVTX) {
fprintf(stderr, stickwarn);
beenhere++;
}
}
/*
* Replicate the 3-bits of the mode from
* the owner position to all positions.
*/
mrepl(m)
register int m;
{
register int m1;
m1 = m&AOWN;
m = m1 | (m1>>3) | (m1>>6);
if (m1 & S_ISUID)
m |= S_ISGID;
return (m);
}
usage()
{
fprintf(stderr, "Usage: chmod mode file ...\n");
exit(1);
}
smusage()
{
fprintf(stderr, "chmod: badly formed symbolic mode\n");
exit(1);
}
omusage()
{
fprintf(stderr, "chmod: badly formed octal mode\n");
exit(1);
}