tmux  3.2a
About: tmux is a terminal multiplexer that lets you switch easily between several programs in one terminal.
  Fossies Dox: tmux-3.2a.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

cmd-source-file.c
Go to the documentation of this file.
1 /* $OpenBSD$ */
2 
3 /*
4  * Copyright (c) 2008 Tiago Cunha <me@tiagocunha.org>
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 
21 #include <errno.h>
22 #include <glob.h>
23 #include <stdlib.h>
24 #include <string.h>
25 
26 #include "tmux.h"
27 
28 /*
29  * Sources a configuration file.
30  */
31 
32 static enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmdq_item *);
33 
34 const struct cmd_entry cmd_source_file_entry = {
35  .name = "source-file",
36  .alias = "source",
37 
38  .args = { "Fnqv", 1, -1 },
39  .usage = "[-Fnqv] path ...",
40 
41  .flags = 0,
42  .exec = cmd_source_file_exec
43 };
44 
46  struct cmdq_item *item;
47  int flags;
48 
49  struct cmdq_item *after;
50  enum cmd_retval retval;
51 
52  u_int current;
53  char **files;
54  u_int nfiles;
55 };
56 
57 static enum cmd_retval
59 {
60  cfg_print_causes(item);
61  return (CMD_RETURN_NORMAL);
62 }
63 
64 static void
66 {
67  struct cmdq_item *new_item;
68 
69  if (cfg_finished) {
70  if (cdata->retval == CMD_RETURN_ERROR &&
71  c != NULL &&
72  c->session == NULL)
73  c->retval = 1;
75  cmdq_insert_after(cdata->after, new_item);
76  }
77 
78  free(cdata->files);
79  free(cdata);
80 }
81 
82 static void
83 cmd_source_file_done(struct client *c, const char *path, int error,
84  int closed, struct evbuffer *buffer, void *data)
85 {
86  struct cmd_source_file_data *cdata = data;
87  struct cmdq_item *item = cdata->item;
88  void *bdata = EVBUFFER_DATA(buffer);
89  size_t bsize = EVBUFFER_LENGTH(buffer);
90  u_int n;
91  struct cmdq_item *new_item;
92 
93  if (!closed)
94  return;
95 
96  if (error != 0)
97  cmdq_error(item, "%s: %s", path, strerror(error));
98  else if (bsize != 0) {
99  if (load_cfg_from_buffer(bdata, bsize, path, c, cdata->after,
100  cdata->flags, &new_item) < 0)
101  cdata->retval = CMD_RETURN_ERROR;
102  else if (new_item != NULL)
103  cdata->after = new_item;
104  }
105 
106  n = ++cdata->current;
107  if (n < cdata->nfiles)
108  file_read(c, cdata->files[n], cmd_source_file_done, cdata);
109  else {
110  cmd_source_file_complete(c, cdata);
111  cmdq_continue(item);
112  }
113 }
114 
115 static void
116 cmd_source_file_add(struct cmd_source_file_data *cdata, const char *path)
117 {
118  log_debug("%s: %s", __func__, path);
119  cdata->files = xreallocarray(cdata->files, cdata->nfiles + 1,
120  sizeof *cdata->files);
121  cdata->files[cdata->nfiles++] = xstrdup(path);
122 }
123 
124 static enum cmd_retval
125 cmd_source_file_exec(struct cmd *self, struct cmdq_item *item)
126 {
127  struct args *args = cmd_get_args(self);
128  struct cmd_source_file_data *cdata;
129  struct client *c = cmdq_get_client(item);
131  char *pattern, *cwd, *expand = NULL;
132  const char *path, *error;
133  glob_t g;
134  int i, result;
135  u_int j;
136 
137  cdata = xcalloc(1, sizeof *cdata);
138  cdata->item = item;
139 
140  if (args_has(args, 'q'))
141  cdata->flags |= CMD_PARSE_QUIET;
142  if (args_has(args, 'n'))
143  cdata->flags |= CMD_PARSE_PARSEONLY;
144  if (args_has(args, 'v'))
145  cdata->flags |= CMD_PARSE_VERBOSE;
146 
147  utf8_stravis(&cwd, server_client_get_cwd(c, NULL), VIS_GLOB);
148 
149  for (i = 0; i < args->argc; i++) {
150  if (args_has(args, 'F')) {
151  free(expand);
152  expand = format_single_from_target(item, args->argv[i]);
153  path = expand;
154  } else
155  path = args->argv[i];
156  if (strcmp(path, "-") == 0) {
157  cmd_source_file_add(cdata, "-");
158  continue;
159  }
160 
161  if (*path == '/')
162  pattern = xstrdup(path);
163  else
164  xasprintf(&pattern, "%s/%s", cwd, path);
165  log_debug("%s: %s", __func__, pattern);
166 
167  if ((result = glob(pattern, 0, NULL, &g)) != 0) {
168  if (result != GLOB_NOMATCH ||
169  (~cdata->flags & CMD_PARSE_QUIET)) {
170  if (result == GLOB_NOMATCH)
171  error = strerror(ENOENT);
172  else if (result == GLOB_NOSPACE)
173  error = strerror(ENOMEM);
174  else
175  error = strerror(EINVAL);
176  cmdq_error(item, "%s: %s", path, error);
178  }
179  free(pattern);
180  continue;
181  }
182  free(expand);
183  free(pattern);
184 
185  for (j = 0; j < g.gl_pathc; j++)
186  cmd_source_file_add(cdata, g.gl_pathv[j]);
187  }
188 
189  cdata->after = item;
190  cdata->retval = retval;
191 
192  if (cdata->nfiles != 0) {
193  file_read(c, cdata->files[0], cmd_source_file_done, cdata);
195  } else
196  cmd_source_file_complete(c, cdata);
197 
198  free(cwd);
199  return (retval);
200 }
int args_has(struct args *args, u_char flag)
Definition: arguments.c:259
int load_cfg_from_buffer(const void *buf, size_t len, const char *path, struct client *c, struct cmdq_item *item, int flags, struct cmdq_item **new_item)
Definition: cfg.c:159
void cfg_print_causes(struct cmdq_item *item)
Definition: cfg.c:228
int cfg_finished
Definition: cfg.c:30
struct client * cmdq_get_client(struct cmdq_item *item)
Definition: cmd-queue.c:150
struct cmdq_item * cmdq_insert_after(struct cmdq_item *after, struct cmdq_item *item)
Definition: cmd-queue.c:312
void cmdq_continue(struct cmdq_item *item)
Definition: cmd-queue.c:434
void cmdq_error(struct cmdq_item *item, const char *fmt,...)
Definition: cmd-queue.c:833
static void cmd_source_file_complete(struct client *c, struct cmd_source_file_data *cdata)
const struct cmd_entry cmd_source_file_entry
static void cmd_source_file_done(struct client *c, const char *path, int error, int closed, struct evbuffer *buffer, void *data)
static void cmd_source_file_add(struct cmd_source_file_data *cdata, const char *path)
static enum cmd_retval cmd_source_file_exec(struct cmd *, struct cmdq_item *)
static enum cmd_retval cmd_source_file_complete_cb(struct cmdq_item *item, void *data)
struct args * cmd_get_args(struct cmd *cmd)
Definition: cmd.c:393
#define __unused
Definition: compat.h:60
void file_read(struct client *c, const char *path, client_file_cb cb, void *cbdata)
Definition: file.c:356
char * format_single_from_target(struct cmdq_item *item, const char *fmt)
Definition: format.c:4643
void log_debug(const char *msg,...)
Definition: log.c:130
const char * server_client_get_cwd(struct client *c, struct session *s)
Definition: tmux.h:1435
int argc
Definition: tmux.h:1437
char ** argv
Definition: tmux.h:1438
Definition: tmux.h:1608
int retval
Definition: tmux.h:1622
const char * cwd
Definition: tmux.h:1631
struct session * session
Definition: tmux.h:1743
Definition: tmux.h:1525
const char * name
Definition: tmux.h:1526
struct cmdq_item * item
struct cmdq_item * after
enum cmd_retval retval
Definition: cmd.c:212
void * data
Definition: cmd-queue.c:63
#define cmdq_get_callback(cb, data)
Definition: tmux.h:2364
#define CMD_PARSE_QUIET
Definition: tmux.h:1495
cmd_retval
Definition: tmux.h:1475
@ CMD_RETURN_NORMAL
Definition: tmux.h:1477
@ CMD_RETURN_ERROR
Definition: tmux.h:1476
@ CMD_RETURN_WAIT
Definition: tmux.h:1478
#define CMD_PARSE_PARSEONLY
Definition: tmux.h:1496
#define CMD_PARSE_VERBOSE
Definition: tmux.h:1498
int utf8_stravis(char **, const char *, int)
Definition: utf8.c:352
void * xreallocarray(void *ptr, size_t nmemb, size_t size)
Definition: xmalloc.c:61
int xasprintf(char **ret, const char *fmt,...)
Definition: xmalloc.c:109
void * xcalloc(size_t nmemb, size_t size)
Definition: xmalloc.c:41
char * xstrdup(const char *str)
Definition: xmalloc.c:89