int main(int argc, char **argv) { if (argc < 3) err_quit("usage: lan_chat <subnet-address> <user-name> <start-idx>"); subnet_address = argv[1]; if (!inet_aton(subnet_address, NULL)) err_quit("The subnet address must be a valid IPv4 address"); user_name = argv[2]; if (strlen(user_name) > 10) err_quit("The user_name must be at most 10 characters"); if (argc == 4) start_idx = atoi(argv[3]); /* * Spawns a listener process which accepts any connection and outputs each * received message on the terminal. */ int listenerpid = spawn_listener(CHAT_PORT); /* * Connects to a listener and waits for user input. On each new line input * by user, creates a message according to the protocol and sends it over * the socket. */ int sockfd = connect_to_listener(); message_loop(sockfd); kill(listenerpid, SIGKILL); exit(0); }
int transmit(void) { // Hide the cursor, and make sure it comes back before exiting. set_cursor(false); signal(SIGINT, sigint_handler); // Set up the keyboard listener. long time_unit = calibrate_listener(); if (time_unit == EOF) { return 0; } if (!spawn_listener()) { print_error("error creating thread"); return 1; } // Set up the circular buffers. int buf_size = number_of_columns(); char code_buf[buf_size]; char text_buf[buf_size]; struct Circle code_circ, text_circ; init_empty(&code_circ, code_buf, buf_size); init_empty(&text_circ, text_buf, buf_size); append(&code_circ, '*'); // Begin the main loop. Code code = 0; int code_size = 0; bool done = false; long time = current_millis(); enum { NONE, CHAR, WORD } wait_mode = NONE; while (!done) { // Check the state of the keyboard listener. long time_now = current_millis(); enum ListenerState state = get_listener_state(time_now); switch (state) { case LS_EOF: done = true; continue; case LS_NONE: break; case LS_DOWN: insert(&code_circ, '.'); wait_mode = NONE; code <<= 1; code_size++; break; case LS_REPEAT: insert(&code_circ, '-'); code |= 1; break; case LS_HOLD: case LS_HOLD_R: break; case LS_UP: append(&code_circ, '*'); time = time_now; wait_mode = CHAR; break; } // Check if enough time has passed to start a new character or word. long elapsed = time_now - time; switch (wait_mode) { case NONE: break; case CHAR: if (elapsed > TIME_BETWEEN_CHARS) { insert(&code_circ, ' '); append(&code_circ, '*'); wait_mode = WORD; char ch = INVALID_CODE; if (code_size <= MAX_SIZE) { code = add_size(code, code_size); char decoded = code_to_char(code); if (decoded) { ch = decoded; } } append(&text_circ, ch); code = 0; code_size = 0; } break; case WORD: if (elapsed > TIME_BETWEEN_WORDS) { insert(&code_circ, '/'); append(&code_circ, ' '); append(&code_circ, '*'); wait_mode = NONE; append(&text_circ, ' '); } break; } // Print the contents of both buffers. putchar('\r'); print_circle(&code_circ); fputs(" \n", stdout); print_circle(&text_circ); fputs(" \x1B[F", stdout); fflush(stdout); usleep(SLEEP_TIME_US); } cleanup(); return 0; }