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

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