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