version 1.45, 2016/10/16 17:55:14 |
version 1.46, 2016/10/16 19:04:05 |
|
|
* Loads a paste buffer from a file. |
* Loads a paste buffer from a file. |
*/ |
*/ |
|
|
static enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmd_q *); |
static enum cmd_retval cmd_load_buffer_exec(struct cmd *, struct cmdq_item *); |
|
|
static void cmd_load_buffer_callback(struct client *, int, void *); |
static void cmd_load_buffer_callback(struct client *, int, void *); |
|
|
const struct cmd_entry cmd_load_buffer_entry = { |
const struct cmd_entry cmd_load_buffer_entry = { |
.name = "load-buffer", |
.name = "load-buffer", |
|
|
}; |
}; |
|
|
struct cmd_load_buffer_data { |
struct cmd_load_buffer_data { |
struct cmd_q *cmdq; |
struct cmdq_item *item; |
char *bufname; |
char *bufname; |
}; |
}; |
|
|
static enum cmd_retval |
static enum cmd_retval |
cmd_load_buffer_exec(struct cmd *self, struct cmd_q *cmdq) |
cmd_load_buffer_exec(struct cmd *self, struct cmdq_item *item) |
{ |
{ |
struct args *args = self->args; |
struct args *args = self->args; |
struct cmd_load_buffer_data *cdata; |
struct cmd_load_buffer_data *cdata; |
struct client *c = cmdq->client; |
struct client *c = item->client; |
struct session *s; |
struct session *s; |
FILE *f; |
FILE *f; |
const char *path, *bufname, *cwd; |
const char *path, *bufname, *cwd; |
|
|
path = args->argv[0]; |
path = args->argv[0]; |
if (strcmp(path, "-") == 0) { |
if (strcmp(path, "-") == 0) { |
cdata = xcalloc(1, sizeof *cdata); |
cdata = xcalloc(1, sizeof *cdata); |
cdata->cmdq = cmdq; |
cdata->item = item; |
cdata->bufname = xstrdup(bufname); |
cdata->bufname = xstrdup(bufname); |
|
|
error = server_set_stdin_callback(c, cmd_load_buffer_callback, |
error = server_set_stdin_callback(c, cmd_load_buffer_callback, |
cdata, &cause); |
cdata, &cause); |
if (error != 0) { |
if (error != 0) { |
cmdq_error(cmdq, "%s: %s", path, cause); |
cmdq_error(item, "%s: %s", path, cause); |
free(cause); |
free(cause); |
return (CMD_RETURN_ERROR); |
return (CMD_RETURN_ERROR); |
} |
} |
|
|
xasprintf(&file, "%s/%s", cwd, path); |
xasprintf(&file, "%s/%s", cwd, path); |
if (realpath(file, resolved) == NULL && |
if (realpath(file, resolved) == NULL && |
strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) { |
strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) { |
cmdq_error(cmdq, "%s: %s", file, strerror(ENAMETOOLONG)); |
cmdq_error(item, "%s: %s", file, strerror(ENAMETOOLONG)); |
return (CMD_RETURN_ERROR); |
return (CMD_RETURN_ERROR); |
} |
} |
f = fopen(resolved, "rb"); |
f = fopen(resolved, "rb"); |
free(file); |
free(file); |
if (f == NULL) { |
if (f == NULL) { |
cmdq_error(cmdq, "%s: %s", resolved, strerror(errno)); |
cmdq_error(item, "%s: %s", resolved, strerror(errno)); |
return (CMD_RETURN_ERROR); |
return (CMD_RETURN_ERROR); |
} |
} |
|
|
|
|
while ((ch = getc(f)) != EOF) { |
while ((ch = getc(f)) != EOF) { |
/* Do not let the server die due to memory exhaustion. */ |
/* Do not let the server die due to memory exhaustion. */ |
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) { |
if ((new_pdata = realloc(pdata, psize + 2)) == NULL) { |
cmdq_error(cmdq, "realloc error: %s", strerror(errno)); |
cmdq_error(item, "realloc error: %s", strerror(errno)); |
goto error; |
goto error; |
} |
} |
pdata = new_pdata; |
pdata = new_pdata; |
pdata[psize++] = ch; |
pdata[psize++] = ch; |
} |
} |
if (ferror(f)) { |
if (ferror(f)) { |
cmdq_error(cmdq, "%s: read error", resolved); |
cmdq_error(item, "%s: read error", resolved); |
goto error; |
goto error; |
} |
} |
if (pdata != NULL) |
if (pdata != NULL) |
|
|
fclose(f); |
fclose(f); |
|
|
if (paste_set(pdata, psize, bufname, &cause) != 0) { |
if (paste_set(pdata, psize, bufname, &cause) != 0) { |
cmdq_error(cmdq, "%s", cause); |
cmdq_error(item, "%s", cause); |
free(pdata); |
free(pdata); |
free(cause); |
free(cause); |
return (CMD_RETURN_ERROR); |
return (CMD_RETURN_ERROR); |
|
|
free(cause); |
free(cause); |
} |
} |
out: |
out: |
cdata->cmdq->flags &= ~CMD_Q_WAITING; |
cdata->item->flags &= ~CMDQ_WAITING; |
|
|
free(cdata->bufname); |
free(cdata->bufname); |
free(cdata); |
free(cdata); |