/* Control input callback. Read lines and fire commands. */ void control_callback(struct client *c, int closed, __unused void *data) { char *line, *cause; struct cmd_list *cmdlist; struct cmd *cmd; struct cmdq_item *item; if (closed) c->flags |= CLIENT_EXIT; for (;;) { line = evbuffer_readln(c->stdin_data, NULL, EVBUFFER_EOL_LF); if (line == NULL) break; if (*line == '\0') { /* empty line exit */ c->flags |= CLIENT_EXIT; break; } if (cmd_string_parse(line, &cmdlist, NULL, 0, &cause) != 0) { item = cmdq_get_callback(control_error, cause); cmdq_append(c, item); } else { TAILQ_FOREACH(cmd, &cmdlist->list, qentry) cmd->flags |= CMD_CONTROL; item = cmdq_get_command(cmdlist, NULL, NULL, 0); cmdq_append(c, item); cmd_list_free(cmdlist); } free(line); } }
static int cmd_confirm_before_callback(void *data, const char *s, __unused int done) { struct cmd_confirm_before_data *cdata = data; struct client *c = cdata->client; struct cmd_list *cmdlist; struct cmdq_item *new_item; char *cause; if (c->flags & CLIENT_DEAD) return (0); if (s == NULL || *s == '\0') return (0); if (tolower((u_char) s[0]) != 'y' || s[1] != '\0') return (0); cmdlist = cmd_string_parse(cdata->cmd, NULL, 0, &cause); if (cmdlist == NULL) { if (cause != NULL) { new_item = cmdq_get_callback(cmd_confirm_before_error, cause); } else new_item = NULL; } else { new_item = cmdq_get_command(cmdlist, NULL, NULL, 0); cmd_list_free(cmdlist); } if (new_item != NULL) cmdq_append(c, new_item); return (0); }
int load_cfg(const char *path, struct cmd_q *cmdq, int quiet) { FILE *f; char delim[3] = { '\\', '\\', '\0' }; u_int found; size_t line = 0; char *buf, *cause1, *p; struct cmd_list *cmdlist; log_debug("loading %s", path); if ((f = fopen(path, "rb")) == NULL) { if (errno == ENOENT && quiet) return (0); cfg_add_cause("%s: %s", path, strerror(errno)); return (-1); } found = 0; while ((buf = fparseln(f, NULL, &line, delim, 0)) != NULL) { log_debug("%s: %s", path, buf); /* Skip empty lines. */ p = buf; while (isspace((u_char) *p)) p++; if (*p == '\0') { free(buf); continue; } /* Parse and run the command. */ if (cmd_string_parse(p, &cmdlist, path, line, &cause1) != 0) { free(buf); if (cause1 == NULL) continue; cfg_add_cause("%s:%zu: %s", path, line, cause1); free(cause1); continue; } free(buf); if (cmdlist == NULL) continue; cmdq_append(cmdq, cmdlist, NULL); cmd_list_free(cmdlist); found++; } fclose(f); return (found); }
static void cmd_if_shell_callback(struct job *job) { struct cmd_if_shell_data *cdata = job->data; struct client *c = cdata->client; struct cmd_list *cmdlist; struct cmdq_item *new_item; char *cause, *cmd, *file = cdata->file; u_int line = cdata->line; if (!WIFEXITED(job->status) || WEXITSTATUS(job->status) != 0) cmd = cdata->cmd_else; else cmd = cdata->cmd_if; if (cmd == NULL) goto out; cmdlist = cmd_string_parse(cmd, file, line, &cause); if (cmdlist == NULL) { if (cause != NULL) new_item = cmdq_get_callback(cmd_if_shell_error, cause); else new_item = NULL; } else { new_item = cmdq_get_command(cmdlist, NULL, &cdata->mouse, 0); cmd_list_free(cmdlist); } if (new_item != NULL) { if (cdata->item == NULL) cmdq_append(c, new_item); else cmdq_insert_after(cdata->item, new_item); } out: if (cdata->item != NULL) cdata->item->flags &= ~CMDQ_WAITING; }
int load_cfg(const char *path, struct cmd_q *cmdq, char **cause) { FILE *f; u_int n, found; char *buf, *copy, *line, *cause1, *msg; size_t len, oldlen; struct cmd_list *cmdlist; log_debug("loading %s", path); if ((f = fopen(path, "rb")) == NULL) { xasprintf(cause, "%s: %s", path, strerror(errno)); return (-1); } n = found = 0; line = NULL; while ((buf = fgetln(f, &len))) { /* Trim \n. */ if (buf[len - 1] == '\n') len--; log_debug("%s: %.*s", path, (int)len, buf); /* Current line is the continuation of the previous one. */ if (line != NULL) { oldlen = strlen(line); line = xrealloc(line, 1, oldlen + len + 1); } else { oldlen = 0; line = xmalloc(len + 1); } /* Append current line to the previous. */ memcpy(line + oldlen, buf, len); line[oldlen + len] = '\0'; n++; /* Continuation: get next line? */ len = strlen(line); if (len > 0 && line[len - 1] == '\\') { line[len - 1] = '\0'; /* Ignore escaped backslash at EOL. */ if (len > 1 && line[len - 2] != '\\') continue; } copy = line; line = NULL; /* Skip empty lines. */ buf = copy; while (isspace((u_char)*buf)) buf++; if (*buf == '\0') { free(copy); continue; } /* Parse and run the command. */ if (cmd_string_parse(buf, &cmdlist, path, n, &cause1) != 0) { free(copy); if (cause1 == NULL) continue; xasprintf(&msg, "%s:%u: %s", path, n, cause1); ARRAY_ADD(&cfg_causes, msg); free(cause1); continue; } free(copy); if (cmdlist == NULL) continue; cmdq_append(cmdq, cmdlist); cmd_list_free(cmdlist); found++; } if (line != NULL) free(line); fclose(f); return (found); }