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

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