summaryrefslogtreecommitdiff
path: root/usr/src/cmd/format/add_definition.c
diff options
context:
space:
mode:
authorstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
committerstevel@tonic-gate <none@none>2005-06-14 00:00:00 -0700
commit7c478bd95313f5f23a4c958a745db2134aa03244 (patch)
treec871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/format/add_definition.c
downloadillumos-gate-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz
OpenSolaris Launch
Diffstat (limited to 'usr/src/cmd/format/add_definition.c')
-rw-r--r--usr/src/cmd/format/add_definition.c390
1 files changed, 390 insertions, 0 deletions
diff --git a/usr/src/cmd/format/add_definition.c b/usr/src/cmd/format/add_definition.c
new file mode 100644
index 0000000000..3745782701
--- /dev/null
+++ b/usr/src/cmd/format/add_definition.c
@@ -0,0 +1,390 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 1991-2003 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * This file contains the code to add new disk_type and partition
+ * definitions to a format data file.
+ */
+#include "global.h"
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <memory.h>
+#include <sys/fcntl.h>
+#include <sys/param.h>
+#include <time.h>
+#include <sys/time.h>
+#include <stdarg.h>
+
+#include "add_definition.h"
+#include "misc.h"
+#include "partition.h"
+#include "menu_command.h"
+#include "startup.h"
+
+extern struct ctlr_type ctlr_types[];
+extern int nctypes;
+
+extern int errno;
+
+/* Function prototypes */
+#ifdef __STDC__
+
+static void add_disktype(FILE *fd, struct disk_info *disk_info);
+static void add_partition(FILE *fd, struct disk_info *,
+ struct partition_info *);
+static int add_entry(int col, FILE *fd, char *format, ...);
+
+#else /* __STDC__ */
+
+static void add_disktype();
+static void add_partition();
+static int add_entry();
+
+#endif /* __STDC__ */
+
+/*
+ * Add new definitions for the current disk/partition to a format data file.
+ */
+int
+add_definition()
+{
+ FILE *fd;
+ char *filename;
+ time_t clock;
+ char *prompt;
+ union {
+ int xfoo;
+ char deflt_str[MAXPATHLEN];
+ } x;
+
+ /*
+ * There must be a current disk and partition table
+ */
+ if (cur_disk == NULL) {
+ err_print("No Current Disk.\n");
+ return (0);
+ }
+ if (cur_dtype == NULL) {
+ err_print("Current disk type is not set.\n");
+ return (-1);
+ }
+ if (cur_parts == NULL) {
+ err_print("Current partition is not set.\n");
+ return (-1);
+ }
+ /*
+ * If neither the disk definition nor the partition
+ * information has been changed, there's nothing to save.
+ */
+ if (cur_dtype->dtype_filename != NULL &&
+ cur_parts->pinfo_filename != NULL) {
+ err_print("\
+Neither the disk type nor the partitioning has been changed.\n");
+ return (-1);
+ }
+ /*
+ * If saving the partition, and it's unnamed, the user should name
+ * it first.
+ */
+ if (cur_parts->pinfo_name == NULL) {
+ assert(cur_parts->pinfo_filename == NULL);
+ err_print("Please name this partition type before saving it\n");
+ return (-1);
+ }
+ /*
+ * Let the user know what we're doing
+ */
+ if (cur_dtype->dtype_filename == NULL &&
+ cur_parts->pinfo_filename == NULL) {
+ fmt_print("Saving new disk and partition definitions\n");
+ } else if (cur_dtype->dtype_filename == NULL) {
+ fmt_print("Saving new disk definition\n");
+ } else {
+ assert(cur_parts->pinfo_filename == NULL);
+ fmt_print("Saving new partition definition\n");
+ }
+ /*
+ * Ask for the file to which to append the new definitions
+ */
+ prompt = "Enter file name";
+ (void) strcpy(x.deflt_str, "./format.dat");
+ filename = (char *)input(FIO_OSTR, prompt,
+ ':', (u_ioparam_t *)NULL, &x.xfoo, DATA_INPUT);
+ assert(filename != NULL);
+ /*
+ * Open the file in append mode, or create it, if necessary
+ */
+ if ((fd = fopen(filename, "a")) == NULL) {
+ err_print("Cannot open `%s' - %s\n", filename,
+ strerror(errno));
+ destroy_data(filename);
+ return (-1);
+ }
+ /*
+ * Write a header for the new definitions
+ */
+ if ((cur_dtype->dtype_filename == NULL) &&
+ (cur_parts->pinfo_filename == NULL)) {
+ (void) fprintf(fd, "#\n# New disk/partition type ");
+ } else if (cur_dtype->dtype_filename == NULL) {
+ (void) fprintf(fd, "#\n# New disk type ");
+ } else {
+ (void) fprintf(fd, "#\n# New partition type ");
+ }
+ (void) time(&clock);
+ (void) fprintf(fd, " saved on %s#\n", ctime(&clock));
+ /*
+ * Save the new definitions
+ */
+ if (cur_dtype->dtype_filename == NULL) {
+ add_disktype(fd, cur_disk);
+ }
+ if (cur_parts->pinfo_filename == NULL) {
+ add_partition(fd, cur_disk, cur_parts);
+ }
+ /*
+ * We're finished. Clean up
+ */
+ (void) fclose(fd);
+ destroy_data(filename);
+ return (0);
+}
+
+/*
+ * Add a disk_type definition to the file fd
+ */
+static void
+add_disktype(fd, disk_info)
+ FILE *fd;
+ struct disk_info *disk_info;
+{
+ int col;
+ struct disk_type *disk_type;
+
+ disk_type = disk_info->disk_type;
+
+ (void) fprintf(fd, "disk_type = \"%s\" \\\n",
+ disk_type->dtype_asciilabel);
+ col = add_entry(0, fd, " : ctlr = %s",
+ ((disk_info->disk_ctlr)->ctlr_ctype)->ctype_name);
+
+ col = add_entry(col, fd, " : ncyl = %d", disk_type->dtype_ncyl);
+
+ col = add_entry(col, fd, " : acyl = %d", disk_type->dtype_acyl);
+
+ col = add_entry(col, fd, " : pcyl = %d", disk_type->dtype_pcyl);
+
+ col = add_entry(col, fd, " : nhead = %d", disk_type->dtype_nhead);
+
+ if (disk_type->dtype_options & SUP_PHEAD) {
+ col = add_entry(col, fd, " : phead = %d",
+ disk_type->dtype_phead);
+ }
+
+ col = add_entry(col, fd, " : nsect = %d", disk_type->dtype_nsect);
+
+ if (disk_type->dtype_options & SUP_PSECT) {
+ col = add_entry(col, fd, " : psect = %d",
+ disk_type->dtype_psect);
+ }
+
+ if (disk_type->dtype_options & SUP_BPT) {
+ col = add_entry(col, fd, " : bpt = %d", disk_type->dtype_bpt);
+ }
+
+ col = add_entry(col, fd, " : rpm = %d", disk_type->dtype_rpm);
+
+ if (disk_type->dtype_options & SUP_FMTTIME) {
+ col = add_entry(col, fd, " : fmt_time = %d",
+ disk_type->dtype_fmt_time);
+ }
+
+ if (disk_type->dtype_options & SUP_CYLSKEW) {
+ col = add_entry(col, fd, " : cyl_skew = %d",
+ disk_type->dtype_cyl_skew);
+ }
+
+ if (disk_type->dtype_options & SUP_TRKSKEW) {
+ col = add_entry(col, fd, " : trk_skew = %d",
+ disk_type->dtype_trk_skew);
+ }
+
+ if (disk_type->dtype_options & SUP_TRKS_ZONE) {
+ col = add_entry(col, fd, " : trks_zone = %d",
+ disk_type->dtype_trks_zone);
+ }
+
+ if (disk_type->dtype_options & SUP_ATRKS) {
+ col = add_entry(col, fd, " : atrks = %d",
+ disk_type->dtype_atrks);
+ }
+
+ if (disk_type->dtype_options & SUP_ASECT) {
+ col = add_entry(col, fd, " : asect = %d",
+ disk_type->dtype_asect);
+ }
+
+ if (disk_type->dtype_options & SUP_CACHE) {
+ col = add_entry(col, fd, " : cache = %d",
+ disk_type->dtype_cache);
+ }
+
+ if (disk_type->dtype_options & SUP_PREFETCH) {
+ col = add_entry(col, fd, " : prefetch = %d",
+ disk_type->dtype_threshold);
+ }
+
+ if (disk_type->dtype_options & SUP_CACHE_MIN) {
+ col = add_entry(col, fd, " : min_prefetch = %d",
+ disk_type->dtype_prefetch_min);
+ }
+
+ if (disk_type->dtype_options & SUP_CACHE_MAX) {
+ col = add_entry(col, fd, " : max_prefetch = %d",
+ disk_type->dtype_prefetch_max);
+ }
+
+ if (disk_type->dtype_options & SUP_BPS) {
+ col = add_entry(col, fd, " : bps = %d",
+ disk_type->dtype_bps);
+ }
+
+ if (disk_type->dtype_options & SUP_DRTYPE) {
+ col = add_entry(col, fd, " : drive_type = %d",
+ disk_type->dtype_dr_type);
+ }
+
+ /*
+ * Terminate the last line, and print one blank line
+ */
+ (void) fprintf(fd, col == 0 ? "\n" : "\n\n");
+}
+
+
+
+/*
+ * Once we exceed this length, wrap to a new line
+ */
+#define MAX_COLUMNS 50
+
+/*
+ * Add a partition definition to the file fd
+ */
+static void
+add_partition(fd, disk_info, part)
+ FILE *fd;
+ struct disk_info *disk_info;
+ struct partition_info *part;
+{
+ int col;
+ int i;
+ struct disk_type *disk_type;
+ struct dk_map32 *pp;
+ char *s;
+
+#if defined(_SUNOS_VTOC_8)
+ struct dk_map2 *pv;
+
+#elif defined(_SUNOS_VTOC_16)
+ struct dkl_partition *pv;
+
+#else
+#error No VTOC format defined.
+#endif /* defined (_SUNOS_VTOC_8) */
+ struct dk_map2 *dv;
+
+ disk_type = disk_info->disk_type;
+
+ (void) fprintf(fd, "partition = \"%s\" \\\n", part->pinfo_name);
+ (void) fprintf(fd, "\t : disk = \"%s\" : ctlr = %s \\\n",
+ disk_type->dtype_asciilabel,
+ ((disk_info->disk_ctlr)->ctlr_ctype)->ctype_name);
+
+ /*
+ * Print the specifications for each useful partition
+ */
+ col = 0;
+ pp = part->pinfo_map;
+ pv = part->vtoc.v_part;
+ dv = default_vtoc_map;
+ for (i = 0; i < NDKMAP; i++, pp++, pv++, dv++) {
+ if (pp->dkl_nblk != 0) {
+ col = add_entry(col, fd, " : %c = ",
+ i + PARTITION_BASE);
+ if (pv->p_tag != dv->p_tag ||
+ pv->p_flag != dv->p_flag) {
+ s = find_string(ptag_choices,
+ (int)pv->p_tag);
+ if (s != NULL) {
+ col = add_entry(col, fd, " %s,", s);
+ }
+ s = find_string(pflag_choices,
+ (int)pv->p_flag);
+ if (s != NULL) {
+ col = add_entry(col, fd, " %s,", s);
+ }
+ }
+ col = add_entry(col, fd, " %d, %d", pp->dkl_cylno,
+ pp->dkl_nblk);
+ }
+ }
+
+ /*
+ * Terminate the last line, and print one blank line
+ */
+ (void) fprintf(fd, col == 0 ? "\n" : "\n\n");
+}
+
+/*
+ * Add an entry to the file fd. col is the current starting column.
+ * Return the resulting new column position.
+ */
+/*PRINTFLIKE3*/
+static int
+add_entry(int col, FILE *fd, char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+
+ if (col > MAX_COLUMNS) {
+ (void) fprintf(fd, " \\\n");
+ col = 0;
+ }
+ if (col == 0) {
+ col += fprintf(fd, "\t");
+ }
+ col += vfprintf(fd, format, ap);
+ va_end(ap);
+
+ return (col);
+}