diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/cmd/format/add_definition.c | |
download | illumos-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.c | 390 |
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); +} |