int cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_paste_buffer_data *data = self->data; struct window_pane *wp; struct session *s; struct paste_buffer *pb; if (cmd_find_pane(ctx, data->target, &s, &wp) == NULL) return (-1); if (data->buffer == -1) pb = paste_get_top(&s->buffers); else { if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) { ctx->error(ctx, "no buffer %d", data->buffer); return (-1); } } if (pb != NULL) cmd_paste_buffer_filter(wp, pb->data, pb->size, data->sepstr); /* Delete the buffer if -d. */ if (data->flag_delete) { if (data->buffer == -1) paste_free_top(&s->buffers); else paste_free_index(&s->buffers, data->buffer); } return (0); }
int cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct client *c = ctx->cmdclient; struct paste_buffer *pb; const char *path; char *cause; int buffer; mode_t mask; FILE *f; if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { ctx->error(ctx, "buffer %s", cause); xfree(cause); return (-1); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { ctx->error(ctx, "no buffer %d", buffer); return (-1); } } path = args->argv[0]; if (strcmp(path, "-") == 0) { if (c == NULL) { ctx->error(ctx, "%s: can't write to stdout", path); return (-1); } bufferevent_write(c->stdout_event, pb->data, pb->size); } else { mask = umask(S_IRWXG | S_IRWXO); if (args_has(self->args, 'a')) f = fopen(path, "ab"); else f = fopen(path, "wb"); umask(mask); if (f == NULL) { ctx->error(ctx, "%s: %s", path, strerror(errno)); return (-1); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { ctx->error(ctx, "%s: fwrite error", path); fclose(f); return (-1); } fclose(f); } return (0); }
int cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct window_pane *wp; struct session *s; struct paste_buffer *pb; const char *sepstr; char *cause; int buffer; int pflag; if (cmd_find_pane(ctx, args_get(args, 't'), &s, &wp) == NULL) return (-1); if (!args_has(args, 'b')) buffer = -1; else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { ctx->error(ctx, "buffer %s", cause); xfree(cause); return (-1); } } if (buffer == -1) pb = paste_get_top(&global_buffers); else { pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { ctx->error(ctx, "no buffer %d", buffer); return (-1); } } if (pb != NULL) { sepstr = args_get(args, 's'); if (sepstr == NULL) { if (args_has(args, 'r')) sepstr = "\n"; else sepstr = "\r"; } pflag = args_has(args, 'p') && (wp->screen->mode & MODE_BRACKETPASTE); cmd_paste_buffer_filter(wp, pb->data, pb->size, sepstr, pflag); } /* Delete the buffer if -d. */ if (args_has(args, 'd')) { if (buffer == -1) paste_free_top(&global_buffers); else paste_free_index(&global_buffers, buffer); } return (0); }
enum cmd_retval cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp; struct session *s; struct paste_buffer *pb; const char *sepstr; char *cause; int buffer; int pflag; if (cmd_find_pane(cmdq, args_get(args, 't'), &s, &wp) == NULL) return (CMD_RETURN_ERROR); if (!args_has(args, 'b')) buffer = -1; else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } } if (buffer == -1) pb = paste_get_top(&global_buffers); else { pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } } if (pb != NULL) { sepstr = args_get(args, 's'); if (sepstr == NULL) { if (args_has(args, 'r')) sepstr = "\n"; else sepstr = "\r"; } pflag = (wp->screen->mode & MODE_BRACKETPASTE); paste_send_pane(pb, wp, sepstr, args_has(args, 'p') && pflag); } /* Delete the buffer if -d. */ if (args_has(args, 'd')) { if (buffer == -1) paste_free_top(&global_buffers); else paste_free_index(&global_buffers, buffer); } return (CMD_RETURN_NORMAL); }
enum cmd_retval cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct paste_buffer *pb; u_int limit; char *pdata, *cause; size_t psize, newsize; int buffer; limit = options_get_number(&global_options, "buffer-limit"); psize = 0; pdata = NULL; pb = NULL; buffer = -1; if (args_has(args, 'b')) { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } } else if (args_has(args, 'a')) { pb = paste_get_top(&global_buffers); if (pb != NULL) buffer = 0; } if (args_has(args, 'a') && pb != NULL) { psize = pb->size; pdata = xmalloc(psize); memcpy(pdata, pb->data, psize); } newsize = strlen(args->argv[0]); pdata = xrealloc(pdata, 1, psize + newsize); memcpy(pdata + psize, args->argv[0], newsize); psize += newsize; if (buffer == -1) paste_add(&global_buffers, pdata, psize, limit); else paste_replace(&global_buffers, buffer, pdata, psize); return (CMD_RETURN_NORMAL); }
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) { char buf[40]; size_t len; struct paste_buffer *pb; if (wp->screen->mode & ALL_MOUSE_MODES) { /* * Use the SGR (1006) extension only if the application * requested it and the underlying terminal also sent the event * in this format (this is because an old style mouse release * event cannot be converted into the new SGR format, since the * released button is unknown). Otherwise pretend that tmux * doesn't speak this extension, and fall back to the UTF-8 * (1005) extension if the application requested, or to the * legacy format. */ if (m->sgr && (wp->screen->mode & MODE_MOUSE_SGR)) { len = xsnprintf(buf, sizeof buf, "\033[<%d;%d;%d%c", m->sgr_xb, m->x + 1, m->y + 1, m->sgr_rel ? 'm' : 'M'); } else if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->xb + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->xb > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->xb + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); return; } if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) && options_get_number(&wp->window->options, "mode-mouse") == 1) { pb = paste_get_top(&global_buffers); if (pb != NULL) { paste_send_pane(pb, wp, "\r", wp->screen->mode & MODE_BRACKETPASTE); } } else if ((m->xb & 3) != 1 && options_get_number(&wp->window->options, "mode-mouse") == 1) { if (window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, s, m); } } }
int cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; struct paste_buffer *pb; mode_t mask; FILE *f; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); if (data->buffer == -1) { if ((pb = paste_get_top(&s->buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) { ctx->error(ctx, "no buffer %d", data->buffer); return (-1); } } mask = umask(S_IRWXG | S_IRWXO); if (data->chflags & CMD_CHFLAG('a')) f = fopen(data->arg, "ab"); else f = fopen(data->arg, "wb"); umask(mask); if (f == NULL) { ctx->error(ctx, "%s: %s", data->arg, strerror(errno)); return (-1); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { ctx->error(ctx, "%s: fwrite error", data->arg); fclose(f); return (-1); } fclose(f); return (0); }
int cmd_copy_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_copy_buffer_data *data = self->data; struct paste_buffer *pb; struct paste_stack *dst_ps, *src_ps; u_char *pdata; struct session *dst_session, *src_session; u_int limit; if ((dst_session = cmd_find_session(ctx, data->dst_session)) == NULL || (src_session = cmd_find_session(ctx, data->src_session)) == NULL) return (-1); dst_ps = &dst_session->buffers; src_ps = &src_session->buffers; if (data->src_idx == -1) { if ((pb = paste_get_top(src_ps)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { if ((pb = paste_get_index(src_ps, data->src_idx)) == NULL) { ctx->error(ctx, "no buffer %d", data->src_idx); return (-1); } } limit = options_get_number(&dst_session->options, "buffer-limit"); pdata = xmalloc(pb->size); memcpy(pdata, pb->data, pb->size); if (data->dst_idx == -1) paste_add(dst_ps, pdata, pb->size, limit); else if (paste_replace(dst_ps, data->dst_idx, pdata, pb->size) != 0) { ctx->error(ctx, "no buffer %d", data->dst_idx); xfree(pdata); return (-1); } return (0); }
/* Translate mouse and output. */ void input_mouse(struct window_pane *wp, struct session *s, struct mouse_event *m) { char buf[10]; size_t len; struct paste_buffer *pb; if (wp->screen->mode & ALL_MOUSE_MODES) { if (wp->screen->mode & MODE_MOUSE_UTF8) { len = xsnprintf(buf, sizeof buf, "\033[M"); len += utf8_split2(m->xb + 32, &buf[len]); len += utf8_split2(m->x + 33, &buf[len]); len += utf8_split2(m->y + 33, &buf[len]); } else { if (m->xb > 223 || m->x >= 222 || m->y > 222) return; len = xsnprintf(buf, sizeof buf, "\033[M"); buf[len++] = m->xb + 32; buf[len++] = m->x + 33; buf[len++] = m->y + 33; } bufferevent_write(wp->event, buf, len); return; } if (m->button == 1 && (m->event & MOUSE_EVENT_CLICK) && options_get_number(&wp->window->options, "mode-mouse") == 1) { pb = paste_get_top(&global_buffers); if (pb != NULL) { paste_send_pane(pb, wp, "\r", wp->screen->mode & MODE_BRACKETPASTE); } } else if ((m->xb & 3) != 1 && options_get_number(&wp->window->options, "mode-mouse") == 1) { if (window_pane_set_mode(wp, &window_copy_mode) == 0) { window_copy_init_from_pane(wp); if (wp->mode->mouse != NULL) wp->mode->mouse(wp, s, m); } } }
static enum cmd_retval cmd_choose_tree_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; struct window_pane *wp = item->target.wp; const struct window_mode *mode; if (self->entry == &cmd_choose_buffer_entry) { if (paste_get_top(NULL) == NULL) return (CMD_RETURN_NORMAL); mode = &window_buffer_mode; } else if (self->entry == &cmd_choose_client_entry) { if (server_client_how_many() == 0) return (CMD_RETURN_NORMAL); mode = &window_client_mode; } else mode = &window_tree_mode; window_pane_set_mode(wp, mode, &item->target, args); return (CMD_RETURN_NORMAL); }
int cmd_paste_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct winlink *wl; struct window_pane *wp; struct session *s; struct paste_buffer *pb; if ((wl = cmd_find_window(ctx, data->target, &s)) == NULL) return (-1); wp = wl->window->active; if (data->buffer == -1) pb = paste_get_top(&s->buffers); else { if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) { ctx->error(ctx, "no buffer %d", data->buffer); return (-1); } } if (pb != NULL) { /* -r means raw data without LF->CR conversion. */ if (cmd_check_flag(data->chflags, 'r')) bufferevent_write(wp->event, pb->data, pb->size); else cmd_paste_buffer_lf2cr(wp, pb->data, pb->size); } /* Delete the buffer if -d. */ if (cmd_check_flag(data->chflags, 'd')) { if (data->buffer == -1) paste_free_top(&s->buffers); else paste_free_index(&s->buffers, data->buffer); } return (0); }
static void window_buffer_key(struct window_mode_entry *wme, struct client *c, __unused struct session *s, __unused struct winlink *wl, key_code key, struct mouse_event *m) { struct window_pane *wp = wme->wp; struct window_buffer_modedata *data = wme->data; struct mode_tree_data *mtd = data->data; struct window_buffer_itemdata *item; int finished; finished = mode_tree_key(mtd, c, &key, m, NULL, NULL); switch (key) { case 'd': item = mode_tree_get_current(mtd); window_buffer_do_delete(data, item, c, key); mode_tree_build(mtd); break; case 'D': mode_tree_each_tagged(mtd, window_buffer_do_delete, c, key, 0); mode_tree_build(mtd); break; case 'P': mode_tree_each_tagged(mtd, window_buffer_do_paste, c, key, 0); finished = 1; break; case 'p': case '\r': item = mode_tree_get_current(mtd); window_buffer_do_paste(data, item, c, key); finished = 1; break; } if (finished || paste_get_top(NULL) == NULL) window_pane_reset_mode(wp); else { mode_tree_draw(mtd); wp->flags |= PANE_REDRAW; } }
int cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct session *s; struct paste_buffer *pb; int buffer; char *in, *buf, *ptr, *cause; size_t size, len; u_int width; if ((s = cmd_find_session(ctx, NULL, 0)) == NULL) return (-1); if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { ctx->error(ctx, "buffer %s", cause); xfree(cause); return (-1); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { ctx->error(ctx, "no buffer %d", buffer); return (-1); } } size = pb->size; if (size > SIZE_MAX / 4 - 1) size = SIZE_MAX / 4 - 1; in = xmalloc(size * 4 + 1); strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB); width = s->sx; if (ctx->cmdclient != NULL) width = ctx->cmdclient->tty.sx; buf = xmalloc(width + 1); len = 0; ptr = in; do { buf[len++] = *ptr++; if (len == width || buf[len - 1] == '\n') { if (buf[len - 1] == '\n') len--; buf[len] = '\0'; ctx->print(ctx, "%s", buf); len = 0; } } while (*ptr != '\0'); if (len != 0) { buf[len] = '\0'; ctx->print(ctx, "%s", buf); } xfree(buf); xfree(in); return (0); }
int cmd_save_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct args *args = self->args; struct client *c = ctx->cmdclient; struct session *s; struct paste_buffer *pb; const char *path, *newpath, *wd; char *cause; int buffer; mode_t mask; FILE *f; if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { ctx->error(ctx, "buffer %s", cause); xfree(cause); return (-1); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { ctx->error(ctx, "no buffer %d", buffer); return (-1); } } path = args->argv[0]; if (strcmp(path, "-") == 0) { if (c == NULL) { ctx->error(ctx, "%s: can't write to stdout", path); return (-1); } evbuffer_add(c->stdout_data, pb->data, pb->size); server_push_stdout(c); } else { if (c != NULL) wd = c->cwd; else if ((s = cmd_current_session(ctx, 0)) != NULL) { wd = options_get_string(&s->options, "default-path"); if (*wd == '\0') wd = s->cwd; } else wd = NULL; if (wd != NULL && *wd != '\0') { newpath = get_full_path(wd, path); if (newpath != NULL) path = newpath; } mask = umask(S_IRWXG | S_IRWXO); if (args_has(self->args, 'a')) f = fopen(path, "ab"); else f = fopen(path, "wb"); umask(mask); if (f == NULL) { ctx->error(ctx, "%s: %s", path, strerror(errno)); return (-1); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { ctx->error(ctx, "%s: fwrite error", path); fclose(f); return (-1); } fclose(f); } return (0); }
enum cmd_retval cmd_set_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct paste_buffer *pb; char *bufdata, *cause; const char *bufname, *olddata; size_t bufsize, newsize; bufname = NULL; if (args_has(args, 'n')) { if (args->argc > 0) { cmdq_error(cmdq, "don't provide data with n flag"); return (CMD_RETURN_ERROR); } if (args_has(args, 'b')) bufname = args_get(args, 'b'); if (bufname == NULL) { pb = paste_get_top(&bufname); if (pb == NULL) { cmdq_error(cmdq, "no buffer"); return (CMD_RETURN_ERROR); } } if (paste_rename(bufname, args_get(args, 'n'), &cause) != 0) { cmdq_error(cmdq, "%s", cause); free(cause); return (CMD_RETURN_ERROR); } return (CMD_RETURN_NORMAL); } if (args->argc != 1) { cmdq_error(cmdq, "no data specified"); return (CMD_RETURN_ERROR); } pb = NULL; bufsize = 0; bufdata = NULL; if ((newsize = strlen(args->argv[0])) == 0) return (CMD_RETURN_NORMAL); if (args_has(args, 'b')) { bufname = args_get(args, 'b'); pb = paste_get_name(bufname); } else if (args_has(args, 'a')) pb = paste_get_top(&bufname); if (args_has(args, 'a') && pb != NULL) { olddata = paste_buffer_data(pb, &bufsize); bufdata = xmalloc(bufsize); memcpy(bufdata, olddata, bufsize); } bufdata = xrealloc(bufdata, bufsize + newsize); memcpy(bufdata + bufsize, args->argv[0], newsize); bufsize += newsize; if (paste_set(bufdata, bufsize, bufname, &cause) != 0) { cmdq_error(cmdq, "%s", cause); free(bufdata); free(cause); return (CMD_RETURN_ERROR); } return (CMD_RETURN_NORMAL); }
static enum cmd_retval cmd_save_buffer_exec(struct cmd *self, struct cmdq_item *item) { struct args *args = self->args; struct client *c = item->client; struct session *s; struct paste_buffer *pb; const char *path, *bufname, *bufdata, *start, *end, *cwd; const char *flags; char *msg, *file, resolved[PATH_MAX]; size_t size, used, msglen, bufsize; FILE *f; if (!args_has(args, 'b')) { if ((pb = paste_get_top(NULL)) == NULL) { cmdq_error(item, "no buffers"); return (CMD_RETURN_ERROR); } } else { bufname = args_get(args, 'b'); pb = paste_get_name(bufname); if (pb == NULL) { cmdq_error(item, "no buffer %s", bufname); return (CMD_RETURN_ERROR); } } bufdata = paste_buffer_data(pb, &bufsize); if (self->entry == &cmd_show_buffer_entry) path = "-"; else path = args->argv[0]; if (strcmp(path, "-") == 0) { if (c == NULL) { cmdq_error(item, "can't write to stdout"); return (CMD_RETURN_ERROR); } if (c->session == NULL || (c->flags & CLIENT_CONTROL)) goto do_stdout; goto do_print; } if (c != NULL && c->session == NULL && c->cwd != NULL) cwd = c->cwd; else if ((s = c->session) != NULL && s->cwd != NULL) cwd = s->cwd; else cwd = "."; flags = "wb"; if (args_has(self->args, 'a')) flags = "ab"; if (*path == '/') file = xstrdup(path); else xasprintf(&file, "%s/%s", cwd, path); if (realpath(file, resolved) == NULL && strlcpy(resolved, file, sizeof resolved) >= sizeof resolved) { cmdq_error(item, "%s: %s", file, strerror(ENAMETOOLONG)); return (CMD_RETURN_ERROR); } f = fopen(resolved, flags); free(file); if (f == NULL) { cmdq_error(item, "%s: %s", resolved, strerror(errno)); return (CMD_RETURN_ERROR); } if (fwrite(bufdata, 1, bufsize, f) != bufsize) { cmdq_error(item, "%s: write error", resolved); fclose(f); return (CMD_RETURN_ERROR); } fclose(f); return (CMD_RETURN_NORMAL); do_stdout: evbuffer_add(c->stdout_data, bufdata, bufsize); server_client_push_stdout(c); return (CMD_RETURN_NORMAL); do_print: if (bufsize > (INT_MAX / 4) - 1) { cmdq_error(item, "buffer too big"); return (CMD_RETURN_ERROR); } msg = NULL; used = 0; while (used != bufsize) { start = bufdata + used; end = memchr(start, '\n', bufsize - used); if (end != NULL) size = end - start; else size = bufsize - used; msglen = size * 4 + 1; msg = xrealloc(msg, msglen); strvisx(msg, start, size, VIS_OCTAL|VIS_TAB); cmdq_print(item, "%s", msg); used += size + (end != NULL); } free(msg); return (CMD_RETURN_NORMAL); }
int cmd_show_buffer_exec(struct cmd *self, struct cmd_ctx *ctx) { struct cmd_buffer_data *data = self->data; struct session *s; struct paste_buffer *pb; char *in, *buf, *ptr; size_t size, len; u_int width; if ((s = cmd_find_session(ctx, data->target)) == NULL) return (-1); if (data->buffer == -1) { if ((pb = paste_get_top(&s->buffers)) == NULL) { ctx->error(ctx, "no buffers"); return (-1); } } else if ((pb = paste_get_index(&s->buffers, data->buffer)) == NULL) { ctx->error(ctx, "no buffer %d", data->buffer); return (-1); } if (pb == NULL) return (0); size = pb->size; if (size > SIZE_MAX / 4 - 1) size = SIZE_MAX / 4 - 1; in = xmalloc(size * 4 + 1); strvisx(in, pb->data, size, VIS_OCTAL|VIS_TAB); width = s->sx; if (ctx->cmdclient != NULL) width = ctx->cmdclient->tty.sx; buf = xmalloc(width + 1); len = 0; ptr = in; do { buf[len++] = *ptr++; if (len == width || buf[len - 1] == '\n') { if (buf[len - 1] == '\n') len--; buf[len] = '\0'; ctx->print(ctx, "%s", buf); len = 0; } } while (*ptr != '\0'); if (len != 0) { buf[len] = '\0'; ctx->print(ctx, "%s", buf); } xfree(buf); xfree(in); return (0); }
enum cmd_retval cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c; struct session *s; struct paste_buffer *pb; const char *path, *newpath, *wd; char *cause, *start, *end; size_t size, used; int buffer; mode_t mask; FILE *f; char *msg; size_t msglen; if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { cmdq_error(cmdq, "no buffers"); return (CMD_RETURN_ERROR); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } } if (self->entry == &cmd_show_buffer_entry) path = "-"; else path = args->argv[0]; if (strcmp(path, "-") == 0) { c = cmdq->client; if (c == NULL) { cmdq_error(cmdq, "can't write to stdout"); return (CMD_RETURN_ERROR); } if (c->session == NULL || (c->flags & CLIENT_CONTROL)) goto do_stdout; goto do_print; } c = cmdq->client; if (c != NULL) wd = c->cwd; else if ((s = cmd_current_session(cmdq, 0)) != NULL) { wd = options_get_string(&s->options, "default-path"); if (*wd == '\0') wd = s->cwd; } else wd = NULL; if (wd != NULL && *wd != '\0') { newpath = get_full_path(wd, path); if (newpath != NULL) path = newpath; } mask = umask(S_IRWXG | S_IRWXO); if (args_has(self->args, 'a')) f = fopen(path, "ab"); else f = fopen(path, "wb"); umask(mask); if (f == NULL) { cmdq_error(cmdq, "%s: %s", path, strerror(errno)); return (CMD_RETURN_ERROR); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { cmdq_error(cmdq, "%s: fwrite error", path); fclose(f); return (CMD_RETURN_ERROR); } fclose(f); return (CMD_RETURN_NORMAL); do_stdout: evbuffer_add(c->stdout_data, pb->data, pb->size); server_push_stdout(c); return (CMD_RETURN_NORMAL); do_print: if (pb->size > (INT_MAX / 4) - 1) { cmdq_error(cmdq, "buffer too big"); return (CMD_RETURN_ERROR); } msg = NULL; msglen = 0; used = 0; while (used != pb->size) { start = pb->data + used; end = memchr(start, '\n', pb->size - used); if (end != NULL) size = end - start; else size = pb->size - used; msglen = size * 4 + 1; msg = xrealloc(msg, 1, msglen); strvisx(msg, start, size, VIS_OCTAL|VIS_TAB); cmdq_print(cmdq, "%s", msg); used += size + (end != NULL); } free(msg); return (CMD_RETURN_NORMAL); }
enum cmd_retval cmd_paste_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct window_pane *wp = cmdq->state.tflag.wp; struct paste_buffer *pb; const char *sepstr, *bufname, *bufdata, *bufend, *line; size_t seplen, bufsize; int bracket = args_has(args, 'p'); bufname = NULL; if (args_has(args, 'b')) bufname = args_get(args, 'b'); if (bufname == NULL) pb = paste_get_top(NULL); else { pb = paste_get_name(bufname); if (pb == NULL) { cmdq_error(cmdq, "no buffer %s", bufname); return (CMD_RETURN_ERROR); } } if (pb != NULL && ~wp->flags & PANE_INPUTOFF) { sepstr = args_get(args, 's'); if (sepstr == NULL) { if (args_has(args, 'r')) sepstr = "\n"; else sepstr = "\r"; } seplen = strlen(sepstr); if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) bufferevent_write(wp->event, "\033[200~", 6); bufdata = paste_buffer_data(pb, &bufsize); bufend = bufdata + bufsize; for (;;) { line = memchr(bufdata, '\n', bufend - bufdata); if (line == NULL) break; bufferevent_write(wp->event, bufdata, line - bufdata); bufferevent_write(wp->event, sepstr, seplen); bufdata = line + 1; } if (bufdata != bufend) bufferevent_write(wp->event, bufdata, bufend - bufdata); if (bracket && (wp->screen->mode & MODE_BRACKETPASTE)) bufferevent_write(wp->event, "\033[201~", 6); } if (pb != NULL && args_has(args, 'd')) paste_free(pb); return (CMD_RETURN_NORMAL); }
enum cmd_retval cmd_save_buffer_exec(struct cmd *self, struct cmd_q *cmdq) { struct args *args = self->args; struct client *c = cmdq->client; struct session *s; struct paste_buffer *pb; const char *path; char *cause, *start, *end, *msg; size_t size, used, msglen; int cwd, fd, buffer; FILE *f; if (!args_has(args, 'b')) { if ((pb = paste_get_top(&global_buffers)) == NULL) { cmdq_error(cmdq, "no buffers"); return (CMD_RETURN_ERROR); } } else { buffer = args_strtonum(args, 'b', 0, INT_MAX, &cause); if (cause != NULL) { cmdq_error(cmdq, "buffer %s", cause); free(cause); return (CMD_RETURN_ERROR); } pb = paste_get_index(&global_buffers, buffer); if (pb == NULL) { cmdq_error(cmdq, "no buffer %d", buffer); return (CMD_RETURN_ERROR); } } if (self->entry == &cmd_show_buffer_entry) path = "-"; else path = args->argv[0]; if (strcmp(path, "-") == 0) { if (c == NULL) { cmdq_error(cmdq, "can't write to stdout"); return (CMD_RETURN_ERROR); } if (c->session == NULL || (c->flags & CLIENT_CONTROL)) goto do_stdout; goto do_print; } if (c != NULL && c->session == NULL) cwd = c->cwd; else if ((s = cmd_current_session(cmdq, 0)) != NULL) cwd = s->cwd; else cwd = AT_FDCWD; f = NULL; if (args_has(self->args, 'a')) { fd = openat(cwd, path, O_CREAT|O_RDWR|O_APPEND, 0600); if (fd != -1) f = fdopen(fd, "ab"); } else { fd = openat(cwd, path, O_CREAT|O_RDWR, 0600); if (fd != -1) f = fdopen(fd, "wb"); } if (f == NULL) { if (fd != -1) close(fd); cmdq_error(cmdq, "%s: %s", path, strerror(errno)); return (CMD_RETURN_ERROR); } if (fwrite(pb->data, 1, pb->size, f) != pb->size) { cmdq_error(cmdq, "%s: fwrite error", path); fclose(f); return (CMD_RETURN_ERROR); } fclose(f); return (CMD_RETURN_NORMAL); do_stdout: evbuffer_add(c->stdout_data, pb->data, pb->size); server_push_stdout(c); return (CMD_RETURN_NORMAL); do_print: if (pb->size > (INT_MAX / 4) - 1) { cmdq_error(cmdq, "buffer too big"); return (CMD_RETURN_ERROR); } msg = NULL; msglen = 0; used = 0; while (used != pb->size) { start = pb->data + used; end = memchr(start, '\n', pb->size - used); if (end != NULL) size = end - start; else size = pb->size - used; msglen = size * 4 + 1; msg = xrealloc(msg, 1, msglen); strvisx(msg, start, size, VIS_OCTAL|VIS_TAB); cmdq_print(cmdq, "%s", msg); used += size + (end != NULL); } free(msg); return (CMD_RETURN_NORMAL); }