xref: /csrg-svn/usr.bin/mail/vars.c (revision 34905)
122471Sdist /*
222471Sdist  * Copyright (c) 1980 Regents of the University of California.
333499Sbostic  * All rights reserved.
433499Sbostic  *
533499Sbostic  * Redistribution and use in source and binary forms are permitted
6*34905Sbostic  * provided that the above copyright notice and this paragraph are
7*34905Sbostic  * duplicated in all such forms and that any documentation,
8*34905Sbostic  * advertising materials, and other materials related to such
9*34905Sbostic  * distribution and use acknowledge that the software was developed
10*34905Sbostic  * by the University of California, Berkeley.  The name of the
11*34905Sbostic  * University may not be used to endorse or promote products derived
12*34905Sbostic  * from this software without specific prior written permission.
13*34905Sbostic  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14*34905Sbostic  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15*34905Sbostic  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
1622471Sdist  */
1722471Sdist 
18*34905Sbostic #ifndef lint
19*34905Sbostic static char sccsid[] = "@(#)vars.c	5.5 (Berkeley) 06/29/88";
20*34905Sbostic #endif /* not lint */
211250Skas 
221250Skas #include "rcv.h"
231250Skas 
241250Skas /*
251250Skas  * Mail -- a mail program
261250Skas  *
271250Skas  * Variable handling stuff.
281250Skas  */
291250Skas 
301250Skas /*
311250Skas  * Assign a value to a variable.
321250Skas  */
331250Skas 
341250Skas assign(name, value)
351250Skas 	char name[], value[];
361250Skas {
371250Skas 	register struct var *vp;
381250Skas 	register int h;
391250Skas 
401250Skas 	h = hash(name);
411250Skas 	vp = lookup(name);
421250Skas 	if (vp == NOVAR) {
431250Skas 		vp = (struct var *) calloc(sizeof *vp, 1);
441250Skas 		vp->v_name = vcopy(name);
451250Skas 		vp->v_link = variables[h];
461250Skas 		variables[h] = vp;
471250Skas 	}
481250Skas 	else
491250Skas 		vfree(vp->v_value);
501250Skas 	vp->v_value = vcopy(value);
511250Skas }
521250Skas 
531250Skas /*
541250Skas  * Free up a variable string.  We do not bother to allocate
551250Skas  * strings whose value is "" since they are expected to be frequent.
561250Skas  * Thus, we cannot free same!
571250Skas  */
581250Skas 
591250Skas vfree(cp)
6031142Sedward 	char *cp;
611250Skas {
6231142Sedward 	if (*cp)
6331142Sedward 		free(cp);
641250Skas }
651250Skas 
661250Skas /*
671250Skas  * Copy a variable value into permanent (ie, not collected after each
681250Skas  * command) space.  Do not bother to alloc space for ""
691250Skas  */
701250Skas 
711250Skas char *
721250Skas vcopy(str)
731250Skas 	char str[];
741250Skas {
7531142Sedward 	char *new;
7631142Sedward 	unsigned len;
771250Skas 
7831142Sedward 	if (*str == '\0')
7931142Sedward 		return "";
8031142Sedward 	len = strlen(str) + 1;
8131142Sedward 	if ((new = malloc(len)) == NULL)
8231142Sedward 		panic("Out of memory");
8331142Sedward 	bcopy(str, new, (int) len);
8431142Sedward 	return new;
851250Skas }
861250Skas 
871250Skas /*
881250Skas  * Get the value of a variable and return it.
891250Skas  * Look in the environment if its not available locally.
901250Skas  */
911250Skas 
921250Skas char *
931250Skas value(name)
941250Skas 	char name[];
951250Skas {
961250Skas 	register struct var *vp;
971250Skas 
981250Skas 	if ((vp = lookup(name)) == NOVAR)
991250Skas 		return(getenv(name));
1001250Skas 	return(vp->v_value);
1011250Skas }
1021250Skas 
1031250Skas /*
1041250Skas  * Locate a variable and return its variable
1051250Skas  * node.
1061250Skas  */
1071250Skas 
1081250Skas struct var *
1091250Skas lookup(name)
11031142Sedward 	register char name[];
1111250Skas {
1121250Skas 	register struct var *vp;
1131250Skas 
11431142Sedward 	for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link)
11531142Sedward 		if (*vp->v_name == *name && equal(vp->v_name, name))
1161250Skas 			return(vp);
1171250Skas 	return(NOVAR);
1181250Skas }
1191250Skas 
1201250Skas /*
1211250Skas  * Locate a group name and return it.
1221250Skas  */
1231250Skas 
1241250Skas struct grouphead *
1251250Skas findgroup(name)
12631142Sedward 	register char name[];
1271250Skas {
1281250Skas 	register struct grouphead *gh;
1291250Skas 
13031142Sedward 	for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link)
13131142Sedward 		if (*gh->g_name == *name && equal(gh->g_name, name))
1321250Skas 			return(gh);
1331250Skas 	return(NOGRP);
1341250Skas }
1351250Skas 
1361250Skas /*
1371250Skas  * Print a group out on stdout
1381250Skas  */
1391250Skas 
1401250Skas printgroup(name)
1411250Skas 	char name[];
1421250Skas {
1431250Skas 	register struct grouphead *gh;
1441250Skas 	register struct group *gp;
1451250Skas 
1461250Skas 	if ((gh = findgroup(name)) == NOGRP) {
1471250Skas 		printf("\"%s\": not a group\n", name);
1481250Skas 		return;
1491250Skas 	}
1501250Skas 	printf("%s\t", gh->g_name);
1511250Skas 	for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link)
1521250Skas 		printf(" %s", gp->ge_name);
15331142Sedward 	putchar('\n');
1541250Skas }
1551250Skas 
1561250Skas /*
1571250Skas  * Hash the passed string and return an index into
1581250Skas  * the variable or group hash table.
1591250Skas  */
1601250Skas 
1611250Skas hash(name)
16231142Sedward 	register char *name;
1631250Skas {
16431142Sedward 	register h = 0;
1651250Skas 
16631142Sedward 	while (*name) {
16731142Sedward 		h <<= 2;
16831142Sedward 		h += *name++;
16931142Sedward 	}
17031142Sedward 	if (h < 0 && (h = -h) < 0)
1714334Skurt 		h = 0;
17231142Sedward 	return (h % HSHSIZE);
1731250Skas }
174