Code:
#include <arpa/telnet.h>
#include <netinet/in.h>
#include "libbb.h"
#include "common_bufsiz.h"
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <arpa/telnet.h>
#include <netinet/in.h>
#include <netdb.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sysexits.h>
#include <unistd.h>
#include <ncurses.h>
#include <menu.h>
#include <sys/stat.h>
#include "misc.h"
#include "global.h"
int ansi = 0;
#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 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();
full_write1_str("\r\nConsole escape. Commands are:\r\n\n"
" l go to line mode\r\n"
" c go to character mode\r\n"
" z suspend telnet\r\n"
" e exit telnet\r\n");
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);
}
full_write1_str("continuing...\r\n");
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;
printf("\r\nEntering %s mode"
"\r\nEscape character is '^%c'.\r\n", "character", ']');
rawmode();
}
} else {
if (G.charmode != CHM_OFF) {
G.charmode = CHM_OFF;
printf("\r\nEntering %s mode"
"\r\nEscape character is '^%c'.\r\n", "line", 'C');
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 *address, const int portnum) MAIN_EXTERNALLY_VISIBLE;
int pbtelnet(const char *address, const int portnum)
//int telnet_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
//int telnet_main(int argc UNUSED_PARAM, char **argv)
{
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);
}
#if ENABLE_FEATURE_TELNET_AUTOLOGIN
if (1 == getopt32(argv, "al:", &G.autologin)) {
/* Only -a without -l USER picks $USER from envvar */
G.autologin = getenv("USER");
}
argv += optind;
#else
// argv++;
#endif
// if (!*argv)
// bb_show_usage();
// host = *argv++;
host = address;
// port = *argv ? bb_lookup_port(*argv++, "tcp", 23)
// : bb_lookup_std_port("telnet", "tcp", 23);
port = portnum;
// if (*argv) /* extra params?? */
// bb_show_usage();
xmove_fd(create_and_connect_stream_or_die(host, port), netfd);
setsockopt_keepalive(netfd);
#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;
startup();
if (use_sbar) draw_statusbar();
while (1) {
if (poll(ufds, 2, -1) < 0) {
/* error, ignore and/or log something, bay go to loop */
if (bb_got_signal)
con_escape();
else
sleep(1);
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");
doexit(EXIT_FAILURE);
}
handle_net_input(len);
}
} /* while (1) */
}
// Ignatius' Comm Prog v1.0
/////////// variables /////////////////////////////
const int maxQuestionID = 4;
int cmdKey = 0;
int questionID = 0;
/////////// end variables /////////////////////////
/////////// init function /////////////////////////
void init()
{
printf("\033(U");
initscr();
raw();
echo();
keypad(stdscr, TRUE);
init_pair(1, COLOR_BLACK, COLOR_CYAN);
start_color();
}
///////////// end init ////////////////////////////
///////////// main screen /////////////////////////
int main()
{
system("stty raw");
system("stty columns 80 rows 25");
// putenv("TERM=linux");
system("clear");
init();
intro();
const char *questions[] = {"\e[24;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[24;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[24;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[24;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[24;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
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 200 rows 60");
exit(1);
return 0;
}
/////////// end quit function /////////////////////
/////////// begin menu system /////////////////////
int loginmatrix(const char *question, int defVal, int x, int y,
int numOptions, const char **options, const char **selected) {
int lastVal=-1;
int value=defVal;
int i;
char *tmp;
int qLen=strlen(question);
int ch;
do {
if (lastVal != value) {
for (i=0; i<numOptions; i++) {
if (value != i) {
printf(options[i]);
} else {
printf(selected[i]);
}
}
lastVal = value;
}
ch = getchar();
switch (ch) {
case 66: // up arrow
value += 1;
if (value > numOptions-1) { value = numOptions-1; }
break;
case 65: // down arrow
value -= 1;
if (value < 0) { value = 0; }
break;
}
} while (ch != 13); // Our termination cond: then hit enter.
return value;
}
/////////// begin phonebook //////////////////////
void add_contact();
void search_contact();
void delete_contact();
void view_all_contact();
void add_contact()
{
FILE *fp;
fp=fopen("hosts.txt","a+");
puts("\e[21;20H ");
puts("\e[20;20H\e[1;34mAddress : ");
puts("\e[20;20H\e[1;34mAddress : \e[0;37m" );
puts("\e[2A");
char name[200];
scanw("%s",name);
// printf("\e[21;20H\e[1;34mAddress : ");
// printf("\e[21;20H\e[1;34mAddress : \e[0;37m" );
// char mob[20];
// scanw("%s",mob);
// fprintf(fp,"%s\n%s ",name,mob);
fprintf(fp,"%s\n",name);
fclose(fp);
/////////////////////
// FILE *fp1;
// fp1=fopen("hosts.txt","a+");
// fprintf(fp1,"%s",name);
// fclose(fp1);
//////////////////////
}
void search_contact()
{
FILE *fp;
fp=fopen("hosts.txt","r");
puts("\e[20;20H ");
puts("\e[21;20H ");
puts("\e[19;20H\e[1;34mSearch : ");
puts("\e[19;20H\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[19;20H ");
printf("\e[20;20H\e[1;34mAddress : ",name1);
printf("\e[20;20H\e[1;34mAddress : \e[0;37m%s\n",name1);
// printf("\e[21;20H\e[1;34mAddress : ",mob);
// printf("\e[21;20H\e[1;34mAddress : \e[0;37m%s\n",mob);
}
}
fclose(fp);
}
void delete_contact()
{
FILE *fp,*fp1;
fp=fopen("hosts.txt","r+");
fp1=fopen("temp.txt","w");
puts("\e[20;20H\e[1;34mDelete which : \e[0;37m");
puts("\e[2A");
char name[200];
scanw("%s",name);
char name1[200],mob[20];
while(fscanf(fp,"%s\n",name1)!=EOF)
{
if(strcmp(name,name1)==0)
{
continue;
}
fprintf(fp1,"%s\n",name1);
}
fclose(fp);
fclose(fp1);
fp=fopen("hosts.txt","w");
fp1=fopen("temp.txt","r");
while(fscanf(fp1,"%s\n",name1)!=EOF)
{
fprintf(fp,"%s\n",name1);
}
fclose(fp);
fclose(fp1);
remove("temp.txt");
}
void view_all_contact()
{
FILE *fp;
fp=fopen("hosts.txt","r");
char name1[200],mob[20];
while(fscanf(fp,"%s %s",name1,mob)!=EOF)
{
printf("\n \e[1;34mName : \e[0;37m%s\n",name1);
printf(" \e[1;34mAddress : \e[0;37m%s",mob);
}
fclose(fp);
}
/////////// end phonebook ////////////////////////////
// int barmenu(const char **array, const int row, const int col, const int arraylength, const int width, int menulength, int selection);
// Removes whitespace from the end of strings
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=75, menulength=10,selection;
header();
char **testarray=NULL;
FILE *fp=fopen("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);
}
initscr();
noecho();
keypad(stdscr,TRUE);
selection=barmenu((const char const **)testarray,row,col,arraylength,width,menulength,0);
// mvprintw(15,0,"Selection= %d",selection);
// mvprintw(1,1,"");
if (selection == 0) pbtelnet(testarray[0], 26);
if (selection == 1) pbtelnet(testarray[1], 23);
if (selection == 2) pbtelnet(testarray[2], 23);
if (selection == 3) pbtelnet(testarray[3], 23);
if (selection == 4) pbtelnet(testarray[4], 23);
if (selection == 5) pbtelnet(testarray[5], 23);
if (selection == 6) pbtelnet(testarray[6], 23);
if (selection == 7) pbtelnet(testarray[7], 23);
if (selection == 8) pbtelnet(testarray[8], 23);
if (selection == 9) pbtelnet(testarray[9], 23);
if (selection == 10) pbtelnet(testarray[10], 23);
if (selection == 11) pbtelnet(testarray[11], 23);
if (selection == 12) pbtelnet(testarray[12], 23);
if (selection == 13) pbtelnet(testarray[13], 23);
if (selection == 14) pbtelnet(testarray[14], 23);
if (selection == 15) pbtelnet(testarray[15], 23);
if (selection == 16) pbtelnet(testarray[16], 23);
if (selection == 17) pbtelnet(testarray[17], 23);
if (selection == 18) pbtelnet(testarray[18], 23);
if (selection == 19) pbtelnet(testarray[19], 23);
if (selection == 20) pbtelnet(testarray[20], 23);
if (selection == 21) pbtelnet(testarray[21], 23);
if (selection == 22) pbtelnet(testarray[22], 23);
if (selection == 23) pbtelnet(testarray[23], 23);
if (selection == 24) pbtelnet(testarray[24], 23);
if (selection == 25) pbtelnet(testarray[25], 23);
if (selection == 26) pbtelnet(testarray[26], 23);
if (selection == 27) pbtelnet(testarray[27], 23);
if (selection == 28) pbtelnet(testarray[28], 23);
if (selection == 29) pbtelnet(testarray[29], 23);
refresh();
getch();
// Add another option to file
// fp=fopen("filename","a");
// fputs("whatever\n", fp);
// fclose(fp);
// We allocated all this stuff, so free it.
for(col=0; col<arraylength; col++) if(testarray[col]) free(testarray[col]);
free(testarray);
// Cannot return -1 to commandline. 127 is the maximum we should return.
if(selection < 0) return(127);
// 0 has special meaning, return n+1
return selection+1;
// conn2();
endwin();
// Char arrays are declared like so:
//char *testarray[]={"Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"};
// Open a file for writing.
// (This will replace any existing file. Use "w+" for appending)
// FILE *file = fopen("filename", "a");
// int results = fputs(testarray, file);
// if (results == EOF) {
// Failed to write do error code here.
// }
// fclose(file);
//
return 0;
}
int barmenu(const char **array,const int row, const int col, const int arraylength, const int width, int menulength, int selection)
{
int counter,offset=0,ky=0;
char formatstring[7];
curs_set(0);
if (arraylength < menulength)
menulength=arraylength;
if (selection > 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): // function key 1
return -1;
case 27: //esc
// esc twice to get out, otherwise eat the chars that don't work
//from home or end on the keypad
// system("touch temp");
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[20;20H\e[1;34mWelcome to igTerm. Press any key to continue");
}
int header()
{
puts("\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)
{
puts("\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);
}
#if ENABLE_FEATURE_TELNET_AUTOLOGIN
if (1 == getopt32(argv, "al:", &G.autologin)) {
/* Only -a without -l USER picks $USER from envvar */
G.autologin = getenv("USER");
}
argv += optind;
#else
// argv++;
#endif
// if (!*argv)
// bb_show_usage();
// host = *argv++;
host = address;
// port = *argv ? bb_lookup_port(*argv++, "tcp", 23)
// : bb_lookup_std_port("telnet", "tcp", 23);
port = portnum;
// if (*argv) /* extra params?? */
// bb_show_usage();
xmove_fd(create_and_connect_stream_or_die(host, port), netfd);
setsockopt_keepalive(netfd);
#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)
con_escape();
else
sleep(1);
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");
doexit(EXIT_FAILURE);
}
handle_net_input(len);
}
} /* while (1) */
}
//////////////// status bar ////////////////////////
void startup(void)
{
printf("\033(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[79];
// wattrset(statusbar, crt2curses(0x1F));
wattrset(statusbar, crt2curses(0x19));
// wcolor_set(statusbar, crt2curses(0x1F), NULL);
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);
wrefresh(win);
}
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;
}