Annotation of src/usr.bin/rdist/message.c, Revision 1.17
1.17 ! chl 1: /* $OpenBSD: message.c,v 1.16 2007/09/11 15:47:17 gilles 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.17 ! chl 40: "$OpenBSD: message.c,v 1.16 2007/09/11 15:47:17 gilles 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;
1.1 dm 513: static char mbuf[2048];
514:
515: if (msgbuf && *msgbuf) {
516: /*
517: * Ensure no stray newlines are present
518: */
1.16 gilles 519: msgbuf[strcspn(msgbuf, "\n")] = CNULL;
1.1 dm 520:
521: checkhostname();
522: if (strncmp(currenthost, msgbuf, strlen(currenthost)) == 0)
1.14 millert 523: (void) strlcpy(mbuf, msgbuf, sizeof(mbuf));
1.1 dm 524: else
1.14 millert 525: (void) snprintf(mbuf, sizeof(mbuf),
526: "%s: %s", currenthost, msgbuf);
1.1 dm 527: } else
1.14 millert 528: mbuf[0] = '\0';
1.1 dm 529:
530: /*
531: * Special case for messages that only get
532: * logged to the system log facility
533: */
534: if (IS_ON(flags, MT_SYSLOG)) {
1.7 millert 535: msgsendsyslog(NULL, MT_SYSLOG, flags, mbuf);
1.1 dm 536: return;
537: }
538:
539: /*
540: * Special cases
541: */
1.5 millert 542: if (isserver && IS_ON(flags, MT_NOTICE)) {
1.7 millert 543: msgsendstdout(NULL, MT_NOTICE, flags, mbuf);
1.5 millert 544: return;
545: } else if (isserver && IS_ON(flags, MT_REMOTE))
1.7 millert 546: msgsendstdout(NULL, MT_REMOTE, flags, mbuf);
1.1 dm 547: else if (isserver && IS_ON(flags, MT_NERROR))
1.7 millert 548: msgsendstdout(NULL, MT_NERROR, flags, mbuf);
1.1 dm 549: else if (isserver && IS_ON(flags, MT_FERROR))
1.7 millert 550: msgsendstdout(NULL, MT_FERROR, flags, mbuf);
1.1 dm 551:
552: /*
553: * For each Message Facility, check each Message Type to see
554: * if the bits in "flags" are set. If so, call the appropriate
555: * Message Facility to dispatch the message.
556: */
557: for (i = 0; msgfacility[i].mf_name; ++i)
558: for (x = 0; msgtypes[x].mt_name; ++x)
559: /*
560: * XXX MT_ALL should not be used directly
561: */
562: if (msgtypes[x].mt_type != MT_ALL &&
563: IS_ON(flags, msgtypes[x].mt_type) &&
564: IS_ON(msgfacility[i].mf_msgtypes,
565: msgtypes[x].mt_type))
566: (*msgfacility[i].mf_sendfunc)(&msgfacility[i],
567: msgtypes[x].mt_type,
568: flags,
569: mbuf);
570: }
571:
572: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
573: /*
574: * Varargs front-end to _message()
575: */
1.14 millert 576: void
577: message(va_alist)
1.1 dm 578: va_dcl
579: {
580: static char buf[MSGBUFSIZ];
581: va_list args;
582: char *fmt;
583: int lvl;
584:
585: va_start(args);
586: lvl = (int) va_arg(args, int);
587: fmt = (char *) va_arg(args, char *);
588: va_end(args);
589:
1.14 millert 590: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 591:
592: _message(lvl, buf);
593: }
594: #endif /* ARG_VARARGS */
595:
596: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
597: /*
598: * Stdarg front-end to _message()
599: */
1.14 millert 600: void
601: message(int lvl, char *fmt, ...)
1.1 dm 602: {
603: static char buf[MSGBUFSIZ];
604: va_list args;
605:
606: va_start(args, fmt);
1.14 millert 607: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 608: va_end(args);
609:
610: _message(lvl, buf);
611: }
612: #endif /* ARG_STDARG */
613:
614: /*
615: * Display a debugging message
616: */
1.14 millert 617: static void
618: _debugmsg(int lvl, char *buf)
1.1 dm 619: {
620: if (IS_ON(debug, lvl))
621: _message(MT_DEBUG, buf);
622: }
623:
624: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
625: /*
626: * Varargs front-end to _debugmsg()
627: */
1.14 millert 628: void
629: debugmsg(va_alist)
1.1 dm 630: va_dcl
631: {
632: static char buf[MSGBUFSIZ];
633: va_list args;
634: char *fmt;
635: int lvl;
636:
637: va_start(args);
638: lvl = (int) va_arg(args, int);
639: fmt = (char *) va_arg(args, char *);
640: va_end(args);
641:
1.14 millert 642: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 643:
644: _debugmsg(lvl, buf);
645: }
646: #endif /* ARG_VARARGS */
647:
648: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
649: /*
650: * Stdarg front-end to _debugmsg()
651: */
1.14 millert 652: void
653: debugmsg(int lvl, char *fmt, ...)
1.1 dm 654: {
655: static char buf[MSGBUFSIZ];
656: va_list args;
657:
658: va_start(args, fmt);
1.14 millert 659: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 660: va_end(args);
661:
662: _debugmsg(lvl, buf);
663: }
664: #endif /* ARG_STDARG */
665:
666: /*
667: * Print an error message
668: */
1.14 millert 669: static void
670: _error(char *msg)
1.1 dm 671: {
672: static char buf[MSGBUFSIZ];
673:
674: nerrs++;
675: buf[0] = CNULL;
676:
677: if (msg) {
678: if (isserver)
1.14 millert 679: (void) snprintf(buf, sizeof(buf),
680: "REMOTE ERROR: %s", msg);
1.1 dm 681: else
1.14 millert 682: (void) snprintf(buf, sizeof(buf),
683: "LOCAL ERROR: %s", msg);
1.1 dm 684: }
685:
686: _message(MT_NERROR, (buf[0]) ? buf : NULL);
687: }
688:
689: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
690: /*
691: * Varargs frontend to _error()
692: */
1.14 millert 693: void
694: error(va_alist)
1.1 dm 695: va_dcl
696: {
697: static char buf[MSGBUFSIZ];
698: va_list args;
699: char *fmt;
700:
701: buf[0] = CNULL;
702: va_start(args);
703: fmt = (char *) va_arg(args, char *);
704: if (fmt)
1.14 millert 705: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 706: va_end(args);
707:
708: _error((buf[0]) ? buf : NULL);
709: }
710: #endif /* ARG_VARARGS */
711:
712: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
713: /*
714: * Stdarg frontend to _error()
715: */
1.14 millert 716: void
717: error(char *fmt, ...)
1.1 dm 718: {
719: static char buf[MSGBUFSIZ];
720: va_list args;
721:
722: buf[0] = CNULL;
723: va_start(args, fmt);
724: if (fmt)
1.14 millert 725: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 726: va_end(args);
727:
728: _error((buf[0]) ? buf : NULL);
729: }
730: #endif /* ARG_STDARG */
731:
732: /*
733: * Display a fatal message
734: */
1.14 millert 735: static void
736: _fatalerr(char *msg)
1.1 dm 737: {
738: static char buf[MSGBUFSIZ];
739:
740: ++nerrs;
741:
742: if (isserver)
1.14 millert 743: (void) snprintf(buf, sizeof(buf), "REMOTE ERROR: %s", msg);
1.1 dm 744: else
1.14 millert 745: (void) snprintf(buf, sizeof(buf), "LOCAL ERROR: %s", msg);
1.1 dm 746:
747: _message(MT_FERROR, buf);
748:
749: exit(nerrs);
750: }
751:
752: #if defined(ARG_TYPE) && ARG_TYPE == ARG_VARARGS
753: /*
754: * Varargs front-end to _fatalerr()
755: */
1.14 millert 756: void
757: fatalerr(va_alist)
1.1 dm 758: va_dcl
759: {
760: static char buf[MSGBUFSIZ];
761: va_list args;
762: char *fmt;
763:
764: va_start(args);
765: fmt = (char *) va_arg(args, char *);
1.14 millert 766: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 767: va_end(args);
768:
769: _fatalerr(buf);
770: }
771: #endif /* ARG_VARARGS */
772:
773: #if defined(ARG_TYPE) && ARG_TYPE == ARG_STDARG
774: /*
775: * Stdarg front-end to _fatalerr()
776: */
1.14 millert 777: void
778: fatalerr(char *fmt, ...)
1.1 dm 779: {
780: static char buf[MSGBUFSIZ];
781: va_list args;
782:
783: va_start(args, fmt);
1.14 millert 784: (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1 dm 785: va_end(args);
786:
787: _fatalerr(buf);
788: }
789: #endif /* ARG_STDARG */
790:
791: /*
792: * Get the name of the file used for notify.
793: * A side effect is that the file pointer to the file
794: * is closed. We assume this function is only called when
795: * we are ready to read the file.
796: */
1.14 millert 797: char *
798: getnotifyfile(void)
1.1 dm 799: {
1.10 mpech 800: int i;
1.1 dm 801:
802: for (i = 0; msgfacility[i].mf_name; i++)
803: if (msgfacility[i].mf_msgfac == MF_NOTIFY &&
804: msgfacility[i].mf_fptr) {
805: (void) fclose(msgfacility[i].mf_fptr);
806: msgfacility[i].mf_fptr = NULL;
807: return(msgfacility[i].mf_filename);
808: }
809:
1.7 millert 810: return(NULL);
1.1 dm 811: }