|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 8013 (0x1f4d) Types: TextFile Names: »misc.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/misc.c«
/**********************************************************************\ * * * misc.c * * * * Miscellaneous routines ranging from password generators to word * * capitalizers to a routine that scrubs untoward characters from user * * names. * * * \**********************************************************************/ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/time.h> #include <sys/dir.h> #include <strings.h> #include <ctype.h> #include "sysdep.h" #include "macros.h" #include "mem.h" #include "lists.h" #include "range.h" #include "sort.h" #define DAY 86400 /* no. of seconds in a day */ extern struct list RangeList; char *ctime(), *sprintf(); long random(); coloncount(s) register char *s; { register int n = 0; while (*s) if (*s++ == ':') n++; return n; } capitalize(s) char *s; { strlower(s); if (isalpha(*s) && islower(*s)) *s = toupper(*s); } strlower(s) char *s; { while (*s) { if (isalpha(*s) && isupper(*s)) *s = tolower(*s); s++; } return; } int search_array(a, s, nelem, elemsize, compfunc, found) char *a, *s; int nelem, elemsize, (*compfunc)(), *found; { int lo = 0, hi = nelem - 1 , middle, compval; int offset; *found = 0; while (lo < hi) { middle = (lo + hi) / 2; offset = middle*elemsize; if ((compval = (*compfunc)(s, a+offset)) == 0) { *found = 1; return middle; } else if (compval < 0) { decr(middle); hi = middle; } else lo = middle + 1; } if (nelem && (*compfunc)(s, a+lo*elemsize) == 0) *found = 1; return lo; } savestr(cpp, s) char **cpp, *s; { *cpp = (char *) MEM(strlen(s)+1); (void) strcpy(*cpp, s); return; } static char *suf[13] = { "Jr.", "Sr.", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "Esq." }; static char *ttl[6] = { "Prof.", "Dr.", "Mr.", "Ms.", "Mrs.", "Rev." }; struct list Suffixes = { 13, 13, (addr *)suf }; struct list Titles = { 6, 6, (addr *)ttl }; addr makeusername(c, v) int c; addr *v; { static addr_t user[SHORT_BUF]; int found, tail; flexaddr up; up.p_ap = user; (void) search_list(&Titles, (char *)v[0], strcmp, &found); if (found) { v++; c--; } (void) search_list(&Suffixes, (char *)v[c-1], strcmp, &found); if (found) c--; /* * If last name is seven characters or less and the * case-lowered version of this isn't taken, use it. */ if (strlen((char *)v[c-1]) < 8) { (void) strcpy((char *)user, (char *)v[c-1]); strlower((char *)user); if (!userexists((char *)user)) { scrub((char *)user); return user; } } /* * If we have three initials and they aren't already taken, use them. */ if (c == 3) { up.p_cp[0] = ((char *)v[0])[0]; up.p_cp[1] = ((char *)v[1])[0]; up.p_cp[2] = ((char *)v[2])[0]; up.p_cp[3] = '\0'; strlower((char *)user); if (!userexists((char *)user)) { scrub((char *)user); return user; } } /* * Oh, well. Chop off last name at five characters, append '_' and * first initial. If the resulting name is unused, use it. * If not increment the first initial through the collating * sequence until we find a name that isn't used. The latter should * happen rarely. */ (void) strcpy((char *)user, (char *)v[c-1]); up.p_cp[5] = '\0'; tail = strlen((char *)user); up.p_cp[tail++] = '_'; up.p_cp[tail++] = ((char *)v[0])[0]; up.p_cp[tail--] = '\0'; strlower((char *)user); while (userexists((char *)user)) up.p_cp[tail]++; scrub((char *)user); return user; } /* * Change all unsavory characters in a username to '_' */ scrub(username) char *username; { for (; *username; username++) { if (isalpha(*username) || isdigit(*username)) continue; if (*username == '-') continue; *username = '_'; } return; } /* * This function is used to shut lint up about long to int conversions * that I don't CARE about when getting a tiny random number. */ int rnd() { union a { int a_i; long a_l; } il; il.a_l = random(); return il.a_i; } #define UPPER (char)(rnd() % 26) + 'A' #define LOWER (char)(rnd() % 26) + 'a' #define NUMBER (char)(rnd() % 10) + '0' #define ODD (rnd() % 2 == 1) #define EVEN !ODD char * makepass() { static char password[SHORT_BUF]; char *cp; cp = password; if (ODD) *cp++ = UPPER; else *cp++ = LOWER; if (EVEN) *cp++ = NUMBER; else *cp++ = UPPER; if (EVEN) *cp++ = LOWER; else *cp++ = NUMBER; if (ODD) *cp++ = LOWER; else *cp++ = NUMBER; if (ODD) *cp++ = NUMBER; else *cp++ = UPPER; if (EVEN) *cp++ = UPPER; else *cp++ = LOWER; return password; } char * rsalt() { static char salt[3]; if (EVEN) salt[0] = UPPER; else salt[0] = LOWER; if (ODD) salt[1] = LOWER; else salt[1] = NUMBER; salt[2] = '\0'; return salt; } char *re_comp(); /* ARGSUSED1 */ addr gethomedir(user, group) char *user, *group; #ifdef xanth { static addr_t dbuf[LONG_BUF], defbuf[LONG_BUF+1]; char expr[LONG_BUF+1]; struct direct *dp; DIR *dirp; (void) sprintf((char *)defbuf, "/tmp/U%s", user); dirp = opendir(USERDIR); if (dirp == NULL) { err1("cannot open %s (read)", USERDIR); return(defbuf); } for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { if (dp->d_name[0] == '.') continue; (void) sprintf(expr, "^%s%c%c", dp->d_name, '.', '*'); (void) re_comp(expr); if (re_exec(group) == 1) { (void) sprintf((char *)dbuf, "%s/%s/%s", USERDIR, dp->d_name, user); closedir(dirp); return(dbuf); } } closedir(dirp); return(defbuf); } #else { static addr_t dbuf[LONG_BUF]; (void) sprintf((char *)dbuf, "%s/%s", USERDIR, user); return dbuf; } #endif /* * Figger out where the next free uid is, taking into * consideration the range tables */ int findnextuid(group) char *group; { struct range *rg; int uid, indx; int maxu, minu; maxu = minu = 0; uid = NOMORE; for (indx=0; indx < RangeList.l_count; indx++) { rg = (struct range *) RangeList.l_list[indx]; if (!eq(group, rg->rg_name)) continue; if (rg->rg_from > rg->rg_to) uid = rnextuid(rg->rg_from, rg->rg_to); else uid = nextuid(rg->rg_from, rg->rg_to); if (uid != NOMORE) return(uid); maxu = max(maxu, rg->rg_from); maxu = max(maxu, rg->rg_to); minu = min(minu, rg->rg_from); minu = min(minu, rg->rg_to); } /* * No preference or no space available so now we look for space * in shared ranges. */ for (indx=0; indx < RangeList.l_count; indx++) { rg = (struct range *) RangeList.l_list[indx]; if (rg->rg_mode == RG_EXCLUSIVE || eq(rg->rg_name, group)) continue; if (rg->rg_from > rg->rg_to) uid = rnextuid(rg->rg_from, rg->rg_to); else uid = nextuid(rg->rg_from, rg->rg_to); if (uid != NOMORE) break; maxu = max(maxu, rg->rg_from); maxu = max(maxu, rg->rg_to); minu = min(minu, rg->rg_from); minu = min(minu, rg->rg_to); } uid = nextuid(0, minu-1); if (uid == -1) uid = nextuid(maxu+1, 1000); return(uid); } int nextuid(lo, hi) int lo, hi; { int i; for (i=lo; i<=hi; i++) if (!uidexists(i)) return(i); return(NOMORE); } int rnextuid(hi, lo) int hi, lo; { int i; for (i=hi; i>=lo; i--) if (!uidexists(i)) return(i); return(NOMORE); } /* * Max is a function here, because it is used in places where macro side * effects are not desired. */ int max(a, b) int a, b; { return (a > b ? a : b); } int min(a, b) int a, b; { return (a < b ? a : b); } dirscan(dir, l) char *dir; register struct list *l; { struct direct *dp; DIR *dirp; zerolist(l); dirp = opendir(dir); if (dirp == NULL) return; for (dp=readdir(dirp); dp != NULL; dp=readdir(dirp)) { if (eq(dp->d_name, ".") || eq(dp->d_name, "..")) continue; strlistadd(l, dp->d_name); } closedir(dirp); sort_list(l, pstrcmp); return; } int isdir(name) char *name; { struct stat sb; if (stat(name, &sb) == -1) return 0; return ((sb.st_mode&S_IFMT) == S_IFDIR) ? 1 : 0; } validint(str) char *str; { if (!str || !*str) return 0; while (*str) if (!isdigit(*str)) return 0; else str++; return 1; }