vars.c revision 1591
128019Sjoerg/*
228021Sjoerg * Copyright (c) 1980, 1993
328021Sjoerg *	The Regents of the University of California.  All rights reserved.
428021Sjoerg *
528021Sjoerg * Redistribution and use in source and binary forms, with or without
628021Sjoerg * modification, are permitted provided that the following conditions
728021Sjoerg * are met:
828021Sjoerg * 1. Redistributions of source code must retain the above copyright
928021Sjoerg *    notice, this list of conditions and the following disclaimer.
1028021Sjoerg * 2. Redistributions in binary form must reproduce the above copyright
1128021Sjoerg *    notice, this list of conditions and the following disclaimer in the
1228021Sjoerg *    documentation and/or other materials provided with the distribution.
1328021Sjoerg * 3. All advertising materials mentioning features or use of this software
1428021Sjoerg *    must display the following acknowledgement:
1528021Sjoerg *	This product includes software developed by the University of
1628021Sjoerg *	California, Berkeley and its contributors.
1728021Sjoerg * 4. Neither the name of the University nor the names of its contributors
1828021Sjoerg *    may be used to endorse or promote products derived from this software
1928021Sjoerg *    without specific prior written permission.
2028021Sjoerg *
2128021Sjoerg * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2228021Sjoerg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2328019Sjoerg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2428019Sjoerg * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2528021Sjoerg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2628019Sjoerg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2728019Sjoerg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2828019Sjoerg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2928019Sjoerg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3028019Sjoerg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3128019Sjoerg * SUCH DAMAGE.
3228019Sjoerg */
3328019Sjoerg
3428019Sjoerg#ifndef lint
3528019Sjoergstatic char sccsid[] = "@(#)vars.c	8.1 (Berkeley) 6/6/93";
3628019Sjoerg#endif /* not lint */
3728019Sjoerg
3828019Sjoerg#include "rcv.h"
3928019Sjoerg#include "extern.h"
4028019Sjoerg
4128019Sjoerg/*
4228019Sjoerg * Mail -- a mail program
4328019Sjoerg *
4428019Sjoerg * Variable handling stuff.
4528019Sjoerg */
4628019Sjoerg
4728019Sjoerg/*
4828019Sjoerg * Assign a value to a variable.
4928019Sjoerg */
5028019Sjoergvoid
5128019Sjoergassign(name, value)
5228019Sjoerg	char name[], value[];
5328019Sjoerg{
5428021Sjoerg	register struct var *vp;
5528021Sjoerg	register int h;
5650476Speter
5728021Sjoerg	h = hash(name);
5828021Sjoerg	vp = lookup(name);
5928019Sjoerg	if (vp == NOVAR) {
6028021Sjoerg		vp = (struct var *) calloc(sizeof *vp, 1);
6128019Sjoerg		vp->v_name = vcopy(name);
6228019Sjoerg		vp->v_link = variables[h];
6328021Sjoerg		variables[h] = vp;
6428021Sjoerg	}
6528019Sjoerg	else
6628019Sjoerg		vfree(vp->v_value);
6728019Sjoerg	vp->v_value = vcopy(value);
6828019Sjoerg}
6928019Sjoerg
7048614Sobrien/*
7148614Sobrien * Free up a variable string.  We do not bother to allocate
7248614Sobrien * strings whose value is "" since they are expected to be frequent.
7348614Sobrien * Thus, we cannot free same!
7428021Sjoerg */
7528019Sjoergvoid
7648614Sobrienvfree(cp)
7748614Sobrien	char *cp;
7848614Sobrien{
7948614Sobrien	if (*cp)
8048614Sobrien		free(cp);
8148614Sobrien}
8248614Sobrien
8348614Sobrien/*
8428021Sjoerg * Copy a variable value into permanent (ie, not collected after each
8528019Sjoerg * command) space.  Do not bother to alloc space for ""
8648614Sobrien */
8748614Sobrien
8828019Sjoergchar *
8928021Sjoergvcopy(str)
9028021Sjoerg	char str[];
9128021Sjoerg{
9228021Sjoerg	char *new;
9353941Sache	unsigned len;
9428019Sjoerg
9528021Sjoerg	if (*str == '\0')
9628021Sjoerg		return "";
9728021Sjoerg	len = strlen(str) + 1;
9828021Sjoerg	if ((new = malloc(len)) == NULL)
9928019Sjoerg		panic("Out of memory");
10028021Sjoerg	bcopy(str, new, (int) len);
10128019Sjoerg	return new;
10228021Sjoerg}
10328164Sache
10428164Sache/*
10528021Sjoerg * Get the value of a variable and return it.
10628021Sjoerg * Look in the environment if its not available locally.
10728021Sjoerg */
10828021Sjoerg
10928021Sjoergchar *
11028019Sjoergvalue(name)
11153941Sache	char name[];
11253941Sache{
11353941Sache	register struct var *vp;
11428021Sjoerg
11528021Sjoerg	if ((vp = lookup(name)) == NOVAR)
11628021Sjoerg		return(getenv(name));
11728021Sjoerg	return(vp->v_value);
11828021Sjoerg}
11928021Sjoerg
12028021Sjoerg/*
12128019Sjoerg * Locate a variable and return its variable
12253941Sache * node.
12348614Sobrien */
12428021Sjoerg
12528021Sjoergstruct var *
12628021Sjoerglookup(name)
12728019Sjoerg	register char name[];
12853941Sache{
12953941Sache	register struct var *vp;
13053941Sache
13153941Sache	for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link)
13253941Sache		if (*vp->v_name == *name && equal(vp->v_name, name))
13353941Sache			return(vp);
13453941Sache	return(NOVAR);
13553941Sache}
13653941Sache
13753941Sache/*
13853941Sache * Locate a group name and return it.
13953941Sache */
14053941Sache
14153941Sachestruct grouphead *
14228021Sjoergfindgroup(name)
14353941Sache	register char name[];
14428021Sjoerg{
14528021Sjoerg	register struct grouphead *gh;
14628021Sjoerg
14728019Sjoerg	for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link)
14828021Sjoerg		if (*gh->g_name == *name && equal(gh->g_name, name))
14948614Sobrien			return(gh);
15028021Sjoerg	return(NOGRP);
15128021Sjoerg}
15228021Sjoerg
15328019Sjoerg/*
15453941Sache * Print a group out on stdout
15553960Sache */
15653960Sachevoid
15753941Sacheprintgroup(name)
15853941Sache	char name[];
15953941Sache{
16053941Sache	register struct grouphead *gh;
16153960Sache	register struct group *gp;
16253960Sache
16353941Sache	if ((gh = findgroup(name)) == NOGRP) {
16453941Sache		printf("\"%s\": not a group\n", name);
16553941Sache		return;
16653960Sache	}
16753960Sache	printf("%s\t", gh->g_name);
16853960Sache	for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link)
16953960Sache		printf(" %s", gp->ge_name);
17053960Sache	putchar('\n');
17153960Sache}
17253960Sache
17353960Sache/*
17453960Sache * Hash the passed string and return an index into
17528021Sjoerg * the variable or group hash table.
17648614Sobrien */
17728021Sjoergint
17828021Sjoerghash(name)
17928021Sjoerg	register char *name;
18028019Sjoerg{
18128021Sjoerg	register h = 0;
18248614Sobrien
18328021Sjoerg	while (*name) {
18428021Sjoerg		h <<= 2;
18528021Sjoerg		h += *name++;
18628019Sjoerg	}
18728021Sjoerg	if (h < 0 && (h = -h) < 0)
18848614Sobrien		h = 0;
18928021Sjoerg	return (h % HSHSIZE);
19028021Sjoerg}
19128021Sjoerg