int main(void) { reset_console(0); return EXIT_SUCCESS; }
static void mux_io(server_conf_t *conf) { /* Multiplexes I/O between all of the objs in the configuration. * This routine is the heart of ConMan. */ ListIterator i; int n; obj_t *obj; int inevent_fd; assert(conf->tp != NULL); assert(!list_is_empty(conf->objs)); i = list_iterator_create(conf->objs); while (!done) { if (reconfig) { /* * FIXME: A reconfig should pro'ly resurrect "downed" serial objs * and reset reconnect timers of "downed" telnet objs. */ log_msg(LOG_NOTICE, "Performing reconfig on signal=%d", reconfig); reopen_logfiles(conf); reconfig = 0; } /* FIXME: Switch from recomputing the tpoll set on each loop iteration * to modifying it based on events. This will eliminate the 1sec * tpoll() sleep timeout and greatly reduce cpu utilization. * It will also eliminate the maze of twisty conditions below. */ DPRINTF((25, "Recomputing tpoll fd set\n")); (void) tpoll_zero(conf->tp, TPOLL_ZERO_FDS); tpoll_set(conf->tp, conf->ld, POLLIN); inevent_fd = inevent_get_fd(); if (inevent_fd >= 0) { tpoll_set(conf->tp, inevent_get_fd(), POLLIN); } list_iterator_reset(i); while ((obj = list_next(i))) { if (obj->gotReset) { reset_console(obj, conf->resetCmd); } if (obj->fd < 0) { continue; } if ( ( ( is_telnet_obj(obj) && obj->aux.telnet.state == CONMAN_TELNET_UP ) || ( is_process_obj(obj) && obj->aux.process.state == CONMAN_PROCESS_UP ) || #if WITH_FREEIPMI ( is_ipmi_obj(obj) && obj->aux.ipmi.state == CONMAN_IPMI_UP ) || #endif /* WITH_FREEIPMI */ ( is_unixsock_obj(obj) && obj->aux.unixsock.state == CONMAN_UNIXSOCK_UP ) || is_serial_obj(obj) || is_client_obj(obj) ) && ( ! obj->gotEOF ) ) { tpoll_set(conf->tp, obj->fd, POLLIN); } if ( ( (obj->bufInPtr != obj->bufOutPtr) || (obj->gotEOF) ) && ( ! (is_telnet_obj(obj) && obj->aux.telnet.state != CONMAN_TELNET_UP) ) && ( ! (is_process_obj(obj) && obj->aux.process.state != CONMAN_PROCESS_UP) ) && #if WITH_FREEIPMI ( ! (is_ipmi_obj(obj) && obj->aux.ipmi.state != CONMAN_IPMI_UP) ) && #endif /* WITH_FREEIPMI */ ( ! (is_unixsock_obj(obj) && obj->aux.unixsock.state != CONMAN_UNIXSOCK_UP) ) && ( ! (is_client_obj(obj) && obj->aux.client.gotSuspend) ) ) { tpoll_set(conf->tp, obj->fd, POLLOUT); } if (is_telnet_obj(obj) && obj->aux.telnet.state == CONMAN_TELNET_PENDING) { tpoll_set(conf->tp, obj->fd, POLLIN | POLLOUT); } } DPRINTF((25, "Calling tpoll\n")); while ((n = tpoll(conf->tp, 1000)) < 0) { if (errno != EINTR) { log_err(errno, "Unable to multiplex I/O"); } else if (done || reconfig) { break; } } if (n <= 0) { continue; } if (tpoll_is_set(conf->tp, conf->ld, POLLIN)) { accept_client(conf); } if ((inevent_fd >= 0) && tpoll_is_set(conf->tp, inevent_fd, POLLIN)) { inevent_process(); } /* If read_from_obj() or write_to_obj() returns -1, * the obj's buffer has been flushed. If it is a telnet obj, * retain it and attempt to re-establish the connection; * o/w, give up and remove it from the master objs list. */ list_iterator_reset(i); while ((obj = list_next(i))) { if (obj->fd < 0) { continue; } if (is_telnet_obj(obj) && tpoll_is_set(conf->tp, obj->fd, POLLIN | POLLOUT) && (obj->aux.telnet.state == CONMAN_TELNET_PENDING)) { open_telnet_obj(obj); continue; } if (tpoll_is_set(conf->tp, obj->fd, POLLIN | POLLHUP | POLLERR)) { if (read_from_obj(obj, conf->tp) < 0) { list_delete(i); continue; } if (obj->fd < 0) { continue; } } if (tpoll_is_set(conf->tp, obj->fd, POLLOUT)) { if (write_to_obj(obj) < 0) { list_delete(i); continue; } if (obj->fd < 0) { continue; } } } } log_msg(LOG_NOTICE, "Exiting on signal=%d", done); list_iterator_destroy(i); return; }
static bool process_vt100_command(const char c, bool seenBracket, int32 *args, int32 argCount) { bool ret = true; // kprintf("process_vt100_command: c '%c', argCount %ld, arg[0] %ld, arg[1] %ld, seenBracket %d\n", // c, argCount, args[0], args[1], seenBracket); if (seenBracket) { switch (c) { case 'H': // set cursor position case 'f': { int32 row = argCount > 0 ? args[0] : 1; int32 col = argCount > 1 ? args[1] : 1; if (row > 0) row--; if (col > 0) col--; move_cursor(col, row); break; } case 'A': // move up { int32 deltaY = argCount > 0 ? -args[0] : -1; if (deltaY == 0) deltaY = -1; move_cursor(sScreen.x, sScreen.y + deltaY); break; } case 'e': case 'B': // move down { int32 deltaY = argCount > 0 ? args[0] : 1; if (deltaY == 0) deltaY = 1; move_cursor(sScreen.x, sScreen.y + deltaY); break; } case 'D': // move left { int32 deltaX = argCount > 0 ? -args[0] : -1; if (deltaX == 0) deltaX = -1; move_cursor(sScreen.x + deltaX, sScreen.y); break; } case 'a': case 'C': // move right { int32 deltaX = argCount > 0 ? args[0] : 1; if (deltaX == 0) deltaX = 1; move_cursor(sScreen.x + deltaX, sScreen.y); break; } case '`': case 'G': // set X position { int32 newX = argCount > 0 ? args[0] : 1; if (newX > 0) newX--; move_cursor(newX, sScreen.y); break; } case 'd': // set y position { int32 newY = argCount > 0 ? args[0] : 1; if (newY > 0) newY--; move_cursor(sScreen.x, newY); break; } #if 0 case 's': // save current cursor save_cur(console, false); break; case 'u': // restore cursor restore_cur(console, false); break; case 'r': // set scroll region { int32 low = argCount > 0 ? args[0] : 1; int32 high = argCount > 1 ? args[1] : sScreen.lines; if (low <= high) set_scroll_region(console, low - 1, high - 1); break; } case 'L': // scroll virtual down at cursor { int32 lines = argCount > 0 ? args[0] : 1; while (lines > 0) { scrdown(console); lines--; } break; } case 'M': // scroll virtual up at cursor { int32 lines = argCount > 0 ? args[0] : 1; while (lines > 0) { scrup(console); lines--; } break; } #endif case 'K': if (argCount == 0 || args[0] == 0) { // erase to end of line erase_line(LINE_ERASE_RIGHT); } else if (argCount > 0) { if (args[0] == 1) erase_line(LINE_ERASE_LEFT); else if (args[0] == 2) erase_line(LINE_ERASE_WHOLE); } break; #if 0 case 'J': if (argCount == 0 || args[0] == 0) { // erase to end of screen erase_screen(console, SCREEN_ERASE_DOWN); } else { if (args[0] == 1) erase_screen(console, SCREEN_ERASE_UP); else if (args[0] == 2) erase_screen(console, SCREEN_ERASE_WHOLE); } break; #endif case 'm': if (argCount >= 0) set_vt100_attributes(args, argCount); break; default: ret = false; } } else { switch (c) { #if 0 case 'c': reset_console(console); break; case 'D': rlf(console); break; case 'M': lf(console); break; case '7': save_cur(console, true); break; case '8': restore_cur(console, true); break; #endif default: ret = false; } } return ret; }