[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.24

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