Description: fdasd: fix generation of disk label for option 'auto' and 'config'
Symptom:     When fdasd is used with option 'config' or 'auto' on a device
             that has no valid disk label, then it may stop with the question,
             'Should I create a new one? (y/n)' or completely fail with
             the message:
             'Disc does not contain a VOL1 label, cannot create partitions.'
Problem:     The code that checks for a valid volume label does not
             correctly differentiate between interactive and non
             interactiv use.
Solution:    Fix checking.
Problem-ID:  74047
---
 fdasd/fdasd.c |  161 +++++++++++++++++++---------------------------------------
 1 file changed, 54 insertions(+), 107 deletions(-)

--- a/fdasd/fdasd.c
+++ b/fdasd/fdasd.c
@@ -819,56 +819,55 @@ fdasd_verify_options (fdasd_anchor_t *an
 	/*                        ser                        */
 	/*                                                   */
 	/* volser       -    inv  INV  inv  inv  inv         */
-	/* label             -    inv  REQ  INV  inv         */
-	/* keep_volser            -    REQ  INV  inv         */
-	/* auto                        -    inv  inv         */
-	/* config                           -    inv         */
+	/* label             -    inv  REQ  REQ  inv         */
+	/* keep_volser            -    REQ  REQ  inv         */
+	/* auto              opt  opt  -    inv  inv         */
+	/* config            opt  opt       -    inv         */
 	/* table                                 -           */
 
-	if (anc->print_volser && 
+	if (anc->print_volser &&
 	    (options.volser || anc->keep_volser || anc->auto_partition ||
 	     options.conffile || anc->print_table)) {
-		fdasd_error(anc, parser_failed, 
+		fdasd_error(anc, parser_failed,
 			    "Option 'volser' cannot be used with other"
 			    " options.\n");
 	}
 
 	if (options.volser) {
-		if (!anc->auto_partition) {
-			fdasd_error(anc, parser_failed, 
-				    "Option 'auto' required when specifying"
-				    " 'label'\n");
-		}
-		if ((anc->keep_volser || options.conffile || 
-		     anc->print_table)) {
-			fdasd_error(anc, parser_failed, 
+		if (!anc->auto_partition && !options.conffile) {
+			fdasd_error(anc, parser_failed,
+				    "Option 'auto' or 'config' required when"
+				    " specifying 'label'\n");
+		}
+		if ((anc->keep_volser || anc->print_table)) {
+			fdasd_error(anc, parser_failed,
 				    "Option 'label' cannot be used with "
-				    "'keep_volser', 'config' and 'table'.\n");
+				    "'keep_volser' and 'table'.\n");
 		}
 	}
 
 	if (anc->keep_volser) {
-		if (!anc->auto_partition) {
-			fdasd_error(anc, parser_failed, 
-				    "Option 'auto' required when specifying"
-				    " 'keep_volser'\n");
+		if (!anc->auto_partition && !options.conffile) {
+			fdasd_error(anc, parser_failed,
+				    "Option 'auto' or 'config' required when"
+				    " specifying 'keep_volser'\n");
 		}
-		if (options.conffile || anc->print_table) {
-			fdasd_error(anc, parser_failed, 
+		if (anc->print_table) {
+			fdasd_error(anc, parser_failed,
 				    "Option 'keep_volser' cannot be used"
-				    " with 'config' and 'table'.\n");
+				    " with 'table'.\n");
 		}
 	}
-	if (anc->auto_partition && 
+	if (anc->auto_partition &&
 	    (options.conffile || anc->print_table)) {
-		fdasd_error(anc, parser_failed, 
+		fdasd_error(anc, parser_failed,
 			    "Option 'auto' cannot be used with "
 			    "'config' and 'table'.\n");
 	}
-	
-	if (options.conffile  && 
+
+	if (options.conffile  &&
 	    (anc->print_table)) {
-		fdasd_error(anc, parser_failed, 
+		fdasd_error(anc, parser_failed,
 			    "Option 'config' cannot be used with"
 			    " 'table'.\n");
 	}
@@ -1545,35 +1544,33 @@ fdasd_change_part_type (fdasd_anchor_t *
  * initialize the VOL1 volume label
  */
 static void
-fdasd_init_volume_label (fdasd_anchor_t *anc) 
+fdasd_init_volume_label(fdasd_anchor_t *anc)
 {
 	volume_label_t *vlabel = anc->vlabel;
-	char old_volser[VOLSER_LENGTH + 1];
+	char volser[VOLSER_LENGTH + 1];
 
 	vtoc_volume_label_init(vlabel);
 	vtoc_volume_label_set_key(vlabel, "VOL1");
 	vtoc_volume_label_set_label(vlabel, "VOL1");
 
 	if (anc->keep_volser) {
-		if(fdasd_get_volser(anc, options.device, old_volser) == 0)
-			vtoc_volume_label_set_volser(vlabel, old_volser);
-		else {
+		if(fdasd_get_volser(anc, options.device, volser) == 0)
+			vtoc_volume_label_set_volser(vlabel, volser);
+		else
 			fdasd_error(anc, volser_not_found, options.device);
-		}
-	}
-	else {
-		if (options.volser == NULL) {
-	        	printf("\nPlease specify volume serial (6 characters)"
-			       "[0X%04x]: ", 
-			       anc->devno);
-			read_line();
-			fdasd_check_volser(line_ptr, anc->devno);
-			vtoc_volume_label_set_volser(vlabel, line_ptr);
-		} else {
-			fdasd_check_volser(options.volser, anc->devno);
-			vtoc_volume_label_set_volser(vlabel, options.volser);
-		}
-
+	} else if (options.volser) {
+		fdasd_check_volser(options.volser, anc->devno);
+		vtoc_volume_label_set_volser(vlabel, options.volser);
+	} else if (anc->auto_partition || options.conffile) {
+		sprintf(volser, "0X%04x", anc->devno);
+		vtoc_volume_label_set_volser(vlabel, volser);
+	} else {
+		printf("\nPlease specify volume serial (6 characters)"
+		       "[0X%04x]: ",
+		       anc->devno);
+		read_line();
+		fdasd_check_volser(line_ptr, anc->devno);
+		vtoc_volume_label_set_volser(vlabel, line_ptr);
 	}
 
 	vtoc_set_cchhb(&vlabel->vtoc, VTOC_START_CC, VTOC_START_HH, 0x01);
@@ -1929,12 +1926,13 @@ fdasd_check_volume (fdasd_anchor_t *anc)
 			if (!anc->silent)
 				printf(" LNX1\n");
 			strcpy(inp_buf,"Overwrite inapplicable label?");
-		}
-		else {
+		} else {
 			if (!anc->silent)
 				printf(" no known label\n");
-			if (!anc->auto_partition)
+			if (!anc->auto_partition && !options.conffile)
 				rc = yes_no("Should I create a new one?");
+			else
+				rc = 0;
 		}
                 if ((!anc->print_volser) && (!anc->print_table) && (rc == 1)) {
 			printf("Disc does not contain a VOL1 label, cannot "
@@ -1943,9 +1941,10 @@ fdasd_check_volume (fdasd_anchor_t *anc)
                 }
 
 		if (anc->hw_cylinders > LV_COMPAT_CYL) {
-			printf("Warning: Device has more then %u cylinders!\n",
+			printf("Warning: Device has more than %u cylinders!\n",
 			       LV_COMPAT_CYL);
-			if (yes_no("Are you sure it was completely"
+			if (!anc->auto_partition && !options.conffile &&
+			    yes_no("Are you sure it was completely"
 				   " formatted with dasdfmt?") == 1) {
 				if (!anc->silent) printf("exiting...\n");
 				fdasd_exit(anc, 0);
@@ -2571,43 +2570,17 @@ fdasd_remove_partition (fdasd_anchor_t *
 static void
 fdasd_auto_partition(fdasd_anchor_t *anc)
 {
-	volume_label_t *vlabel = anc->vlabel;
 	partition_info_t *part_info = anc->first;
 	cchh_t llimit,ulimit;
 	cchhb_t hf1;
 	extent_t ext;
-	char volser[VOLSER_LENGTH + 1];
 	u_int32_t cyl;
 	u_int16_t head;
-	char old_volser[VOLSER_LENGTH + 1];
 
 	if (!anc->silent)
 		printf("auto-creating one partition for the whole disk...\n");
 
-	vtoc_volume_label_init(vlabel);
-	vtoc_volume_label_set_key(vlabel, "VOL1");
-	vtoc_volume_label_set_label(vlabel, "VOL1");
-
-	if (anc->keep_volser) {
-		if(fdasd_get_volser(anc, options.device, old_volser) == 0)
-			vtoc_volume_label_set_volser(vlabel, old_volser);
-		else {
-			fdasd_error(anc, volser_not_found, options.device);
-		}
-	}
-	else {
-		if (options.volser == NULL) 
-			sprintf(volser, "0X%04x", anc->devno);
-		else {
-			bzero(volser, VOLSER_LENGTH + 1);
-			strncpy(volser, options.volser, VOLSER_LENGTH);
-			fdasd_check_volser(volser, anc->devno);
-		}
-		vtoc_volume_label_set_volser(vlabel, volser);
-
-	}
-
-	vtoc_set_cchhb(&vlabel->vtoc, VTOC_START_CC, VTOC_START_HH, 0x01);
+	fdasd_init_volume_label(anc);
 
 	if (anc->verbose) printf("initializing labels...\n");
 	vtoc_init_format4_label(anc->f4, USABLE_PARTITIONS,
@@ -2644,7 +2617,6 @@ fdasd_auto_partition(fdasd_anchor_t *anc
 	get_addr_of_highest_f1_f8_label(anc, &hf1);
 	vtoc_update_format4_label(anc->f4, &hf1, anc->f4->DS4DSREC - 1);
 
-	anc->vlabel_changed++;
 	anc->vtoc_changed++;
 
 	fdasd_write_labels(anc);
@@ -2660,37 +2632,13 @@ fdasd_auto_partition_conffile(fdasd_anch
 {
 	volume_label_t *vlabel = anc->vlabel;
 	partition_info_t *part_info = anc->first;
-	char volser[VOLSER_LENGTH + 1];
 	cchh_t llimit,ulimit;
 	unsigned long start, stop;
 	extent_t ext;
 	cchhb_t hf1;
-	char old_volser[VOLSER_LENGTH + 1], *type;
-
+	char *type;
 
-	vtoc_volume_label_init(vlabel);
-	vtoc_volume_label_set_key(vlabel, "VOL1");
-	vtoc_volume_label_set_label(vlabel, "VOL1");
-
-	if (anc->keep_volser) {
-		if(fdasd_get_volser(anc, options.device, old_volser) == 0)
-			vtoc_volume_label_set_volser(vlabel, old_volser);
-		else {
-			fdasd_error(anc, volser_not_found, options.device);
-		}
-	}
-	else {
-		if (options.volser == NULL)
-			sprintf(volser, "0X%04x", anc->devno);
-		else {
-			bzero(volser, VOLSER_LENGTH + 1);
-			strncpy(volser, options.volser, VOLSER_LENGTH);
-			fdasd_check_volser(volser, anc->devno);
-		}
-		vtoc_volume_label_set_volser(vlabel, volser);
-	}
-
-	vtoc_set_cchhb(&vlabel->vtoc, VTOC_START_CC, VTOC_START_HH, 0x01);
+	fdasd_init_volume_label(anc);
 
 	if (anc->verbose) printf("initializing labels...\n");
 	vtoc_init_format4_label(anc->f4, USABLE_PARTITIONS,
@@ -2762,7 +2710,6 @@ fdasd_auto_partition_conffile(fdasd_anch
 				part_info->f1->DS1DSNAM, 44);
 	} while ((part_info = part_info->next) != NULL);
 
-	anc->vlabel_changed++;
 	anc->vtoc_changed++;
 
 	fdasd_write_labels(anc);
