Annotation of src/usr.bin/rdist/message.c, Revision 1.2
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[] =
36: "$Id: message.c,v 6.22 1995/12/11 23:37:35 mcooper Exp $";
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: {
448: if (IS_ON(flags, MT_DEBUG))
449: return;
450:
451: if (!msgbuf || !*msgbuf)
452: return;
453:
454: if (!msgfac->mf_fptr) {
455: register char *cp;
456: char *getenv();
457:
458: /*
459: * Create and open a new temporary file
460: */
461: if ((cp = getenv("TMPDIR")) == (char *) NULL)
462: cp = _PATH_TMP;
463: tempfile = (char *) xmalloc(strlen(cp) + 1 +
464: strlen(_RDIST_TMP) + 2);
465: (void) sprintf(tempfile, "%s/%s", cp, _RDIST_TMP);
466:
467: msgfac->mf_filename = tempfile;
468: (void) mktemp(msgfac->mf_filename);
469: if ((msgfac->mf_fptr = fopen(msgfac->mf_filename, "w"))==NULL)
470: fatalerr("Cannot open notify file for writing: %s: %s.",
471: msgfac->mf_filename, SYSERR);
472: debugmsg(DM_MISC, "Created notify temp file '%s'",
473: msgfac->mf_filename);
474: }
475:
476: if (msgfac->mf_fptr == NULL)
477: return;
478:
479: (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
480: (void) fflush(msgfac->mf_fptr);
481: }
482:
483: /*
484: * Insure currenthost is set to something reasonable.
485: */
486: extern void checkhostname()
487: {
488: static char mbuf[MAXHOSTNAMELEN];
489: char *cp;
490:
491: if (!currenthost) {
492: if (gethostname(mbuf, sizeof(mbuf)) == 0) {
493: if ((cp = strchr(mbuf, '.')) != NULL)
494: *cp = CNULL;
495: currenthost = strdup(mbuf);
496: } else
497: currenthost = "(unknown)";
498: }
499: }
500:
501: /*
502: * Print a message contained in "msgbuf" if a level "lvl" is set.
503: */
504: static void _message(flags, msgbuf)
505: int flags;
506: char *msgbuf;
507: {
508: register int i, x;
509: register char *cp;
510: static char mbuf[2048];
511:
512: if (msgbuf && *msgbuf) {
513: /*
514: * Ensure no stray newlines are present
515: */
516: if (cp = strchr(msgbuf, '\n'))
517: *cp = CNULL;
518:
519: checkhostname();
520: if (strncmp(currenthost, msgbuf, strlen(currenthost)) == 0)
521: (void) strcpy(mbuf, msgbuf);
522: else
523: (void) sprintf(mbuf, "%s: %s", currenthost, msgbuf);
524: } else
525: (void) strcpy(mbuf, "");
526:
527: /*
528: * Special case for messages that only get
529: * logged to the system log facility
530: */
531: if (IS_ON(flags, MT_SYSLOG)) {
532: msgsendsyslog((MSGFACILITY *)NULL, MT_SYSLOG, flags, mbuf);
533: return;
534: }
535:
536: /*
537: * Special cases
538: */
539: if (isserver && IS_ON(flags, MT_REMOTE))
540: msgsendstdout((MSGFACILITY *)NULL, MT_REMOTE, flags, mbuf);
541: else if (isserver && IS_ON(flags, MT_NERROR))
542: msgsendstdout((MSGFACILITY *)NULL, MT_NERROR, flags, mbuf);
543: else if (isserver && IS_ON(flags, MT_FERROR))
544: msgsendstdout((MSGFACILITY *)NULL, MT_FERROR, flags, mbuf);
545: else if (isserver && IS_ON(flags, MT_NOTICE)) {
546: msgsendstdout((MSGFACILITY *)NULL, MT_NOTICE, flags, mbuf);
547: return;
548: }
549:
550: /*
551: * For each Message Facility, check each Message Type to see
552: * if the bits in "flags" are set. If so, call the appropriate
553: * Message Facility to dispatch the message.
554: */
555: for (i = 0; msgfacility[i].mf_name; ++i)
556: for (x = 0; msgtypes[x].mt_name; ++x)
557: /*
558: * XXX MT_ALL should not be used directly
559: */
560: if (msgtypes[x].mt_type != MT_ALL &&
561: IS_ON(flags, msgtypes[x].mt_type) &&
562: IS_ON(msgfacility[i].mf_msgtypes,
563: msgtypes[x].mt_type))
564: (*msgfacility[i].mf_sendfunc)(&msgfacility[i],
565: msgtypes[x].mt_type,
566: flags,
567: mbuf);
568: }
569:
570: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
571: /*
572: * Varargs front-end to _message()
573: */
574: extern void message(va_alist)
575: va_dcl
576: {
577: static char buf[MSGBUFSIZ];
578: va_list args;
579: char *fmt;
580: int lvl;
581:
582: va_start(args);
583: lvl = (int) va_arg(args, int);
584: fmt = (char *) va_arg(args, char *);
585: va_end(args);
586:
587: (void) vsprintf(buf, fmt, args);
588:
589: _message(lvl, buf);
590: }
591: #endif /* ARG_VARARGS */
592:
593: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
594: /*
595: * Stdarg front-end to _message()
596: */
597: extern void message(int lvl, char *fmt, ...)
598: {
599: static char buf[MSGBUFSIZ];
600: va_list args;
601:
602: va_start(args, fmt);
603: (void) vsprintf(buf, fmt, args);
604: va_end(args);
605:
606: _message(lvl, buf);
607: }
608: #endif /* ARG_STDARG */
609:
610:
611: #if !defined(ARG_TYPE)
612: /*
613: * Simple front-end to _message()
614: */
615: /*VARARGS2*/
616: extern void message(lvl, fmt, a1, a2, a3, a4, a5)
617: int lvl;
618: char *fmt;
619: {
620: static char buf[MSGBUFSIZ];
621:
622: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
623:
624: _message(lvl, buf);
625: }
626: #endif /* !ARG_TYPE */
627:
628: /*
629: * Display a debugging message
630: */
631: static void _debugmsg(lvl, buf)
632: int lvl;
633: char *buf;
634: {
635: if (IS_ON(debug, lvl))
636: _message(MT_DEBUG, buf);
637: }
638:
639: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
640: /*
641: * Varargs front-end to _debugmsg()
642: */
643: extern void debugmsg(va_alist)
644: va_dcl
645: {
646: static char buf[MSGBUFSIZ];
647: va_list args;
648: char *fmt;
649: int lvl;
650:
651: va_start(args);
652: lvl = (int) va_arg(args, int);
653: fmt = (char *) va_arg(args, char *);
654: va_end(args);
655:
656: (void) vsprintf(buf, fmt, args);
657:
658: _debugmsg(lvl, buf);
659: }
660: #endif /* ARG_VARARGS */
661:
662: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
663: /*
664: * Stdarg front-end to _debugmsg()
665: */
666: extern void debugmsg(int lvl, char *fmt, ...)
667: {
668: static char buf[MSGBUFSIZ];
669: va_list args;
670:
671: va_start(args, fmt);
672: (void) vsprintf(buf, fmt, args);
673: va_end(args);
674:
675: _debugmsg(lvl, buf);
676: }
677: #endif /* ARG_STDARG */
678:
679: #if !defined(ARG_TYPE)
680: /*
681: * Simple front-end to _debugmsg()
682: */
683: /*VARARGS2*/
684: extern void debugmsg(lvl, fmt, a1, a2, a3, a4, a5)
685: int lvl;
686: char *fmt;
687: {
688: static char buf[MSGBUFSIZ];
689:
690: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
691:
692: _debugmsg(lvl, buf);
693: }
694: #endif /* ARG_TYPE */
695:
696: /*
697: * Print an error message
698: */
699: static void _error(msg)
700: char *msg;
701: {
702: static char buf[MSGBUFSIZ];
703:
704: nerrs++;
705: buf[0] = CNULL;
706:
707: if (msg) {
708: if (isserver)
709: (void) sprintf(buf, "REMOTE ERROR: %s", msg);
710: else
711: (void) sprintf(buf, "LOCAL ERROR: %s", msg);
712: }
713:
714: _message(MT_NERROR, (buf[0]) ? buf : NULL);
715: }
716:
717: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
718: /*
719: * Varargs frontend to _error()
720: */
721: extern void error(va_alist)
722: va_dcl
723: {
724: static char buf[MSGBUFSIZ];
725: va_list args;
726: char *fmt;
727:
728: buf[0] = CNULL;
729: va_start(args);
730: fmt = (char *) va_arg(args, char *);
731: if (fmt)
732: (void) vsprintf(buf, fmt, args);
733: va_end(args);
734:
735: _error((buf[0]) ? buf : NULL);
736: }
737: #endif /* ARG_VARARGS */
738:
739: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
740: /*
741: * Stdarg frontend to _error()
742: */
743: extern void error(char *fmt, ...)
744: {
745: static char buf[MSGBUFSIZ];
746: va_list args;
747:
748: buf[0] = CNULL;
749: va_start(args, fmt);
750: if (fmt)
751: (void) vsprintf(buf, fmt, args);
752: va_end(args);
753:
754: _error((buf[0]) ? buf : NULL);
755: }
756: #endif /* ARG_STDARG */
757:
758: #if !defined(ARG_TYPE)
759: /*
760: * Simple frontend to _error()
761: */
762: /*VARARGS1*/
763: extern void error(fmt, a1, a2, a3, a4, a5, a6)
764: char *fmt;
765: {
766: static char buf[MSGBUFSIZ];
767:
768: buf[0] = CNULL;
769: if (fmt)
770: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5, a6);
771:
772: _error((buf[0]) ? buf : NULL);
773: }
774: #endif /* ARG_TYPE */
775:
776: /*
777: * Display a fatal message
778: */
779: static void _fatalerr(msg)
780: char *msg;
781: {
782: static char buf[MSGBUFSIZ];
783:
784: ++nerrs;
785:
786: if (isserver)
787: (void) sprintf(buf, "REMOTE ERROR: %s", msg);
788: else
789: (void) sprintf(buf, "LOCAL ERROR: %s", msg);
790:
791: _message(MT_FERROR, buf);
792:
793: exit(nerrs);
794: }
795:
796: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
797: /*
798: * Varargs front-end to _fatalerr()
799: */
800: extern void fatalerr(va_alist)
801: va_dcl
802: {
803: static char buf[MSGBUFSIZ];
804: va_list args;
805: char *fmt;
806:
807: va_start(args);
808: fmt = (char *) va_arg(args, char *);
809: (void) vsprintf(buf, fmt, args);
810: va_end(args);
811:
812: _fatalerr(buf);
813: }
814: #endif /* ARG_VARARGS */
815:
816: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
817: /*
818: * Stdarg front-end to _fatalerr()
819: */
820: extern void fatalerr(char *fmt, ...)
821: {
822: static char buf[MSGBUFSIZ];
823: va_list args;
824:
825: va_start(args, fmt);
826: (void) vsprintf(buf, fmt, args);
827: va_end(args);
828:
829: _fatalerr(buf);
830: }
831: #endif /* ARG_STDARG */
832:
833: #if !defined(ARG_TYPE)
834: /*
835: * Simple front-end to _fatalerr()
836: */
837: /*VARARGS1*/
838: extern void fatalerr(fmt, a1, a2, a3, a4, a5)
839: char *fmt;
840: {
841: static char buf[MSGBUFSIZ];
842:
843: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
844:
845: _fatalerr(buf);
846: }
847: #endif /* !ARG_TYPE */
848:
849: /*
850: * Get the name of the file used for notify.
851: * A side effect is that the file pointer to the file
852: * is closed. We assume this function is only called when
853: * we are ready to read the file.
854: */
855: extern char *getnotifyfile()
856: {
857: register int i;
858:
859: for (i = 0; msgfacility[i].mf_name; i++)
860: if (msgfacility[i].mf_msgfac == MF_NOTIFY &&
861: msgfacility[i].mf_fptr) {
862: (void) fclose(msgfacility[i].mf_fptr);
863: msgfacility[i].mf_fptr = NULL;
864: return(msgfacility[i].mf_filename);
865: }
866:
867: return((char *) NULL);
868: }