/* * Process any signals we have received. * A received signal cause a bit to be set in "sigs". */ void psignals(void) { int tsignals; if ((tsignals = sigs) == 0) return; sigs = 0; if (tsignals & S_STOP) { /* * Clean up the terminal. */ lsignal(SIGTTOU, SIG_IGN); clear_bot(); deinit(); flush(0); raw_mode(0); lsignal(SIGTTOU, SIG_DFL); lsignal(SIGTSTP, SIG_DFL); kill(getpid(), SIGTSTP); /* * ... Bye bye. ... * Hopefully we'll be back later and resume here... * Reset the terminal and arrange to repaint the * screen when we get back to the main command loop. */ lsignal(SIGTSTP, stop); raw_mode(1); init(); screen_trashed = 1; tsignals |= S_WINCH; } if (tsignals & S_WINCH) { int old_width, old_height; /* * Re-execute scrsize() to read the new window size. */ old_width = sc_width; old_height = sc_height; get_term(); if (sc_width != old_width || sc_height != old_height) { wscroll = (sc_height + 1) / 2; calc_jump_sline(); calc_shift_count(); screen_trashed = 1; } } if (tsignals & S_INTERRUPT) { ring_bell(); if (quit_on_intr) quit(QUIT_INTERRUPT); } }
int main(int argc, char *argv[]) { FILE *fp; int needclose; int ttyfd; int line; if (isatty(STDIN_FILENO) == 0) { fp = stdin; needclose = 0; } else { if (argc <= 1) { printf("Usage: mymore [file]\n"); return 0; } if ((fp = fopen(argv[1], "r")) == NULL) { perror("fopen"); return 1; } needclose = 1; } // cat if (isatty(STDOUT_FILENO) == 0) { cat(fp); // more } else { if (termcap() == -1) { fprintf(stderr, "failed to load termcap."); } if ((tty = open("/dev/tty", O_RDONLY)) == -1) { perror("open"); // return; tty = STDERR_FILENO; } raw_mode(1); more(fp); raw_mode(0); if (tty != STDERR_FILENO) { close(tty); } } if (needclose) { fclose(fp); } return 0; }
void asio_sender::send(ana::detail::shared_buffer buffer , tcp::socket& socket , ana::send_handler* handler, ana::detail::sender* sender , ana::operation_id op_id ) { ana::timer* running_timer( NULL ); try { if ( sender->timeouts_enabled() ) { running_timer = sender->create_timer(); sender->start_timer( running_timer, buffer, boost::bind(&asio_sender::handle_send, this, boost::asio::placeholders::error, handler, running_timer, op_id, true ) ); } stats_collector().start_send_packet( buffer->size() + ( raw_mode() ? 0 : ana::HEADER_LENGTH ) ); if ( raw_mode() ) { socket.async_write_some( boost::asio::buffer(buffer->base(), buffer->size() ), boost::bind(&asio_sender::handle_partial_send,this, buffer, boost::asio::placeholders::error, &socket, handler, running_timer, 0, _2, op_id )); } else { ana::ana_uint32 size( buffer->size() ); ana::host_to_network_long( size ); ana::serializer::bostream* output_stream = new ana::serializer::bostream(); (*output_stream) << size; //write the header first in a separate operation, then send the full buffer socket.async_write_some( boost::asio::buffer( output_stream->str() ), boost::bind(&asio_sender::handle_sent_header,this, boost::asio::placeholders::error, output_stream, &socket, buffer, handler, running_timer, _2, op_id )); } } catch(const std::exception&) { disconnect(); delete running_timer; } }
char *my_read(t_caps *caps) { if (raw_mode(caps) == -1) return (NULL); aff_cmd(caps); while (caps->buff[0] != '\n' && nll == 0) { memset(caps->buff, 0, 4); if (read(0, caps->buff, 4) <= 0) return (NULL); if (is_print_char(caps->buff[0])) { caps->cmd = put_char_str(caps->cmd, caps->buff[0], caps->cursor_pos++); aff_cmd(caps); } else buff_read_cmd(caps); if (caps->ok == 0) return (NULL); } if ((caps->cmd = strcatrealloc(caps->cmd, "\n", 1)) == NULL) return (NULL); if (tcsetattr(0, 0, &(caps->save)) == -1) return (NULL); if (caps->cmd != NULL) caps->hist = add_history(caps->hist, caps->cmd); return (caps->cmd); }
static void vt_from_here(int num) { ioctl(tty_fd, TCSETSW, &old_termio); raw_mode(tty_fd, 0); /* don't use rawmode_exit 'cos of other things it does */ ioctl(tty_fd, VT_RELDISP, VT_ACKACQ); signal(SIGUSR1, vt_from_here); }
int main(int ac, char **av) { t_list *list; t_list *tmp; struct termios t; struct termios old; list = create_list(); if (tcgetattr(0, &t) == -1) { my_putstr("Error: tcgetattr failed"); return (0); } old = t; if (manage_arg(ac, av, list) == -1) return (0); if (screen_clear() == -1) return (0); if (raw_mode(&t) == -1) return (0); tmp = list->next; tmp->cursor = 1; my_select(list, old); list_free(&list); return (0); }
int init_readline(t_rl *info) { static unsigned char start = 0; char *term; if (CHCK(info->flags, 0x04)) { info->info.buffer = NULL; info->info.tmp = NULL; info->prompt = NULL; info->tmp.buffer = NULL; info->info.i = 0; info->info.nb = 0; info->info.insert_m = 1; if (!(info->bind)) default_database(info); if ((info->flags |= raw_mode(&info->terminal)) && !start) { if (!(term = getenv("TERM"))) get_termcap("dumb", info); else if (!(get_termcap(term, info))) get_termcap("dumb", info); start++; } } return (MTRUE); }
int main(int argc, char **argv) { t_list *list; char *term; char *bp; int tty; struct termios t; struct termios save; init_main(&bp, &list); tty = get_tty_fd(); if (argc < 2) { my_printf("[*] Usage : %s [arg:]\n", argv[0]); return (0); } if (my_params_to_list(&list, argc, argv)) return (1); if (catch_error(&term, bp, &t, &save)) return (1); raw_mode(&t); clean_screen(tty); my_select(&list, tty); default_mode(&save); return (0); }
int alum_remove(t_element **list, int nbr) { int i; echo_mode(UNSET); raw_mode(SET); if (nbr <= 0) nbr = 1; i = 0; while ((*list)->name[i]) i++; nbr = i - nbr; while (i > nbr && i > 0) i--; if (i >= 0) (*list)->name[i] = '\0'; (*list)->cursor = 1; if ((nbr < 0) || (my_is_instr('|', (*list)->name) == IS_NOT_STR)) { (*list) = del_one_in_list((*list)); if ((*list) == NULL) return (END); (*list)->cursor = 1; } return (0); }
int init_termcaps(struct termios *t) { if (tcgetattr(0, t) == -1) return (-1); if (raw_mode(t) == -1) return (-1); if (d_echo(t) == -1) return (-1); my_tputs(tgetstr("im", NULL)); return (0); }
static void vt_to_here(int num) { struct termios ios; ioctl(tty_fd, TCSETSW, &new_termio); restart_con = 1; /* we're back, say to start up again */ alt_pressed = 0; raw_mode(tty_fd, 1); ios = oldios; ios.c_lflag &= ~ECHO; tcsetattr(tty_fd, 0, &ios); blank_key_down(); signal(SIGUSR2, vt_to_here); }
int get_number(void) { int nbr; char buffer[11]; int len; echo_mode(SET); raw_mode(UNSET); my_printf("\ngive number : "); if ((len = read(0, buffer, 10)) < 0) return (ERROR); buffer[len] = 0; nbr = my_getnbr(buffer); return (nbr); }
static void rawmode_exit(void) { struct vt_mode vtm; if (mypid != getpid()) return; if (closed) return; closed = 1; raw_mode(tty_fd, 0); ioctl(tty_fd, VT_GETMODE, &vtm); vtm.mode = VT_AUTO; ioctl(tty_fd, VT_SETMODE, &vtm); ioctl(tty_fd, TCSETSW, &old_termio); fcntl(tty_fd, F_SETFL, 0); /* allow for old versions of bash */ tty_fd = -1; tcsetattr(tty_fd, 0, &oldios); }
VALUE or_feval(VALUE function_name, VALUE arguments) { VALUE ruby_val = Qnil; int i, n; octave_value_list argList; n = RARRAY_LEN(arguments); bool is_function_definition = (n == 1 && FIXNUM_P(RARRAY_PTR(arguments)[0]) == 0 && strncmp(RSTRING_PTR(StringValue(RARRAY_PTR(arguments)[0])), "function ", 9) == 0); for (i = 0; i < n; i++) { argList(i) = OR_Variable(RARRAY_PTR(arguments)[i]).to_octave(); } if (octave_set_current_context) { // unwind_protect::run_all(); raw_mode(0); } can_interrupt = true; octave_initialized = true; try { symbol_table::set_scope(symbol_table::top_scope()); reset_error_handler(); int nargout = (is_function_definition ? 0 : 1); octave_value_list val = feval(std::string(RSTRING_PTR(function_name)), argList, nargout); if(val.length() > 0 && val(0).is_defined()) { ruby_val = OR_Variable(val(0)).to_ruby(); } } catch (octave_interrupt_exception) { recover_from_exception(); error_state = -2; } catch (std::bad_alloc) { recover_from_exception(); error_state = -3; } octave_initialized = false; return(ruby_val); }
/* returns 1 if ok, 0 otherwise */ static int rawmode_init(void) { if (!closed) return; mypid = getpid(); if (tty_fd == -1) { tty_fd = fileno(stdin); fcntl(tty_fd, F_SETFL, O_NONBLOCK); } /* fix termio stuff so ^C-style interrupts are ignored */ ioctl(tty_fd, TCGETS, &old_termio); new_termio = old_termio; new_termio.c_lflag &= ~(ISIG | ICANON); ioctl(tty_fd, TCSETSW, &new_termio); if (get_keyb_map()) { struct vt_mode vtm; struct termios ios; blank_key_down(); raw_mode(tty_fd, 1); signal(SIGUSR1, vt_from_here); signal(SIGUSR2, vt_to_here); ioctl(tty_fd, VT_GETMODE, &vtm); vtm.mode = VT_PROCESS; vtm.relsig = SIGUSR1; vtm.acqsig = SIGUSR2; ioctl(tty_fd, VT_SETMODE, &vtm); tcgetattr(tty_fd, &oldios); ios = oldios; ios.c_lflag &= ~ECHO; tcsetattr(tty_fd, 0, &ios); closed = 0; return (1); } else return (0); }
int main(int argc, char *argv[]) { /* handle arguments */ if(argc != 4) { printf("Incorrect arguments, please use:\n./client server port username\n"); return 1; } raw_mode(); memset(liveChannel, '\0', CHANNEL_MAX); char * address = argv[1]; char * port = argv[2]; char * username = argv[3]; /* Build Socket we pass the function the address and port */ if(buildSocket(address, port) != true) { cooked_mode(); return 1; } /* Handle Login */ if(login(username) != true) { cooked_mode(); return 1; } int parseStatus = true; char * input; fd_set readfds; promptUser(); do { FD_ZERO(&readfds); FD_SET(0, &readfds); FD_SET(socketfd, &readfds); select(socketfd+1, &readfds, NULL, NULL, NULL); if(FD_ISSET(0, &readfds)) { input = inputString(); if(input != NULL) { /* Parse Input */ parseStatus = parseInput(input); if(parseStatus != -1) { promptUser(); } } } else if (FD_ISSET(socketfd, &readfds)) { struct text * text = (struct text *) malloc(sizeof(struct text) + 1024); int bytes = 0; if((bytes = recvfrom(socketfd, text, 1024, 0,servinfo->ai_addr, &servinfo->ai_addrlen)) > 0) { clearPrompt(); switchResp(text); free(text); } } } while(parseStatus != -1); freeaddrinfo(servinfo); cooked_mode(); return 0; }
int octave_call(const char *string) { int parse_status; octave_save_signal_mask (); if (octave_set_current_context) { #if defined (USE_EXCEPTIONS_FOR_INTERRUPTS) panic_impossible (); #else unwind_protect::run_all (); raw_mode (0); std::cout << "\n"; octave_restore_signal_mask (); #endif } can_interrupt = true; octave_catch_interrupts (); octave_initialized = true; // XXX FIXME XXX need to give caller an opaque pointer // so that they can define and use separate namespaces // when calling octave, with a shared global namespace. // Something like: // int call_octave (const char *string, void *psymtab = NULL) { // ... // curr_sym_tab = psymtab == NULL ? top_level_sym_tab : symbol_table; // I suppose to be safe from callbacks (surely we have to // provide some way to call back from embedded octave into // the user's application), we should push and pop the current // symbol table. // Note that I'm trying to distinguish exception from // failure in the return codes. I believe failure is // indicated by -1. I have execution exception (including // user interrupt and more dramatic failures) returning -2 // and memory failure returning -3. We should formalize // this with error codes defined in embed_octave.h. Maybe // a more fine-grained approach could be used within octave // proper. try { curr_sym_tab = top_level_sym_tab; reset_error_handler (); eval_string(string, false, parse_status); } catch (octave_interrupt_exception) { recover_from_exception (); std::cout << "\n"; error_state = -2; } catch (std::bad_alloc) { recover_from_exception (); std::cout << "\n"; error_state = -3; } octave_restore_signal_mask(); octave_initialized = false; // XXX FIXME XXX callbacks calling embed_octave // may or may not want error_state reset. return error_state; }
int main(int argc, char *argv[]) { char *domain; char *port_str; int port_num; char *username; std::string input; char *output = (char *) ""; fd_set read_set; int result; char stdin_buffer[SAY_MAX + 1]; char *stdin_buffer_pointer = stdin_buffer; char receive_buffer[kBufferSize]; memset(&receive_buffer, 0, kBufferSize); if (argc < 4) { Error("usage: client [server name] [port] [username]"); } domain = argv[1]; port_str = argv[2]; port_num = atoi(argv[2]); username = argv[3]; if (strlen(domain) > UNIX_PATH_MAX) { Error("client: server name must be less than 108 characters"); } if (port_num < 0 || port_num > 65535) { Error("client: port number must be between 0 and 65535"); } if (strlen(username) > USERNAME_MAX) { Error("client: username must be less than 32 characters"); } CreateSocket(domain, port_str); // SendLogin(username); // // current_channel = "Common"; // SendJoin(current_channel); if (raw_mode() != 0) { Error("client: error using raw mode"); } PrintPrompt(); while (1) { FD_ZERO(&read_set); FD_SET(client_socket, &read_set); FD_SET(STDIN_FILENO, &read_set); if ((result = select(client_socket + 1, &read_set, NULL, NULL, NULL)) < 0) { Error("client: problem using select"); } if (result > 0) { if (FD_ISSET(STDIN_FILENO, &read_set)) { // User entered a char. char c = (char) getchar(); if (c == '\n') { // Increments pointer and adds NULL char. *stdin_buffer_pointer++ = '\0'; // Resets stdin_buffer_pointer to the start of stdin_buffer. stdin_buffer_pointer = stdin_buffer; std::cout << "\n" << std::flush; // Prevents output from printing on the new prompt after a newline char. output = (char *) ""; input.assign(stdin_buffer, stdin_buffer + strlen(stdin_buffer)); if (input[0] == '/') { if (!ProcessInput(input)) { break; } } else { // Sends chat messages. if (current_channel != "") { SendSay(input); } else { PrintPrompt(); } } } else if (stdin_buffer_pointer != stdin_buffer + SAY_MAX) { // Increments pointer and adds char c. *stdin_buffer_pointer++ = c; std::cout << c << std::flush; // Copies pointer into output. output = stdin_buffer_pointer; // Increments and sets NULL char. *output++ = '\0'; // Copies stdin_buffer into part of output before NULL char. output = stdin_buffer; } } else if (FD_ISSET(client_socket, &read_set)) { // Socket has data. ssize_t read_size = read(client_socket, receive_buffer, kBufferSize); if (read_size != 0) { struct text message; memcpy(&message, receive_buffer, sizeof(struct text)); text_t text_type = message.txt_type; switch (text_type) { case TXT_SAY: HandleTextSay(receive_buffer, output); break; case TXT_LIST: HandleTextList(receive_buffer, output); break; case TXT_WHO: HandleTextWho(receive_buffer, output); break; case TXT_ERROR: HandleError(receive_buffer, output); break; default: break; } } memset(&receive_buffer, 0, SAY_MAX); } // end of if client_socket } // end of if result } // end of while return 0; }
/* * Pass the specified command to a shell to be executed. * Like plain "system()", but handles resetting terminal modes, etc. */ void lsystem(const char *cmd) { int inp; char sysbuf[256]; char *shell; /* * Print the command which is to be executed, * unless the command starts with a "-". */ if (cmd[0] == '-') cmd++; else { lower_left(); clear_eol(); printf("!%s\n", cmd); } /* * De-initialize the terminal and take out of raw mode. */ deinit(); fflush(stdout); raw_mode(0); /* * Restore signals to their defaults. */ init_signals(0); /* * Force standard input to be the terminal, "/dev/tty", * even if less's standard input is coming from a pipe. */ inp = dup(0); (void)close(0); if (open(_PATH_TTY, O_RDONLY, 0) < 0) (void)dup(inp); /* * Pass the command to the system to be executed. * If we have a SHELL environment variable, use * <$SHELL -c "command"> instead of just <command>. * If the command is empty, just invoke a shell. */ if ((shell = getenv("SHELL")) != NULL && *shell != '\0') { if (*cmd == '\0') cmd = shell; else { snprintf(sysbuf, sizeof(sysbuf), "%s -c \"%s\"", shell, cmd); cmd = sysbuf; } } if (*cmd == '\0') cmd = "sh"; (void)system(cmd); /* * Restore standard input, reset signals, raw mode, etc. */ (void)close(0); (void)dup(inp); (void)close(inp); init_signals(1); raw_mode(1); init(); screen_trashed = 1; /* * Since we were ignoring window change signals while we executed * the system command, we must assume the window changed. */ windoch(0); }
bool COctaveInterface::run_octave_helper(CSGInterface* from_if) { from_if->SG_DEBUG("Entering Octave\n"); octave_save_signal_mask (); if (octave_set_current_context) { #if defined (USE_EXCEPTIONS_FOR_INTERRUPTS) panic_impossible (); #else unwind_protect::run_all (); raw_mode (0); octave_restore_signal_mask (); #endif } can_interrupt = true; octave_catch_interrupts (); octave_initialized = true; try { int parse_status; char* octave_code=NULL; clear_octave_globals(); for (int i=0; i<from_if->get_nrhs(); i++) { int len=0; char* var_name = from_if->get_string(len); from_if->SG_DEBUG("var_name = '%s'\n", var_name); if (strmatch(var_name, "octavecode")) { len=0; octave_code=from_if->get_string(len); from_if->SG_DEBUG("octave_code = '%s'\n", octave_code); break; } else { octave_value_list args; COctaveInterface* in = new COctaveInterface(args, 1, false); in->create_return_values(1); from_if->translate_arg(from_if, in); #if OCTAVE_APIVERSION >= 37 symbol_table::varref (var_name) = in->get_return_values()(0); #else set_global_value(var_name, in->get_return_values()(0)); #endif delete[] var_name; SG_UNREF(in); } } #if OCTAVE_APIVERSION >= 37 #else symbol_table* old=curr_sym_tab; curr_sym_tab = global_sym_tab; #endif reset_error_handler (); eval_string(octave_code, false, parse_status); delete[] octave_code; int32_t sz=0; octave_value_list results; #if OCTAVE_APIVERSION >= 37 if (symbol_table::is_variable("results")) { results = symbol_table::varval("results"); //results = get_global_value("results", false); sz=results.length(); } #else if (curr_sym_tab->lookup("results")) { results = get_global_value("results", false); sz=results.length(); } #endif if (sz>0) { if (results(0).is_list()) { from_if->SG_DEBUG("Found return list of length %d\n", results(0).length()); results=results(0).list_value(); sz=results.length(); } } if (sz>0 && from_if->create_return_values(sz)) { from_if->SG_DEBUG("Found %d args\n", sz); COctaveInterface* out = new COctaveInterface(results, sz, false); //process d for (int32_t i=0; i<sz; i++) from_if->translate_arg(out, from_if); SG_UNREF(out); } else { if (sz!=from_if->get_nlhs()) { from_if->SG_ERROR("Number of return values (%d) does not match number of expected" " return values (%d).\n", sz, from_if->get_nlhs()); } } #if OCTAVE_APIVERSION >= 37 #else curr_sym_tab=old; #endif } catch (octave_interrupt_exception) { recover_from_exception (); SG_SPRINT("%\n"); } catch (std::bad_alloc) { recover_from_exception (); SG_SPRINT("%\n"); } octave_restore_signal_mask(); octave_initialized = false; from_if->SG_DEBUG("Leaving Octave.\n"); return true; }
int main(int argc, char *argv[]){ int ret, // general return variable i, // general counter activeChannelIndex = 1; // index; set to 1 for 'Common' channel char *domain, // domain name of the server the client will connect to *port, // port number on server-end *uname, // username the user requests inputBuf[SAY_MAX], // buffer input from command line sayBuf[SAY_MAX], // buffer to send message to server inputChar, // used along with buffer for user input consoleBuf[TEXT_MAX], // buffer for the input from the server activeChannel[CHANNEL_MAX] = "Common", // name of channel user is on channels[CHANNEL_COUNT][CHANNEL_MAX]; // list of channels user can interact with struct addrinfo hints, // used to define what type of socket the client needs *serv, // used to hold socket-descr that the server has offered us to use *servIter; // used to iterate through the socket-descr the server has offered us to use fd_set read_fdset; // used during call to select // allocate space for things that have to be heap allocated and initialize // variables that have to be initialized. memset(channels, 0, CHANNEL_COUNT*CHANNEL_MAX); // initialize channels strncpy(channels[0], activeChannel, CHANNEL_MAX); // add 'Common' to channels command = malloc(SAY_MAX); channel = malloc(SAY_MAX); if (channel == NULL || command == NULL){ printf("Issue allocating space for tokens"); bad_exit(); } message = malloc(MESSAGE_MAX); // allocate message which will be repeatedly sent to server if (message == NULL){ printf("Error occurred durring malloc"); bad_exit(); } // (1) Client Initialization // verfiy input params if (argc != 4){ printf("Usage: %s <domain/address> <port> <username>\n", argv[0]); bad_exit(); } // name input params domain = argv[1]; port = argv[2]; uname = argv[3]; // make sure domain path is not too long #ifdef UNIX_PATH_MAX if ( (strlen(domain) + 1) > UNIX_PATH_MAX){ printf("Exceeded unix-path-max for domain. \n " "Please enter a different server name. \n"); bad_exit(); } #endif // initialize hints for call to getaddrinfo memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; // INET/INET6 capable hints.ai_socktype = SOCK_DGRAM; // attempt getaddrinfo on the provided server ret = getaddrinfo(domain, port, &hints, &serv); if (ret != 0){ printf("Error occurred during getaddrinfo: errorcode(%d)\n",ret); bad_exit(); } // attempt to create our socket matching the addrinfo given sockfd = -1; servIter = serv; while(sockfd == -1 && servIter != NULL ){ sockfd = socket(servIter->ai_family, servIter->ai_socktype, servIter->ai_protocol); if (sockfd == -1) servIter = servIter->ai_next; } if (sockfd == -1){ printf("Could not establish socket: %s\n", strerror(errno)); bad_exit(); } if(servIter == NULL){ printf("Could not establish socket. \nIs the server online?\n"); bad_exit(); } serv = servIter; // (2) User Login and Channel join // pack login request ret = packRequest(message, REQ_LOGIN, NULL, NULL, uname); if (ret == -1){ printf("Error packing request\n"); bad_exit(); } // send login request ret = sendRequest(sockfd, serv, message); if (ret == -1){ printf("Error sending request\n"); bad_exit(); } // pack join request ret = packRequest(message, REQ_JOIN, activeChannel, NULL, NULL); if (ret == -1){ printf("Error packing request\n"); bad_exit(); } // send join request ret = sendRequest(sockfd, serv, message); if (ret == -1){ printf("Error sending request\n"); bad_exit(); } // (3, 4, 5) Main event loop ret = raw_mode(); if (ret != 0){ printf("Issue entering raw mode"); bad_exit(); } // promt the user for input printf(">"); fflush(NULL); while(1){//begin Main event loop // (3) Get user input memset(inputBuf, '\0', SAY_MAX); memset(sayBuf, '\0', SAY_MAX); i = 0; inputChar = '\0'; // main loop to collect user input and server messages while(1){ // setup for call to select FD_ZERO(&read_fdset); FD_SET(STDIN, &read_fdset); FD_SET(sockfd, &read_fdset); ret = select(sockfd+1, &read_fdset, NULL, NULL, NULL); // read from server if(FD_ISSET(sockfd, &read_fdset)){ ret = recvfrom(sockfd, consoleBuf, TEXT_MAX, 0, (serv->ai_addr), &(serv->ai_addrlen)); if (ret == -1){ printf("Error occurred during read from server: %s\n", strerror(errno)); bad_exit(); } printf(" \r"); ret = parseServer(consoleBuf); #ifdef DEBUG if (ret == -1) printf("Server sent nonstandard message\n"); #endif /* DEBUG */ // promt the user for input printf("\r>%s",inputBuf); fflush(NULL); // read from stdin }else if(FD_ISSET(STDIN, &read_fdset)){ ret = read(STDIN, &inputChar, CHAR_AMOUNT); if (ret == -1){ printf("Error occurred during user input: %s\n", strerror(errno)); bad_exit(); } if (inputChar == '\n'){ break; }else if (i >= SAY_MAX - 1){ // if have read full amount, wait for \n continue; }else{ inputBuf[i] = inputChar; printf("\r>%s",inputBuf); fflush(NULL); i++; } // default case }else{ if (ret == -1){ perror("Error during select"); bad_exit(); } } } strncpy(sayBuf, inputBuf, strlen(inputBuf)); // (4) Parse user input command = strtok(inputBuf, " "); channel = strtok(NULL, ""); // if we are given a channel, make sure it is not too long if(channel != NULL) channel[CHANNEL_MAX-1]='\0'; if(sayBuf[0] == '/' ){ // implies command if(strcmp("/exit", command) == 0){ // pack the message for logout ret = packRequest(message, REQ_LOGOUT, NULL, NULL, NULL); if (ret == -1){ printf("Error from packRequest\n"); bad_exit(); } // halt the client successfully clean_exit(); }else if(strcmp("/join", command) == 0){ // check the channel parameter if (channel == NULL) goto UNKNOWN_COMMAND; // run through our stack to make sure we have not already // added the channel 'channel' for( i=0 ; i < activeChannelIndex ; i++){ if( strcmp(channel, channels[i]) == 0 ){ // have this channel already break; } } // resulting from the previous check, we know that we have // not yet seen this in our stack if( strcmp(channel, channels[i]) != 0 ){ // bound check on our active channels if (activeChannelIndex >= CHANNEL_COUNT){ printf("You have joined the maximum allowed number of channels: %d", CHANNEL_COUNT); continue; } // add the channel requested to our channels array strncpy( channels[activeChannelIndex], channel, CHANNEL_MAX); activeChannelIndex++; } // pack the message for join ret = packRequest(message, REQ_JOIN, channel, NULL, NULL); if (ret == -1){ printf("Error from packRequest\n"); bad_exit(); } }else if(strcmp("/leave", command) == 0){ // uses token 2 // check the channel parameter if (channel == NULL) goto UNKNOWN_COMMAND; // see if we are leaving the active channel if (strcmp(activeChannel, channel) == 0) memset(activeChannel, 0, CHANNEL_MAX); // step through our stack of channels to see if the one // the user asked to leave exists for( i=0 ; i < activeChannelIndex ; i++){ // if the channel does exist in our channels array if( strcmp(channel, channels[i]) == 0 ){ // swap the last item on the stack with the one that needs // to be removed, then remove the bottom item strncpy(channels[i], channels[activeChannelIndex-1], CHANNEL_MAX); memset(channels[activeChannelIndex-1], 0, CHANNEL_MAX); activeChannelIndex--; break; } } // pack the message for leave ret = packRequest(message, REQ_LEAVE, channel, NULL, NULL); if (ret == -1){ printf("Error from packRequest\n"); bad_exit(); } }else if(strcmp("/list", command) == 0){ // pack the message for list ret = packRequest(message, REQ_LIST, NULL, NULL, NULL); if (ret == -1){ printf("Error from packRequest\n"); bad_exit(); } }else if(strcmp("/who", command) == 0){ // check token 2 // check the channel parameter if (channel == NULL) goto UNKNOWN_COMMAND; // pack the message for who ret = packRequest(message, REQ_WHO, channel, NULL, NULL); if (ret == -1){ printf("Error from packRequest\n"); bad_exit(); } }else if(strcmp("/switch", command) == 0){ // check token 2 // check the channel parameter if (channel == NULL) goto UNKNOWN_COMMAND; // checks through for( i=0 ; i < activeChannelIndex ; i++){ if( strcmp(channel, channels[i]) == 0 ){ // modify our local activeChannel to be the one requested strncpy(activeChannel, channel, CHANNEL_MAX); break; } } // let the user know the result of the switch if (strcmp(channel, activeChannel) != 0) printf("You have not subscribed to the channel %s\n", channel); // do not pack a request to send so continue continue; }else{ //wrong UNKNOWN_COMMAND: // inform the client user the command is not valid printf("*Unkown command\n"); printf(">"); fflush(NULL); // do not pack a request to send so continue continue; } }else{ // implies say message // make sure we are not trying to send to a nonexistant channel if (strcmp(activeChannel, "") == 0) continue; ret = packRequest(message, REQ_SAY, activeChannel, sayBuf, NULL); if (ret == -1){ printf("Error from packRequest\n"); bad_exit(); } } // (5) Send client message to server ret = sendRequest(sockfd, serv, message); if (ret == -1){ printf("Error during sendRequest\n"); bad_exit(); } }//end Main event loop // should never get here bad_exit(); }