Module Name:    src
Committed By:   martin
Date:           Tue Mar 30 20:09:25 UTC 2010

Modified Files:
        src/distrib/utils/sysinst: menus.mi msg.mi.de msg.mi.en msg.mi.es
            msg.mi.fr msg.mi.pl util.c

Log Message:
Do not bother to ask the user for CD details (like device name or path
on the CD) if we can find CDs (i.e. media, not drives) automagically
and check the standard paths on it.

If we find multiple CDs, offer a menu to select showing the volume
name. If something goes wrong, fall back to the manual input method.

In typical installs this makes us just proceed with extracting the sets
after selecting "install from CD/DVD", w/o any further interaction.

As a side effect fixes PR 43012.
XXX new messages need translations.


To generate a diff of this commit:
cvs rdiff -u -r1.37 -r1.38 src/distrib/utils/sysinst/menus.mi
cvs rdiff -u -r1.51 -r1.52 src/distrib/utils/sysinst/msg.mi.de
cvs rdiff -u -r1.159 -r1.160 src/distrib/utils/sysinst/msg.mi.en
cvs rdiff -u -r1.28 -r1.29 src/distrib/utils/sysinst/msg.mi.es
cvs rdiff -u -r1.109 -r1.110 src/distrib/utils/sysinst/msg.mi.fr
cvs rdiff -u -r1.67 -r1.68 src/distrib/utils/sysinst/msg.mi.pl
cvs rdiff -u -r1.163 -r1.164 src/distrib/utils/sysinst/util.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/utils/sysinst/menus.mi
diff -u src/distrib/utils/sysinst/menus.mi:1.37 src/distrib/utils/sysinst/menus.mi:1.38
--- src/distrib/utils/sysinst/menus.mi:1.37	Wed Dec 16 16:03:26 2009
+++ src/distrib/utils/sysinst/menus.mi	Tue Mar 30 20:09:25 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: menus.mi,v 1.37 2009/12/16 16:03:26 ahoka Exp $	*/
+/*	$NetBSD: menus.mi,v 1.38 2010/03/30 20:09:25 martin Exp $	*/
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -320,7 +320,7 @@
 			clean_xfer_dir = yesno; };
 
 menu cdromsource, y=-4, x=0, w=70, no box, no clear, exitstring MSG_Continue;
-	display action { msg_display(MSG_cdromsource); };
+	display action { msg_display_add(MSG_cdromsource); };
 	option {src_legend(menu, MSG_Device, cdrom_dev);},
 		action { src_prompt(MSG_dev, cdrom_dev, sizeof cdrom_dev); };
 	option {src_legend(menu, MSG_Set_dir, set_dir);},

