Annotation of researchv10dc/ipc/libipc/pwsearch.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * pwsearch(name, uid, pwline)
        !             3:  *   search for name (if non null) or uid in password.
        !             4:      return ptr to passwd structure.
        !             5:      if pwline is non null return whole password line.
        !             6:  */
        !             7: #include <stdio.h>
        !             8: #include <sys/types.h>
        !             9: #include <sys/stat.h>
        !            10: #include <pwd.h>
        !            11: 
        !            12: #define PASSWD "/etc/passwd"
        !            13: #define PWLINE 500
        !            14: #define CHUNK 64       /* allocation of hint table -- must be a power of two */
        !            15: 
        !            16: static struct hint {
        !            17:        long    hint;
        !            18:        char    *name;
        !            19:        short   uid;
        !            20: } *htab;
        !            21: 
        !            22: static int htabsize = 0;
        !            23: static char buf[PWLINE];
        !            24: static FILE *pwf;
        !            25: static time_t pwtime;
        !            26: 
        !            27: struct passwd *pwdecode();
        !            28: char *malloc(), *realloc(), *strcpy();
        !            29: static int buildtable();
        !            30: 
        !            31: struct passwd *
        !            32: pwsearch(name, uid, pwline)
        !            33: char *name, *pwline;
        !            34: {
        !            35:        register int min, max, mid;
        !            36:        register struct passwd *pw;
        !            37:        int ntries = 0;
        !            38:        struct stat sbuf;
        !            39: 
        !            40: again:
        !            41:        if (ntries>1)
        !            42:                return(NULL);
        !            43:        if (pwf)
        !            44:                fstat(fileno(pwf), &sbuf);
        !            45:        if (pwf==NULL || ntries || pwtime < sbuf.st_ctime) {
        !            46:                buildtable();
        !            47:                pwtime = sbuf.st_ctime;
        !            48:        }
        !            49:        ntries++;
        !            50:        if (name) {
        !            51:                /* binary search for name */
        !            52:                min = 0;
        !            53:                max = htabsize - 1;
        !            54:                while (min <= max) {
        !            55:                        register n;
        !            56:                        mid = (min + max) >> 1;
        !            57:                        n = strcmp (name, htab[mid].name);
        !            58:                        if (n == 0)
        !            59:                                break;
        !            60:                        if (n < 0)
        !            61:                                max = mid - 1;
        !            62:                        else
        !            63:                                min = mid + 1;
        !            64:                }
        !            65:                if (min > max)
        !            66:                        goto again;
        !            67:        } else {
        !            68:                /* linear search for uid */
        !            69:                for (mid = 0; mid <htabsize; mid++)
        !            70:                        if (htab[mid].uid == uid)
        !            71:                                break;
        !            72:                if (mid == htabsize)
        !            73:                        goto again;
        !            74:        }
        !            75:        /*
        !            76:         * We have a hint.  Seek to the given point in the file.
        !            77:         * If it's not the very beginning, ensure it is the start
        !            78:         * of a line by peeking at the preceding character.
        !            79:         */
        !            80:        if (htab[mid].hint) {
        !            81:                fseek(pwf, htab[mid].hint-1, 0);
        !            82:                if (getc(pwf) != '\n')
        !            83:                        goto again;
        !            84:        } else
        !            85:                fseek(pwf, htab[mid].hint, 0);
        !            86:        if (fgets(buf, PWLINE, pwf) == NULL)
        !            87:                goto again;
        !            88:        if (pwline)
        !            89:                strcpy(pwline, buf);
        !            90:        pw = pwdecode(buf);
        !            91:        if (name) {
        !            92:                if (strcmp(name, pw->pw_name))
        !            93:                        goto again;
        !            94:        } else if (uid != pw->pw_uid)
        !            95:                goto again;
        !            96:        return(pw);
        !            97: }
        !            98: 
        !            99: /* comparison function for call to qsort */
        !           100: static int
        !           101: comp (p, q)
        !           102: struct hint *p, *q;
        !           103: {
        !           104:        return(strcmp (p->name, q->name));
        !           105: }
        !           106: 
        !           107: static int
        !           108: buildtable()
        !           109: {
        !           110:        long where;
        !           111:        register int i;
        !           112: 
        !           113:        /* free the old hint table */
        !           114:        for (i = 0; i < htabsize; i++) {
        !           115:                if (htab[i].name) {
        !           116:                        (void)free((char *)htab[i].name);
        !           117:                        htab[i].name = NULL;
        !           118:                }
        !           119:        }
        !           120:        if (htab) {
        !           121:                (void)free((char *)htab);
        !           122:                htab = NULL;
        !           123:        }
        !           124:        htabsize = 0;
        !           125:        if (pwf)
        !           126:                fclose(pwf);
        !           127:        pwf = fopen(PASSWD, "r");
        !           128:        if (pwf == NULL)
        !           129:                return;
        !           130:        while (where = ftell(pwf), fgets(buf, PWLINE, pwf) != NULL) {
        !           131:                register struct passwd *pw = pwdecode(buf);
        !           132:                register char *p = malloc(strlen(pw->pw_name) + 1);
        !           133: 
        !           134:                if (p == NULL)
        !           135:                        return;
        !           136:                /* time to expand the hint table? */
        !           137:                if ((htabsize & (CHUNK - 1)) == 0) {
        !           138:                        unsigned s = (htabsize + CHUNK) * sizeof(struct hint);
        !           139:                        if (htab)
        !           140:                                htab = (struct hint *) realloc((char *)htab, s);
        !           141:                        else
        !           142:                                htab = (struct hint *) malloc(s);
        !           143:                        if (htab == NULL) {
        !           144:                                htabsize = 0;
        !           145:                                return;
        !           146:                        }
        !           147:                }
        !           148:                htab[htabsize].name = strcpy(p, pw->pw_name);
        !           149:                htab[htabsize].uid = pw->pw_uid;
        !           150:                htab[htabsize].hint = where;
        !           151:                htabsize++;
        !           152:        }
        !           153:        qsort((char *) htab, htabsize, sizeof (struct hint), comp);
        !           154: }
        !           155: 
        !           156: pwclose()
        !           157: {
        !           158:        if (pwf)
        !           159:                fclose(pwf);
        !           160: }

unix.superglobalmegacorp.com

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