All of lore.kernel.org
 help / color / mirror / Atom feed
From: aq <aquynh@gmail.com>
To: xen-devel <xen-devel@lists.xensource.com>
Subject: Re: [PATCH] pygrub improvements
Date: Mon, 23 May 2005 10:27:46 +0900	[thread overview]
Message-ID: <9cde8bff05052218272012c1ff@mail.gmail.com> (raw)
In-Reply-To: <9cde8bff0505221825523c3508@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 901 bytes --]

hmm... sorry, i have pressed the send button by accidental. here is a
patch of pygrub attached.

On 5/23/05, aq <aquynh@gmail.com> wrote:
> here is a patch for pygrub (tools/pygrub/src/pygrub), which provides:
> 
> - generalize grub menu display (by using constants for menu position and size)
> - support basic grub menu color
> - correctly handle choosing menu item, even if menu size is less then
> number of grub menu items
> - allow user to quit pygrub by pressing 'q'
> - few cleanups
> 
> Signed-off-by: Nguyen Anh Quynh <aquynh@gmail.com>
> 
> for those interested, here is a screenshot of the patched pygrub:
> http://133.27.240.160/xen/pygrub2.png
> 
> $ diffstat pygrub3.patch
>  pygrub |  166 ++++++++++++++++++++++++++++++++++++-----------------------------
>  1 files changed, 93 insertions(+), 73 deletions(-)
> 
> --
> regards,
> aq
> 


-- 
regards,
aq

[-- Attachment #2: pygrub3.patch --]
[-- Type: application/octet-stream, Size: 9712 bytes --]

===== 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 <katzj@redhat.com>
+# 
+# Copyright (C) 2005 Nguyen Anh Quynh <aquynh@gmail.com>
 #
 # 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)
-    

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

  reply	other threads:[~2005-05-23  1:27 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-05-23  1:25 [PATCH] pygrub improvements aq
2005-05-23  1:27 ` aq [this message]
2005-05-27 11:06   ` aq
2005-06-17 20:37     ` Andy Kwong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9cde8bff05052218272012c1ff@mail.gmail.com \
    --to=aquynh@gmail.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.