/* * chmod: does what you'd want it to do */ #include #include #ifdef OS2 #include #endif #include "glob.h" char force=0; /* chmod -f */ char mode; /* +, -, = */ char f_wr=0; short attrib = 0; /* hopefully the attributes we're gonna be setting */ /* * badboy() complains, then dies */ badboy() { fprintf(stderr, "usage: chmod [-f] permission file [...]\n"); exit(1); } /* badboy */ /* * newmodefor() figures out what mode we're chmod'ing to */ newmodefor(p) register char *p; { if (strchr("0123456789", *p)) { /* set absolute mode (hex number) */ mode = '='; attrib = 0; while (isdigit(*p)) { attrib = (attrib * 16) + (*p - '0'); ++p; } if (*p) badboy(); else if (attrib != (attrib & F_AMASK)) { fprintf(stderr, "chmod: invalid permissions\n"); exit(2); } } else { /* set symbolic mode */ if (strchr("oag", *p)) { /* allow trivial case of a+w, etc */ ++p; } if (strchr("+-=", *p)) { mode = *p; /* pick out the modes we're symbolicly diddling. */ for (++p; *p; ++p) switch (*p) { case 'w': attrib &= ~F_RDONLY; f_wr = 1; break; case 's': attrib |= F_SYSTEM; break; case 'h': attrib |= F_HIDDEN; break; case 'a': attrib |= F_ARCHIVE; break; default: badboy(); } /* If we don't explicitly make the mode writable, we're * making it readonly... */ if (mode == '=' && !f_wr) attrib |= F_RDONLY; } /* if strchr() ... */ else badboy(); } } /* newmodefor */ /* * chmod, in mortal flesh */ main(argc, argv) char **argv; { register char *p; register i; register status; /* latest status from DosSetFileMode() */ struct glob_t st; /* for file mode returned from glob() */ /* one argument, possibly, so we won't deal with getopt() today. */ ++argv, --argc; if (argc > 0 && strcmp(*argv, "-f") == 0) { ++argv, --argv; force=1; } /* pick out the new file mode */ if (argc < 2) badboy(); newmodefor(*argv); /* process all the files you want */ for (++argv ;--argc > 0; ++argv) { /* walk through all of the wildcards we were fed, setting all of * the files to our hearts content */ if (p=glob(*argv, &st)) { do { switch (mode) { case '+': st.attrib |= attrib; if (f_wr) st.attrib &= ~F_RDONLY; break; case '-': st.attrib &= ~attrib; if (f_wr) st.attrib |= F_RDONLY; break; default: /* = */ st.attrib = attrib; break; } status = DosSetFileMode(p, st.attrib & F_AMASK, 0L); if (status != 0 && force == 0) fprintf(stderr, "chmod: can't change %s\n", p); } while (p=glob((char*)0, (struct glob_t*)0)); } else if (force == 0) fprintf(stderr, "chmod: %s: no such file\n", *argv); } exit(0); } /* chmod */