chmod args
David C Lawrence
tale at pawl.rpi.edu
Sat Jun 3 18:13:46 AEST 1989
/* -*- Mode: C -*-
* permit.c --- change the permission of a file/directory using long form
* Author : David C Lawrence <tale at pawl.rpi.edu>
* Created On : Sat Jun 3 03:32:10 1989
* Last Modified By: David C Lawrence
* Last Modified On: Sat Jun 3 04:04:08 1989
* Update Count : 4
* Status : Works just fine for BSD/Sun, maybe SYSV
*/
/*
* Usage is: permit rwxrwxrwx-pattern file(s)
*
* This deals fine with all current permission schemes on Sun/BSD
* (and mostly on SYSV) systems of which I am aware. I'm not sure
* how portable it is beyond that.
*
* It will accept patterns like rwsr-S--t (bozotic, I realize) without
* complaint and try to permit accordingly. It even gives you a warning
* message if you try to set the sticky bit on a file without being
* the superuser (the regular chmod doesn't).
*
* Caveat: I couldn't get to a SYSV machine to try this out; I
* have a feeling sticky bit stuff might be wrong there, but I am
* not sure.
*
* BUGS: none that I know of at the moment, but it does have really
* dorky error messages.
*/
#include <malloc.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
char *pname; /* for the programme name (error messages) */
extern int errno;
extern char *sys_errlist[];
extern char *strcpy();
int
decipher_permission(perm_str)
char *perm_str;
{
int loop, ch, perm=0;
for (loop=0;loop<9;loop++) {
ch=perm_str[loop];
switch (ch) { /* A switch statement probably isn't the */
case 'r': /* most efficient, but it only gets called */
if (loop%3 != 0) { /* nine times anyway. */
(void)fprintf(stderr,"%s: 'r'ead permission misplaced\n",pname);
exit(99);
}
perm |= S_IREAD >> ((int)(loop/3))*3;
break;
case 'w':
if (loop%3 != 1) {
(void)fprintf(stderr,"%s: 'w'rite permission misplaced\n",pname);
exit(99);
}
perm |= S_IWRITE >> ((int)(loop/3))*3;
break;
case 'x':
if (loop%3 != 2) {
(void)fprintf(stderr,"%s: e'x'ecute permisson misplaced\n",pname);
exit(99);
}
perm |= S_IEXEC >> ((int)(loop/3))*3;
break;
case 'S':
case 's':
case 'l': /* 'l' is SYSV 'S' for setgid (?) */
if (loop%3 != 2 || loop == 8 || (ch == 'l' && loop != 5)) {
(void)fprintf(stderr,"%s: 's'et[ug]id permission misplaced\n",pname);
exit(99);
}
perm |= (loop==2 ? S_ISUID : S_ISGID);
/* add execute permission, too */
if (ch == 's') perm |= S_IEXEC >> ((int)(loop/3))*3;
break;
case 'T':
case 't':
if (loop != 8) {
(void)fprintf(stderr,"%s: s't'icky permission misplaced\n",pname);
exit(99);
}
perm |= S_ISVTX;
/* add execute permission, too */
if (ch == 't') perm |= S_IXOTH;
break;
case '-':
break;
default:
(void)fprintf(stderr,"%s: unknown permission: %c\n",pname,ch);
exit(99);
}
}
return(perm);
}
int
main(argc,argv)
int argc;
char **argv;
{
int permission, rc=0;
struct stat *statbuf;
if (argc < 3 || strlen(argv[1]) != 9) {
(void)fprintf(stderr,"Usage: %s 9-char-permission file(s)\n",argv[0]);
exit(101);
}
if((pname=malloc((unsigned)strlen(argv[0])+1))==NULL) {
(void)fprintf(stderr,"%s: malloc: couldn't allocate space\n",argv[0]);
exit(102);
}
(void)strcpy(pname,argv[0]);
permission=decipher_permission(argv[1]);
for(argc--;argc>1;argc--) {
if (chmod(argv[argc],permission) == -1) {
(void)fprintf(stderr,"%s: %s: %s\n",pname,argv[argc],sys_errlist[errno]);
rc++;
} else {
(void)stat(argv[argc], statbuf); /* since chmod succeeded, stat should */
/* could possibly check here for clearing of setgid, too */
if ((geteuid() != 0) && (permission & S_ISVTX) &&
!(statbuf->st_mode & S_IFDIR)) {
(void)fprintf(stderr,
"%s: couldn't set sticky bit for %s\n",pname,argv[argc]);
rc++;
}
}
}
/* exit with the number of files we were not able to permit as requested */
exit(rc);
}
--
(setq mail '("tale at pawl.rpi.edu" "tale at itsgw.rpi.edu" "tale at rpitsmts.bitnet"))
More information about the Alt.sources
mailing list