Code:
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);
if (selection == 0) pbtelnet(testarray[0], testarray[1], 24);
if (selection == 1) pbtelnet(testarray[1], testarray[2], 26);
if (selection == 2) pbtelnet(testarray[2], testarray[3], 23);
if (selection == 3) pbtelnet(testarray[3], testarray[4], 23);
if (selection == 4) pbtelnet(testarray[4], testarray[5], 23);
if (selection == 5) pbtelnet(testarray[5], testarray[6], 23);
if (selection == 6) pbtelnet(testarray[6], testarray[7], 23);
if (selection == 7) pbtelnet(testarray[7], testarray[2], 23);
if (selection == 8) pbtelnet(testarray[8], testarray[2], 23);
if (selection == 9) pbtelnet(testarray[9], testarray[10], 23);
if (selection == 10) pbtelnet(testarray[10], testarray[11], 23);
if (selection == 11) pbtelnet(testarray[11], testarray[12], 23);
if (selection == 12) pbtelnet(testarray[12], testarray[13], 23);
if (selection == 13) pbtelnet(testarray[13], testarray[14], 23);
if (selection == 14) pbtelnet(testarray[14], testarray[15], 23);
if (selection == 15) pbtelnet(testarray[15], testarray[16], 23);
if (selection == 16) pbtelnet(testarray[16], testarray[17], 23);
if (selection == 17) pbtelnet(testarray[17], testarray[18], 23);
if (selection == 18) pbtelnet(testarray[18], testarray[19], 23);
if (selection == 19) pbtelnet(testarray[19], testarray[20], 23);
if (selection == 20) pbtelnet(testarray[20], testarray[21], 23);
if (selection == 21) pbtelnet(testarray[21], testarray[22], 23);
if (selection == 22) pbtelnet(testarray[22], testarray[23], 23);
if (selection == 23) pbtelnet(testarray[23], testarray[24], 23);
if (selection == 24) pbtelnet(testarray[24], testarray[25], 23);
if (selection == 25) pbtelnet(testarray[25], testarray[26], 23);
if (selection == 26) pbtelnet(testarray[26], testarray[27], 23);
if (selection == 27) pbtelnet(testarray[27], testarray[28], 23);
if (selection == 28) pbtelnet(testarray[28], testarray[29], 23);
if (selection == 29) pbtelnet(testarray[29], testarray[30], 23);
refresh();
getch();
// 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;
endwin();
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;
}