2 * Copyright (c) 1996 Whistle Communications
5 * Permission to use, copy, modify and distribute this software and its
6 * documentation is hereby granted, provided that both the copyright
7 * notice and this permission notice appear in all copies of the
8 * software, derivative works or modified versions, and any portions
9 * thereof, and that both notices appear in supporting documentation.
11 * Whistle Communications allows free use of this software in its "as is"
12 * condition. Whistle Communications disclaims any liability of any kind for
13 * any damages whatsoever resulting from the use of this software.
15 * $FreeBSD: src/sbin/i386/nextboot/nextboot.c,v 1.6 1999/08/28 00:13:06 peter Exp $
16 * $DragonFly: src/sbin/i386/nextboot/nextboot.c,v 1.4 2004/02/04 17:39:59 joerg Exp $
19 #include <sys/types.h>
20 #include <sys/disklabel.h>
21 #include <sys/diskmbr.h>
31 unsigned char padding[2]; /* force the longs to be long aligned */
32 unsigned char bootinst[DOSPARTOFF];
33 struct dos_partition parts[4];
34 unsigned short int signature;
38 #define NAMEBLOCK 1 /* 2nd block */
40 #define ENABLE_MAGIC 0xfadefeed
41 #define DISABLE_MAGIC 0xfadefade
46 #define BOOT_MAGIC 0xAA55
50 fprintf (stderr, "%s\n%s\n",
51 "usage: nextboot [-b] device bootstring [bootstring] ...",
52 " nextboot {-e,-d} device");
57 main (int argc, char** argv)
60 char namebuf[1024], *cp = namebuf;
66 while ((ch = getopt(argc, argv, "bde")) != -1) {
85 if ( (dflag + eflag + bflag) > 1 ) {
97 if ((fd = open(argv[0], O_RDWR, 0)) < 0)
98 errx(1, "can't open %s", argv[0]);
103 /*******************************************
104 * Check that we have an MBR
106 if (lseek(fd,0,0) == -1)
108 if (read (fd,&mboot.bootinst[0],BLOCKSIZE ) != BLOCKSIZE)
110 if (mboot.signature != (unsigned short)BOOT_MAGIC)
111 errx(1, "no fdisk part.. not touching block 1");
113 /*******************************************
114 * And check that none of the partitions in it cover the name block;
116 for ( part = 0; part < 4; part++) {
117 if( mboot.parts[part].dp_size
118 && (mboot.parts[part].dp_start <= NAMEBLOCK)
119 && (mboot.parts[part].dp_start
120 + mboot.parts[part].dp_size > NAMEBLOCK))
122 "name sector lies within a Bios partition: aborting write");
126 /*******************************************
127 * Now check the name sector itself to see if it's been initialized.
129 if (lseek(fd,NAMEBLOCK * BLOCKSIZE,0) == -1)
131 if (read(fd,namebuf,BLOCKSIZE) != BLOCKSIZE)
133 /*******************************************
134 * check if we are just enabling or disabling
135 * Remember the flags are exclusive..
137 if(!bflag) { /* don't care what's there if bflag is set */
138 switch(*(unsigned long *)cp)
144 errx(1, "namesector not initialized, use the -b flag");
149 /*******************************************
150 * If the z or r flag is set, damage or restore the magic number..
151 * to disable/enable the feature
154 *(unsigned long *)cp = DISABLE_MAGIC;
156 *(unsigned long *)cp = ENABLE_MAGIC;
158 if ((!dflag) && (!eflag)) {
159 /*******************************************
160 * Create a new namesector in ram
163 for ( i = 0 ; i < argc ; i++ ) {
167 strncpy(cp,argv[i],j);
174 namebuf[BLOCKSIZE-1] = 0; /* paranoid */
175 namebuf[BLOCKSIZE] = 0xff;
178 /*******************************************
181 if (lseek(fd,NAMEBLOCK * BLOCKSIZE,0) == -1)
183 if(write (fd,namebuf,BLOCKSIZE ) != BLOCKSIZE)
187 /*******************************************
188 * just to be safe/paranoid.. read it back..
191 if (lseek(fd,NAMEBLOCK * BLOCKSIZE,0) == -1)
192 err(1, "lseek (second)");
193 read (fd,namebuf,512);
194 for (i = 0;i< 16;i++) {
195 for ( j = 0; j < 16; j++) {
196 printf("%02x ",(unsigned char )namebuf[(i*16) + j ]);