md5(1): Add support for sha512.
[dragonfly.git] / sbin / nextboot / nextboot.c
blobf42cfc739fc2cca4cf4fc76b8ae1c3d0e1322e65
1 /*
2 * Copyright (c) 1996 Whistle Communications
3 * All Rights Reserved.
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.5 2007/05/20 23:21:36 dillon Exp $
19 #include <sys/types.h>
20 #include <sys/diskmbr.h>
21 #include <fcntl.h>
22 #include <err.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <unistd.h>
28 struct mboot
30 unsigned char padding[2]; /* force the longs to be long aligned */
31 unsigned char bootinst[DOSPARTOFF];
32 struct dos_partition parts[4];
33 unsigned short int signature;
35 struct mboot mboot;
37 #define NAMEBLOCK 1 /* 2nd block */
38 #define BLOCKSIZE 512
39 #define ENABLE_MAGIC 0xfadefeed
40 #define DISABLE_MAGIC 0xfadefade
41 static int bflag;
42 static int eflag;
43 static int dflag;
45 #define BOOT_MAGIC 0xAA55
47 static void
48 usage(void) {
49 fprintf (stderr, "%s\n%s\n",
50 "usage: nextboot [-b] device bootstring [bootstring] ...",
51 " nextboot {-e,-d} device");
52 exit(1);
55 int
56 main (int argc, char** argv)
58 int fd = -1;
59 char namebuf[1024], *cp = namebuf;
60 int i,j;
61 int ch;
62 int part;
64 bflag = 0;
65 while ((ch = getopt(argc, argv, "bde")) != -1) {
66 switch(ch) {
67 case 'b':
68 bflag = 1;
69 break;
70 case 'd':
71 dflag = 1;
72 break;
73 case 'e':
74 eflag = 1;
75 break;
76 case '?':
77 default:
78 usage();
81 argc -= optind;
82 argv += optind;
84 if ( (dflag + eflag + bflag) > 1 ) {
85 usage();
87 if (dflag + eflag){
88 if(argc != 1 ) {
89 usage();
91 } else {
92 if (argc <2) {
93 usage();
96 if ((fd = open(argv[0], O_RDWR, 0)) < 0)
97 errx(1, "can't open %s", argv[0]);
99 argc--;
100 argv++;
102 /*******************************************
103 * Check that we have an MBR
105 if (lseek(fd,0,0) == -1)
106 err(1, "lseek");
107 if (read (fd,&mboot.bootinst[0],BLOCKSIZE ) != BLOCKSIZE)
108 err(1, "read0");
109 if (mboot.signature != (unsigned short)BOOT_MAGIC)
110 errx(1, "no fdisk part.. not touching block 1");
112 /*******************************************
113 * And check that none of the partitions in it cover the name block;
115 for ( part = 0; part < 4; part++) {
116 if( mboot.parts[part].dp_size
117 && (mboot.parts[part].dp_start <= NAMEBLOCK)
118 && (mboot.parts[part].dp_start
119 + mboot.parts[part].dp_size > NAMEBLOCK))
120 errx(1,
121 "name sector lies within a Bios partition: aborting write");
125 /*******************************************
126 * Now check the name sector itself to see if it's been initialized.
128 if (lseek(fd,NAMEBLOCK * BLOCKSIZE,0) == -1)
129 err(1, "lseek");
130 if (read(fd,namebuf,BLOCKSIZE) != BLOCKSIZE)
131 err(1, "read1");
132 /*******************************************
133 * check if we are just enabling or disabling
134 * Remember the flags are exclusive..
136 if(!bflag) { /* don't care what's there if bflag is set */
137 switch(*(unsigned long *)cp)
139 case DISABLE_MAGIC:
140 case ENABLE_MAGIC:
141 break;
142 default:
143 errx(1, "namesector not initialized, use the -b flag");
148 /*******************************************
149 * If the z or r flag is set, damage or restore the magic number..
150 * to disable/enable the feature
152 if(dflag) {
153 *(unsigned long *)cp = DISABLE_MAGIC;
154 } else {
155 *(unsigned long *)cp = ENABLE_MAGIC;
157 if ((!dflag) && (!eflag)) {
158 /*******************************************
159 * Create a new namesector in ram
161 cp += 4;
162 for ( i = 0 ; i < argc ; i++ ) {
163 *cp++ = 'D';
164 *cp++ = 'N';
165 j = strlen(argv[i]);
166 strncpy(cp,argv[i],j);
167 cp += j;
168 *cp++ = 0;
170 *cp++ = 0xff;
171 *cp++ = 0xff;
172 *cp++ = 0xff;
173 namebuf[BLOCKSIZE-1] = 0; /* paranoid */
174 namebuf[BLOCKSIZE] = 0xff;
177 /*******************************************
178 * write it to disk.
180 if (lseek(fd,NAMEBLOCK * BLOCKSIZE,0) == -1)
181 err(1, "lseek");
182 if(write (fd,namebuf,BLOCKSIZE ) != BLOCKSIZE)
183 err(1, "write");
185 #if 0
186 /*******************************************
187 * just to be safe/paranoid.. read it back..
188 * and print it..
190 if (lseek(fd,NAMEBLOCK * BLOCKSIZE,0) == -1)
191 err(1, "lseek (second)");
192 read (fd,namebuf,512);
193 for (i = 0;i< 16;i++) {
194 for ( j = 0; j < 16; j++) {
195 printf("%02x ",(unsigned char )namebuf[(i*16) + j ]);
197 printf("\n");
199 #endif
200 exit(0);