/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- opendisk
- diskblocksize
- diskblocks
- diskwrite
- diskread
- closedisk
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <assert.h>
34 #include <stdint.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <fcntl.h>
38 #include <err.h>
39
40 #include "support.h"
41 #include "disk.h"
42
43 #define HOSTSTRING "System/161 Disk Image"
44 #define BLOCKSIZE 512
45
46 #ifndef EINTR
47 #define EINTR 0
48 #endif
49
50 static int fd=-1;
51 static uint32_t nblocks;
52
53 void
54 opendisk(const char *path)
55 {
56 struct stat statbuf;
57
58 assert(fd<0);
59 fd = open(path, O_RDWR);
60 if (fd<0) {
61 err(1, "%s", path);
62 }
63 if (fstat(fd, &statbuf)) {
64 err(1, "%s: fstat", path);
65 }
66
67 nblocks = statbuf.st_size / BLOCKSIZE;
68
69 #ifdef HOST
70 nblocks--;
71
72 {
73 char buf[64];
74 int len;
75
76 do {
77 len = read(fd, buf, sizeof(buf)-1);
78 if (len < 0 && (errno==EINTR || errno==EAGAIN)) {
79 continue;
80 }
81 } while (0);
82
83 buf[len] = 0;
84 buf[strlen(HOSTSTRING)] = 0;
85
86 if (strcmp(buf, HOSTSTRING)) {
87 errx(1, "%s: Not a System/161 disk image", path);
88 }
89 }
90 #endif
91 }
92
93 uint32_t
94 diskblocksize(void)
95 {
96 assert(fd>=0);
97 return BLOCKSIZE;
98 }
99
100 uint32_t
101 diskblocks(void)
102 {
103 assert(fd>=0);
104 return nblocks;
105 }
106
107 void
108 diskwrite(const void *data, uint32_t block)
109 {
110 const char *cdata = data;
111 uint32_t tot=0;
112 int len;
113
114 assert(fd>=0);
115
116 #ifdef HOST
117 // skip over disk file header
118 block++;
119 #endif
120
121 if (lseek(fd, block*BLOCKSIZE, SEEK_SET)<0) {
122 err(1, "lseek");
123 }
124
125 while (tot < BLOCKSIZE) {
126 len = write(fd, cdata + tot, BLOCKSIZE - tot);
127 if (len < 0) {
128 if (errno==EINTR || errno==EAGAIN) {
129 continue;
130 }
131 err(1, "write");
132 }
133 if (len==0) {
134 err(1, "write returned 0?");
135 }
136 tot += len;
137 }
138 }
139
140 void
141 diskread(void *data, uint32_t block)
142 {
143 char *cdata = data;
144 uint32_t tot=0;
145 int len;
146
147 assert(fd>=0);
148
149 #ifdef HOST
150 // skip over disk file header
151 block++;
152 #endif
153
154 if (lseek(fd, block*BLOCKSIZE, SEEK_SET)<0) {
155 err(1, "lseek");
156 }
157
158 while (tot < BLOCKSIZE) {
159 len = read(fd, cdata + tot, BLOCKSIZE - tot);
160 if (len < 0) {
161 if (errno==EINTR || errno==EAGAIN) {
162 continue;
163 }
164 err(1, "read");
165 }
166 if (len==0) {
167 err(1, "unexpected EOF in mid-sector");
168 }
169 tot += len;
170 }
171 }
172
173 void
174 closedisk(void)
175 {
176 assert(fd>=0);
177 if (close(fd)) {
178 err(1, "close");
179 }
180 fd = -1;
181 }