Home | History | Annotate | Line # | Download | only in installboot
installboot.c revision 1.5
      1 /*	$NetBSD: installboot.c,v 1.4 2007/03/26 23:08:29 hubertf Exp $	*/
      2 
      3 #include <err.h>
      4 #include <fcntl.h>
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <unistd.h>
      9 
     10 #include "../elf2bb/chksum.h"
     11 
     12 /* XXX Must be kept in sync with bbstart.s! */
     13 #define CMDLN_LOC 0x10
     14 #define CMDLN_LEN 0x20
     15 
     16 int main(int argc, char *argv[]);
     17 
     18 int main(int argc, char *argv[]){
     19 
     20 	char *line;
     21 	char *progname;
     22 	char *bootnam, *devnam;
     23 	char *dline;
     24 	int bootfd, devfd;
     25 	int rc;	/* read,  write */
     26 	int c;	/* getopt */
     27 	int sumlen;
     28 	u_int32_t sum2, sum16;
     29 
     30 	u_int32_t block[128*16];
     31 
     32 	progname = argv[0];
     33 	while ((c = getopt(argc, argv, "l:")) != -1) {
     34 		switch(c) {
     35 		case 'l':
     36 			line = optarg;
     37 			break;
     38 		default:
     39 			errx(1,
     40 			"usage: %s [-l newcommandline] bootblock device",
     41 			progname);
     42 		}
     43 	}
     44 	argc -= optind;
     45 	argv += optind;
     46 	if (argc != 2) {
     47 		errx(1, "usage: %s [-l newcommandline] bootblock device",
     48 			progname);
     49 		/* NOTREACHED */
     50 	}
     51 
     52 	bootnam = *argv++;
     53 	devnam = *argv;
     54 
     55 	bootfd = open(bootnam, O_RDONLY, 0);
     56 	if (bootfd < 0) {
     57 		err(1, "Can't open bootblock for reading");
     58 		/* NOTREACHED */
     59 	}
     60 
     61 	devfd = open(devnam, O_CREAT|O_RDWR, 0666);
     62 	if (devfd < 0) {
     63 		err(1, "Can't open output device for writing");
     64 		/* NOTREACHED */
     65 	}
     66 
     67 	rc = read(bootfd, block, sizeof(block));
     68 
     69 	if (rc < sizeof(block)) {
     70 		err(1, "Can't read bootblock");
     71 		/* NOTREACHED */
     72 	}
     73 
     74 	/* XXX the choices should not be hardcoded */
     75 
     76 	sum2  = chksum(block, 1024/4);
     77 	sum16 = chksum(block, 8192/4);
     78 
     79 	if (sum16 == 0xffffffff) {
     80 		sumlen = 8192/4;
     81 	} else if (sum2 == 0xffffffff) {
     82 		sumlen = 1024/4;
     83 	} else {
     84 		errx(1, "%s: wrong checksum", bootnam);
     85 		/* NOTREACHED */
     86 	}
     87 
     88 	if (sum2 == sum16) {
     89 		warnx("eek - both sums are the same");
     90 	}
     91 
     92 
     93 	if (line) {
     94 		dline = (char *)&(block[CMDLN_LOC/4]);
     95 		/* XXX keep the default default line in sync with bbstart.s */
     96 		if (strcmp(dline, "netbsd -ASn2") != 0) {
     97 			errx(1, "Old bootblock version? Can't change command line.");
     98 		}
     99 		(void)strncpy(dline, line, CMDLN_LEN-1);
    100 
    101 		block[1] = 0;
    102 		block[1] = 0xffffffff - chksum(block, sumlen);
    103 	}
    104 
    105 	rc = write(devfd, block, sizeof(block));
    106 
    107 	if (rc < sizeof(block)) {
    108 		err(1, "Can't write bootblock");
    109 		/* NOTREACHED */
    110 	}
    111 
    112 	exit(1);
    113 	/* NOTREACHED */
    114 }
    115