int main(int argc, char **argv) { to_send = (message *)malloc(sizeof(message)); // message struct to talk to server with message *received = (message *)malloc(sizeof(message)); client *me = (client *)malloc(sizeof(client)); // ME! tbuf B = 0; char welcome_msg[100]; signal(SIGINT, sigint_handler); // handle command line args int i; if (argc > 0) { for (i = 0 ; i < argc ; i++) { if (*argv[i] == '-') { switch(*(argv[i] + 1)) { case 'n': strncpy(NAME, argv[++i], sizeof(NAME)); break; case 'h': printf("%s\n", HELP); exit(1); break; case 'l': // local use CONN = 0; me->room_id = 0; break; case 'j': // not creating a room, but joining ROOM_NO = atoi(argv[++i]); break; case 't': DEBUG = 1; break; } } else if(i > 0) { strncpy(filename, argv[i], sizeof(filename)); B = read_from_file(argv[i]); debug("reading done (%s)\n", argv[i]); } } } if (!NAME[0] && CONN) { // name is not set yet and connecting to network printf("%s\n", HELP); exit(1); } if (!B) { B = new_tbuf(); printf("is this it?\n"); } // build socket connection if (CONN) { if ((FROM_SERVER = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "Fatal - Cannot create socket\n"); close(1); } serv_addr.sin_family = AF_INET; serv_addr.sin_port = htons(CLIENT_PORT); serv_addr.sin_addr.s_addr = inet_addr(SERVER_ADDR); if (connect(FROM_SERVER, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) { fprintf(stderr, "Fatal - Connection to server failed\n"); close(1); } // setup terminal args and handshake with server // 1. join server request strncpy(to_send->cmd, CONN_REQUEST, sizeof(CONN_REQUEST)); strncpy(to_send->content, NAME, sizeof(NAME)); debug("Name sent to server: %s\n", to_send->content); write(FROM_SERVER, to_send, sizeof(message)); read(FROM_SERVER, &to_send->remote_client_id, sizeof(int)); debug("Received from server: %d\n", to_send->remote_client_id); // let us assume that you are creating a room here if (ROOM_NO != -1) { // join a given room me->room = ROOM_NO; strncpy(to_send->cmd, "join", 5); to_send->to_distribute = 1; sprintf(to_send->content, "%d", ROOM_NO); debug("command sent: %s\n", to_send->cmd); send_to_server(to_send, sizeof(message)); room_state *current_room = (room_state *)malloc(sizeof(room_state)); read(FROM_SERVER, current_room, sizeof(room_state)); B = chararr2tbuf(current_room->buf); memcpy(usernames, current_room->usernames, sizeof(usernames)); read(FROM_SERVER, &me->room_id, sizeof(int)); to_send->local_client_id = me->room_id; strncpy(usernames[me->room_id], NAME, sizeof(NAME)); sprintf(welcome_msg, "<SERVER> You have just joined room %d", me->room); } else { // create a room strncpy(to_send->cmd, "new", 4); debug("command sent: %s\n", to_send->cmd); send_to_server(to_send, sizeof(message)); read(FROM_SERVER, &ROOM_NO, sizeof(int)); to_send->local_client_id = 0; // create a room = 0 me->room = ROOM_NO; me->room_id = 0; strncpy(usernames[me->room_id], NAME, sizeof(NAME)); debug("recv from server: in room %d\n", me->room); sprintf(welcome_msg, "<SERVER> You are now the owner of %d", me->room); } to_send->to_distribute = 1; } else { sprintf(welcome_msg, "You are currently running NetScribe locally"); } //getchar(); // setup GUI WINDOW *mainwin = initscr(); cbreak(); noecho(); keypad(mainwin, true); int vis = curs_set(0); int ncols = getmaxx(mainwin); int nlines = getmaxy(mainwin); int begx = getbegx(mainwin); int begy = getbegy(mainwin); debug("%d, %d, %d, %d\n", ncols, nlines, begx, begy); WINDOW *canvas = subwin(mainwin, nlines - 4, // save 2 lines for bottom status ncols, // same as main begy + 2, // save one line for title and one line for 'chat' begx); WINDOW *topbar = subwin(mainwin, 1, ncols, begy, begx); WINDOW *chatbar = subwin(mainwin, 1, ncols, begy + 1, begx); WINDOW *botbar = subwin(mainwin, 1, ncols, nlines - 2, begx); WINDOW *inputbar = subwin(mainwin, 1, ncols, nlines - 1, begx); render_topbar(topbar); render_string(chatbar, welcome_msg); render_botbar(botbar); wrefresh(mainwin); debug("setup done\n"); // setup the select program char c[3]; fd_set readfds, current; FD_ZERO(&readfds); FD_ZERO(¤t); FD_SET(STDIN_FILENO, &readfds); if (CONN) { FD_SET(FROM_SERVER, &readfds); } while (1) { if (!DEBUG) { render_tbuf(B, canvas); // FIXME OVERWRITING STUFF } current = readfds; debug("BEFORE SELECT\n"); if (select(FROM_SERVER + 1, ¤t, NULL, NULL, NULL) < 0) { fprintf(stderr, "Error %d: %s", errno, strerror(errno)); } debug("HELLO!\n"); if (FD_ISSET(FROM_SERVER, ¤t)) { // receive msg from server read(FROM_SERVER, received, sizeof(message)); debug("MSG FROM SERVER: %s\n", received->cmd); int c_user = received->local_client_id; if (strstr(received->cmd, "chat")) { // this is a chat command time_t t; struct tm *tinfo; time(&t); tinfo = localtime(&t); char time_s[20]; if (!strftime(time_s, sizeof(time_s), "%H:%M:%S", tinfo)) { fprintf(stderr, "Error %d: %s", errno, strerror(errno)); exit(1); } char to_put_up[100]; sprintf(to_put_up, "[%s] %s: %s", time_s, usernames[received->local_client_id], received->content); render_string(chatbar, to_put_up); } if (strstr(received->cmd, "join")) { // if new user joins debug("THIS IS A JOIN REQUEST\n"); strncpy(usernames[received->local_client_id], received->content, 16); time_t t; struct tm *tinfo; time(&t); tinfo = localtime(&t); char time_s[20]; if (!strftime(time_s, sizeof(time_s), "%H:%M:%S", tinfo)) { fprintf(stderr, "Error %d: %s", errno, strerror(errno)); exit(1); } char to_put_up[100]; sprintf(to_put_up, "[%s] <SERVER>: %s has joined", time_s, usernames[received->local_client_id]); render_string(chatbar, to_put_up); } if (strstr(received->cmd, "exit")) { // if user exits time_t t; struct tm *tinfo; time(&t); tinfo = localtime(&t); char time_s[20]; if (!strftime(time_s, sizeof(time_s), "%H:%M:%S", tinfo)) { fprintf(stderr, "Error %d: %s", errno, strerror(errno)); exit(1); } char to_put_up[100]; sprintf(to_put_up, "[%s] <SERVER>: %s has exited", time_s, usernames[received->local_client_id]); render_string(chatbar, to_put_up); memset(usernames[received->local_client_id], 0, sizeof(usernames[received->local_client_id])); } if (strstr(received->cmd, SERVER_EXIT)) { // server died :( SERVER_DIED = 1; break; } if (strstr(received->cmd, BUF_REQUEST)) { // you are the owner and the server asked you for the buffer debug("HELLO I GOTCHU\n"); //assert(me->room_id == 0); // i should be the owner room_state *current_state = (room_state *)malloc(sizeof(room_state)); strncpy(current_state->buf, tbuf2chararr(B), 20480); memcpy(current_state->usernames, usernames, sizeof(usernames)); debug("conversion done\n"); write(FROM_SERVER, current_state, sizeof(room_state)); // only except to the RO rule debug("Wrote to server\n"); } if (strstr(received->cmd, "edit")) { memcpy(c, received->content, sizeof(c)); if (c[0] == 27) { switch (c[2]) { case 'C': // move cursor right backward_char(B, c_user); break; case 'D': forward_char(B, c_user); break; } } else if (c[0] == 127) { // backspace delete_char(B, c_user); } else if (0 < c[0] && c[0] < 127) { // other characters insert_char(B, c[0], c_user); } } } if (FD_ISSET(STDIN_FILENO, ¤t)) { // reading from stdin read(STDIN_FILENO, &c, 1); if (c[0] == 24) { // ^X --> exit break; // exit out of the listening loop } switch (mode) { case EDIT_MODE: if (c[0] == 12) { // ^L --> redraw wclear(mainwin); render_topbar(topbar); render_string(chatbar, ""); render_tbuf(B, canvas); wrefresh(mainwin); } else if (c[0] == 15) { // ^O --> saving mode mode = SAVE_MODE; } else if (c[0] == 8) { // ^H --> chat mode = CHAT_MODE; werase(inputbar); wmove(inputbar, 0, 1); waddstr(inputbar, "Chat (press enter to send): "); wrefresh(inputbar); msg_i = 0; } else { // these will be sent strncpy(to_send->cmd, "edit", 5); if (c[0] == 27) { read(STDIN_FILENO, &c[1], 2); switch (c[2]) { case 'C': // move cursor right backward_char(B, me->room_id); break; case 'D': forward_char(B, me->room_id); break; } memcpy(to_send->content, c, 3); } else if (c[0] == 127) { // backspace delete_char(B, me->room_id); memcpy(to_send->content, c, 3); } else if (0 < c[0] && c[0] < 127) { // other characters printf("%c\n", c[0]); insert_char(B, c[0], me->room_id); memcpy(to_send->content, c, 3); } send_to_server(to_send, sizeof(message)); } break; case CHAT_MODE: // when user is inputing things for the chat if (c[0] == 13) { // enter msg[msg_i] = 0; // null terminator strncpy(to_send->cmd, "chat", 5); strncpy(to_send->content, msg, sizeof(to_send->content)); send_to_server(to_send, sizeof(message)); werase(inputbar); wrefresh(inputbar); mode = EDIT_MODE; } else if (0 < c[0] && c[0] < 127) { // other chars msg[msg_i] = c[0]; msg_i++; waddch(inputbar, c[0]); wrefresh(inputbar); } break; case SAVE_MODE: // when user is typing in the to-save filename break; } } } if (CONN && !SERVER_DIED) { // send off closing request strncpy(to_send->cmd, "exit", 5); send_to_server(to_send, sizeof(message)); } curs_set(vis); endwin(); if (SERVER_DIED) { printf("The server has shutdown or the owner of the room has quit\n"); } else { printf("Exiting...\n"); } return 0; }
void TE_View::right() { forward_char(1); }