Annotation of coherent/d/bin/chmog.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * chmog -- change the mode, owner, and group of files.
        !             3:  *
        !             4:  * This program was done from the 'chmod', 'chown', and 'chgrp'
        !             5:  * As result code may not be optimal, but should be pretty reliable
        !             6:  * and be backword compatible (including bugs and bad design as exit(2)).
        !             7:  *
        !             8:  * chmog should be link to chown, chmod, and chgrp. BTW it saves about
        !             9:  * 15K :-).
        !            10:  *
        !            11:  * 1-31-92 Vlad
        !            12:  */
        !            13: 
        !            14: #include <stdio.h>
        !            15: #include <pwd.h>
        !            16: #include <grp.h>
        !            17: #include <ctype.h>
        !            18: #include <sys/stat.h>
        !            19: #include <string.h>
        !            20: 
        !            21: /* Masks by types of permissions */
        !            22: #define        AEXEC   (S_IEXEC|(S_IEXEC>>3)|(S_IEXEC>>6))
        !            23: #define        AREAD   (S_IREAD|(S_IREAD>>3)|(S_IREAD>>6))
        !            24: #define        AWRITE  (S_IWRITE|(S_IWRITE>>3)|(S_IWRITE>>6))
        !            25: #define        ASUID   (S_ISUID|S_ISGID)
        !            26: #define        ATEXT   S_ISVTX
        !            27: 
        !            28: /* Masks by types of users */
        !            29: #define        AOWN    (S_ISUID|S_ISVTX|S_IREAD|S_IWRITE|S_IEXEC)
        !            30: #define        AGRP    (S_ISGID|S_ISVTX|(S_IREAD>>3)|(S_IWRITE>>3)|(S_IEXEC>>3))
        !            31: #define        AOTH    (S_ISVTX|(S_IREAD>>6)|(S_IWRITE>>6)|(S_IEXEC>>6))
        !            32: #define        AALL    (AOWN|AGRP|AOTH)
        !            33: 
        !            34: short  int     uid;
        !            35: 
        !            36: char   *chmod_usage = "chmod mode file ...";
        !            37: char   *chown_usage = "chown owner file ...";
        !            38: char   *chgrp_usage = "chgrp group file ...";
        !            39: char   *chmog_usage = "chmog mod owner group file ...";
        !            40: 
        !            41: char   stickwarn[] = "\
        !            42: chmod: Warning: non-super user may not set sticky bit\n\
        !            43: ";
        !            44: 
        !            45: main(argc, argv)
        !            46: int    argc;
        !            47: char   *argv[];
        !            48: {
        !            49:        char    *cmdname;       /* Name of the command */
        !            50: 
        !            51:        /* Strip the pathname off of the name of the executable */
        !            52:        if ((cmdname = strrchr(argv[0], '/')) != (char *) NULL) 
        !            53:                cmdname++;
        !            54:        else
        !            55:                cmdname = argv[0];
        !            56: 
        !            57:        /* Who am I? */
        !            58:        if (!strcmp(cmdname, "chmod"))
        !            59:                cmd_chmod(argc, argv, 0);       /* Emulate chmod */
        !            60:        else if (!strcmp(cmdname, "chown"))
        !            61:                cmd_chown(argc, argv, 0, 0);    /* Emulate chown */
        !            62:        else if (!strcmp(cmdname, "chgrp"))
        !            63:                cmd_chgrp(argc, argv, 0, 0);    /* Emulate chgrp */
        !            64:        else if (!strcmp(cmdname, "chmog"))
        !            65:                chmog(argc, argv);              /* Be itself */
        !            66:        else    /* If some entysiast will link to a different name....*/
        !            67:                usage(chmog_usage);
        !            68:        exit(0);
        !            69: }
        !            70: 
        !            71: /*
        !            72:  * This is main entry for chmog. Call all functions (*chmod, *chown, *chgrp)
        !            73:  * and set the proper shifts of the argv. If correspoding *argv is '-'
        !            74:  * it means that this characteristic of file should be unchanged.
        !            75:  */
        !            76: chmog(argc, argv)
        !            77: int    argc;
        !            78: char   **argv;
        !            79: {
        !            80:        if (argc < 5)
        !            81:                usage(chmog_usage);
        !            82: 
        !            83:        /* Change owner */
        !            84:        if (strcmp(argv[2], "-")) 
        !            85:                cmd_chown(argc, argv, 1, 2);
        !            86:        /* Change group */
        !            87:        if (strcmp(argv[3], "-")) 
        !            88:                cmd_chgrp(argc, argv, 2, 2);
        !            89:        /* Change mode. We want to do it at the very and, otherwise
        !            90:         * chown or chgrp will remove setuid & setgid bits
        !            91:         */
        !            92:        if (strcmp(argv[1], "-")) 
        !            93:                cmd_chmod(argc, argv, 2);
        !            94:        exit(0);
        !            95: }
        !            96: 
        !            97: /*
        !            98:  * Change mode of the file.
        !            99:  */
        !           100: cmd_chmod(argc, argv, shift_file)
        !           101: int    argc;
        !           102: char   **argv;
        !           103: int    shift_file;     /* Shift argv to the file names */
        !           104: {
        !           105:        register int i;
        !           106:        register char *fn;
        !           107:        int status = 0;
        !           108: 
        !           109:        if (argc < 3)
        !           110:                usage(chmod_usage);
        !           111:        uid = getuid();
        !           112:        for (i = 2 + shift_file; i < argc; i++) {
        !           113:                fn = argv[i];
        !           114:                if (chmod(fn, readmode(argv[1], fn)) < 0) {
        !           115:                        perror(fn);
        !           116:                        status = 2;
        !           117:                }
        !           118:        }
        !           119:        if (status)
        !           120:                exit(status);
        !           121: }
        !           122: 
        !           123: /*
        !           124:  * Read in the symbolic mode and
        !           125:  * set the variables `who', `op',
        !           126:  * and `mode'.
        !           127:  * Knows about the old octal modes as well.
        !           128:  */
        !           129: readmode(s, file)
        !           130: register char *s;
        !           131: char *file;
        !           132: {
        !           133:        register int c;
        !           134:        register int mode;
        !           135:        register int op;
        !           136:        register int m1, m2;
        !           137:        struct stat sb;
        !           138: 
        !           139:        mode = 0;
        !           140:        if (*s>='0' && *s<='7') {
        !           141:                while (*s != '\0') {
        !           142:                        if (*s<'0' || *s>'7')
        !           143:                                omusage();
        !           144:                        mode = (mode<<3) | *s++-'0';
        !           145:                }
        !           146:                checkmode(mode);
        !           147:                return (mode);
        !           148:        }
        !           149:        sb.st_mode = 0;
        !           150:        stat(file, &sb);
        !           151:        mode = sb.st_mode;
        !           152: newsym:
        !           153:        m1 = 0;
        !           154:        for (;;) {
        !           155:                switch (*s++) {
        !           156:                case 'u':
        !           157:                        m1 |= AOWN;
        !           158:                        continue;
        !           159: 
        !           160:                case 'g':
        !           161:                        m1 |= AGRP;
        !           162:                        continue;
        !           163: 
        !           164:                case 'o':
        !           165:                        m1 |= AOTH;
        !           166:                        continue;
        !           167: 
        !           168:                case 'a':
        !           169:                        m1 |= AALL;
        !           170:                        continue;
        !           171: 
        !           172:                default:
        !           173:                        s--;
        !           174:                        break;
        !           175:                }
        !           176:                break;
        !           177:        }
        !           178:        if (m1 == 0) {
        !           179:                m1 = AALL&~getumask();
        !           180:        }
        !           181: newop:
        !           182:        if ((c = *s++)=='=' || c=='+' || c=='-')
        !           183:                op = c;
        !           184:        else
        !           185:                smusage();
        !           186:        m2 = 0;
        !           187:        for (;;) {
        !           188:                switch (*s++) {
        !           189:                case 'r':
        !           190:                        m2 |= AREAD;
        !           191:                        continue;
        !           192: 
        !           193:                case 'w':
        !           194:                        m2 |= AWRITE;
        !           195:                        continue;
        !           196: 
        !           197:                case 'x':
        !           198:                        m2 |= AEXEC;
        !           199:                        continue;
        !           200: 
        !           201:                case 's':
        !           202:                        m2 |= ASUID;
        !           203:                        continue;
        !           204: 
        !           205:                case 't':
        !           206:                        m2 |= ATEXT;
        !           207:                        continue;
        !           208: 
        !           209:                case 'u':
        !           210:                        m2 |= mrepl(mode&AOWN);
        !           211:                        continue;
        !           212: 
        !           213:                case 'g':
        !           214:                        m2 |= mrepl((mode&AGRP)<<3);
        !           215:                        continue;
        !           216: 
        !           217:                case 'o':
        !           218:                        m2 |= mrepl((mode&AOTH)<<6);
        !           219:                        continue;
        !           220: 
        !           221:                default:
        !           222:                        s--;
        !           223:                        break;
        !           224:                }
        !           225:                break;
        !           226:        }
        !           227:        switch (op) {
        !           228:        case '-':
        !           229:                mode &= ~(m1&m2);
        !           230:                break;
        !           231: 
        !           232:        case '+':
        !           233:                mode |= m1&m2;
        !           234:                break;
        !           235: 
        !           236:        case '=':
        !           237:                mode = (mode&~m1) | (m1&m2);
        !           238:                break;
        !           239:        }
        !           240:        if (*s == '\0') {
        !           241:                checkmode(mode);
        !           242:                return (mode);
        !           243:        }
        !           244:        if (*s=='+' || *s=='-' || *s=='=')
        !           245:                goto newop;
        !           246:        if (*s++ == ',')
        !           247:                goto newsym;
        !           248:        smusage();
        !           249: }
        !           250: 
        !           251: /*
        !           252:  * Get the value of the umask setting.
        !           253:  */
        !           254: getumask()
        !           255: {
        !           256:        register int omask;
        !           257: 
        !           258:        omask = umask(0);
        !           259:        umask(omask);
        !           260:        return (omask);
        !           261: }
        !           262: 
        !           263: /*
        !           264:  * Check the mode to see if any problem
        !           265:  * bits are on.  For now, this is
        !           266:  * S_ISVTX for non-super-users.
        !           267:  */
        !           268: checkmode(mode)
        !           269: register int mode;
        !           270: {
        !           271:        static int beenhere;
        !           272: 
        !           273:        if (!beenhere && uid!=0 && mode&S_ISVTX) {
        !           274:                fprintf(stderr, stickwarn);
        !           275:                beenhere++;
        !           276:        }
        !           277: }
        !           278: 
        !           279: /*
        !           280:  * Replicate the 3-bits of the mode from
        !           281:  * the owner position to all positions.
        !           282:  */
        !           283: mrepl(m)
        !           284: register int m;
        !           285: {
        !           286:        register int m1;
        !           287: 
        !           288:        m1 = m&AOWN;
        !           289:        m = m1 | (m1>>3) | (m1>>6);
        !           290:        if (m1 & S_ISUID)
        !           291:                m |= S_ISGID;
        !           292:        return (m);
        !           293: }
        !           294: 
        !           295: smusage()
        !           296: {
        !           297:        fprintf(stderr, "chmod: badly formed symbolic mode\n");
        !           298:        exit(1);
        !           299: }
        !           300: 
        !           301: omusage()
        !           302: {
        !           303:        fprintf(stderr, "chmod: badly formed octal mode\n");
        !           304:        exit(1);
        !           305: }
        !           306: 
        !           307: /*
        !           308:  * Change owner of the file
        !           309:  */
        !           310: cmd_chown(argc, argv, shift_cmd, shift_file)
        !           311: int    argc;
        !           312: char   **argv;
        !           313: int    shift_cmd;      /* Shift argv to the owner */
        !           314: int    shift_file;     /* Shift argv to the file names */
        !           315: {
        !           316:        register struct passwd *pwp;
        !           317:        register int c;
        !           318:        register short owner, group;
        !           319:        struct stat sb;
        !           320:        register short status = 0;
        !           321:        int     i_cmd;
        !           322:        int     i_file;
        !           323: 
        !           324:        if (argc < 3)
        !           325:                usage(chown_usage);
        !           326:        i_cmd = 1 + shift_cmd;
        !           327:        i_file = 2 + shift_file;
        !           328: 
        !           329:        if ((c = *argv[i_cmd]) >='0' && c <= '9')
        !           330:                owner = atoi(argv[i_cmd]);
        !           331:        else {
        !           332:                if ((pwp = getpwnam(argv[i_cmd])) == NULL)
        !           333:                        cherr("%s: bad username `%s'\n", argv[0], argv[i_cmd]);
        !           334:                owner = pwp->pw_uid;
        !           335:        }
        !           336:        for (c = i_file; c < argc; c++) {
        !           337:                group = 0;
        !           338:                if (stat(argv[c], &sb) >= 0)
        !           339:                        group = sb.st_gid;
        !           340:                if (chown(argv[c], owner, group) < 0) {
        !           341:                        perror(argv[c]);
        !           342:                        status = 2;
        !           343:                }
        !           344:        }
        !           345:        if (status)
        !           346:                exit (status);
        !           347: }
        !           348: 
        !           349: /*
        !           350:  * Change the group owner of specified files.
        !           351:  */
        !           352: cmd_chgrp(argc, argv,  shift_cmd, shift_file)
        !           353: int    argc;
        !           354: char   **argv;
        !           355: int    shift_cmd;      /* Shift argv to the group */
        !           356: int    shift_file;     /* Shift argv to the file names */
        !           357: {
        !           358:        register struct group *grp;
        !           359:        register int c;
        !           360:        register short owner, group;
        !           361:        struct stat sb;
        !           362:        register short status = 0;
        !           363:        int     i_cmd;
        !           364:        int     i_file;
        !           365: 
        !           366:        /* Only superuser can invoke chgrp under COHERENT. Vlad */
        !           367:        if (geteuid())
        !           368:                cherr("%s: only superuser can changed group name.\n", argv[0]);
        !           369: 
        !           370:        if (argc < 3)
        !           371:                usage(chgrp_usage);
        !           372:        
        !           373:        i_cmd = 1 + shift_cmd;
        !           374:        i_file = 2 + shift_file;
        !           375: 
        !           376:        /* You can specify group by numeric id or by name. Vlad */
        !           377:        if (isdigit((int) *argv[i_cmd])) {
        !           378:                if ((grp = getgrgid(atoi(argv[i_cmd]))) == NULL)
        !           379:                        cherr("%s: bad numeric group id `%s'\n",
        !           380:                                argv[0], argv[i_cmd]);
        !           381:        } else
        !           382:                if ((grp = getgrnam(argv[i_cmd])) == NULL)
        !           383:                        cherr("%s: bad group name `%s'\n", argv[0],argv[i_cmd]);
        !           384: 
        !           385:        group = grp->gr_gid;
        !           386: 
        !           387:        for (c = i_file; c < argc; c++) {
        !           388:                owner = 0;
        !           389:                if (stat(argv[c], &sb) >= 0)
        !           390:                        owner = sb.st_uid;
        !           391:                if (chown(argv[c], owner, group) < 0) {
        !           392:                        perror(argv[c]);
        !           393:                        status = 2;
        !           394:                }
        !           395:        }
        !           396:        if (status)
        !           397:                exit (status);
        !           398: }
        !           399: 
        !           400: usage(msg)
        !           401: char   *msg;
        !           402: {
        !           403:        fprintf(stderr, "Usage: %s\n", msg);
        !           404:        exit(1);
        !           405: }
        !           406: 
        !           407: /* VARARGS */
        !           408: cherr(x)
        !           409: {
        !           410:        fprintf(stderr, "%r", &x);
        !           411:        exit(2);
        !           412: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.