Annotation of cci/usr/src/ucb/chfn.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char *sccsid = "@@(#)chfn.c     4.6 (Berkeley) 7/10/83";
        !             3: #endif lint
        !             4: 
        !             5: /*
        !             6:  *      changefinger - change finger entries
        !             7:  */
        !             8: #include <stdio.h>
        !             9: #include <signal.h>
        !            10: #include <pwd.h>
        !            11: #include <sys/time.h>
        !            12: #include <sys/resource.h>
        !            13: #include <sys/file.h>
        !            14: #include <ctype.h>
        !            15: 
        !            16: struct default_values {
        !            17:        char *name;
        !            18:        char *office_num;
        !            19:        char *office_phone;
        !            20:        char *home_phone;
        !            21: };
        !            22: 
        !            23: char   passwd[] = "/etc/passwd";
        !            24: char   temp[]   = "/etc/ptmp";
        !            25: struct passwd *pwd;
        !            26: struct passwd *getpwent(), *getpwnam(), *getpwuid();
        !            27: int    endpwent();
        !            28: char   *crypt();
        !            29: char   *getpass();
        !            30: int    hadQ = 0, hadZ = 0;
        !            31: 
        !            32: main(argc, argv)
        !            33:        int argc;
        !            34:        char *argv[];
        !            35: {
        !            36:        int user_uid;
        !            37:        char replacement[4*BUFSIZ];
        !            38:        int fd;
        !            39:        FILE *tf;
        !            40: 
        !            41:        if (argc > 2) {
        !            42:                printf("Usage: changefinger [user]\n");
        !            43:                exit(1);
        !            44:        }
        !            45:        /*
        !            46:         * Error check to make sure the user (foolishly) typed their own name.
        !            47:         */
        !            48:        user_uid = getuid();
        !            49:        if ((argc == 2) && (user_uid != 0)) {
        !            50:                pwd = getpwnam(argv[1]);
        !            51:                if (pwd == NULL) {
        !            52:                        printf("%s%s%s%s%s%s%s%s",
        !            53:                                "There is no account for ", argv[1],
        !            54:                                " on this machine.\n", 
        !            55:                                "You probably mispelled your login name;\n",
        !            56:                                "only root is allowed to change another",
        !            57:                                " person's finger entry.\n",
        !            58:                                "Note:  you do not need to type your login",
        !            59:                                " name as an argument.\n");
        !            60:                        exit(1);
        !            61:                }
        !            62:                if (pwd->pw_uid != user_uid) {
        !            63:                        printf("%s%s",
        !            64:                                "You are not allowed to change another",
        !            65:                                " person's finger entry.\n");
        !            66:                        exit(1);
        !            67:                }
        !            68:        }
        !            69:        /*
        !            70:         * If root is changing a finger entry, then find the uid that
        !            71:         * corresponds to the user's login name.
        !            72:         */
        !            73:        if ((argc == 2) && (user_uid == 0)) {
        !            74:                pwd = getpwnam(argv[1]);
        !            75:                if (pwd == NULL) {
        !            76:                        printf("There is no account for %s on this machine\n", 
        !            77:                                pwd->pw_name);
        !            78:                        exit(1);
        !            79:                }
        !            80:                user_uid = pwd->pw_uid;
        !            81:        }
        !            82:        if (argc == 1) {
        !            83:                pwd = getpwuid(user_uid);
        !            84:                if (pwd == NULL) {
        !            85:                        fprintf(stderr, "No passwd file entry!?\n");
        !            86:                        exit(1);
        !            87:                }
        !            88:        }
        !            89:        /*
        !            90:         * Collect name, office number, office phone, and home phone.
        !            91:         */
        !            92:        get_info(pwd->pw_gecos, replacement);
        !            93: 
        !            94:        (void) signal(SIGHUP, SIG_IGN);
        !            95:        (void) signal(SIGINT, SIG_IGN);
        !            96:        (void) signal(SIGQUIT, SIG_IGN);
        !            97:        (void) signal(SIGTSTP, SIG_IGN);
        !            98:        (void) umask(0);
        !            99:        if ((fd = open(temp, O_CREAT|O_EXCL|O_RDWR, 0644)) < 0) {
        !           100:                printf("Temporary file busy -- try again\n");
        !           101:                exit(1);
        !           102:        }
        !           103:        if ((tf = fdopen(fd, "w")) == NULL) {
        !           104:                printf("Absurd fdopen failure - seek help\n");
        !           105:                goto out;
        !           106:        }
        !           107:        unlimit(RLIMIT_CPU);
        !           108:        unlimit(RLIMIT_FSIZE);
        !           109:        /*
        !           110:         * Copy passwd to temp, replacing matching lines
        !           111:         * with new gecos field.
        !           112:         */
        !           113:        while ((pwd = getpwent()) != NULL) {
        !           114:                if (pwd->pw_uid == user_uid)
        !           115:                        pwd->pw_gecos = replacement;
        !           116:                fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n",
        !           117:                        pwd->pw_name,
        !           118:                        pwd->pw_passwd,
        !           119:                        pwd->pw_uid,
        !           120:                        pwd->pw_gid,
        !           121:                        pwd->pw_gecos,
        !           122:                        pwd->pw_dir,
        !           123:                        pwd->pw_shell);
        !           124:        }
        !           125:        (void) endpwent();
        !           126:        if (rename(temp, passwd) < 0) {
        !           127:                fprintf(stderr, "chfn: "); perror("rename");
        !           128:   out:
        !           129:                (void) unlink(temp);
        !           130:                exit(1);
        !           131:        }
        !           132:        (void) fclose(tf);
        !           133:        exit(0);
        !           134: }
        !           135: 
        !           136: unlimit(lim)
        !           137: {
        !           138:        struct rlimit rlim;
        !           139: 
        !           140:        rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
        !           141:        (void) setrlimit(lim, &rlim);
        !           142: }
        !           143: 
        !           144: /*
        !           145:  * Get name, office number, office phone, and home phone.
        !           146:  */
        !           147: get_info(gecos_field, answer)
        !           148:        char *gecos_field;
        !           149:        char *answer;
        !           150: {
        !           151:        char *strcpy(), *strcat();
        !           152:        char in_str[BUFSIZ];
        !           153:        struct default_values *defaults, *get_defaults();
        !           154:        int phflag;
        !           155: 
        !           156:        answer[0] = '\0';
        !           157:        defaults = get_defaults(gecos_field);
        !           158:        printf("Default values are printed inside of '[]'.\n");
        !           159:        printf("Examples are printed inside of '()'.\n");
        !           160:        printf("To accept the default, type <return>.\n");
        !           161:        printf("To have a blank entry, type the word 'none'.\n");
        !           162:        /*
        !           163:         * Get name.
        !           164:         */
        !           165:        do {
        !           166:                printf("\nName [%s]: ", defaults->name);
        !           167:                (void) fgets(in_str, BUFSIZ, stdin);
        !           168:                if (special_case(in_str, defaults->name)) 
        !           169:                        break;
        !           170:        } while (illegal_input(in_str));
        !           171:        (void) strcpy(answer, in_str);
        !           172:        /*
        !           173:         * Get office number.
        !           174:         */
        !           175: again:
        !           176:        do {
        !           177:                printf("Office number (Exs: 597E or 197C) [%s]: ",
        !           178:                        defaults->office_num);
        !           179:                (void) fgets(in_str, BUFSIZ, stdin);
        !           180:                if (special_case(in_str, defaults->office_num)) {
        !           181:                        if (hadQ)
        !           182:                                if (*in_str != '\0')
        !           183:                                        strcat(in_str, "Q");
        !           184:                        break;
        !           185:                }
        !           186:        } while (illegal_input(in_str));
        !           187:        if (illegal_building(in_str))
        !           188:                strcat(in_str, "Q");
        !           189:        if (strlen(in_str) > 10) {
        !           190:                printf("office number must be no more than 9 characters\n");
        !           191:                goto again;
        !           192:        }
        !           193:        (void) strcat(strcat(answer, ","), in_str);
        !           194:        /*
        !           195:         * Get office phone number.
        !           196:         * Remove hyphens and 642, x2, or 2 prefixes if present.
        !           197:         */
        !           198:        do {
        !           199:                printf("Office Phone (Ex: 1632) [%s]: ",
        !           200:                        defaults->office_phone);
        !           201:                (void) fgets(in_str, BUFSIZ, stdin);
        !           202:                phflag = 0;
        !           203:                if (special_case(in_str, defaults->office_phone)) {
        !           204:                        phflag = 1;
        !           205:                        if (hadZ)
        !           206:                                if (*in_str != '\0')
        !           207:                                        strcat(in_str, "Z");
        !           208:                        break;
        !           209:                }
        !           210:                remove_hyphens(in_str);
        !           211:                if ((strlen(in_str) == 8) && (strcmpn(in_str, "642", 3) == 0)) {
        !           212:                        (void) strcpy(in_str, in_str+3);
        !           213:                        phflag = 1;
        !           214:                }
        !           215:                if ((strlen(in_str) == 7) && (strcmpn(in_str, "x2", 2) == 0)) {
        !           216:                        (void) strcpy(in_str, in_str+2);
        !           217:                        phflag = 1;
        !           218:                }
        !           219:                if ((strlen(in_str) == 6) && (in_str[0] == '2')) {
        !           220:                        (void) strcpy(in_str, in_str+1);
        !           221:                        phflag = 1;
        !           222:                }
        !           223:        } while (illegal_input(in_str) || wrong_length(in_str, 7));
        !           224:        if (!phflag)
        !           225:                strcat(in_str, "Z");
        !           226:        (void) strcat(strcat(answer, ","), in_str);
        !           227:        /*
        !           228:         * Get home phone number.
        !           229:         * Remove hyphens if present.
        !           230:         */
        !           231:        do {
        !           232:                printf("Home Phone (Ex: 9875432) [%s]: ", defaults->home_phone);
        !           233:                (void) fgets(in_str, BUFSIZ, stdin);
        !           234:                if (special_case(in_str, defaults->home_phone))
        !           235:                        break;
        !           236:                remove_hyphens(in_str);
        !           237:        } while (illegal_input(in_str));
        !           238:        (void) strcat(strcat(answer, ","), in_str);
        !           239: }
        !           240: 
        !           241: /*
        !           242:  * Prints an error message if a ':' or a newline is found in the string.
        !           243:  * A message is also printed if the input string is too long.
        !           244:  * The password file uses :'s as seperators, and are not allowed in the "gcos"
        !           245:  * field.  Newlines serve as delimiters between users in the password file,
        !           246:  * and so, those too, are checked for.  (I don't think that it is possible to
        !           247:  * type them in, but better safe than sorry)
        !           248:  *
        !           249:  * Returns '1' if a colon or newline is found or the input line is too long.
        !           250:  */
        !           251: illegal_input(input_str)
        !           252:        char *input_str;
        !           253: {
        !           254:        char *index();
        !           255:        char *ptr;
        !           256:        int error_flag = 0;
        !           257:        int length = strlen(input_str);
        !           258: 
        !           259:        if (index(input_str, ':')) {
        !           260:                printf("':' is not allowed.\n");
        !           261:                error_flag = 1;
        !           262:        }
        !           263:        if (input_str[length-1] != '\n') {
        !           264:                /* the newline and the '\0' eat up two characters */
        !           265:                printf("Maximum number of characters allowed is %d\n",
        !           266:                        BUFSIZ-2);
        !           267:                /* flush the rest of the input line */
        !           268:                while (getchar() != '\n')
        !           269:                        /* void */;
        !           270:                error_flag = 1;
        !           271:        }
        !           272:        /*
        !           273:         * Delete newline by shortening string by 1.
        !           274:         */
        !           275:        input_str[length-1] = '\0';
        !           276:        /*
        !           277:         * Don't allow control characters, etc in input string.
        !           278:         */
        !           279:        for (ptr=input_str; *ptr != '\0'; ptr++) {
        !           280:                if ((int) *ptr < 040) {
        !           281:                        printf("Control characters are not allowed.\n");
        !           282:                        error_flag = 1;
        !           283:                        break;
        !           284:                }
        !           285:        }
        !           286:        return(error_flag);
        !           287: }
        !           288: 
        !           289: /*
        !           290:  * Removes '-'s from the input string.
        !           291:  */
        !           292: remove_hyphens(str)
        !           293:        char *str;
        !           294: {
        !           295:        char *hyphen, *index(), *strcpy();
        !           296: 
        !           297:        while ((hyphen=index(str, '-')) != NULL) {
        !           298:                (void) strcpy(hyphen, hyphen+1);
        !           299:        }
        !           300: }
        !           301: 
        !           302: /*
        !           303:  * Returns 1 when the length of the input string is not zero and
        !           304:  * greater than n.
        !           305:  * Prints an error message in this case.
        !           306:  */
        !           307: wrong_length(str, n)
        !           308:        char *str;
        !           309:        int n;
        !           310: {
        !           311: 
        !           312:        if ((strlen(str) != 0) && (strlen(str) >= n)) {
        !           313:                printf("The phone number should be less than %d digits long.\n",
        !           314:                        n);
        !           315:                return(1);
        !           316:        }
        !           317:        return(0);
        !           318: }
        !           319: 
        !           320: /*
        !           321:  * Make sure that building is 'E', 'C' or 'L'.
        !           322:  * Error correction is done if building is 'e', 'c', 'l',
        !           323:  * "evans", "cory" or "lbl".
        !           324:  * Correction changes "str".
        !           325:  * The finger program determines the building by looking at the last
        !           326:  * character.  Currently, finger only allows that character to be 'E', 'C'
        !           327:  * or 'L'.
        !           328:  *
        !           329:  * Returns 1 if incorrect office format.
        !           330:  * 
        !           331:  * Note: this function assumes that the newline has been removed from str.
        !           332:  */
        !           333: illegal_building(str)
        !           334:        char *str;
        !           335: {
        !           336:        int length = strlen(str);
        !           337:        char *last_ch, *ptr;
        !           338: 
        !           339:        /*
        !           340:         * Zero length strings are acceptable input.
        !           341:         */
        !           342:        if (length == 0)
        !           343:                return(0);
        !           344:        /*
        !           345:         * Delete "vans", "ory" and "bl".
        !           346:         */
        !           347:        if (strcmpn(str+length-4, "vans", 4) == 0) {
        !           348:                length -= 4;
        !           349:                str[length] = '\0';
        !           350:        }
        !           351:        if (strcmpn(str+length-3, "ory", 3) == 0) {
        !           352:                length -= 3;
        !           353:                str[length] = '\0';
        !           354:        }
        !           355:        if (strcmpn(str+length-2, "bl", 2) == 0) {
        !           356:                length -= 2;
        !           357:                str[length] = '\0';
        !           358:        }
        !           359:        last_ch = str+length-1;
        !           360:        /*
        !           361:         * Now change e to E or c to C or l to L.
        !           362:         */
        !           363:        if (*last_ch == 'e')
        !           364:                *last_ch = 'E';
        !           365:        if (*last_ch == 'c')
        !           366:                *last_ch = 'C';
        !           367:        if (*last_ch == 'l')
        !           368:                *last_ch = 'L';
        !           369:        /*
        !           370:         * Delete any spaces before the E, C or L.
        !           371:         */
        !           372:        for (ptr=last_ch-1; ptr>str; ptr--) {
        !           373:                if (*ptr != ' ')
        !           374:                        break;
        !           375:        }
        !           376:        (void) strcpy(ptr+1, last_ch);
        !           377:        /*
        !           378:         * Make sure building is evans, cory or lbl.
        !           379:         */
        !           380:        if ((*last_ch != 'E') && (*last_ch != 'C') && (*last_ch != 'L'))
        !           381:                return(1);
        !           382:        return(0);
        !           383: }
        !           384: 
        !           385: /* get_defaults picks apart "str" and returns a structure points.
        !           386:  * "str" contains up to 4 fields separated by commas.
        !           387:  * Any field that is missing is set to blank.
        !           388:  */
        !           389: struct default_values 
        !           390: *get_defaults(str)
        !           391:        char *str;
        !           392: {
        !           393:        struct default_values *answer;
        !           394:        char *malloc(), *index();
        !           395:        int len;
        !           396: 
        !           397:        answer = (struct default_values *)
        !           398:                malloc((unsigned)sizeof(struct default_values));
        !           399:        if (answer == (struct default_values *) NULL) {
        !           400:                fprintf(stderr,
        !           401:                        "\nUnable to allocate storage in get_defaults!\n");
        !           402:                exit(1);
        !           403:        }
        !           404:        /*
        !           405:         * Values if no corresponding string in "str".
        !           406:         */
        !           407:        answer->name = str;
        !           408:        answer->office_num = "";
        !           409:        answer->office_phone = "";
        !           410:        answer->home_phone = "";
        !           411:        str = index(answer->name, ',');
        !           412:        if (str == 0)
        !           413:                return(answer);
        !           414:        *str = '\0';
        !           415:        answer->office_num = str + 1;
        !           416:        str = index(answer->office_num, ',');
        !           417:        if (str == 0)  {
        !           418:                len = strlen(answer->office_num);
        !           419:                if (answer->office_num[len - 1] == 'Q')  {
        !           420:                        answer->office_num[len - 1] = '\0';
        !           421:                        hadQ = 1;
        !           422:                }
        !           423:                return(answer);
        !           424:        }
        !           425:        *str = '\0';
        !           426:        len = strlen(answer->office_num);
        !           427:        if (answer->office_num[len - 1] == 'Q')  {
        !           428:                answer->office_num[len - 1] = '\0';
        !           429:                hadQ = 1;
        !           430:        }
        !           431:        answer->office_phone = str + 1;
        !           432:        str = index(answer->office_phone, ',');
        !           433:        if (str == 0)  {
        !           434:                len = strlen(answer->office_phone);
        !           435:                if (answer->office_phone[len - 1] == 'Z')  {
        !           436:                        answer->office_phone[len - 1] = '\0';
        !           437:                        hadZ = 1;
        !           438:                }
        !           439:                return(answer);
        !           440:        }
        !           441:        *str = '\0';
        !           442:        len = strlen(answer->office_phone);
        !           443:        if (answer->office_phone[len - 1] == 'Z')  {
        !           444:                answer->office_phone[len - 1] = '\0';
        !           445:                hadZ = 1;
        !           446:        }
        !           447:        answer->home_phone = str + 1;
        !           448:        return(answer);
        !           449: }
        !           450: 
        !           451: /*
        !           452:  *  special_case returns true when either the default is accepted
        !           453:  *  (str = '\n'), or when 'none' is typed.  'none' is accepted in
        !           454:  *  either upper or lower case (or any combination).  'str' is modified
        !           455:  *  in these two cases.
        !           456:  */
        !           457: int special_case(str,default_str)
        !           458:        char *str;
        !           459:        char *default_str;
        !           460: {
        !           461:        static char word[] = "none\n";
        !           462:        char *ptr, *wordptr;
        !           463: 
        !           464:        /*
        !           465:         *  If the default is accepted, then change the old string do the 
        !           466:         *  default string.
        !           467:         */
        !           468:        if (*str == '\n') {
        !           469:                (void) strcpy(str, default_str);
        !           470:                return(1);
        !           471:        }
        !           472:        /*
        !           473:         *  Check to see if str is 'none'.  (It is questionable if case
        !           474:         *  insensitivity is worth the hair).
        !           475:         */
        !           476:        wordptr = word-1;
        !           477:        for (ptr=str; *ptr != '\0'; ++ptr) {
        !           478:                ++wordptr;
        !           479:                if (*wordptr == '\0')   /* then words are different sizes */
        !           480:                        return(0);
        !           481:                if (*ptr == *wordptr)
        !           482:                        continue;
        !           483:                if (isupper(*ptr) && (tolower(*ptr) == *wordptr))
        !           484:                        continue;
        !           485:                /*
        !           486:                 * At this point we have a mismatch, so we return
        !           487:                 */
        !           488:                return(0);
        !           489:        }
        !           490:        /*
        !           491:         * Make sure that words are the same length.
        !           492:         */
        !           493:        if (*(wordptr+1) != '\0')
        !           494:                return(0);
        !           495:        /*
        !           496:         * Change 'str' to be the null string
        !           497:         */
        !           498:        *str = '\0';
        !           499:        return(1);
        !           500: }

unix.superglobalmegacorp.com

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