122471Sdist /* 222471Sdist * Copyright (c) 1980 Regents of the University of California. 333499Sbostic * All rights reserved. 433499Sbostic * 5*42741Sbostic * %sccs.include.redist.c% 622471Sdist */ 722471Sdist 834905Sbostic #ifndef lint 9*42741Sbostic static char sccsid[] = "@(#)vars.c 5.6 (Berkeley) 06/01/90"; 1034905Sbostic #endif /* not lint */ 111250Skas 121250Skas #include "rcv.h" 131250Skas 141250Skas /* 151250Skas * Mail -- a mail program 161250Skas * 171250Skas * Variable handling stuff. 181250Skas */ 191250Skas 201250Skas /* 211250Skas * Assign a value to a variable. 221250Skas */ 231250Skas 241250Skas assign(name, value) 251250Skas char name[], value[]; 261250Skas { 271250Skas register struct var *vp; 281250Skas register int h; 291250Skas 301250Skas h = hash(name); 311250Skas vp = lookup(name); 321250Skas if (vp == NOVAR) { 331250Skas vp = (struct var *) calloc(sizeof *vp, 1); 341250Skas vp->v_name = vcopy(name); 351250Skas vp->v_link = variables[h]; 361250Skas variables[h] = vp; 371250Skas } 381250Skas else 391250Skas vfree(vp->v_value); 401250Skas vp->v_value = vcopy(value); 411250Skas } 421250Skas 431250Skas /* 441250Skas * Free up a variable string. We do not bother to allocate 451250Skas * strings whose value is "" since they are expected to be frequent. 461250Skas * Thus, we cannot free same! 471250Skas */ 481250Skas 491250Skas vfree(cp) 5031142Sedward char *cp; 511250Skas { 5231142Sedward if (*cp) 5331142Sedward free(cp); 541250Skas } 551250Skas 561250Skas /* 571250Skas * Copy a variable value into permanent (ie, not collected after each 581250Skas * command) space. Do not bother to alloc space for "" 591250Skas */ 601250Skas 611250Skas char * 621250Skas vcopy(str) 631250Skas char str[]; 641250Skas { 6531142Sedward char *new; 6631142Sedward unsigned len; 671250Skas 6831142Sedward if (*str == '\0') 6931142Sedward return ""; 7031142Sedward len = strlen(str) + 1; 7131142Sedward if ((new = malloc(len)) == NULL) 7231142Sedward panic("Out of memory"); 7331142Sedward bcopy(str, new, (int) len); 7431142Sedward return new; 751250Skas } 761250Skas 771250Skas /* 781250Skas * Get the value of a variable and return it. 791250Skas * Look in the environment if its not available locally. 801250Skas */ 811250Skas 821250Skas char * 831250Skas value(name) 841250Skas char name[]; 851250Skas { 861250Skas register struct var *vp; 871250Skas 881250Skas if ((vp = lookup(name)) == NOVAR) 891250Skas return(getenv(name)); 901250Skas return(vp->v_value); 911250Skas } 921250Skas 931250Skas /* 941250Skas * Locate a variable and return its variable 951250Skas * node. 961250Skas */ 971250Skas 981250Skas struct var * 991250Skas lookup(name) 10031142Sedward register char name[]; 1011250Skas { 1021250Skas register struct var *vp; 1031250Skas 10431142Sedward for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link) 10531142Sedward if (*vp->v_name == *name && equal(vp->v_name, name)) 1061250Skas return(vp); 1071250Skas return(NOVAR); 1081250Skas } 1091250Skas 1101250Skas /* 1111250Skas * Locate a group name and return it. 1121250Skas */ 1131250Skas 1141250Skas struct grouphead * 1151250Skas findgroup(name) 11631142Sedward register char name[]; 1171250Skas { 1181250Skas register struct grouphead *gh; 1191250Skas 12031142Sedward for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link) 12131142Sedward if (*gh->g_name == *name && equal(gh->g_name, name)) 1221250Skas return(gh); 1231250Skas return(NOGRP); 1241250Skas } 1251250Skas 1261250Skas /* 1271250Skas * Print a group out on stdout 1281250Skas */ 1291250Skas 1301250Skas printgroup(name) 1311250Skas char name[]; 1321250Skas { 1331250Skas register struct grouphead *gh; 1341250Skas register struct group *gp; 1351250Skas 1361250Skas if ((gh = findgroup(name)) == NOGRP) { 1371250Skas printf("\"%s\": not a group\n", name); 1381250Skas return; 1391250Skas } 1401250Skas printf("%s\t", gh->g_name); 1411250Skas for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) 1421250Skas printf(" %s", gp->ge_name); 14331142Sedward putchar('\n'); 1441250Skas } 1451250Skas 1461250Skas /* 1471250Skas * Hash the passed string and return an index into 1481250Skas * the variable or group hash table. 1491250Skas */ 1501250Skas 1511250Skas hash(name) 15231142Sedward register char *name; 1531250Skas { 15431142Sedward register h = 0; 1551250Skas 15631142Sedward while (*name) { 15731142Sedward h <<= 2; 15831142Sedward h += *name++; 15931142Sedward } 16031142Sedward if (h < 0 && (h = -h) < 0) 1614334Skurt h = 0; 16231142Sedward return (h % HSHSIZE); 1631250Skas } 164