122471Sdist /* 222471Sdist * Copyright (c) 1980 Regents of the University of California. 3*33499Sbostic * All rights reserved. 4*33499Sbostic * 5*33499Sbostic * Redistribution and use in source and binary forms are permitted 6*33499Sbostic * provided that this notice is preserved and that due credit is given 7*33499Sbostic * to the University of California at Berkeley. The name of the University 8*33499Sbostic * may not be used to endorse or promote products derived from this 9*33499Sbostic * software without specific prior written permission. This software 10*33499Sbostic * is provided ``as is'' without express or implied warranty. 1122471Sdist */ 1222471Sdist 13*33499Sbostic #ifdef notdef 14*33499Sbostic static char sccsid[] = "@(#)vars.c 5.4 (Berkeley) 02/18/88"; 15*33499Sbostic #endif /* notdef */ 161250Skas 171250Skas #include "rcv.h" 181250Skas 191250Skas /* 201250Skas * Mail -- a mail program 211250Skas * 221250Skas * Variable handling stuff. 231250Skas */ 241250Skas 251250Skas /* 261250Skas * Assign a value to a variable. 271250Skas */ 281250Skas 291250Skas assign(name, value) 301250Skas char name[], value[]; 311250Skas { 321250Skas register struct var *vp; 331250Skas register int h; 341250Skas 351250Skas h = hash(name); 361250Skas vp = lookup(name); 371250Skas if (vp == NOVAR) { 381250Skas vp = (struct var *) calloc(sizeof *vp, 1); 391250Skas vp->v_name = vcopy(name); 401250Skas vp->v_link = variables[h]; 411250Skas variables[h] = vp; 421250Skas } 431250Skas else 441250Skas vfree(vp->v_value); 451250Skas vp->v_value = vcopy(value); 461250Skas } 471250Skas 481250Skas /* 491250Skas * Free up a variable string. We do not bother to allocate 501250Skas * strings whose value is "" since they are expected to be frequent. 511250Skas * Thus, we cannot free same! 521250Skas */ 531250Skas 541250Skas vfree(cp) 5531142Sedward char *cp; 561250Skas { 5731142Sedward if (*cp) 5831142Sedward free(cp); 591250Skas } 601250Skas 611250Skas /* 621250Skas * Copy a variable value into permanent (ie, not collected after each 631250Skas * command) space. Do not bother to alloc space for "" 641250Skas */ 651250Skas 661250Skas char * 671250Skas vcopy(str) 681250Skas char str[]; 691250Skas { 7031142Sedward char *new; 7131142Sedward unsigned len; 721250Skas 7331142Sedward if (*str == '\0') 7431142Sedward return ""; 7531142Sedward len = strlen(str) + 1; 7631142Sedward if ((new = malloc(len)) == NULL) 7731142Sedward panic("Out of memory"); 7831142Sedward bcopy(str, new, (int) len); 7931142Sedward return new; 801250Skas } 811250Skas 821250Skas /* 831250Skas * Get the value of a variable and return it. 841250Skas * Look in the environment if its not available locally. 851250Skas */ 861250Skas 871250Skas char * 881250Skas value(name) 891250Skas char name[]; 901250Skas { 911250Skas register struct var *vp; 921250Skas 931250Skas if ((vp = lookup(name)) == NOVAR) 941250Skas return(getenv(name)); 951250Skas return(vp->v_value); 961250Skas } 971250Skas 981250Skas /* 991250Skas * Locate a variable and return its variable 1001250Skas * node. 1011250Skas */ 1021250Skas 1031250Skas struct var * 1041250Skas lookup(name) 10531142Sedward register char name[]; 1061250Skas { 1071250Skas register struct var *vp; 1081250Skas 10931142Sedward for (vp = variables[hash(name)]; vp != NOVAR; vp = vp->v_link) 11031142Sedward if (*vp->v_name == *name && equal(vp->v_name, name)) 1111250Skas return(vp); 1121250Skas return(NOVAR); 1131250Skas } 1141250Skas 1151250Skas /* 1161250Skas * Locate a group name and return it. 1171250Skas */ 1181250Skas 1191250Skas struct grouphead * 1201250Skas findgroup(name) 12131142Sedward register char name[]; 1221250Skas { 1231250Skas register struct grouphead *gh; 1241250Skas 12531142Sedward for (gh = groups[hash(name)]; gh != NOGRP; gh = gh->g_link) 12631142Sedward if (*gh->g_name == *name && equal(gh->g_name, name)) 1271250Skas return(gh); 1281250Skas return(NOGRP); 1291250Skas } 1301250Skas 1311250Skas /* 1321250Skas * Print a group out on stdout 1331250Skas */ 1341250Skas 1351250Skas printgroup(name) 1361250Skas char name[]; 1371250Skas { 1381250Skas register struct grouphead *gh; 1391250Skas register struct group *gp; 1401250Skas 1411250Skas if ((gh = findgroup(name)) == NOGRP) { 1421250Skas printf("\"%s\": not a group\n", name); 1431250Skas return; 1441250Skas } 1451250Skas printf("%s\t", gh->g_name); 1461250Skas for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) 1471250Skas printf(" %s", gp->ge_name); 14831142Sedward putchar('\n'); 1491250Skas } 1501250Skas 1511250Skas /* 1521250Skas * Hash the passed string and return an index into 1531250Skas * the variable or group hash table. 1541250Skas */ 1551250Skas 1561250Skas hash(name) 15731142Sedward register char *name; 1581250Skas { 15931142Sedward register h = 0; 1601250Skas 16131142Sedward while (*name) { 16231142Sedward h <<= 2; 16331142Sedward h += *name++; 16431142Sedward } 16531142Sedward if (h < 0 && (h = -h) < 0) 1664334Skurt h = 0; 16731142Sedward return (h % HSHSIZE); 1681250Skas } 169