📄 nfl.c
字号:
if (*p == '\0') break; if (*p == '\n') { /* Null-terminate this entry string */ *p++ = '\0'; /* Set 'waiting for first entry character' flag */ first_entry_char = 1; } } while (i < MAX_ENTRIES); return ( i );}/* NOTE: ANSI defines (1,1) as upper left corner, IBM BIOS uses (0,0)--------------------------------------------------------------------------*/void gotoxy (int x, int y){ printf ("\e[%d;%dH", y+1, x+1);}/*Display screen border.--------------------------------------------------------------------------*/static void show_border ( void ){ unsigned short i; int disp_ul = DISP_UL; int disp_ur = DISP_UR; int disp_ll = DISP_LL; int disp_lr = DISP_LR; int disp_horiz = DISP_HORIZ; int disp_vert = DISP_VERT; /* Clear the screen, and set foreground and background attributes */ for (i = 0; i<rows; i++) { gotoxy (0, i); printf ( "\e[K" ); } /* Turn off the text cursor */ console_nocursor(); /* Show the top line of the border */ gotoxy (menu_ulx, menu_uly); ansi_putc (disp_ul); for (i = 0; i < (menu_cols); i++) ansi_putc (disp_horiz); gotoxy (menu_ulx+menu_cols+1, menu_uly); ansi_putc (disp_ur); /* Show the sides of the border */ for (i = 0; i<menu_rows; i++) { gotoxy (menu_ulx, menu_uly+1+i); ansi_putc (disp_vert); gotoxy (menu_ulx+menu_cols+1, menu_uly+1+i); ansi_putc (disp_vert); } /* Show the bottom line of the border */ gotoxy (menu_ulx, menu_uly+menu_rows+1); ansi_putc (disp_ll); for (i = 0; i < (menu_cols); i++) ansi_putc (disp_horiz); gotoxy (menu_ulx+menu_cols+1, menu_uly+menu_rows+1); ansi_putc (disp_lr); gotoxy ( 1, 0 ); printf ( "Network Free-Loader v" NFL_VERSION );}/*--------------------------------------------------------------------------*/static void pad_printxy ( char *szBuff, int x, unsigned short y, int len_entry, int reverse ){ int i;#if 0 gotoxy( 30, 20); printf( "strlen:%d", strlen(szBuff));#endif for ( i=strlen(szBuff); (i < len_entry ); i++ ) strcat( szBuff, " " ); gotoxy( x, y ); if ( reverse ) printf ( "\e[7m%s\e[27m", szBuff ); else printf ( "%s", szBuff );}/*--------------------------------------------------------------------------*/static void show_entries ( unsigned short first_row, unsigned short num_rows ){ unsigned short i, bot_entry; int len_entry; int disp_up = DISP_UP; int disp_down = DISP_DOWN; char szTmp[10], szBuff[80];#ifdef SUPPORT_SERIAL if (terminal & TERMINAL_SERIAL) { disp_up = ACS_UARROW; disp_down = ACS_DARROW; }#endif /* SUPPORT_SERIAL *//* menu_cols = 25; */ len_entry = menu_cols;/* bot_entry = top_entry+menu_rows-1; if (bot_entry > num_entries) bot_entry = num_entries;*/ #if 0 gotoxy( 30, 15 ); printf( "[%d]SE(1R:%d, #:%d, cur:%d, top:%d", dbg_count1++, first_row, num_rows, cur_entry, top_entry );#endif/* for (i = 0; i <= bot_entry-top_entry; i++) { */ for (i = first_row; ((i < first_row+num_rows) && ((top_entry+i-1) <= num_entries)); i++) { *szTmp = 0; *szBuff = 0; if (number_entries) { if ((top_entry+i-1) <= 9) strncat( szBuff, " ", len_entry ); sprintf ( szTmp, "%d. ", (top_entry+i-1) ); strncat( szBuff, szTmp, len_entry );// len_entry -= strlen( szBuff ); } /* add the entry to the current string */ strncat ( szBuff, menu_entries[top_entry+i-1], len_entry ); pad_printxy( szBuff, menu_ulx+1, menu_uly+i, len_entry, ((top_entry+i-1) == cur_entry) );#if 0 if (i == first_row) { gotoxy( 30, 16); printf( "%d. %d [%s]", i, cur_entry, szBuff ); gotoxy( 30, 17); printf( " " ); gotoxy( 30, 18); printf( " " ); gotoxy( 30, 19); printf( " " ); } else if (i == first_row+1) { gotoxy( 30,17); printf( "%d. %d [%s]", i, cur_entry, szBuff ); }#endif } if (top_entry != 1) { *szBuff = 0; sprintf ( szBuff, " %c ", disp_up ); pad_printxy( szBuff, menu_ulx+1, menu_uly+1, len_entry, 0 );#if 0 gotoxy( 30, 18); printf( "%d. %d [%s]", i, cur_entry, szBuff );#endif } if ((top_entry+menu_rows-1) < num_entries) { *szBuff = 0; sprintf ( szBuff, " %c ", disp_down ); pad_printxy( szBuff, menu_ulx+1, menu_uly+menu_rows, len_entry, 0 );#if 0 gotoxy( 30, 19); printf( "%d. %d [%s]", i, cur_entry, szBuff );#endif }}/*--------------------------------------------------------------------------*/static int select_entry ( void ){ int c, c1, count=0; unsigned short bot_entry; unsigned short tmp; ansi_reset(); enable_cursor(0); printf ( "\e[3%dm\e[4%dm", color_fg, color_bg ); gotoxy( 20, 5 ); tmp = columns-5; if (menu_cols > tmp) menu_cols = tmp; tmp = rows-3; if (menu_rows > tmp) menu_rows = tmp; show_border (); top_entry = 1; cur_entry = 1; bot_entry = top_entry+menu_rows-1; show_entries ( 1, menu_rows ); while (1) { if ((checkkey () != -1) || (timeout == -1)) { /* Key was pressed, show which entry is selected before GETKEY, since we're comming in here also on TIMEOUT == -1 and hang in GETKEY */ c1 = getkey(); c = translate_keycode( c1 );#if 0 gotoxy( 30, 10 ); printf( "\e[K%d [%X]->[%X]", count++, c1, c ); gotoxy( 30, 11 ); printf( "cur:%d top:%d bot:%d rows:%d num_entries:%d", cur_entry, top_entry, bot_entry, menu_rows, num_entries );#endif /* We told them above (at least in SUPPORT_SERIAL) to use '^' or 'v' so accept these keys. */ if (c == 16 || c == '^') { if (terminal & TERMINAL_DUMB) { if (cur_entry > 1) cur_entry--; } else { if (cur_entry > 1) { cur_entry--; if ((cur_entry == top_entry) && (top_entry > 1)) { top_entry--; bot_entry--; show_entries ( 1, (bot_entry-top_entry+1) ); } else show_entries ( (cur_entry-top_entry+1), 2 ); } } } if ((c == 14 || c == 'v') && ((cur_entry + 1) <= num_entries)) { if (terminal & TERMINAL_DUMB) cur_entry++; else { if (cur_entry < num_entries) { cur_entry++; if ((cur_entry >= bot_entry) && (bot_entry < num_entries)) { top_entry++; bot_entry++; show_entries ( 1, (bot_entry-top_entry+1) ); } else show_entries( (cur_entry-top_entry), 2 ); } } } if (c == '\r') { return( cur_entry ); } } }}/*Set new filename in bootp path--------------------------------------------------------------------------*/void set_file_to_load( struct bootp_t *bootp, char *file2load ){ char *p, *szPath = bootp->bp_file; if (*file2load != '/') { /* if reletive path, append to current path */ if ((p = strrchr( szPath, '/')) != 0) szPath = p+1; } strcpy( szPath, file2load );}static void parse_elf_boot_notes( void *notes, union infoblock **rheader, struct bootp_t **rbootp){ unsigned char *note, *end; Elf_Bhdr *bhdr; Elf_Nhdr *hdr; bhdr = notes; if (bhdr->b_signature != ELF_BHDR_MAGIC) { return; } note = ((char *)bhdr) + sizeof(*bhdr); end = ((char *)bhdr) + bhdr->b_size; while (note < end) { unsigned char *n_name, *n_desc, *next; hdr = (Elf_Nhdr *)note; n_name = note + sizeof(*hdr); n_desc = n_name + ((hdr->n_namesz + 3) & ~3); next = n_desc + ((hdr->n_descsz + 3) & ~3); if (next > end) break;#if 0 printf("n_type: %x n_name(%d): n_desc(%d): \n", hdr->n_type, hdr->n_namesz, hdr->n_descsz);#endif if ((hdr->n_namesz == 10) && (memcmp(n_name, "Etherboot", 10) == 0)) { switch(hdr->n_type) { case EB_BOOTP_DATA: *rbootp = *((void **)n_desc); break; case EB_HEADER: *rheader = *((void **)n_desc); break; default: break; } } note = next; }}/*--------------------------------------------------------------------------*/int menu(struct ebinfo *eb, union infoblock *header, struct bootp_t *bootp){ int i; parse_elf_boot_notes(eb, &header, &bootp); num_entries = scan_entries(); if (!num_entries) { printf( "ERROR: No menu entries found\n"#if 1 "Rebuild menu program with a menu configuration file.\n"#endif "Press any key:" ); getchar(); /* 2 = Tell Etherboot to retry */ return( 2 ); } i = select_entry( );#if 0 gotoxy( 30, 13 ); printf( "Selected entry:%d [%s]", i, menu_entries[i] ); getchar();#else console_cls();#endif if (memcmp(menu_entries[i], "Quit Etherboot", sizeof("Quit Etherboot")) == 0) return (255); set_file_to_load ( bootp, menu_entries[ i ] ); return ( 1 );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -