/* * 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-2000 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. */ #include "irc.h" IRCII_RCSID("@(#)$Id: status.c,v 1.55 2000/08/05 10:04:59 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" 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_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 void status_make_printable _((u_char *, int)); static void alarm_switch _((int)); static u_char *convert_sub_format _((u_char *, int)); /* * Maximum number of "%" expressions in a status line format. If you change * this number, you must manually change the sprintf() in make_status */ #define MAX_FUNCTIONS 33 /* 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 *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 _((void)); int do_status_alarmed; /* alarmed: This is called whenever a SIGALRM is received and the alarm is on */ /* * XXX this is evil; we should set up a flag and make irc_io() do this work * for us OUTSIDE of signal context! */ static RETSIGTYPE alarmed() { 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 it's 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; { 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') { sprintf(CP(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 { sprintf(CP(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); } } /* 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; { static u_char time_str[10]; static int min = -1, hour = -1; struct tm *time_val; char *merid; time_t t; t = time(0); time_val = localtime(&t); if (get_string_var(CLOCK_ALARM_VAR)) { if ((time_val->tm_hour == alarm_hours) && (time_val->tm_min == alarm_minutes)) alarm_switch(1); else alarm_switch(0); } if (flag == RESET_TIME || time_val->tm_min != min || time_val->tm_hour != hour) { int tmp_hour, tmp_min, server; tmp_hour = time_val->tm_hour; tmp_min = time_val->tm_min; if (get_int_var(CLOCK_24HOUR_VAR)) merid = CP(empty_string); else { if (time_val->tm_hour < 12) merid = "AM"; else merid = "PM"; if (time_val->tm_hour > 12) time_val->tm_hour -= 12; else if (time_val->tm_hour == 0) time_val->tm_hour = 12; } server = from_server; from_server = primary_server; sprintf(CP(time_str), "%02d:%02d%s", time_val->tm_hour, time_val->tm_min, merid); if (buf) { my_strncpy(buf, time_str, len - 1); buf[len - 1] = '\0'; } if (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) u_char *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 sprintf. 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 + 1]; 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, BIG_BUFFER_SIZE); *(ptr++) = '%'; if ((*ptr == c) && dont_got_it) { dont_got_it = 0; my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); } else { bletch[2] = *ptr; my_strmcat(lbuf, bletch, BIG_BUFFER_SIZE); } ptr++; } else my_strmcat(lbuf, format, BIG_BUFFER_SIZE); 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 + 1]; 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, BIG_BUFFER_SIZE); *(ptr++) = '%'; cp = &func_cnt[k]; if (*cp < MAX_FUNCTIONS) { switch (*(ptr++)) { case '%': my_strmcat(lbuf, "%", BIG_BUFFER_SIZE); break; case 'N': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_nickname; break; case '>': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_notify_windows; break; case '@': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); 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",BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_mail; break; case 'I': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_insert_mode; break; case 'O': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_overwrite_mode; break; case 'A': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_away; break; case 'V': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_version; break; case 'R': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_clock; break; case 'U': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_user0; break; case 'H': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); 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", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_hold_lines; break; case '*': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_oper; break; case 'W': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_window; break; case 'X': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_user1; break; case 'Y': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); status_func[k][(*cp)++] = status_user2; break; case 'Z': my_strmcat(lbuf, "%s", BIG_BUFFER_SIZE); 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, BIG_BUFFER_SIZE); 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 i, len, k, l, RJustifyPos = -1, RealPosition; u_char lbuf[BIG_BUFFER_SIZE + 1]; u_char *func_value[MAX_FUNCTIONS]; int 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]) { /* * XXX: note that this code below depends on the definition * of MAX_FUNCTIONS (currently 33), and the sprintf 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; sprintf(CP(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]); 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. */ RealPosition = 0; RJustifyPos = -1; for (i = 0; lbuf[i]; i++) /* formfeed is a marker for left/right border*/ if (lbuf[i] == '\f') { RJustifyPos = i; } else if (lbuf[i] != REV_TOG && lbuf[i] != UND_TOG && lbuf[i] != ALL_OFF && lbuf[i] != BOLD_TOG) { if (RealPosition == CO) { lbuf[i] = '\0'; break; } RealPosition++; } /* note that i points to the nul, RealPosition is vis.chars */ if (RJustifyPos == -1) { RJustifyPos = i; } else { /* get rid of the marker */ my_strcpy(&lbuf[RJustifyPos], &lbuf[RJustifyPos+1]); i--; } if (get_int_var(FULL_STATUS_LINE_VAR)) { int diff; u_char c; if (RJustifyPos == 0) c = ' '; else c = lbuf[RJustifyPos - 1]; diff = CO - RealPosition; for ( ; i >= RJustifyPos; i--) lbuf[i + diff] = lbuf[i]; for (i++ ; diff > 0 ; diff--, i++) lbuf[i] = c; } len = my_strlen(lbuf); lbuf[len] = ALL_OFF; lbuf[len+1] = '\0'; status_make_printable(lbuf, len); /* * Thanks to Max Bell (mbell@cie.uoregon.edu) for info about TVI * terminals and the sg terminal capability */ RealPosition = 0; if (window->status_line[k] && (SG == -1)) { for (i = 0; lbuf[i] && window->status_line[k][i]; i++) { if ((u_char) lbuf[i] != window->status_line[k][i]) break; if (lbuf[i] != REV_TOG && lbuf[i] != UND_TOG && lbuf[i] != ALL_OFF && lbuf[i] != BOLD_TOG) RealPosition++; } } else i = 0; if ((len = my_strlen(lbuf + i)) || lbuf[i] || window->status_line[k] || window->status_line[k][i]) { Screen *old_current_screen; old_current_screen = current_screen; set_current_screen(window->screen); term_move_cursor(RealPosition, window->bottom + k); /* term_move_cursor(RealPosition, window->bottom + k - window->double_status); */ output_line(lbuf, NULL, i); cursor_in_display(); if (term_clear_to_eol()) term_space_erase(len); malloc_strcpy(&window->status_line[k], lbuf); set_current_screen(old_current_screen); } } } out: cursor_to_input(); } 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)) sprintf(CP(lbuf), CP(server_format), name); else { *rest = '\0'; sprintf(CP(lbuf), CP(server_format), name); *rest = '.'; } } else sprintf(CP(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]; sprintf(CP(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]; sprintf(CP(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'; while ((window = traverse_all_windows(&flag)) != NULL) { if (window->miscflags & WINDOW_NOTIFIED) { if (!doneone) { doneone++; sprintf(CP(refnum), "%d", window->refnum); } else sprintf(CP(refnum), ",%d", window->refnum); my_strmcat(buf2, refnum, 81); } } } if (doneone && notify_format) { u_char lbuf[BIG_BUFFER_SIZE]; sprintf(CP(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]; sprintf(CP(lbuf), CP(clock_format), update_clock(time_str, 16, 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]; sprintf(CP(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'; *c++ = '\0'; if (*localbuf != '\0' && umode_format) { u_char lbuf[BIG_BUFFER_SIZE]; sprintf(CP(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]; sprintf(CP(localbuf), "%d", num); sprintf(CP(lbuf), CP(hold_lines_format), localbuf); malloc_strcpy(&ptr, lbuf); } else malloc_strcpy(&ptr, empty_string); 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; sprintf(CP(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]; sprintf(CP(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_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]; sprintf(CP(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); } /* * pass an already allocated char array with n bits, and this * gets rid of nasty unprintables. */ static void status_make_printable(str, n) u_char *str; int n; { u_char *s; size_t pos; u_char lbuf[BIG_BUFFER_SIZE]; if (!str || !*str) return; bzero(lbuf, BIG_BUFFER_SIZE); for (pos = 0, s = str; s && pos < BIG_BUFFER_SIZE && pos < n; s++) { if (translation) *s = transToClient[*s]; if (*s < 32) { switch(*s) { case UND_TOG: case ALL_OFF: case REV_TOG: case BOLD_TOG: lbuf[pos++] = *s; break; default: lbuf[pos++] = REV_TOG; lbuf[pos++] = (*s & 0x7f) | 0x40; lbuf[pos++] = REV_TOG; break; } } else if ((u_char) 0x7f == *s) { lbuf[pos++] = REV_TOG; lbuf[pos++] = '?'; lbuf[pos++] = REV_TOG; } else lbuf[pos++] = *s; } lbuf[pos] = '\0'; my_strncpy(str, lbuf, pos); } .