Index: src/distrib/utils/sysinst/msg.mi.de
diff -u src/distrib/utils/sysinst/msg.mi.de:1.51 src/distrib/utils/sysinst/msg.mi.de:1.52
--- src/distrib/utils/sysinst/msg.mi.de:1.51	Mon Sep  7 02:31:53 2009
+++ src/distrib/utils/sysinst/msg.mi.de	Tue Mar 30 20:09:25 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.de,v 1.51 2009/09/07 02:31:53 jnemeth Exp $	*/
+/*	$NetBSD: msg.mi.de,v 1.52 2010/03/30 20:09:25 martin Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -486,6 +486,16 @@
 
 }
 
+message Available_cds
+{Verfügbare CDs}
+
+message ask_cd
+{Es wurden mehrere CDs gefunden. Bitte wählen Sie die Installations CD aus.}
+
+message cd_path_not_found
+{Die Installationsdateien wurden auf der ausgewählten CD nicht gefunden. Bitte
+prüfen Sie den Gerätenamen und Pfad der Installationsdateien.}
+
 message localfssource
 {Geben Sie das noch nicht gemountete lokale Gerät und dessen entsprechendes
 Verzeichnis an, in dem die Distribution zu finden ist.

Index: src/distrib/utils/sysinst/msg.mi.en
diff -u src/distrib/utils/sysinst/msg.mi.en:1.159 src/distrib/utils/sysinst/msg.mi.en:1.160
--- src/distrib/utils/sysinst/msg.mi.en:1.159	Mon Sep  7 02:31:53 2009
+++ src/distrib/utils/sysinst/msg.mi.en	Tue Mar 30 20:09:25 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.en,v 1.159 2009/09/07 02:31:53 jnemeth Exp $	*/
+/*	$NetBSD: msg.mi.en,v 1.160 2010/03/30 20:09:25 martin Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -471,6 +471,16 @@
 
 }
 
+message Available_cds
+{Available CDs }
+
+message ask_cd
+{Multiple CDs found, please select the one containing the install CD.}
+
+message cd_path_not_found
+{The installation sets have not been found at the default location on this
+CD. Please check device and path name.}
+
 message localfssource
 {Enter the unmounted local device and directory on that device where
 the distribution is located. 

Index: src/distrib/utils/sysinst/msg.mi.es
diff -u src/distrib/utils/sysinst/msg.mi.es:1.28 src/distrib/utils/sysinst/msg.mi.es:1.29
--- src/distrib/utils/sysinst/msg.mi.es:1.28	Mon Sep  7 02:31:53 2009
+++ src/distrib/utils/sysinst/msg.mi.es	Tue Mar 30 20:09:25 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.es,v 1.28 2009/09/07 02:31:53 jnemeth Exp $	*/
+/*	$NetBSD: msg.mi.es,v 1.29 2010/03/30 20:09:25 martin Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -484,6 +484,16 @@
 
 }
 
+message Available_cds
+{Available CDs}
+
+message ask_cd
+{Multiple CDs found, please select the one containing the install CD.}
+
+message cd_path_not_found
+{The installation sets have not been found at the default location on this
+CD. Please check device and path name.}
+
 message localfssource
 {Introduzca el dispositivo local desmontado y el directorio de ese
 dispositivo donde se encuentre la distribución. 

Index: src/distrib/utils/sysinst/msg.mi.fr
diff -u src/distrib/utils/sysinst/msg.mi.fr:1.109 src/distrib/utils/sysinst/msg.mi.fr:1.110
--- src/distrib/utils/sysinst/msg.mi.fr:1.109	Sun Oct 18 19:31:53 2009
+++ src/distrib/utils/sysinst/msg.mi.fr	Tue Mar 30 20:09:25 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.fr,v 1.109 2009/10/18 19:31:53 stacktic Exp $	*/
+/*	$NetBSD: msg.mi.fr,v 1.110 2010/03/30 20:09:25 martin Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -484,6 +484,16 @@
 }
 
 
+message Available_cds
+{Available CDs}
+
+message ask_cd
+{Multiple CDs found, please select the one containing the install CD.}
+
+message cd_path_not_found
+{The installation sets have not been found at the default location on this
+CD. Please check device and path name.}
+
 message localfssource
 {Veuillez spécifier le nom du périphérique local (qui ne doit pas
 être monté) à utiliser. Ce dernier doit contenir les fichiers

Index: src/distrib/utils/sysinst/msg.mi.pl
diff -u src/distrib/utils/sysinst/msg.mi.pl:1.67 src/distrib/utils/sysinst/msg.mi.pl:1.68
--- src/distrib/utils/sysinst/msg.mi.pl:1.67	Mon Sep  7 02:31:53 2009
+++ src/distrib/utils/sysinst/msg.mi.pl	Tue Mar 30 20:09:25 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: msg.mi.pl,v 1.67 2009/09/07 02:31:53 jnemeth Exp $	*/
+/*	$NetBSD: msg.mi.pl,v 1.68 2010/03/30 20:09:25 martin Exp $	*/
 /*	Based on english version: */
 /*	NetBSD: msg.mi.pl,v 1.36 2004/04/17 18:55:35 atatat Exp       */
 
@@ -465,6 +465,16 @@
 
 }
 
