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