/****************************************************************************** * This file is part of a software distribution, which is furnished under the * * terms of a license. Use of this software by any means is subject to this * * license and signifies the acceptance of the licensing terms stated * * therein. Please see the file LICENSE in the top-level directory of this * * software distribution for detailed copyright disclaimers and licensing * * terms. * ****************************************************************************** * Copryight (c) by Andreas S. Wetzel - All rights reserved. * ******************************************************************************/ /* $Id: vc_main.c,v 1.2 2001/03/19 14:54:04 mickey Exp $ */ #include #include #include #include #include /******* Globals ********/ char *prog_name; char nlstr[] = "\n"; VP vp; VCONN sconn; extern ED *ed; extern VTCAP vtcap; /********* Code *********/ int main(int argc, char *argv[]) { u_char pwdbuf[VPPASSWDSIZE+1]; u_char *offmsg = NULL; u_int len; int ret; #if HAVE_SIGACTION struct sigaction sa; #else struct sigvec sv; #endif BZERO(&vp, sizeof(VP)); if((prog_name = (char *)strrchr(argv[0], '/')) != NULL) prog_name++; else prog_name = argv[0]; /* * 1] Initialize and set default parameters. * 2] Lookout for user's .vchatrc * 3] Gather and process commandline arguments. * 4] Load and process termcap database entry. * 5] Init tty settings. */ if(init()) return(-1); vchatrc_load(); if(get_param(argc, argv) || init_vtcap()) return(-1); /* * Switch terminal to CBREAK mode */ tty_mode(1); /* * Request password */ printf("\nEnter password for '%s' at server %s\n", vp.nick, iptoname(vp.sv_ip)); printf("If you do not have a password, just press ENTER\n\n"); printf("Password: "); fflush(stdout); BZERO(pwdbuf, VPPASSWDSIZE+1); read_string(pwdbuf, VPPASSWDSIZE, 0); printf("\n"); /* * Init ok - connect to server */ printf("\nTrying %s:%d...", inet_ntoa(vp.sv_ip), vp.sv_port); ret = connect_server(&sconn, &vp.sv_ip, vp.sv_port, VSERVER_MAGIC, pwdbuf); BZERO(pwdbuf, VPPASSWDSIZE+1); switch(ret) { case -1: { printf("\nConnect failed (%s)\n\n", strerror(errno)); return(-1); } case CONN_OK: { break; } default: { printf("\n%s\n\n", v_error(ret)); return(-1); } } /* * Get local hostname from the connected peer */ { struct sockaddr_in local_addr; int addrlen = sizeof(struct sockaddr_in); if(GETSOCKNAME(sconn.fd, &local_addr, &addrlen) == -1) { local_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); } vp.my_ip = local_addr.sin_addr; } /* * Initialize command history buffer */ history_init(); /* * Switch to META mode if possible */ if(vtcap.metamode_on) tputs(vtcap.metamode_on, 1, (void *)outc); /* * Switch cursor keys to application mode */ keymode(1); /* * Initialize statusline and screen */ init_status(); screen_init(); /* * Get any information already waiting on socket */ rcv_sv_msg(); /* * Initialize async i/o, timer event and * window size change handlers. */ pbc_disable(); v_io_init(); v_timer_init(); v_winch_init(); /* * We will silently ignore SIGINT as * well as SIGQUIT for this session. */ #if HAVE_SIGACTION sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGINT, &sa, NULL); sigaction(SIGTSTP, &sa, NULL); #else sv.sv_handler = SIG_IGN; sigemptyset(&sv.sv_mask); sv.sv_flags = 0; sigvec(SIGINT, &sv, NULL); sigvec(SIGTSTP, &sv, NULL); #endif /* * Add a 1 sec delay to catch a SUBMIT_TOPIC message * the server possibly sends before we are stuck in * the input_line() function. This is to avoid loosing * the first character after a topic has been entered. */ vsleep(1,0); /* * Main loop. * Get user input and handle commands */ for(;;) { /* * Get user input */ clear_ed(ed); uinp: len = input_line(NULL, 0, (ED_HISTORY)); if(!len) /*** NULL input ***/ { continue; } else if(len == -2) /*** HISTORY UP ***/ { /* * If we are at end of history then we will have * to save the contents of the current input line * (if any) in order to have the ability to scroll * back down to this line. In any case the buffer * indexed by vp.history_next must be freed if it * has already been in use. */ if(vp.history_current == vp.history_next) { /* * Free current buffer if already used */ if(vp.history[vp.history_next] != NULL) { free(vp.history[vp.history_next]); vp.history[vp.history_next] = NULL; } /* * If the input line was not empty to the * time when the user pressed the HISTORY * UP key then save it into the current * history position, so that we can scroll * down back to it later. */ len = strlen(ed->buffer); if(len) { u_char *newbuf; /* * Allocate a new buffer */ if((newbuf = (u_char *)calloc(1, len+1)) != NULL) { strncpy(newbuf, ed->buffer, len); vp.history[vp.history_next] = newbuf; } } } /* * Shift current position up one place */ if(vp.history_current == 0) vp.history_current = (vp.history_lines - 1); else --vp.history_current; /* * Copy history buffer into current input * buffer and re-edit this line */ clear_ed(ed); strcpy(ed->buffer, vp.history[vp.history_current]); ed->endpos += strlen(ed->buffer); ed->curpos = ed->endpos; if((ed->endpos - ed->margin) >= vtcap.cols) ed->margin = (ed->endpos - (vtcap.cols - 1)); goto uinp; } else if(len == -4) /*** HISTORY DOWN ***/ { /* * Shift current position one place down */ if(++vp.history_current >= vp.history_lines) vp.history_current = 0; /* * Copy history buffer into current input buffer */ clear_ed(ed); if(vp.history[vp.history_current] != NULL) { strcpy(ed->buffer, vp.history[vp.history_current]); ed->endpos += strlen(ed->buffer); ed->curpos = ed->endpos; if((ed->endpos - ed->margin) >= vtcap.cols) ed->margin = (ed->endpos - (vtcap.cols - 1)); } goto uinp; } /* * Save commandline in history buffer */ history_save(ed->buffer); /* * Process user input */ if(ed->buffer[0] == '.' && ed->buffer[1] != 'x') { handle_cmd(ed->buffer); } else if(ED_USED == 2 && ed->buffer[0] == '.' && ed->buffer[1] == 'x') { break; } else if(ED_USED > 2 && ed->buffer[0] == '.' && ed->buffer[1] == 'x' && ed->buffer[2] == ' ') { offmsg = &ed->buffer[3]; break; } else { snd_serv(CMD_PUBMSG, ed->buffer, len); } } /* * Disable asynchronous I/O, send * signoff command and exit program */ v_io_end(); snd_serv(CMD_SIGNOFF, offmsg, (offmsg) ? strlen(offmsg) : 0); vquit("Have a nice day ..."); /*** UNREACHED ***/ return(0); }