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