1 /* $OpenBSD: names.c,v 1.23 2014/05/13 08:08:32 nicm Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Nicholas Marriott <nicm@users.sourceforge.net> 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 <ctype.h> 22 #include <libgen.h> 23 #include <stdlib.h> 24 #include <string.h> 25 26 #include "tmux.h" 27 28 void window_name_callback(unused int, unused short, void *); 29 30 void 31 queue_window_name(struct window *w) 32 { 33 struct timeval tv; 34 35 tv.tv_sec = 0; 36 tv.tv_usec = NAME_INTERVAL * 1000L; 37 38 if (event_initialized(&w->name_timer)) 39 evtimer_del(&w->name_timer); 40 evtimer_set(&w->name_timer, window_name_callback, w); 41 evtimer_add(&w->name_timer, &tv); 42 } 43 44 void 45 window_name_callback(unused int fd, unused short events, void *data) 46 { 47 struct window *w = data; 48 char *name; 49 50 if (w->active == NULL) 51 return; 52 53 if (!options_get_number(&w->options, "automatic-rename")) { 54 if (event_initialized(&w->name_timer)) 55 event_del(&w->name_timer); 56 return; 57 } 58 queue_window_name(w); 59 60 name = format_window_name(w); 61 if (strcmp(name, w->name) != 0) { 62 window_set_name(w, name); 63 server_status_window(w); 64 } 65 free(name); 66 } 67 68 char * 69 default_window_name(struct window *w) 70 { 71 char *cmd, *s; 72 73 cmd = cmd_stringify_argv(w->active->argc, w->active->argv); 74 if (cmd != NULL && *cmd != '\0') 75 s = parse_window_name(cmd); 76 else 77 s = parse_window_name(w->active->shell); 78 free(cmd); 79 return (s); 80 } 81 82 char * 83 format_window_name(struct window *w) 84 { 85 struct format_tree *ft; 86 char *fmt, *name; 87 88 ft = format_create(); 89 format_window(ft, w); 90 format_window_pane(ft, w->active); 91 92 fmt = options_get_string(&w->options, "automatic-rename-format"); 93 name = format_expand(ft, fmt); 94 95 format_free(ft); 96 return (name); 97 } 98 99 char * 100 parse_window_name(const char *in) 101 { 102 char *copy, *name, *ptr; 103 104 name = copy = xstrdup(in); 105 if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0) 106 name = name + (sizeof "exec ") - 1; 107 108 while (*name == ' ' || *name == '-') 109 name++; 110 if ((ptr = strchr(name, ' ')) != NULL) 111 *ptr = '\0'; 112 113 if (*name != '\0') { 114 ptr = name + strlen(name) - 1; 115 while (ptr > name && !isalnum((u_char)*ptr)) 116 *ptr-- = '\0'; 117 } 118 119 if (*name == '/') 120 name = basename(name); 121 name = xstrdup(name); 122 free(copy); 123 return (name); 124 } 125