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