1 # 2 3 #include "rcv.h" 4 5 /* 6 * Mail -- a mail program 7 * 8 * Variable handling stuff. 9 */ 10 11 static char *SccsId = "@(#)vars.c 2.3 10/21/82"; 12 13 /* 14 * Assign a value to a variable. 15 */ 16 17 assign(name, value) 18 char name[], value[]; 19 { 20 register struct var *vp; 21 register int h; 22 23 h = hash(name); 24 vp = lookup(name); 25 if (vp == NOVAR) { 26 vp = (struct var *) calloc(sizeof *vp, 1); 27 vp->v_name = vcopy(name); 28 vp->v_link = variables[h]; 29 variables[h] = vp; 30 } 31 else 32 vfree(vp->v_value); 33 vp->v_value = vcopy(value); 34 } 35 36 /* 37 * Free up a variable string. We do not bother to allocate 38 * strings whose value is "" since they are expected to be frequent. 39 * Thus, we cannot free same! 40 */ 41 42 vfree(cp) 43 register char *cp; 44 { 45 if (!equal(cp, "")) 46 cfree(cp); 47 } 48 49 /* 50 * Copy a variable value into permanent (ie, not collected after each 51 * command) space. Do not bother to alloc space for "" 52 */ 53 54 char * 55 vcopy(str) 56 char str[]; 57 { 58 register char *top, *cp, *cp2; 59 60 if (equal(str, "")) 61 return(""); 62 if ((top = calloc(strlen(str)+1, 1)) == NULL) 63 panic ("Out of memory"); 64 cp = top; 65 cp2 = str; 66 while (*cp++ = *cp2++) 67 ; 68 return(top); 69 } 70 71 /* 72 * Get the value of a variable and return it. 73 * Look in the environment if its not available locally. 74 */ 75 76 char * 77 value(name) 78 char name[]; 79 { 80 register struct var *vp; 81 82 if ((vp = lookup(name)) == NOVAR) 83 return(getenv(name)); 84 return(vp->v_value); 85 } 86 87 /* 88 * Locate a variable and return its variable 89 * node. 90 */ 91 92 struct var * 93 lookup(name) 94 char name[]; 95 { 96 register struct var *vp; 97 register int h; 98 99 h = hash(name); 100 for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) 101 if (equal(vp->v_name, name)) 102 return(vp); 103 return(NOVAR); 104 } 105 106 /* 107 * Locate a group name and return it. 108 */ 109 110 struct grouphead * 111 findgroup(name) 112 char name[]; 113 { 114 register struct grouphead *gh; 115 register int h; 116 117 h = hash(name); 118 for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) 119 if (equal(gh->g_name, name)) 120 return(gh); 121 return(NOGRP); 122 } 123 124 /* 125 * Print a group out on stdout 126 */ 127 128 printgroup(name) 129 char name[]; 130 { 131 register struct grouphead *gh; 132 register struct group *gp; 133 134 if ((gh = findgroup(name)) == NOGRP) { 135 printf("\"%s\": not a group\n", name); 136 return; 137 } 138 printf("%s\t", gh->g_name); 139 for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) 140 printf(" %s", gp->ge_name); 141 printf("\n"); 142 } 143 144 /* 145 * Hash the passed string and return an index into 146 * the variable or group hash table. 147 */ 148 149 hash(name) 150 char name[]; 151 { 152 register int h; 153 register char *cp; 154 155 for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) 156 ; 157 if (h < 0) 158 h = -h; 159 if (h < 0) 160 h = 0; 161 return(h % HSHSIZE); 162 } 163