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