1 # include <stdio.h> 2 # include <pwd.h> 3 # include <sys/types.h> 4 # include <sys/stat.h> 5 # include <sysexits.h> 6 # include "useful.h" 7 # include <ctype.h> 8 9 static char SccsId[] = "@(#)util.c 3.12.1.1 11/21/81"; 10 11 /* 12 ** STRIPQUOTES -- Strip quotes & quote bits from a string. 13 ** 14 ** Runs through a string and strips off unquoted quote 15 ** characters and quote bits. This is done in place. 16 ** 17 ** Parameters: 18 ** s -- the string to strip. 19 ** qf -- if set, remove actual `` " '' characters 20 ** as well as the quote bits. 21 ** 22 ** Returns: 23 ** none. 24 ** 25 ** Side Effects: 26 ** none. 27 ** 28 ** Called By: 29 ** deliver 30 */ 31 32 stripquotes(s, qf) 33 char *s; 34 bool qf; 35 { 36 register char *p; 37 register char *q; 38 register char c; 39 40 if (s == NULL) 41 return; 42 43 for (p = q = s; (c = *p++) != '\0'; ) 44 { 45 if (c != '"' || !qf) 46 *q++ = c & 0177; 47 } 48 *q = '\0'; 49 } 50 /* 51 ** CAPITALIZE -- return a copy of a string, properly capitalized. 52 ** 53 ** Parameters: 54 ** s -- the string to capitalize. 55 ** 56 ** Returns: 57 ** a pointer to a properly capitalized string. 58 ** 59 ** Side Effects: 60 ** none. 61 */ 62 63 char * 64 capitalize(s) 65 register char *s; 66 { 67 static char buf[50]; 68 register char *p; 69 70 p = buf; 71 72 for (;;) 73 { 74 while (!isalpha(*s) && *s != '\0') 75 *p++ = *s++; 76 if (*s == '\0') 77 break; 78 *p++ = toupper(*s++); 79 while (isalpha(*s)) 80 *p++ = *s++; 81 } 82 83 *p = '\0'; 84 return (buf); 85 } 86 /* 87 ** XALLOC -- Allocate memory and bitch wildly on failure. 88 ** 89 ** THIS IS A CLUDGE. This should be made to give a proper 90 ** error -- but after all, what can we do? 91 ** 92 ** Parameters: 93 ** sz -- size of area to allocate. 94 ** 95 ** Returns: 96 ** pointer to data region. 97 ** 98 ** Side Effects: 99 ** Memory is allocated. 100 */ 101 102 char * 103 xalloc(sz) 104 register unsigned int sz; 105 { 106 register char *p; 107 108 p = malloc(sz); 109 if (p == NULL) 110 { 111 syserr("Out of memory!!"); 112 exit(EX_UNAVAILABLE); 113 } 114 return (p); 115 } 116 /* 117 ** NEWSTR -- make copy of string. 118 ** 119 ** Space is allocated for it using xalloc. 120 ** 121 ** Parameters: 122 ** string to copy. 123 ** 124 ** Returns: 125 ** pointer to new string. 126 ** 127 ** Side Effects: 128 ** none. 129 */ 130 131 char * 132 newstr(s) 133 register char *s; 134 { 135 register char *p; 136 137 p = xalloc((unsigned) (strlen(s) + 1)); 138 strcpy(p, s); 139 return (p); 140 } 141 /* 142 ** COPYPLIST -- copy list of pointers. 143 ** 144 ** This routine is the equivalent of newstr for lists of 145 ** pointers. 146 ** 147 ** Parameters: 148 ** list -- list of pointers to copy. 149 ** Must be NULL terminated. 150 ** copycont -- if TRUE, copy the contents of the vector 151 ** (which must be a string) also. 152 ** 153 ** Returns: 154 ** a copy of 'list'. 155 ** 156 ** Side Effects: 157 ** none. 158 */ 159 160 char ** 161 copyplist(list, copycont) 162 char **list; 163 bool copycont; 164 { 165 register char **vp; 166 register char **newvp; 167 168 for (vp = list; *vp != NULL; vp++) 169 continue; 170 171 vp++; 172 173 newvp = (char **) xalloc((unsigned) (vp - list) * sizeof *vp); 174 bmove((char *) list, (char *) newvp, (vp - list) * sizeof *vp); 175 176 if (copycont) 177 { 178 for (vp = newvp; *vp != NULL; vp++) 179 *vp = newstr(*vp); 180 } 181 182 return (newvp); 183 } 184 /* 185 ** PRINTAV -- print argument vector. 186 ** 187 ** Parameters: 188 ** av -- argument vector. 189 ** 190 ** Returns: 191 ** none. 192 ** 193 ** Side Effects: 194 ** prints av. 195 */ 196 197 # ifdef DEBUG 198 printav(av) 199 register char **av; 200 { 201 while (*av != NULL) 202 { 203 printf("\t%08x=", *av); 204 xputs(*av++); 205 putchar('\n'); 206 } 207 } 208 # endif DEBUG 209 /* 210 ** LOWER -- turn letter into lower case. 211 ** 212 ** Parameters: 213 ** c -- character to turn into lower case. 214 ** 215 ** Returns: 216 ** c, in lower case. 217 ** 218 ** Side Effects: 219 ** none. 220 */ 221 222 char 223 lower(c) 224 register char c; 225 { 226 if (isascii(c) && isupper(c)) 227 c = c - 'A' + 'a'; 228 return (c); 229 } 230 /* 231 ** XPUTS -- put string doing control escapes. 232 ** 233 ** Parameters: 234 ** s -- string to put. 235 ** 236 ** Returns: 237 ** none. 238 ** 239 ** Side Effects: 240 ** output to stdout 241 */ 242 243 # ifdef DEBUG 244 xputs(s) 245 register char *s; 246 { 247 register char c; 248 249 while ((c = *s++) != '\0') 250 { 251 if (!isascii(c)) 252 { 253 putchar('\\'); 254 c &= 0177; 255 } 256 if (iscntrl(c)) 257 { 258 putchar('^'); 259 c |= 0100; 260 } 261 putchar(c); 262 } 263 (void) fflush(stdout); 264 } 265 # endif DEBUG 266 /* 267 ** MAKELOWER -- Translate a line into lower case 268 ** 269 ** Parameters: 270 ** p -- the string to translate. If NULL, return is 271 ** immediate. 272 ** 273 ** Returns: 274 ** none. 275 ** 276 ** Side Effects: 277 ** String pointed to by p is translated to lower case. 278 ** 279 ** Called By: 280 ** parse 281 */ 282 283 makelower(p) 284 register char *p; 285 { 286 register char c; 287 288 if (p == NULL) 289 return; 290 for (; (c = *p) != '\0'; p++) 291 if (isascii(c) && isupper(c)) 292 *p = c - 'A' + 'a'; 293 } 294 /* 295 ** SAMEWORD -- return TRUE if the words are the same 296 ** 297 ** Ignores case. 298 ** 299 ** Parameters: 300 ** a, b -- the words to compare. 301 ** 302 ** Returns: 303 ** TRUE if a & b match exactly (modulo case) 304 ** FALSE otherwise. 305 ** 306 ** Side Effects: 307 ** none. 308 */ 309 310 bool 311 sameword(a, b) 312 register char *a, *b; 313 { 314 while (lower(*a) == lower(*b)) 315 { 316 if (*a == '\0') 317 return (TRUE); 318 a++; 319 b++; 320 } 321 return (FALSE); 322 } 323 /* 324 ** CLEAR -- clear a block of memory 325 ** 326 ** Parameters: 327 ** p -- location to clear. 328 ** l -- number of bytes to clear. 329 ** 330 ** Returns: 331 ** none. 332 ** 333 ** Side Effects: 334 ** none. 335 */ 336 337 clear(p, l) 338 register char *p; 339 register int l; 340 { 341 while (l-- > 0) 342 *p++ = 0; 343 } 344 /* 345 ** FULLNAME -- extract full name from a passwd file entry. 346 ** 347 ** Parameters: 348 ** pw -- password entry to start from. 349 ** buf -- buffer to store result in. 350 ** 351 ** Returns: 352 ** none. 353 ** 354 ** Side Effects: 355 ** none. 356 */ 357 358 fullname(pw, buf) 359 register struct passwd *pw; 360 char *buf; 361 { 362 register char *bp = buf; 363 register char *p = pw->pw_gecos; 364 365 if (*p == '*') 366 p++; 367 while (*p != '\0' && *p != ',' && *p != ';') 368 { 369 if (*p == '&') 370 { 371 (void) strcpy(bp, pw->pw_name); 372 *bp = toupper(*bp); 373 while (*bp != '\0') 374 bp++; 375 p++; 376 } 377 else 378 *bp++ = *p++; 379 } 380 *bp = '\0'; 381 } 382 /* 383 ** SAFEFILE -- return true if a file exists and is safe for a user. 384 ** 385 ** Parameters: 386 ** fn -- filename to check. 387 ** uid -- uid to compare against. 388 ** mode -- mode bits that must match. 389 ** 390 ** Returns: 391 ** TRUE if fn exists, is owned by uid, and matches mode. 392 ** FALSE otherwise. 393 ** 394 ** Side Effects: 395 ** none. 396 */ 397 398 bool 399 safefile(fn, uid, mode) 400 char *fn; 401 int uid; 402 int mode; 403 { 404 struct stat stbuf; 405 406 if (stat(fn, &stbuf) >= 0 && stbuf.st_uid == uid && 407 (stbuf.st_mode & mode) == mode) 408 return (TRUE); 409 return (FALSE); 410 } 411 /* 412 ** FIXCRLF -- fix <CR><LF> in line. 413 ** 414 ** Looks for the <CR><LF> combination and turns it into the 415 ** UNIX canonical <NL> character. It only takes one line, 416 ** i.e., it is assumed that the first <NL> found is the end 417 ** of the line. 418 ** 419 ** Parameters: 420 ** line -- the line to fix. 421 ** stripnl -- if true, strip the newline also. 422 ** 423 ** Returns: 424 ** none. 425 ** 426 ** Side Effects: 427 ** line is changed in place. 428 */ 429 430 fixcrlf(line, stripnl) 431 char *line; 432 bool stripnl; 433 { 434 register char *p; 435 436 p = index(line, '\n'); 437 if (p == NULL) 438 return; 439 if (p[-1] == '\r') 440 p--; 441 if (!stripnl) 442 *p++ = '\n'; 443 *p = '\0'; 444 } 445 /* 446 ** SYSLOG -- fake entry to fool lint 447 */ 448 449 # ifdef LOG 450 # ifdef lint 451 452 /*VARARGS2*/ 453 syslog(pri, fmt, args) 454 int pri; 455 char *fmt; 456 { 457 pri = *fmt; 458 args = pri; 459 pri = args; 460 } 461 462 # endif lint 463 # endif LOG 464