static void autolog_log(void *server, const char *target) { LOG_REC *log; char *fname, *dir, *str; log = log_find_item(target); if (log != NULL) return; fname = parse_special_string(autolog_path, server, NULL, target, NULL); if (log_find(fname) == NULL) { str = convert_home(fname); dir = g_dirname(str); g_free(str); mkdir(dir, LOG_DIR_CREATE_MODE); g_free(dir); log = log_create_rec(fname, autolog_level, target); if (log != NULL) { log->temp = TRUE; log_update(log); log_start_logging(log); } } g_free(fname); }
void window_update_prompt(void) { const char *special; char *prompt, *text; int var_used; special = settings_get_str(active_win->active != NULL ? "prompt" : "prompt_window"); if (*special == '\0') { gui_entry_set_prompt(""); return; } prompt = parse_special_string(special, active_win->active_server, active_win->active, "", &var_used, PARSE_FLAG_ISSET_ANY); if (!var_used && strchr(special, '$') != NULL) { /* none of the $vars had non-empty values, use empty prompt */ *prompt = '\0'; } /* set prompt */ text = show_lowascii(prompt); gui_entry_set_prompt(text); g_free(text); g_free(prompt); }
void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only, const char *str, const char *data, int escape_vars) { SERVER_REC *server; WI_ITEM_REC *wiitem; char *tmpstr, *tmpstr2; int len; if (str == NULL) str = statusbar_item_get_value(item); if (str == NULL || *str == '\0') { item->min_size = item->max_size = 0; return; } if (active_win == NULL) { server = NULL; wiitem = NULL; } else { server = active_win->active_server; wiitem = active_win->active; } /* expand templates */ tmpstr = theme_format_expand_data(current_theme, &str, 'n', 'n', NULL, NULL, EXPAND_FLAG_ROOT | EXPAND_FLAG_IGNORE_REPLACES | EXPAND_FLAG_IGNORE_EMPTY); /* expand $variables */ tmpstr2 = parse_special_string(tmpstr, server, wiitem, data, NULL, (escape_vars ? PARSE_FLAG_ESCAPE_VARS : 0 )); g_free(tmpstr); /* remove color codes (not %formats) */ tmpstr = strip_codes(tmpstr2); g_free(tmpstr2); if (get_size_only) { item->min_size = item->max_size = format_get_length(tmpstr); } else { if (item->size < item->min_size) { /* they're forcing us smaller than minimum size.. */ len = format_real_length(tmpstr, item->size); tmpstr[len] = '\0'; } tmpstr2 = update_statusbar_bg(tmpstr, item->bar->color); gui_printtext(item->xpos, item->bar->real_ypos, tmpstr2); g_free(tmpstr2); } g_free(tmpstr); }
/* CTCP version */ static void ctcp_version(const char *data, IRC_SERVER_REC *server, const char *nick) { char *str, *reply; g_return_if_fail(server != NULL); g_return_if_fail(nick != NULL); reply = parse_special_string(settings_get_str("ctcp_version_reply"), server, NULL, "", NULL); str = g_strdup_printf("NOTICE %s :\001VERSION %s\001", nick, reply); ctcp_send_reply(server, str); g_free(str); g_free(reply); }
/* SYNTAX: WALL [<channel>] <message> */ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { char *channame, *msg, *args, *recoded; void *free_arg; IRC_CHANNEL_REC *chanrec; GSList *tmp, *nicks; CMD_IRC_SERVER(server); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg)) return; if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); chanrec = irc_channel_find(server, channame); if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND); /* See if the server has advertised support of wallchops */ if (g_hash_table_lookup(chanrec->server->isupport, "statusmsg") || g_hash_table_lookup(chanrec->server->isupport, "wallchops")) irc_send_cmdv(server, "NOTICE @%s :%s", chanrec->name, msg); else { /* Fall back to manually noticing each op */ nicks = NULL; g_hash_table_foreach(chanrec->nicks, (GHFunc) cmd_wall_hash, &nicks); args = g_strconcat(chanrec->name, " ", msg, NULL); msg = parse_special_string(settings_get_str("wall_format"), SERVER(server), item, args, NULL, 0); g_free(args); recoded = recode_out(SERVER(server), msg, channame); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (rec != chanrec->ownnick) { irc_send_cmdv(server, "NOTICE %s :%s", rec->nick, recoded); } } g_free(recoded); g_free(msg); g_slist_free(nicks); } cmd_params_free(free_arg); }
static void autolog_open(SERVER_REC *server, const char *server_tag, const char *target) { LOG_REC *log; char *fname, *dir, *fixed_target, *params; log = logs_find_item(LOG_ITEM_TARGET, target, server_tag, NULL); if (log != NULL && !log->failed) { log_start_logging(log); return; } /* '/' -> '_' - don't even accidentally try to log to #../../../file if you happen to join to such channel.. similar for some characters that are metacharacters and/or illegal in Windows filenames. '%' -> '%%' - so strftime() won't mess with them */ fixed_target = escape_target(target); if (CHAT_PROTOCOL(server)->case_insensitive) ascii_strdown(fixed_target); /* $0 = target, $1 = server tag */ params = g_strconcat(fixed_target, " ", server_tag, NULL); g_free(fixed_target); fname = parse_special_string(autolog_path, server, NULL, params, NULL, 0); g_free(params); if (log_find(fname) == NULL) { log = log_create_rec(fname, autolog_level); if (!settings_get_bool("autolog_colors")) log->colorizer = log_colorizer_strip; log_item_add(log, LOG_ITEM_TARGET, target, server_tag); dir = g_path_get_dirname(log->real_fname); #ifdef HAVE_CAPSICUM capsicum_mkdir_with_parents_wrapper(dir, log_dir_create_mode); #else g_mkdir_with_parents(dir, log_dir_create_mode); #endif g_free(dir); log->temp = TRUE; log_update(log); log_start_logging(log); } g_free(fname); }
static void sig_gui_key_pressed(int key) { XMPP_QUERY_REC *query; time_t current_time; char *str = NULL; if (!settings_get_bool("xmpp_send_composing") && keylog_active) return; query = XMPP_QUERY(active_win->active); if (query == NULL || !IS_XMPP_SERVER(query->server)) return; /* ignore command or empty line */ str = parse_special_string("$L", active_win->active_server, active_win->active, "", NULL, 0); if (str != NULL && (*str == *settings_get_str("cmdchars") || *str == '\0')) goto out; if (key != KEY_TAB && key != KEY_RETURN && last_key != KEY_ESCAPE && key != KEY_ESCAPE && last_key != KEYS_PAGE && key != KEYS_PAGE && key != KEYS_OTHER && key != KEY_BACKSPACE) { current_time = time(NULL); /* start composing */ if (query->composing_time == 0) { query->composing_time = current_time; g_timeout_add(COMPOSING_TIMEOUT * 1000, (GSourceFunc)stop_composing, query); signal_emit("xmpp composing start", 2, query->server, query->name); /* still composing */ } else if ((current_time - query->composing_time) < (COMPOSING_TIMEOUT - 1)) query->composing_time = current_time; } out: /* message sent */ if (key == KEY_RETURN) query->composing_time = 0; last_key = key; g_free(str); }
/* execute the commands in string - commands can be split with ';' */ void eval_special_string(const char *cmd, const char *data, SERVER_REC *server, void *item) { const char *cmdchars; char *orig, *str, *start, *ret; int arg_used; cmdchars = settings_get_str("cmdchars"); orig = start = str = g_strdup(cmd); do { if (is_split_char(str, start)) *str++ = '\0'; else if (*str != '\0') { str++; continue; } ret = parse_special_string(start, server, item, data, &arg_used); if (strchr(cmdchars, *ret) == NULL) { /* no command char - let's put it there.. */ char *old = ret; ret = g_strdup_printf("%c%s", *cmdchars, old); g_free(old); } if (!arg_used && *data != '\0') { /* append the string with all the arguments */ char *old = ret; ret = g_strconcat(old, " ", data, NULL); g_free(old); } signal_emit("send command", 3, ret, server, item); g_free(ret); start = str; } while (*start != '\0'); g_free(orig); }
static char *theme_replace_expand(THEME_REC *theme, int index, char default_fg, char default_bg, char *last_fg, char *last_bg, char chr, int flags) { GSList *rec; char *ret, *abstract, data[2]; rec = g_slist_nth(theme->replace_values, index); g_return_val_if_fail(rec != NULL, NULL); data[0] = chr; data[1] = '\0'; abstract = rec->data; abstract = theme_format_expand_data(theme, (const char **) &abstract, default_fg, default_bg, last_fg, last_bg, flags); ret = parse_special_string(abstract, NULL, NULL, data, NULL, PARSE_FLAG_ONLY_ARGS); g_free(abstract); return ret; }
/* SYNTAX: WALL [<channel>] <message> */ static void cmd_wall(const char *data, IRC_SERVER_REC *server, WI_ITEM_REC *item) { char *channame, *msg, *args; void *free_arg; IRC_CHANNEL_REC *chanrec; GSList *tmp, *nicks; g_return_if_fail(data != NULL); if (!IS_IRC_SERVER(server) || !server->connected) cmd_return_error(CMDERR_NOT_CONNECTED); if (!cmd_get_params(data, &free_arg, 2 | PARAM_FLAG_OPTCHAN | PARAM_FLAG_GETREST, item, &channame, &msg)) return; if (*msg == '\0') cmd_param_error(CMDERR_NOT_ENOUGH_PARAMS); chanrec = irc_channel_find(server, channame); if (chanrec == NULL) cmd_param_error(CMDERR_CHAN_NOT_FOUND); /* send notice to all ops */ nicks = NULL; g_hash_table_foreach(chanrec->nicks, (GHFunc) cmd_wall_hash, &nicks); args = g_strconcat(chanrec->name, " ", msg, NULL); msg = parse_special_string(settings_get_str("wall_format"), SERVER(server), item, args, NULL); g_free(args); for (tmp = nicks; tmp != NULL; tmp = tmp->next) { NICK_REC *rec = tmp->data; if (g_strcasecmp(rec->nick, server->nick) != 0) irc_send_cmdv(server, "NOTICE %s :%s", rec->nick, msg); } g_free(msg); g_slist_free(nicks); cmd_params_free(free_arg); }
/* expand a single {abstract ...data... } */ static char *theme_format_expand_abstract(THEME_REC *theme, const char **formatp, char default_fg, char default_bg, int flags) { GString *str; const char *p, *format; char *abstract, *data, *ret; int len; format = *formatp; /* get abstract name first */ p = format; while (*p != '\0' && *p != ' ' && *p != '{' && *p != '}') p++; if (*p == '\0' || p == format) return NULL; /* error */ len = (int) (p-format); abstract = g_strndup(format, len); /* skip the following space, if there's any more spaces they're treated as arguments */ if (*p == ' ') { len++; if ((flags & EXPAND_FLAG_IGNORE_EMPTY) && data_is_empty(&p)) { *formatp = p; g_free(abstract); return NULL; } } *formatp = format+len; /* get the abstract data */ data = g_hash_table_lookup(theme->abstracts, abstract); g_free(abstract); if (data == NULL) { /* unknown abstract, just display the data */ data = "$0-"; } abstract = g_strdup(data); /* we'll need to get the data part. it may contain more abstracts, they are _NOT_ expanded. */ data = theme_format_expand_get(theme, formatp); len = strlen(data); if (len > 1 && i_isdigit(data[len-1]) && data[len-2] == '$') { /* ends with $<digit> .. this breaks things if next character is digit or '-' */ char digit, *tmp; tmp = data; digit = tmp[len-1]; tmp[len-1] = '\0'; data = g_strdup_printf("%s{%c}", tmp, digit); g_free(tmp); } ret = parse_special_string(abstract, NULL, NULL, data, NULL, PARSE_FLAG_ONLY_ARGS); g_free(abstract); g_free(data); str = g_string_new(NULL); p = ret; while (*p != '\0') { if (*p == '\\') { int chr; p++; chr = expand_escape(&p); g_string_append_c(str, chr != -1 ? chr : *p); } else g_string_append_c(str, *p); p++; } g_free(ret); abstract = str->str; g_string_free(str, FALSE); /* abstract may itself contain abstracts or replaces */ p = abstract; ret = theme_format_expand_data(theme, &p, default_fg, default_bg, &default_fg, &default_bg, flags | EXPAND_FLAG_LASTCOLOR_ARG); g_free(abstract); return ret; }
void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only, const char *str, const char *data, int escape_vars) { SERVER_REC *server; WI_ITEM_REC *wiitem; char *tmpstr, *tmpstr2; theme_rm_col reset; strcpy(reset.m, "n"); int len; if (str == NULL) str = statusbar_item_get_value(item); if (str == NULL || *str == '\0') { item->min_size = item->max_size = 0; return; } if (active_win == NULL) { server = NULL; wiitem = NULL; } else { server = active_win->active_server != NULL ? active_win->active_server : active_win->connect_server; wiitem = active_win->active; } /* expand templates */ tmpstr = theme_format_expand_data(current_theme, &str, reset, reset, NULL, NULL, EXPAND_FLAG_ROOT | EXPAND_FLAG_IGNORE_REPLACES | EXPAND_FLAG_IGNORE_EMPTY); /* expand $variables */ tmpstr2 = parse_special_string(tmpstr, server, wiitem, data, NULL, (escape_vars ? PARSE_FLAG_ESCAPE_VARS : 0 )); g_free(tmpstr); /* remove color codes (not %formats) */ tmpstr = strip_codes(tmpstr2); g_free(tmpstr2); if (get_size_only) { item->min_size = item->max_size = format_get_length(tmpstr); } else { GString *out; if (item->size < item->min_size) { /* they're forcing us smaller than minimum size.. */ len = format_real_length(tmpstr, item->size); tmpstr[len] = '\0'; } out = finalize_string(tmpstr, item->bar->color); /* make sure the str is big enough to fill the requested size, so it won't corrupt screen */ len = format_get_length(tmpstr); if (len < item->size) { int i; len = item->size-len; for (i = 0; i < len; i++) g_string_append_c(out, ' '); } gui_printtext(item->xpos, item->bar->real_ypos, out->str); g_string_free(out, TRUE); } g_free(tmpstr); }
void statusbar_item_default_handler(SBAR_ITEM_REC *item, int get_size_only, const char *str, const char *data, int escape_vars) { SERVER_REC *server; WI_ITEM_REC *wiitem; char *tmpstr, *tmpstr2; int len; if (str == NULL) str = statusbar_item_get_value(item); if (str == NULL || *str == '\0') { item->min_size = item->max_size = 0; return; } if (active_win == NULL) { server = NULL; wiitem = NULL; } else { server = active_win->active_server != NULL ? active_win->active_server : active_win->connect_server; wiitem = active_win->active; } /* expand templates */ tmpstr = theme_format_expand_data(current_theme, &str, 'n', 'n', NULL, NULL, EXPAND_FLAG_ROOT | EXPAND_FLAG_IGNORE_REPLACES | EXPAND_FLAG_IGNORE_EMPTY); /* expand $variables */ tmpstr2 = parse_special_string(tmpstr, server, wiitem, data, NULL, (escape_vars ? PARSE_FLAG_ESCAPE_VARS : 0 )); g_free(tmpstr); /* remove color codes (not %formats) */ tmpstr = strip_codes(tmpstr2); g_free(tmpstr2); /* show all control chars reversed */ tmpstr2 = reverse_controls(tmpstr); g_free(tmpstr); tmpstr = tmpstr2; if (get_size_only) { item->min_size = item->max_size = format_get_length(tmpstr); } else { if (item->size < item->min_size) { /* they're forcing us smaller than minimum size.. */ len = format_real_length(tmpstr, item->size); tmpstr[len] = '\0'; } else { /* make sure the str is big enough to fill the requested size, so it won't corrupt screen */ len = format_get_length(tmpstr); if (len < item->size) { char *fill; len = item->size-len; fill = g_malloc(len + 1); memset(fill, ' ', len); fill[len] = '\0'; tmpstr2 = g_strconcat(tmpstr, fill, NULL); g_free(fill); g_free(tmpstr); tmpstr = tmpstr2; } } tmpstr2 = update_statusbar_bg(tmpstr, item->bar->color); gui_printtext(item->xpos, item->bar->real_ypos, tmpstr2); g_free(tmpstr2); } g_free(tmpstr); }