summaryrefslogtreecommitdiffstats
path: root/sbin/sysinstall/bootarea.c
blob: 399f7ae27a076c301eba063caf2fafc4a48f9f73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/*
 * Copyright (c) 1994, Paul Richards.
 *
 * All rights reserved.
 *
 * This software may be used, modified, copied, distributed, and
 * sold, in both source and binary form provided that the above
 * copyright and these terms are retained, verbatim, as the first
 * lines of this file.  Under no circumstances is the author
 * responsible for the proper functioning of this software, nor does
 * the author assume any responsibility for damages incurred with
 * its use.
 */

#include <sys/types.h>
#include <sys/errno.h>
#include <sys/disklabel.h>
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <dialog.h>

#include "mbr.h"
#include "sysinstall.h"

extern char *bootblocks;
extern struct mbr *mbr;
extern char boot1[];
extern char boot2[];

void
enable_label(int fd)
{ 
	int flag = 1;
	if (ioctl(fd, DIOCWLABEL, &flag) < 0) 
	    Fatal("ioctl(DIOCWLABEL,1) failed: %s",strerror(errno));
}

void
disable_label(int fd)
{  
	int flag = 0;
	if (ioctl(fd, DIOCWLABEL, &flag) < 0) 
	    Fatal("ioctl(DIOCWLABEL,0) failed: %s",strerror(errno));
}

int
write_bootblocks(int fd, struct disklabel *lbl)
{
    off_t of = lbl->d_partitions[OURPART].p_offset;

    Debug("Seeking to byte %ld ", of * lbl->d_secsize);
    if (lseek(fd, (of * lbl->d_secsize), SEEK_SET) < 0) {
	    Fatal("Couldn't seek to start of partition\n");
    }

    enable_label(fd);

    if (write(fd, bootblocks, lbl->d_bbsize) != lbl->d_bbsize) {
	    Fatal("Failed to write bootblocks (%p,%d) %d %s\n",
		    bootblocks, lbl->d_bbsize,
		    errno, strerror(errno)
		    );
    }

    disable_label(fd);

    return(0);
}

int
build_bootblocks(int dfd,struct disklabel *label,struct dos_partition *dospart)
{
    int fd;
    off_t of = label->d_partitions[OURPART].p_offset;

    Debug("Loading boot code from %s", boot1);

    fd = open(boot1, O_RDONLY);
    if (fd < 0) 
	Fatal("Couldn't open boot file %s\n", boot1);

    if (read(fd, bootblocks, MBRSIZE) < 0) 
	Fatal("Couldn't read from boot file %s\n", boot1);

    if (close(fd) == -1) 
	Fatal("Couldn't close boot file %s\n", boot1);

    Debug("Loading boot code from %s", boot2);

    fd = open(boot2, O_RDONLY);
    if (fd < 0) 
	Fatal("Couldn't open boot file %s", boot2);

    if (read(fd, &bootblocks[MBRSIZE], (int)(label->d_bbsize - MBRSIZE)) < 0) 
	Fatal("Couldn't read from boot file %s\n", boot2);

    if (close(fd) == -1) 
	Fatal("Couldn't close boot file %s", boot2);

    bcopy(dospart, &bootblocks[DOSPARTOFF],
	  sizeof(struct dos_partition) * NDOSPART);

    label->d_checksum = 0;
    label->d_checksum = dkcksum(label);
    bcopy(label, &bootblocks[(LABELSECTOR * label->d_secsize) + LABELOFFSET],
		    sizeof *label);

    Debug("Seeking to byte %ld ", of * label->d_secsize);

    if (lseek(dfd, (of * label->d_secsize), SEEK_SET) < 0) {
	    Fatal("Couldn't seek to start of partition\n");
    }

    enable_label(dfd);

    if (write(dfd, bootblocks, label->d_bbsize) != label->d_bbsize) {
	    Fatal("Failed to write bootblocks (%p,%d) %d %s\n",
		    bootblocks, label->d_bbsize,
		    errno, strerror(errno)
		    );
    }

    disable_label(dfd);

    return(0);
}
OpenPOWER on IntegriCloud