Annotation of src/usr.bin/rdist/message.c, Revision 1.5
1.5 ! millert 1: /* $OpenBSD: message.c,v 1.4 1996/06/26 05:38:14 deraadt Exp $ */
1.4 deraadt 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.5 ! millert 38: "$OpenBSD: message.c,v 1.4 1996/06/26 05:38:14 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) {
1.5 ! millert 122: (void) snprintf(buf, sizeof(buf),
! 123: " %s=", msgfacility[i].mf_name);
1.1 dm 124: for (x = 0; msgtypes[x].mt_name; ++x)
125: if (IS_ON(msgfacility[i].mf_msgtypes,
126: msgtypes[x].mt_type)) {
127: if (x > 0)
128: (void) strcat(buf, ",");
129: (void) strcat(buf, msgtypes[x].mt_name);
130: }
131: debugmsg(DM_MISC, "%s", buf);
132: }
133:
134: }
135:
136: /*
137: * Get the Message Facility entry "name"
138: */
139: static MSGFACILITY *getmsgfac(name)
140: char *name;
141: {
142: register int i;
143:
144: for (i = 0; msgfacility[i].mf_name; ++i)
145: if (strcasecmp(name, msgfacility[i].mf_name) == 0)
146: return(&msgfacility[i]);
147:
148: return((MSGFACILITY *) NULL);
149: }
150:
151: /*
152: * Get the Message Type entry named "name"
153: */
154: static MSGTYPE *getmsgtype(name)
155: char *name;
156: {
157: register int i;
158:
159: for (i = 0; msgtypes[i].mt_name; ++i)
160: if (strcasecmp(name, msgtypes[i].mt_name) == 0)
161: return(&msgtypes[i]);
162:
163: return((MSGTYPE *) NULL);
164: }
165:
166: /*
167: * Set Message Type information for Message Facility "msgfac" as
168: * indicated by string "str".
169: */
170: static char *setmsgtypes(msgfac, str)
171: MSGFACILITY *msgfac;
172: char *str;
173: {
174: static char ebuf[BUFSIZ];
175: register char *cp;
176: register char *strptr, *word;
177: register MSGTYPE *mtp;
178:
179: /*
180: * MF_SYSLOG is the only supported message facility for the server
181: */
182: if (isserver && (msgfac->mf_msgfac != MF_SYSLOG &&
183: msgfac->mf_msgfac != MF_FILE)) {
1.5 ! millert 184: (void) snprintf(ebuf, sizeof(ebuf),
1.1 dm 185: "The \"%s\" message facility cannot be used by the server.",
186: msgfac->mf_name);
187: return(ebuf);
188: }
189:
190: strptr = str;
191:
192: /*
193: * Do any necessary Message Facility preparation
194: */
195: switch(msgfac->mf_msgfac) {
196: case MF_FILE:
197: /*
198: * The MF_FILE string should look like "<file>=<types>".
199: */
200: if ((cp = strchr(strptr, '=')) == NULL)
201: return(
202: "No file name found for \"file\" message facility");
203: *cp++ = CNULL;
204:
205: if ((msgfac->mf_fptr = fopen(strptr, "w")) == NULL)
206: fatalerr("Cannot open log file for writing: %s: %s.",
207: strptr, SYSERR);
208: msgfac->mf_filename = strdup(strptr);
209:
210: strptr = cp;
211: break;
212:
213: case MF_NOTIFY:
214: break;
215:
216: case MF_STDOUT:
217: msgfac->mf_fptr = stdout;
218: break;
219:
220: case MF_SYSLOG:
221: #if defined(LOG_OPTS)
222: #if defined(LOG_FACILITY)
223: openlog(progname, LOG_OPTS, LOG_FACILITY);
224: #else
225: openlog(progname, LOG_OPTS);
226: #endif /* LOG_FACILITY */
227: #endif /* LOG_OPTS */
228: break;
229: }
230:
231: /*
232: * Parse each type word
233: */
234: msgfac->mf_msgtypes = 0; /* Start from scratch */
235: while (strptr) {
236: word = strptr;
237: if (cp = strchr(strptr, ','))
238: *cp++ = CNULL;
239: strptr = cp;
240:
241: if (mtp = getmsgtype(word)) {
242: msgfac->mf_msgtypes |= mtp->mt_type;
243: /*
244: * XXX This is really a kludge until we add real
245: * control over debugging.
246: */
247: if (!debug && isserver &&
248: strcasecmp(word, "debug") == 0)
249: debug = DM_ALL;
250: } else {
1.5 ! millert 251: (void) snprintf(ebuf, sizeof(ebuf),
! 252: "Message type \"%s\" is invalid.",
! 253: word);
1.1 dm 254: return(ebuf);
255: }
256: }
257:
258: return((char *) NULL);
259: }
260:
261: /*
262: * Parse a message logging option string
263: */
264: extern char *msgparseopts(msgstr, doset)
265: char *msgstr;
266: int doset;
267: {
268: static char ebuf[BUFSIZ], msgbuf[MSGBUFSIZ];
269: register char *cp, *optstr;
270: register char *word;
271: MSGFACILITY *msgfac;
272:
273: if (msgstr == NULL)
274: return("NULL message string");
275:
276: /* strtok() is harmful */
277: (void) strcpy(msgbuf, msgstr);
278:
279: /*
280: * Each <facility>=<types> list is seperated by ":".
281: */
282: for (optstr = strtok(msgbuf, ":"); optstr;
283: optstr = strtok((char *)NULL, ":")) {
284:
285: if ((cp = strchr(optstr, '=')) == NULL)
286: return("No '=' found");
287:
288: *cp++ = CNULL;
289: word = optstr;
290: if ((int)strlen(word) <= 0)
291: return("No message facility specified");
292: if ((int)strlen(cp) <= 0)
293: return("No message type specified");
294:
295: if ((msgfac = getmsgfac(word)) == NULL) {
1.5 ! millert 296: (void) snprintf(ebuf, sizeof(ebuf),
! 297: "%s is not a valid message facility",
! 298: word);
1.1 dm 299: return(ebuf);
300: }
301:
302: if (doset) {
303: char *mcp;
304:
305: if (mcp = setmsgtypes(msgfac, cp))
306: return(mcp);
307: }
308: }
309:
310: if (isserver && debug) {
311: debugmsg(DM_MISC, "%s", getversion());
312: msgprconfig();
313: }
314:
315: return((char *) NULL);
316: }
317:
318: /*
319: * Send a message to facility "stdout".
320: * For rdistd, this is really the rdist client.
321: */
322: static void msgsendstdout(msgfac, mtype, flags, msgbuf)
323: /*ARGSUSED*/
324: MSGFACILITY *msgfac;
325: int mtype;
326: int flags;
327: char *msgbuf;
328: {
329: char cmd;
330:
331: if (isserver) {
332: if (rem_w < 0 || IS_ON(flags, MT_NOREMOTE))
333: return;
334:
335: cmd = CNULL;
336:
337: switch(mtype) {
338: case MT_NERROR: cmd = C_ERRMSG; break;
339: case MT_FERROR: cmd = C_FERRMSG; break;
340: case MT_NOTICE: cmd = C_NOTEMSG; break;
341: case MT_REMOTE: cmd = C_LOGMSG; break;
342: }
343:
344: if (cmd != CNULL)
345: (void) sendcmd(cmd, "%s", msgbuf);
346: } else {
347: switch(mtype) {
348: case MT_FERROR:
349: case MT_NERROR:
350: if (msgbuf && *msgbuf) {
351: (void) fprintf(stderr, "%s\n", msgbuf);
352: (void) fflush(stderr);
353: }
354: break;
355:
356: case MT_DEBUG:
357: /*
358: * Only things that are strictly MT_DEBUG should
359: * be shown.
360: */
361: if (flags != MT_DEBUG)
362: return;
363: case MT_NOTICE:
364: case MT_CHANGE:
365: case MT_INFO:
366: case MT_VERBOSE:
367: case MT_WARNING:
368: if (msgbuf && *msgbuf) {
369: (void) printf("%s\n", msgbuf);
370: (void) fflush(stdout);
371: }
372: break;
373: }
374: }
375: }
376:
377: /*
378: * Send a message to facility "syslog"
379: */
380: static void msgsendsyslog(msgfac, mtype, flags, msgbuf)
381: /*ARGSUSED*/
382: MSGFACILITY *msgfac;
383: int mtype;
384: int flags;
385: char *msgbuf;
386: {
387: int syslvl = 0;
388:
389: if (!msgbuf || !*msgbuf)
390: return;
391:
392: switch(mtype) {
393: #if defined(SL_NERROR)
394: case MT_NERROR: syslvl = SL_NERROR; break;
395: #endif
396: #if defined(SL_FERROR)
397: case MT_FERROR: syslvl = SL_FERROR; break;
398: #endif
399: #if defined(SL_WARNING)
400: case MT_WARNING: syslvl = SL_WARNING; break;
401: #endif
402: #if defined(SL_CHANGE)
403: case MT_CHANGE: syslvl = SL_CHANGE; break;
404: #endif
405: #if defined(SL_INFO)
406: case MT_SYSLOG:
407: case MT_VERBOSE:
408: case MT_INFO: syslvl = SL_INFO; break;
409: #endif
410: #if defined(SL_NOTICE)
411: case MT_NOTICE: syslvl = SL_NOTICE; break;
412: #endif
413: #if defined(SL_DEBUG)
414: case MT_DEBUG: syslvl = SL_DEBUG; break;
415: #endif
416: }
417:
418: if (syslvl)
419: syslog(syslvl, "%s", msgbuf);
420: }
421:
422: /*
423: * Send a message to a "file" facility.
424: */
425: static void msgsendfile(msgfac, mtype, flags, msgbuf)
426: /*ARGSUSED*/
427: MSGFACILITY *msgfac;
428: int mtype;
429: int flags;
430: char *msgbuf;
431: {
432: if (msgfac->mf_fptr == NULL)
433: return;
434:
435: if (!msgbuf || !*msgbuf)
436: return;
437:
438: (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
439: (void) fflush(msgfac->mf_fptr);
440: }
441:
442: /*
443: * Same method as msgsendfile()
444: */
445: static void msgsendnotify(msgfac, mtype, flags, msgbuf)
446: /*ARGSUSED*/
447: MSGFACILITY *msgfac;
448: int mtype;
449: int flags;
450: char *msgbuf;
451: {
1.3 deraadt 452: int fd;
453:
1.1 dm 454: if (IS_ON(flags, MT_DEBUG))
455: return;
456:
457: if (!msgbuf || !*msgbuf)
458: return;
459:
460: if (!msgfac->mf_fptr) {
461: register char *cp;
462: char *getenv();
463:
464: /*
465: * Create and open a new temporary file
466: */
467: if ((cp = getenv("TMPDIR")) == (char *) NULL)
468: cp = _PATH_TMP;
469: tempfile = (char *) xmalloc(strlen(cp) + 1 +
470: strlen(_RDIST_TMP) + 2);
471: (void) sprintf(tempfile, "%s/%s", cp, _RDIST_TMP);
472:
473: msgfac->mf_filename = tempfile;
1.3 deraadt 474: if ((fd = mkstemp(msgfac->mf_filename)) == -1 ||
475: (msgfac->mf_fptr = fdopen(fd, "w"))==NULL) {
476: if (fd != -1)
477: close(fd);
1.1 dm 478: fatalerr("Cannot open notify file for writing: %s: %s.",
479: msgfac->mf_filename, SYSERR);
1.3 deraadt 480: }
1.1 dm 481: debugmsg(DM_MISC, "Created notify temp file '%s'",
482: msgfac->mf_filename);
483: }
484:
485: if (msgfac->mf_fptr == NULL)
486: return;
487:
488: (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
489: (void) fflush(msgfac->mf_fptr);
490: }
491:
492: /*
493: * Insure currenthost is set to something reasonable.
494: */
495: extern void checkhostname()
496: {
497: static char mbuf[MAXHOSTNAMELEN];
498: char *cp;
499:
500: if (!currenthost) {
501: if (gethostname(mbuf, sizeof(mbuf)) == 0) {
502: if ((cp = strchr(mbuf, '.')) != NULL)
503: *cp = CNULL;
504: currenthost = strdup(mbuf);
505: } else
506: currenthost = "(unknown)";
507: }
508: }
509:
510: /*
511: * Print a message contained in "msgbuf" if a level "lvl" is set.
512: */
513: static void _message(flags, msgbuf)
514: int flags;
515: char *msgbuf;
516: {
517: register int i, x;
518: register char *cp;
519: static char mbuf[2048];
520:
521: if (msgbuf && *msgbuf) {
522: /*
523: * Ensure no stray newlines are present
524: */
525: if (cp = strchr(msgbuf, '\n'))
526: *cp = CNULL;
527:
528: checkhostname();
529: if (strncmp(currenthost, msgbuf, strlen(currenthost)) == 0)
530: (void) strcpy(mbuf, msgbuf);
531: else
532: (void) sprintf(mbuf, "%s: %s", currenthost, msgbuf);
533: } else
534: (void) strcpy(mbuf, "");
535:
536: /*
537: * Special case for messages that only get
538: * logged to the system log facility
539: */
540: if (IS_ON(flags, MT_SYSLOG)) {
541: msgsendsyslog((MSGFACILITY *)NULL, MT_SYSLOG, flags, mbuf);
542: return;
543: }
544:
545: /*
546: * Special cases
547: */
1.5 ! millert 548: if (isserver && IS_ON(flags, MT_NOTICE)) {
! 549: msgsendstdout((MSGFACILITY *)NULL, MT_NOTICE, flags, mbuf);
! 550: return;
! 551: } else if (isserver && IS_ON(flags, MT_REMOTE))
1.1 dm 552: msgsendstdout((MSGFACILITY *)NULL, MT_REMOTE, flags, mbuf);
553: else if (isserver && IS_ON(flags, MT_NERROR))
554: msgsendstdout((MSGFACILITY *)NULL, MT_NERROR, flags, mbuf);
555: else if (isserver && IS_ON(flags, MT_FERROR))
556: msgsendstdout((MSGFACILITY *)NULL, MT_FERROR, flags, mbuf);
557:
558: /*
559: * For each Message Facility, check each Message Type to see
560: * if the bits in "flags" are set. If so, call the appropriate
561: * Message Facility to dispatch the message.
562: */
563: for (i = 0; msgfacility[i].mf_name; ++i)
564: for (x = 0; msgtypes[x].mt_name; ++x)
565: /*
566: * XXX MT_ALL should not be used directly
567: */
568: if (msgtypes[x].mt_type != MT_ALL &&
569: IS_ON(flags, msgtypes[x].mt_type) &&
570: IS_ON(msgfacility[i].mf_msgtypes,
571: msgtypes[x].mt_type))
572: (*msgfacility[i].mf_sendfunc)(&msgfacility[i],
573: msgtypes[x].mt_type,
574: flags,
575: mbuf);
576: }
577:
578: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
579: /*
580: * Varargs front-end to _message()
581: */
582: extern void message(va_alist)
583: va_dcl
584: {
585: static char buf[MSGBUFSIZ];
586: va_list args;
587: char *fmt;
588: int lvl;
589:
590: va_start(args);
591: lvl = (int) va_arg(args, int);
592: fmt = (char *) va_arg(args, char *);
593: va_end(args);
594:
595: (void) vsprintf(buf, fmt, args);
596:
597: _message(lvl, buf);
598: }
599: #endif /* ARG_VARARGS */
600:
601: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
602: /*
603: * Stdarg front-end to _message()
604: */
605: extern void message(int lvl, char *fmt, ...)
606: {
607: static char buf[MSGBUFSIZ];
608: va_list args;
609:
610: va_start(args, fmt);
611: (void) vsprintf(buf, fmt, args);
612: va_end(args);
613:
614: _message(lvl, buf);
615: }
616: #endif /* ARG_STDARG */
617:
618:
619: #if !defined(ARG_TYPE)
620: /*
621: * Simple front-end to _message()
622: */
623: /*VARARGS2*/
624: extern void message(lvl, fmt, a1, a2, a3, a4, a5)
625: int lvl;
626: char *fmt;
627: {
628: static char buf[MSGBUFSIZ];
629:
630: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
631:
632: _message(lvl, buf);
633: }
634: #endif /* !ARG_TYPE */
635:
636: /*
637: * Display a debugging message
638: */
639: static void _debugmsg(lvl, buf)
640: int lvl;
641: char *buf;
642: {
643: if (IS_ON(debug, lvl))
644: _message(MT_DEBUG, buf);
645: }
646:
647: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
648: /*
649: * Varargs front-end to _debugmsg()
650: */
651: extern void debugmsg(va_alist)
652: va_dcl
653: {
654: static char buf[MSGBUFSIZ];
655: va_list args;
656: char *fmt;
657: int lvl;
658:
659: va_start(args);
660: lvl = (int) va_arg(args, int);
661: fmt = (char *) va_arg(args, char *);
662: va_end(args);
663:
664: (void) vsprintf(buf, fmt, args);
665:
666: _debugmsg(lvl, buf);
667: }
668: #endif /* ARG_VARARGS */
669:
670: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
671: /*
672: * Stdarg front-end to _debugmsg()
673: */
674: extern void debugmsg(int lvl, char *fmt, ...)
675: {
676: static char buf[MSGBUFSIZ];
677: va_list args;
678:
679: va_start(args, fmt);
680: (void) vsprintf(buf, fmt, args);
681: va_end(args);
682:
683: _debugmsg(lvl, buf);
684: }
685: #endif /* ARG_STDARG */
686:
687: #if !defined(ARG_TYPE)
688: /*
689: * Simple front-end to _debugmsg()
690: */
691: /*VARARGS2*/
692: extern void debugmsg(lvl, fmt, a1, a2, a3, a4, a5)
693: int lvl;
694: char *fmt;
695: {
696: static char buf[MSGBUFSIZ];
697:
698: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
699:
700: _debugmsg(lvl, buf);
701: }
702: #endif /* ARG_TYPE */
703:
704: /*
705: * Print an error message
706: */
707: static void _error(msg)
708: char *msg;
709: {
710: static char buf[MSGBUFSIZ];
711:
712: nerrs++;
713: buf[0] = CNULL;
714:
715: if (msg) {
716: if (isserver)
717: (void) sprintf(buf, "REMOTE ERROR: %s", msg);
718: else
719: (void) sprintf(buf, "LOCAL ERROR: %s", msg);
720: }
721:
722: _message(MT_NERROR, (buf[0]) ? buf : NULL);
723: }
724:
725: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
726: /*
727: * Varargs frontend to _error()
728: */
729: extern void error(va_alist)
730: va_dcl
731: {
732: static char buf[MSGBUFSIZ];
733: va_list args;
734: char *fmt;
735:
736: buf[0] = CNULL;
737: va_start(args);
738: fmt = (char *) va_arg(args, char *);
739: if (fmt)
740: (void) vsprintf(buf, fmt, args);
741: va_end(args);
742:
743: _error((buf[0]) ? buf : NULL);
744: }
745: #endif /* ARG_VARARGS */
746:
747: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
748: /*
749: * Stdarg frontend to _error()
750: */
751: extern void error(char *fmt, ...)
752: {
753: static char buf[MSGBUFSIZ];
754: va_list args;
755:
756: buf[0] = CNULL;
757: va_start(args, fmt);
758: if (fmt)
759: (void) vsprintf(buf, fmt, args);
760: va_end(args);
761:
762: _error((buf[0]) ? buf : NULL);
763: }
764: #endif /* ARG_STDARG */
765:
766: #if !defined(ARG_TYPE)
767: /*
768: * Simple frontend to _error()
769: */
770: /*VARARGS1*/
771: extern void error(fmt, a1, a2, a3, a4, a5, a6)
772: char *fmt;
773: {
774: static char buf[MSGBUFSIZ];
775:
776: buf[0] = CNULL;
777: if (fmt)
778: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5, a6);
779:
780: _error((buf[0]) ? buf : NULL);
781: }
782: #endif /* ARG_TYPE */
783:
784: /*
785: * Display a fatal message
786: */
787: static void _fatalerr(msg)
788: char *msg;
789: {
790: static char buf[MSGBUFSIZ];
791:
792: ++nerrs;
793:
794: if (isserver)
795: (void) sprintf(buf, "REMOTE ERROR: %s", msg);
796: else
797: (void) sprintf(buf, "LOCAL ERROR: %s", msg);
798:
799: _message(MT_FERROR, buf);
800:
801: exit(nerrs);
802: }
803:
804: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
805: /*
806: * Varargs front-end to _fatalerr()
807: */
808: extern void fatalerr(va_alist)
809: va_dcl
810: {
811: static char buf[MSGBUFSIZ];
812: va_list args;
813: char *fmt;
814:
815: va_start(args);
816: fmt = (char *) va_arg(args, char *);
817: (void) vsprintf(buf, fmt, args);
818: va_end(args);
819:
820: _fatalerr(buf);
821: }
822: #endif /* ARG_VARARGS */
823:
824: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
825: /*
826: * Stdarg front-end to _fatalerr()
827: */
828: extern void fatalerr(char *fmt, ...)
829: {
830: static char buf[MSGBUFSIZ];
831: va_list args;
832:
833: va_start(args, fmt);
834: (void) vsprintf(buf, fmt, args);
835: va_end(args);
836:
837: _fatalerr(buf);
838: }
839: #endif /* ARG_STDARG */
840:
841: #if !defined(ARG_TYPE)
842: /*
843: * Simple front-end to _fatalerr()
844: */
845: /*VARARGS1*/
846: extern void fatalerr(fmt, a1, a2, a3, a4, a5)
847: char *fmt;
848: {
849: static char buf[MSGBUFSIZ];
850:
851: (void) sprintf(buf, fmt, a1, a2, a3, a4, a5);
852:
853: _fatalerr(buf);
854: }
855: #endif /* !ARG_TYPE */
856:
857: /*
858: * Get the name of the file used for notify.
859: * A side effect is that the file pointer to the file
860: * is closed. We assume this function is only called when
861: * we are ready to read the file.
862: */
863: extern char *getnotifyfile()
864: {
865: register int i;
866:
867: for (i = 0; msgfacility[i].mf_name; i++)
868: if (msgfacility[i].mf_msgfac == MF_NOTIFY &&
869: msgfacility[i].mf_fptr) {
870: (void) fclose(msgfacility[i].mf_fptr);
871: msgfacility[i].mf_fptr = NULL;
872: return(msgfacility[i].mf_filename);
873: }
874:
875: return((char *) NULL);
876: }