|
|
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;
}