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