Annotation of src/usr.bin/rdist/message.c, Revision 1.3
1.1 dm 1: /*
2: * Copyright (c) 1983 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: */
33:
34: #ifndef lint
35: static char RCSid[] =
1.3 ! deraadt 36: "$Id: message.c,v 1.2 1996/03/05 03:16:08 dm Exp $";
1.1 dm 37:
38: static char sccsid[] = "@(#)common.c";
39:
40: static char copyright[] =
41: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
42: All rights reserved.\n";
43: #endif /* !lint */
44:
45: /*
46: * Message handling functions for both rdist and rdistd.
47: */
48:
49: #include "defs.h"
50:
51: #define MSGBUFSIZ 32*1024
52:
53: int debug = 0; /* Debugging level */
54: int nerrs = 0; /* Number of errors */
55: char *tempfile = NULL; /* Name of temporary file */
56:
57: /*
58: * Message Types
59: */
60: MSGTYPE msgtypes[] = {
61: { MT_CHANGE, "change" },
62: { MT_INFO, "info" },
63: { MT_NOTICE, "notice" },
64: { MT_NERROR, "nerror" },
65: { MT_FERROR, "ferror" },
66: { MT_WARNING, "warning" },
67: { MT_VERBOSE, "verbose" },
68: { MT_ALL, "all" },
69: { MT_DEBUG, "debug" },
70: { 0 },
71: };
72:
73: static void msgsendstdout(), msgsendfile(), msgsendsyslog(),
74: msgsendnotify();
75:
76: /*
77: * Message Facilities
78: */
79: MSGFACILITY msgfacility[] = {
80: { MF_STDOUT, "stdout", msgsendstdout },
81: { MF_FILE, "file", msgsendfile },
82: { MF_SYSLOG, "syslog", msgsendsyslog },
83: { MF_NOTIFY, "notify", msgsendnotify },
84: { 0 },
85: };
86:
87: /*
88: * Print message logging usage message
89: */
90: extern void msgprusage()
91: {
92: register int i, x;
93:
94: (void) fprintf(stderr, "\nWhere <msgopt> is of form\n");
95: (void) fprintf(stderr,
96: "\t<facility1>=<type1>,<type2>,...:<facility2>=<type1>,<type2>...\n");
97:
98: (void) fprintf(stderr, "Valid <facility> names:");
99:
100: for (i = 0; msgfacility[i].mf_name; ++i)
101: (void) fprintf(stderr, " %s", msgfacility[i].mf_name);
102:
103: (void) fprintf(stderr, "\nValid <type> names:");
104: for (x = 0; msgtypes[x].mt_name; ++x)
105: (void) fprintf(stderr, " %s", msgtypes[x].mt_name);
106:
107: (void) fprintf(stderr, "\n");
108: }
109:
110: /*
111: * Print enabled message logging info
112: */
113: extern void msgprconfig()
114: {
115: register int i, x;
116: static char buf[MSGBUFSIZ];
117:
118: debugmsg(DM_MISC, "Current message logging config:");
119: for (i = 0; msgfacility[i].mf_name; ++i) {
120: (void) sprintf(buf, " %s=", msgfacility[i].mf_name);
121: for (x = 0; msgtypes[x].mt_name; ++x)
122: if (IS_ON(msgfacility[i].mf_msgtypes,
123: msgtypes[x].mt_type)) {
124: if (x > 0)
125: (void) strcat(buf, ",");
126: (void) strcat(buf, msgtypes[x].mt_name);
127: }
128: debugmsg(DM_MISC, "%s", buf);
129: }
130:
131: }
132:
133: /*
134: * Get the Message Facility entry "name"
135: */
136: static MSGFACILITY *getmsgfac(name)
137: char *name;
138: {
139: register int i;
140:
141: for (i = 0; msgfacility[i].mf_name; ++i)
142: if (strcasecmp(name, msgfacility[i].mf_name) == 0)
143: return(&msgfacility[i]);
144:
145: return((MSGFACILITY *) NULL);
146: }
147:
148: /*
149: * Get the Message Type entry named "name"
150: */
151: static MSGTYPE *getmsgtype(name)
152: char *name;
153: {
154: register int i;
155:
156: for (i = 0; msgtypes[i].mt_name; ++i)
157: if (strcasecmp(name, msgtypes[i].mt_name) == 0)
158: return(&msgtypes[i]);
159:
160: return((MSGTYPE *) NULL);
161: }
162:
163: /*
164: * Set Message Type information for Message Facility "msgfac" as
165: * indicated by string "str".
166: */
167: static char *setmsgtypes(msgfac, str)
168: MSGFACILITY *msgfac;
169: char *str;
170: {
171: static char ebuf[BUFSIZ];
172: register char *cp;
173: register char *strptr, *word;
174: register MSGTYPE *mtp;
175:
176: /*
177: * MF_SYSLOG is the only supported message facility for the server
178: */
179: if (isserver && (msgfac->mf_msgfac != MF_SYSLOG &&
180: msgfac->mf_msgfac != MF_FILE)) {
181: (void) sprintf(ebuf,
182: "The \"%s\" message facility cannot be used by the server.",
183: msgfac->mf_name);
184: return(ebuf);
185: }
186:
187: strptr = str;
188:
189: /*
190: * Do any necessary Message Facility preparation
191: */
192: switch(msgfac->mf_msgfac) {
193: case MF_FILE:
194: /*
195: * The MF_FILE string should look like "<file>=<types>".
196: */
197: if ((cp = strchr(strptr, '=')) == NULL)
198: return(
199: "No file name found for \"file\" message facility");
200: *cp++ = CNULL;
201:
202: if ((msgfac->mf_fptr = fopen(strptr, "w")) == NULL)
203: fatalerr("Cannot open log file for writing: %s: %s.",
204: strptr, SYSERR);
205: msgfac->mf_filename = strdup(strptr);
206:
207: strptr = cp;
208: break;
209:
210: case MF_NOTIFY:
211: break;
212:
213: case MF_STDOUT:
214: msgfac->mf_fptr = stdout;
215: break;
216:
217: case MF_SYSLOG:
218: #if defined(LOG_OPTS)
219: #if defined(LOG_FACILITY)
220: openlog(progname, LOG_OPTS, LOG_FACILITY);
221: #else
222: openlog(progname, LOG_OPTS);
223: #endif /* LOG_FACILITY */
224: #endif /* LOG_OPTS */
225: break;
226: }
227:
228: /*
229: * Parse each type word
230: */
231: msgfac->mf_msgtypes = 0; /* Start from scratch */
232: while (strptr) {
233: word = strptr;
234: if (cp = strchr(strptr, ','))
235: *cp++ = CNULL;
236: strptr = cp;
237:
238: if (mtp = getmsgtype(word)) {
239: msgfac->mf_msgtypes |= mtp->mt_type;
240: /*
241: * XXX This is really a kludge until we add real
242: * control over debugging.
243: */
244: if (!debug && isserver &&
245: strcasecmp(word, "debug") == 0)
246: debug = DM_ALL;
247: } else {
248: (void) sprintf(ebuf, "Message type \"%s\" is invalid.",
249: word);
250: return(ebuf);
251: }
252: }
253:
254: return((char *) NULL);
255: }
256:
257: /*
258: * Parse a message logging option string
259: */
260: extern char *msgparseopts(msgstr, doset)
261: char *msgstr;
262: int doset;
263: {
264: static char ebuf[BUFSIZ], msgbuf[MSGBUFSIZ];
265: register char *cp, *optstr;
266: register char *word;
267: MSGFACILITY *msgfac;
268:
269: if (msgstr == NULL)
270: return("NULL message string");
271:
272: /* strtok() is harmful */
273: (void) strcpy(msgbuf, msgstr);
274:
275: /*
276: * Each <facility>=<types> list is seperated by ":".
277: */
278: for (optstr = strtok(msgbuf, ":"); optstr;
279: optstr = strtok((char *)NULL, ":")) {
280:
281: if ((cp = strchr(optstr, '=')) == NULL)
282: return("No '=' found");
283:
284: *cp++ = CNULL;
285: word = optstr;
286: if ((int)strlen(word) <= 0)
287: return("No message facility specified");
288: if ((int)strlen(cp) <= 0)
289: return("No message type specified");
290:
291: if ((msgfac = getmsgfac(word)) == NULL) {
292: (void) sprintf(ebuf,
293: "%s is not a valid message facility",
294: word);
295: return(ebuf);
296: }
297:
298: if (doset) {
299: char *mcp;
300:
301: if (mcp = setmsgtypes(msgfac, cp))
302: return(mcp);
303: }
304: }
305:
306: if (isserver && debug) {
307: debugmsg(DM_MISC, "%s", getversion());
308: msgprconfig();
309: }
310:
311: return((char *) NULL);
312: }
313:
314: /*
315: * Send a message to facility "stdout".
316: * For rdistd, this is really the rdist client.
317: */
318: static void msgsendstdout(msgfac, mtype, flags, msgbuf)
319: /*ARGSUSED*/
320: MSGFACILITY *msgfac;
321: int mtype;
322: int flags;
323: char *msgbuf;
324: {
325: char cmd;
326:
327: if (isserver) {
328: if (rem_w < 0 || IS_ON(flags, MT_NOREMOTE))
329: return;
330:
331: cmd = CNULL;
332:
333: switch(mtype) {
334: case MT_NERROR: cmd = C_ERRMSG; break;
335: case MT_FERROR: cmd = C_FERRMSG; break;
336: case MT_NOTICE: cmd = C_NOTEMSG; break;
337: case MT_REMOTE: cmd = C_LOGMSG; break;
338: }
339:
340: if (cmd != CNULL)
341: (void) sendcmd(cmd, "%s", msgbuf);
342: } else {
343: switch(mtype) {
344: case MT_FERROR:
345: case MT_NERROR:
346: if (msgbuf && *msgbuf) {
347: (void) fprintf(stderr, "%s\n", msgbuf);
348: (void) fflush(stderr);
349: }
350: break;
351:
352: case MT_DEBUG:
353: /*
354: * Only things that are strictly MT_DEBUG should
355: * be shown.
356: */
357: if (flags != MT_DEBUG)
358: return;
359: case MT_NOTICE:
360: case MT_CHANGE:
361: case MT_INFO:
362: case MT_VERBOSE:
363: case MT_WARNING:
364: if (msgbuf && *msgbuf) {
365: (void) printf("%s\n", msgbuf);
366: (void) fflush(stdout);
367: }
368: break;
369: }
370: }
371: }
372:
373: /*
374: * Send a message to facility "syslog"
375: */
376: static void msgsendsyslog(msgfac, mtype, flags, msgbuf)
377: /*ARGSUSED*/
378: MSGFACILITY *msgfac;
379: int mtype;
380: int flags;
381: char *msgbuf;
382: {
383: int syslvl = 0;
384:
385: if (!msgbuf || !*msgbuf)
386: return;
387:
388: switch(mtype) {
389: #if defined(SL_NERROR)
390: case MT_NERROR: syslvl = SL_NERROR; break;
391: #endif
392: #if defined(SL_FERROR)
393: case MT_FERROR: syslvl = SL_FERROR; break;
394: #endif
395: #if defined(SL_WARNING)
396: case MT_WARNING: syslvl = SL_WARNING; break;
397: #endif
398: #if defined(SL_CHANGE)
399: case MT_CHANGE: syslvl = SL_CHANGE; break;
400: #endif
401: #if defined(SL_INFO)
402: case MT_SYSLOG:
403: case MT_VERBOSE:
404: case MT_INFO: syslvl = SL_INFO; break;
405: #endif
406: #if defined(SL_NOTICE)
407: case MT_NOTICE: syslvl = SL_NOTICE; break;
408: #endif
409: #if defined(SL_DEBUG)
410: case MT_DEBUG: syslvl = SL_DEBUG; break;
411: #endif
412: }
413:
414: if (syslvl)
415: syslog(syslvl, "%s", msgbuf);
416: }
417:
418: /*
419: * Send a message to a "file" facility.
420: */
421: static void msgsendfile(msgfac, mtype, flags, msgbuf)
422: /*ARGSUSED*/
423: MSGFACILITY *msgfac;
424: int mtype;
425: int flags;
426: char *msgbuf;
427: {
428: if (msgfac->mf_fptr == NULL)
429: return;
430:
431: if (!msgbuf || !*msgbuf)
432: return;
433:
434: (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
435: (void) fflush(msgfac->mf_fptr);
436: }
437:
438: /*
439: * Same method as msgsendfile()
440: */
441: static void msgsendnotify(msgfac, mtype, flags, msgbuf)
442: /*ARGSUSED*/
443: MSGFACILITY *msgfac;
444: int mtype;
445: int flags;
446: char *msgbuf;
447: {
1.3 ! deraadt 448: int fd;
! 449:
1.1 dm 450: if (IS_ON(flags, MT_DEBUG))
451: return;
452:
453: if (!msgbuf || !*msgbuf)
454: return;
455:
456: if (!msgfac->mf_fptr) {
457: register char *cp;
458: char *getenv();
459:
460: /*
461: * Create and open a new temporary file
462: */
463: if ((cp = getenv("TMPDIR")) == (char *) NULL)
464: cp = _PATH_TMP;
465: tempfile = (char *) xmalloc(strlen(cp) + 1 +
466: strlen(_RDIST_TMP) + 2);
467: (void) sprintf(tempfile, "%s/%s", cp, _RDIST_TMP);
468:
469: msgfac->mf_filename = tempfile;
1.3 ! deraadt 470: if ((fd = mkstemp(msgfac->mf_filename)) == -1 ||
! 471: (msgfac->mf_fptr = fdopen(fd, "w"))==NULL) {
! 472: if (fd != -1)
! 473: close(fd);
1.1 dm 474: fatalerr("Cannot open notify file for writing: %s: %s.",
475: msgfac->mf_filename, SYSERR);
1.3 ! deraadt 476: }
1.1 dm 477: debugmsg(DM_MISC, "Created notify temp file '%s'",
478: msgfac->mf_filename);
479: }
480:
481: if (msgfac->mf_fptr == NULL)
482: return;
483:
484: (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
485: (void) fflush(msgfac->mf_fptr);
486: }
487:
488: /*
489: * Insure currenthost is set to something reasonable.
490: */
491: extern void checkhostname()
492: {
493: static char mbuf[MAXHOSTNAMELEN];
494: char *cp;
495:
496: if (!currenthost) {
497: if (gethostname(mbuf, sizeof(mbuf)) == 0) {
498: if ((cp = strchr(mbuf, '.')) != NULL)
499: *cp = CNULL;
500: currenthost = strdup(mbuf);
501: } else
502: currenthost = "(unknown)";
503: }
504: }
505:
506: /*
507: * Print a message contained in "msgbuf" if a level "lvl" is set.
508: */
509: static void _message(flags, msgbuf)
510: int flags;
511: char *msgbuf;
512: {
513: register int i, x;
514: register char *cp;
515: static char mbuf[2048];
516:
517: if (msgbuf && *msgbuf) {
518: /*
519: * Ensure no stray newlines are present
520: */
521: if (cp = strchr(msgbuf, '\n'))
522: *cp = CNULL;
523:
524: checkhostname();
525: if (strncmp(currenthost, msgbuf, strlen(currenthost)) == 0)
526: (void) strcpy(mbuf, msgbuf);
527: else
528: (void) sprintf(mbuf, "%s: %s", currenthost, msgbuf);
529: } else
530: (void) strcpy(mbuf, "");
531:
532: /*
533: * Special case for messages that only get
534: * logged to the system log facility
535: */
536: if (IS_ON(flags, MT_SYSLOG)) {
537: msgsendsyslog((MSGFACILITY *)NULL, MT_SYSLOG, flags, mbuf);
538: return;
539: }
540:
541: /*
542: * Special cases
543: */
544: if (isserver && IS_ON(flags, MT_REMOTE))
545: msgsendstdout((MSGFACILITY *)NULL, MT_REMOTE, flags, mbuf);
546: else if (isserver && IS_ON(flags, MT_NERROR))
547: msgsendstdout((MSGFACILITY *)NULL, MT_NERROR, flags, mbuf);
548: else if (isserver && IS_ON(flags, MT_FERROR))
549: msgsendstdout((MSGFACILITY *)NULL, MT_FERROR, flags, mbuf);
550: else if (isserver && IS_ON(flags, MT_NOTICE)) {
551: msgsendstdout((MSGFACILITY *)NULL, MT_NOTICE, flags, mbuf);
552: return;
553: }
554:
555: /*
556: * For each Message Facility, check each Message Type to see
557: * if the bits in "flags" are set. If so, call the appropriate
558: * Message Facility to dispatch the message.
559: */
560: for (i = 0; msgfacility[i].mf_name; ++i)
561: for (x = 0; msgtypes[x].mt_name; ++x)
562: /*
563: * XXX MT_ALL should not be used directly
564: */
565: if (msgtypes[x].mt_type != MT_ALL &&
566: IS_ON(flags, msgtypes[x].mt_type) &&
567: IS_ON(msgfacility[i].mf_msgtypes,
568: msgtypes[x].mt_type))
569: (*msgfacility[i].mf_sendfunc)(&msgfacility[i],
570: msgtypes[x].mt_type,
571: flags,
572: mbuf);
573: }
574:
575: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
576: /*
577: * Varargs front-end to _message()
578: */
579: extern void message(va_alist)
580: va_dcl
581: {
582: static char buf[MSGBUFSIZ];
583: va_list args;
584: char *fmt;
585: int lvl;
586:
587: va_start(args);
588: lvl = (int) va_arg(args, int);
589: fmt = (char *) va_arg(args, char *);
590: va_end(args);
591:
592: (void) vsprintf(buf, fmt, args);
593:
594: _message(lvl, buf);
595: }
596: #endif /* ARG_VARARGS */
597:
598: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
599: /*
600: * Stdarg front-end to _message()
601: */
602: extern void message(int lvl, char *fmt, ...)
603: {
604: static char buf[MSGBUFSIZ];
605: va_list args;
606:
607: va_start(args, fmt);
608: (void) vsprintf(buf, fmt, args);
609: va_end(args);
610:
611: _message(lvl, buf);
612: }
613: #endif /* ARG_STDARG */
614:
615:
616: #if !defined(ARG_TYPE)
617: /*
618: * Simple front-end to _message()
619: */
620: /*VARARGS2*/
621: extern void message(lvl, fmt, a1, a2, a3, a4, a5)
622: int lvl;
623: char *fmt;
624: {
625: static char buf[MSGBUFSIZ];
626:
627: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
628:
629: _message(lvl, buf);
630: }
631: #endif /* !ARG_TYPE */
632:
633: /*
634: * Display a debugging message
635: */
636: static void _debugmsg(lvl, buf)
637: int lvl;
638: char *buf;
639: {
640: if (IS_ON(debug, lvl))
641: _message(MT_DEBUG, buf);
642: }
643:
644: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
645: /*
646: * Varargs front-end to _debugmsg()
647: */
648: extern void debugmsg(va_alist)
649: va_dcl
650: {
651: static char buf[MSGBUFSIZ];
652: va_list args;
653: char *fmt;
654: int lvl;
655:
656: va_start(args);
657: lvl = (int) va_arg(args, int);
658: fmt = (char *) va_arg(args, char *);
659: va_end(args);
660:
661: (void) vsprintf(buf, fmt, args);
662:
663: _debugmsg(lvl, buf);
664: }
665: #endif /* ARG_VARARGS */
666:
667: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
668: /*
669: * Stdarg front-end to _debugmsg()
670: */
671: extern void debugmsg(int lvl, char *fmt, ...)
672: {
673: static char buf[MSGBUFSIZ];
674: va_list args;
675:
676: va_start(args, fmt);
677: (void) vsprintf(buf, fmt, args);
678: va_end(args);
679:
680: _debugmsg(lvl, buf);
681: }
682: #endif /* ARG_STDARG */
683:
684: #if !defined(ARG_TYPE)
685: /*
686: * Simple front-end to _debugmsg()
687: */
688: /*VARARGS2*/
689: extern void debugmsg(lvl, fmt, a1, a2, a3, a4, a5)
690: int lvl;
691: char *fmt;
692: {
693: static char buf[MSGBUFSIZ];
694:
695: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
696:
697: _debugmsg(lvl, buf);
698: }
699: #endif /* ARG_TYPE */
700:
701: /*
702: * Print an error message
703: */
704: static void _error(msg)
705: char *msg;
706: {
707: static char buf[MSGBUFSIZ];
708:
709: nerrs++;
710: buf[0] = CNULL;
711:
712: if (msg) {
713: if (isserver)
714: (void) sprintf(buf, "REMOTE ERROR: %s", msg);
715: else
716: (void) sprintf(buf, "LOCAL ERROR: %s", msg);
717: }
718:
719: _message(MT_NERROR, (buf[0]) ? buf : NULL);
720: }
721:
722: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
723: /*
724: * Varargs frontend to _error()
725: */
726: extern void error(va_alist)
727: va_dcl
728: {
729: static char buf[MSGBUFSIZ];
730: va_list args;
731: char *fmt;
732:
733: buf[0] = CNULL;
734: va_start(args);
735: fmt = (char *) va_arg(args, char *);
736: if (fmt)
737: (void) vsprintf(buf, fmt, args);
738: va_end(args);
739:
740: _error((buf[0]) ? buf : NULL);
741: }
742: #endif /* ARG_VARARGS */
743:
744: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
745: /*
746: * Stdarg frontend to _error()
747: */
748: extern void error(char *fmt, ...)
749: {
750: static char buf[MSGBUFSIZ];
751: va_list args;
752:
753: buf[0] = CNULL;
754: va_start(args, fmt);
755: if (fmt)
756: (void) vsprintf(buf, fmt, args);
757: va_end(args);
758:
759: _error((buf[0]) ? buf : NULL);
760: }
761: #endif /* ARG_STDARG */
762:
763: #if !defined(ARG_TYPE)
764: /*
765: * Simple frontend to _error()
766: */
767: /*VARARGS1*/
768: extern void error(fmt, a1, a2, a3, a4, a5, a6)
769: char *fmt;
770: {
771: static char buf[MSGBUFSIZ];
772:
773: buf[0] = CNULL;
774: if (fmt)
775: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5, a6);
776:
777: _error((buf[0]) ? buf : NULL);
778: }
779: #endif /* ARG_TYPE */
780:
781: /*
782: * Display a fatal message
783: */
784: static void _fatalerr(msg)
785: char *msg;
786: {
787: static char buf[MSGBUFSIZ];
788:
789: ++nerrs;
790:
791: if (isserver)
792: (void) sprintf(buf, "REMOTE ERROR: %s", msg);
793: else
794: (void) sprintf(buf, "LOCAL ERROR: %s", msg);
795:
796: _message(MT_FERROR, buf);
797:
798: exit(nerrs);
799: }
800:
801: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
802: /*
803: * Varargs front-end to _fatalerr()
804: */
805: extern void fatalerr(va_alist)
806: va_dcl
807: {
808: static char buf[MSGBUFSIZ];
809: va_list args;
810: char *fmt;
811:
812: va_start(args);
813: fmt = (char *) va_arg(args, char *);
814: (void) vsprintf(buf, fmt, args);
815: va_end(args);
816:
817: _fatalerr(buf);
818: }
819: #endif /* ARG_VARARGS */
820:
821: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
822: /*
823: * Stdarg front-end to _fatalerr()
824: */
825: extern void fatalerr(char *fmt, ...)
826: {
827: static char buf[MSGBUFSIZ];
828: va_list args;
829:
830: va_start(args, fmt);
831: (void) vsprintf(buf, fmt, args);
832: va_end(args);
833:
834: _fatalerr(buf);
835: }
836: #endif /* ARG_STDARG */
837:
838: #if !defined(ARG_TYPE)
839: /*
840: * Simple front-end to _fatalerr()
841: */
842: /*VARARGS1*/
843: extern void fatalerr(fmt, a1, a2, a3, a4, a5)
844: char *fmt;
845: {
846: static char buf[MSGBUFSIZ];
847:
848: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
849:
850: _fatalerr(buf);
851: }
852: #endif /* !ARG_TYPE */
853:
854: /*
855: * Get the name of the file used for notify.
856: * A side effect is that the file pointer to the file
857: * is closed. We assume this function is only called when
858: * we are ready to read the file.
859: */
860: extern char *getnotifyfile()
861: {
862: register int i;
863:
864: for (i = 0; msgfacility[i].mf_name; i++)
865: if (msgfacility[i].mf_msgfac == MF_NOTIFY &&
866: msgfacility[i].mf_fptr) {
867: (void) fclose(msgfacility[i].mf_fptr);
868: msgfacility[i].mf_fptr = NULL;
869: return(msgfacility[i].mf_filename);
870: }
871:
872: return((char *) NULL);
873: }