[BACK]Return to message.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / rdist

Annotation of src/usr.bin/rdist/message.c, Revision 1.29

1.29    ! deraadt     1: /*     $OpenBSD: message.c,v 1.28 2016/03/30 20:51:59 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.27      guenther   32: #include <errno.h>
                     33: #include <limits.h>
                     34: #include <paths.h>
                     35: #include <stdarg.h>
                     36: #include <stdio.h>
                     37: #include <stdlib.h>
                     38: #include <string.h>
1.23      guenther   39: #include <syslog.h>
1.27      guenther   40: #include <unistd.h>
                     41:
1.14      millert    42: #include "defs.h"
1.1       dm         43:
                     44: /*
                     45:  * Message handling functions for both rdist and rdistd.
                     46:  */
                     47:
                     48:
                     49: #define MSGBUFSIZ      32*1024
                     50:
                     51: int                    debug = 0;              /* Debugging level */
                     52: int                    nerrs = 0;              /* Number of errors */
                     53:
                     54: /*
                     55:  * Message Types
                     56:  */
1.24      guenther   57: struct msgtype {
                     58:        int             mt_type;                /* Type (bit) */
                     59:        char           *mt_name;                /* Name of message type */
                     60: } msgtypes[] = {
1.1       dm         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:
1.24      guenther   73: /*
                     74:  * Description of message facilities
                     75:  */
                     76: struct msgfacility {
                     77:        /* compile time initialized data */
                     78:        int             mf_msgfac;              /* One of MF_* from below */
                     79:        char           *mf_name;                /* Name of this facility */
                     80:        void          (*mf_sendfunc)            /* Function to send msg */
                     81:                        (struct msgfacility *, int, int, char *);
                     82:        /* run time initialized data */
                     83:        int             mf_msgtypes;            /* Bitmask of MT_* from above*/
                     84:        char           *mf_filename;            /* Name of file */
                     85:        FILE           *mf_fptr;                /* File pointer to output to */
                     86: };
1.25      guenther   87:
                     88: /*
                     89:  * Message Facilities
                     90:  */
                     91: #define MF_STDOUT      1                       /* Standard Output */
                     92: #define MF_NOTIFY      2                       /* Notify mail service */
                     93: #define MF_FILE                3                       /* A normal file */
                     94: #define MF_SYSLOG      4                       /* syslog() */
1.24      guenther   95:
                     96: static void msgsendstdout(struct msgfacility *, int, int, char *);
                     97: static void msgsendsyslog(struct msgfacility *, int, int, char *);
                     98: static void msgsendfile(struct msgfacility *, int, int, char *);
                     99: static void msgsendnotify(struct msgfacility *, int, int, char *);
1.1       dm        100:
                    101: /*
                    102:  * Message Facilities
                    103:  */
1.24      guenther  104: struct msgfacility msgfacility[] = {
1.1       dm        105:        { MF_STDOUT,    "stdout",       msgsendstdout },
                    106:        { MF_FILE,      "file",         msgsendfile },
                    107:        { MF_SYSLOG,    "syslog",       msgsendsyslog },
                    108:        { MF_NOTIFY,    "notify",       msgsendnotify },
                    109:        { 0 },
                    110: };
                    111:
1.24      guenther  112: static struct msgfacility *getmsgfac(char *);
                    113: static struct msgtype *getmsgtype(char *);
                    114: static char *setmsgtypes(struct msgfacility *, char *);
1.14      millert   115: static void _message(int, char *);
                    116: static void _debugmsg(int, char *);
1.19      guenther  117: static void _error(const char *);
                    118: static void _fatalerr(const char *);
1.14      millert   119:
1.1       dm        120: /*
                    121:  * Print message logging usage message
                    122:  */
1.14      millert   123: void
                    124: msgprusage(void)
1.1       dm        125: {
1.10      mpech     126:        int i, x;
1.1       dm        127:
                    128:        (void) fprintf(stderr, "\nWhere <msgopt> is of form\n");
                    129:        (void) fprintf(stderr,
                    130:        "\t<facility1>=<type1>,<type2>,...:<facility2>=<type1>,<type2>...\n");
                    131:
                    132:        (void) fprintf(stderr, "Valid <facility> names:");
                    133:
                    134:        for (i = 0; msgfacility[i].mf_name; ++i)
                    135:                (void) fprintf(stderr, " %s", msgfacility[i].mf_name);
                    136:
                    137:        (void) fprintf(stderr, "\nValid <type> names:");
                    138:        for (x = 0; msgtypes[x].mt_name; ++x)
                    139:                (void) fprintf(stderr, " %s", msgtypes[x].mt_name);
                    140:
                    141:        (void) fprintf(stderr, "\n");
                    142: }
                    143:
                    144: /*
                    145:  * Print enabled message logging info
                    146:  */
1.14      millert   147: void
                    148: msgprconfig(void)
1.1       dm        149: {
1.10      mpech     150:        int i, x;
1.1       dm        151:        static char buf[MSGBUFSIZ];
                    152:
                    153:        debugmsg(DM_MISC, "Current message logging config:");
                    154:        for (i = 0; msgfacility[i].mf_name; ++i) {
1.14      millert   155:                (void) snprintf(buf, sizeof(buf), "    %.*s=",
                    156:                               (int)(sizeof(buf) - 7), msgfacility[i].mf_name);
1.1       dm        157:                for (x = 0; msgtypes[x].mt_name; ++x)
                    158:                        if (IS_ON(msgfacility[i].mf_msgtypes,
                    159:                                  msgtypes[x].mt_type)) {
                    160:                                if (x > 0)
1.14      millert   161:                                        (void) strlcat(buf, ",", sizeof(buf));
1.12      deraadt   162:                                (void) strlcat(buf, msgtypes[x].mt_name,
1.14      millert   163:                                    sizeof(buf));
1.1       dm        164:                        }
                    165:                debugmsg(DM_MISC, "%s", buf);
                    166:        }
                    167:
                    168: }
                    169:
                    170: /*
                    171:  * Get the Message Facility entry "name"
                    172:  */
1.24      guenther  173: static struct msgfacility *
1.14      millert   174: getmsgfac(char *name)
1.1       dm        175: {
1.10      mpech     176:        int i;
1.1       dm        177:
                    178:        for (i = 0; msgfacility[i].mf_name; ++i)
                    179:                if (strcasecmp(name, msgfacility[i].mf_name) == 0)
                    180:                        return(&msgfacility[i]);
                    181:
1.7       millert   182:        return(NULL);
1.1       dm        183: }
                    184:
                    185: /*
                    186:  * Get the Message Type entry named "name"
                    187:  */
1.24      guenther  188: static struct msgtype *
1.14      millert   189: getmsgtype(char *name)
1.1       dm        190: {
1.10      mpech     191:        int i;
1.1       dm        192:
                    193:        for (i = 0; msgtypes[i].mt_name; ++i)
                    194:                if (strcasecmp(name, msgtypes[i].mt_name) == 0)
                    195:                        return(&msgtypes[i]);
                    196:
1.7       millert   197:        return(NULL);
1.1       dm        198: }
                    199:
                    200: /*
                    201:  * Set Message Type information for Message Facility "msgfac" as
                    202:  * indicated by string "str".
                    203:  */
1.14      millert   204: static char *
1.24      guenther  205: setmsgtypes(struct msgfacility *msgfac, char *str)
1.1       dm        206: {
                    207:        static char ebuf[BUFSIZ];
1.10      mpech     208:        char *cp;
                    209:        char *strptr, *word;
1.24      guenther  210:        struct msgtype *mtp;
1.1       dm        211:
                    212:        /*
                    213:         * MF_SYSLOG is the only supported message facility for the server
                    214:         */
                    215:        if (isserver && (msgfac->mf_msgfac != MF_SYSLOG &&
                    216:                         msgfac->mf_msgfac != MF_FILE)) {
1.5       millert   217:                (void) snprintf(ebuf, sizeof(ebuf),
1.14      millert   218:                "The \"%.*s\" message facility cannot be used by the server.",
                    219:                                100, msgfac->mf_name);
1.1       dm        220:                return(ebuf);
                    221:        }
                    222:
                    223:        strptr = str;
                    224:
                    225:        /*
                    226:         * Do any necessary Message Facility preparation
                    227:         */
                    228:        switch(msgfac->mf_msgfac) {
                    229:        case MF_FILE:
                    230:                /*
                    231:                 * The MF_FILE string should look like "<file>=<types>".
                    232:                 */
                    233:                if ((cp = strchr(strptr, '=')) == NULL)
                    234:                        return(
                    235:                           "No file name found for \"file\" message facility");
                    236:                *cp++ = CNULL;
                    237:
                    238:                if ((msgfac->mf_fptr = fopen(strptr, "w")) == NULL)
                    239:                        fatalerr("Cannot open log file for writing: %s: %s.",
                    240:                                 strptr, SYSERR);
1.8       millert   241:                msgfac->mf_filename = xstrdup(strptr);
1.1       dm        242:
                    243:                strptr = cp;
                    244:                break;
                    245:
                    246:        case MF_NOTIFY:
                    247:                break;
                    248:
                    249:        case MF_STDOUT:
                    250:                msgfac->mf_fptr = stdout;
                    251:                break;
                    252:
                    253:        case MF_SYSLOG:
1.26      guenther  254:                openlog(progname, LOG_PID, LOG_DAEMON);
1.1       dm        255:                break;
                    256:        }
                    257:
                    258:        /*
                    259:         * Parse each type word
                    260:         */
                    261:        msgfac->mf_msgtypes = 0;        /* Start from scratch */
                    262:        while (strptr) {
                    263:                word = strptr;
1.14      millert   264:                if ((cp = strchr(strptr, ',')) != NULL)
1.1       dm        265:                        *cp++ = CNULL;
                    266:                strptr = cp;
                    267:
1.14      millert   268:                if ((mtp = getmsgtype(word)) != NULL) {
1.1       dm        269:                        msgfac->mf_msgtypes |= mtp->mt_type;
                    270:                        /*
                    271:                         * XXX This is really a kludge until we add real
                    272:                         * control over debugging.
                    273:                         */
                    274:                        if (!debug && isserver &&
                    275:                            strcasecmp(word, "debug") == 0)
                    276:                                debug = DM_ALL;
                    277:                } else {
1.5       millert   278:                        (void) snprintf(ebuf, sizeof(ebuf),
1.14      millert   279:                                        "Message type \"%.*s\" is invalid.",
                    280:                                        100, word);
1.1       dm        281:                        return(ebuf);
                    282:                }
                    283:        }
                    284:
1.7       millert   285:        return(NULL);
1.1       dm        286: }
                    287:
                    288: /*
                    289:  * Parse a message logging option string
                    290:  */
1.14      millert   291: char *
                    292: msgparseopts(char *msgstr, int doset)
1.1       dm        293: {
                    294:        static char ebuf[BUFSIZ], msgbuf[MSGBUFSIZ];
1.10      mpech     295:        char *cp, *optstr;
                    296:        char *word;
1.24      guenther  297:        struct msgfacility *msgfac;
1.1       dm        298:
                    299:        if (msgstr == NULL)
                    300:                return("NULL message string");
                    301:
                    302:        /* strtok() is harmful */
1.14      millert   303:        (void) strlcpy(msgbuf, msgstr, sizeof(msgbuf));
1.1       dm        304:
                    305:        /*
1.9       provos    306:         * Each <facility>=<types> list is separated by ":".
1.1       dm        307:         */
                    308:        for (optstr = strtok(msgbuf, ":"); optstr;
1.7       millert   309:             optstr = strtok(NULL, ":")) {
1.1       dm        310:
                    311:                if ((cp = strchr(optstr, '=')) == NULL)
                    312:                        return("No '=' found");
                    313:
                    314:                *cp++ = CNULL;
                    315:                word = optstr;
                    316:                if ((int)strlen(word) <= 0)
                    317:                        return("No message facility specified");
                    318:                if ((int)strlen(cp) <= 0)
                    319:                        return("No message type specified");
                    320:
                    321:                if ((msgfac = getmsgfac(word)) == NULL) {
1.5       millert   322:                        (void) snprintf(ebuf, sizeof(ebuf),
1.14      millert   323:                                        "%.*s is not a valid message facility",
                    324:                                        100, word);
1.1       dm        325:                        return(ebuf);
                    326:                }
                    327:
                    328:                if (doset) {
                    329:                        char *mcp;
                    330:
1.14      millert   331:                        if ((mcp = setmsgtypes(msgfac, cp)) != NULL)
1.1       dm        332:                                return(mcp);
                    333:                }
                    334:        }
                    335:
                    336:        if (isserver && debug) {
                    337:                debugmsg(DM_MISC, "%s", getversion());
                    338:                msgprconfig();
                    339:        }
                    340:
1.7       millert   341:        return(NULL);
1.1       dm        342: }
                    343:
                    344: /*
                    345:  * Send a message to facility "stdout".
                    346:  * For rdistd, this is really the rdist client.
                    347:  */
1.14      millert   348: static void
1.24      guenther  349: msgsendstdout(struct msgfacility *msgfac, int mtype, int flags, char *msgbuf)
1.1       dm        350: {
                    351:        char cmd;
                    352:
                    353:        if (isserver) {
                    354:                if (rem_w < 0 || IS_ON(flags, MT_NOREMOTE))
                    355:                        return;
                    356:
                    357:                cmd = CNULL;
                    358:
                    359:                switch(mtype) {
                    360:                case MT_NERROR:         cmd = C_ERRMSG;         break;
                    361:                case MT_FERROR:         cmd = C_FERRMSG;        break;
                    362:                case MT_NOTICE:         cmd = C_NOTEMSG;        break;
                    363:                case MT_REMOTE:         cmd = C_LOGMSG;         break;
                    364:                }
                    365:
                    366:                if (cmd != CNULL)
                    367:                        (void) sendcmd(cmd, "%s", msgbuf);
                    368:        } else {
                    369:                switch(mtype) {
                    370:                case MT_FERROR:
                    371:                case MT_NERROR:
                    372:                        if (msgbuf && *msgbuf) {
                    373:                                (void) fprintf(stderr, "%s\n", msgbuf);
                    374:                                (void) fflush(stderr);
                    375:                        }
                    376:                        break;
                    377:
                    378:                case MT_DEBUG:
                    379:                        /*
                    380:                         * Only things that are strictly MT_DEBUG should
                    381:                         * be shown.
                    382:                         */
                    383:                        if (flags != MT_DEBUG)
                    384:                                return;
                    385:                case MT_NOTICE:
                    386:                case MT_CHANGE:
                    387:                case MT_INFO:
                    388:                case MT_VERBOSE:
                    389:                case MT_WARNING:
                    390:                        if (msgbuf && *msgbuf) {
                    391:                                (void) printf("%s\n", msgbuf);
                    392:                                (void) fflush(stdout);
                    393:                        }
                    394:                        break;
                    395:                }
                    396:        }
                    397: }
                    398:
                    399: /*
                    400:  * Send a message to facility "syslog"
                    401:  */
1.14      millert   402: static void
1.24      guenther  403: msgsendsyslog(struct msgfacility *msgfac, int mtype, int flags, char *msgbuf)
1.1       dm        404: {
                    405:        int syslvl = 0;
                    406:
                    407:        if (!msgbuf || !*msgbuf)
                    408:                return;
                    409:
                    410:        switch(mtype) {
                    411: #if    defined(SL_NERROR)
                    412:        case MT_NERROR:         syslvl = SL_NERROR;     break;
                    413: #endif
                    414: #if    defined(SL_FERROR)
                    415:        case MT_FERROR:         syslvl = SL_FERROR;     break;
                    416: #endif
                    417: #if    defined(SL_WARNING)
                    418:        case MT_WARNING:        syslvl = SL_WARNING;    break;
                    419: #endif
                    420: #if    defined(SL_CHANGE)
                    421:        case MT_CHANGE:         syslvl = SL_CHANGE;     break;
                    422: #endif
                    423: #if    defined(SL_INFO)
                    424:        case MT_SYSLOG:
                    425:        case MT_VERBOSE:
                    426:        case MT_INFO:           syslvl = SL_INFO;       break;
                    427: #endif
                    428: #if    defined(SL_NOTICE)
                    429:        case MT_NOTICE:         syslvl = SL_NOTICE;     break;
                    430: #endif
                    431: #if    defined(SL_DEBUG)
                    432:        case MT_DEBUG:          syslvl = SL_DEBUG;      break;
                    433: #endif
                    434:        }
                    435:
                    436:        if (syslvl)
                    437:                syslog(syslvl, "%s", msgbuf);
                    438: }
                    439:
                    440: /*
                    441:  * Send a message to a "file" facility.
                    442:  */
1.14      millert   443: static void
1.24      guenther  444: msgsendfile(struct msgfacility *msgfac, int mtype, int flags, char *msgbuf)
1.1       dm        445: {
                    446:        if (msgfac->mf_fptr == NULL)
                    447:                return;
                    448:
                    449:        if (!msgbuf || !*msgbuf)
                    450:                return;
                    451:
                    452:        (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
                    453:        (void) fflush(msgfac->mf_fptr);
                    454: }
                    455:
                    456: /*
                    457:  * Same method as msgsendfile()
                    458:  */
1.14      millert   459: static void
1.24      guenther  460: msgsendnotify(struct msgfacility *msgfac, int mtype, int flags, char *msgbuf)
1.1       dm        461: {
1.13      millert   462:        char *tempfile;
                    463:
1.1       dm        464:        if (IS_ON(flags, MT_DEBUG))
                    465:                return;
                    466:
                    467:        if (!msgbuf || !*msgbuf)
                    468:                return;
                    469:
                    470:        if (!msgfac->mf_fptr) {
1.10      mpech     471:                char *cp;
1.7       millert   472:                int fd;
1.11      deraadt   473:                size_t len;
1.1       dm        474:
                    475:                /*
                    476:                 * Create and open a new temporary file
                    477:                 */
1.14      millert   478:                if ((cp = getenv("TMPDIR")) == NULL || *cp == '\0')
1.1       dm        479:                        cp = _PATH_TMP;
1.13      millert   480:                len = strlen(cp) + 1 + sizeof(_RDIST_TMP);
1.20      guenther  481:                tempfile = xmalloc(len);
1.11      deraadt   482:                (void) snprintf(tempfile, len, "%s/%s", cp, _RDIST_TMP);
1.1       dm        483:
                    484:                msgfac->mf_filename = tempfile;
1.29    ! deraadt   485:                if ((fd = mkstemp(msgfac->mf_filename)) == -1 ||
1.14      millert   486:                    (msgfac->mf_fptr = fdopen(fd, "w")) == NULL)
                    487:                    fatalerr("Cannot open notify file for writing: %s: %s.",
                    488:                        msgfac->mf_filename, SYSERR);
1.1       dm        489:                debugmsg(DM_MISC, "Created notify temp file '%s'",
                    490:                         msgfac->mf_filename);
                    491:        }
                    492:
                    493:        if (msgfac->mf_fptr == NULL)
                    494:                return;
                    495:
                    496:        (void) fprintf(msgfac->mf_fptr, "%s\n", msgbuf);
                    497:        (void) fflush(msgfac->mf_fptr);
                    498: }
                    499:
                    500: /*
                    501:  * Insure currenthost is set to something reasonable.
                    502:  */
1.14      millert   503: void
                    504: checkhostname(void)
1.1       dm        505: {
1.22      deraadt   506:        static char mbuf[HOST_NAME_MAX+1];
1.1       dm        507:        char *cp;
                    508:
                    509:        if (!currenthost) {
                    510:                if (gethostname(mbuf, sizeof(mbuf)) == 0) {
                    511:                        if ((cp = strchr(mbuf, '.')) != NULL)
                    512:                                *cp = CNULL;
1.8       millert   513:                        currenthost = xstrdup(mbuf);
1.1       dm        514:                } else
                    515:                        currenthost = "(unknown)";
                    516:        }
                    517: }
                    518:
                    519: /*
                    520:  * Print a message contained in "msgbuf" if a level "lvl" is set.
                    521:  */
1.14      millert   522: static void
                    523: _message(int flags, char *msgbuf)
1.1       dm        524: {
1.10      mpech     525:        int i, x;
1.1       dm        526:        static char mbuf[2048];
                    527:
                    528:        if (msgbuf && *msgbuf) {
                    529:                /*
                    530:                 * Ensure no stray newlines are present
                    531:                 */
1.16      gilles    532:                msgbuf[strcspn(msgbuf, "\n")] = CNULL;
1.1       dm        533:
                    534:                checkhostname();
                    535:                if (strncmp(currenthost, msgbuf, strlen(currenthost)) == 0)
1.14      millert   536:                        (void) strlcpy(mbuf, msgbuf, sizeof(mbuf));
1.1       dm        537:                else
1.14      millert   538:                        (void) snprintf(mbuf, sizeof(mbuf),
                    539:                                        "%s: %s", currenthost, msgbuf);
1.1       dm        540:        } else
1.14      millert   541:                mbuf[0] = '\0';
1.1       dm        542:
                    543:        /*
                    544:         * Special case for messages that only get
                    545:         * logged to the system log facility
                    546:         */
                    547:        if (IS_ON(flags, MT_SYSLOG)) {
1.7       millert   548:                msgsendsyslog(NULL, MT_SYSLOG, flags, mbuf);
1.1       dm        549:                return;
                    550:        }
                    551:
                    552:        /*
                    553:         * Special cases
                    554:         */
1.5       millert   555:        if (isserver && IS_ON(flags, MT_NOTICE)) {
1.7       millert   556:                msgsendstdout(NULL, MT_NOTICE, flags, mbuf);
1.5       millert   557:                return;
                    558:        } else if (isserver && IS_ON(flags, MT_REMOTE))
1.7       millert   559:                msgsendstdout(NULL, MT_REMOTE, flags, mbuf);
1.1       dm        560:        else if (isserver && IS_ON(flags, MT_NERROR))
1.7       millert   561:                msgsendstdout(NULL, MT_NERROR, flags, mbuf);
1.1       dm        562:        else if (isserver && IS_ON(flags, MT_FERROR))
1.7       millert   563:                msgsendstdout(NULL, MT_FERROR, flags, mbuf);
1.1       dm        564:
                    565:        /*
                    566:         * For each Message Facility, check each Message Type to see
                    567:         * if the bits in "flags" are set.  If so, call the appropriate
                    568:         * Message Facility to dispatch the message.
                    569:         */
                    570:        for (i = 0; msgfacility[i].mf_name; ++i)
                    571:                for (x = 0; msgtypes[x].mt_name; ++x)
                    572:                        /*
                    573:                         * XXX MT_ALL should not be used directly
                    574:                         */
                    575:                        if (msgtypes[x].mt_type != MT_ALL &&
                    576:                            IS_ON(flags, msgtypes[x].mt_type) &&
                    577:                            IS_ON(msgfacility[i].mf_msgtypes,
                    578:                                  msgtypes[x].mt_type))
                    579:                                (*msgfacility[i].mf_sendfunc)(&msgfacility[i],
                    580:                                                           msgtypes[x].mt_type,
                    581:                                                              flags,
                    582:                                                              mbuf);
                    583: }
                    584:
                    585: /*
1.21      guenther  586:  * Front-end to _message()
1.1       dm        587:  */
1.14      millert   588: void
1.19      guenther  589: message(int lvl, const char *fmt, ...)
1.1       dm        590: {
                    591:        static char buf[MSGBUFSIZ];
                    592:        va_list args;
                    593:
1.28      millert   594:        if (fmt != NULL) {
                    595:                va_start(args, fmt);
                    596:                (void) vsnprintf(buf, sizeof(buf), fmt, args);
                    597:                va_end(args);
                    598:        }
1.1       dm        599:
1.28      millert   600:        _message(lvl, fmt ? buf : NULL);
1.1       dm        601: }
                    602:
                    603: /*
                    604:  * Display a debugging message
                    605:  */
1.14      millert   606: static void
                    607: _debugmsg(int lvl, char *buf)
1.1       dm        608: {
                    609:        if (IS_ON(debug, lvl))
                    610:                _message(MT_DEBUG, buf);
                    611: }
                    612:
                    613: /*
1.21      guenther  614:  * Front-end to _debugmsg()
1.1       dm        615:  */
1.14      millert   616: void
1.19      guenther  617: debugmsg(int lvl, const char *fmt, ...)
1.1       dm        618: {
                    619:        static char buf[MSGBUFSIZ];
                    620:        va_list args;
                    621:
                    622:        va_start(args, fmt);
1.14      millert   623:        (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1       dm        624:        va_end(args);
                    625:
                    626:        _debugmsg(lvl, buf);
                    627: }
                    628:
                    629: /*
                    630:  * Print an error message
                    631:  */
1.14      millert   632: static void
1.19      guenther  633: _error(const char *msg)
1.1       dm        634: {
                    635:        static char buf[MSGBUFSIZ];
                    636:
                    637:        nerrs++;
                    638:        buf[0] = CNULL;
                    639:
                    640:        if (msg) {
                    641:                if (isserver)
1.14      millert   642:                        (void) snprintf(buf, sizeof(buf),
                    643:                                        "REMOTE ERROR: %s", msg);
1.1       dm        644:                else
1.14      millert   645:                        (void) snprintf(buf, sizeof(buf),
                    646:                                        "LOCAL ERROR: %s", msg);
1.1       dm        647:        }
                    648:
                    649:        _message(MT_NERROR, (buf[0]) ? buf : NULL);
                    650: }
                    651:
                    652: /*
1.21      guenther  653:  * Frontend to _error()
1.1       dm        654:  */
1.14      millert   655: void
1.19      guenther  656: error(const char *fmt, ...)
1.1       dm        657: {
                    658:        static char buf[MSGBUFSIZ];
                    659:        va_list args;
                    660:
                    661:        buf[0] = CNULL;
                    662:        va_start(args, fmt);
                    663:        if (fmt)
1.14      millert   664:                (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1       dm        665:        va_end(args);
                    666:
                    667:        _error((buf[0]) ? buf : NULL);
                    668: }
                    669:
                    670: /*
                    671:  * Display a fatal message
                    672:  */
1.14      millert   673: static void
1.19      guenther  674: _fatalerr(const char *msg)
1.1       dm        675: {
                    676:        static char buf[MSGBUFSIZ];
                    677:
                    678:        ++nerrs;
                    679:
                    680:        if (isserver)
1.14      millert   681:                (void) snprintf(buf, sizeof(buf), "REMOTE ERROR: %s", msg);
1.1       dm        682:        else
1.14      millert   683:                (void) snprintf(buf, sizeof(buf), "LOCAL ERROR: %s", msg);
1.1       dm        684:
                    685:        _message(MT_FERROR, buf);
                    686:
                    687:        exit(nerrs);
                    688: }
                    689:
                    690: /*
1.21      guenther  691:  * Front-end to _fatalerr()
1.1       dm        692:  */
1.14      millert   693: void
1.19      guenther  694: fatalerr(const char *fmt, ...)
1.1       dm        695: {
                    696:        static char buf[MSGBUFSIZ];
                    697:        va_list args;
                    698:
                    699:        va_start(args, fmt);
1.14      millert   700:        (void) vsnprintf(buf, sizeof(buf), fmt, args);
1.1       dm        701:        va_end(args);
                    702:
                    703:        _fatalerr(buf);
                    704: }
                    705:
                    706: /*
                    707:  * Get the name of the file used for notify.
                    708:  * A side effect is that the file pointer to the file
                    709:  * is closed.  We assume this function is only called when
                    710:  * we are ready to read the file.
                    711:  */
1.14      millert   712: char *
                    713: getnotifyfile(void)
1.1       dm        714: {
1.10      mpech     715:        int i;
1.1       dm        716:
                    717:        for (i = 0; msgfacility[i].mf_name; i++)
                    718:                if (msgfacility[i].mf_msgfac == MF_NOTIFY &&
                    719:                    msgfacility[i].mf_fptr) {
                    720:                        (void) fclose(msgfacility[i].mf_fptr);
                    721:                        msgfacility[i].mf_fptr = NULL;
                    722:                        return(msgfacility[i].mf_filename);
                    723:                }
                    724:
1.7       millert   725:        return(NULL);
1.1       dm        726: }