static void show_fkey(int key) { int fkey; while (1) { switch (key) { case KEY_F1: fkey = 0; break; case KEY_F2: fkey = 1; break; case KEY_F3: fkey = 2; break; case KEY_F4: fkey = 3; break; case KEY_F5: fkey = 4; break; case KEY_F6: fkey = 5; break; case KEY_F7: fkey = 6; break; case KEY_F8: fkey = 7; break; case KEY_F9: fkey = 8; break; case KEY_F10: fkey = 9; break; case KEY_F11: fkey = 10; break; case KEY_F12: fkey = 11; break; default: fkey = -1; break; } if (fkey == -1) break; if (cm->fkeyhelp[fkey].textname) key = show_message_file(cm->fkeyhelp[fkey].textname, cm->fkeyhelp[fkey].background); else break; } }
int handle_cwd(void) { struct stat statbuf; if (!qualify_validate(req_param)) return 1; if (fullpath.len > 1) { if (stat(fullpath.s+1, &statbuf) == -1) return respond(550, 1, "Directory does not exist."); if (!S_ISDIR(statbuf.st_mode)) return respond(550, 1, "Is not a directory."); if (access(fullpath.s+1, X_OK) == -1) return respond_permission_denied(); } if (!str_copy(&cwd, &fullpath)) return respond_internal_error(); show_message_file(250); return respond(250, 1, "Changed directory."); }
static const char *run_menu(void) { int key; int done = 0; volatile int entry = cm->curentry; int prev_entry = -1; volatile int top = cm->curtop; int prev_top = -1; int clear = 1, to_clear; const char *cmdline = NULL; volatile clock_t key_timeout, timeout_left, this_timeout; const struct menu_entry *me; bool hotkey = false; /* Note: for both key_timeout and timeout == 0 means no limit */ timeout_left = key_timeout = cm->timeout; /* If we're in shiftkey mode, exit immediately unless a shift key is pressed */ if (shiftkey && !shift_is_held()) { return cm->menu_entries[cm->defentry]->cmdline; } else { shiftkey = 0; } /* Do this before hiddenmenu handling, so we show the background */ prepare_screen_for_menu(); /* Handle hiddenmenu */ if (hiddenmenu) { cmdline = do_hidden_menu(); if (cmdline) return cmdline; /* Otherwise display the menu now; the timeout has already been cancelled, since the user pressed a key. */ hiddenmenu = 0; key_timeout = 0; } /* Handle both local and global timeout */ if (setjmp(timeout_jump)) { entry = cm->defentry; if (top < 0 || top < entry - MENU_ROWS + 1) top = max(0, entry - MENU_ROWS + 1); else if (top > entry || top > max(0, cm->nentries - MENU_ROWS)) top = min(entry, max(0, cm->nentries - MENU_ROWS)); draw_menu(cm->ontimeout ? -1 : entry, top, 1); cmdline = cm->ontimeout ? cm->ontimeout : cm->menu_entries[entry]->cmdline; done = 1; } while (!done) { if (entry <= 0) { entry = 0; while (entry < cm->nentries && is_disabled(cm->menu_entries[entry])) entry++; } if (entry >= cm->nentries - 1) { entry = cm->nentries - 1; while (entry > 0 && is_disabled(cm->menu_entries[entry])) entry--; } me = cm->menu_entries[entry]; if (top < 0 || top < entry - MENU_ROWS + 1) top = max(0, entry - MENU_ROWS + 1); else if (top > entry || top > max(0, cm->nentries - MENU_ROWS)) top = min(entry, max(0, cm->nentries - MENU_ROWS)); /* Start with a clear screen */ if (clear) { /* Clear and redraw whole screen */ /* Enable ASCII on G0 and DEC VT on G1; do it in this order to avoid confusing the Linux console */ if (clear >= 2) prepare_screen_for_menu(); clear_screen(); clear = 0; prev_entry = prev_top = -1; } if (top != prev_top) { draw_menu(entry, top, 1); display_help(me->helptext); } else if (entry != prev_entry) { draw_row(prev_entry - top + 4 + VSHIFT, entry, top, 0, 0); draw_row(entry - top + 4 + VSHIFT, entry, top, 0, 0); display_help(me->helptext); } prev_entry = entry; prev_top = top; cm->curentry = entry; cm->curtop = top; /* Cursor movement cancels timeout */ if (entry != cm->defentry) key_timeout = 0; if (key_timeout) { int tol = timeout_left / CLK_TCK; print_timeout_message(tol, TIMEOUT_ROW, cm->messages[MSG_AUTOBOOT]); to_clear = 1; } else { to_clear = 0; } if (hotkey && me->immediate) { /* If the hotkey was flagged immediate, simulate pressing ENTER */ key = KEY_ENTER; } else { this_timeout = min(min(key_timeout, timeout_left), (clock_t) CLK_TCK); key = mygetkey(this_timeout); if (key != KEY_NONE) { timeout_left = key_timeout; if (to_clear) printf("\033[%d;1H\1#0\033[K", TIMEOUT_ROW); } } hotkey = false; switch (key) { case KEY_NONE: /* Timeout */ /* This is somewhat hacky, but this at least lets the user know what's going on, and still deals with "phantom inputs" e.g. on serial ports. Warning: a timeout will boot the default entry without any password! */ if (key_timeout) { if (timeout_left <= this_timeout) longjmp(timeout_jump, 1); timeout_left -= this_timeout; } break; case KEY_CTRL('L'): clear = 1; break; case KEY_ENTER: case KEY_CTRL('J'): key_timeout = 0; /* Cancels timeout */ if (me->passwd) { clear = 1; done = ask_passwd(me->passwd); } else { done = 1; } cmdline = NULL; if (done) { switch (me->action) { case MA_CMD: cmdline = me->cmdline; break; case MA_SUBMENU: case MA_GOTO: case MA_EXIT: done = 0; clear = 2; cm = me->submenu; entry = cm->curentry; top = cm->curtop; break; case MA_QUIT: /* Quit menu system */ done = 1; clear = 1; draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0); break; case MA_HELP: key = show_message_file(me->cmdline, me->background); /* If the exit was an F-key, display that help screen */ show_fkey(key); done = 0; clear = 1; break; default: done = 0; break; } } if (done && !me->passwd) { /* Only save a new default if we don't have a password... */ if (me->save && me->label) { syslinux_setadv(ADV_MENUSAVE, strlen(me->label), me->label); syslinux_adv_write(); } } break; case KEY_UP: case KEY_CTRL('P'): while (entry > 0) { entry--; if (entry < top) top -= MENU_ROWS; if (!is_disabled(cm->menu_entries[entry])) break; } break; case KEY_DOWN: case KEY_CTRL('N'): while (entry < cm->nentries - 1) { entry++; if (entry >= top + MENU_ROWS) top += MENU_ROWS; if (!is_disabled(cm->menu_entries[entry])) break; } break; case KEY_PGUP: case KEY_LEFT: case KEY_CTRL('B'): case '<': entry -= MENU_ROWS; top -= MENU_ROWS; while (entry > 0 && is_disabled(cm->menu_entries[entry])) { entry--; if (entry < top) top -= MENU_ROWS; } break; case KEY_PGDN: case KEY_RIGHT: case KEY_CTRL('F'): case '>': case ' ': entry += MENU_ROWS; top += MENU_ROWS; while (entry < cm->nentries - 1 && is_disabled(cm->menu_entries[entry])) { entry++; if (entry >= top + MENU_ROWS) top += MENU_ROWS; } break; case '-': while (entry > 0) { entry--; top--; if (!is_disabled(cm->menu_entries[entry])) break; } break; case '+': while (entry < cm->nentries - 1) { entry++; top++; if (!is_disabled(cm->menu_entries[entry])) break; } break; case KEY_CTRL('A'): case KEY_HOME: top = entry = 0; break; case KEY_CTRL('E'): case KEY_END: entry = cm->nentries - 1; top = max(0, cm->nentries - MENU_ROWS); break; case KEY_F1: case KEY_F2: case KEY_F3: case KEY_F4: case KEY_F5: case KEY_F6: case KEY_F7: case KEY_F8: case KEY_F9: case KEY_F10: case KEY_F11: case KEY_F12: show_fkey(key); clear = 1; break; case KEY_TAB: if (cm->allowedit && me->action == MA_CMD) { int ok = 1; key_timeout = 0; /* Cancels timeout */ draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0); if (cm->menu_master_passwd) { ok = ask_passwd(NULL); clear_screen(); draw_menu(-1, top, 0); } else { /* Erase [Tab] message and help text */ printf("\033[%d;1H\1#0\033[K", TABMSG_ROW); display_help(NULL); } if (ok) { cmdline = edit_cmdline(me->cmdline, top); done = !!cmdline; clear = 1; /* In case we hit [Esc] and done is null */ } else { draw_row(entry - top + 4 + VSHIFT, entry, top, 0, 0); } } break; case KEY_CTRL('C'): /* Ctrl-C */ case KEY_ESC: /* Esc */ if (cm->parent) { cm = cm->parent; clear = 2; entry = cm->curentry; top = cm->curtop; } else if (cm->allowedit) { done = 1; clear = 1; key_timeout = 0; draw_row(entry - top + 4 + VSHIFT, -1, top, 0, 0); if (cm->menu_master_passwd) done = ask_passwd(NULL); } break; default: if (key > 0 && key < 0xFF) { key &= ~0x20; /* Upper case */ if (cm->menu_hotkeys[key]) { key_timeout = 0; entry = cm->menu_hotkeys[key]->entry; /* Should we commit at this point? */ hotkey = true; } } break; } } printf("\033[?25h"); /* Show cursor */ /* Return the label name so localboot and ipappend work */ return cmdline; }
int startup(int argc, char* argv[]) { const char* tmp; const char* end; const char* cwdstr; char* ptr; unsigned long session_timeout; unsigned startup_code; if ((tmp = getenv("TCPLOCALIP")) == 0) FAIL("Missing $TCPLOCALIP."); if (!parse_localip(tmp)) FAIL("Could not parse $TCPLOCALIP."); if ((tmp = getenv("TCPREMOTEIP")) == 0) FAIL("Missing $TCPREMOTEIP."); if (!parse_remoteip(tmp)) FAIL("Could not parse $TCPREMOTEIP."); if ((tmp = getenv("UID")) == 0) FAIL("Missing $UID."); if (!(uid = strtou(tmp, &end)) || *end) FAIL("Invalid $UID."); if ((tmp = getenv("GID")) == 0) FAIL("Missing $GID."); if (!(gid = strtou(tmp, &end)) || *end) FAIL("Invalid $GID."); if ((home = getenv("HOME")) == 0) FAIL("Missing $HOME."); if ((tmp = getenv("GIDS")) != 0 && !parse_gids(tmp)) FAIL("Could not parse or set supplementary group IDs."); /* Strip off trailing slashes in $HOME */ ptr = (char*)home + strlen(home)-1; while (ptr > home && *ptr == '/') *ptr-- = 0; if ((user = getenv("USER")) == 0) FAIL("Missing $USER."); if ((group = getenv("GROUP")) == 0) group = "mygroup"; if (chdir(home)) FAIL("Could not chdir to $HOME."); if (!load_tables()) FAIL("Loading startup tables failed."); if (getenv("CHROOT") != 0) { cwdstr = "/"; if (chroot(".")) FAIL("Could not chroot."); } else if (getenv("SOFTCHROOT") != 0) { cwdstr = "/"; } else { cwdstr = home; if (chdir("/")) FAIL("Could not chdir to '/'."); } if (!str_copys(&cwd, cwdstr)) FAIL("Could not set CWD string"); if (setgid(gid)) FAIL("Could not set GID."); if (setuid(uid)) FAIL("Could not set UID."); if ((user_len = strlen(user)) > MAX_NAME_LEN) { user_len = MAX_NAME_LEN; ((char*)user)[MAX_NAME_LEN] = 0; } if ((group_len = strlen(group)) > MAX_NAME_LEN) { group_len = MAX_NAME_LEN; ((char*)group)[MAX_NAME_LEN] = 0; } lockhome = (getenv("LOCKHOME") != 0); nodotfiles = (getenv("NODOTFILES") != 0); list_options = (nodotfiles ? 0 : PATH_MATCH_DOTFILES); session_timeout = 0; if ((tmp = getenv("SESSION_TIMEOUT")) != 0) session_timeout = strtou(tmp, &tmp); alarm(session_timeout); connect_timeout = timeout; if ((tmp = getenv("CONNECT_TIMEOUT")) != 0) connect_timeout = strtou(tmp, &tmp); if ((tmp = getenv("TWOFTPD_BIND_PORT_FD")) != 0) { if ((bind_port_fd = strtou(tmp, &end)) == 0 || *end != 0) FAIL("Invalid $TWOFTPD_BIND_PORT_FD"); } else bind_port_fd = -1; startup_code = (getenv("AUTHENTICATED") != 0) ? 230 : 220; if ((tmp = getenv("BANNER")) != 0) show_banner(startup_code, tmp); message_file = getenv("MESSAGEFILE"); show_message_file(startup_code); return respond(startup_code, 1, "Ready to transfer files."); (void)argc; (void)argv; }