===== tools/pygrub/src/pygrub 1.3 vs edited ===== --- 1.3/tools/pygrub/src/pygrub 2005-04-27 17:57:44 +09:00 +++ edited/tools/pygrub/src/pygrub 2005-05-21 22:33:09 +09:00 @@ -4,6 +4,8 @@ # # Copyright 2005 Red Hat, Inc. # Jeremy Katz +# +# Copyright (C) 2005 Nguyen Anh Quynh # # This software may be freely redistributed under the terms of the GNU # general public license. @@ -16,60 +18,71 @@ import os, sys, string, struct, tempfile import logging -import curses, _curses, curses.wrapper +import curses, curses.wrapper import getopt -sys.path = [ '/usr/lib/python' ] + sys.path +sys.path = sys.path + [ '/usr/lib/python' ] import grub.GrubConf import grub.fsys PYGRUB_VER = 0.02 +SIZEY = 10 +SIZEX = 74 +TOPY = 2 +TOPX = 1 - -def draw_window(): +def draw_window(cf): stdscr = curses.initscr() - curses.use_default_colors() + # curses.use_default_colors() try: curses.curs_set(0) except _curses.error: pass - stdscr.addstr(1, 4, "pyGRUB version %s" %(PYGRUB_VER,)) + color = cf.get_color() + if color != "self.color": # show grub menu with color + if curses.has_colors(): + curses.start_color() + menucolor = color[0] + itemcolor = color[1] + exec("curses.init_pair(1, curses.COLOR_%s, curses.COLOR_%s)" %(menucolor[0].upper(), menucolor[1].upper())) + exec("curses.init_pair(2, curses.COLOR_%s, curses.COLOR_%s)" %(itemcolor[0].upper(), itemcolor[1].upper())) + else: + color = "self.color" + + stdscr.addstr(1, 4, "pyGRUB version %s" %(PYGRUB_VER,)) - win = curses.newwin(10, 74, 2, 1) + win = curses.newwin(SIZEY, SIZEX, TOPY, TOPX) win.box() win.refresh() - stdscr.addstr(12, 5, "Use the U and D keys to select which entry is highlighted.") - stdscr.addstr(13, 5, "Press enter to boot the selected OS. 'e' to edit the") - stdscr.addstr(14, 5, "commands before booting, 'a' to modify the kernel arguments ") - stdscr.addstr(15, 5, "before booting, or 'c' for a command line.") - stdscr.addch(12, 13, curses.ACS_UARROW) - stdscr.addch(12, 19, curses.ACS_DARROW) - (y, x) = stdscr.getmaxyx() - stdscr.move(y - 1, x - 1) + stdscr.addstr(SIZEY + TOPY, TOPX + 4, "Use the U and D keys to select which entry is highlighted.") + stdscr.addstr(TOPY + SIZEY + 1, TOPX + 4, "Press enter to boot the selected OS. 'e' to edit the") + stdscr.addstr(TOPY + SIZEY + 2, TOPX + 4, "commands before booting, 'a' to modify the kernel arguments ") + stdscr.addstr(TOPY + SIZEY + 3, TOPX + 4, "before booting, or 'c' for a command line.") + stdscr.addstr(TOPY + SIZEY + 4, TOPX + 4, "Press 'q' to quit.") + stdscr.addch(TOPY + SIZEY, TOPX + 12, curses.ACS_UARROW) + stdscr.addch(TOPY + SIZEY, TOPX + 18, curses.ACS_DARROW) stdscr.refresh() return (stdscr, win) -def fill_entries(win, cfg, selected): - y = 0 +def fill_entries(win, cfg, top, selected): + color = cf.get_color() + if color != "self.color": # show grub menu with color + menucolor = curses.color_pair(1) + itemcolor = curses.color_pair(2) + else: + menucolor = 0 + itemcolor = curses.A_REVERSE - for i in cfg.images: - if (0, y) > win.getmaxyx(): - break - if y == selected: - attr = curses.A_REVERSE + for i in range(top, min(top + SIZEY - 2, len(cfg.images))): + if i == selected: + attr = itemcolor else: - attr = 0 - win.addstr(y + 1, 2, i.title.ljust(70), attr) - y += 1 - win.refresh() - -def select(win, line): - win.attron(curses.A_REVERSE) - win.redrawln(line + 1, 1) + attr = menucolor + win.addstr(i - top + 1, 2, ' ' + cfg.images[i].title.ljust(SIZEX - 5)[:SIZEX - 5], attr) win.refresh() def is_disk_image(file): @@ -77,18 +90,19 @@ buf = os.read(fd, 512) os.close(fd) - if len(buf) >= 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaaff): + if len(buf) == 512 and struct.unpack("H", buf[0x1fe: 0x200]) == (0xaaff): return True return False def get_config(fn): + if not os.access(fn, os.R_OK): raise RuntimeError, "Unable to access %s" %(fn,) cf = grub.GrubConf.GrubConfigFile() if is_disk_image(fn): - raise RuntimeError, "appears to be a full disk image... unable to handle this yet" + raise RuntimeError, "Appears to be a full disk image... unable to handle this yet" # open the image and read the grub config fs = None @@ -103,7 +117,7 @@ elif fs.file_exist("/boot/grub/grub.conf"): grubfile = "/boot/grub/grub.conf" else: - raise RuntimeError, "we couldn't find /boot/grub{menu.lst,grub.conf} " + \ + raise RuntimeError, "We couldn't find /boot/grub/{menu.lst,grub.conf} " + \ "in the image provided. halt!" f = fs.open_file(grubfile) buf = f.read() @@ -136,24 +150,28 @@ def main(cf = None): mytime = 0 - (stdscr, win) = draw_window() + (stdscr, win) = draw_window(cf) stdscr.timeout(1000) selected = cf.default + top = 0 + stdscr.addstr(SIZEY + TOPY + 8, TOPX + 4, "Will boot selected entry in %2d seconds" + %(int(cf.timeout) - mytime)) while (mytime < int(cf.timeout)): - if cf.timeout != -1 and mytime != -1: - stdscr.addstr(20, 5, "Will boot selected entry in %2d seconds" - %(int(cf.timeout) - mytime)) - else: - stdscr.addstr(20, 5, " " * 80) - fill_entries(win, cf, selected) + fill_entries(win, cf, top, selected) c = stdscr.getch() - if mytime != -1: - mytime += 1 -# if c == ord('q'): -# selected = -1 -# break + if (c == -1): + if mytime != -1: + mytime += 1 + stdscr.addstr(SIZEY + TOPY + 8, TOPX + 4, "Will boot selected entry in %2d seconds" + %(int(cf.timeout) - mytime)) + elif mytime != -1: + stdscr.addstr(SIZEY + TOPY + 8, TOPX + 4, " " * 80) + mytime = -1 + if c == ord('q'): + selected = -1 + break elif c == ord('c'): # FIXME: needs to go to command line mode continue @@ -164,30 +182,36 @@ # FIXME: needs to go to edit mode continue elif c in (curses.KEY_ENTER, ord('\n'), ord('\r')): - break + if not cf.images[selected].get_kernel() == None: # is this an illegal kernel ? + break elif c == curses.KEY_UP: - mytime = -1 - selected -= 1 + if selected == top: + if top > 0: + # bound at the top + top -= 1 + selected = top + else: + selected -= 1 elif c == curses.KEY_DOWN: - mytime = -1 - selected += 1 - else: - pass + if selected == len(cf.images) - 1: + continue + if selected == top + SIZEY - 3: + if top + SIZEY - 2 < len(cf.images): + # bound at the bottom + top +=1 + selected = top + SIZEY - 3 + else: + selected += 1 - # bound at the top and bottom - if selected < 0: - selected = 0 - elif selected >= len(cf.images): - selected = len(cf.images) - 1 - - if selected >= 0: - return selected + return selected if __name__ == "__main__": sel = None + cf = None def run_main(scr, *args): global sel + global cf sel = main(cf) def usage(): @@ -229,13 +253,15 @@ cf = get_config(file) if interactive: curses.wrapper(run_main) + if sel == -1: # user has chosen to quit + sys.exit(1) else: sel = cf.default # set the entry to boot as requested if entry is not None: idx = get_entry_idx(cf, entry) - if idx is not None and idx > 0 and idx < len(cf.images): + if idx is not None and idx >= 0 and idx < len(cf.images): sel = idx img = cf.images[sel] @@ -244,35 +270,29 @@ if img.initrd: print " initrd: %s" %(img.initrd[1],) - if is_disk_image(file): - raise RuntimeError, "unable to handle full disk images yet" - # read the kernel and initrd onto the hostfs fs = None for fstype in grub.fsys.fstypes.values(): if fstype.sniff_magic(file): fs = fstype.open_fs(file) break - - if fs is None: - raise RuntimeError, "Unable to open filesystem" + else: + raise RuntimeError, "Unable to open filesystem or filesystem not supported" kernel = fs.open_file(img.kernel[1],).read() (tfd, fn) = tempfile.mkstemp(prefix="vmlinuz.") os.write(tfd, kernel) os.close(tfd) - sxp = "linux (kernel %s)" %(fn,) + sxp = "linux (kernel %s) " %(fn,) if img.initrd: initrd = fs.open_file(img.initrd[1],).read() (tfd, fn) = tempfile.mkstemp(prefix="initrd.") os.write(tfd, initrd) os.close(tfd) - sxp += "(ramdisk %s)" %(fn,) - else: - initrd = None - sxp += "(args '%s')" %(img.args,) + sxp += "(ramdisk %s) " %(fn,) + + sxp += "(args '%s')\n" %(img.args,) sys.stdout.flush() os.write(fd, sxp) -