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

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