122471Sdist /* 222471Sdist * Copyright (c) 1980 Regents of the University of California. 333499Sbostic * All rights reserved. 433499Sbostic * 542741Sbostic * %sccs.include.redist.c% 622471Sdist */ 722471Sdist 834905Sbostic #ifndef lint 9*54505Sbostic static char sccsid[] = "@(#)vars.c 5.7 (Berkeley) 06/26/92"; 1034905Sbostic #endif /* not lint */ 111250Skas 121250Skas #include "rcv.h" 13*54505Sbostic #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 */ 24*54505Sbostic void 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 */ 49*54505Sbostic void 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 * 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 * 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 * 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 * 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 */ 130*54505Sbostic void 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 */ 151*54505Sbostic int 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