+message Available_cds
+{Available CDs}
+
+message ask_cd
+{Multiple CDs found, please select the one containing the install CD.}
+
+message cd_path_not_found
+{The installation sets have not been found at the default location on this
+CD. Please check device and path name.}
+
 message localfssource
 {Podaj niezamountowane lokalne urzadzenie oraz katalog na nim, gdzie
 znajduje sie dystrybucja. 

Index: src/distrib/utils/sysinst/util.c
diff -u src/distrib/utils/sysinst/util.c:1.163 src/distrib/utils/sysinst/util.c:1.164
--- src/distrib/utils/sysinst/util.c:1.163	Wed Jan 27 11:02:03 2010
+++ src/distrib/utils/sysinst/util.c	Tue Mar 30 20:09:25 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: util.c,v 1.163 2010/01/27 11:02:03 jmmv Exp $	*/
+/*	$NetBSD: util.c,v 1.164 2010/03/30 20:09:25 martin Exp $	*/
 
 /*
  * Copyright 1997 Piermont Information Systems Inc.
@@ -40,12 +40,17 @@
 
 #include <stdio.h>
 #include <stdarg.h>
+#include <string.h>
 #include <unistd.h>
+#include <sys/disklabel.h>
+#include <sys/dkio.h>
+#include <sys/ioctl.h>
 #include <sys/types.h>
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <sys/stat.h>
 #include <sys/statvfs.h>
+#include <isofs/cd9660/iso.h>
 #include <curses.h>
 #include <err.h>
 #include <errno.h>
@@ -66,6 +71,9 @@
 #define MD_SETS_VALID SET_KERNEL, SET_SYSTEM, SET_X11, SET_MD
 #endif
 
+#define MAX_CD_DEVS	256	/* how many cd drives do we expect to attach */
+#define ISO_BLKSIZE	ISO_DEFAULT_BLOCK_SIZE
+
 static const char *msg_yes, *msg_no, *msg_all, *msg_some, *msg_none;
 static const char *msg_cur_distsets_row;
 static int select_menu_width;
@@ -145,11 +153,20 @@
 	{NULL,			SET_LAST,		NULL, NULL},
 };
 
+#define MAX_CD_INFOS	16	/* how many media can be found? */
+struct cd_info {
+	char device_name[16];
+	char menu[100];
+};
+static struct cd_info cds[MAX_CD_INFOS];
+
 /*
  * local prototypes 
  */
 
 static int check_for(unsigned int mode, const char *pathname);
+static int get_iso9660_volname(int dev, int sess, char *volname);
+static int get_available_cds(void);
 
 void
 init_set_status(int minimal)
