int main (int argc, char *argv[]) { vc_component *v = NULL; fpos_t *fpos = NULL; long pos = 0; FILE *fp = NULL; ITEM *it = NULL; int entry_number = 0; bool done = FALSE; int win_state = WINDOW_INDEX; int command = 0; set_defaults (); process_command_line_args (argc, argv); /* * process_environment_variables(); * process_configuration_file(); */ signal (SIGINT, finish); /* catch interrupt for exiting */ signal (SIGWINCH, resize); /* catch interrupt for resizing */ initscr (); keypad (stdscr, TRUE); /* enable keypad for use of arrow keys */ nonl (); /* tell curses not to do NL->CR/NL on output */ cbreak (); /* take input chars immediately */ noecho (); init_index (data_path); set_index_help_fcn (show_index_help); init_view (); set_view_help_fcn (show_view_help); init_edit (); set_edit_help_fcn (show_edit_help); init_help (); while (!done) { switch (win_state) { case WINDOW_INDEX: /*------------------- display the index -------------------*/ display_index (); command = process_index_commands (); switch (command) { case INDEX_COMMAND_VIEW: win_state = WINDOW_VIEW; break; case INDEX_COMMAND_RAW_VIEW: win_state = WINDOW_RAW_VIEW; break; case INDEX_COMMAND_EDIT: win_state = WINDOW_EDIT; break; case INDEX_COMMAND_ADD: win_state = WINDOW_ADD; break; case INDEX_COMMAND_DELETE: win_state = WINDOW_DELETE; break; case INDEX_COMMAND_QUIT: done = TRUE; break; default: break; } break; case WINDOW_RAW_VIEW: /*------------------------------------------------- view the currently selected item with the pager -------------------------------------------------*/ it = get_current_item (); /* only display if there is an item that is selected */ if (NULL == it) { v = NULL; } else { fpos = (fpos_t *) item_userptr (it); fp = fopen (data_path, "r"); fsetpos (fp, fpos); v = parse_vcard_file (fp); fclose (fp); } if (v != NULL) { raw_view (v); vc_delete_deep (v); v = NULL; } win_state = WINDOW_INDEX; break; case WINDOW_VIEW: /*---------------------------------- view the currently selected item ----------------------------------*/ it = get_current_item (); /* only display if there is an item that is selected */ if (NULL == it) { v = NULL; } else { fpos = (fpos_t *) item_userptr (it); fp = fopen (data_path, "r"); fsetpos (fp, fpos); v = parse_vcard_file (fp); fclose (fp); } if (v != NULL) { entry_number = get_entry_number (it); view_vcard (entry_number, v); command = process_view_commands (); switch (command) { case VIEW_COMMAND_EDIT: win_state = WINDOW_EDIT; break; case VIEW_COMMAND_INDEX: win_state = WINDOW_INDEX; break; case VIEW_COMMAND_PREVIOUS: select_previous_item (); win_state = WINDOW_VIEW; break; case VIEW_COMMAND_NEXT: select_next_item (); win_state = WINDOW_VIEW; break; default: break; } } else { win_state = WINDOW_INDEX; } vc_delete_deep (v); v = NULL; break; case WINDOW_EDIT: /*-------------- edit a vcard --------------*/ it = get_current_item (); /* only display if there is an item that is selected */ if (NULL != it) { fpos = (fpos_t *) item_userptr (it); fp = fopen (data_path, "r"); fsetpos (fp, fpos); pos = ftell (fp); fclose (fp); fp = NULL; if (EDIT_SUCCESSFUL == edit_entry (data_path, pos)) { refresh_index (); } } win_state = WINDOW_INDEX; break; case WINDOW_ADD: if (ADD_SUCCESSFUL == add_entry (data_path)) { refresh_index (); } win_state = WINDOW_INDEX; break; case WINDOW_DELETE: it = get_current_item (); /* only delete if there is an item that is selected */ if (NULL != it) { fpos = (fpos_t *) item_userptr (it); fp = fopen (data_path, "r"); fsetpos (fp, fpos); pos = ftell (fp); fclose (fp); fp = NULL; if (DELETE_SUCCESSFUL == delete_entry (data_path, pos)) { refresh_index (); } } win_state = WINDOW_INDEX; break; default: break; } } finish (0); exit (EXIT_SUCCESS); return (0); }
/* Show the menu and handle menu entry selection. Returns the menu entry index that should be executed or -1 if no entry should be executed (e.g., Esc pressed to exit a sub-menu or switching menu viewers). If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu entry to be executed is a result of an automatic default selection because of the timeout. */ static int run_menu (grub_menu_t menu, int nested, int *auto_boot) { grub_uint64_t saved_time; int default_entry, current_entry; int timeout; default_entry = get_entry_number (menu, "default"); /* If DEFAULT_ENTRY is not within the menu entries, fall back to the first entry. */ if (default_entry < 0 || default_entry >= menu->size) default_entry = 0; /* If timeout is 0, drawing is pointless (and ugly). */ if (grub_menu_get_timeout () == 0) { *auto_boot = 1; return default_entry; } current_entry = default_entry; /* Initialize the time. */ saved_time = grub_get_time_ms (); refresh: menu_init (current_entry, menu, nested); timeout = grub_menu_get_timeout (); if (timeout > 0) menu_print_timeout (timeout); else clear_timeout (); while (1) { int c; timeout = grub_menu_get_timeout (); if (grub_normal_exit_level) return -1; if (timeout > 0) { grub_uint64_t current_time; current_time = grub_get_time_ms (); if (current_time - saved_time >= 1000) { timeout--; grub_menu_set_timeout (timeout); saved_time = current_time; menu_print_timeout (timeout); } } if (timeout == 0) { grub_env_unset ("timeout"); *auto_boot = 1; menu_fini (); return default_entry; } c = grub_getkey_noblock (); if (c != GRUB_TERM_NO_KEY) { if (timeout >= 0) { grub_env_unset ("timeout"); grub_env_unset ("fallback"); clear_timeout (); } switch (c) { case GRUB_TERM_KEY_HOME: case GRUB_TERM_CTRL | 'a': current_entry = 0; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_KEY_END: case GRUB_TERM_CTRL | 'e': current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_KEY_UP: case GRUB_TERM_CTRL | 'p': case '^': if (current_entry > 0) current_entry--; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_CTRL | 'n': case GRUB_TERM_KEY_DOWN: case 'v': if (current_entry < menu->size - 1) current_entry++; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_CTRL | 'g': case GRUB_TERM_KEY_PPAGE: if (current_entry < GRUB_MENU_PAGE_SIZE) current_entry = 0; else current_entry -= GRUB_MENU_PAGE_SIZE; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_CTRL | 'c': case GRUB_TERM_KEY_NPAGE: if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) current_entry += GRUB_MENU_PAGE_SIZE; else current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; case '\n': case '\r': case GRUB_TERM_KEY_RIGHT: case GRUB_TERM_CTRL | 'f': menu_fini (); *auto_boot = 0; return current_entry; case '\e': if (nested) { menu_fini (); return -1; } break; case 'c': menu_fini (); grub_cmdline_run (1); goto refresh; case 'e': menu_fini (); { grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); if (e) grub_menu_entry_run (e); } goto refresh; default: { grub_menu_entry_t entry; int i; for (i = 0, entry = menu->entry_list; i < menu->size; i++, entry = entry->next) if (entry->hotkey == c) { menu_fini (); *auto_boot = 0; return i; } } break; } } } /* Never reach here. */ }
/* Show the menu and handle menu entry selection. Returns the menu entry index that should be executed or -1 if no entry should be executed (e.g., Esc pressed to exit a sub-menu or switching menu viewers). If the return value is not -1, then *AUTO_BOOT is nonzero iff the menu entry to be executed is a result of an automatic default selection because of the timeout. */ static int run_menu (grub_menu_t menu, int nested, int *auto_boot) { grub_uint64_t saved_time; int default_entry, current_entry; int timeout; default_entry = get_entry_number (menu, "default"); /* If DEFAULT_ENTRY is not within the menu entries, fall back to the first entry. */ if (default_entry < 0 || default_entry >= menu->size) default_entry = 0; /* If timeout is 0, drawing is pointless (and ugly). */ if (grub_menu_get_timeout () == 0) { *auto_boot = 1; return default_entry; } current_entry = default_entry; /* Initialize the time. */ saved_time = grub_get_time_ms (); refresh: menu_init (current_entry, menu, nested); timeout = grub_menu_get_timeout (); if (timeout > 0) menu_print_timeout (timeout); else clear_timeout (); while (1) { int c; timeout = grub_menu_get_timeout (); if (grub_normal_exit_level) return -1; if (timeout > 0) { grub_uint64_t current_time; current_time = grub_get_time_ms (); if (current_time - saved_time >= 1000) { timeout--; grub_menu_set_timeout (timeout); saved_time = current_time; menu_print_timeout (timeout); } } if (timeout == 0) { grub_env_unset ("timeout"); *auto_boot = 1; menu_fini (); return default_entry; } if (grub_checkkey () >= 0 || timeout < 0) { c = GRUB_TERM_ASCII_CHAR (grub_getkey ()); if (timeout >= 0) { grub_env_unset ("timeout"); grub_env_unset ("fallback"); clear_timeout (); } switch (c) { case GRUB_TERM_HOME: current_entry = 0; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_END: current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_UP: case '^': if (current_entry > 0) current_entry--; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_DOWN: case 'v': if (current_entry < menu->size - 1) current_entry++; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_PPAGE: if (current_entry < GRUB_MENU_PAGE_SIZE) current_entry = 0; else current_entry -= GRUB_MENU_PAGE_SIZE; menu_set_chosen_entry (current_entry); break; case GRUB_TERM_NPAGE: if (current_entry + GRUB_MENU_PAGE_SIZE < menu->size) current_entry += GRUB_MENU_PAGE_SIZE; else current_entry = menu->size - 1; menu_set_chosen_entry (current_entry); break; case '\n': case '\r': case 6: menu_fini (); *auto_boot = 0; return current_entry; case '\e': if (nested) { menu_fini (); return -1; } break; case 'c': menu_fini (); grub_cmdline_run (1); goto refresh; case 'e': menu_fini (); { grub_menu_entry_t e = grub_menu_get_entry (menu, current_entry); if (e) grub_menu_entry_run (e); } goto refresh; default: break; } } }