[BACK]Return to cfg.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / tmux

Annotation of src/usr.bin/tmux/cfg.c, Revision 1.13

1.13    ! nicm        1: /* $OpenBSD: cfg.c,v 1.12 2010/12/29 21:28:32 nicm Exp $ */
1.1       nicm        2:
                      3: /*
                      4:  * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
                     15:  * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
                     16:  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: #include <sys/types.h>
                     20: #include <sys/stat.h>
                     21:
                     22: #include <errno.h>
                     23: #include <stdio.h>
                     24: #include <string.h>
                     25:
                     26: #include "tmux.h"
                     27:
                     28: /*
                     29:  * Config file parser. Pretty quick and simple, each line is parsed into a
                     30:  * argv array and executed as a command.
                     31:  */
                     32:
                     33: void printflike2 cfg_print(struct cmd_ctx *, const char *, ...);
                     34: void printflike2 cfg_error(struct cmd_ctx *, const char *, ...);
                     35:
1.10      nicm       36: char                  *cfg_cause;
                     37: int                    cfg_finished;
                     38: struct causelist       cfg_causes = ARRAY_INITIALIZER;
1.1       nicm       39:
1.8       nicm       40: /* ARGSUSED */
1.1       nicm       41: void printflike2
                     42: cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
                     43: {
                     44: }
                     45:
1.8       nicm       46: /* ARGSUSED */
1.1       nicm       47: void printflike2
                     48: cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
                     49: {
                     50:        va_list ap;
                     51:
                     52:        va_start(ap, fmt);
                     53:        xvasprintf(&cfg_cause, fmt, ap);
                     54:        va_end(ap);
                     55: }
                     56:
1.10      nicm       57: void printflike2
                     58: cfg_add_cause(struct causelist *causes, const char *fmt, ...)
1.9       nicm       59: {
                     60:        char    *cause;
                     61:        va_list  ap;
                     62:
                     63:        va_start(ap, fmt);
                     64:        xvasprintf(&cause, fmt, ap);
                     65:        va_end(ap);
                     66:
1.10      nicm       67:        ARRAY_ADD(causes, cause);
1.9       nicm       68: }
                     69:
                     70: /*
                     71:  * Load configuration file. Returns -1 for an error with a list of messages in
1.11      nicm       72:  * causes. Note that causes must be initialised by the caller!
1.9       nicm       73:  */
1.1       nicm       74: int
1.10      nicm       75: load_cfg(const char *path, struct cmd_ctx *ctxin, struct causelist *causes)
1.1       nicm       76: {
1.7       deraadt    77:        FILE            *f;
1.1       nicm       78:        u_int            n;
1.9       nicm       79:        char            *buf, *line, *cause;
1.1       nicm       80:        size_t           len;
                     81:        struct cmd_list *cmdlist;
                     82:        struct cmd_ctx   ctx;
1.12      nicm       83:        int              retval;
1.1       nicm       84:
                     85:        if ((f = fopen(path, "rb")) == NULL) {
1.10      nicm       86:                cfg_add_cause(causes, "%s: %s", path, strerror(errno));
1.9       nicm       87:                return (-1);
1.1       nicm       88:        }
                     89:        n = 0;
                     90:
                     91:        line = NULL;
1.12      nicm       92:        retval = 0;
1.1       nicm       93:        while ((buf = fgetln(f, &len))) {
                     94:                if (buf[len - 1] == '\n')
1.13    ! nicm       95:                        len--;
        !            96:
        !            97:                if (line != NULL)
        !            98:                        line = xrealloc(line, 1, strlen(line) + len + 1);
1.1       nicm       99:                else {
1.13    ! nicm      100:                        line = xmalloc(len + 1);
        !           101:                        *line = '\0';
1.1       nicm      102:                }
1.13    ! nicm      103:
        !           104:                /* Append buffer to line. strncat will terminate. */
        !           105:                strncat(line, buf, len);
1.1       nicm      106:                n++;
                    107:
1.13    ! nicm      108:                /* Continuation: get next line? */
        !           109:                len = strlen(line);
        !           110:                if (len > 0 && line[len - 1] == '\\') {
        !           111:                        line[len - 1] = '\0';
        !           112:                        continue;
        !           113:                }
        !           114:                buf = line;
        !           115:                line = NULL;
        !           116:
1.9       nicm      117:                if (cmd_string_parse(buf, &cmdlist, &cause) != 0) {
1.13    ! nicm      118:                        xfree(buf);
1.9       nicm      119:                        if (cause == NULL)
1.1       nicm      120:                                continue;
1.10      nicm      121:                        cfg_add_cause(causes, "%s: %u: %s", path, n, cause);
1.9       nicm      122:                        xfree(cause);
                    123:                        continue;
1.13    ! nicm      124:                } else
        !           125:                        xfree(buf);
1.1       nicm      126:                if (cmdlist == NULL)
                    127:                        continue;
                    128:                cfg_cause = NULL;
                    129:
1.6       nicm      130:                if (ctxin == NULL) {
                    131:                        ctx.msgdata = NULL;
                    132:                        ctx.curclient = NULL;
                    133:                        ctx.cmdclient = NULL;
                    134:                } else {
                    135:                        ctx.msgdata = ctxin->msgdata;
                    136:                        ctx.curclient = ctxin->curclient;
                    137:                        ctx.cmdclient = ctxin->cmdclient;
                    138:                }
1.1       nicm      139:
                    140:                ctx.error = cfg_error;
                    141:                ctx.print = cfg_print;
                    142:                ctx.info = cfg_print;
                    143:
                    144:                cfg_cause = NULL;
1.12      nicm      145:                if (cmd_list_exec(cmdlist, &ctx) == 1)
                    146:                        retval = 1;
1.1       nicm      147:                cmd_list_free(cmdlist);
                    148:                if (cfg_cause != NULL) {
1.13    ! nicm      149:                        cfg_add_cause(
        !           150:                            causes, "%s: %d: %s", path, n, cfg_cause);
1.9       nicm      151:                        xfree(cfg_cause);
1.1       nicm      152:                }
                    153:        }
1.13    ! nicm      154:        if (line != NULL) {
        !           155:                cfg_add_cause(causes,
        !           156:                    "%s: %d: line continuation at end of file", path, n);
1.1       nicm      157:                xfree(line);
1.13    ! nicm      158:        }
1.1       nicm      159:        fclose(f);
                    160:
1.12      nicm      161:        return (retval);
1.1       nicm      162: }