/* * status.c: handles the status line updating, etc for IRCII * * Written By Michael Sandrof * * Copyright (c) 1990 Michael Sandrof. * Copyright (c) 1991, 1992 Troy Rollo. * Copyright (c) 1992-2006 Matthew R. Green. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * WARNING! THIS CODE HAS DRAGONS. BE *VERY* CAREFUL WHEN CHANGING * ANYTHING IN HERE. TEST IT EXTENSIVELY. */ #include "irc.h" IRCII_RCSID("@(#)$eterna: status.c,v 1.89 2006/07/22 03:50:10 mrg Exp $"); #include "ircterm.h" #include "status.h" #include "server.h" #include "vars.h" #include "hook.h" #include "input.h" #include "edit.h" #include "window.h" #include "screen.h" #include "mail.h" #include "output.h" #include "names.h" #include "ircaux.h" #include "translat.h" #include "debug.h" static u_char *convert_format(u_char *, int); static u_char *status_nickname(Window *); static u_char *status_query_nick(Window *); static u_char *status_right_justify(Window *); static u_char *status_chanop(Window *); static u_char *status_channel(Window *); static u_char *status_server(Window *); static u_char *status_mode(Window *); static u_char *status_umode(Window *); static u_char *status_insert_mode(Window *); static u_char *status_overwrite_mode(Window *); static u_char *status_away(Window *); static u_char *status_oper(Window *); static u_char *status_voice(Window *); static u_char *status_user0(Window *); static u_char *status_user1(Window *); static u_char *status_user2(Window *); static u_char *status_user3(Window *); static u_char *status_hold(Window *); static u_char *status_version(Window *); static u_char *status_clock(Window *); static u_char *status_hold_lines(Window *); static u_char *status_window(Window *); static u_char *status_mail(Window *); static u_char *status_refnum(Window *); static u_char *status_null_function(Window *); static u_char *status_notify_windows(Window *); static u_char *status_group(Window *); static u_char *status_scrolled(Window *); static u_char *status_scrolled_lines(Window *); static void alarm_switch(int); static u_char *convert_sub_format(u_char *, int); static void make_status_one(Window *, int, int); /* * Maximum number of "%" expressions in a status line format. If you change * this number, you must manually change the snprintf() in make_status */ #define MAX_FUNCTIONS 45 /* The format statements to build each portion of the status line */ static u_char *mode_format = (u_char *) 0; static u_char *umode_format = (u_char *) 0; static u_char *status_format[3] = {(u_char *) 0, (u_char *) 0, (u_char *) 0,}; static u_char *query_format = (u_char *) 0; static u_char *clock_format = (u_char *) 0; static u_char *hold_lines_format = (u_char *) 0; static u_char *scrolled_lines_format = (u_char *) 0; static u_char *channel_format = (u_char *) 0; static u_char *mail_format = (u_char *) 0; static u_char *server_format = (u_char *) 0; static u_char *notify_format = (u_char *) 0; static u_char *group_format = (u_char *) 0; /* * status_func: The list of status line function in the proper order for * display. This list is set in convert_format() */ static u_char *(*status_func[3][MAX_FUNCTIONS])(Window *); /* func_cnt: the number of status line functions assigned */ static int func_cnt[3]; static int alarm_hours, /* hour setting for alarm in 24 hour time */ alarm_minutes; /* minute setting for alarm */ /* Stuff for the alarm */ static struct itimerval clock_timer = { { 10L, 0L }, { 1L, 0L } }; static struct itimerval off_timer = { { 0L, 0L }, { 0L, 0L } }; static RETSIGTYPE alarmed(int); int do_status_alarmed; /* alarmed: This is called whenever a SIGALRM is received and the alarm is on */ static RETSIGTYPE alarmed(signo) int signo; { do_status_alarmed = 1; } void real_status_alarmed() { u_char time_str[16]; say("The time is %s", update_clock(time_str, 16, GET_TIME)); term_beep(); term_beep(); term_beep(); } /* * alarm_switch: turns on and off the alarm display. Sets the system timer * and sets up a signal to trap SIGALRMs. If flag is 1, the alarmed() * routine will be activated every 10 seconds or so. If flag is 0, the timer * and signal stuff are reset */ static void alarm_switch(flag) int flag; { static int alarm_on = 0; if (flag) { if (!alarm_on) { setitimer(ITIMER_REAL, &clock_timer, (struct itimerval *) 0); (void) MY_SIGNAL(SIGALRM, alarmed, 0); alarm_on = 1; } } else if (alarm_on) { setitimer(ITIMER_REAL, &off_timer, (struct itimerval *) 0); (void) MY_SIGNAL(SIGALRM, (sigfunc *)SIG_IGN, 0); alarm_on = 0; } } /* * set_alarm: given an input string, this checks its validity as a clock * type time thingy. It accepts two time formats. The first is the HH:MM:XM * format where HH is between 1 and 12, MM is between 0 and 59, and XM is * either AM or PM. The second is the HH:MM format where HH is between 0 and * 23 and MM is between 0 and 59. This routine also looks for one special * case, "OFF", which sets the alarm string to null */ void set_alarm(str) u_char *str; { u_char hours[10], minutes[10], merid[3]; u_char time_str[10]; int c, h, m, min_hours, max_hours; if (str == (u_char *) 0) { alarm_switch(0); return; } if (!my_stricmp(str, UP(var_settings[OFF]))) { set_string_var(CLOCK_ALARM_VAR, (u_char *) 0); alarm_switch(0); return; } c = sscanf(CP(str), " %2[^:]:%2[^paPA]%2s ", hours, minutes, merid); switch (c) { case 2: min_hours = 0; max_hours = 23; break; case 3: min_hours = 1; max_hours = 12; upper(UP(merid)); break; default: say("CLOCK_ALARM: Bad time format."); set_string_var(CLOCK_ALARM_VAR, (u_char *) 0); return; } h = my_atoi(hours); m = my_atoi(minutes); if (h >= min_hours && h <= max_hours && isdigit(hours[0]) && (isdigit(hours[1]) || hours[1] == (u_char) 0)) { if (m >= 0 && m <= 59 && isdigit(minutes[0]) && isdigit(minutes[1])) { alarm_minutes = m; alarm_hours = h; if (max_hours == 12) { if (merid[0] != 'A') { if (merid[0] == 'P') { if (h != 12) alarm_hours += 12; } else { say("CLOCK_ALARM: alarm time must end with either \"AM\" or \"PM\""); set_string_var(CLOCK_ALARM_VAR, (u_char *) 0); } } else { if (h == 12) alarm_hours = 0; } if (merid[1] == 'M') { snprintf(CP(time_str), sizeof time_str, "%02d:%02d%s", h, m, merid); set_string_var(CLOCK_ALARM_VAR, time_str); } else { say("CLOCK_ALARM: alarm time must end with either \"AM\" or \"PM\""); set_string_var(CLOCK_ALARM_VAR, (u_char *) 0); } } else { snprintf(CP(time_str), sizeof time_str, "%02d:%02d", h, m); set_string_var(CLOCK_ALARM_VAR, time_str); } } else { say("CLOCK_ALARM: alarm minutes value must be between 0 and 59."); set_string_var(CLOCK_ALARM_VAR, (u_char *) 0); } } else { say("CLOCK_ALARM: alarm hour value must be between %d and %d.", min_hours, max_hours); set_string_var(CLOCK_ALARM_VAR, (u_char *) 0); } } u_char * format_clock(buf, len, hour, min) u_char *buf; size_t len; int hour; int min; { char *merid; if (get_int_var(CLOCK_24HOUR_VAR)) merid = CP(empty_string); else { if (hour < 12) merid = "AM"; else merid = "PM"; if (hour > 12) hour -= 12; else if (hour == 0) hour = 12; } snprintf(CP(buf), len, "%02d:%02d%s", hour, min, merid); return buf; } /* update_clock: figures out the current time and returns it in a nice format */ u_char * update_clock(buf, len, flag) u_char *buf; size_t len; int flag; { struct tm *time_val; static u_char time_str[10]; static int min = -1, hour = -1; time_t t; int tmp_hour, tmp_min; t = time(0); time_val = localtime(&t); tmp_hour = time_val->tm_hour; tmp_min = time_val->tm_min; Debug((8, "update_clock (%s): time %lu (%02d:%02d) [old %02d:%02d]", flag == RESET_TIME ? "reset" : flag == GET_TIME ? "get" : flag == UPDATE_TIME ? "update" : "unknown", (long unsigned) t, tmp_hour, tmp_min, hour, min)); if (get_string_var(CLOCK_ALARM_VAR)) { if ((tmp_hour == alarm_hours) && (tmp_min == alarm_minutes)) alarm_switch(1); else alarm_switch(0); } if (flag == RESET_TIME || (flag == UPDATE_TIME && (tmp_min != min || tmp_hour != hour))) { int server; format_clock(time_str, sizeof time_str, tmp_hour, tmp_min); server = from_server; from_server = primary_server; Debug((8, "update_clock: in reset_time block, time_str: %s", time_str)); if (flag == UPDATE_TIME && (tmp_min != min || tmp_hour != hour)) { hour = tmp_hour; min = tmp_min; do_hook(TIMER_LIST, "%s", time_str); } do_hook(IDLE_LIST, "%ld", (t - idle_time) / 60L); from_server = server; flag = GET_TIME; } if (buf) { my_strncpy(buf, time_str, len - 1); buf[len - 1] = '\0'; } if (flag == GET_TIME) return(buf ? buf : time_str); else return ((u_char *) 0); } /*ARGSUSED*/ void reset_clock(unused) int unused; { update_clock(0, 0, RESET_TIME); update_all_status(); } /* * convert_sub_format: This is used to convert the formats of the * sub-portions of the status line to a format statement specially designed * for that sub-portions. convert_sub_format looks for a single occurence of * %c (where c is passed to the function). When found, it is replaced by "%s" * for use is a snprintf. All other occurences of % followed by any other * character are left unchanged. Only the first occurence of %c is * converted, all subsequence occurences are left unchanged. This routine * mallocs the returned string. */ static u_char * convert_sub_format(format, c) u_char *format; int c; { u_char lbuf[BIG_BUFFER_SIZE]; static u_char bletch[] = "%% "; u_char *ptr = (u_char *) 0; int dont_got_it = 1; if (format == (u_char *) 0) return ((u_char *) 0); *lbuf = (u_char) 0; while (format) { if ((ptr = my_index(format, '%')) != NULL) { *ptr = (u_char) 0; my_strmcat(lbuf, format, sizeof lbuf); *(ptr++) = '%'; if ((*ptr == c) && dont_got_it) { dont_got_it = 0; my_strmcat(lbuf, "%s", sizeof lbuf); } else { bletch[2] = *ptr; my_strmcat(lbuf, bletch, sizeof lbuf); } ptr++; } else my_strmcat(lbuf, format, sizeof lbuf); format = ptr; } malloc_strcpy(&ptr, lbuf); return (ptr); } static u_char * convert_format(format, k) u_char *format; int k; { u_char lbuf[BIG_BUFFER_SIZE]; u_char *ptr, *malloc_ptr = (u_char *) 0; int *cp; *lbuf = (u_char) 0; while (format) { if ((ptr = my_index(format, '%')) != NULL) { *ptr = (u_char) 0; my_strmcat(lbuf, format, sizeof lbuf); *(ptr++) = '%'; cp = &func_cnt[k]; if (*cp < MAX_FUNCTIONS) { switch (*(ptr++)) { case '%': /* %% instead of %, because this will be passed to snprintf */ my_strmcat(lbuf, "%%", sizeof lbuf); break; case 'N': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_nickname; break; case '>': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_right_justify; break; case 'G': new_free(&group_format); group_format = convert_sub_format(get_string_var(STATUS_GROUP_VAR), 'G'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_group; break; case 'Q': new_free(&query_format); query_format = convert_sub_format(get_string_var(STATUS_QUERY_VAR), 'Q'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_query_nick; break; case 'F': new_free(¬ify_format); notify_format = convert_sub_format(get_string_var(STATUS_NOTIFY_VAR), 'F'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_notify_windows; break; case '@': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_chanop; break; case 'C': new_free(&channel_format); channel_format = convert_sub_format(get_string_var(STATUS_CHANNEL_VAR), 'C'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_channel; break; case 'S': new_free(&server_format); server_format = convert_sub_format(get_string_var(STATUS_SERVER_VAR), 'S'); my_strmcat(lbuf,"%s",sizeof lbuf); status_func[k][(*cp)++] = status_server; break; case '+': new_free(&mode_format); mode_format = convert_sub_format(get_string_var(STATUS_MODE_VAR), '+'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_mode; break; case '#': new_free(&umode_format); umode_format = convert_sub_format(get_string_var(STATUS_UMODE_VAR), '#'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_umode; break; case 'M': new_free(&mail_format); mail_format = convert_sub_format(get_string_var(STATUS_MAIL_VAR), 'M'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_mail; break; case 'I': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_insert_mode; break; case 'O': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_overwrite_mode; break; case 'A': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_away; break; case 'V': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_version; break; case 'R': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_refnum; break; case 'T': new_free(&clock_format); clock_format = convert_sub_format(get_string_var(STATUS_CLOCK_VAR), 'T'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_clock; break; case 'U': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_user0; break; case 'H': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_hold; break; case 'B': new_free(&hold_lines_format); hold_lines_format = convert_sub_format(get_string_var(STATUS_HOLD_LINES_VAR), 'B'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_hold_lines; break; case 'P': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_scrolled; Debug((2, "got P in status")); break; case 's': new_free(&scrolled_lines_format); scrolled_lines_format = convert_sub_format(get_string_var(STATUS_SCROLLED_LINES_VAR), 's'); my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_scrolled_lines; Debug((2, "got s in status: sl-format '%s'", scrolled_lines_format)); break; case '*': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_oper; break; case 'v': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_voice; break; case 'W': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_window; break; case 'X': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_user1; break; case 'Y': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_user2; break; case 'Z': my_strmcat(lbuf, "%s", sizeof lbuf); status_func[k][(*cp)++] = status_user3; break; /* no default..?? - phone, jan 1993 */ /* empty is a good default -lynx, mar 93 */ } } else ptr++; } else my_strmcat(lbuf, format, sizeof lbuf); format = ptr; } /* this frees the old str first */ malloc_strcpy(&malloc_ptr, lbuf); return (malloc_ptr); } void build_status(format) u_char *format; { int i, k; for (k = 0; k < 3; k++) { new_free(&status_format[k]); func_cnt[k] = 0; switch (k) { case 0 : format = get_string_var(STATUS_FORMAT_VAR); break; case 1 : format = get_string_var(STATUS_FORMAT1_VAR); break; case 2 : format = get_string_var(STATUS_FORMAT2_VAR); break; } if (format != NULL) /* convert_format mallocs for us */ status_format[k] = convert_format(format, k); for (i = func_cnt[k]; i < MAX_FUNCTIONS; i++) status_func[k][i] = status_null_function; } update_all_status(); } void make_status(window) Window *window; { int k, l, final; switch (window->double_status) { case -1: new_free(&window->status_line[0]); new_free(&window->status_line[1]); goto out; case 0: new_free(&window->status_line[1]); final = 1; break; case 1: final = 2; break; default: yell("--- make_status: unknown window->double value %d", window->double_status); final = 1; } for (k = 0 ; k < final; k++) { if (k) l = 2; else if (window->double_status) l = 1; else l = 0; if (!dumb && status_format[l]) make_status_one(window, k, l); } out: cursor_to_input(); } static void make_status_one(window, k, l) Window *window; int k; int l; { Screen *old_current_screen; u_char lbuf[BIG_BUFFER_SIZE]; u_char rbuf[BIG_BUFFER_SIZE]; u_char *func_value[MAX_FUNCTIONS]; size_t len; int i; int rjustifypos; int justifypadlen; int RealPosition; /* * XXX: note that this code below depends on the definition * of MAX_FUNCTIONS (currently 45), and the snprintf must * be updated if MAX_FUNCTIONS is changed. */ for (i = 0; i < MAX_FUNCTIONS; i++) func_value[i] = (status_func[l][i]) (window); lbuf[0] = REV_TOG; snprintf(CP(lbuf+1), sizeof(lbuf) - 1, CP(status_format[l]), func_value[0], func_value[1], func_value[2], func_value[3], func_value[4], func_value[5], func_value[6], func_value[7], func_value[8], func_value[9], func_value[10], func_value[11], func_value[12], func_value[13], func_value[14], func_value[15], func_value[16], func_value[17], func_value[18], func_value[19], func_value[20], func_value[21], func_value[22], func_value[23], func_value[24], func_value[25], func_value[26], func_value[27], func_value[28], func_value[29], func_value[30], func_value[31], func_value[32], func_value[33], func_value[34], func_value[35], func_value[36], func_value[37], func_value[38], func_value[39], func_value[40], func_value[41], func_value[42], func_value[43], func_value[44]); for (i = 0; i < MAX_FUNCTIONS; i++) new_free(&(func_value[i])); /* Patched 26-Mar-93 by Aiken * make_window now right-justifies everything * after a %> * it's also more efficient. */ rjustifypos = -1; justifypadlen = 0; for (i = 0; lbuf[i]; i++) { /* formfeed is a marker for left/right border*/ if (lbuf[i] == '\f') { int len_left; int len_right; /* Split the line to left and right part */ lbuf[i] = '\0'; /* Get lengths of left and right part in number of columns */ len_right = my_strlen_c(lbuf); len_left = my_strlen_c(lbuf+i+1); justifypadlen = current_screen->co - len_right - len_left; if (justifypadlen < 0) justifypadlen = 0; /* Delete the marker */ /* FIXME: strcpy may not be used for overlapping buffers */ my_strcpy(lbuf+i, lbuf+i+1); rjustifypos = i; } } if (get_int_var(FULL_STATUS_LINE_VAR)) { if (rjustifypos == -1) { int length = my_strlen_c(lbuf); justifypadlen = current_screen->co - length; if (justifypadlen < 0) justifypadlen = 0; rjustifypos = my_strlen(lbuf); } if (justifypadlen > 0) { /* Move a part of the data out of way */ memmove(lbuf + rjustifypos + justifypadlen, lbuf + rjustifypos, my_strlen(lbuf) - rjustifypos + 1); // +1 = zero terminator /* Then fill the part with spaces */ memset(lbuf + rjustifypos, ' ', justifypadlen); } } len = my_strlen(lbuf); if (len > (sizeof(lbuf) - 2)) len = sizeof(lbuf) - 2; lbuf[len] = ALL_OFF; lbuf[len+1] = '\0'; my_strcpy_ci(rbuf, lbuf); RealPosition = 0; i = 0; old_current_screen = current_screen; set_current_screen(window->screen); term_move_cursor(RealPosition, window->bottom + k); len = output_line(rbuf, i); cursor_in_display(); if (term_clear_to_eol() && len < current_screen->co) term_space_erase(current_screen->co - len); malloc_strcpy(&window->status_line[k], rbuf); set_current_screen(old_current_screen); } static u_char * status_nickname(window) Window *window; { u_char *ptr = (u_char *) 0; if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR) && (!window->current_channel) && (window->screen->current_window != window)) malloc_strcpy(&ptr, empty_string); else malloc_strcpy(&ptr, get_server_nickname(window->server)); return (ptr); } static u_char * status_server(window) Window *window; { u_char *ptr = NULL, *rest, *name; u_char lbuf[BIG_BUFFER_SIZE]; if (connected_to_server != 1) { if (window->server != -1) { if (server_format) { name = get_server_name(window->server); rest = my_index(name, '.'); if (rest != NULL && my_strnicmp(name, UP("irc"), 3) != 0 && my_strnicmp(name, UP("icb"), 3) != 0) { if (is_number(name)) snprintf(CP(lbuf), sizeof lbuf, CP(server_format), name); else { *rest = '\0'; snprintf(CP(lbuf), sizeof lbuf, CP(server_format), name); *rest = '.'; } } else snprintf(CP(lbuf), sizeof lbuf, CP(server_format), name); } else *lbuf = '\0'; } else my_strcpy(lbuf, " No Server"); } else *lbuf = '\0'; malloc_strcpy(&ptr, lbuf); return (ptr); } static u_char * status_group(window) Window *window; { u_char *ptr = (u_char *) 0; if (window->server_group && group_format) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(lbuf), sizeof lbuf, CP(group_format), find_server_group_name(window->server_group)); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_query_nick(window) Window *window; { u_char *ptr = (u_char *) 0; if (window->query_nick && query_format) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(lbuf), sizeof lbuf, CP(query_format), window->query_nick); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_right_justify(window) Window *window; { u_char *ptr = (u_char *) 0; malloc_strcpy(&ptr, UP("\f")); return (ptr); } static u_char * status_notify_windows(window) Window *window; { u_char refnum[10]; int doneone = 0; u_char *ptr = (u_char *) 0; int flag = 1; u_char buf2[81]; if (get_int_var(SHOW_STATUS_ALL_VAR) || window == window->screen->current_window) { buf2[0] = '\0'; while ((window = traverse_all_windows(&flag)) != NULL) { if (window->miscflags & WINDOW_NOTIFIED) { if (!doneone) { doneone++; snprintf(CP(refnum), sizeof refnum, "%d", window->refnum); } else snprintf(CP(refnum), sizeof refnum, ",%d", window->refnum); my_strmcat(buf2, refnum, sizeof buf2); } } } if (doneone && notify_format) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(lbuf), sizeof lbuf, CP(notify_format), buf2); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); return ptr; } static u_char * status_clock(window) Window *window; { u_char *ptr = (u_char *) 0; if ((get_int_var(CLOCK_VAR) && clock_format) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window == window->screen->current_window))) { u_char lbuf[BIG_BUFFER_SIZE]; u_char time_str[16]; snprintf(CP(lbuf), sizeof lbuf, CP(clock_format), update_clock(time_str, sizeof time_str, GET_TIME)); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_mode(window) Window *window; { u_char *ptr = (u_char *) 0, *mode; if (window->current_channel && chan_is_connected(window->current_channel, window->server)) { mode = get_channel_mode(window->current_channel,window->server); if (mode && *mode && mode_format) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(lbuf), sizeof lbuf, CP(mode_format), mode); malloc_strcpy(&ptr, lbuf); return (ptr); } } malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_umode(window) Window *window; { u_char *ptr = (u_char *) 0; u_char localbuf[10]; u_char *c; if (connected_to_server == 0) malloc_strcpy(&ptr, empty_string); else if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR) && (window->screen->current_window != window)) malloc_strcpy(&ptr, empty_string); else { c = localbuf; if (get_server_flag(window->server, USER_MODE_I)) *c++ = 'i'; if (get_server_operator(window->server)) *c++ = 'o'; if (get_server_flag(window->server, USER_MODE_R)) *c++ = 'r'; if (get_server_flag(window->server, USER_MODE_S)) *c++ = 's'; if (get_server_flag(window->server, USER_MODE_W)) *c++ = 'w'; if (get_server_flag(window->server, USER_MODE_Z)) *c++ = 'z'; *c++ = '\0'; if (*localbuf != '\0' && umode_format) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(lbuf), sizeof lbuf, CP(umode_format), localbuf); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); } return (ptr); } static u_char * status_chanop(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if (window->current_channel && chan_is_connected(window->current_channel, window->server) && get_channel_oper(window->current_channel, window->server) && (text = get_string_var(STATUS_CHANOP_VAR))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_hold_lines(window) Window *window; { u_char *ptr = (u_char *) 0; int num; u_char localbuf[40]; num = window->held_lines - window->held_lines%10; if (num) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(localbuf), sizeof localbuf, "%d", num); snprintf(CP(lbuf), sizeof lbuf, CP(hold_lines_format), localbuf); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_scrolled(window) Window *window; { u_char *ptr = (u_char *) 0, *text; Debug((2, "status_scrolled: lines = %d", window->scrolled_lines + window->new_scrolled_lines)); if ((window->scrolled_lines + window->new_scrolled_lines) && (text = get_string_var(STATUS_SCROLLED_VAR))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_scrolled_lines(window) Window *window; { u_char *ptr = (u_char *) 0; int num; u_char localbuf[40]; num = window->scrolled_lines + window->new_scrolled_lines; if (num) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(localbuf), sizeof localbuf, "%d", num); snprintf(CP(lbuf), sizeof lbuf, CP(hold_lines_format), localbuf); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); Debug((2, "status_scrolled_lines: lines = %d, str = '%s'", num, ptr)); return (ptr); } static u_char * status_channel(window) Window *window; { int num; u_char *s, *ptr, channel[IRCD_BUFFER_SIZE + 1]; s = window->current_channel; if (s && chan_is_connected(s, window->server)) { u_char lbuf[BIG_BUFFER_SIZE]; if (get_int_var(HIDE_PRIVATE_CHANNELS_VAR) && is_channel_mode(window->current_channel, MODE_PRIVATE | MODE_SECRET, window->server)) ptr = UP("*private*"); else ptr = window->current_channel; strmcpy(channel, ptr, IRCD_BUFFER_SIZE); if ((num = get_int_var(CHANNEL_NAME_WIDTH_VAR)) && ((int) my_strlen(channel) > num)) channel[num] = (u_char) 0; /* num = my_atoi(channel); */ ptr = (u_char *) 0; snprintf(CP(lbuf), sizeof lbuf, CP(channel_format), channel); malloc_strcpy(&ptr, lbuf); } else { ptr = (u_char *) 0; malloc_strcpy(&ptr, empty_string); } return (ptr); } static u_char * status_mail(window) Window *window; { u_char *ptr = (u_char *) 0, *number; if ((get_int_var(MAIL_VAR) && (number = check_mail()) && mail_format) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window == window->screen->current_window))) { u_char lbuf[BIG_BUFFER_SIZE]; snprintf(CP(lbuf), sizeof lbuf, CP(mail_format), number); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_insert_mode(window) Window *window; { u_char *ptr = (u_char *) 0, *text; text = empty_string; if (get_int_var(INSERT_MODE_VAR) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window->screen->current_window == window))) { if ((text = get_string_var(STATUS_INSERT_VAR)) == (u_char *) 0) text = empty_string; } malloc_strcpy(&ptr, text); return (ptr); } static u_char * status_overwrite_mode(window) Window *window; { u_char *ptr = (u_char *) 0, *text; text = empty_string; if (!get_int_var(INSERT_MODE_VAR) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window->screen->current_window == window))) { if ((text = get_string_var(STATUS_OVERWRITE_VAR)) == (u_char *) 0) text = empty_string; } malloc_strcpy(&ptr, text); return (ptr); } static u_char * status_away(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if (connected_to_server == 0) malloc_strcpy(&ptr, empty_string); else if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR) && (window->screen->current_window != window)) malloc_strcpy(&ptr, empty_string); else { if (server_list[window->server].away && (text = get_string_var(STATUS_AWAY_VAR))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); } return (ptr); } static u_char * status_user0(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if ((text = get_string_var(STATUS_USER_VAR)) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window == window->screen->current_window))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_user1(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if ((text = get_string_var(STATUS_USER1_VAR)) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window == window->screen->current_window))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_user2(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if ((text = get_string_var(STATUS_USER2_VAR)) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window == window->screen->current_window))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_user3(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if ((text = get_string_var(STATUS_USER3_VAR)) && (get_int_var(SHOW_STATUS_ALL_VAR) || (window == window->screen->current_window))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_hold(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if (window->held && (text = get_string_var(STATUS_HOLD_VAR))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_oper(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if (!connected_to_server) malloc_strcpy(&ptr, empty_string); else if (get_server_operator(window->server) && (text = get_string_var(STATUS_OPER_VAR)) && (get_int_var(SHOW_STATUS_ALL_VAR) || connected_to_server != 1 || (window->screen->current_window == window))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_voice(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if (!connected_to_server) malloc_strcpy(&ptr, empty_string); else if (has_voice(window->current_channel, get_server_nickname(window->server), window->server) && (text = get_string_var(STATUS_VOICE_VAR)) && (get_int_var(SHOW_STATUS_ALL_VAR) || connected_to_server != 1 || (window->screen->current_window == window))) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_window(window) Window *window; { u_char *ptr = (u_char *) 0, *text; if ((text = get_string_var(STATUS_WINDOW_VAR)) && (number_of_windows() > 1) && (window->screen->current_window == window)) malloc_strcpy(&ptr, text); else malloc_strcpy(&ptr, empty_string); return (ptr); } static u_char * status_refnum(window) Window *window; { u_char *ptr = (u_char *) 0; if (window->name) malloc_strcpy(&ptr, window->name); else { u_char lbuf[10]; snprintf(CP(lbuf), sizeof lbuf, "%u", window->refnum); malloc_strcpy(&ptr, lbuf); } return (ptr); } static u_char * status_version(window) Window *window; { u_char *ptr = (u_char *) 0; if ((connected_to_server == 1) && !get_int_var(SHOW_STATUS_ALL_VAR) && (window->screen->current_window != window)) malloc_strcpy(&ptr, empty_string); else { malloc_strcpy(&ptr, irc_version); } return (ptr); } static u_char * status_null_function(window) Window *window; { u_char *ptr = (u_char *) 0; malloc_strcpy(&ptr, empty_string); return (ptr); }