void setup_ov_mode(int on, int hide, int log) { #ifdef WANT_OPERVIEW char *default_oper = "wsckf"; Window *win = NULL; if (on) { if ((win = get_window_by_name("oper_view"))) { if (win->log) do_log(0, NULL, &win->log_fp); delete_window(win); update_all_windows(); set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0); cursor_to_input(); } send_to_server("MODE %s -%s%s", get_server_nickname(from_server), get_string_var(OPER_MODES_VAR)?get_string_var(OPER_MODES_VAR):default_oper, send_umode); } else { Window *tmp = NULL; win = current_window; if ((tmp = new_window(current_window->screen))) { malloc_strcpy(&tmp->name, "oper_view"); tmp->double_status = 0; if (hide) hide_window(tmp); else resize_window(1, tmp, -5); tmp->window_level = LOG_WALLOP|LOG_OPNOTE|LOG_SNOTE; tmp->absolute_size = 1; tmp->skip = 1; set_wset_string_var(tmp->wset, STATUS_FORMAT1_WSET, fget_string_var(FORMAT_OV_FSET)); build_status(tmp, NULL, 0); update_all_windows(); set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0); cursor_to_input(); send_to_server("MODE %s +%s", get_server_nickname(from_server), get_string_var(OPER_MODES_VAR)?get_string_var(OPER_MODES_VAR):default_oper); set_screens_current_window(win->screen, win); tmp->mangler = operlog_line_mangler; if (log != -1) { tmp->log = log; if (tmp->log) do_log(log, "~/.BitchX/operview.log", &tmp->log_fp); } } } #endif }
/* * input_beginning_of_line: moves the input cursor to the first character in * the input buffer */ void new_input_beginning_of_line(char unused, char *not_used) { cursor_to_input(); THIS_POS = MIN_POS; update_input(UPDATE_JUST_CURSOR); extended_handled = 1; }
/* input_backspace: does a backspace in the input buffer */ void input_backspace(char key, char *blah) { cursor_to_input(); if (THIS_POS > MIN_POS) { char *ptr = NULL; int pos; malloc_strcpy(&ptr, &(THIS_CHAR)); strcpy(&(PREV_CHAR), ptr); new_free(&ptr); THIS_POS--; term_cursor_left(); if (THIS_CHAR) { if (term_delete()) update_input(UPDATE_FROM_CURSOR); { pos = str_start + term_cols - 1; pos += count_ansi(&(current_screen->input_buffer[str_start]), zone); if (pos < strlen(INPUT_BUFFER)) { term_move_cursor(term_cols - 1, input_line); term_putchar(INPUT_BUFFER[pos]); } update_input(UPDATE_JUST_CURSOR); } } else { term_putchar(' '); term_cursor_left(); update_input(NO_UPDATE); } } in_completion = STATE_NORMAL; *new_nick = 0; }
/* input_delete_character: deletes a character from the input line */ void input_delete_character(char unused, char *not_used) { cursor_to_input(); if (THIS_CHAR) { char *ptr = NULL; int pos; malloc_strcpy(&ptr, &(NEXT_CHAR)); strcpy(&(THIS_CHAR), ptr); new_free(&ptr); if (term_delete()) update_input(UPDATE_FROM_CURSOR); else { pos = str_start + term_cols - 1; pos += count_ansi(&(current_screen->input_buffer[str_start]), zone); if (pos < strlen(INPUT_BUFFER)) { term_move_cursor(term_cols - 1, input_line); term_putchar(INPUT_BUFFER[pos]); term_move_cursor(cursor, input_line); } update_input(NO_UPDATE); } } in_completion = STATE_NORMAL; }
/* * input_transpose_characters: swaps the positions of the two characters * before the cursor position */ void input_transpose_characters(char unused, char *not_used) { cursor_to_input(); if (current_screen->buffer_pos > MIN_POS) { u_char c1[3] = { 0 }; int pos, end_of_line = 0; if (THIS_CHAR) pos = THIS_POS; else if (strlen(get_input()) > MIN_POS + 2) { pos = THIS_CHAR - 1; end_of_line = 1; } else return; c1[0] = INPUT_BUFFER[pos]; c1[1] = INPUT_BUFFER[pos] = INPUT_BUFFER[pos - 1]; INPUT_BUFFER[pos - 1] = c1[0]; term_cursor_left(); if (end_of_line) term_cursor_left(); term_putchar(c1[0]); term_putchar(c1[1]); if (!end_of_line) term_cursor_left(); update_input(NO_UPDATE); } }
/* input_clear_to_eol: erases from the cursor to the end of the input buffer */ void input_clear_to_eol(char unused, char *not_used) { cursor_to_input(); malloc_strcpy(&cut_buffer, &(THIS_CHAR)); THIS_CHAR = 0; term_clear_to_eol(); update_input(NO_UPDATE); }
/* nap_exit: cleans up and leaves */ void nap_exit (int really_quit, char *reason, char *format, ...) { if (dead == 1) { kill_all_threads(); exit(1); } else if (dead == 2) { kill_all_threads(); _exit(1); } else if (dead == 3) { kill_all_threads(); kill(getpid(), SIGKILL); } dead++; set_lastlog_size(NULL, NULL, 0); set_history_size(NULL, NULL, 0); if (really_quit) { kill_all_threads(); say("Signon time : %s", my_ctime(start_time)); say("Signoff time : %s", my_ctime(now)); say("Total uptime : %s", convert_time(now - start_time)); } do_hook(EXIT_LIST, "%s", reason ? reason : empty_string); if (reason) say("%s", reason); close_all_servers(); close_all_sockets(); if (term_initialized) { cursor_to_input(); term_cr(); term_clear_to_eol(); term_reset(); } remove_bindings(); clear_variables(); delete_all_windows(); destroy_call_stack(); write_unfinished_list(); debug_cleanup(); fprintf(stdout, "\r"); fflush(stdout); if (really_quit) exit(0); kill_all_threads(); my_signal(SIGABRT, SIG_DFL, 0); kill(getpid(), SIGABRT); kill(getpid(), SIGQUIT); exit(1); }
/* * input_clear_line: clears entire input line */ void input_clear_line(char unused, char *not_used) { cursor_to_input(); malloc_strcpy(&cut_buffer, INPUT_BUFFER + MIN_POS); MIN_CHAR = (char) 0; THIS_POS = MIN_POS; term_move_cursor(current_screen->buffer_min_pos - count_ansi(current_screen->input_buffer, zone), input_line); term_clear_to_eol(); update_input(NO_UPDATE); }
/* input_backward_word: move the cursor left on word in the input line */ void input_backward_word(char unused, char *not_used) { cursor_to_input(); while ((THIS_POS > MIN_POS) && (my_isspace(PREV_CHAR) || ispunct(PREV_CHAR))) THIS_POS--; while ((THIS_POS > MIN_POS) && !(ispunct(PREV_CHAR) || my_isspace(PREV_CHAR))) THIS_POS--; update_input(UPDATE_JUST_CURSOR); }
/* * input_forward_word: move the input cursor forward one word in the input * line */ void input_forward_word(char unused, char *not_used) { cursor_to_input(); while ((my_isspace(THIS_CHAR) || ispunct(THIS_CHAR)) && (THIS_CHAR)) THIS_POS++; while (!(ispunct(THIS_CHAR) || my_isspace(THIS_CHAR)) && (THIS_CHAR)) THIS_POS++; update_input(UPDATE_JUST_CURSOR); }
void debug_window(Window *win, char *value, int unused) { Window *old_win = win; char *nv = NULL; internal_debug = parse_debug(value, internal_debug, &nv); set_string_var(DEBUG_VAR, nv); if (internal_debug) { Window *tmp = NULL; if (!get_window_by_name("debug") && (tmp = new_window(win->screen))) { malloc_strcpy(&tmp->name, "debug"); tmp->double_status = 0; hide_window(tmp); tmp->window_level = LOG_DEBUG; tmp->absolute_size = 1; tmp->skip = 1; debugging_window = tmp; set_wset_string_var(tmp->wset, STATUS_FORMAT1_WSET, DEFAULT_FORMAT_DEBUG_FSET); build_status(tmp, NULL, 0); update_all_windows(); set_input_prompt(win, get_string_var(INPUT_PROMPT_VAR), 0); cursor_to_input(); set_screens_current_window(old_win->screen, old_win); } } else { if ((old_win = get_window_by_name("debug"))) { delete_window(old_win); debugging_window = NULL; update_all_windows(); set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0); cursor_to_input(); } } new_free(&nv); }
void reset_clock (const void *stuff) { if (x_debug & DEBUG_BROKEN_CLOCK) reset_broken_clock(); else if (get_int_var(METRIC_TIME_VAR)) reset_metric_clock(); else reset_standard_clock(); update_all_status(); cursor_to_input(); }
/* * input_clear_to_bol: clears from the cursor to the beginning of the input * buffer */ void input_clear_to_bol(char unused, char *not_used) { char *ptr = NULL; cursor_to_input(); malloc_strcpy(&cut_buffer, &(MIN_CHAR)); cut_buffer[THIS_POS - MIN_POS] = (char) 0; malloc_strcpy(&ptr, &(THIS_CHAR)); MIN_CHAR = (char) 0; ADD_TO_INPUT(ptr); new_free(&ptr); THIS_POS = MIN_POS; term_move_cursor(MIN_POS, input_line); term_clear_to_eol(); update_input(UPDATE_FROM_CURSOR); }
/* input_move_cursor: moves the cursor left or right... got it? */ void input_move_cursor(int dir) { cursor_to_input(); if (dir) { if (THIS_CHAR) { THIS_POS++; term_cursor_right(); } } else { if (THIS_POS > MIN_POS) { THIS_POS--; term_cursor_left(); } } update_input(NO_UPDATE); }
/* * input_delete_previous_word: deletes from the cursor backwards to the next * space character. */ void input_delete_previous_word(char unused, char *not_used) { int old_pos; char c; cursor_to_input(); old_pos = THIS_POS; while ((THIS_POS > MIN_POS) && (my_isspace(PREV_CHAR) || ispunct(PREV_CHAR))) THIS_POS--; while ((THIS_POS > MIN_POS) && !(ispunct(PREV_CHAR) || my_isspace(PREV_CHAR))) THIS_POS--; c = INPUT_BUFFER[old_pos]; INPUT_BUFFER[old_pos] = (char) 0; malloc_strcpy(&cut_buffer, &THIS_CHAR); INPUT_BUFFER[old_pos] = c; strcpy(&(THIS_CHAR), &(INPUT_BUFFER[old_pos])); update_input(UPDATE_FROM_CURSOR); }
void input_delete_to_previous_space(char key, char *blah) { int old_pos; char c; cursor_to_input(); old_pos = THIS_POS; c = THIS_CHAR; while (!my_isspace(THIS_CHAR) && THIS_POS >= MIN_POS) THIS_POS--; if (THIS_POS < old_pos) { strcpy(&(NEXT_CHAR), &(INPUT_BUFFER[old_pos])); THIS_POS++; } update_input(UPDATE_FROM_CURSOR); }
/* * input_add_character: adds the character c to the input buffer, repecting * the current overwrite/insert mode status, etc */ void input_add_character(char c, char *unused) { int display_flag = NO_UPDATE; cursor_to_input(); if (THIS_POS < INPUT_BUFFER_SIZE) { if (get_int_var(INSERT_MODE_VAR)) { if (THIS_CHAR) { char *ptr = NULL; ptr = strdup(&(THIS_CHAR)); THIS_CHAR = c; NEXT_CHAR = 0; ADD_TO_INPUT(ptr); free(ptr); if (term_insert(c)) { term_putchar(c); if (NEXT_CHAR) display_flag = UPDATE_FROM_CURSOR; else display_flag = NO_UPDATE; } } else { THIS_CHAR = c; NEXT_CHAR = 0; term_putchar(c); } } else { if (THIS_CHAR == 0) NEXT_CHAR = 0; THIS_CHAR = c; term_putchar(c); } THIS_POS++; update_input(display_flag); } if (in_completion == STATE_COMPLETE && c == ' ' && input_lastmsg) { new_free(&input_lastmsg); *new_nick = 0; in_completion = STATE_NORMAL; } }
/* * input_delete_next_word: deletes from the cursor to the end of the next * word */ void input_delete_next_word(char unused, char *not_used) { int pos; char *ptr = NULL, c; cursor_to_input(); pos = THIS_POS; while ((my_isspace(INPUT_BUFFER[pos]) || ispunct(INPUT_BUFFER[pos])) && INPUT_BUFFER[pos]) pos++; while (!(ispunct(INPUT_BUFFER[pos]) || my_isspace(INPUT_BUFFER[pos])) && INPUT_BUFFER[pos]) pos++; c = INPUT_BUFFER[pos]; INPUT_BUFFER[pos] = (char) 0; malloc_strcpy(&cut_buffer, &(THIS_CHAR)); INPUT_BUFFER[pos] = c; malloc_strcpy(&ptr, &(INPUT_BUFFER[pos])); strcpy(&(THIS_CHAR), ptr); new_free(&ptr); update_input(UPDATE_FROM_CURSOR); }
void set_mail (const void *stuff) { int value = *(const int *)stuff; if (value < 0 || value > 3) { say("/SET MAIL must be 0, 1, 2, or 3"); set_int_var(MAIL_VAR, 0); return; } else if (value == 0) checkmail->deinit(); else { if (!checkmail->init()) return; } update_system_timer(mail_timeref); update_all_status(); cursor_to_input(); }
void mail_systimer (void) { int x; switch ((x = get_int_var(MAIL_VAR))) { case 1: checkmail->level1(); break; case 2: checkmail->level2(); break; case 3: checkmail->level3(); break; default: panic("mail_systimer called with set mail %d", x); } update_all_status(); cursor_to_input(); return; }
/* * update_input: does varying amount of updating on the input line depending * upon the position of the cursor and the update flag. If the cursor has * move toward one of the edge boundaries on the screen, update_cursor() * flips the input line to the next (previous) line of text. The update flag * may be: * * NO_UPDATE - only do the above bounds checking. * * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should * be. * * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from * the cursor to the right edge of the screen is current (by redrawing it). * * UPDATE_ALL - redraws the entire line */ void update_input (int update) { int old_zone; char *ptr, *ptr_free; int len, free_it = 0, max; char *prompt; int do_echo = 1; Screen *os = last_input_screen; Screen *ns; Window *saved_current_window = current_window; /* * No input line in dumb or bg mode. */ if (dumb_mode || !foreground) return; for (ns = screen_list; ns; ns = ns->next) { if (!ns->alive) continue; /* It's dead, Jim! */ last_input_screen = ns; current_window = ns->current_window; /* * Make sure the client thinks the cursor is on the input line. */ cursor_to_input(); /* * See if we're in a add_wait_prompt() call. If we are, grab that * current prompt, otherwise use the default input prompt. */ if (last_input_screen->promptlist) prompt = last_input_screen->promptlist->prompt; else prompt = input_prompt; /* * * GET THE INPUT PROMPT * */ /* * If we have a prompt, and we're supposed to update the input * prompt, then we do need to expand the prompt. */ if (prompt && update != NO_UPDATE) { int af; /* * If the current window is query'ing an exec'd process, * then we just get the current prompt for that process. * Note that it is not malloced. */ if (is_valid_process(get_target_by_refnum(0)) != -1) ptr = get_prompt_by_refnum(0); /* * Otherwise, we just expand the prompt as normal. */ else { ptr = expand_alias(prompt, empty_string, &af, NULL); free_it = 1; } /* * If we're in an add_wait_prompt(), we see whether or not * this is an "invisible" prompt. If it is, we turn off the * echo so what the user types doesnt show up. */ if (last_input_screen->promptlist) term_echo(last_input_screen->promptlist->echo); /* * Mangle out any ansi chars or so forth. */ ptr_free = ptr; ptr = normalize_string(ptr, 0); /* This should be ok */ if (free_it) new_free(&ptr_free); free_it = 1; /* * If the prompt has changed, or if there is no prompt... */ if ( (ptr && !INPUT_PROMPT) || (!ptr && INPUT_PROMPT) || strcmp(ptr, INPUT_PROMPT) ) { if (last_input_screen->input_prompt_malloc) new_free(&INPUT_PROMPT); last_input_screen->input_prompt_malloc = free_it; INPUT_PROMPT = ptr; INPUT_PROMPT_LEN = output_with_count(INPUT_PROMPT, 0, 0); update = UPDATE_ALL; } /* * Prompt didnt change, so clean up our mess */ else { if (free_it) new_free(&ptr); } } /* * * HAS THE SCREEN CHANGED SIZE SINCE THE LAST TIME? * */ /* * If the screen has resized, then we need to re-compute the * side-to-side scrolling effect. */ if ((last_input_screen->li != last_input_screen->old_li) || (last_input_screen->co != last_input_screen->old_co)) { /* * The input line is always the bottom line */ INPUT_LINE = last_input_screen->li - 1; /* * The "zone" is the range in which when you type, the * input line does not scroll. It is WIDTH chars in from * either side of the display. */ ZONE = last_input_screen->co - (WIDTH * 2); if (ZONE < 10) ZONE = 10; /* Take that! */ START_ZONE = WIDTH; END_ZONE = last_input_screen->co - WIDTH; last_input_screen->old_co = last_input_screen->co; last_input_screen->old_li = last_input_screen->li; } /* * About zones: * The input line is divided into "zones". A "zone" is set above, * and is the width of the screen minus 20 (by default). The input * line, as displayed, is therefore composed of the current "zone", * plus 10 characters from the previous zone, plus 10 characters * from the next zone. When the cursor moves to an adjacent zone, * (by going into column 9 from the right or left of the edge), the * input line is redrawn. There is one catch. The first "zone" * includes the first ten characters of the input line. */ old_zone = START_ZONE; /* * The BEGINNING of the current "zone" is a calculated value: * The number of characters since the origin of the input buffer * is the number of printable chars in the input prompt plus the * current position in the input buffer. We subtract from that * the WIDTH delta to take off the first delta, which doesnt * count towards the width of the zone. Then we divide that by * the size of the zone, to get an integer, then we multiply it * back. This gives us the first character on the screen. We * add WIDTH to the result in order to get the start of the zone * itself. * The END of the current "zone" is just the beginning plus the width. * If we have moved to an different "zone" since last time, we want to * completely redraw the input line. */ START_ZONE = ((INPUT_PROMPT_LEN + THIS_POS - WIDTH) / ZONE) * ZONE + WIDTH; END_ZONE = START_ZONE + ZONE; if (old_zone != START_ZONE) update = UPDATE_ALL; /* * Now that we know where the "zone" is in the input buffer, we can * easily calculate where where we want to start displaying stuff * from the INPUT_BUFFER. If we're in the first "zone", then we will * output from the beginning of the buffer. If we're not in the first * "zone", then we will begin to output from 10 characters to the * left of the zone, after adjusting for the length of the prompt. */ if (START_ZONE == WIDTH) INPUT_ONSCREEN = 0; else { if ((INPUT_ONSCREEN = START_ZONE - WIDTH - INPUT_PROMPT_LEN) < 0) INPUT_ONSCREEN = 0; } /* * And the cursor is simply how many characters away THIS_POS is * from the first column on the screen. */ if (INPUT_ONSCREEN == 0) INPUT_CURSOR = INPUT_PROMPT_LEN + THIS_POS; else INPUT_CURSOR = THIS_POS - INPUT_ONSCREEN; /* * If the cursor moved, or if we're supposed to do a full update, * then redraw the entire input line. */ if (update == UPDATE_ALL) { /* * Move the cursor to the start of the input line */ term_move_cursor(0, INPUT_LINE); /* * If the input line is NOT empty, and we're starting the * display at the beginning of the input buffer, then we * output the prompt first. */ if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT) { /* * Forcibly turn on echo. */ do_echo = term_echo(1); /* * Crop back the input prompt so it does not extend * past the end of the zone. */ if (INPUT_PROMPT_LEN > (last_input_screen->co - WIDTH)) INPUT_PROMPT_LEN = last_input_screen->co - WIDTH - 1; /* * Output the prompt. */ output_with_count(INPUT_PROMPT, 0, 1); /* * Turn the echo back to what it was before, * and output the rest of the input buffer. */ term_echo(do_echo); safe_puts(INPUT_BUFFER, last_input_screen->co - INPUT_PROMPT_LEN, do_echo); } /* * Otherwise we just output whatever we have. */ else if (do_echo) safe_puts(&(INPUT_VISIBLE), last_input_screen->co, do_echo); /* * Clear the rest of the input line and reset the cursor * to the current input position. */ term_clear_to_eol(); term_move_cursor(INPUT_CURSOR, INPUT_LINE); cursor_not_in_display(last_input_screen); } /* * If we're just supposed to refresh whats to the right of the * current logical position... */ else if (update == UPDATE_FROM_CURSOR) { /* * Move the cursor to where its supposed to be, * Figure out how much we can output from here, * and then output it. */ term_move_cursor(INPUT_CURSOR, INPUT_LINE); max = last_input_screen->co - (THIS_POS - INPUT_ONSCREEN); if (INPUT_ONSCREEN == 0 && INPUT_PROMPT && *INPUT_PROMPT) max -= INPUT_PROMPT_LEN; if ((len = strlen(&(THIS_CHAR))) > max) len = max; safe_puts(&(THIS_CHAR), len, do_echo); term_clear_to_eol(); term_move_cursor(INPUT_CURSOR, INPUT_LINE); cursor_not_in_display(last_input_screen); } /* * If we're just supposed to move the cursor back to the input * line, then go ahead and do that. */ else if (update == UPDATE_JUST_CURSOR) { term_move_cursor(INPUT_CURSOR, INPUT_LINE); cursor_not_in_display(last_input_screen); } /* * Turn the terminal echo back on, and flush all of the output * we may have done here. */ term_echo(1); term_flush(); } last_input_screen = os; current_window = saved_current_window; }
void io (const char *what) { static int first_time = 1; long clock_timeout = 0, timer_timeout = 0, real_timeout = 0; static struct timeval my_now, my_timer, *time_ptr = &my_timer; int hold_over, rc; fd_set rd, wd; get_time(&my_now); now = my_now.tv_sec; /* CHECK FOR CPU SAVER MODE */ if (!cpu_saver && get_int_var(CPU_SAVER_AFTER_VAR)) if (now - idle_time > get_int_var(CPU_SAVER_AFTER_VAR) * 60) cpu_saver_on(0, NULL); rd = readables; wd = writables; FD_ZERO(&wd); FD_ZERO(&rd); set_screens(&rd, &wd); set_server_bits(&rd, &wd); set_process_bits(&rd); set_socket_read(&rd, &wd); icmp_sockets(&rd, &wd); #if defined(WANT_THREAD) #ifdef WANT_NSLOOKUP set_dns_output_fd(&rd); #endif #ifdef WANT_PTEST set_ptest_output_fd(&rd); #endif #ifdef WANT_MP3PLAYER set_mp3_output_fd(&rd); #endif # if defined(GTK) if (tgtk_okay()) tgtk_set_output_fd(&rd); # endif #endif clock_timeout = (timeout_select - (my_now.tv_sec % timeout_select)) * 1000; if (cpu_saver && get_int_var(CPU_SAVER_EVERY_VAR)) clock_timeout += (get_int_var(CPU_SAVER_EVERY_VAR) - 1) * 60000; timer_timeout = TimerTimeout(); if ((hold_over = unhold_windows())) real_timeout = 0; else if (timer_timeout <= clock_timeout) real_timeout = timer_timeout; else real_timeout = clock_timeout; if (real_timeout == -1) time_ptr = NULL; else { time_ptr->tv_sec = real_timeout / 1000; time_ptr->tv_usec = ((real_timeout % 1000) * 1000); } /* GO AHEAD AND WAIT FOR SOME DATA TO COME IN */ switch ((rc = new_select(&rd, &wd, time_ptr))) { case 0: break; case -1: { /* if we just got a sigint */ first_time = 0; if (cntl_c_hit) edit_char('\003'); else if (errno && errno != EINTR) { int ii = 0; fd_set rd1, wd1; char ii_buff_r[500]; char ii_buff_w[500]; int ii_r[FD_SETSIZE]; int ii_w[FD_SETSIZE]; yell("Select failed with [%d:%s]", errno, strerror(errno)); /* Reseed fd_sets so we can dig further */ yell("Packing fd_sets... Dump of fd's set in fd_set"); ii_buff_r[0] = '\0'; ii_buff_w[0] = '\0'; for (ii = 0; ii < FD_SETSIZE; ii++) { ii_r[ii] = 0; ii_w[ii] = 0; } FD_ZERO(&wd1); FD_ZERO(&rd1); set_screens(&rd1, &wd1); set_server_bits(&rd1, &wd1); set_process_bits(&rd1); set_socket_read(&rd1, &wd1); icmp_sockets(&rd1, &wd1); #if defined(WANT_THREAD) #ifdef WANT_NSLOOKUP set_dns_output_fd(&rd1); #endif #ifdef WANT_PTEST set_ptest_output_fd(&rd1); #endif #ifdef WANT_MP3PLAYER set_mp3_output_fd(&rd1); #endif # if defined(GTK) if (tgtk_okay()) tgtk_set_output_fd(&rd1); # endif #endif for (ii = 0; ii <= global_max_fd; ii++) { fd_set rblah, wblah; memcpy(&rblah, &rd1, sizeof(fd_set)); FD_SET(ii, &rblah); if (memcmp(&rblah, &rd1, sizeof(fd_set)) == 0) { char blahblah[20]; sprintf(blahblah, "%d ", ii); strcat(ii_buff_r, blahblah); ii_r[ii] = 1; } memcpy(&wblah, &wd1, sizeof(fd_set)); FD_SET(ii, &wblah); if (memcmp(&wblah, &wd1, sizeof(fd_set)) == 0) { char blahblah[20]; yell("blah"); sprintf(blahblah, "%d ", ii); strcat(ii_buff_w, blahblah); ii_w[ii] = 1; } } yell("Read fd's in set: %s", (ii_buff_r[0] == '\0') ? "<NONE>" : ii_buff_r); for (ii = 0; ii <= global_max_fd; ii++) { if (ii_r[ii] == 1) { struct stat st; if (fstat(ii, &st) == -1) { yell("READ FD %d is causing the select failure!", ii); } else { if (S_ISSOCK(st.st_mode)) yell("READ FD %d is a socket!", ii); else if (S_ISREG(st.st_mode)) yell("READ FD %d is a regular file!", ii); else if (S_ISFIFO(st.st_mode)) yell("READ FD %d is a FIFO!", ii); else ; } } } yell("Write fd's in set: %s", (ii_buff_w[0] == '\0') ? "<NONE>" : ii_buff_w); for (ii = 0; ii <= global_max_fd; ii++) { if (ii_w[ii] == 1) { struct stat st; if (fstat(ii, &st) == -1) { yell("WRITE FD %d is causing the select failure!", ii); } else { if (S_ISSOCK(st.st_mode)) yell("WRITE FD %d is a socket!", ii); else if (S_ISREG(st.st_mode)) yell("WRITE FD %d is a regular file!", ii); else if (S_ISFIFO(st.st_mode)) yell("WRITE FD %d is a FIFO!", ii); else ; } } } sleep(10); } else { #if 0 yell("errno 0 rc = -1, maybe it'll go away"); sleep(10); #endif } break; } /* we got something on one of the descriptors */ default: { cntl_c_hit = 0; now = time(NULL); make_window_current(NULL); do_screens(&rd); check_icmpresult(&rd, &wd); #if defined(WANT_THREAD) #ifdef WANT_NSLOOKUP dns_check(&rd); #endif #ifdef WANT_PTEST ptest_check(&rd); #endif #ifdef WANT_MP3PLAYER mp3_check(&rd); #endif # if defined(GTK) if (tgtk_okay()) tgtk_check(&rd); # endif #endif do_server(&rd, &wd); do_processes(&rd); scan_sockets(&rd, &wd); clean_sockets(); break; } } now = time(NULL); ExecuteTimers(); get_child_exit(-1); if (update_refresh) { update_refresh = 0; refresh_screen(0, NULL); } if (!hold_over) cursor_to_input(); if (update_clock(RESET_TIME)) { if (get_int_var(CLOCK_VAR)) { update_all_status(current_window, NULL, 0); cursor_to_input(); } clean_queue(get_int_var(TRANSFER_TIMEOUT_VAR)); /* timeout if send time is greater than 5 minutes */ } /* (set in term.c) -- we should redraw the screen here */ if (need_redraw) refresh_screen(0, NULL); #ifdef WANT_THREAD if (scan_done) scan_is_done(); #endif alloca(0); return; }
void set_clock (const void *stuff) { update_system_timer(clock_timeref); update_all_status(); cursor_to_input(); }
/* * This just sucked beyond words. I was always planning on rewriting this, * but the crecendo of complaints with regards to this just got to be too * irritating, so i fixed it early. */ int make_status (Window *window, int must_redraw) { int status_line; u_char buffer [BIG_BUFFER_SIZE + 1]; u_char lhs_buffer [BIG_BUFFER_SIZE + 1]; u_char rhs_buffer [BIG_BUFFER_SIZE + 1]; Char *func_value [MAX_FUNCTIONS]; u_char *ptr; size_t save_size; /* We do NOT redraw status bars for hidden windows */ if (!window->screen || !status_updates_permitted) return -1; for (status_line = 0; status_line < window->status.double_status + 1; status_line++) { u_char lhs_fillchar[6], rhs_fillchar[6], *fillchar = lhs_fillchar, *lhp = lhs_buffer, *rhp = rhs_buffer, *cp, *start_rhs = 0, *str; int in_rhs = 0, pr_lhs = 0, pr_rhs = 0, line, *prc = &pr_lhs, i; fillchar[0] = fillchar[1] = 0; /* * If status line gets to one, then that means that * window->double_status is not zero. That means that * the status line we're working on is STATUS2. */ if (status_line) line = 2; /* * If status_line is zero, and window->double_status is * not zero (double status line is on) then we're working * on STATUS1. */ else if (window->status.double_status) line = 1; /* * So status_line is zero and window->double_status is zero. * So we're working on STATUS (0). */ else line = 0; /* * Sanity check: If the status format doesnt exist, dont do * anything for it. */ if (!window->status.line[line].format) continue; /* * Run each of the status-generating functions from the the * status list. Note that the retval of the functions is no * longer malloc()ed. This saves 40-some odd malloc/free sets * each time the status bar is updated, which is non-trivial. */ for (i = 0; i < MAX_FUNCTIONS; i++) { if (window->screen == NULL) return -1; if (window->status.line[line].func[i] == NULL) panic("status callback null. Window [%d], line [%d], function [%d]", window->refnum, line, i); func_value[i] = window->status.line[line].func[i] (window, window->status.line[line].map[i], window->status.line[line].key[i]); } /* * If the REVERSE_STATUS_LINE var is on, then put a reverse * character in the first position (itll get translated to * the tcap code in the output code. */ if (get_int_var(REVERSE_STATUS_LINE_VAR)) *buffer = REV_TOG , str = buffer + 1; else str = buffer; /* * Now press the status line into "buffer". The magic about * setting status_format is handled elsewhere. */ snprintf(str, BIG_BUFFER_SIZE - 1, window->status.line[line].format, 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]); /* * If the user wants us to, pass the status bar through the * expander to pick any variables/function calls. * This is horribly expensive, but what do i care if you * want to waste cpu cycles? ;-) */ if (get_int_var(STATUS_DOES_EXPANDOS_VAR)) { int af = 0; int old_fs = from_server; Window *old = current_window; int owd = window_display; current_window = window; from_server = current_window->server; window_display = 0; str = expand_alias(buffer, empty_string, &af, NULL); window_display = owd; from_server = old_fs; current_window = old; strlcpy(buffer, str, sizeof buffer); new_free(&str); } /* * This converts away any ansi codes in the status line * in accordance with the currenet settings. This leaves us * with nothing but logical characters, which are then easy * to count. :-) */ str = normalize_string(buffer, 3); /* * Count out the characters. * Walk the entire string, looking for nonprintable * characters. We count all the printable characters * on both sides of the %> tag. */ ptr = str; cp = lhp; lhs_buffer[0] = rhs_buffer[0] = 0; while (*ptr) { /* * The FIRST such %> tag is used. * Using multiple %>s is bogus. */ if (*ptr == '\f' && start_rhs == NULL) { ptr++; start_rhs = ptr; fillchar = rhs_fillchar; in_rhs = 1; *cp = 0; cp = rhp; prc = &pr_rhs; } /* * Skip over attribute changes, not useful. */ else if (*ptr == '\006') { /* Copy the next 5 values */ *cp++ = *ptr++; *cp++ = *ptr++; *cp++ = *ptr++; *cp++ = *ptr++; *cp++ = *ptr++; } /* * XXXXX This is a bletcherous hack. * If i knew what was good for me id not do this. */ else if (*ptr == 9) /* TAB */ { fillchar[0] = ' '; fillchar[1] = 0; do *cp++ = ' '; while (++(*prc) % 8); ptr++; } /* * So it is a printable character. */ else { *prc += 1; fillchar[0] = *cp++ = *ptr++; fillchar[1] = 0; } /* * Dont allow more than CO printable characters */ if (pr_lhs + pr_rhs >= window->screen->co) { *cp = 0; break; } } *cp = 0; /* What will we be filling with? */ if (get_int_var(STATUS_NO_REPEAT_VAR)) { lhs_fillchar[0] = ' '; lhs_fillchar[1] = 0; rhs_fillchar[0] = ' '; rhs_fillchar[1] = 0; } /* * Now if we have a rhs, then we have to adjust it. */ if (start_rhs) { int numf = 0; numf = window->screen->co - pr_lhs - pr_rhs -1; while (numf-- >= 0) strlcat(lhs_buffer, lhs_fillchar, sizeof lhs_buffer); } /* * No rhs? If the user wants us to pad it out, do so. */ else if (get_int_var(FULL_STATUS_LINE_VAR)) { int chars = window->screen->co - pr_lhs - 1; while (chars-- >= 0) strlcat(lhs_buffer, lhs_fillchar, sizeof lhs_buffer); } save_size = strlen(all_off()); strlcpy(buffer, lhs_buffer, sizeof buffer - save_size); strlcat(buffer, rhs_buffer, sizeof buffer - save_size); strlcat(buffer, all_off(), sizeof buffer); new_free(&str); /* * Ends up that BitchX always throws this hook and * people seem to like having this thrown in standard * mode, so i'll go along with that. */ do_hook(STATUS_UPDATE_LIST, "%d %d %s", window->refnum, status_line, buffer); if (dumb_mode || !foreground) continue; /* * Update the status line on the screen. * First check to see if it has changed * Remember this is only done in full screen mode. */ if (must_redraw || !window->status.line[status_line].result || strcmp(buffer, window->status.line[status_line].result)) { /* * Roll the new back onto the old */ malloc_strcpy(&window->status.line[status_line].result, buffer); /* * Output the status line to the screen */ output_screen = window->screen; term_move_cursor(0, window->bottom + status_line); output_with_count(buffer, 1, 1); cursor_in_display(window); } } cursor_to_input(); return 0; }
/* irc_exit: cleans up and leaves */ void BX_irc_exit (int really_quit, char *reason, char *format, ...) { char buffer[BIG_BUFFER_SIZE]; logger(current_window, NULL, 0); if (get_int_var(MSGLOG_VAR)) log_toggle(0, NULL); if (format) { va_list arglist; va_start(arglist, format); vsprintf(buffer, format, arglist); va_end(arglist); } else sprintf(buffer, "%s -- just do it.",irc_version); if (really_quit) { put_it("%s", convert_output_format("$G Signon time : $0-", "%s", my_ctime(start_time))); put_it("%s", convert_output_format("$G Signoff time : $0-", "%s", my_ctime(now))); put_it("%s", convert_output_format("$G Total uptime : $0-", "%s", convert_time(now - start_time))); } do_hook(EXIT_LIST, "%s", reason ? reason : buffer); close_all_servers(reason ? reason : buffer); put_it("%s", buffer ? buffer : reason ? reason : empty_string); clean_up_processes(); if (!dumb_mode && term_initialized) { cursor_to_input(); /* Needed so that ircII doesn't gobble * the last line of the kill. */ term_cr(); term_clear_to_eol(); term_reset(); } destroy_call_stack(); #if defined(THREAD) && defined(WANT_NSLOOKUP) kill_dns(); #endif remove_pid(); if (really_quit) { #ifdef GUI gui_exit(); #else #if defined(WANT_DETACH) && !defined(GUI) kill_attached_if_needed(0); #endif fprintf(stdout, "\r"); fflush(stdout); exit(0); #endif } }
/* * update_input: does varying amount of updating on the input line depending * upon the position of the cursor and the update flag. If the cursor has * move toward one of the edge boundaries on the screen, update_cursor() * flips the input line to the next (previous) line of text. The update flag * may be: * * NO_UPDATE - only do the above bounds checking. * * UPDATE_JUST_CURSOR - do bounds checking and position cursor where is should * be. * * UPDATE_FROM_CURSOR - does all of the above, and makes sure everything from * the cursor to the right edge of the screen is current (by redrawing it). * * UPDATE_ALL - redraws the entire line */ void update_input(int update) { int old_start; static int co = 0, li = 0; char *ptr; int len, free_it = 1, cnt, ansi_count, max; char *prompt; cursor_to_input(); if (current_screen->promptlist) prompt = current_screen->promptlist->prompt; else prompt = input_prompt; if (prompt) { if (update != NO_UPDATE) { char *inp_ptr = NULL; int args_used; if (is_process(get_target_by_refnum(0))) { ptr = (char *) get_prompt_by_refnum(0); free_it = 0; } else if (!get_int_var(DISPLAY_ANSI_VAR)) ptr = expand_alias(stripansicodes(prompt), empty_str, &args_used, NULL); else ptr = expand_alias(prompt, empty_str, &args_used, NULL); if (*ptr && ((my_strnicmp(ptr, "Password:"******"Operator Password:"******"Server Password:", 16) == 0))) term_echo(0); else term_echo(1); len = strlen(ptr); if (strncmp(ptr, current_screen->input_buffer, len) || !len) { malloc_strcpy(&inp_ptr, INPUT_BUFFER + MIN_POS); strmcpy(INPUT_BUFFER, ptr, INPUT_BUFFER_SIZE); THIS_POS += (len - MIN_POS); MIN_POS = strlen(ptr); ADD_TO_INPUT(inp_ptr); new_free(&inp_ptr); update = UPDATE_ALL; } if (free_it) new_free(&ptr); } } else term_echo(1); if ((li != term_rows) || (co != term_cols)) { /* resized? Keep it simple and reset everything */ input_line = term_rows - 1; zone = term_cols - (WIDTH * 2) + 4; lower_mark = WIDTH; upper_mark = term_cols - WIDTH; cursor = current_screen->buffer_min_pos; current_screen->buffer_pos = current_screen->buffer_min_pos; str_start = 0; li = term_rows; co = term_cols; } old_start = str_start; ansi_count = count_ansi(current_screen->input_buffer, zone); if (old_ansi != ansi_count || current_screen->buffer_pos - ansi_count > zone) { lower_mark = WIDTH; upper_mark = term_cols - WIDTH; str_start = 0; } ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone); while ((current_screen->buffer_pos - ansi_count < lower_mark) && lower_mark > WIDTH) { upper_mark = lower_mark - ansi_count; lower_mark -= (zone + ansi_count); str_start -= (zone + ansi_count); if (str_start < zone) { str_start = 0; ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone); lower_mark -= ansi_count; upper_mark -= ansi_count; } } while (current_screen->buffer_pos - ansi_count >= upper_mark) { lower_mark = upper_mark + ansi_count; upper_mark += zone + ansi_count; str_start += zone + ansi_count; if (ansi_count) ansi_count = 0; } /* we need to count ansi characters again, this time in the part of the string we are gonna display in a few moments */ ansi_count = count_ansi(&(current_screen->input_buffer[str_start]), zone); old_ansi = count_ansi(current_screen->input_buffer, zone); /* we need to substract number of ansi characters from cursor position since those are not visible, otherwise we'd display cursor * in wrong place */ cursor = current_screen->buffer_pos - str_start - ansi_count; if ((old_start != str_start) || (update == UPDATE_ALL)) { term_move_cursor(0, input_line); if ((str_start == 0) && (MIN_POS > 0)) { int echo; echo = term_echo(1); if (MIN_POS > (term_cols - WIDTH)) len = term_cols - WIDTH - 1 /* + ansi_count */ ; else len = MIN_POS; cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), len); term_echo(echo); cnt += /* term_puts */ safe_puts(&(current_screen->input_buffer[ str_start + len]), term_cols - len + ansi_count); } else cnt = /* term_puts */ safe_puts(&(INPUT_BUFFER[str_start]), term_cols); term_clear_to_eol(); term_move_cursor(cursor, input_line); } else if (update == UPDATE_FROM_CURSOR) { term_move_cursor(cursor, input_line); cnt = cursor; max = term_cols - (current_screen->buffer_pos - str_start) + ansi_count; if ((len = strlen(&(THIS_CHAR))) > max) len = max; cnt += /* term_puts */ safe_puts(&(THIS_CHAR), len); term_clear_to_eol(); term_move_cursor(cursor, input_line); } else if (update == UPDATE_JUST_CURSOR) term_move_cursor(cursor, input_line); term_flush(); }
/* * input_beginning_of_line: moves the input cursor to the first character in * the input buffer */ void input_beginning_of_line(char unused, char *not_used) { cursor_to_input(); THIS_POS = MIN_POS; update_input(UPDATE_JUST_CURSOR); }
/* * input_end_of_line: moves the input cursor to the last character in the * input buffer */ void input_end_of_line(char unused, char *not_used) { cursor_to_input(); THIS_POS = strlen(INPUT_BUFFER); update_input(UPDATE_JUST_CURSOR); }