Annotation of 43BSDTahoe/bin/passwd/passwd.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)passwd.c   4.32 (Berkeley) 1/21/88";
                     15: #endif not lint
                     16: 
                     17: /*
                     18:  * Modify a field in the password file (either password, login shell, or
                     19:  * gecos field).  This program should be suid with an owner with write
                     20:  * permission on /etc/passwd.
                     21:  */
                     22: #include <sys/types.h>
                     23: #include <sys/file.h>
                     24: #include <sys/stat.h>
                     25: #include <sys/time.h>
                     26: #include <sys/resource.h>
                     27: 
                     28: #include <stdio.h>
                     29: #include <signal.h>
                     30: #include <pwd.h>
                     31: #include <ndbm.h>
                     32: #include <errno.h>
                     33: #include <strings.h>
                     34: #include <ctype.h>
                     35: 
                     36: /*
                     37:  * This should be the first thing returned from a getloginshells()
                     38:  * but too many programs know that it is /bin/sh.
                     39:  */
                     40: #define        DEFSHELL        "/bin/sh"
                     41: 
                     42: #define        DICT            "/usr/dict/words"
                     43: #define        PASSWD          "/etc/passwd"
                     44: #define        PTEMP           "/etc/ptmp"
                     45: 
                     46: #define        EOS             '\0';
                     47: 
                     48: main(argc, argv)
                     49:        int     argc;
                     50:        char    **argv;
                     51: {
                     52:        extern char     *optarg;
                     53:        extern int      errno, optind;
                     54:        struct passwd   *pwd;
                     55:        FILE    *tf;
                     56:        DBM     *dp;
                     57:        uid_t   uid, getuid();
                     58:        int     ch, fd, dochfn, dochsh;
                     59:        char    *cp, *uname, *progname, *umsg,
                     60:                *getfingerinfo(), *getloginshell(), *getnewpasswd(), *malloc();
                     61: 
                     62:        progname = (cp = rindex(*argv, '/')) ? cp + 1 : *argv;
                     63:        dochfn = dochsh = 0;
                     64:        if (!strcmp(progname, "chfn")) {
                     65:                dochfn = 1;
                     66:                umsg = "usage: chfn [username]\n";
                     67:        }
                     68:        else if (!strcmp(progname, "chsh")) {
                     69:                dochsh = 1;
                     70:                umsg = "usage: chsh [username]\n";
                     71:        }
                     72:        else
                     73:                umsg = "usage: passwd [-fs] [username]\n";
                     74: 
                     75:        while ((ch = getopt(argc, argv, "fs")) != EOF)
                     76:                switch((char)ch) {
                     77:                case 'f':
                     78:                        if (dochsh)
                     79:                                goto usage;
                     80:                        dochfn = 1;
                     81:                        break;
                     82:                case 's':
                     83:                        if (dochfn)
                     84:                                goto usage;
                     85:                        dochsh = 1;
                     86:                        break;
                     87:                case '?':
                     88:                default:
                     89: usage:                 fputs(umsg, stderr);
                     90:                        exit(1);
                     91:                }
                     92: 
                     93:        uid = getuid();
                     94:        if (argc - optind < 1) {
                     95:                if (!(pwd = getpwuid(uid))) {
                     96:                        fprintf(stderr, "%s: %u: unknown user uid.\n", progname, uid);
                     97:                        exit(1);
                     98:                }
                     99:                if (!(uname = malloc((u_int)(strlen(pwd->pw_name) + 1)))) {
                    100:                        fprintf(stderr, "%s: out of space.\n", progname);
                    101:                        exit(1);
                    102:                }
                    103:                (void)strcpy(uname, pwd->pw_name);
                    104:        }
                    105:        else {
                    106:                uname = *(argv + optind);
                    107:                if (!(pwd = getpwnam(uname))) {
                    108:                        fprintf(stderr, "%s: %s: unknown user.\n", progname, uname);
                    109:                        exit(1);
                    110:                }
                    111:        }
                    112:        if (uid && uid != pwd->pw_uid) {
                    113:                fputs("Permission denied.\n", stderr);
                    114:                exit(1);
                    115:        }
                    116:        printf("Changing %s for %s.\n", dochfn ? "finger information" : dochsh ? "login shell" : "password", uname);
                    117:        if (dochfn)
                    118:                cp = getfingerinfo(pwd);
                    119:        else if (dochsh)
                    120:                cp = getloginshell(pwd, uid);
                    121:        else
                    122:                cp = getnewpasswd(pwd, uid);
                    123:        (void) signal(SIGHUP, SIG_IGN);
                    124:        (void) signal(SIGINT, SIG_IGN);
                    125:        (void) signal(SIGQUIT, SIG_IGN);
                    126:        (void) signal(SIGTSTP, SIG_IGN);
                    127:        (void) umask(0);
                    128:        if ((fd = open(PTEMP, O_WRONLY|O_CREAT|O_EXCL, 0644)) < 0) {
                    129:                if (errno == EEXIST)
                    130:                        fprintf(stderr, "%s: password file busy - try again.\n", progname);
                    131:                else {
                    132:                        fprintf(stderr, "%s: %s: ", progname, PTEMP);
                    133:                        perror((char *)NULL);
                    134:                }
                    135:                exit(1);
                    136:        }
                    137:        if ((tf = fdopen(fd, "w")) == NULL) {
                    138:                fprintf(stderr, "%s: fdopen failed.\n", progname);
                    139:                exit(1);
                    140:        }
                    141:        if ((dp = dbm_open(PASSWD, O_RDWR, 0644)) == NULL) {
                    142:                fprintf(stderr, "Warning: dbm_open failed: %s: ", PASSWD);
                    143:                perror((char *)NULL);
                    144:        }
                    145:        else if (flock(dp->dbm_dirf, LOCK_EX) < 0) {
                    146:                perror("Warning: lock failed");
                    147:                dbm_close(dp);
                    148:                dp = NULL;
                    149:        }
                    150:        unlimit(RLIMIT_CPU);
                    151:        unlimit(RLIMIT_FSIZE);
                    152:        /*
                    153:         * Copy passwd to temp, replacing matching lines
                    154:         * with new password.
                    155:         */
                    156:        while ((pwd = getpwent()) != NULL) {
                    157:                if (!strcmp(pwd->pw_name, uname)) {
                    158:                        if (uid && uid != pwd->pw_uid) {
                    159:                                fprintf(stderr, "%s: permission denied.\n", progname);
                    160:                                goto out;
                    161:                        }
                    162:                        if (dochfn)
                    163:                                pwd->pw_gecos = cp;
                    164:                        else if (dochsh)
                    165:                                pwd->pw_shell = cp;
                    166:                        else
                    167:                                pwd->pw_passwd = cp;
                    168:                        if (pwd->pw_gecos[0] == '*')    /* ??? */
                    169:                                pwd->pw_gecos++;
                    170:                        replace(dp, pwd);
                    171:                }
                    172:                fprintf(tf, "%s:%s:%d:%d:%s:%s:%s\n",
                    173:                        pwd->pw_name,
                    174:                        pwd->pw_passwd,
                    175:                        pwd->pw_uid,
                    176:                        pwd->pw_gid,
                    177:                        pwd->pw_gecos,
                    178:                        pwd->pw_dir,
                    179:                        pwd->pw_shell);
                    180:        }
                    181:        endpwent();
                    182:        if (dp && dbm_error(dp))
                    183:                fputs("Warning: dbm_store failed.\n", stderr);
                    184:        (void) fflush(tf);
                    185:        if (ferror(tf)) {
                    186:                fprintf(stderr, "Warning: %s write error, %s not updated.\n",
                    187:                    PTEMP, PASSWD);
                    188:                goto out;
                    189:        }
                    190:        (void)fclose(tf);
                    191:        if (dp != NULL)
                    192:                dbm_close(dp);
                    193:        if (rename(PTEMP, PASSWD) < 0) {
                    194:                perror(progname);
                    195:        out:
                    196:                (void)unlink(PTEMP);
                    197:                exit(1);
                    198:        }
                    199:        exit(0);
                    200: }
                    201: 
                    202: unlimit(lim)
                    203:        int     lim;
                    204: {
                    205:        struct rlimit rlim;
                    206: 
                    207:        rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY;
                    208:        (void)setrlimit(lim, &rlim);
                    209: }
                    210: 
                    211: /*
                    212:  * Replace the password entry in the dbm data base with pwd.
                    213:  */
                    214: replace(dp, pwd)
                    215:        DBM *dp;
                    216:        struct passwd *pwd;
                    217: {
                    218:        datum key, content;
                    219:        register char *cp, *tp;
                    220:        char buf[BUFSIZ];
                    221: 
                    222:        if (dp == NULL)
                    223:                return;
                    224: 
                    225:        cp = buf;
                    226: #define        COMPACT(e)      tp = pwd->e; while (*cp++ = *tp++);
                    227:        COMPACT(pw_name);
                    228:        COMPACT(pw_passwd);
                    229:        bcopy((char *)&pwd->pw_uid, cp, sizeof (int));
                    230:        cp += sizeof (int);
                    231:        bcopy((char *)&pwd->pw_gid, cp, sizeof (int));
                    232:        cp += sizeof (int);
                    233:        bcopy((char *)&pwd->pw_quota, cp, sizeof (int));
                    234:        cp += sizeof (int);
                    235:        COMPACT(pw_comment);
                    236:        COMPACT(pw_gecos);
                    237:        COMPACT(pw_dir);
                    238:        COMPACT(pw_shell);
                    239:        content.dptr = buf;
                    240:        content.dsize = cp - buf;
                    241:        key.dptr = pwd->pw_name;
                    242:        key.dsize = strlen(pwd->pw_name);
                    243:        dbm_store(dp, key, content, DBM_REPLACE);
                    244:        key.dptr = (char *)&pwd->pw_uid;
                    245:        key.dsize = sizeof (int);
                    246:        dbm_store(dp, key, content, DBM_REPLACE);
                    247: }
                    248: 
                    249: char *
                    250: getnewpasswd(pwd, u)
                    251:        register struct passwd *pwd;
                    252:        uid_t u;
                    253: {
                    254:        time_t  salt, time();
                    255:        int     c, i, insist;
                    256:        char    *pw, pwbuf[10], pwcopy[10], saltc[2],
                    257:                *crypt(), *getpass();
                    258: 
                    259:        if (pwd->pw_passwd[0] && u != 0) {
                    260:                (void)strcpy(pwbuf, getpass("Old password:"));
                    261:                pw = crypt(pwbuf, pwd->pw_passwd);
                    262:                if (strcmp(pw, pwd->pw_passwd) != 0) {
                    263:                        puts("Sorry.");
                    264:                        exit(1);
                    265:                }
                    266:        }
                    267:        for(;;) {
                    268:                (void)strcpy(pwbuf, getpass("New password:"));
                    269:                if (!*pwbuf) {
                    270:                        puts("Password unchanged.");
                    271:                        exit(1);
                    272:                }
                    273:                if (strcmp(pwbuf, pwcopy)) {
                    274:                        insist = 1;
                    275:                        (void)strcpy(pwcopy, pwbuf);
                    276:                }
                    277:                else if (++insist == 4)
                    278:                        break;
                    279:                if (strlen(pwbuf) <= 4)
                    280:                        puts("Please enter a longer password.");
                    281:                else {
                    282:                        for (pw = pwbuf; *pw && islower(*pw); ++pw);
                    283:                        if (*pw)
                    284:                                break;
                    285:                        puts("Please don't use an all-lower case password.\nUnusual capitalization, control characters or digits are suggested.");
                    286:                }
                    287:        }
                    288:        if (strcmp(pwbuf, getpass("Retype new password:"))) {
                    289:                puts("Mismatch - password unchanged.");
                    290:                exit(1);
                    291:        }
                    292:        (void)time(&salt);
                    293:        salt = 9 * getpid();
                    294:        saltc[0] = salt & 077;
                    295:        saltc[1] = (salt>>6) & 077;
                    296:        for (i = 0; i < 2; i++) {
                    297:                c = saltc[i] + '.';
                    298:                if (c > '9')
                    299:                        c += 7;
                    300:                if (c > 'Z')
                    301:                        c += 6;
                    302:                saltc[i] = c;
                    303:        }
                    304:        return(crypt(pwbuf, saltc));
                    305: }
                    306: 
                    307: char *
                    308: getloginshell(pwd, u)
                    309:        struct passwd *pwd;
                    310:        uid_t u;
                    311: {
                    312:        static char newshell[BUFSIZ];
                    313:        char *cp, *valid, *getusershell();
                    314: 
                    315:        if (pwd->pw_shell == 0 || *pwd->pw_shell == '\0')
                    316:                pwd->pw_shell = DEFSHELL;
                    317:        if (u != 0) {
                    318:                do {
                    319:                        valid = getusershell();
                    320:                        if (valid == NULL) {
                    321:                                printf("Cannot change from restricted shell %s\n",
                    322:                                        pwd->pw_shell);
                    323:                                exit(1);
                    324:                        }
                    325:                } while (strcmp(pwd->pw_shell, valid) != 0);
                    326:        }
                    327:        printf("Old shell: %s\nNew shell: ", pwd->pw_shell);
                    328:        (void)fgets(newshell, sizeof (newshell) - 1, stdin);
                    329:        cp = index(newshell, '\n');
                    330:        if (cp)
                    331:                *cp = '\0';
                    332:        if (newshell[0] == 0) {
                    333:                puts("Login shell unchanged.");
                    334:                exit(1);
                    335:        }
                    336:        /*
                    337:         * Allow user to give shell name w/o preceding pathname.
                    338:         */
                    339:        if (u != 0 || newshell[0] != '/') {
                    340:                endusershell();
                    341:                do {
                    342:                        valid = getusershell();
                    343:                        if (valid == 0) {
                    344:                                if (u == 0) {
                    345:                                        valid = newshell;
                    346:                                        break;
                    347:                                }
                    348:                                printf("%s is unacceptable as a new shell.\n",
                    349:                                        newshell);
                    350:                                exit(1);
                    351:                        }
                    352:                        if (newshell[0] == '/') {
                    353:                                cp = valid;
                    354:                        } else {
                    355:                                cp = rindex(valid, '/');
                    356:                                if (cp == 0)
                    357:                                        cp = valid;
                    358:                                else
                    359:                                        cp++;
                    360:                        }
                    361:                } while (strcmp(newshell, cp) != 0);
                    362:        }
                    363:        else
                    364:                valid = newshell;
                    365:        if (strcmp(valid, pwd->pw_shell) == 0) {
                    366:                puts("Login shell unchanged.");
                    367:                exit(1);
                    368:        }
                    369:        if (access(valid, X_OK) < 0) {
                    370:                printf("%s is unavailable.\n", valid);
                    371:                exit(1);
                    372:        }
                    373:        if (strcmp(valid, DEFSHELL) == 0)
                    374:                valid[0] = '\0';
                    375:        return (valid);
                    376: }
                    377: 
                    378: struct default_values {
                    379:        char *name;
                    380:        char *office_num;
                    381:        char *office_phone;
                    382:        char *home_phone;
                    383: };
                    384: 
                    385: /*
                    386:  * Get name, room number, school phone, and home phone.
                    387:  */
                    388: char *
                    389: getfingerinfo(pwd)
                    390:        struct passwd *pwd;
                    391: {
                    392:        char in_str[BUFSIZ];
                    393:        struct default_values *defaults, *get_defaults();
                    394:        static char answer[4*BUFSIZ];
                    395: 
                    396:        answer[0] = '\0';
                    397:        defaults = get_defaults(pwd->pw_gecos);
                    398:        puts("Default values are printed inside of '[]'.");
                    399:        puts("To accept the default, type <return>.");
                    400:        puts("To have a blank entry, type the word 'none'.");
                    401:        /*
                    402:         * Get name.
                    403:         */
                    404:        do {
                    405:                printf("\nName [%s]: ", defaults->name);
                    406:                (void) fgets(in_str, BUFSIZ - 1, stdin);
                    407:                if (special_case(in_str, defaults->name)) 
                    408:                        break;
                    409:        } while (illegal_input(in_str));
                    410:        (void) strcpy(answer, in_str);
                    411:        /*
                    412:         * Get room number.
                    413:         */
                    414:        do {
                    415:                printf("Room number (Exs: 597E or 197C) [%s]: ",
                    416:                        defaults->office_num);
                    417:                (void) fgets(in_str, BUFSIZ - 1, stdin);
                    418:                if (special_case(in_str, defaults->office_num))
                    419:                        break;
                    420:        } while (illegal_input(in_str) || illegal_building(in_str));
                    421:        (void) strcat(strcat(answer, ","), in_str);
                    422:        /*
                    423:         * Get office phone number.
                    424:         * Remove hyphens.
                    425:         */
                    426:        do {
                    427:                printf("Office Phone (Ex: 6426000) [%s]: ",
                    428:                        defaults->office_phone);
                    429:                (void) fgets(in_str, BUFSIZ - 1, stdin);
                    430:                if (special_case(in_str, defaults->office_phone))
                    431:                        break;
                    432:                remove_hyphens(in_str);
                    433:        } while (illegal_input(in_str) || not_all_digits(in_str));
                    434:        (void) strcat(strcat(answer, ","), in_str);
                    435:        /*
                    436:         * Get home phone number.
                    437:         * Remove hyphens if present.
                    438:         */
                    439:        do {
                    440:                printf("Home Phone (Ex: 9875432) [%s]: ", defaults->home_phone);
                    441:                (void) fgets(in_str, BUFSIZ - 1, stdin);
                    442:                if (special_case(in_str, defaults->home_phone))
                    443:                        break;
                    444:                remove_hyphens(in_str);
                    445:        } while (illegal_input(in_str) || not_all_digits(in_str));
                    446:        (void) strcat(strcat(answer, ","), in_str);
                    447:        if (strcmp(answer, pwd->pw_gecos) == 0) {
                    448:                puts("Finger information unchanged.");
                    449:                exit(1);
                    450:        }
                    451:        return (answer);
                    452: }
                    453: 
                    454: /*
                    455:  * Prints an error message if a ':', ',' or a newline is found in the string.
                    456:  * A message is also printed if the input string is too long.  The password
                    457:  * file uses :'s as separators, and are not allowed in the "gcos" field;
                    458:  * commas are used as separators in the gcos field, so are disallowed.
                    459:  * Newlines serve as delimiters between users in the password file, and so,
                    460:  * those too, are checked for.  (I don't think that it is possible to
                    461:  * type them in, but better safe than sorry)
                    462:  *
                    463:  * Returns '1' if a colon, comma or newline is found or the input line is
                    464:  * too long.
                    465:  */
                    466: illegal_input(input_str)
                    467:        char *input_str;
                    468: {
                    469:        char *ptr;
                    470:        int error_flag = 0;
                    471:        int length = strlen(input_str);
                    472: 
                    473:        if (strpbrk(input_str, ",:")) {
                    474:                puts("':' and ',' are not allowed.");
                    475:                error_flag = 1;
                    476:        }
                    477:        if (input_str[length-1] != '\n') {
                    478:                /* the newline and the '\0' eat up two characters */
                    479:                printf("Maximum number of characters allowed is %d\n",
                    480:                        BUFSIZ-2);
                    481:                /* flush the rest of the input line */
                    482:                while (getchar() != '\n')
                    483:                        /* void */;
                    484:                error_flag = 1;
                    485:        }
                    486:        /*
                    487:         * Delete newline by shortening string by 1.
                    488:         */
                    489:        input_str[length-1] = '\0';
                    490:        /*
                    491:         * Don't allow control characters, etc in input string.
                    492:         */
                    493:        for (ptr = input_str; *ptr; ptr++)
                    494:                if (!isprint(*ptr)) {
                    495:                        puts("Control characters are not allowed.");
                    496:                        error_flag = 1;
                    497:                        break;
                    498:                }
                    499:        return (error_flag);
                    500: }
                    501: 
                    502: /*
                    503:  * Removes '-'s from the input string.
                    504:  */
                    505: remove_hyphens(str)
                    506:        char *str;
                    507: {
                    508:        char *hyphen;
                    509: 
                    510:        while ((hyphen = index(str, '-')) != NULL)
                    511:                (void) strcpy(hyphen, hyphen+1);
                    512: }
                    513: 
                    514: /*
                    515:  *  Checks to see if 'str' contains only digits (0-9).  If not, then
                    516:  *  an error message is printed and '1' is returned.
                    517:  */
                    518: not_all_digits(str)
                    519:        register char *str;
                    520: {
                    521:        for (; *str; ++str)
                    522:                if (!isdigit(*str)) {
                    523:                        puts("Phone numbers may only contain digits.");
                    524:                        return(1);
                    525:                }
                    526:        return(0);
                    527: }
                    528: 
                    529: /*
                    530:  * Deal with Berkeley buildings.  Abbreviating Cory to C and Evans to E.
                    531:  * Correction changes "str".
                    532:  *
                    533:  * Returns 1 if incorrect room format.
                    534:  * 
                    535:  * Note: this function assumes that the newline has been removed from str.
                    536:  */
                    537: illegal_building(str)
                    538:        register char *str;
                    539: {
                    540:        int length = strlen(str);
                    541:        register char *ptr;
                    542: 
                    543:        /*
                    544:         * If the string is [Ee]vans or [Cc]ory or ends in
                    545:         * [ \t0-9][Ee]vans or [ \t0-9M][Cc]ory, then contract the name
                    546:         * into 'E' or 'C', as the case may be, and delete leading blanks.
                    547:         */
                    548:        if (length >= 5 && strcmp(ptr = str + length - 4, "vans") == 0 &&
                    549:            (*--ptr == 'e' || *ptr == 'E') &&
                    550:            (--ptr < str || isspace(*ptr) || isdigit(*ptr))) {
                    551:                for (; ptr > str && isspace(*ptr); ptr--)
                    552:                        ;
                    553:                ptr++;
                    554:                *ptr++ = 'E';
                    555:                *ptr = '\0';
                    556:        } else
                    557:        if (length >= 4 && strcmp(ptr = str + length - 3, "ory") == 0 &&
                    558:            (*--ptr == 'c' || *ptr == 'C') &&
                    559:            (--ptr < str || *ptr == 'M' || isspace(*ptr) || isdigit(*ptr))) {
                    560:                for (; ptr > str && isspace(*ptr); ptr--)
                    561:                        ;
                    562:                ptr++;
                    563:                *ptr++ = 'C';
                    564:                *ptr = '\0';
                    565:        }
                    566:        return (0);
                    567: }
                    568: 
                    569: /*
                    570:  * get_defaults picks apart "str" and returns a structure points.
                    571:  * "str" contains up to 4 fields separated by commas.
                    572:  * Any field that is missing is set to blank.
                    573:  */
                    574: struct default_values *
                    575: get_defaults(str)
                    576:        char *str;
                    577: {
                    578:        struct default_values *answer;
                    579:        char    *malloc();
                    580: 
                    581:        answer = (struct default_values *)
                    582:                malloc((unsigned)sizeof(struct default_values));
                    583:        if (answer == (struct default_values *) NULL) {
                    584:                fputs("\nUnable to allocate storage in get_defaults!\n", stderr);
                    585:                exit(1);
                    586:        }
                    587:        /*
                    588:         * Values if no corresponding string in "str".
                    589:         */
                    590:        answer->name = str;
                    591:        answer->office_num = "";
                    592:        answer->office_phone = "";
                    593:        answer->home_phone = "";
                    594:        str = index(answer->name, ',');
                    595:        if (str == 0) 
                    596:                return (answer);
                    597:        *str = '\0';
                    598:        answer->office_num = str + 1;
                    599:        str = index(answer->office_num, ',');
                    600:        if (str == 0) 
                    601:                return (answer);
                    602:        *str = '\0';
                    603:        answer->office_phone = str + 1;
                    604:        str = index(answer->office_phone, ',');
                    605:        if (str == 0) 
                    606:                return (answer);
                    607:        *str = '\0';
                    608:        answer->home_phone = str + 1;
                    609:        return (answer);
                    610: }
                    611: 
                    612: /*
                    613:  *  special_case returns true when either the default is accepted
                    614:  *  (str = '\n'), or when 'none' is typed.  'none' is accepted in
                    615:  *  either upper or lower case (or any combination).  'str' is modified
                    616:  *  in these two cases.
                    617:  */
                    618: special_case(str,default_str)
                    619:        char *str, *default_str;
                    620: {
                    621:        static char word[] = "none\n";
                    622:        char *ptr, *wordptr;
                    623: 
                    624:        /*
                    625:         *  If the default is accepted, then change the old string do the 
                    626:         *  default string.
                    627:         */
                    628:        if (*str == '\n') {
                    629:                (void) strcpy(str, default_str);
                    630:                return (1);
                    631:        }
                    632:        /*
                    633:         *  Check to see if str is 'none'.  (It is questionable if case
                    634:         *  insensitivity is worth the hair).
                    635:         */
                    636:        wordptr = word-1;
                    637:        for (ptr = str; *ptr != '\0'; ++ptr) {
                    638:                ++wordptr;
                    639:                if (*wordptr == '\0')   /* then words are different sizes */
                    640:                        return (0);
                    641:                if (*ptr == *wordptr)
                    642:                        continue;
                    643:                if (isupper(*ptr) && (tolower(*ptr) == *wordptr))
                    644:                        continue;
                    645:                /*
                    646:                 * At this point we have a mismatch, so we return
                    647:                 */
                    648:                return (0);
                    649:        }
                    650:        /*
                    651:         * Make sure that words are the same length.
                    652:         */
                    653:        if (*(wordptr+1) != '\0')
                    654:                return (0);
                    655:        /*
                    656:         * Change 'str' to be the null string
                    657:         */
                    658:        *str = '\0';
                    659:        return (1);
                    660: }

unix.superglobalmegacorp.com

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