DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T m

⟦621e63063⟧ TextFile

    Length: 8013 (0x1f4d)
    Types: TextFile
    Names: »misc.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/misc.c« 

TextFile

/**********************************************************************\
* 								       *
* 	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;
}