1*6ae61da3Snicm /* $OpenBSD: names.c,v 1.35 2016/07/15 09:27:35 nicm Exp $ */ 2311827fbSnicm 3311827fbSnicm /* 498ca8272Snicm * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com> 5311827fbSnicm * 6311827fbSnicm * Permission to use, copy, modify, and distribute this software for any 7311827fbSnicm * purpose with or without fee is hereby granted, provided that the above 8311827fbSnicm * copyright notice and this permission notice appear in all copies. 9311827fbSnicm * 10311827fbSnicm * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11311827fbSnicm * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12311827fbSnicm * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13311827fbSnicm * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14311827fbSnicm * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER 15311827fbSnicm * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING 16311827fbSnicm * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17311827fbSnicm */ 18311827fbSnicm 19311827fbSnicm #include <sys/types.h> 20311827fbSnicm 21311827fbSnicm #include <ctype.h> 22311827fbSnicm #include <libgen.h> 237d053cf9Snicm #include <stdlib.h> 24311827fbSnicm #include <string.h> 25311827fbSnicm 26311827fbSnicm #include "tmux.h" 27311827fbSnicm 2800b2deccSnicm void name_time_callback(int, short, void *); 2900b2deccSnicm int name_time_expired(struct window *, struct timeval *); 30f5015e68Snicm 31311827fbSnicm void 32d0e2e7f1Snicm name_time_callback(__unused int fd, __unused short events, void *arg) 33311827fbSnicm { 3400b2deccSnicm struct window *w = arg; 35f5015e68Snicm 3600b2deccSnicm /* The event loop will call check_window_name for us on the way out. */ 3700b2deccSnicm log_debug("@%u name timer expired", w->id); 3800b2deccSnicm } 39f5015e68Snicm 4000b2deccSnicm int 4100b2deccSnicm name_time_expired(struct window *w, struct timeval *tv) 4200b2deccSnicm { 4300b2deccSnicm struct timeval offset; 4400b2deccSnicm 4500b2deccSnicm timersub(tv, &w->name_time, &offset); 4600b2deccSnicm if (offset.tv_sec != 0 || offset.tv_usec > NAME_INTERVAL) 4700b2deccSnicm return (0); 4800b2deccSnicm return (NAME_INTERVAL - offset.tv_usec); 49f5015e68Snicm } 50f5015e68Snicm 51f5015e68Snicm void 5200b2deccSnicm check_window_name(struct window *w) 53f5015e68Snicm { 5400b2deccSnicm struct timeval tv, next; 55203ea44bSnicm char *name; 5600b2deccSnicm int left; 57311827fbSnicm 58a3560846Snicm if (w->active == NULL) 59a3560846Snicm return; 60a3560846Snicm 61d89252e5Snicm if (!options_get_number(w->options, "automatic-rename")) 6200b2deccSnicm return; 6300b2deccSnicm 6400b2deccSnicm if (~w->active->flags & PANE_CHANGED) { 6500b2deccSnicm log_debug("@%u active pane not changed", w->id); 6691e80530Snicm return; 67f5015e68Snicm } 6800b2deccSnicm log_debug("@%u active pane changed", w->id); 69b0b8e5bfSnicm 7000b2deccSnicm gettimeofday(&tv, NULL); 7100b2deccSnicm left = name_time_expired(w, &tv); 7200b2deccSnicm if (left != 0) { 7300b2deccSnicm if (!event_initialized(&w->name_event)) 7400b2deccSnicm evtimer_set(&w->name_event, name_time_callback, w); 7500b2deccSnicm if (!evtimer_pending(&w->name_event, NULL)) { 76*6ae61da3Snicm log_debug("@%u name timer queued (%d left)", w->id, 77*6ae61da3Snicm left); 7800b2deccSnicm timerclear(&next); 7900b2deccSnicm next.tv_usec = left; 8000b2deccSnicm event_add(&w->name_event, &next); 81*6ae61da3Snicm } else { 82*6ae61da3Snicm log_debug("@%u name timer already queued (%d left)", 83*6ae61da3Snicm w->id, left); 84*6ae61da3Snicm } 855b9cc8aaSnicm return; 8600b2deccSnicm } 8700b2deccSnicm memcpy(&w->name_time, &tv, sizeof w->name_time); 8800b2deccSnicm if (event_initialized(&w->name_event)) 8900b2deccSnicm evtimer_del(&w->name_event); 9000b2deccSnicm 915b9cc8aaSnicm w->active->flags &= ~PANE_CHANGED; 925b9cc8aaSnicm 93203ea44bSnicm name = format_window_name(w); 94203ea44bSnicm if (strcmp(name, w->name) != 0) { 9500b2deccSnicm log_debug("@%u new name %s (was %s)", w->id, name, w->name); 96203ea44bSnicm window_set_name(w, name); 97311827fbSnicm server_status_window(w); 9800b2deccSnicm } else 9900b2deccSnicm log_debug("@%u name not changed (still %s)", w->id, w->name); 10000b2deccSnicm 101203ea44bSnicm free(name); 102311827fbSnicm } 103311827fbSnicm 104311827fbSnicm char * 105311827fbSnicm default_window_name(struct window *w) 106311827fbSnicm { 10758034113Snicm char *cmd, *s; 10858034113Snicm 10958034113Snicm cmd = cmd_stringify_argv(w->active->argc, w->active->argv); 11058034113Snicm if (cmd != NULL && *cmd != '\0') 11158034113Snicm s = parse_window_name(cmd); 11258034113Snicm else 11358034113Snicm s = parse_window_name(w->active->shell); 11458034113Snicm free(cmd); 11558034113Snicm return (s); 116311827fbSnicm } 117311827fbSnicm 118311827fbSnicm char * 119203ea44bSnicm format_window_name(struct window *w) 120203ea44bSnicm { 121203ea44bSnicm struct format_tree *ft; 122203ea44bSnicm char *fmt, *name; 123203ea44bSnicm 124229bdecfSnicm ft = format_create(NULL, 0); 125f426771eSnicm format_defaults_window(ft, w); 126f426771eSnicm format_defaults_pane(ft, w->active); 127203ea44bSnicm 128d89252e5Snicm fmt = options_get_string(w->options, "automatic-rename-format"); 129203ea44bSnicm name = format_expand(ft, fmt); 130203ea44bSnicm 131203ea44bSnicm format_free(ft); 132203ea44bSnicm return (name); 133203ea44bSnicm } 134203ea44bSnicm 135203ea44bSnicm char * 13666fd4858Snicm parse_window_name(const char *in) 137311827fbSnicm { 13866fd4858Snicm char *copy, *name, *ptr; 139311827fbSnicm 140311827fbSnicm name = copy = xstrdup(in); 14166fd4858Snicm if (strncmp(name, "exec ", (sizeof "exec ") - 1) == 0) 14266fd4858Snicm name = name + (sizeof "exec ") - 1; 143311827fbSnicm 144203ea44bSnicm while (*name == ' ' || *name == '-') 145311827fbSnicm name++; 146311827fbSnicm if ((ptr = strchr(name, ' ')) != NULL) 147311827fbSnicm *ptr = '\0'; 148311827fbSnicm 149311827fbSnicm if (*name != '\0') { 150311827fbSnicm ptr = name + strlen(name) - 1; 1513619f6a1Sray while (ptr > name && !isalnum((u_char)*ptr)) 152311827fbSnicm *ptr-- = '\0'; 153311827fbSnicm } 154311827fbSnicm 155311827fbSnicm if (*name == '/') 156311827fbSnicm name = basename(name); 157311827fbSnicm name = xstrdup(name); 1587d053cf9Snicm free(copy); 159311827fbSnicm return (name); 160311827fbSnicm } 161