xref: /csrg-svn/usr.bin/mail/vars.c (revision 62083)
122471Sdist /*
2*62083Sbostic  * Copyright (c) 1980, 1993
3*62083Sbostic  *	The Regents of the University of California.  All rights reserved.
433499Sbostic  *
542741Sbostic  * %sccs.include.redist.c%
622471Sdist  */
722471Sdist 
834905Sbostic #ifndef lint
9*62083Sbostic static char sccsid[] = "@(#)vars.c	8.1 (Berkeley) 06/06/93";
1034905Sbostic #endif /* not lint */
111250Skas 
121250Skas #include "rcv.h"
1354505Sbostic #include "extern.h"
141250Skas 
151250Skas /*
161250Skas  * Mail -- a mail program
171250Skas  *
181250Skas  * Variable handling stuff.
191250Skas  */
201250Skas 
211250Skas /*
221250Skas  * Assign a value to a variable.
231250Skas  */
2454505Sbostic void
assign(name,value)251250Skas assign(name, value)
261250Skas 	char name[], value[];
271250Skas {
281250Skas 	register struct var *vp;
291250Skas 	register int h;
301250Skas 
311250Skas 	h = hash(name);
321250Skas 	vp = lookup(name);
331250Skas 	if (vp == NOVAR) {
341250Skas 		vp = (struct var *) calloc(sizeof *vp, 1);
351250Skas 		vp->v_name = vcopy(name);
361250Skas 		vp->v_link = variables[h];
371250Skas 		variables[h] = vp;
381250Skas 	}
391250Skas 	else
401250Skas 		vfree(vp->v_value);
411250Skas 	vp->v_value = vcopy(value);
421250Skas }
431250Skas 
441250Skas /*
451250Skas  * Free up a variable string.  We do not bother to allocate
461250Skas  * strings whose value is "" since they are expected to be frequent.
471250Skas  * Thus, we cannot free same!
481250Skas  */
4954505Sbostic void
vfree(cp)501250Skas vfree(cp)
5131142Sedward 	char *cp;
521250Skas {
5331142Sedward 	if (*cp)
5431142Sedward 		free(cp);
551250Skas }
561250Skas 
571250Skas /*
581250Skas  * Copy a variable value into permanent (ie, not collected after each
591250Skas  * command) space.  Do not bother to alloc space for ""
601250Skas  */
611250Skas 
621250Skas char *
vcopy(str)631250Skas vcopy(str)
641250Skas 	char str[];
651250Skas {
6631142Sedward 	char *new;
6731142Sedward 	unsigned len;
681250Skas 
6931142Sedward 	if (*str == '\0')
7031142Sedward 		return "";
7131142Sedward 	len = strlen(str) + 1;
7231142Sedward 	if ((new = malloc(len)) == NULL)
7331142Sedward 		panic("Out of memory");
7431142Sedward 	bcopy(str, new, (int) len);
7531142Sedward 	return new;
761250Skas }
771250Skas 
781250Skas /*
791250Skas  * Get the value of a variable and return it.
801250Skas  * Look in the environment if its not available locally.
811250Skas  */
821250Skas 
831250Skas char *
value(name)841250Skas value(name)
851250Skas 	char name[];
861250Skas {
871250Skas 	register struct var *vp;
881250Skas 
891250Skas 	if ((vp = lookup(name)) == NOVAR)
901250Skas 		return(getenv(name));
911250Skas 	return(vp->v_value);
921250Skas }
931250Skas 
941250Skas /*
951250Skas  * Locate a variable and return its variable
961250Skas  * node.
971250Skas  */
981250Skas 
991250Skas struct var *
lookup(name)1001250Skas lookup(name)
10131142Sedward 	register char name[];
1021250Skas {
1031250Skas 	register struct var *vp;
1041250Skas 
10531142Sedward 	for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link)
10631142Sedward 		if (*vp->v_name == *name && equal(vp->v_name, name))
1071250Skas 			return(vp);
1081250Skas 	return(NOVAR);
1091250Skas }
1101250Skas 
1111250Skas /*
1121250Skas  * Locate a group name and return it.
1131250Skas  */
1141250Skas 
1151250Skas struct grouphead *
findgroup(name)1161250Skas findgroup(name)
11731142Sedward 	register char name[];
1181250Skas {
1191250Skas 	register struct grouphead *gh;
1201250Skas 
12131142Sedward 	for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link)
12231142Sedward 		if (*gh->g_name == *name && equal(gh->g_name, name))
1231250Skas 			return(gh);
1241250Skas 	return(NOGRP);
1251250Skas }
1261250Skas 
1271250Skas /*
1281250Skas  * Print a group out on stdout
1291250Skas  */
13054505Sbostic void
printgroup(name)1311250Skas printgroup(name)
1321250Skas 	char name[];
1331250Skas {
1341250Skas 	register struct grouphead *gh;
1351250Skas 	register struct group *gp;
1361250Skas 
1371250Skas 	if ((gh = findgroup(name)) == NOGRP) {
1381250Skas 		printf("\"%s\": not a group\n", name);
1391250Skas 		return;
1401250Skas 	}
1411250Skas 	printf("%s\t", gh->g_name);
1421250Skas 	for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link)
1431250Skas 		printf(" %s", gp->ge_name);
14431142Sedward 	putchar('\n');
1451250Skas }
1461250Skas 
1471250Skas /*
1481250Skas  * Hash the passed string and return an index into
1491250Skas  * the variable or group hash table.
1501250Skas  */
15154505Sbostic int
hash(name)1521250Skas hash(name)
15331142Sedward 	register char *name;
1541250Skas {
15531142Sedward 	register h = 0;
1561250Skas 
15731142Sedward 	while (*name) {
15831142Sedward 		h <<= 2;
15931142Sedward 		h += *name++;
16031142Sedward 	}
16131142Sedward 	if (h < 0 && (h = -h) < 0)
1624334Skurt 		h = 0;
16331142Sedward 	return (h % HSHSIZE);
1641250Skas }
165