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 }