Ncurses status bar

Hi, all,

I'm writing a BBS telnet client, and am trying to implement a status bar into it, at the bottom of the screen.
I am using NCurses to accomplish this. So far, it appears to be working, that is, upon connecting to BBS, it
will display the status bar, and then quickly disappear.

Here is some code:

https://pastebin.com/raw/wM6hcQkk

The first function is executed before the second.
It works and everything, but only for a second or so.

Can anyone tell me what i'm doing wrong?

Thanks.

Cannot visit site listed. Mordac has it listed as malicious.

Mordac is being ridiculous. It's a direct link to some code.

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 = 32;
   mvwaddstr(statusbar, 0,0, sbar);
   touchwin(statusbar);
   wrefresh(statusbar);
   touchwin(win);
   textattr(0x07);
   wrefresh(win);
}

But that's one reason it's best to post here instead of linking.

If I had to make a wild guess, you're drawing something else on top of it. What, I can't say, without seeing all of your code.

Ok. Here's the 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;

        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);
            } else {
                printf(selected);
            }
        }

                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 = 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;
}



That's still only part of your code. Its missing libbb.h, common_bufsiz.h, misc.h, and global.h. We need those to compile your code and find the problem by testing.