Annotation of src/usr.bin/tmux/cfg.c, Revision 1.7
1.7 ! deraadt 1: /* $OpenBSD: cfg.c,v 1.6 2009/08/23 17:29:51 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:
36: char *cfg_cause;
37:
38: void printflike2
39: cfg_print(unused struct cmd_ctx *ctx, unused const char *fmt, ...)
40: {
41: }
42:
43: void printflike2
44: cfg_error(unused struct cmd_ctx *ctx, const char *fmt, ...)
45: {
46: va_list ap;
47:
48: va_start(ap, fmt);
49: xvasprintf(&cfg_cause, fmt, ap);
50: va_end(ap);
51: }
52:
53: int
1.6 nicm 54: load_cfg(const char *path, struct cmd_ctx *ctxin, char **cause)
1.1 nicm 55: {
1.7 ! deraadt 56: FILE *f;
1.1 nicm 57: u_int n;
1.7 ! deraadt 58: char *buf, *line, *ptr;
1.1 nicm 59: size_t len;
60: struct cmd_list *cmdlist;
61: struct cmd_ctx ctx;
62:
63: if ((f = fopen(path, "rb")) == NULL) {
64: xasprintf(cause, "%s: %s", path, strerror(errno));
65: return (1);
66: }
67: n = 0;
68:
69: line = NULL;
70: while ((buf = fgetln(f, &len))) {
71: if (buf[len - 1] == '\n')
72: buf[len - 1] = '\0';
73: else {
74: line = xrealloc(line, 1, len + 1);
75: memcpy(line, buf, len);
76: line[len] = '\0';
77: buf = line;
78: }
79: n++;
80:
81: if (cmd_string_parse(buf, &cmdlist, cause) != 0) {
82: if (*cause == NULL)
83: continue;
84: goto error;
85: }
86: if (cmdlist == NULL)
87: continue;
88: cfg_cause = NULL;
89:
1.6 nicm 90: if (ctxin == NULL) {
91: ctx.msgdata = NULL;
92: ctx.curclient = NULL;
93: ctx.cmdclient = NULL;
94: } else {
95: ctx.msgdata = ctxin->msgdata;
96: ctx.curclient = ctxin->curclient;
97: ctx.cmdclient = ctxin->cmdclient;
98: }
1.1 nicm 99:
100: ctx.error = cfg_error;
101: ctx.print = cfg_print;
102: ctx.info = cfg_print;
103:
104: cfg_cause = NULL;
105: cmd_list_exec(cmdlist, &ctx);
106: cmd_list_free(cmdlist);
107: if (cfg_cause != NULL) {
108: *cause = cfg_cause;
109: goto error;
110: }
111: }
112: if (line != NULL)
113: xfree(line);
114: fclose(f);
115:
116: return (0);
117:
118: error:
1.4 nicm 119: if (line != NULL)
120: xfree(line);
1.1 nicm 121: fclose(f);
122:
123: xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);
124: xfree(*cause);
125: *cause = ptr;
126: return (1);
127: }