[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.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: }