xref: /csrg-svn/usr.bin/mail/vars.c (revision 42741)
122471Sdist /*
222471Sdist  * Copyright (c) 1980 Regents of the University of California.
333499Sbostic  * All rights reserved.
433499Sbostic  *
5*42741Sbostic  * %sccs.include.redist.c%
622471Sdist  */
722471Sdist 
834905Sbostic #ifndef lint
9*42741Sbostic static char sccsid[] = "@(#)vars.c	5.6 (Berkeley) 06/01/90";
1034905Sbostic #endif /* not lint */
111250Skas 
121250Skas #include "rcv.h"
131250Skas 
141250Skas /*
151250Skas  * Mail -- a mail program
161250Skas  *
171250Skas  * Variable handling stuff.
181250Skas  */
191250Skas 
201250Skas /*
211250Skas  * Assign a value to a variable.
221250Skas  */
231250Skas 
241250Skas assign(name, value)
251250Skas 	char name[], value[];
261250Skas {
271250Skas 	register struct var *vp;
281250Skas 	register int h;
291250Skas 
301250Skas 	h = hash(name);
311250Skas 	vp = lookup(name);
321250Skas 	if (vp == NOVAR) {
331250Skas 		vp = (struct var *) calloc(sizeof *vp, 1);
341250Skas 		vp->v_name = vcopy(name);
351250Skas 		vp->v_link = variables[h];
361250Skas 		variables[h] = vp;
371250Skas 	}
381250Skas 	else
391250Skas 		vfree(vp->v_value);
401250Skas 	vp->v_value = vcopy(value);
411250Skas }
421250Skas 
431250Skas /*
441250Skas  * Free up a variable string.  We do not bother to allocate
451250Skas  * strings whose value is "" since they are expected to be frequent.
461250Skas  * Thus, we cannot free same!
471250Skas  */
481250Skas 
491250Skas vfree(cp)
5031142Sedward 	char *cp;
511250Skas {
5231142Sedward 	if (*cp)
5331142Sedward 		free(cp);
541250Skas }
551250Skas 
561250Skas /*
571250Skas  * Copy a variable value into permanent (ie, not collected after each
581250Skas  * command) space.  Do not bother to alloc space for ""
591250Skas  */
601250Skas 
611250Skas char *
621250Skas vcopy(str)
631250Skas 	char str[];
641250Skas {
6531142Sedward 	char *new;
6631142Sedward 	unsigned len;
671250Skas 
6831142Sedward 	if (*str == '\0')
6931142Sedward 		return "";
7031142Sedward 	len = strlen(str) + 1;
7131142Sedward 	if ((new = malloc(len)) == NULL)
7231142Sedward 		panic("Out of memory");
7331142Sedward 	bcopy(str, new, (int) len);
7431142Sedward 	return new;
751250Skas }
761250Skas 
771250Skas /*
781250Skas  * Get the value of a variable and return it.
791250Skas  * Look in the environment if its not available locally.
801250Skas  */
811250Skas 
821250Skas char *
831250Skas value(name)
841250Skas 	char name[];
851250Skas {
861250Skas 	register struct var *vp;
871250Skas 
881250Skas 	if ((vp = lookup(name)) == NOVAR)
891250Skas 		return(getenv(name));
901250Skas 	return(vp->v_value);
911250Skas }
921250Skas 
931250Skas /*
941250Skas  * Locate a variable and return its variable
951250Skas  * node.
961250Skas  */
971250Skas 
981250Skas struct var *
991250Skas lookup(name)
10031142Sedward 	register char name[];
1011250Skas {
1021250Skas 	register struct var *vp;
1031250Skas 
10431142Sedward 	for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link)
10531142Sedward 		if (*vp->v_name == *name && equal(vp->v_name, name))
1061250Skas 			return(vp);
1071250Skas 	return(NOVAR);
1081250Skas }
1091250Skas 
1101250Skas /*
1111250Skas  * Locate a group name and return it.
1121250Skas  */
1131250Skas 
1141250Skas struct grouphead *
1151250Skas findgroup(name)
11631142Sedward 	register char name[];
1171250Skas {
1181250Skas 	register struct grouphead *gh;
1191250Skas 
12031142Sedward 	for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link)
12131142Sedward 		if (*gh->g_name == *name && equal(gh->g_name, name))
1221250Skas 			return(gh);
1231250Skas 	return(NOGRP);
1241250Skas }
1251250Skas 
1261250Skas /*
1271250Skas  * Print a group out on stdout
1281250Skas  */
1291250Skas 
1301250Skas printgroup(name)
1311250Skas 	char name[];
1321250Skas {
1331250Skas 	register struct grouphead *gh;
1341250Skas 	register struct group *gp;
1351250Skas 
1361250Skas 	if ((gh = findgroup(name)) == NOGRP) {
1371250Skas 		printf("\"%s\": not a group\n", name);
1381250Skas 		return;
1391250Skas 	}
1401250Skas 	printf("%s\t", gh->g_name);
1411250Skas 	for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link)
1421250Skas 		printf(" %s", gp->ge_name);
14331142Sedward 	putchar('\n');
1441250Skas }
1451250Skas 
1461250Skas /*
1471250Skas  * Hash the passed string and return an index into
1481250Skas  * the variable or group hash table.
1491250Skas  */
1501250Skas 
1511250Skas hash(name)
15231142Sedward 	register char *name;
1531250Skas {
15431142Sedward 	register h = 0;
1551250Skas 
15631142Sedward 	while (*name) {
15731142Sedward 		h <<= 2;
15831142Sedward 		h += *name++;
15931142Sedward 	}
16031142Sedward 	if (h < 0 && (h = -h) < 0)
1614334Skurt 		h = 0;
16231142Sedward 	return (h % HSHSIZE);
1631250Skas }
164