diff options
-rw-r--r-- | CHANGES | 12 | ||||
-rw-r--r-- | TODO | 1 | ||||
-rw-r--r-- | server.c | 38 | ||||
-rw-r--r-- | tmux.c | 85 | ||||
-rw-r--r-- | tmux.h | 4 |
5 files changed, 96 insertions, 44 deletions
@@ -1,3 +1,13 @@ +27 March 2009 + +* Sockets in /tmp are now created in a subdirectory named, tmux-UID, eg + tmux-1000. The default socket is thus /tmp/tmux-UID/default. To start a + separate server, the new -L command line option should be used: this creates + a socket in the same directory with a different name ("-L main" will create + socket called "main"). -S should only be used to place the socket outside + /tmp. This makes sockets a little more secure and a bit more convenient to + use multiple servers. + 21 March 2009 * New session flag "set-remain-on-exit" to set remain-on-exit flag for new @@ -1132,7 +1142,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.259 2009-03-21 12:44:05 nicm Exp $ +$Id: CHANGES,v 1.260 2009-03-27 15:57:09 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB ms @@ -96,3 +96,4 @@ - refer to windows by name etc (duplicates? fnmatch?) - n/p repeat is annoying, turn off - repeat should be a key flag and should be configurable (bind -r) +- document -L and update socket path bits in tmux.1 @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.127 2009-03-27 08:46:02 nicm Exp $ */ +/* $Id: server.c,v 1.128 2009-03-27 15:57:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -43,7 +43,7 @@ /* Client list. */ struct clients clients; -int server_main(const char *, int); +int server_main(int); void server_shutdown(void); void server_child_signal(void); void server_fill_windows(struct pollfd **); @@ -59,7 +59,7 @@ void server_check_redraw(struct client *); void server_redraw_locked(struct client *); void server_check_timers(struct client *); void server_second_timers(void); -int server_update_socket(const char *); +int server_update_socket(void); /* Create a new client. */ struct client * @@ -127,6 +127,9 @@ server_start(const char *path) mode_t mask; int n, fd, pair[2], mode; char *cause; +#ifndef NO_SETPROCTITLE + char rpathbuf[MAXPATHLEN]; +#endif /* The first client is special and gets a socketpair; create it. */ if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pair) != 0) @@ -170,17 +173,20 @@ server_start(const char *path) log_warnx("%s", cause); exit(1); } - logfile("server"); -#ifndef NO_SETPROCTITLE - setproctitle("server (%s)", path); -#endif + log_debug("server started, pid %ld", (long) getpid()); log_debug("socket path %s", socket_path); + +#ifndef NO_SETPROCTITLE + if (realpath(socket_path, rpathbuf) == NULL) + strlcpy(rpathbuf, socket_path, sizeof rpathbuf); + setproctitle("server (%s)", rpathbuf); +#endif memset(&sa, 0, sizeof sa); sa.sun_family = AF_UNIX; - size = strlcpy(sa.sun_path, path, sizeof sa.sun_path); + size = strlcpy(sa.sun_path, socket_path, sizeof sa.sun_path); if (size >= sizeof sa.sun_path) { errno = ENAMETOOLONG; fatal("socket failed"); @@ -207,7 +213,7 @@ server_start(const char *path) server_create_client(pair[1]); - n = server_main(path, fd); + n = server_main(fd); #ifdef DEBUG xmalloc_report(getpid(), "server"); #endif @@ -216,7 +222,7 @@ server_start(const char *path) /* Main server loop. */ int -server_main(const char *srv_path, int srv_fd) +server_main(int srv_fd) { struct window *w; struct pollfd *pfds, *pfd; @@ -263,7 +269,7 @@ server_main(const char *srv_path, int srv_fd) /* Update socket permissions. */ xtimeout = INFTIM; - if (sigterm || server_update_socket(srv_path) != 0) + if (sigterm || server_update_socket() != 0) xtimeout = 100; /* Do the poll. */ @@ -337,7 +343,9 @@ server_main(const char *srv_path, int srv_fd) key_bindings_free(); close(srv_fd); - unlink(srv_path); + + unlink(socket_path); + xfree(socket_path); options_free(&global_options); options_free(&global_window_options); @@ -996,7 +1004,7 @@ server_second_timers(void) /* Update socket execute permissions based on whether sessions are attached. */ int -server_update_socket(const char *path) +server_update_socket() { struct session *s; u_int i; @@ -1015,9 +1023,9 @@ server_update_socket(const char *path) if (n != last) { last = n; if (n != 0) - chmod(path, S_IRWXU); + chmod(socket_path, S_IRWXU); else - chmod(path, S_IRUSR|S_IWUSR); + chmod(socket_path, S_IRUSR|S_IWUSR); } return (n); @@ -1,4 +1,4 @@ -/* $Id: tmux.c,v 1.109 2009-03-21 12:44:06 nicm Exp $ */ +/* $Id: tmux.c,v 1.110 2009-03-27 15:57:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -17,6 +17,7 @@ */ #include <sys/types.h> +#include <sys/stat.h> #include <errno.h> #include <pwd.h> @@ -58,9 +59,10 @@ time_t server_activity; int debug_level; int be_quiet; time_t start_time; -const char *socket_path; +char *socket_path; __dead void usage(void); +char *makesockpath(const char *); #ifdef NO_PROGNAME const char *__progname = "tmux"; @@ -173,6 +175,34 @@ sigreset(void) fatal("sigaction failed"); } +char * +makesockpath(const char *label) +{ + char base[MAXPATHLEN], *path; + struct stat sb; + u_int uid; + + uid = getuid(); + xsnprintf(base, MAXPATHLEN, "%s/%s-%d", _PATH_TMP, __progname, uid); + + if (mkdir(base, S_IRWXU) != 0 && errno != EEXIST) + return (NULL); + + if (lstat(base, &sb) != 0) + return (NULL); + if (!S_ISDIR(sb.st_mode) || sb.st_uid != uid) { + errno = EACCES; + return (NULL); + } + if ((sb.st_mode & (S_IRWXG|S_IRWXO)) != 0) { + errno = EACCES; + return (NULL); + } + + xasprintf(&path, "%s/%s", base, label); + return (path); +} + int main(int argc, char **argv) { @@ -185,13 +215,13 @@ main(int argc, char **argv) struct hdr hdr; const char *shell; struct passwd *pw; - char *path, *cause, *home, *pass = NULL; - char rpath[MAXPATHLEN], cwd[MAXPATHLEN]; + char *path, *label, *cause, *home, *pass = NULL; + char cwd[MAXPATHLEN]; int retcode, opt, flags, unlock, start_server; unlock = flags = 0; - path = NULL; - while ((opt = getopt(argc, argv, "28df:qS:uUVv")) != -1) { + label = path = NULL; + while ((opt = getopt(argc, argv, "28df:L:qS:uUVv")) != -1) { switch (opt) { case '2': flags |= IDENTIFY_256COLOURS; @@ -204,7 +234,22 @@ main(int argc, char **argv) case 'f': cfg_file = xstrdup(optarg); break; + case 'L': + if (path != NULL) { + log_warnx("-L and -S cannot be used together"); + exit(1); + } + if (label != NULL) + xfree(label); + label = xstrdup(optarg); + break; case 'S': + if (label != NULL) { + log_warnx("-L and -S cannot be used together"); + exit(1); + } + if (path != NULL) + xfree(path); path = xstrdup(optarg); break; case 'q': @@ -299,26 +344,13 @@ main(int argc, char **argv) } } - if (path == NULL) { - xasprintf(&path, - "%s/%s-%lu", _PATH_TMP, __progname, (u_long) getuid()); - } - if (realpath(path, rpath) == NULL) { - if (errno != ENOENT) { - log_warn("%s", path); - exit(1); - } - /* - * Linux appears to fill in the buffer fine but then returns - * ENOENT if the file doesn't exist. But since it returns an - * error, we can't rely on the buffer. Grr. - */ - if (strlcpy(rpath, path, sizeof rpath) >= sizeof rpath) { - log_warnx("%s: %s", path, strerror(ENAMETOOLONG)); - exit(1); - } + if (label == NULL) + label = xstrdup("default"); + if (path == NULL && (path = makesockpath(label)) == NULL) { + log_warn("can't create socket"); + exit(1); } - xfree(path); + xfree(label); shell = getenv("SHELL"); if (shell == NULL || *shell == '\0') { @@ -374,8 +406,9 @@ main(int argc, char **argv) } memset(&cctx, 0, sizeof cctx); - if (client_init(rpath, &cctx, start_server, flags) != 0) + if (client_init(path, &cctx, start_server, flags) != 0) exit(1); + xfree(path); b = buffer_create(BUFSIZ); if (unlock) { @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.280 2009-03-21 12:44:06 nicm Exp $ */ +/* $Id: tmux.h,v 1.281 2009-03-27 15:57:10 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott <nicm@users.sourceforge.net> @@ -1022,7 +1022,7 @@ extern time_t server_activity; extern int debug_level; extern int be_quiet; extern time_t start_time; -extern const char *socket_path; +extern char *socket_path; void logfile(const char *); void siginit(void); void sigreset(void); |