FreeCalypso > hg > freecalypso-tools
comparison rvinterf/etmsync/fileio.c @ 0:e7502631a0f9
initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sat, 11 Jun 2016 00:13:35 +0000 |
parents | |
children | a0754c98fc2b |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e7502631a0f9 |
---|---|
1 /* | |
2 * FFS2 file descriptor I/O operations | |
3 */ | |
4 | |
5 #include <sys/types.h> | |
6 #include <stdio.h> | |
7 #include <stdlib.h> | |
8 #include <string.h> | |
9 #include <strings.h> | |
10 #include "etm.h" | |
11 #include "ffs.h" | |
12 #include "ffserr.h" | |
13 #include "tmffs2.h" | |
14 #include "limits.h" | |
15 #include "localtypes.h" | |
16 #include "localstruct.h" | |
17 #include "exitcodes.h" | |
18 | |
19 extern u_char rvi_msg[]; | |
20 extern int rvi_msg_len; | |
21 | |
22 fd_open(pathname, flags, fdrtn) | |
23 char *pathname; | |
24 int flags, *fdrtn; | |
25 { | |
26 u_char cmdpkt[MAX_PKT_TO_TARGET], *dp; | |
27 int rc, slen; | |
28 | |
29 slen = strlen(pathname); | |
30 if (slen >= TMFFS_STRING_SIZE) { | |
31 printf("error: pathname arg exceeds string length limit\n"); | |
32 return(ERROR_USAGE); | |
33 } | |
34 dp = cmdpkt + 1; | |
35 *dp++ = ETM_FFS2; | |
36 *dp++ = TMFFS_OPEN; | |
37 *dp++ = slen + 1; | |
38 strcpy(dp, pathname); | |
39 dp += slen + 1; | |
40 *dp++ = flags; | |
41 rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1); | |
42 if (rc) | |
43 return(rc); | |
44 if (rvi_msg[3]) { | |
45 report_ffs_err("open fd", rvi_msg[3]); | |
46 return(ERROR_TARGET); | |
47 } | |
48 if (rvi_msg_len != 6) { | |
49 printf("error: open fd response has wrong length\n"); | |
50 return(ERROR_TARGET); | |
51 } | |
52 *fdrtn = rvi_msg[4]; | |
53 return(0); | |
54 } | |
55 | |
56 fd_read(fd, databuf, rdsize, rdret) | |
57 u_char *databuf; | |
58 int fd, rdsize, *rdret; | |
59 { | |
60 u_char cmdpkt[6]; | |
61 int rc, sz; | |
62 | |
63 if (rdsize > MAX_READ_DATA) { | |
64 printf("error: # of bytes to read may not exceed %d\n", | |
65 MAX_READ_DATA); | |
66 return(ERROR_USAGE); | |
67 } | |
68 cmdpkt[1] = ETM_FFS2; | |
69 cmdpkt[2] = TMFFS_READ; | |
70 cmdpkt[3] = fd; | |
71 cmdpkt[4] = rdsize; | |
72 rc = etm_pkt_exch(cmdpkt, 4); | |
73 if (rc) | |
74 return(rc); | |
75 if (rvi_msg[3]) { | |
76 report_ffs_err("read fd", rvi_msg[3]); | |
77 return(ERROR_TARGET); | |
78 } | |
79 if (rvi_msg_len < 6) { | |
80 *rdret = 0; | |
81 return(0); | |
82 } | |
83 sz = rvi_msg[4]; | |
84 if (rvi_msg_len != sz + 6 || sz > rdsize) { | |
85 printf("error: read fd response has wrong length\n"); | |
86 return(ERROR_TARGET); | |
87 } | |
88 bcopy(rvi_msg + 5, databuf, sz); | |
89 *rdret = sz; | |
90 return(0); | |
91 } | |
92 | |
93 fd_write(fd, data, wrsize) | |
94 u_char *data; | |
95 { | |
96 u_char cmdpkt[MAX_PKT_TO_TARGET], *dp; | |
97 int rc; | |
98 | |
99 if (wrsize > MAX_PKT_TO_TARGET - 6) { | |
100 printf("error: fd write data fails to fit in the packet\n"); | |
101 return(ERROR_USAGE); | |
102 } | |
103 dp = cmdpkt + 1; | |
104 *dp++ = ETM_FFS2; | |
105 *dp++ = TMFFS_WRITE; | |
106 *dp++ = fd; | |
107 *dp++ = wrsize; | |
108 bcopy(data, dp, wrsize); | |
109 dp += wrsize; | |
110 rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1); | |
111 if (rc) | |
112 return(rc); | |
113 if (rvi_msg[3]) { | |
114 report_ffs_err("fd write", rvi_msg[3]); | |
115 return(ERROR_TARGET); | |
116 } | |
117 if (rvi_msg_len != 6) { | |
118 printf("error: TMFFS_WRITE response has wrong length\n"); | |
119 return(ERROR_TARGET); | |
120 } | |
121 if (rvi_msg[4] != wrsize) { | |
122 printf("fd write error: # of bytes written != requested\n"); | |
123 return(ERROR_TARGET); | |
124 } | |
125 return(0); | |
126 } | |
127 | |
128 fd_close(fd) | |
129 { | |
130 u_char cmdpkt[5]; | |
131 int rc; | |
132 | |
133 cmdpkt[1] = ETM_FFS2; | |
134 cmdpkt[2] = TMFFS_CLOSE; | |
135 cmdpkt[3] = fd; | |
136 rc = etm_pkt_exch(cmdpkt, 3); | |
137 if (rc) | |
138 return(rc); | |
139 if (rvi_msg[3]) { | |
140 report_ffs_err("close fd", rvi_msg[3]); | |
141 return(ERROR_TARGET); | |
142 } | |
143 if (rvi_msg_len != 5) { | |
144 printf("error: close fd response has wrong length\n"); | |
145 return(ERROR_TARGET); | |
146 } | |
147 return(0); | |
148 } | |
149 | |
150 do_file_read(pathname, databuf, rdsize, rdret) | |
151 char *pathname; | |
152 u_char *databuf; | |
153 int rdsize, *rdret; | |
154 { | |
155 u_char cmdpkt[MAX_PKT_TO_TARGET], *dp; | |
156 int rc, slen, sz; | |
157 | |
158 slen = strlen(pathname); | |
159 if (slen >= TMFFS_STRING_SIZE) { | |
160 printf("error: pathname arg exceeds string length limit\n"); | |
161 return(ERROR_USAGE); | |
162 } | |
163 if (rdsize > MAX_READ_DATA) { | |
164 printf("error: # of bytes to read may not exceed %d\n", | |
165 MAX_READ_DATA); | |
166 return(ERROR_USAGE); | |
167 } | |
168 dp = cmdpkt + 1; | |
169 *dp++ = ETM_FFS2; | |
170 *dp++ = TMFFS_FILE_READ; | |
171 *dp++ = slen + 1; | |
172 strcpy(dp, pathname); | |
173 dp += slen + 1; | |
174 *dp++ = rdsize; | |
175 rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1); | |
176 if (rc) | |
177 return(rc); | |
178 if (rvi_msg[3]) { | |
179 report_ffs_err("read file", rvi_msg[3]); | |
180 return(ERROR_TARGET); | |
181 } | |
182 if (rvi_msg_len < 6) { | |
183 *rdret = 0; | |
184 return(0); | |
185 } | |
186 sz = rvi_msg[4]; | |
187 if (rvi_msg_len != sz + 6 || sz > rdsize) { | |
188 printf("error: read file response has wrong length\n"); | |
189 return(ERROR_TARGET); | |
190 } | |
191 bcopy(rvi_msg + 5, databuf, sz); | |
192 *rdret = sz; | |
193 return(0); | |
194 } | |
195 | |
196 max_short_file_write(pathname) | |
197 char *pathname; | |
198 { | |
199 return MAX_PKT_TO_TARGET - 3 - (strlen(pathname) + 2) - 3; | |
200 } | |
201 | |
202 do_short_fwrite(pathname, data, datalen) | |
203 char *pathname; | |
204 u_char *data; | |
205 { | |
206 u_char cmdpkt[MAX_PKT_TO_TARGET], *dp; | |
207 int rc, slen; | |
208 | |
209 slen = strlen(pathname); | |
210 if (slen >= TMFFS_STRING_SIZE) { | |
211 printf("error: pathname arg exceeds string length limit\n"); | |
212 return(ERROR_USAGE); | |
213 } | |
214 if (datalen > max_short_file_write(pathname)) { | |
215 printf("error: short write data fails to fit in the packet\n"); | |
216 return(ERROR_USAGE); | |
217 } | |
218 dp = cmdpkt + 1; | |
219 *dp++ = ETM_FFS2; | |
220 *dp++ = TMFFS_FILE_WRITE; | |
221 *dp++ = slen + 1; | |
222 strcpy(dp, pathname); | |
223 dp += slen + 1; | |
224 *dp++ = datalen; | |
225 bcopy(data, dp, datalen); | |
226 dp += datalen; | |
227 *dp++ = FFS_O_CREATE | FFS_O_TRUNC; | |
228 rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1); | |
229 if (rc) | |
230 return(rc); | |
231 if (rvi_msg_len != 5) { | |
232 printf("error: TMFFS_FILE_WRITE response has wrong length\n"); | |
233 return(ERROR_TARGET); | |
234 } | |
235 if (rvi_msg[3]) { | |
236 report_ffs_err("short file write", rvi_msg[3]); | |
237 return(ERROR_TARGET); | |
238 } | |
239 return(0); | |
240 } | |
241 | |
242 do_opendir(pathname, statertn, countrtn) | |
243 char *pathname; | |
244 u_char *statertn; | |
245 int *countrtn; | |
246 { | |
247 u_char cmdpkt[MAX_PKT_TO_TARGET], *dp; | |
248 int rc, slen; | |
249 | |
250 slen = strlen(pathname); | |
251 if (slen >= TMFFS_STRING_SIZE) { | |
252 printf("error: pathname arg exceeds string length limit\n"); | |
253 return(ERROR_USAGE); | |
254 } | |
255 dp = cmdpkt + 1; | |
256 *dp++ = ETM_FFS2; | |
257 *dp++ = TMFFS_OPENDIR; | |
258 *dp++ = slen + 1; | |
259 strcpy(dp, pathname); | |
260 dp += slen + 1; | |
261 rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1); | |
262 if (rc) | |
263 return(rc); | |
264 if (rvi_msg[3]) { | |
265 report_ffs_err("opendir", rvi_msg[3]); | |
266 return(ERROR_TARGET); | |
267 } | |
268 if (rvi_msg_len != 11 || rvi_msg[5] != 4) { | |
269 printf("error: opendir response has wrong length\n"); | |
270 return(ERROR_TARGET); | |
271 } | |
272 *countrtn = rvi_msg[4]; | |
273 bcopy(rvi_msg + 6, statertn, 4); | |
274 return(0); | |
275 } | |
276 | |
277 do_readdir(state, namebuf, namebuflen) | |
278 u_char *state; | |
279 char *namebuf; | |
280 { | |
281 u_char cmdpkt[10]; | |
282 int rc, slen; | |
283 | |
284 cmdpkt[1] = ETM_FFS2; | |
285 cmdpkt[2] = TMFFS_READDIR; | |
286 cmdpkt[3] = 4; | |
287 bcopy(state, cmdpkt+4, 4); | |
288 cmdpkt[8] = TMFFS_STRING_SIZE; | |
289 rc = etm_pkt_exch(cmdpkt, 8); | |
290 if (rc) | |
291 return(rc); | |
292 if (rvi_msg[3]) { | |
293 report_ffs_err("readdir", rvi_msg[3]); | |
294 return(ERROR_TARGET); | |
295 } | |
296 if (rvi_msg_len < 14) { | |
297 malformed: printf("error: readdir response is malformed\n"); | |
298 return(ERROR_TARGET); | |
299 } | |
300 if (rvi_msg[5] != 4) | |
301 goto malformed; | |
302 slen = rvi_msg[10]; | |
303 if (slen < 2 || rvi_msg_len != slen + 12) | |
304 goto malformed; | |
305 if (slen > namebuflen) { | |
306 printf("error: readdir response exceeds provided buffer\n"); | |
307 return(ERROR_TARGET); | |
308 } | |
309 if (rvi_msg[11 + slen - 1]) /* must be terminating NUL */ | |
310 goto malformed; | |
311 bcopy(rvi_msg + 6, state, 4); | |
312 strcpy(namebuf, rvi_msg + 11); | |
313 return(0); | |
314 } | |
315 | |
316 do_xlstat(pathname, result) | |
317 char *pathname; | |
318 struct stat_info *result; | |
319 { | |
320 u_char cmdpkt[MAX_PKT_TO_TARGET], *dp; | |
321 int rc, slen; | |
322 | |
323 slen = strlen(pathname); | |
324 if (slen >= TMFFS_STRING_SIZE) { | |
325 printf("error: pathname arg exceeds string length limit\n"); | |
326 return(ERROR_USAGE); | |
327 } | |
328 dp = cmdpkt + 1; | |
329 *dp++ = ETM_FFS2; | |
330 *dp++ = TMFFS_XLSTAT; | |
331 *dp++ = slen + 1; | |
332 strcpy(dp, pathname); | |
333 dp += slen + 1; | |
334 rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1); | |
335 if (rc) | |
336 return(rc); | |
337 if (rvi_msg[3]) { | |
338 report_ffs_err("xlstat", rvi_msg[3]); | |
339 return(ERROR_TARGET); | |
340 } | |
341 if (rvi_msg_len != 30 || rvi_msg[4] != 24) { | |
342 printf("error: xlstat response has wrong length\n"); | |
343 return(ERROR_TARGET); | |
344 } | |
345 result->type = rvi_msg[5]; | |
346 result->flags = rvi_msg[6]; | |
347 result->inode = rvi_msg[7] | rvi_msg[8] << 8; | |
348 result->size = rvi_msg[9] | rvi_msg[10] << 8 | rvi_msg[11] << 16 | | |
349 rvi_msg[12] << 24; | |
350 result->space = rvi_msg[13] | rvi_msg[14] << 8 | rvi_msg[15] << 16 | | |
351 rvi_msg[16] << 24; | |
352 result->location = rvi_msg[17] | rvi_msg[18] << 8 | rvi_msg[19] << 16 | | |
353 rvi_msg[20] << 24; | |
354 result->block = rvi_msg[22]; | |
355 result->sequence = rvi_msg[23] | rvi_msg[24] << 8; | |
356 result->updates = rvi_msg[25] | rvi_msg[26] << 8; | |
357 return(0); | |
358 } | |
359 | |
360 do_mkdir_existok(pathname) | |
361 char *pathname; | |
362 { | |
363 u_char cmdpkt[MAX_PKT_TO_TARGET], *dp; | |
364 int rc, slen; | |
365 struct stat_info stat; | |
366 | |
367 slen = strlen(pathname); | |
368 if (slen >= TMFFS_STRING_SIZE) { | |
369 printf("error: pathname arg exceeds string length limit\n"); | |
370 return(ERROR_USAGE); | |
371 } | |
372 dp = cmdpkt + 1; | |
373 *dp++ = ETM_FFS2; | |
374 *dp++ = TMFFS_MKDIR; | |
375 *dp++ = slen + 1; | |
376 strcpy(dp, pathname); | |
377 dp += slen + 1; | |
378 rc = etm_pkt_exch(cmdpkt, dp - cmdpkt - 1); | |
379 if (rc) | |
380 return(rc); | |
381 if (rvi_msg_len != 5) { | |
382 printf("error: mkdir response has wrong length\n"); | |
383 return(ERROR_TARGET); | |
384 } | |
385 if (!rvi_msg[3]) /* success */ | |
386 return(0); | |
387 if (rvi_msg[3] != TMFFS_ERR_EXISTS) { | |
388 report_ffs_err("mkdir", rvi_msg[3]); | |
389 return(ERROR_TARGET); | |
390 } | |
391 /* object already exists: OK if it's a directory, error otherwise */ | |
392 rc = do_xlstat(pathname, &stat); | |
393 if (rc) | |
394 return(rc); | |
395 if (stat.type == OT_DIR) | |
396 return(0); | |
397 else { | |
398 printf("error: %s exists and is not a directory\n", pathname); | |
399 return(ERROR_TARGET); | |
400 } | |
401 } |