@@ -342,12 +359,138 @@
 }
 
 /*
+ * Get the volume name of a ISO9660 file system
+ */
+static int
+get_iso9660_volname(int dev, int sess, char *volname)
+{
+	int blkno, error, last;
+	char buf[ISO_BLKSIZE];
+	struct iso_volume_descriptor *vd = NULL;
+	struct iso_primary_descriptor *pd = NULL;
+
+	for (blkno = sess+16; blkno < sess+16+100; blkno++) {
+		error = pread(dev, buf, ISO_BLKSIZE, blkno*ISO_BLKSIZE);
+		if (error == -1)
+			return -1;
+		vd = (struct iso_volume_descriptor *)&buf;
+		if (memcmp(vd->id, ISO_STANDARD_ID, sizeof(vd->id)) != 0)
+			return -1;
+		if (isonum_711((const unsigned char *)&vd->type)
+		     == ISO_VD_PRIMARY) {
+			pd = (struct iso_primary_descriptor*)buf;
+			strncpy(volname, pd->volume_id, sizeof pd->volume_id);
+			last = sizeof pd->volume_id-1;
+			while (last >= 0 
+			    && (volname[last] == ' ' || volname[last] == 0))
+				last--;
+			volname[last+1] = 0;
+			return 0;
+		}
+	}
+	return -1;
+}
+
+/*
+ * Get a list of all available CD media (not drives!), return
+ * the number of entries collected.
+ */
+static int
+get_available_cds()
+{
+	char dname[16], volname[80];
+	struct cd_info *info = cds;
+	struct disklabel label;
+	int i, part, dev, error, sess, ready, count = 0;
+
+	for (i = 0; i < MAX_CD_DEVS; i++) {
+		sprintf(dname, "/dev/rcd%d%c", i, 'a'+RAW_PART);
+		dev = open(dname, O_RDONLY, 0);
+		if (dev == -1)
+			break;
+		ready = 0;
+		error = ioctl(dev, DIOCTUR, &ready);
+		if (error != 0 || ready == 0) {
+			close(dev);
+			continue;
+		}
+		error = ioctl(dev, DIOCGDINFO, &label);
+		close(dev);
+		if (error == 0) {
+			for (part = 0; part < label.d_npartitions; part++) {
+				if (label.d_partitions[part].p_fstype
+				    != FS_ISO9660)
+					continue;
+				if (label.d_partitions[part].p_fstype
+				    == FS_ISO9660) {
+					sess = label.d_partitions[part]
+					    .p_cdsession;
+					sprintf(dname, "/dev/rcd%d%c", i,
+					    'a'+part);
+					dev = open(dname, O_RDONLY, 0);
+					if (dev == -1)
+						continue;
+					error = get_iso9660_volname(dev, sess,
+					    volname);
+					close(dev);
+					if (error) continue;
+					sprintf(info->device_name, "cd%d%c",
+						i, 'a'+part);
+					sprintf(info->menu, "%s (%s)",
+						info->device_name,
+						volname);
+				} else {
+					/*
+					 * All install CDs use partition
+					 * a for the sets.
+					 */
+					if (part > 0)
+						continue;
+					sprintf(info->device_name, "cd%d%c",
+						i, 'a'+part);
+					strcpy(info->menu, info->device_name);
+				}
+				info++;
+				if (++count >= MAX_CD_INFOS)
+					break;
+			}
+		}
+	}
+	return count;
+}
+
+static int
+cd_has_sets(void)
+{
+	/* Mount it */
+	if (run_program(RUN_SILENT, "/sbin/mount -rt cd9660 /dev/%s /mnt2",
+	    cdrom_dev) != 0)
+		return 0;
+
+	mnt2_mounted = 1;
+
+	snprintf(ext_dir, sizeof ext_dir, "%s/%s", "/mnt2", set_dir);
+	return dir_exists_p(ext_dir);
+}
+
+
+static int
+set_cd_select(menudesc *m, void *arg)
+{
+	*(int *)arg = m->cursel;
+	return 1;
+}
+
+/*
  * Get from a CDROM distribution.
  */
 int
 get_via_cdrom(void)
 {
+	menu_ent cd_menu[MAX_CD_INFOS];
 	struct statvfs sb;
+	int num_cds, menu_cd, i, selected_cd = 0;
+	bool silent = false;
 
 	/* If root is a CD-ROM and we have sets, skip this step. */
 	if (statvfs(set_dir, &sb) == 0 &&
@@ -356,19 +499,51 @@
 		return SET_OK;
 	}
 
-	/* Get CD-rom device name and path within CD-rom */
-	process_menu(MENU_cdromsource, NULL);
+	num_cds = get_available_cds();
+	if (num_cds <= 0) {
+		silent = true;
+	} else if (num_cds == 1) {
+		/* single CD found, check for sets on it */
+		strcpy(cdrom_dev, cds[0].device_name);
+		if (cd_has_sets())
+			return SET_OK;
+	} else {
+		for (i = 0; i< num_cds; i++) {
+			cd_menu[i].opt_name = cds[i].menu;
+			cd_menu[i].opt_menu = OPT_NOMENU;
+			cd_menu[i].opt_flags = OPT_EXIT;
+			cd_menu[i].opt_action = set_cd_select;
+		}
+		/* create a menu offering available choices */
+		menu_cd = new_menu(MSG_Available_cds,
+			cd_menu, num_cds, -1, 4, 0, 0,
+			MC_SCROLL | MC_NOEXITOPT,
+			NULL, NULL, NULL, NULL, NULL);
+		if (menu_cd == -1)
+			return SET_RETRY;
+		msg_display(MSG_ask_cd);
+		process_menu(menu_cd, &selected_cd);
+		free_menu(menu_cd);
+		strcpy(cdrom_dev, cds[selected_cd].device_name);
+		if (cd_has_sets())
+			return SET_OK;
+	}
 
-	/* Mount it */
-	if (run_program(0, "/sbin/mount -rt cd9660 /dev/%s /mnt2",
-	    cdrom_dev) != 0)
-		return SET_RETRY;
+	if (silent)
+		msg_display("");
+	else {
+		umount_mnt2();
+		msg_display(MSG_cd_path_not_found);
+		msg_display_add("\r\n\r\n");
+	}
 
-	mnt2_mounted = 1;
+	/* ask for paths on the CD */
+	process_menu(MENU_cdromsource, NULL);
 
-	snprintf(ext_dir, sizeof ext_dir, "%s/%s", "/mnt2", set_dir);
+	if (cd_has_sets())
+		return SET_OK;
 
-	return SET_OK;
+	return SET_RETRY;
 }
 
 

Reply via email to