#include #include #include "common_bufsiz.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "misc.h" #include "global.h" #include "transfer.h" #include #ifdef __BIONIC__ /* should be in arpa/telnet.h */ # define IAC 255 /* interpret as command: */ # define DONT 254 /* you are not to use option */ # define DO 253 /* please, you use option */ # define WONT 252 /* I won't use option */ # define WILL 251 /* I will use option */ # define SB 250 /* interpret as subnegotiation */ # define SE 240 /* end sub negotiation */ # define TELOPT_ECHO 1 /* echo */ # define TELOPT_SGA 3 /* suppress go ahead */ # define TELOPT_TTYPE 24 /* terminal type */ # define TELOPT_NAWS 31 /* window size */ #endif enum { DATABUFSIZE = 128, IACBUFSIZE = 128, CHM_TRY = 0, CHM_ON = 1, CHM_OFF = 2, UF_ECHO = 0x01, UF_SGA = 0x02, TS_NORMAL = 0, TS_COPY = 1, TS_IAC = 2, TS_OPT = 3, TS_SUB1 = 4, TS_SUB2 = 5, TS_CR = 6, }; typedef unsigned char byte; enum { netfd = 3 }; struct globals { int iaclen; /* could even use byte, but it's a loss on x86 */ byte telstate; /* telnet negotiation state from network input */ byte telwish; /* DO, DONT, WILL, WONT */ byte charmode; byte telflags; byte do_termios; #if ENABLE_FEATURE_TELNET_TTYPE char *ttype; #endif #if ENABLE_FEATURE_TELNET_AUTOLOGIN const char *autologin; #endif #if ENABLE_FEATURE_TELNET_WIDTH unsigned win_width, win_height; #endif /* same buffer used both for network and console read/write */ char buf[DATABUFSIZE]; /* buffer to handle telnet negotiations */ char iacbuf[IACBUFSIZE]; struct termios termios_def; struct termios termios_raw; } FIX_ALIASING; #define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ setup_common_bufsiz(); \ BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ } while (0) static void rawmode(void); static void cookmode(void); static void do_linemode(void); static void will_charmode(void); static void telopt(byte c); static void subneg(byte c); void draw_statusbar(void); int pbmenu(void); int quit(); static void iac_flush(void) { full_write(netfd, G.iacbuf, G.iaclen); G.iaclen = 0; } static void doexit(int ev) NORETURN; static void doexit(int ev) { cookmode(); exit(ev); } static void con_escape(void) { char b; if (bb_got_signal) /* came from line mode... go raw */ rawmode(); if (read(STDIN_FILENO, &b, 1) <= 0) doexit(EXIT_FAILURE); switch (b) { case 'd': system("rz -Z"); break; case 'l': if (!bb_got_signal) { do_linemode(); goto ret; } break; case 'c': if (bb_got_signal) { will_charmode(); goto ret; } break; case 'z': cookmode(); kill(0, SIGTSTP); rawmode(); break; case 'e': doexit(EXIT_SUCCESS); } if (bb_got_signal) cookmode(); ret: bb_got_signal = 0; } static void handle_net_output(int len) { byte outbuf[2 * DATABUFSIZE]; byte *dst = outbuf; byte *src = (byte*)G.buf; byte *end = src + len; while (src < end) { byte c = *src++; if (c == 0x1d) { //con_escape(); return; } *dst = c; if (c == IAC) *++dst = c; /* IAC -> IAC IAC */ else if (c == '\r' || c == '\n') { /* Enter key sends '\r' in raw mode and '\n' in cooked one. * * See RFC 1123 3.3.1 Telnet End-of-Line Convention. * Using CR LF instead of other allowed possibilities * like CR NUL - easier to talk to HTTP/SMTP servers. */ *dst = '\r'; /* Enter -> CR LF */ *++dst = '\n'; } dst++; } if (dst - outbuf != 0) full_write(netfd, outbuf, dst - outbuf); } static void handle_net_input(int len) { int i; int cstart = 0; for (i = 0; i < len; i++) { byte c = G.buf[i]; if (G.telstate == TS_NORMAL) { /* most typical state */ if (c == IAC) { cstart = i; G.telstate = TS_IAC; } else if (c == '\r') { cstart = i + 1; G.telstate = TS_CR; } /* No IACs were seen so far, no need to copy * bytes within G.buf: */ continue; } switch (G.telstate) { case TS_CR: /* Prev char was CR. If cur one is NUL, ignore it. * See RFC 1123 section 3.3.1 for discussion of telnet EOL handling. */ G.telstate = TS_COPY; if (c == '\0') break; /* else: fall through - need to handle CR IAC ... properly */ case TS_COPY: /* Prev char was ordinary */ /* Similar to NORMAL, but in TS_COPY we need to copy bytes */ if (c == IAC) G.telstate = TS_IAC; else G.buf[cstart++] = c; if (c == '\r') G.telstate = TS_CR; break; case TS_IAC: /* Prev char was IAC */ if (c == IAC) { /* IAC IAC -> one IAC */ G.buf[cstart++] = c; G.telstate = TS_COPY; break; } /* else */ switch (c) { case SB: G.telstate = TS_SUB1; break; case DO: case DONT: case WILL: case WONT: G.telwish = c; G.telstate = TS_OPT; break; /* DATA MARK must be added later */ default: G.telstate = TS_COPY; } break; case TS_OPT: /* Prev chars were IAC WILL/WONT/DO/DONT */ telopt(c); G.telstate = TS_COPY; break; case TS_SUB1: /* Subnegotiation */ case TS_SUB2: /* Subnegotiation */ subneg(c); /* can change G.telstate */ break; } } if (G.telstate != TS_NORMAL) { /* We had some IACs, or CR */ if (G.iaclen) iac_flush(); if (G.telstate == TS_COPY) /* we aren't in the middle of IAC */ G.telstate = TS_NORMAL; len = cstart; } if (len) full_write(STDOUT_FILENO, G.buf, len); } static void put_iac(int c) { G.iacbuf[G.iaclen++] = c; } static void put_iac2_merged(unsigned wwdd_and_c) { if (G.iaclen + 3 > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(wwdd_and_c >> 8); put_iac(wwdd_and_c & 0xff); } #define put_iac2(wwdd,c) put_iac2_merged(((wwdd)<<8) + (c)) #if ENABLE_FEATURE_TELNET_TTYPE static void put_iac_subopt(byte c, char *str) { int len = strlen(str) + 6; // ( 2 + 1 + 1 + strlen + 2 ) if (G.iaclen + len > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(SB); put_iac(c); put_iac(0); while (*str) put_iac(*str++); put_iac(IAC); put_iac(SE); } #endif #if ENABLE_FEATURE_TELNET_AUTOLOGIN static void put_iac_subopt_autologin(void) { int len = strlen(G.autologin) + 6; // (2 + 1 + 1 + strlen + 2) const char *p = "USER"; if (G.iaclen + len > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(SB); put_iac(TELOPT_NEW_ENVIRON); put_iac(TELQUAL_IS); put_iac(NEW_ENV_VAR); while (*p) put_iac(*p++); put_iac(NEW_ENV_VALUE); p = G.autologin; while (*p) put_iac(*p++); put_iac(IAC); put_iac(SE); } #endif #if ENABLE_FEATURE_TELNET_WIDTH static void put_iac_naws(byte c, int x, int y) { if (G.iaclen + 9 > IACBUFSIZE) iac_flush(); put_iac(IAC); put_iac(SB); put_iac(c); /* "... & 0xff" implicitly done below */ put_iac(x >> 8); put_iac(x); put_iac(y >> 8); put_iac(y); put_iac(IAC); put_iac(SE); } #endif static void setConMode(void) { if (G.telflags & UF_ECHO) { if (G.charmode == CHM_TRY) { G.charmode = CHM_ON; rawmode(); } } else { if (G.charmode != CHM_OFF) { G.charmode = CHM_OFF; cookmode(); } } } static void will_charmode(void) { G.charmode = CHM_TRY; G.telflags |= (UF_ECHO | UF_SGA); setConMode(); put_iac2(DO, TELOPT_ECHO); put_iac2(DO, TELOPT_SGA); iac_flush(); } static void do_linemode(void) { G.charmode = CHM_TRY; G.telflags &= ~(UF_ECHO | UF_SGA); setConMode(); put_iac2(DONT, TELOPT_ECHO); put_iac2(DONT, TELOPT_SGA); iac_flush(); } static void to_notsup(char c) { if (G.telwish == WILL) put_iac2(DONT, c); else if (G.telwish == DO) put_iac2(WONT, c); } static void to_echo(void) { /* if server requests ECHO, don't agree */ if (G.telwish == DO) { put_iac2(WONT, TELOPT_ECHO); return; } if (G.telwish == DONT) return; if (G.telflags & UF_ECHO) { if (G.telwish == WILL) return; } else if (G.telwish == WONT) return; if (G.charmode != CHM_OFF) G.telflags ^= UF_ECHO; if (G.telflags & UF_ECHO) put_iac2(DO, TELOPT_ECHO); else put_iac2(DONT, TELOPT_ECHO); setConMode(); full_write1_str("\r\n"); /* sudden modec */ } static void to_sga(void) { /* daemon always sends will/wont, client do/dont */ if (G.telflags & UF_SGA) { if (G.telwish == WILL) return; } else if (G.telwish == WONT) return; G.telflags ^= UF_SGA; /* toggle */ if (G.telflags & UF_SGA) put_iac2(DO, TELOPT_SGA); else put_iac2(DONT, TELOPT_SGA); } #if ENABLE_FEATURE_TELNET_TTYPE static void to_ttype(void) { /* Tell server we will (or won't) do TTYPE */ if (G.ttype) put_iac2(WILL, TELOPT_TTYPE); else put_iac2(WONT, TELOPT_TTYPE); } #endif #if ENABLE_FEATURE_TELNET_AUTOLOGIN static void to_new_environ(void) { /* Tell server we will (or will not) do AUTOLOGIN */ if (G.autologin) put_iac2(WILL, TELOPT_NEW_ENVIRON); else put_iac2(WONT, TELOPT_NEW_ENVIRON); } #endif #if ENABLE_FEATURE_TELNET_WIDTH static void to_naws(void) { /* Tell server we will do NAWS */ put_iac2(WILL, TELOPT_NAWS); } #endif static void telopt(byte c) { switch (c) { case TELOPT_ECHO: to_echo(); break; case TELOPT_SGA: to_sga(); break; #if ENABLE_FEATURE_TELNET_TTYPE case TELOPT_TTYPE: to_ttype(); break; #endif #if ENABLE_FEATURE_TELNET_AUTOLOGIN case TELOPT_NEW_ENVIRON: to_new_environ(); break; #endif #if ENABLE_FEATURE_TELNET_WIDTH case TELOPT_NAWS: to_naws(); put_iac_naws(c, G.win_width, G.win_height); break; #endif default: to_notsup(c); break; } } /* subnegotiation -- ignore all (except TTYPE,NAWS) */ static void subneg(byte c) { switch (G.telstate) { case TS_SUB1: if (c == IAC) G.telstate = TS_SUB2; #if ENABLE_FEATURE_TELNET_TTYPE else if (c == TELOPT_TTYPE && G.ttype) put_iac_subopt(TELOPT_TTYPE, G.ttype); #endif #if ENABLE_FEATURE_TELNET_AUTOLOGIN else if (c == TELOPT_NEW_ENVIRON && G.autologin) put_iac_subopt_autologin(); #endif break; case TS_SUB2: if (c == SE) { G.telstate = TS_COPY; return; } G.telstate = TS_SUB1; break; } } static void rawmode(void) { if (G.do_termios) tcsetattr(0, TCSADRAIN, &G.termios_raw); } static void cookmode(void) { if (G.do_termios) tcsetattr(0, TCSADRAIN, &G.termios_def); } int pbtelnet(const char *name, const char *address, const char *portnum) MAIN_EXTERNALLY_VISIBLE; int pbtelnet(const char *name, const char *address, const char *portnum) { char *host; int port; int len; struct pollfd ufds[2]; INIT_G(); #if ENABLE_FEATURE_TELNET_TTYPE G.ttype = getenv("TERM"); #endif if (tcgetattr(0, &G.termios_def) >= 0) { G.do_termios = 1; G.termios_raw = G.termios_def; cfmakeraw(&G.termios_raw); } host = address; port = portnum; message("Connected!", 1); wrefresh(win); xmove_fd(create_and_connect_stream_or_die(host, port), netfd); setsockopt_keepalive(netfd); startup(); puts(""); if (use_sbar) draw_statusbar(); signal(SIGINT, record_signo); ufds[0].fd = STDIN_FILENO; ufds[0].events = POLLIN; ufds[1].fd = netfd; ufds[1].events = POLLIN; while (1) { if (poll(ufds, 2, -1) < 0) { /* error, ignore and/or log something, bay go to loop */ } // FIXME: reads can block. Need full bidirectional buffering. if (ufds[0].revents) { len = safe_read(STDIN_FILENO, G.buf, DATABUFSIZE); if (len <= 0) doexit(EXIT_SUCCESS); handle_net_output(len); } if (ufds[1].revents) { len = safe_read(netfd, G.buf, DATABUFSIZE); if (len <= 0) { system("clear"); pbmenu(); main(); full_write1_str("Connection closed by foreign host\r\n"); doexit(EXIT_FAILURE); } handle_net_input(len); } } /* while (1) */ } /////////// variables ///////////////////////////// const int maxQuestionID = 4; int cmdKey = 0; int questionID = 0; /////////// end variables ///////////////////////// /////////// init function ///////////////////////// void init() { putenv("TERM=pcansi-25"); printf("\033(U"); initscr(); raw(); echo(); keypad(stdscr, TRUE); use_sbar = (LINES > 24) ? 1 : 0; /* only use statbar on big terms */ win = newwin(screenlen, COLS, 0, 0); /* configurable later? */ wrefresh(win); init_pair(1, COLOR_BLACK, COLOR_CYAN); start_color(); } ///////////// end init //////////////////////////// ///////////// main screen ///////////////////////// int main() { system("stty raw"); system("stty columns 80 rows 25"); ifdirexists(); makedirs(); init(); intro(); const char *questions[] = {"\e[22;1H\e[1;30m[\e[1;34;44mAdd BBS\e[0;37m\e[1;30m] \e[0;37mDelete BBS Display Phonebook Search Phonebook Exit Phonebook ", "\e[22;1H\e[0;37m Add BBS \e[1;30m[\e[1;34;44mDelete BBS\e[0;37m\e[1;30m]\e[0;37m Display Phonebook Search Phonebook Exit Phonebook ", "\e[22;1H\e[0;37m Add BBS Delete BBS \e[1;30m[\e[1;34;44mDisplay Phonebook\e[0;37m\e[1;30m]\e[0;37m Search Phonebook Exit Phonebook ", "\e[22;1H\e[0;37m Add BBS Delete BBS Display Phonebook \e[0;37m\e[1;30m[\e[1;34;44mSearch Phonebook\e[0;37m\e[1;30m]\e[0;37m Exit Phonebook ", "\e[22;1H\e[0;37m Add BBS Delete BBS Display Phonebook Search Phonebook \e[1;30m[\e[1;34;44mExit Phonebook\e[0;37m\e[1;30m]\e[0;37m"}; while (cmdKey != 13) { int cmdKey = getchar(); switch(cmdKey) { case 68: // left if (questionID > 0) questionID--; break; case 67: // right if (questionID < maxQuestionID) questionID++; break; case 100: // alt-d init(); refresh(); pbmenu(); break; case 116: // alt-t system("clear"); refresh(); telnet(); break; case 13: if (questionID == 0) { init(); refresh(); phonebook(); add_contact(); break; } else if (questionID == 1) { init(); refresh(); phonebook(); delete_contact(); break; } else if (questionID == 2) { init(); system("clear"); refresh(); pbmenu(); break; } else if (questionID == 3) { init(); refresh(); phonebook(); search_contact(); break; } else if (questionID == 4) { quit(); break; } } printf("%s\n", questions[questionID]); } } //////////// end main screen ////////////////////// //////////// begin quit function ////////////////// int quit() { system("stty columns 80 rows 25"); exit(1); return 0; } /////////// end quit function ///////////////////// /////////// begin menu system ///////////////////// /////////// begin phonebook ////////////////////// int add_contact(); int search_contact(); int delete_contact(); int view_all_contact(); int add_contact() { if (chdir(getenv("HOME")) == 0) { FILE *fp; fp=fopen(".igterm/hosts.txt","a+"); puts("\e[6;01H "); puts("\e[6;01H\e[1;34mBBS Name : "); puts("\e[6;01H\e[1;34mBBS Name : \e[0;37m" ); puts("\e[2A"); char *name; scanw("%m[^\n]s",&name); FILE *fp2; fp2=fopen(".igterm/hosts2.txt","a+"); puts("\e[7;01H "); puts("\e[7;01H\e[1;34mBBS Address : "); puts("\e[7;01H\e[1;34mBBS Address : \e[0;37m" ); puts("\e[2A"); char address[200]; scanw("%s",address); FILE *fp3; fp3=fopen(".igterm/hosts3.txt","a+"); puts("\e[8;01H "); puts("\e[8;01H\e[1;34mPort "); puts("\e[8;01H\e[1;34mPort : \e[0;37m" ); puts("\e[2A"); char port[10]; scanw("%s",port); fprintf(fp,"%s %s %s\n",name,address,port); fprintf(fp2,"%s\n",address); fprintf(fp3,"%s\n",port); fclose(fp); fclose(fp2); fclose(fp3); } } int search_contact() { FILE *fp; fp=fopen(".igterm/hosts.txt","r"); puts("\e[6;01H "); puts("\e[6;01H "); puts("\e[6;01H\e[1;34mSearch : "); puts("\e[6;01H\e[1;34mSearch : \e[0;37m"); puts("\e[2A"); char name[200]; scanw("%s",name); char name1[200],mob[20]; while(fscanf(fp,"%s",name1)!=EOF) { if(strcmp(name,name1)==0) { printf("\e[7;01H "); printf("\e[7;01H\e[1;34mAddress : ",name1); printf("\e[7;01H\e[1;34mAddress : \e[0;37m%s\n",name1); } } fclose(fp); } int delete_contact() { if (chdir(getenv("HOME")) == 0) { FILE *fp,*fp1; fp=fopen(".igterm/hosts2.txt","r+"); fp1=fopen(".igterm/temp.txt","w"); puts("\e[6;01H\e[1;34mDelete which : \e[0;37m"); puts("\e[2A"); char name[200]; scanw("%s",name); char name1[200]; while(fscanf(fp,"%s",name1)!=EOF) { if(strcmp(name,name1)==0) { continue; } fprintf(fp1,"%s\n",name1); } fclose(fp); fclose(fp1); fp=fopen(".igterm/hosts2.txt","w"); fp1=fopen(".igterm/temp.txt","r"); while(fscanf(fp1,"%s",name1)!=EOF) { fprintf(fp,"%s\n",name1); } fclose(fp); fclose(fp1); remove(".igterm/temp.txt"); } } int view_all_contact() { if (chdir(getenv("HOME")) == 0) { FILE *fp; fp=fopen(".igterm/hosts.txt","r"); char name1[200],mob[20]; while(fscanf(fp,"%s %s",name1,mob)!=EOF) { printf(" \e[1;34mName : \e[0;37m%s\n",name1); printf(" \e[1;34mAddress : \e[0;37m%s",mob); } fclose(fp); } } /////////// end phonebook //////////////////////////// void chomp(char *str) { int len=strlen(str); if(len>0) while((len>0) && isspace(str[len-1])) str[--len]='\0'; } int pbmenu(void) { char buf[128]; int row=8,col=2,arraylength=0,width=70, menulength=10,selection; header(); char **testarray=NULL; FILE *fp=fopen(".igterm/hosts.txt","r"); while(fgets(buf,128,fp) != NULL) { chomp(buf); // Remove \n from end of line if(strlen(buf) > width) width=strlen(buf); if(!buf[0]) continue; // Ignore blank lines arraylength++; // Room for n+1 elements of char * size. testarray=realloc(testarray, sizeof(char *)*(arraylength+1)); // strdup is an easy str=malloc(strlen(s)+1); strcpy(str,s); testarray[arraylength-1]=strdup(buf); } // The +1 gives us room for a NULL on the end. Makes it easier to find crashes. testarray[arraylength]=NULL; fclose(fp); // If no elements were loaded, it will still be NULL if(testarray == NULL) { fprintf(stderr, "Unable to load options\n"); exit(1); } /////////////////////////// char buf2[128]; int arraylength2=0; char **testarray2=NULL; FILE *fp2=fopen(".igterm/hosts2.txt","r"); while(fgets(buf2,128,fp2) != NULL) { chomp(buf2); // Remove \n from end of line if(strlen(buf2) > width) width=strlen(buf2); if(!buf2[0]) continue; // Ignore blank lines arraylength2++; // Room for n+1 elements of char * size. testarray2=realloc(testarray2, sizeof(char *)*(arraylength2+1)); // strdup is an easy str=malloc(strlen(s)+1); strcpy(str,s); testarray2[arraylength2-1]=strdup(buf2); } // The +1 gives us room for a NULL on the end. Makes it easier to find crashes. testarray2[arraylength2]=NULL; fclose(fp2); // If no elements were loaded, it will still be NULL if(testarray2 == NULL) { fprintf(stderr, "Unable to load options\n"); exit(1); } /////////////////////////// char buf3[128]; int arraylength3=0; char **testarray3=NULL; FILE *fp3=fopen(".igterm/hosts3.txt","r"); while(fgets(buf3,128,fp3) != NULL) { chomp(buf3); // Remove \n from end of line if(strlen(buf3) > width) width=strlen(buf3); if(!buf3[0]) continue; // Ignore blank lines arraylength3++; // Room for n+1 elements of char * size. testarray3=realloc(testarray3, sizeof(char *)*(arraylength3+1)); // strdup is an easy str=malloc(strlen(s)+1); strcpy(str,s); testarray3[arraylength3-1]=strdup(buf3); } // The +1 gives us room for a NULL on the end. Makes it easier to find crashes. testarray3[arraylength3]=NULL; fclose(fp3); // If no elements were loaded, it will still be NULL if(testarray3 == NULL) { fprintf(stderr, "Unable to load options\n"); exit(1); } /////////////////////////// initscr(); noecho(); keypad(stdscr,TRUE); selection=barmenu((const char const **)testarray,row,col,arraylength,width,menulength,0); if (selection == 0) pbtelnet(testarray[0], testarray2[0], 24); if (selection == 1) pbtelnet(testarray[1], testarray2[1], 26); if (selection == 2) pbtelnet(testarray[2], testarray2[2], 28); if (selection == 3) pbtelnet(testarray[3], testarray2[3], 30); if (selection == 4) pbtelnet(testarray[4], testarray2[4], 23); if (selection == 5) pbtelnet(testarray[5], testarray2[5], 23); if (selection == 6) pbtelnet(testarray[6], testarray2[6], 23); if (selection == 7) pbtelnet(testarray[7], testarray2[7], 23); if (selection == 8) pbtelnet(testarray[8], testarray2[8], 23); if (selection == 9) pbtelnet(testarray[9], testarray2[9], 23); if (selection == 10) pbtelnet(testarray[10], testarray2[10], 23); if (selection == 11) pbtelnet(testarray[11], testarray2[11], 23); if (selection == 12) pbtelnet(testarray[12], testarray2[12], 23); if (selection == 13) pbtelnet(testarray[13], testarray2[13], 23); if (selection == 14) pbtelnet(testarray[14], testarray2[14], 23); if (selection == 15) pbtelnet(testarray[15], testarray2[15], 23); if (selection == 16) pbtelnet(testarray[16], testarray2[16], 23); if (selection == 17) pbtelnet(testarray[17], testarray2[17], 23); if (selection == 18) pbtelnet(testarray[18], testarray2[18], 23); if (selection == 19) pbtelnet(testarray[19], testarray2[19], 23); if (selection == 20) pbtelnet(testarray[20], testarray2[20], 23); if (selection == 21) pbtelnet(testarray[21], testarray2[21], 23); if (selection == 22) pbtelnet(testarray[22], testarray2[22], 23); if (selection == 23) pbtelnet(testarray[23], testarray2[23], 23); if (selection == 24) pbtelnet(testarray[24], testarray2[24], 23); if (selection == 25) pbtelnet(testarray[25], testarray2[25], 23); if (selection == 26) pbtelnet(testarray[26], testarray2[26], 23); if (selection == 27) pbtelnet(testarray[27], testarray2[27], 23); if (selection == 28) pbtelnet(testarray[28], testarray2[28], 23); if (selection == 29) pbtelnet(testarray[29], testarray2[29], 23); if (selection == 30) pbtelnet(testarray[30], testarray2[30], 23); if (selection == 31) pbtelnet(testarray[31], testarray2[31], 23); if (selection == 32) pbtelnet(testarray[32], testarray2[32], 23); if (selection == 33) pbtelnet(testarray[33], testarray2[33], 23); if (selection == 34) pbtelnet(testarray[34], testarray2[34], 23); if (selection == 35) pbtelnet(testarray[35], testarray2[35], 23); if (selection == 36) pbtelnet(testarray[36], testarray2[36], 23); if (selection == 37) pbtelnet(testarray[37], testarray2[37], 23); if (selection == 38) pbtelnet(testarray[38], testarray2[38], 23); if (selection == 39) pbtelnet(testarray[39], testarray2[39], 23); if (selection == 40) pbtelnet(testarray[40], testarray2[40], 23); if (selection == 41) pbtelnet(testarray[41], testarray2[41], 23); if (selection == 42) pbtelnet(testarray[42], testarray2[42], 23); if (selection == 43) pbtelnet(testarray[43], testarray2[43], 23); if (selection == 44) pbtelnet(testarray[44], testarray2[44], 23); if (selection == 45) pbtelnet(testarray[45], testarray2[45], 23); if (selection == 46) pbtelnet(testarray[46], testarray2[46], 23); if (selection == 47) pbtelnet(testarray[47], testarray2[47], 23); if (selection == 48) pbtelnet(testarray[48], testarray2[48], 23); if (selection == 49) pbtelnet(testarray[49], testarray2[49], 23); if (selection == 50) pbtelnet(testarray[50], testarray2[50], 23); if (selection == 51) pbtelnet(testarray[51], testarray2[51], 23); if (selection == 52) pbtelnet(testarray[52], testarray2[52], 23); if (selection == 53) pbtelnet(testarray[53], testarray2[53], 23); if (selection == 54) pbtelnet(testarray[54], testarray2[54], 23); if (selection == 55) pbtelnet(testarray[55], testarray2[55], 23); if (selection == 56) pbtelnet(testarray[56], testarray2[56], 23); if (selection == 57) pbtelnet(testarray[57], testarray2[57], 23); if (selection == 58) pbtelnet(testarray[58], testarray2[58], 23); if (selection == 59) pbtelnet(testarray[59], testarray2[59], 23); if (selection == 60) pbtelnet(testarray[60], testarray2[60], 23); refresh(); getch(); // We allocated all this stuff, so free it. for(col=0; col menulength) offset=selection-menulength+1; sprintf(formatstring,"%%-%ds",width); // remove - sign to right-justify the menu items while(ky != 27) { for (counter=0; counter < menulength; counter++) { if (counter+offset==selection) attron(COLOR_PAIR(1)); mvprintw(row+counter,col,formatstring,array[counter+offset]); attroff(COLOR_PAIR(1)); } ky=getch(); switch(ky) { case KEY_UP: if (selection) { selection--; if (selection < offset) offset--; } break; case KEY_DOWN: if (selection < arraylength-1) { selection++; if (selection > offset+menulength-1) offset++; } break; case KEY_HOME: selection=0; offset=0; break; case KEY_END: selection=arraylength-1; offset=arraylength-menulength; break; case KEY_PPAGE: selection-=menulength; if (selection < 0) selection=0; offset-=menulength; if (offset < 0) offset=0; break; case KEY_NPAGE: selection+=menulength; if (selection > arraylength-1) selection=arraylength-1; offset+=menulength; if (offset > arraylength-menulength) offset=arraylength-menulength; break; case 10: //enter return selection; break; case KEY_F(1) : if (zmodem_receive() != -1) { waddstr(win, "\nStarting Zmodem Transfer ..\n"); } else waddstr(win, "\nZmodem Start Failure!\n"); break; case 27: //esc // esc twice to get out, otherwise eat the chars that don't work //from home or end on the keypad ky=getch(); if (ky == 27) { curs_set(0); mvaddstr(9,77," "); return -1; } else if (ky=='[') { getch(); getch(); } else ungetch(ky); } } return -1; } ///////////////////////////////////// ///////// ANSIs ///////////////////////////////////////// int intro(void) { puts("\e[?7h\e[40m\e[2J\e[7;2H\e[0;34m%%%%%%%%%%%%\e[C\e[1;30m�\e[0m���\e[1;30m�\e[2C�\e[0m�����\e[1;30m�\e[0m��������\e[1;30m�\e[0m�������\e[1;30m�\e[0m������\e[1;30m�\e[2C�\e[0m���\e[3C\e[1;30m�\e[0m���\e[1;30m�\e[0;34m%%%%%%%%%%%%%\e[8;2H�\e[C����������\e[C\e[37m�\e[1;47m���\e[C\e[0m�\e[1;47m�\e[40m���������������\e[C����������������\e[C\e[0m�\e[1m����\e[C\e[0m�\e[1;47m�\e[40m���\e[C\e[0;34m�����������\e[C�\e[9;4H�\e[C���\e[1;44m���\e[0;34m�\e[1;44m�\e[C\e[0m�\e[1;47m���\e[C\e[40m����\e[C���\e[0m�\e[C�\e[1m���\e[C\e[0;34m�\e[C\e[37m�\e[1m�����\e[0m�\e[C�\e[1m���\e[C�����\e[0m�\e[1m�����\e[C����\e[C\e[34;44m�\e[0;34m�\e[1;44m���\e[0;34m����\e[C�\e[10;2H�\e[C��\e[C�\e[1;44m����\e[47m�\e[0;34m�\e[C\e[37m�\e[1m���\e[0m�\e[1m���\e[C����\e[C\e[0;34m�\e[37m�\e[1m���\e[C\e[0;34m�\e[C\e[37m�\e[1m���\e[C\e[0;34m����\e[37m�\e[1m���\e[C����\e[0m�\e[1m����������\e[C\e[0;34m�\e[1;47m�\e[44m����\e[C\e[0;34m�\e[C��\e[C�\e[11;6H�����\e[1;44m�\e[0;34m��\e[C\e[1;37m���\e[C\e[0m�\e[1m��������\e[C\e[0;34m�\e[37m�\e[1m��\e[2C\e[0;34m�\e[C\e[1;37m���\e[2C\e[0;34m���\e[C\e[37m�\e[1m��\e[47m�\e[40m����\e[C���\e[C\e[0m�\e[1m��\e[C\e[0m�\e[1m���\e[C\e[0;34m��\e[1;44m�\e[0;34m�����\e[12;3H�\e[C�\e[C��\e[1;44m�\e[0;34m�\e[1;44m�\e[3C\e[37;40m����\e[C��������\e[2C\e[0m�\e[1m���\e[2C\e[0m�\e[1m�������\e[2C���\e[C\e[0m�\e[1;47m�\e[40m��\e[0m�\e[1m����\e[C\e[0m�\e[1m�\e[C����\e[2C\e[0;34m�\e[1;44m�\e[0;34m�\e[1;44m�\e[0;34m߲\e[C�\e[C�\e[13;6H������\e[1;30m�\e[0m�\e[1;47m�����\e[C���������\e[30;40m�\e[C\e[37;47m���\e[30;40m�\e[0m�\e[1;47m��������\e[0m�\e[1;47m����\e[30;40m�\e[2C\e[0m�\e[1;47m������\e[3C\e[30;40m�\e[37;47m�����\e[30;40m�\e[0;34m�������\e[CsM\e[14;11H\e[1;30m�\e[0m����������������������������������������������������������\e[1;30m�\e[0m"); printf("\e[18;20H\e[1;34mWelcome to igTerm. Press any key to continue"); } int header() { puts("\e[H\e[1;1H\e\e[2;3H\e[0m�\e[1m��\e[C���\e[0m�\e[C�\e[1m����\e[C���\e[0m�\e[C\e[1m����\e[47m�\e[C\e[40m����\e[47m�\e[0m�\e[1;47m��\e[C\e[0;34m��������������\e[C�����\e[5C�\e[2C..\e[C�\e[Cioi\e[Ci\e[Co\e[C.\e[3;2H�\e[C\e[1;37m��\e[C��\e[C���\e[C��\e[2C��\e[3C�����\e[C��\e[C��\e[C��\e[C\e[44m BBS Directory \e[0;34m�\e[C����\e[2Ci0\e[C�1\e[C0\e[C1\e[C0\e[C11\e[C0\e[4;4H\e[37m��\e[C\e[1m�����\e[2C\e[0m��\e[2C\e[1m���\e[0m�\e[C��\e[2C�\e[C��\e[C\e[1m��\e[C\e[0m��\e[3C\e[34m���\e[C�\e[C�\e[4C��\e[5;1H�����������������������������������������������������������������������������ͻ\e[6;1H\e[1m:\e[37;44m >> BBSName \e[34;40m:\e[37;44m >> Telnet Address \e[34;40m:\e[37;44m >> Port # \e[34;40m:\e[7;1H�����������������������������������������������������������������������������͹\e[0m\e[1;1H"); } int phonebook(void) { printf("\e[H\e[H\e[40m\e[2J\e[2;3H\e[0m�\e[1m��\e[C���\e[0m�\e[C�\e[1m����\e[C���\e[0m�\e[C\e[1m����\e[47m�\e[C\e[40m����\e[47m�\e[0m�\e[1;47m��\e[C\e[0;34m��������������\e[C�����\e[5C�\e[2C..\e[C�\e[Cioi\e[Ci\e[Co\e[C.\e[3;2H�\e[C\e[1;37m��\e[C��\e[C���\e[C��\e[2C��\e[3C�����\e[C��\e[C��\e[C��\e[C\e[44m BBS Phone Book \e[0;34m�\e[C����\e[2Ci0\e[C�1\e[C0\e[C1\e[C0\e[C11\e[C0\e[4;4H\e[37m��\e[C\e[1m�����\e[2C\e[0m��\e[2C\e[1m���\e[0m�\e[C��\e[2C�\e[C��\e[C\e[1m��\e[C\e[0m��\e[3C\e[34m���\e[C�\e[C�\e[4C��\e[0m"); } ///////// END ANSIs ///////////////////////////////////// ///////// EOF /////////////////////////////////////////// int telnet(void) MAIN_EXTERNALLY_VISIBLE; int telnet(void) { char address[300]; printw("Address: "); scanw("%s", &address); int portnum; printw("Port: "); scanw("%d", &portnum); char *host; int port; int len; struct pollfd ufds[2]; INIT_G(); #if ENABLE_FEATURE_TELNET_TTYPE G.ttype = getenv("TERM"); #endif if (tcgetattr(0, &G.termios_def) >= 0) { G.do_termios = 1; G.termios_raw = G.termios_def; cfmakeraw(&G.termios_raw); } host = address; port = portnum; xmove_fd(create_and_connect_stream_or_die(host, port), netfd); setsockopt_keepalive(netfd); startup(); puts(""); if (use_sbar) draw_statusbar(); #if ENABLE_FEATURE_TELNET_WIDTH get_terminal_width_height(0, &G.win_width, &G.win_height); //TODO: support dynamic resize? #endif signal(SIGINT, record_signo); ufds[0].fd = STDIN_FILENO; ufds[0].events = POLLIN; ufds[1].fd = netfd; ufds[1].events = POLLIN; while (1) { if (poll(ufds, 2, -1) < 0) { /* error, ignore and/or log something, bay go to loop */ if (bb_got_signal) continue; } // FIXME: reads can block. Need full bidirectional buffering. if (ufds[0].revents) { len = safe_read(STDIN_FILENO, G.buf, DATABUFSIZE); if (len <= 0) doexit(EXIT_SUCCESS); handle_net_output(len); } if (ufds[1].revents) { len = safe_read(netfd, G.buf, DATABUFSIZE); if (len <= 0) { full_write1_str("Connection closed by foreign host\r\n"); main(); doexit(EXIT_FAILURE); } handle_net_input(len); } } /* while (1) */ } //////////////// status bar //////////////////////// void startup(void) { printf("\e(U"); /* set to ibm character set */ initscr(); /* initialize ncurses */ start_color(); COLOR_PAIRS = 72; /* needed to fix the 64 color pair bug */ cbreak(); // raw(); noecho(); /* don't echo input */ //nonl(); use_sbar = (LINES > 24) ? 1 : 0; /* only use statbar on big terms */ win = newwin(screenlen, COLS, 0, 0); /* configurable later? */ wrefresh(win); if (win == NULL) { printf("\nError creating main window!\n"); exit(2); } scrollok(win, TRUE); nodelay(win, TRUE); keypad(win, TRUE); if (use_sbar) { statusbar = newwin(1, COLS, screenlen, 0); if (statusbar == NULL) { delwin(win); endwin(); printf("\nError creating status bar window!\n"); exit(3); } } dos_lf = 1; /* emulate dos linefeeds for bbs compatibility */ stage = 0; binary_mode = 0; /* option defaults */ did_SGA = 0; did_TERM = 0; did_BIN = 0; ansi = 1; rz_active = 0; } void draw_statusbar(void) { int i; char sbar[80]; wattrset(statusbar, crt2curses(0x19)); wcolor_set(statusbar, crt2curses(0x19), NULL); sprintf(sbar, " %s %s", appname, version); for (i = strlen(sbar); i < 80; i++) sbar[i] = 32; mvwaddstr(statusbar, 0,0, sbar); touchwin(statusbar); wrefresh(statusbar); touchwin(win); textattr(0x07); } static struct termios stored, new; /* very useful; convert a STANDARD color attribute byte to a ncurses pair attr, for use with textattr() */ int crt2curses(unsigned char attr) { int pairnum, boldstate = A_NORMAL; short nfore, nback; if (fgof(attr) > 7) boldstate = A_BOLD; switch(fgof(attr)) { case 0 : nfore = COLOR_BLACK; break; case 1 : nfore = COLOR_BLUE; break; case 2 : nfore = COLOR_GREEN; break; case 3 : nfore = COLOR_CYAN; break; case 4 : nfore = COLOR_RED; break; case 5 : nfore = COLOR_MAGENTA; break; case 6 : nfore = COLOR_YELLOW; break; case 7 : nfore = COLOR_WHITE; break; case 8 : nfore = COLOR_BLACK; break; case 9 : nfore = COLOR_BLUE; break; case 10 : nfore = COLOR_GREEN; break; case 11 : nfore = COLOR_CYAN; break; case 12 : nfore = COLOR_RED; break; case 13 : nfore = COLOR_MAGENTA; break; case 14 : nfore = COLOR_YELLOW; break; case 15 : nfore = COLOR_WHITE; break; } switch(bgof(attr)) { case 0 : nback = COLOR_BLACK; break; case 1 : nback = COLOR_BLUE; break; case 2 : nback = COLOR_GREEN; break; case 3 : nback = COLOR_CYAN; break; case 4 : nback = COLOR_RED; break; case 5 : nback = COLOR_MAGENTA; break; case 6 : nback = COLOR_YELLOW; break; case 7 : nback = COLOR_WHITE; break; } pairnum = bgof(attr) * 8 + fgof(attr) + 1; if (fgof(attr) > 7) { boldstate = A_BOLD; pairnum = pairnum - 8; } /* errors attr = 31, pairnum = -8 attr = 42, pairnum = -8 31 in hex would be like 1F bgof(attr) = 1 fgof(attr) = F 1 * 8 + 15 = 23 res = 15 so if attr = 31, pairnum is 15 */ /* printf("\nattr = %d, pairnum = %d\n", attr, pairnum); */ init_pair(pairnum, nfore, nback); return (COLOR_PAIR(pairnum) | boldstate); } /* for pascal ease and sanity */ void textattr(unsigned char attr) { wattrset(win, crt2curses(attr)); curattr = attr; } /* show a message box for 'secs' seconds or until a key is pressed */ void message(char *s, int secs) { #define _rows 5 #define _cols 40 WINDOW *msg; unsigned char x, y; int i; time_t timer; x = wherex(); y = wherey(); msg = newwin(_rows, _cols, 8, 20); nodelay(msg, TRUE); overwrite(msg, win); wattrset(msg, crt2curses(0x19)); for (i = 0; i < _rows * _cols; i++) waddch(msg, ' '); mvwaddstr(msg, (_rows+1) / 2 - 1, (_cols / 2) - (strlen(s) / 2), s); wrefresh(msg); timer = time(NULL); while (wgetch(msg) == ERR && time(NULL) < (timer+secs)); delwin(msg); gotoxy(x, y); } /////////////////////// /* return the current cursor position (column), 1-based */ int wherex(void) { int x, y; getyx(win, y, x); return (x + 1); } /* return the current line number, 1-based */ int wherey(void) { int x, y; getyx(win, y, x); return (y + 1); } /* if dir exists function */ int ifdirexists() { chdir(getenv("HOME")); mkdir(".igterm", 0700); } int makedirs() { if (chdir(getenv("HOME")) == 0) { /* try to open file to read */ FILE *file1; if (file1 = fopen(".igterm/hosts.txt", "r")) { fclose(file1); printf("file exists"); } else { printf("file doesn't exist"); FILE *fp = fopen(".igterm/hosts.txt", "a"); fputs("catch\ 22\ \[renegade\] catch22.zapto.org 24\n", fp); fputs("catch\ 22\ \[daydream\] catch22.zapto.org 26\n", fp); fputs("catch\ 22\ \[impulse\] catch22.zapto.org 28\n", fp); fputs("catch\ 22\ \[iniquity\] catch22.zapto.org 30\n", fp); fclose(fp); } } if (chdir(getenv("HOME")) == 0) { /* try to open file to read */ FILE *file2; if (file2 = fopen(".igterm/hosts2.txt", "r")) { fclose(file2); printf("file exists"); } else { printf("file doesn't exist"); FILE *fp2 = fopen(".igterm/hosts2.txt", "a"); fputs("catch22.zapto.org\n", fp2); fputs("catch22.zapto.org\n", fp2); fputs("catch22.zapto.org\n", fp2); fputs("catch22.zapto.org\n", fp2); fclose(fp2); } } if (chdir(getenv("HOME")) == 0) { /* try to open file to read */ FILE *file3; if (file3 = fopen(".igterm/hosts3.txt", "r")) { fclose(file3); printf("file exists"); } else { printf("file doesn't exist"); FILE *fp3 = fopen(".igterm/hosts3.txt", "a"); fputs("24\n", fp3); fputs("26\n", fp3); fputs("28\n", fp3); fputs("30\n", fp3); fclose(fp3); } } } /* download file(s) using the zmodem protocol */ int zmodem_receive(void) { system("rz -Z"); }