Annotation of researchv10dc/ipc/libipc/pwsearch.c, revision 1.1.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.