4 * Copyright (c) 2008 Nicholas Marriott <nicm@users.sourceforge.net>
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.
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.
19 #include <sys/types.h>
30 struct cmd_q
*cfg_cmd_q
;
33 struct causelist cfg_causes
;
34 struct client
*cfg_client
;
37 load_cfg(const char *path
, struct cmd_q
*cmdq
, char **cause
)
41 char *buf
, *copy
, *line
, *cause1
, *msg
;
43 struct cmd_list
*cmdlist
;
45 log_debug("loading %s", path
);
46 if ((f
= fopen(path
, "rb")) == NULL
) {
47 xasprintf(cause
, "%s: %s", path
, strerror(errno
));
53 while ((buf
= fgetln(f
, &len
))) {
55 if (buf
[len
- 1] == '\n')
57 log_debug("%s: %.*s", path
, (int)len
, buf
);
59 /* Current line is the continuation of the previous one. */
61 oldlen
= strlen(line
);
62 line
= xrealloc(line
, 1, oldlen
+ len
+ 1);
65 line
= xmalloc(len
+ 1);
68 /* Append current line to the previous. */
69 memcpy(line
+ oldlen
, buf
, len
);
70 line
[oldlen
+ len
] = '\0';
73 /* Continuation: get next line? */
75 if (len
> 0 && line
[len
- 1] == '\\') {
78 /* Ignore escaped backslash at EOL. */
79 if (len
> 1 && line
[len
- 2] != '\\')
85 /* Skip empty lines. */
87 while (isspace((u_char
)*buf
))
94 /* Parse and run the command. */
95 if (cmd_string_parse(buf
, &cmdlist
, path
, n
, &cause1
) != 0) {
99 xasprintf(&msg
, "%s:%u: %s", path
, n
, cause1
);
100 ARRAY_ADD(&cfg_causes
, msg
);
108 cmdq_append(cmdq
, cmdlist
);
109 cmd_list_free(cmdlist
);
120 cfg_default_done(unused
struct cmd_q
*cmdq
)
122 if (--cfg_references
!= 0)
126 if (!RB_EMPTY(&sessions
))
127 cfg_show_causes(RB_MIN(sessions
, &sessions
));
129 cmdq_free(cfg_cmd_q
);
132 if (cfg_client
!= NULL
) {
134 * The client command queue starts with client_exit set to 1 so
135 * only continue if not empty (that is, we have been delayed
136 * during configuration parsing for long enough that the
137 * MSG_COMMAND has arrived), else the client will exit before
138 * the MSG_COMMAND which might tell it not to.
140 if (!TAILQ_EMPTY(&cfg_client
->cmdq
->queue
))
141 cmdq_continue(cfg_client
->cmdq
);
142 cfg_client
->references
--;
148 cfg_show_causes(struct session
*s
)
150 struct window_pane
*wp
;
154 if (s
== NULL
|| ARRAY_EMPTY(&cfg_causes
))
156 wp
= s
->curw
->window
->active
;
158 window_pane_set_mode(wp
, &window_copy_mode
);
159 window_copy_init_for_output(wp
);
160 for (i
= 0; i
< ARRAY_LENGTH(&cfg_causes
); i
++) {
161 cause
= ARRAY_ITEM(&cfg_causes
, i
);
162 window_copy_add(wp
, "%s", cause
);
165 ARRAY_FREE(&cfg_causes
);