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 #pragma ident "%Z%%M% %I% %E% SMI" 42 43 #include "rcv.h" 44 #include <locale.h> 45 46 /* 47 * mailx -- a modified version of a University of California at Berkeley 48 * mail program 49 * 50 * Variable handling stuff. 51 */ 52 53 static struct var *lookup(char name[]); 54 55 /* 56 * Assign a value to a variable. 57 */ 58 void 59 assign(char name[], char value[]) 60 { 61 register struct var *vp; 62 register int h; 63 64 if (name[0]=='-') 65 deassign(name+1); 66 else if (name[0]=='n' && name[1]=='o') 67 deassign(name+2); 68 else { 69 h = hash(name); 70 vp = lookup(name); 71 if (vp == NOVAR) { 72 if ((vp = (struct var *) 73 calloc(sizeof (*vp), 1)) == NULL) 74 panic("Out of memory"); 75 vp->v_name = vcopy(name); 76 vp->v_link = variables[h]; 77 variables[h] = vp; 78 } else 79 vfree(vp->v_value); 80 vp->v_value = vcopy(value); 81 /* 82 * for efficiency, intercept certain assignments here 83 */ 84 if (strcmp(name, "prompt")==0) 85 prompt = vp->v_value; 86 else if (strcmp(name, "debug")==0) 87 debug = 1; 88 if (debug) fprintf(stderr, "assign(%s)=%s\n", vp->v_name, vp->v_value); 89 } 90 } 91 92 int 93 deassign(register char *s) 94 { 95 register struct var *vp, *vp2; 96 register int h; 97 98 if ((vp2 = lookup(s)) == NOVAR) { 99 if (!sourcing) { 100 printf(gettext("\"%s\": undefined variable\n"), s); 101 return(1); 102 } 103 return(0); 104 } 105 if (debug) fprintf(stderr, "deassign(%s)\n", s); 106 if (strcmp(s, "prompt")==0) 107 prompt = NOSTR; 108 else if (strcmp(s, "debug")==0) 109 debug = 0; 110 h = hash(s); 111 if (vp2 == variables[h]) { 112 variables[h] = variables[h]->v_link; 113 vfree(vp2->v_name); 114 vfree(vp2->v_value); 115 free(vp2); 116 return(0); 117 } 118 for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link) 119 ; 120 vp->v_link = vp2->v_link; 121 vfree(vp2->v_name); 122 vfree(vp2->v_value); 123 free(vp2); 124 return(0); 125 } 126 127 /* 128 * Free up a variable string. We do not bother to allocate 129 * strings whose value is "" since they are expected to be frequent. 130 * Thus, we cannot free same! 131 */ 132 void 133 vfree(register char *cp) 134 { 135 if (!equal(cp, "")) 136 free(cp); 137 } 138 139 /* 140 * Copy a variable value into permanent (ie, not collected after each 141 * command) space. Do not bother to alloc space for "" 142 */ 143 144 char * 145 vcopy(char str[]) 146 { 147 register char *top, *cp, *cp2; 148 149 if (equal(str, "")) 150 return(""); 151 if ((top = (char *)calloc(strlen(str)+1, 1)) == NULL) 152 panic("Out of memory"); 153 cp = top; 154 cp2 = str; 155 while (*cp++ = *cp2++) 156 ; 157 return(top); 158 } 159 160 /* 161 * Get the value of a variable and return it. 162 * Look in the environment if its not available locally. 163 */ 164 165 char * 166 value(char name[]) 167 { 168 register struct var *vp; 169 register char *cp; 170 171 if ((vp = lookup(name)) == NOVAR) 172 cp = getenv(name); 173 else 174 cp = vp->v_value; 175 if (debug) fprintf(stderr, "value(%s)=%s\n", name, (cp)?cp:""); 176 return(cp); 177 } 178 179 /* 180 * Locate a variable and return its variable 181 * node. 182 */ 183 184 static struct var * 185 lookup(char name[]) 186 { 187 register struct var *vp; 188 register int h; 189 190 h = hash(name); 191 for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) 192 if (equal(vp->v_name, name)) 193 return(vp); 194 return(NOVAR); 195 } 196 197 /* 198 * Locate a group name and return it. 199 */ 200 201 struct grouphead * 202 findgroup(char name[]) 203 { 204 register struct grouphead *gh; 205 register int h; 206 207 h = hash(name); 208 for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) 209 if (equal(gh->g_name, name)) 210 return(gh); 211 return(NOGRP); 212 } 213 214 /* 215 * Print a group out on stdout 216 */ 217 void 218 printgroup(char name[]) 219 { 220 register struct grouphead *gh; 221 register struct mgroup *gp; 222 223 if ((gh = findgroup(name)) == NOGRP) { 224 printf(gettext("\"%s\": not a group\n"), name); 225 return; 226 } 227 printf("%s\t", gh->g_name); 228 for (gp = gh->g_list; gp != NOGE; gp = gp->ge_link) 229 printf(" %s", gp->ge_name); 230 printf("\n"); 231 } 232 233 /* 234 * Hash the passed string and return an index into 235 * the variable or group hash table. 236 */ 237 238 int 239 hash(char name[]) 240 { 241 register unsigned h; 242 register char *cp; 243 244 for (cp = name, h = 0; *cp; h = (h << 2) + *cp++) 245 ; 246 return(h % HSHSIZE); 247 } 248