[PATCH 2/2] ui/ncurses: Add device hierarchy

Samuel Mendoza-Jonas sam.mj at au1.ibm.com
Thu Jul 3 15:53:51 EST 2014


Boot options are now listed under their matching boot device in the
ncurses UI to help differentitate similar boot option names

Signed-off-by: Samuel Mendoza-Jonas <sam.mj at au1.ibm.com>
---
 ui/ncurses/nc-cui.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 114 insertions(+), 5 deletions(-)

diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index 7200a81..9e71097 100644
--- a/ui/ncurses/nc-cui.c
+++ b/ui/ncurses/nc-cui.c
@@ -26,6 +26,7 @@
 #include <string.h>
 #include <locale.h>
 #include <sys/ioctl.h>
+#include <util/util.h>
 
 #include "log/log.h"
 #include "pb-protocol/pb-protocol.h"
@@ -407,10 +408,13 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
 {
 	struct cui *cui = cui_from_arg(arg);
 	struct cui_opt_data *cod;
-	unsigned int insert_pt;
+	unsigned int insert_pt, j;
 	int result, rows, cols;
-	struct pmenu_item *i;
+	int newdev = 1;
+	size_t len;
+	struct pmenu_item *i, *dev_hdr;
 	ITEM *selected;
+	char *shift;
 
 	pb_debug("%s: %p %s\n", __func__, opt, opt->id);
 
@@ -420,9 +424,96 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
 	if (cui->current == &cui->main->scr)
 		nc_scr_unpost(cui->current);
 
+
+	/* Check if device header exists */
+	for (j=0; j < cui->main->item_count; j++){
+		struct pmenu_item *item = item_userptr(cui->main->items[j]);
+		struct cui_opt_data *data = item->data;
+		/* boot entries will have this defined */
+		if(!data || data->opt)
+			continue;
+		if(!strcmp(data->name,opt->device_id)){
+			pb_debug("%s: %s fits under %s\n",__func__,
+				 opt->name, opt->device_id);
+			newdev = 0;
+			break;
+		}
+	}
+
+	/* Create a dummy pmenu_item to represent the dev */
+	if (newdev) {
+		char *buf = talloc_array(cui->main, char, sizeof(char)*256);
+		struct system_info *sys = cui->sysinfo;
+		int matched;
+		switch (dev->type) {
+		case DEVICE_TYPE_OPTICAL:
+		case DEVICE_TYPE_DISK:
+		{
+			/* find block info */
+			for (j=0; sys && j < sys->n_blockdevs; j++){
+				struct blockdev_info *bd = sys->blockdevs[j];
+				if (!strcmp(opt->device_id,bd->name)){
+					snprintf(buf,sizeof(char)*256,"[%s: %s / %s]",
+						 dev->type == DEVICE_TYPE_DISK ? "Disk" : "CD/DVD",
+						 bd->name, bd->uuid);
+					matched = 1;
+					break;
+				}
+			}
+			break;
+		}
+		case DEVICE_TYPE_NETWORK:
+		{
+			/* find interface info */
+			char *hwaddr = talloc_array(cui->main, char, 32);
+			for (j=0; sys && j < sys->n_interfaces; j++){
+				struct interface_info *intf = sys->interfaces[j];
+				if (!strcmp(opt->device_id,intf->name)){
+					mac_str(intf->hwaddr, intf->hwaddr_size, hwaddr, 32);
+					snprintf(buf,sizeof(char)*256,"[Interface: %s / %s]",
+						 intf->name, hwaddr);
+					matched = 1;
+					break;
+				}
+			}
+			talloc_free(hwaddr);
+			break;
+		}
+		default:
+			/* Assume it might be able to boot */
+			break;
+		}
+		if(!matched){
+			pb_debug("%s: No matching device found for %s (%s)\n",__func__,opt->device_id, dev->id);
+			snprintf(buf,sizeof(char)*256,"[Unknown Device: %s]",dev->id);
+		}
+
+		dev_hdr = pmenu_item_create(cui->main, buf);
+		dev_hdr->on_edit = NULL;
+		dev_hdr->on_execute = NULL;
+		item_opts_off(dev_hdr->nci, O_SELECTABLE);
+
+		/* We identify dev_hdr items as having a valid c->name,
+		 * but a NULL c->opt */
+		struct cui_opt_data *c = talloc(dev_hdr, struct cui_opt_data);
+		c->name = talloc_strdup(dev_hdr, opt->device_id);
+		c->opt = NULL;
+		dev_hdr->data = c;
+		talloc_free(buf);
+	}
+
+	/* All actual boot entries are 'tabbed' across */
+	if(!opt->name)
+		len = sizeof("    Unknown Name");
+	else
+		len = strlen(opt->name) + sizeof(char)*5;
+	shift = talloc_array(cui->main, char, len);
+	snprintf(shift,len,"    %s",opt->name ? opt->name : "Unknown Name");
+
 	/* Save the item in opt->ui_info for cui_device_remove() */
 
-	opt->ui_info = i = pmenu_item_create(cui->main, opt->name);
+	opt->ui_info = i = pmenu_item_create(cui->main, shift);
+	talloc_free(shift);
 	if (!i)
 		return -1;
 
@@ -448,8 +539,15 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
 		pb_log("%s: set_menu_items failed: %d\n", __func__, result);
 
 	/* Insert new items at insert_pt. */
-	insert_pt = pmenu_grow(cui->main, 1);
-	pmenu_item_insert(cui->main, i, insert_pt);
+	if(newdev){
+		insert_pt = pmenu_grow(cui->main, 2);
+		pmenu_item_insert(cui->main, dev_hdr, insert_pt);
+		pb_log("%s: adding new device hierarchy %s\n",__func__,opt->device_id);
+		pmenu_item_insert(cui->main, i, insert_pt+1);
+	} else {
+		insert_pt = pmenu_grow(cui->main, 1);
+		pmenu_item_add(cui->main, i, insert_pt);
+	}
 
 	pb_log("%s: adding opt '%s'\n", __func__, cod->name);
 	pb_log("   image  '%s'\n", cod->bd->image);
@@ -500,6 +598,7 @@ static void cui_device_remove(struct device *dev, void *arg)
 {
 	struct cui *cui = cui_from_arg(arg);
 	int result;
+	unsigned int ind;
 	struct boot_option *opt;
 
 	pb_log("%s: %p %s\n", __func__, dev, dev->id);
@@ -521,6 +620,16 @@ static void cui_device_remove(struct device *dev, void *arg)
 		pmenu_remove(cui->main, i);
 	}
 
+	/* Manually remove remaining device hierarchy item */
+	for (ind=0; ind< cui->main->item_count; ind++) {
+		struct pmenu_item *i = item_userptr(cui->main->items[ind]);
+		if(i && i->data){
+			struct cui_opt_data *data = i->data;
+			if(data && data->name && !strcmp(data->name,dev->id))
+				pmenu_remove(cui->main,i);
+		}
+	}
+
 	/* Re-attach the items array. */
 
 	result = set_menu_items(cui->main->ncm, cui->main->items);
-- 
1.9.3



More information about the Petitboot mailing list