char *get_string(int fd) { static char buffer[4096]; size_t len = 0; if (flush_socket(fd) == -1) return NULL; do { int key = readchar(fd); if (key == -1) return NULL; if (key == 10 || key == 13) break; buffer[len++] = key; } while(len < (sizeof(buffer) - 1)); buffer[len] = 0x00; return buffer; }
int read_thread(void *p) { int err = 0; int frame = 0; fd_set saveset, readset; int count; int sock = *(int *) p; struct JoyScrHeader head; FD_ZERO(&saveset); FD_SET(sock, &saveset); while(!err) { readset = saveset; count = select(FD_SETSIZE, &readset, NULL, NULL, NULL); if(count > 0) { int ret; int mode; int size; if(FD_ISSET(sock, &readset)) { ret = read(sock, &head, sizeof(head)); if((ret != sizeof(head)) || (LE32(head.magic) != JOY_MAGIC)) { fprintf(stderr, "Error in socket %d, magic %08X\n", ret, head.magic); flush_socket(sock); break; } mode = LE32(head.mode); size = LE32(head.size); g_buffers[frame].head.mode = mode; g_buffers[frame].head.size = size; if(mode < 0) { if(g_context.args.video) { post_event(EVENT_ENABLE_SCREEN); } else { g_context.scron = 0; } } else if(mode > 3) { /* Flush socket */ flush_socket(sock); } else { /* Try and read in screen */ /* If we do not get a full frame read and we timeout in quater second or so then * reset sync as it probably means the rest isn't coming */ int loc = 0; //fprintf(stderr, "Size %d\n", size); while(1) { readset = saveset; /* Should have a time out */ count = select(FD_SETSIZE, &readset, NULL, NULL, NULL); if(count > 0) { ret = read(sock, &(g_buffers[frame].buf[loc]), size-loc); if(ret < 0) { if(errno != EINTR) { perror("read:"); err = 1; break; } } else if(ret == 0) { fprintf(stderr, "EOF\n"); break; } //fprintf(stderr, "Read %d\n", loc); loc += ret; if(loc == size) { break; } } else if(count < 0) { if(errno != EINTR) { perror("select:"); err = 1; break; } } } if(!err) { if(frame) { post_event(EVENT_RENDER_FRAME_2); } else { post_event(EVENT_RENDER_FRAME_1); } frame ^= 1; } } } } else if(count < 0) { if(errno != EINTR) { perror("select:"); err = 1; } } } return 0; }
DWORD server_setup(SOCKET fd) { Remote *remote = NULL; DWORD res = 0; #ifdef _UNIX int local_error = 0; #endif // if hAppInstance is still == NULL it means that we havent been // reflectivly loaded so we must patch in the hAppInstance value // for use with loading server extensions later. InitAppInstance(); srand((unsigned int)time(NULL)); __try { do { if (!(remote = remote_allocate(fd))) { SetLastError(ERROR_NOT_ENOUGH_MEMORY); break; } // Do not allow the file descriptor to be inherited by child // processes SetHandleInformation((HANDLE)fd, HANDLE_FLAG_INHERIT, 0); // Flush the socket handle dprintf("Flushing the socket handle..."); flush_socket(remote); // Initialize SSL on the socket dprintf("Negotiating SSL..."); negotiate_ssl(remote); // Register extension dispatch routines dprintf("Registering dispatch routines..."); register_dispatch_routines(); dprintf("Entering the monitor loop..."); // Keep processing commands res = monitor_loop(remote); dprintf("Deregistering dispatch routines..."); // Clean up our dispatch routines deregister_dispatch_routines(); } while (0); dprintf("Closing down SSL..."); SSL_free(remote->ssl); SSL_CTX_free(remote->ctx); if (remote) remote_deallocate(remote); } /* Invoke the fatal error handler */ __except(exceptionfilter(GetExceptionCode(), GetExceptionInformation())) { dprintf("*** exception triggered!"); ExitThread(0); } return res; }
static void tintin(void) { int i, result, maxfd; struct timeval tv; fd_set readfdmask; #ifdef XTERM_TITLE struct session *lastsession=0; #endif char kbdbuf[BUFFER_SIZE]; WC ch; int inbuf=0; mbstate_t instate; memset(&instate, 0, sizeof(instate)); for (;;) { #ifdef XTERM_TITLE if (ui_own_output && activesession!=lastsession) { lastsession=activesession; if (activesession==nullsession) user_title(XTERM_TITLE, "(no session)"); else user_title(XTERM_TITLE, activesession->name); } #endif tv.tv_sec = check_events(); tv.tv_usec = 0; maxfd=0; FD_ZERO(&readfdmask); if (!eofinput) FD_SET(0, &readfdmask); else if (activesession==nullsession) end_command(0, activesession); for (struct session *ses = sessionlist; ses; ses = ses->next) { if (ses==nullsession) continue; if (ses->nagle) flush_socket(ses); FD_SET(ses->socket, &readfdmask); if (ses->socket>maxfd) maxfd=ses->socket; } result = select(maxfd+1, &readfdmask, 0, 0, &tv); if (need_resize) { char buf[BUFFER_SIZE]; user_resize(); sprintf(buf, "#NEW SCREEN SIZE: %dx%d.", COLS, LINES); tintin_puts1(buf, activesession); } if (result == 0) continue; else if (result < 0 && errno == EINTR) continue; /* Interrupted system call */ else if (result < 0) syserr("select"); if (FD_ISSET(0, &readfdmask)) { PROFSTART; PROFPUSH("user interface"); result=read(0, kbdbuf+inbuf, BUFFER_SIZE-inbuf); if (result==-1) myquitsig(0); if (result==0 && !isatty(0)) eofinput=true; inbuf+=result; i=0; while (i<inbuf) { result=mbrtowc(&ch, kbdbuf+i, inbuf-i, &instate); if (result==-2) /* incomplete but valid sequence */ { memmove(kbdbuf, kbdbuf+i, inbuf-i); inbuf-=i; goto partial; } else if (result==-1) /* invalid sequence */ { ch=0xFFFD; i++; errno=0; /* Shift by 1 byte. We can use a more intelligent shift, * but staying charset-agnostic makes the code simpler. */ } else if (result==0) /* literal 0 */ i++; /* oops... bad ISO/ANSI, bad */ else i+=result; if (user_process_kbd(activesession, ch)) { hist_num=-1; if (term_echoing || (got_more_kludge && done_input[0])) /* got_more_kludge: echo any non-empty line */ { if (activesession && *done_input) if (strcmp(done_input, prev_command)) do_history(done_input, activesession); if (activesession->echo) echo_input(done_input); if (activesession->logfile) write_logf(activesession, done_input, activesession->loginputprefix, activesession->loginputsuffix); } if (*done_input) strcpy(prev_command, done_input); aborting=false; activesession = parse_input(done_input, false, activesession); recursion=0; } } inbuf=0; partial: PROFEND(kbd_lag, kbd_cnt); PROFPOP; } for (struct session *ses = sessionlist; ses; ses = ses->next) { if (ses->socket && FD_ISSET(ses->socket, &readfdmask)) { aborting=false; any_closed=false; do { read_mud(ses); if (any_closed) { any_closed=false; goto after_read; /* The remaining sessions will be done after select() */ } #ifdef HAVE_ZLIB } while (ses->mccp_more); #else } while (0); #endif } } after_read: if (activesession->server_echo && (2-activesession->server_echo != gotpassword)) { gotpassword= 2-activesession->server_echo; if (!gotpassword) got_more_kludge=false; user_passwd(gotpassword && !got_more_kludge); term_echoing=!gotpassword; } }