Annotation of src/usr.bin/tmux/cfg.c, Revision 1.2
1.2 ! nicm 1: /* $OpenBSD: cfg.c,v 1.1 2009/06/01 22:58:49 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
54: load_cfg(const char *path, char **cause)
55: {
56: FILE *f;
57: u_int n;
58: struct stat sb;
59: char *buf, *line, *ptr;
60: size_t len;
61: struct cmd_list *cmdlist;
62: struct cmd_ctx ctx;
63:
64: if (stat(path, &sb) != 0) {
65: xasprintf(cause, "%s: %s", path, strerror(errno));
66: return (-1);
67: }
68: if (!S_ISREG(sb.st_mode)) {
69: xasprintf(cause, "%s: not a regular file", path);
70: return (-1);
71: }
72:
73: if ((f = fopen(path, "rb")) == NULL) {
74: xasprintf(cause, "%s: %s", path, strerror(errno));
75: return (1);
76: }
77: n = 0;
78:
79: line = NULL;
80: while ((buf = fgetln(f, &len))) {
81: if (buf[len - 1] == '\n')
82: buf[len - 1] = '\0';
83: else {
84: line = xrealloc(line, 1, len + 1);
85: memcpy(line, buf, len);
86: line[len] = '\0';
87: buf = line;
88: }
89: n++;
90:
91: if (cmd_string_parse(buf, &cmdlist, cause) != 0) {
92: if (*cause == NULL)
93: continue;
94: goto error;
95: }
96: if (cmdlist == NULL)
97: continue;
98: cfg_cause = NULL;
99:
100: ctx.msgdata = NULL;
101: ctx.cursession = NULL;
102: ctx.curclient = NULL;
103:
104: ctx.error = cfg_error;
105: ctx.print = cfg_print;
106: ctx.info = cfg_print;
107:
108: ctx.cmdclient = NULL;
109:
110: cfg_cause = NULL;
111: cmd_list_exec(cmdlist, &ctx);
112: cmd_list_free(cmdlist);
113: if (cfg_cause != NULL) {
114: *cause = cfg_cause;
115: goto error;
116: }
117: }
118: if (line != NULL)
119: xfree(line);
120: fclose(f);
121:
122: return (0);
123:
124: error:
125: fclose(f);
126:
127: xasprintf(&ptr, "%s: %s at line %u", path, *cause, n);
128: xfree(*cause);
129: *cause = ptr;
130: return (1);
131: }