Home | History | Annotate | Line # | Download | only in newdisk
newdisk.c revision 1.5.4.1
      1  1.5.4.1    rmind /*	$NetBSD: newdisk.c,v 1.5.4.1 2011/05/31 03:04:22 rmind Exp $	*/
      2  1.5.4.1    rmind 
      3      1.1  minoura /*-
      4      1.1  minoura  * Copyright (c) 1999 Minoura Makoto
      5      1.1  minoura  * All rights reserved.
      6      1.1  minoura  *
      7      1.1  minoura  * Redistribution and use in source and binary forms, with or without
      8      1.1  minoura  * modification, are permitted provided that the following conditions
      9      1.1  minoura  * are met:
     10      1.1  minoura  * 1. Redistributions of source code must retain the above copyright
     11      1.1  minoura  *    notice, this list of conditions and the following disclaimer.
     12      1.1  minoura  * 2. Redistributions in binary form must reproduce the above copyright
     13      1.1  minoura  *    notice, this list of conditions and the following disclaimer in the
     14      1.1  minoura  *    documentation and/or other materials provided with the distribution.
     15      1.1  minoura  * 3. All advertising materials mentioning features or use of this software
     16      1.1  minoura  *    must display the following acknowledgement:
     17      1.1  minoura  *	This product includes software developed by Minoura Makoto.
     18      1.1  minoura  * 4. The name of the author may not be used to endorse or promote products
     19      1.1  minoura  *    derived from this software without specific prior written permission.
     20      1.1  minoura  *
     21      1.1  minoura  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     22      1.1  minoura  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     23      1.1  minoura  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     24      1.1  minoura  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     25      1.1  minoura  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     26      1.1  minoura  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     27      1.1  minoura  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     28      1.1  minoura  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     29      1.1  minoura  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     30      1.1  minoura  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     31      1.1  minoura  */
     32      1.1  minoura 
     33      1.1  minoura /*
     34      1.1  minoura  * Create the disk mark for x68k SCSI IPL.
     35      1.1  minoura  * It used to be a shell/awk script, but is rewritten in order to be fit with
     36      1.1  minoura  * the install kernel.
     37      1.1  minoura  *
     38      1.1  minoura  * Usage: /usr/mdec/newdisk [-vnfc] [-m /usr/mdec/mboot] /dev/rsd?c
     39      1.1  minoura  */
     40      1.1  minoura 
     41      1.1  minoura #include <stdio.h>
     42      1.1  minoura #include <stdlib.h>
     43      1.1  minoura #include <string.h>
     44  1.5.4.1    rmind #include <err.h>
     45      1.1  minoura #include <fcntl.h>
     46      1.1  minoura #include <unistd.h>
     47      1.1  minoura #include <util.h>
     48      1.1  minoura #include <sys/param.h>
     49      1.1  minoura #include <sys/disklabel.h>
     50      1.1  minoura #include <sys/dkio.h>
     51  1.5.4.1    rmind #include <sys/ioctl.h>
     52      1.1  minoura 
     53  1.5.4.1    rmind const char *mboot = MBOOT;
     54      1.1  minoura char dev[MAXPATHLEN];
     55      1.1  minoura char buf[4096 + 1];
     56      1.1  minoura 
     57      1.2  minoura const char copyright[] = "NetBSD/x68k SCSI Primary Boot. ";
     58      1.1  minoura 
     59      1.2  minoura int verbose = 0, dry_run = 0, force = 0, check_only = 0, mark_only = 0;
     60      1.1  minoura 
     61      1.4      dsl void usage(void) __attribute__((__noreturn__));
     62      1.4      dsl int main(int, char *[]);
     63      1.1  minoura 
     64      1.3   mhitch void
     65      1.1  minoura usage(void)
     66      1.1  minoura {
     67  1.5.4.1    rmind 	fprintf(stderr,
     68  1.5.4.1    rmind 		"Usage: %s [-v] [-n] [-f] [-c] [-m /usr/mdec/mboot] "
     69  1.5.4.1    rmind 		"/dev/rsdXc\n", getprogname());
     70  1.5.4.1    rmind 	exit(1);
     71  1.5.4.1    rmind 	/* NOTREACHED */
     72      1.1  minoura }
     73      1.1  minoura 
     74      1.1  minoura int
     75      1.5      dsl main(int argc, char *argv[])
     76      1.1  minoura {
     77  1.5.4.1    rmind 	int ch;
     78  1.5.4.1    rmind 	int fd;
     79  1.5.4.1    rmind 	struct disklabel label;
     80  1.5.4.1    rmind 
     81  1.5.4.1    rmind 	while ((ch = getopt(argc, argv, "vnfcm:p")) != -1) {
     82  1.5.4.1    rmind 		switch (ch) {
     83  1.5.4.1    rmind 		case 'v':
     84  1.5.4.1    rmind 			verbose = 1;
     85  1.5.4.1    rmind 			break;
     86  1.5.4.1    rmind 		case 'n':
     87  1.5.4.1    rmind 			dry_run = 1;
     88  1.5.4.1    rmind 			break;
     89  1.5.4.1    rmind 		case 'f':
     90  1.5.4.1    rmind 			force = 1;
     91  1.5.4.1    rmind 			break;
     92  1.5.4.1    rmind 		case 'c':
     93  1.5.4.1    rmind 			check_only = 1;
     94  1.5.4.1    rmind 			break;
     95  1.5.4.1    rmind 		case 'm':
     96  1.5.4.1    rmind 			mboot = optarg;
     97  1.5.4.1    rmind 			break;
     98  1.5.4.1    rmind 		case 'p':
     99  1.5.4.1    rmind 			mark_only = 1;
    100  1.5.4.1    rmind 			break;
    101  1.5.4.1    rmind 		default:
    102  1.5.4.1    rmind 			usage();
    103  1.5.4.1    rmind 		}
    104      1.1  minoura 	}
    105  1.5.4.1    rmind 	argc -= optind;
    106  1.5.4.1    rmind 	argv += optind;
    107      1.1  minoura 
    108  1.5.4.1    rmind 	if (argc != 1)
    109  1.5.4.1    rmind 		usage();
    110      1.1  minoura 
    111  1.5.4.1    rmind 	fd = opendisk(argv[0], O_RDONLY, dev, MAXPATHLEN, 0);
    112  1.5.4.1    rmind 	if (fd < 0)
    113  1.5.4.1    rmind 		err(1, "opening %s", dev);
    114  1.5.4.1    rmind 	if (access(mboot, R_OK) < 0)
    115  1.5.4.1    rmind 		err(1, "checking %s", mboot);
    116  1.5.4.1    rmind 
    117  1.5.4.1    rmind 	if (read(fd, buf, 512) < 0)
    118  1.5.4.1    rmind 		err(1, "reading %s", dev);
    119  1.5.4.1    rmind 	if (strncmp(buf, "X68SCSI1", 8) == 0 && !force)
    120  1.5.4.1    rmind 		errx(1, "%s is already marked.  "
    121  1.5.4.1    rmind 		        "Use -f to overwrite the existing mark.", dev);
    122  1.5.4.1    rmind 	if (check_only)
    123  1.5.4.1    rmind 		return 0;
    124  1.5.4.1    rmind 
    125  1.5.4.1    rmind 	if (verbose)
    126  1.5.4.1    rmind 		fprintf(stderr, "Inspecting %s... ", dev);
    127      1.1  minoura 
    128  1.5.4.1    rmind 	if (ioctl(fd, DIOCGDINFO, &label) < 0)
    129  1.5.4.1    rmind 		err(1, "inspecting %s", dev);
    130  1.5.4.1    rmind 	close(fd);
    131  1.5.4.1    rmind 	if (label.d_secsize != 512)
    132  1.5.4.1    rmind 		errx(1, "This type of disk is not supported by NetBSD.");
    133      1.1  minoura 
    134      1.2  minoura 	if (verbose)
    135  1.5.4.1    rmind 		fprintf(stderr, "total number of sector is %d.\n",
    136  1.5.4.1    rmind 			label.d_secperunit);
    137  1.5.4.1    rmind 
    138  1.5.4.1    rmind 	if (verbose)
    139  1.5.4.1    rmind 		fprintf(stderr, "Building disk mark... ");
    140  1.5.4.1    rmind 	memset(buf, 0, 3072);
    141  1.5.4.1    rmind #define n label.d_secperunit
    142  1.5.4.1    rmind 	sprintf(buf, "X68SCSI1%c%c%c%c%c%c%c%c%s",
    143  1.5.4.1    rmind 		2, 0,
    144  1.5.4.1    rmind 		(n/16777216)%256, (n/65536)%256, (n/256)%256, n%256,
    145  1.5.4.1    rmind 		1, 0, copyright);
    146      1.1  minoura #undef n
    147      1.2  minoura 	if (verbose)
    148  1.5.4.1    rmind 		fprintf(stderr, "done.\n");
    149      1.1  minoura 
    150  1.5.4.1    rmind 	if (verbose)
    151  1.5.4.1    rmind 		fprintf(stderr, "Merging %s... ", mboot);
    152  1.5.4.1    rmind 	fd = open(mboot, O_RDONLY);
    153      1.1  minoura 	if (fd < 0)
    154  1.5.4.1    rmind 		err(1, "opening %s", mboot);
    155  1.5.4.1    rmind 	if (read(fd, buf+1024, 1024) < 0)
    156  1.5.4.1    rmind 		err(1, "reading %s", mboot);
    157      1.1  minoura 	close(fd);
    158      1.1  minoura 	if (verbose)
    159  1.5.4.1    rmind 		fprintf(stderr, "done.\n");
    160  1.5.4.1    rmind 
    161  1.5.4.1    rmind 	if (!mark_only) {
    162  1.5.4.1    rmind 		if (verbose)
    163  1.5.4.1    rmind 			fprintf(stderr,
    164  1.5.4.1    rmind 				"Creating an empty partition table... ");
    165  1.5.4.1    rmind #define n (label.d_secperunit/2)
    166  1.5.4.1    rmind 		sprintf(buf+2048,
    167  1.5.4.1    rmind 			"X68K%c%c%c%c%c%c%c%c%c%c%c%c",
    168  1.5.4.1    rmind 			0, 0, 0, 32,
    169  1.5.4.1    rmind 			(n/16777215)%256, (n/65536)%256, (n/256)%256, n%256,
    170  1.5.4.1    rmind 			(n/16777215)%256, (n/65536)%256, (n/256)%256, n%256);
    171  1.5.4.1    rmind #undef n
    172  1.5.4.1    rmind 		if (verbose)
    173  1.5.4.1    rmind 			fprintf(stderr, "done.\n");
    174      1.1  minoura 	}
    175      1.1  minoura 
    176  1.5.4.1    rmind 	if (dry_run) {
    177  1.5.4.1    rmind 		char filename[MAXPATHLEN] = "/tmp/diskmarkXXXXX";
    178  1.5.4.1    rmind 		fd = mkstemp(filename);
    179  1.5.4.1    rmind 		if (fd < 0)
    180  1.5.4.1    rmind 			err(1, "opening %s", filename);
    181  1.5.4.1    rmind 		if (write(fd, buf, 4096) < 0)
    182  1.5.4.1    rmind 			err(1, "writing %s", filename);
    183  1.5.4.1    rmind 		close(fd);
    184  1.5.4.1    rmind 		fprintf(stderr, "Disk mark is kept in %s.\n", filename);
    185  1.5.4.1    rmind 	} else {
    186  1.5.4.1    rmind 		int mode = 1;
    187  1.5.4.1    rmind 
    188  1.5.4.1    rmind 		if (verbose)
    189  1.5.4.1    rmind 			fprintf(stderr, "Writing... ");
    190  1.5.4.1    rmind 		fd = open(dev, O_WRONLY);
    191  1.5.4.1    rmind 		if (fd < 0)
    192  1.5.4.1    rmind 			err(1, "opening %s", dev);
    193  1.5.4.1    rmind 		if (ioctl(fd, DIOCWLABEL, (char *)&mode) < 0)
    194  1.5.4.1    rmind 			err(1, "DIOCWLABEL %s", dev);
    195  1.5.4.1    rmind 		if (write(fd, buf, 4096) != 4096) {
    196  1.5.4.1    rmind 			mode = 0;
    197  1.5.4.1    rmind 			ioctl(fd, DIOCWLABEL, (char *)&mode);
    198  1.5.4.1    rmind 			err(1, "DIOCWLABEL %s", dev);
    199  1.5.4.1    rmind 		}
    200  1.5.4.1    rmind 		ioctl(fd, DIOCWLABEL, (char *)&mode);
    201  1.5.4.1    rmind 		if (verbose)
    202  1.5.4.1    rmind 			fprintf(stderr, "done.\n");
    203  1.5.4.1    rmind 		close(fd);
    204  1.5.4.1    rmind 	}
    205  1.5.4.1    rmind 
    206  1.5.4.1    rmind 	return 0;
    207      1.1  minoura }
    208