1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 /* 27 * Copyright 2002 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * University Copyright- Copyright (c) 1982, 1986, 1988 33 * The Regents of the University of California 34 * All Rights Reserved 35 * 36 * University Acknowledgment- Portions of this document are derived from 37 * software developed by the University of California, Berkeley, and its 38 * contributors. 39 */ 40 41 #include "rcv.h" 42 #include <locale.h> 43 44 /* 45 * mailx -- a modified version of a University of California at Berkeley 46 * mail program 47 * 48 * Variable handling stuff. 49 */ 50 51 static struct var *lookup(char name[]); 52 53 /* 54 * Assign a value to a variable. 55 */ 56 void 57 assign(char name[], char value[]) 58 { 59 register struct var *vp; 60 register int h; 61 62 if (name[0]=='-') 63 deassign(name+1); 64 else if (name[0]=='n' && name[1]=='o') 65 deassign(name+2); 66 else { 67 h = hash(name); 68 vp = lookup(name); 69 if (vp == NOVAR) { 70 if ((vp = (struct var *) 71 calloc(sizeof (*vp), 1)) == NULL) 72 panic("Out of memory"); 73 vp->v_name = vcopy(name); 74 vp->v_link = variables[h]; 75 variables[h] = vp; 76 } else 77 vfree(vp->v_value); 78 vp->v_value = vcopy(value); 79 /* 80 * for efficiency, intercept certain assignments here 81 */ 82 if (strcmp(name, "prompt")==0) 83 prompt = vp->v_value; 84 else if (strcmp(name, "debug")==0) 85 debug = 1; 86 if (debug) fprintf(stderr, "assign(%s)=%s\n", vp->v_name, vp->v_value); 87 } 88 } 89 90 int 91 deassign(register char *s) 92 { 93 register struct var *vp, *vp2; 94 register int h; 95 96 if ((vp2 = lookup(s)) == NOVAR) { 97 if (!sourcing) { 98 printf(gettext("\"%s\": undefined variable\n"), s); 99 return(1); 100 } 101 return(0); 102 } 103 if (debug) fprintf(stderr, "deassign(%s)\n", s); 104 if (strcmp(s, "prompt")==0) 105 prompt = NOSTR; 106 else if (strcmp(s, "debug")==0) 107 debug = 0; 108 h = hash(s); 109 if (vp2 == variables[h]) { 110 variables[h] = variables[h]->v_link; 111 vfree(vp2->v_name); 112 vfree(vp2->v_value); 113 free(vp2); 114 return(0); 115 } 116 for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link) 117 ; 118 vp->v_link = vp2->v_link; 119 vfree(vp2->v_name); 120 vfree(vp2->v_value); 121 free(vp2); 122 return(0); 123 } 124 125 /* 126 * Free up a variable string. We do not bother to allocate 127 * strings whose value is "" since they are expected to be frequent. 128 * Thus, we cannot free same! 129 */ 130 void 131 vfree(register char *cp) 132 { 133 if (!equal(cp, "")) 134 free(cp); 135 } 136 137 /* 138 * Copy a variable value into permanent (ie, not collected after each 139 * command) space. Do not bother to alloc space for "" 140 */ 141 142 char * 143 vcopy(char str[]) 144 { 145 register char *top, *cp, *cp2; 146 147 if (equal(str, "")) 148 return(""); 149 if ((top = (char *)calloc(strlen(str)+1, 1)) == NULL) 150 panic("Out of memory"); 151 cp = top; 152 cp2 = str; 153 while (*cp++ = *cp2++) 154 ; 155 return(top); 156 } 157 158 /* 159 * Get the value of a variable and return it. 160 * Look in the environment if its not available locally. 161 */ 162 163 char * 164 value(char name[]) 165 { 166 register struct var *vp; 167 register char *cp; 168 169 if ((vp = lookup(name)) == NOVAR) 170 cp = getenv(name); 171 else 172 cp = vp->v_value; 173 if (debug) fprintf(stderr, "value(%s)=%s\n", name, (cp)?cp:""); 174 return(cp); 175 } 176 177 /* 178 * Locate a variable and return its variable 179 * node. 180 */ 181 182 static struct var * 183 lookup(char name[]) 184 { 185 register struct var *vp; 186 register int h; 187 188 h = hash(name); 189 for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) 190 if (equal(vp->v_name, name)) 191 return(vp); 192 return(NOVAR); 193 } 194 195 /* 196 * Locate a group name and return it. 197 */ 198 199 struct grouphead * 200 findgroup(char name[]) 201 { 202 register struct grouphead *gh; 203 register int h; 204 205 h = hash(name); 206 for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) 207 if (equal(gh->g_name, name)) 208 return(gh); 209 return(NOGRP); 210 } 211 212 /* 213 * Print a group out on stdout 214 */ 215 void 216 printgroup(char name[]) 217 { 218 register struct grouphead *gh; 219 register struct mgroup *gp; 220 221 if ((gh = findgroup(name)) == NOGRP) { 222 printf(gettext("\"%s\": not a group\n"), name); 223 return; 224 } 225 printf("%s\t", gh->g_name); 226 for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) 227 printf(" %s", gp->ge_name); 228 printf("\n"); 229 } 230 231 /* 232 * Hash the passed string and return an index into 233 * the variable or group hash table. 234 */ 235 236 int 237 hash(char name[]) 238 { 239 register unsigned h; 240 register char *cp; 241 242 for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) 243 ; 244 return(h % HSHSIZE); 245 } 246