Print this page
10131 fmtmsg is bitwise, not streetwise
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/fmtmsg/main.c
+++ new/usr/src/cmd/fmtmsg/main.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
21 21 */
22 22
23 23 /*
24 24 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
25 25 * Use is subject to license terms.
26 26 */
27 27
28 28 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
29 29 /* All Rights Reserved */
30 30
31 -#pragma ident "%Z%%M% %I% %E% SMI"
31 +/*
32 + * Copyright (c) 2018, Joyent, Inc.
33 + */
32 34
33 -
34 35 /*
35 36 * fmtmsg.c
36 37 *
37 38 * Contains:
38 39 * fmtmsg Command that writes a message in the standard
39 40 * message format. May in future make these
40 41 * messages available for logging.
41 42 */
42 43
43 44
44 45 /*
45 46 * Header files used:
46 47 * <stdio.h> C Standard I/O function definitions
47 48 * <string.h> C string-handling definitions
48 49 * <errno.h> UNIX error-code "errno" definitions
49 50 * <fmtmsg.h> Standard Message definitions
50 51 */
51 52
52 53 #include <stdio.h>
53 54 #include <string.h>
54 55 #include <errno.h>
55 56 #include <fmtmsg.h>
56 57
57 58
58 59 /*
59 60 * Externals referenced:
60 61 * strtol Function that converts char strings to "long"
61 62 * fmtmsg Function that writes a message in standard format
62 63 * getenv Function that extracts an environment variable's
63 64 * value
64 65 * malloc Allocate memory from the memory pool
65 66 * free Frees allocated memory
66 67 * getopt Function that extracts arguments from the command-
67 68 * optarg Points to option's argument (from getopt())
68 69 * optind Option's argument index (from getopt())
69 70 * opterr FLAG, write error if invalid option (for getopt())
70 71 * line.
71 72 * exit Exits the command
72 73 */
73 74
74 75 extern long strtol();
75 76 extern int fmtmsg();
76 77 extern char *getenv();
77 78 extern void *malloc();
78 79 extern void free();
79 80 extern int getopt();
80 81 extern char *optarg;
81 82 extern int optind;
82 83 extern int opterr;
83 84 extern void exit();
84 85
85 86 /*
86 87 * Local definitions
87 88 */
88 89
89 90 /*
90 91 * Local constants
91 92 */
92 93
93 94
94 95 /*
95 96 * Boolean constants
96 97 * TRUE Boolean value for "true" (any bits on)
97 98 * FALSE Boolean value for "false" (all bits off)
98 99 */
99 100
100 101 #ifndef FALSE
101 102 #define FALSE (0)
102 103 #endif
103 104
104 105 #ifndef TRUE
105 106 #define TRUE (1)
106 107 #endif
107 108
108 109
109 110 #define CLASS (MM_PRINT|MM_SOFT|MM_NRECOV|MM_UTIL)
110 111 #define BIGUSAGE "fmtmsg [-a action] [-c class] [-l label] [-s severity] [-t tag]\n [-u subclass[,subclass[,...]]] [text]\n"
111 112
112 113
113 114 /*
114 115 * Local data-type definitions
115 116 */
116 117
117 118 /*
118 119 * Structure used for tables containing keywords and integer values
119 120 */
120 121
121 122 struct sev_info {
122 123 char *keyword;
123 124 int value;
124 125 };
125 126
126 127
127 128 /*
128 129 * Structure used for tables containing keywords, long values
129 130 */
130 131
131 132 struct class_info {
132 133 char *keyword;
133 134 long value;
134 135 long conflict;
135 136 };
136 137
137 138
138 139 /*
139 140 * Severity string structure
140 141 *
141 142 * struct sevstr
142 143 * sevvalue Value of the severity-level being defined
143 144 * sevkywd Keyword identifying the severity
144 145 * sevprptr Pointer to the string associated with the value
145 146 * sevnext Pointer to the next value in the list.
146 147 */
147 148
148 149 struct sevstr {
149 150 int sevvalue;
150 151 char *sevkywd;
151 152 char *sevprstr;
152 153 struct sevstr *sevnext;
153 154 };
154 155
155 156
156 157 /*
157 158 * Local static data
158 159 */
159 160
160 161
161 162 /*
162 163 * Table contains the keywords for the classes of a message
163 164 */
164 165
165 166 static struct class_info classes[] = {
166 167
167 168 {"hard", MM_HARD, MM_SOFT|MM_FIRM}, /* hardware */
168 169 {"soft", MM_SOFT, MM_HARD|MM_FIRM}, /* software */
169 170 {"firm", MM_FIRM, MM_SOFT|MM_FIRM}, /* firmware */
170 171
171 172 {(char *) NULL, 0L, 0L} /* end of list */
172 173
173 174 };
174 175
175 176
176 177 /*
177 178 * Table contains the keywords for the subclasses for a message
178 179 */
179 180
180 181 static struct class_info subclasses[] = {
181 182
182 183 {"appl", MM_APPL, MM_UTIL|MM_OPSYS}, /* Application */
183 184 {"util", MM_UTIL, MM_APPL|MM_OPSYS}, /* Utility */
184 185 {"opsys", MM_OPSYS, MM_APPL|MM_UTIL}, /* Operating System */
185 186
186 187 {"recov", MM_RECOVER, MM_NRECOV}, /* Recoverable */
187 188 {"nrecov", MM_NRECOV, MM_RECOVER}, /* Non-recoverable */
188 189
189 190 {"print", MM_PRINT, 0L}, /* Write message to stderr */
190 191 {"console", MM_CONSOLE, 0L}, /* Write message on /dev/console */
191 192 {(char *) NULL, 0L, 0L} /* End of list */
192 193
193 194 };
194 195
195 196
196 197 /*
197 198 * Table contains the keywords for the standard severities of a message.
198 199 * User may supply more through the SEV_LEVEL environment variable.
199 200 */
200 201
201 202 static struct sev_info severities[] = {
202 203 {"halt", MM_HALT}, /* halt */
203 204 {"error", MM_ERROR}, /* error */
204 205 {"warn", MM_WARNING}, /* warn */
205 206 {"info", MM_INFO}, /* info */
206 207 {(char *) NULL, 0} /* end of list */
207 208 };
208 209
209 210
210 211 /*
211 212 * Buffers used by the command
212 213 */
213 214
214 215 static char labelbuf[128]; /* Buf for message label */
215 216 static char msgbuf[256]; /* Buf for messages */
216 217
217 218 /*
218 219 * static char *exttok(str, delims)
219 220 * char *str
220 221 * char *delims
221 222 *
222 223 * This function examines the string pointed to by "str", looking
223 224 * for the first occurrence of any of the characters in the string
224 225 * whose address is "delims". It returns the address of that
225 226 * character or (char *) NULL if there was nothing to search.
226 227 *
227 228 * Arguments:
228 229 * str Address of the string to search
229 230 * delims Address of the string containing delimiters
230 231 *
231 232 * Returns: char *
232 233 * Returns the address of the first occurrence of any of the characters
233 234 * in "delim" in the string "str" (incl '\0'). If there was nothing
234 235 * to search, the function returns (char *) NULL.
235 236 *
236 237 * Notes:
237 238 * - This function is needed because strtok() can't be used inside a
238 239 * function. Besides, strtok() is destructive in the string, which
239 240 * is undesirable in many circumstances.
240 241 * - This function understands escaped delimiters as non-delimiters.
241 242 * Delimiters are escaped by preceding them with '\' characters.
242 243 * The '\' character also must be escaped.
243 244 */
244 245
245 246 static char *
246 247 exttok(tok, delims)
247 248 char *tok; /* Ptr to the token we're parsing */
248 249 char *delims; /* Ptr to string with delimiters */
249 250 {
250 251
251 252 /* Automatic Data */
252 253 char *tokend; /* Ptr to the end of the token */
253 254 char *p, *q; /* Temp pointers */
254 255
255 256
256 257 /* Algorithm:
257 258 * 1. Get the starting address (new string or where we
258 259 * left off). If nothing to search, return (char *) NULL
259 260 * 2. Find the end of the string
260 261 * 3. Look for the first unescaped delimiter closest to the
261 262 * beginning of the string
262 263 * 4. Remember where we left off
263 264 * 5. Return a pointer to the delimiter we found
264 265 */
265 266
266 267 /* Begin at the beginning, if any */
267 268 if (tok == (char *) NULL) {
268 269 return ((char *) NULL);
269 270 }
270 271
271 272 /* Find end of the token string */
272 273 tokend = tok + strlen(tok);
273 274
274 275 /* Look for the 1st occurrence of any delimiter */
275 276 for (p = delims ; *p != '\0' ; p++) {
276 277 for (q = strchr(tok, *p) ; q && (q != tok) && (*(q-1) == '\\') ; q = strchr(q+1, *p)) ;
277 278 if (q && (q < tokend)) tokend = q;
278 279 }
279 280
280 281 /* Done */
281 282 return(tokend);
282 283 }
283 284
284 285 /*
285 286 * char *noesc(str)
286 287 *
287 288 * This function squeezes out all of the escaped character sequences
288 289 * from the string <str>. It returns a pointer to that string.
289 290 *
290 291 * Arguments:
291 292 * str char *
292 293 * The string that is to have its escaped characters removed.
293 294 *
294 295 * Returns: char *
295 296 * This function returns its argument <str> always.
296 297 *
297 298 * Notes:
298 299 * This function potentially modifies the string it is given.
299 300 */
300 301
301 302 char *
302 303 noesc(str)
303 304 char *str; /* String to remove escaped characters from */
304 305 {
305 306 char *p; /* Temp string pointer */
306 307 char *q; /* Temp string pointer */
307 308
308 309 /* Look for an escaped character */
309 310 p = str;
310 311 while (*p && (*p != '\\')) p++;
311 312
312 313
313 314 /*
314 315 * If there was at least one, squeeze them out
315 316 * Otherwise, don't touch the argument string
316 317 */
317 318
318 319 if (*p) {
319 320 q = p++;
320 321 while (*q++ = *p++) if (*p == '\\') p++;
321 322 }
322 323
323 324 /* Finished. Return our argument */
324 325 return(str);
325 326 }
326 327
327 328 /*
328 329 * struct sevstr *getauxsevs(ptr)
329 330 *
330 331 * Parses a string that is in the format of the severity definitions.
331 332 * Returns a pointer to a (malloc'd) structure that contains the
332 333 * definition, or (struct sevstr *) NULL if none was parsed.
333 334 *
334 335 * Arguments:
335 336 * ptr char *
336 337 * References the string from which data is to be extracted.
337 338 * If (char *) NULL, continue where we left off. Otherwise,
338 339 * start with the string referenced by ptr.
339 340 *
340 341 * Returns: struct sevstr *
341 342 * A pointer to a malloc'd structure containing the severity definition
342 343 * parsed from string, or (struct sevstr *) NULL if none.
343 344 *
344 345 * Notes:
345 346 * - This function is destructive to the string referenced by its argument.
346 347 */
347 348
348 349
349 350 /* Static data */
350 351 static char *leftoff = (char *) NULL;
351 352
352 353 static struct sevstr *
353 354 getauxsevs(ptr)
354 355 char *ptr;
355 356 {
356 357
357 358 /* Automatic data */
358 359 char *current; /* Ptr to current sev def'n */
359 360 char *tokend; /* Ptr to end of current sev def'n */
360 361 char *kywd; /* Ptr to extracted kywd */
361 362 char *valstr; /* Ptr to extracted sev value */
362 363 char *prstr; /* Ptr to extracted print str */
363 364 char *p; /* Temp pointer */
364 365 int val; /* Converted severity value */
365 366 int done; /* Flag, sev def'n found and ok? */
366 367 struct sevstr *rtnval; /* Value to return */
367 368
368 369
369 370 /* Start anew or start where we left off? */
370 371 current = (ptr == (char *) NULL) ? leftoff : ptr;
371 372
372 373
373 374 /* If nothing to parse, return (char *) NULL */
374 375 if (current == (char *) NULL) {
375 376 return ((struct sevstr *) NULL);
376 377 }
377 378
378 379
379 380 /*
380 381 * Look through the string "current" for a token of the form
381 382 * <kywd>,<sev>,<printstring> delimited by ':' or '\0'
382 383 */
383 384
384 385 /* Loop initializations */
385 386 done = FALSE;
386 387 rtnval = (struct sevstr *) NULL;
387 388 while (!done) {
388 389
389 390 /* Eat leading junk */
390 391 while (*(tokend = exttok(current, ":,")) == ':') {
391 392 current = tokend + 1;
392 393 }
393 394
394 395 /* If we've found a <kywd>,... */
395 396 if (*tokend == ',') {
396 397 kywd = current;
397 398 *tokend = '\0';
398 399
399 400 /* Look for <kywd>,<sev>,... */
400 401 current = tokend + 1;
401 402 if (*(tokend = exttok(current, ":,")) == ',') {
402 403 valstr = current;
403 404 *tokend = '\0';
404 405 current = tokend+1;
405 406 prstr = current;
406 407
407 408 /* Make sure <sev> > 4 */
408 409 val = (int) strtol(noesc(valstr), &p, 0);
409 410 if ((val > 4) && (p == tokend)) {
410 411
411 412 /*
412 413 * Found <kywd>,<sev>,<printstring>.
413 414 * remember where we left off
414 415 */
415 416
416 417 if (*(tokend = exttok(current, ":")) == ':') {
417 418 *tokend = '\0';
418 419 leftoff = tokend + 1;
419 420 } else leftoff = (char *) NULL;
420 421
421 422 /* Alloc structure to contain severity definition */
422 423 if (rtnval = (struct sevstr *) malloc(sizeof(struct sevstr))) {
423 424
424 425 /* Fill in structure */
425 426 rtnval->sevkywd = noesc(kywd);
426 427 rtnval->sevvalue = val;
427 428 rtnval->sevprstr = noesc(prstr);
428 429 rtnval->sevnext = (struct sevstr *) NULL;
429 430 }
430 431
431 432 done = TRUE;
432 433
433 434 } else {
434 435
435 436 /* Invalid severity value, eat thru end of token */
436 437 current = tokend;
437 438 if (*(tokend = exttok(prstr, ":")) == ':')
438 439 current++;
439 440 }
440 441
441 442 } else {
442 443
443 444 /* Invalid severity definition, eat thru end of token */
444 445 current = tokend;
445 446 if (*tokend == ':')
446 447 current++;
447 448 }
448 449
449 450 } else {
450 451
451 452 /* End of string found */
452 453 done = TRUE;
453 454 leftoff = (char *) NULL;
454 455 }
455 456
456 457 } /* while (!done) */
457 458
458 459 /* Finished */
459 460 return(rtnval);
460 461 }
461 462
462 463 /*
463 464 * fmtmsg [-a action] [-c classification] [-l label] [-s severity] [-t tag]
464 465 * [-u subclass[,subclass[,...]]] [text]
465 466 *
466 467 * Function:
467 468 * Writes a message in the standard format. Typically used by shell
468 469 * scripts to write error messages to the user.
469 470 *
470 471 * Arguments:
471 472 * text String that is the text of the message
472 473 *
473 474 * Options:
474 475 * -a action String that describes user action to take to
475 476 * correct the situation
476 477 * -c classification Keyword that identifies the type of the message
477 478 * -l label String that identifies the source of the message
478 479 * -s severity Keyword that identifies the severity of the message
479 480 * -t tag String that identifies the message (use unclear)
480 481 * -u sub_classes Comma-list of keywords that refines the type of
481 482 * the message
482 483 *
483 484 * Environment Variables Used:
484 485 * MSGVERB Defines the pieces of a message the user expects
485 486 * to see. It is a list of keywords separated by
486 487 * colons (':').
487 488 * SEV_LEVEL Defines a list of auxiliary severity keywords, values,
488 489 * and print-strings. It is a list of fields separated
489 490 * by colons (':'). Each field consists of three
490 491 * elements, keyword, value (in octal, hex, or decimal),
491 492 * and print-string, separated by commas (',').
492 493 *
493 494 * Needs:
494 495 *
495 496 * Open Issues:
496 497 */
497 498
498 499 int
499 500 main(int argc, char **argv)
500 501 {
501 502
502 503 /* Local automatic data */
503 504
504 505 long class; /* Classification (built) */
505 506
506 507 int severity; /* User specified severity */
507 508 int msgrtn; /* Value returned by fmtmsg() */
508 509 int optchar; /* Opt char on cmdline */
509 510 int exitval; /* Value to return */
510 511
511 512 int found; /* FLAG, kywd found yet? */
512 513 int errflg; /* FLAG, error seen in cmd */
513 514 int a_seen; /* FLAG, -a option seen */
514 515 int c_seen; /* FLAG, -c option seen */
515 516 int l_seen; /* FLAG, -l option seen */
516 517 int s_seen; /* FLAG, -s option seen */
517 518 int t_seen; /* FLAG, -t option seen */
518 519 int u_seen; /* FLAG, -u option seen */
519 520 int text_seen; /* FLAG, text seen */
520 521
521 522 char *text; /* Ptr to user's text */
522 523 char *label; /* Ptr to user's label */
523 524 char *tag; /* Ptr to user's tag */
524 525 char *action; /* Ptr to user's action str */
525 526 char *sstr; /* Ptr to -s (severity) arg */
526 527 char *ustr; /* Ptr to -u (subclass) arg */
527 528 char *cstr; /* Ptr to -c (class) arg */
528 529 char *sevstrval; /* Ptr to SEV_LEVEL argument */
529 530 char *sevval; /* Ptr to temp SEV_LEVEL arg */
530 531 char *tokenptr; /* Ptr to current token */
531 532 char *cmdname; /* Ptr to base command name */
532 533 char *p; /* Multipurpose ptr */
533 534
534 535 struct class_info *class_info; /* Ptr to class/subclass info structure */
535 536 struct sev_info *sev_info; /* Ptr to severity info struct */
536 537 struct sevstr *penvsev; /* Ptr to SEV_LEVEL values */
537 538
538 539
539 540
540 541 /*
541 542 * fmtmsg
542 543 */
543 544
544 545
545 546 /* Initializations */
546 547
547 548
548 549 /* Extract the base command name from the command */
549 550 if ((p = strrchr(argv[0], '/')) == (char *) NULL)
550 551 cmdname = argv[0];
551 552 else
552 553 cmdname = p+1;
553 554
554 555 /* Build the label for messages from "fmtmsg" */
555 556 (void) snprintf(labelbuf, sizeof (labelbuf), "UX:%s", cmdname);
556 557
557 558
558 559 /*
559 560 * Extract arguments from the command line
560 561 */
561 562
562 563 /* Initializations */
563 564
564 565 opterr = 0; /* Disable messages from getopt() */
565 566 errflg = FALSE; /* No errors seen yet */
566 567
567 568 a_seen = FALSE; /* No action (-a) text seen yet */
568 569 c_seen = FALSE; /* No classification (-c) seen yet */
569 570 l_seen = FALSE; /* No label (-l) seen yet */
570 571 s_seen = FALSE; /* No severity (-s) seen yet */
571 572 t_seen = FALSE; /* No tag (-t) seen yet */
572 573 u_seen = FALSE; /* No subclass (-u) seen yet */
573 574 text_seen = FALSE; /* No text seen yet */
574 575
575 576
576 577 /*
577 578 * If only the command name was used, write out a usage string to
578 579 * the standard output file.
579 580 */
580 581
581 582 if (argc == 1) {
582 583 (void) fputs(BIGUSAGE, stderr);
583 584 exit(0);
584 585 }
585 586
586 587
587 588 /* Parce command line */
588 589 while (((optchar = getopt(argc, argv, "a:c:l:s:t:u:")) != EOF) &&
589 590 !errflg) {
590 591
591 592 switch(optchar) {
592 593
593 594 case 'a': /* -a actiontext */
594 595 if (!a_seen) {
595 596 action = optarg;
596 597 a_seen = TRUE;
597 598 } else errflg = TRUE;
598 599 break;
599 600
600 601 case 'c': /* -c classification */
601 602 if (!c_seen) {
602 603 cstr = optarg;
603 604 c_seen = TRUE;
604 605 } else errflg = TRUE;
605 606 break;
606 607
607 608 case 'l': /* -l label */
608 609 if (!l_seen) {
609 610 label = optarg;
610 611 l_seen = TRUE;
611 612 } else errflg = TRUE;
612 613 break;
613 614
614 615 case 's': /* -s severity */
615 616 if (!s_seen) {
616 617 sstr = optarg;
617 618 s_seen = TRUE;
618 619 } else errflg = TRUE;
619 620 break;
620 621
621 622 case 't': /* -t tag */
622 623 if (!t_seen) {
623 624 tag = optarg;
624 625 t_seen = TRUE;
625 626 } else errflg = TRUE;
626 627 break;
627 628
628 629 case 'u': /* -u subclasslist */
629 630 if (!u_seen) {
630 631 ustr = optarg;
631 632 u_seen = TRUE;
632 633 } else errflg = TRUE;
633 634 break;
634 635
635 636 case '?': /* -? or unknown option */
636 637 default:
637 638 errflg = TRUE;
638 639 break;
639 640
640 641 } /* esac */
641 642 }
642 643
643 644
644 645 /* Get the text */
645 646 if (!errflg) {
646 647 if (argc == (optind+1)) {
647 648 text = argv[optind];
648 649 text_seen = TRUE;
649 650 }
650 651 else if (argc != optind) {
651 652 errflg = TRUE;
652 653 }
653 654 }
654 655
655 656
656 657 /* Report syntax errors */
657 658 if (errflg) {
658 659 (void) fputs(BIGUSAGE, stderr);
659 660 exit(1);
660 661 }
661 662
662 663
663 664 /*
664 665 * Classification.
665 666 */
666 667
667 668 class = 0L;
668 669 if (c_seen) {
669 670
670 671 /* Search for keyword in list */
671 672 for (class_info = &classes[0] ;
672 673 (class_info->keyword != (char *) NULL) &&
673 674 (strcmp(cstr, class_info->keyword)) ;
674 675 class_info++) ;
675 676
676 677 /* If invalid (keyword unknown), write a message and exit */
677 678 if (class_info->keyword == (char *) NULL) {
678 679 (void) snprintf(msgbuf, sizeof (msgbuf),
679 680 "Invalid class: %s", cstr);
680 681 (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf,
681 682 MM_NULLACT, MM_NULLTAG);
682 683 exit(1);
683 684 }
684 685
685 686 /* Save classification */
686 687 class = class_info->value;
687 688
688 689 }
689 690
690 691
691 692 /*
692 693 * Subclassification.
693 694 */
694 695
695 696 if (u_seen) {
696 697
697 698 errflg = FALSE;
698 699 p = strcpy(malloc((unsigned int) strlen(ustr)+1), ustr);
699 700 if ((tokenptr = strtok(p, ",")) == (char *) NULL) errflg = TRUE;
700 701 else do {
701 702
702 703 /* Got a keyword. Look for it in keyword list */
703 704 for (class_info = subclasses ;
704 705 (class_info->keyword != (char *) NULL) &&
705 706 (strcmp(tokenptr, class_info->keyword) != 0) ;
706 707 class_info++) ;
707 708
708 709 /* If found in list and no conflict, remember in class */
709 710 if ((class_info->keyword != (char *) NULL) && ((class & class_info->conflict) == 0L))
710 711 class |= class_info->value;
711 712 else
712 713 errflg = TRUE;
713 714
714 715 } while (!errflg && ((tokenptr = strtok((char *) NULL, ",")) != (char *) NULL)) ;
715 716
↓ open down ↓ |
672 lines elided |
↑ open up ↑ |
716 717 if (errflg) {
717 718 (void) snprintf(msgbuf, sizeof (msgbuf),
718 719 "Invalid subclass: %s", ustr);
719 720 (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf,
720 721 MM_NULLACT, MM_NULLTAG);
721 722 exit(1);
722 723 }
723 724
724 725 }
725 726
726 - if (!c_seen & !u_seen) class = MM_NULLMC;
727 + if (!c_seen && !u_seen) class = MM_NULLMC;
727 728
728 729
729 730
730 731 /*
731 732 * Severity.
732 733 */
733 734
734 735 if (s_seen) {
735 736
736 737 /* If the severity is specified as a number, use that value */
737 738 severity = strtol(sstr, &p, 10);
738 739 if (*p || (strlen(sstr) == 0)) {
739 740
740 741 /* Look for the standard severities */
741 742 for (sev_info = severities ;
742 743 (sev_info->keyword != (char *) NULL) &&
743 744 (strcmp(sstr, sev_info->keyword)) ;
744 745 sev_info++) ;
745 746
746 747 /*
747 748 * If the "severity" argument is one of the standard keywords,
748 749 * remember it for fmtmsg(). Otherwise, look at the SEV_LEVEL
749 750 * environment variable for severity extensions.
750 751 */
751 752
752 753 /* If the keyword is one of the standard ones, save severity */
753 754 if (sev_info->keyword != (char *) NULL) severity = sev_info->value;
754 755
755 756 else {
756 757
757 758 /*
758 759 * Severity keyword may be one of the extended set, if any.
759 760 */
760 761
761 762 /* Get the value of the SEV_LEVEL environment variable */
762 763 found = FALSE;
763 764 if ((sevstrval = getenv(SEV_LEVEL)) != (char *) NULL) {
764 765 sevval = (char *) malloc((unsigned int) strlen(sevstrval)+1);
765 766 penvsev = getauxsevs(strcpy(sevval, sevstrval));
766 767 if (penvsev != (struct sevstr *) NULL) do {
767 768 if (strcmp(penvsev->sevkywd, sstr) == 0) {
768 769 severity = penvsev->sevvalue;
769 770 found = TRUE;
770 771 }
771 772 else {
772 773 free(penvsev);
773 774 penvsev = getauxsevs((char *) NULL);
774 775 }
775 776 } while (!found && (penvsev != (struct sevstr *) NULL));
776 777
777 778 if (found) free(penvsev);
778 779 free(sevval);
779 780 }
780 781
781 782 if (!found) {
782 783 (void) snprintf(msgbuf, sizeof (msgbuf),
783 784 "Invalid severity: %s", sstr);
784 785 (void) fmtmsg(CLASS, labelbuf, MM_ERROR, msgbuf,
785 786 MM_NULLACT, MM_NULLTAG);
786 787 exit(1);
787 788 }
788 789
789 790 } /* <severity> is not one of the standard severities */
790 791
791 792 } /* <severity> is not numeric */
792 793
793 794 } /* if (s_seen) */
794 795
795 796 else severity = MM_NULLSEV;
796 797
797 798
798 799 /*
799 800 * Other options
800 801 */
801 802
802 803 if (!a_seen) action = MM_NULLACT;
803 804 if (!l_seen) label = MM_NULLLBL;
804 805 if (!t_seen) tag = MM_NULLTAG;
805 806 if (!text_seen) text = MM_NULLTXT;
806 807
807 808
808 809 /*
809 810 * Write the message
810 811 */
811 812
812 813 msgrtn = fmtmsg(class, label, severity, text, action ,tag);
813 814
814 815
815 816 /*
816 817 * Return appropriate value to the shell (or wherever)
817 818 */
818 819
819 820 exitval = 0;
820 821 if (msgrtn == MM_NOTOK) exitval = 32;
821 822 else {
822 823 if (msgrtn & MM_NOMSG) exitval += 2;
823 824 if (msgrtn & MM_NOCON) exitval += 4;
824 825 }
825 826
826 827 return(exitval);
827 828 }
↓ open down ↓ |
91 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX