FreeCalypso > hg > freecalypso-sw
comparison rvinterf/etmsync/fsread.c @ 295:3dd74b16df82
fc-fsio: pathname recursion handling revamped
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sat, 01 Mar 2014 08:01:08 +0000 |
parents | e33d71e9033f |
children | 792f164b63a6 |
comparison
equal
deleted
inserted
replaced
294:797468042b32 | 295:3dd74b16df82 |
---|---|
12 #include <unistd.h> | 12 #include <unistd.h> |
13 #include "etm.h" | 13 #include "etm.h" |
14 #include "ffs.h" | 14 #include "ffs.h" |
15 #include "tmffs2.h" | 15 #include "tmffs2.h" |
16 #include "limits.h" | 16 #include "limits.h" |
17 #include "ffslimits.h" | |
17 #include "localtypes.h" | 18 #include "localtypes.h" |
18 #include "localstruct.h" | 19 #include "localstruct.h" |
19 #include "exitcodes.h" | 20 #include "exitcodes.h" |
21 | |
22 extern char *pathname_for_ffs_child(); | |
20 | 23 |
21 void | 24 void |
22 ll_print_line(pathname, stat) | 25 ll_print_line(pathname, stat) |
23 char *pathname; | 26 char *pathname; |
24 struct stat_info *stat; | 27 struct stat_info *stat; |
42 default: | 45 default: |
43 printf("?%c %s\n", readonly, pathname); | 46 printf("?%c %s\n", readonly, pathname); |
44 } | 47 } |
45 } | 48 } |
46 | 49 |
47 void | |
48 mk_ffs_child_path_from_readdir(dirpath, rdname, buf) | |
49 char *dirpath, *rdname, *buf; | |
50 { | |
51 char *tailp; | |
52 | |
53 tailp = index(dirpath, '\0') - 1; | |
54 if (*tailp == '/') | |
55 sprintf(buf, "%s%s", dirpath, rdname); | |
56 else | |
57 sprintf(buf, "%s/%s", dirpath, rdname); | |
58 } | |
59 | |
60 cmd_ll(argc, argv) | 50 cmd_ll(argc, argv) |
61 char **argv; | 51 char **argv; |
62 { | 52 { |
63 struct stat_info stat; | 53 struct stat_info stat; |
64 u_char rdstate[4]; | 54 u_char rdstate[4]; |
65 char rdbuf[TMFFS_STRING_SIZE], childpath[TMFFS_STRING_SIZE*2]; | 55 char rdbuf[MAX_FN_COMPONENT+1], childpath[MAX_FULL_PATHNAME+1], *childp; |
66 int nument, i, rc; | 56 int nument, i, rc; |
67 | 57 |
58 if (validate_ffs_pathname(argv[1]) < 0) | |
59 return(ERROR_USAGE); /* err msg already printed */ | |
68 rc = do_xlstat(argv[1], &stat); | 60 rc = do_xlstat(argv[1], &stat); |
69 if (rc) | 61 if (rc) |
70 return(rc); | 62 return(rc); |
71 if (stat.type != OT_DIR) { | 63 if (stat.type != OT_DIR) { |
72 ll_print_line(argv[1], &stat); | 64 ll_print_line(argv[1], &stat); |
77 return(rc); | 69 return(rc); |
78 if (!nument) { | 70 if (!nument) { |
79 printf("<empty dir>\n"); | 71 printf("<empty dir>\n"); |
80 return(0); | 72 return(0); |
81 } | 73 } |
74 childp = pathname_for_ffs_child(argv[1], childpath); | |
75 if (!childp) { | |
76 printf("error: non-empty dir at the limit of pathname depth\n"); | |
77 return(ERROR_TARGET); | |
78 } | |
82 for (i = 0; i < nument; i++) { | 79 for (i = 0; i < nument; i++) { |
83 rc = do_readdir(rdstate, rdbuf); | 80 rc = do_readdir(rdstate, rdbuf, MAX_FN_COMPONENT+1); |
84 if (rc) | 81 if (rc) |
85 return(rc); | 82 return(rc); |
86 mk_ffs_child_path_from_readdir(argv[1], rdbuf, childpath); | 83 if (index(rdbuf, '/')) { |
84 printf("error: readdir result contains a slash\n"); | |
85 return(ERROR_TARGET); | |
86 } | |
87 strcpy(childp, rdbuf); | |
87 rc = do_xlstat(childpath, &stat); | 88 rc = do_xlstat(childpath, &stat); |
88 if (rc) { | 89 if (rc) { |
89 printf("xlstat failed on %s\n", childpath); | 90 printf("xlstat failed on %s\n", childpath); |
90 return(rc); | 91 return(rc); |
91 } | 92 } |
146 rc = do_xlstat(ffspath, &stat); | 147 rc = do_xlstat(ffspath, &stat); |
147 if (rc) | 148 if (rc) |
148 return(rc); | 149 return(rc); |
149 switch (stat.type) { | 150 switch (stat.type) { |
150 case OT_FILE: | 151 case OT_FILE: |
151 return cpout_file(ffspath, &stat, hostpath); | 152 return cpout_file(ffspath, hostpath); |
152 case OT_DIR: | 153 case OT_DIR: |
153 return cpout_dir(ffspath, hostpath); | 154 return cpout_dir(ffspath, hostpath); |
154 case OT_LINK: | 155 case OT_LINK: |
155 printf("skipping FFS symlink %s\n", ffspath); | 156 printf("skipping FFS symlink %s\n", ffspath); |
156 return(0); | 157 return(0); |
158 printf("error: stat returned bad objtype for %s\n", ffspath); | 159 printf("error: stat returned bad objtype for %s\n", ffspath); |
159 return(ERROR_TARGET); | 160 return(ERROR_TARGET); |
160 } | 161 } |
161 } | 162 } |
162 | 163 |
163 cpout_file(ffspath, stat, hostpath) | 164 cpout_file(ffspath, hostpath) |
164 char *ffspath, *hostpath; | 165 char *ffspath, *hostpath; |
165 struct stat_info *stat; | |
166 { | 166 { |
167 int tfd; | 167 int tfd; |
168 FILE *of; | 168 FILE *of; |
169 u_char buf[MAX_READ_DATA]; | 169 u_char buf[MAX_READ_DATA]; |
170 int rc, sz; | 170 int rc, sz; |
222 | 222 |
223 cpout_dir(ffspath_dir, hostpath_dir) | 223 cpout_dir(ffspath_dir, hostpath_dir) |
224 char *ffspath_dir, *hostpath_dir; | 224 char *ffspath_dir, *hostpath_dir; |
225 { | 225 { |
226 u_char rdstate[4]; | 226 u_char rdstate[4]; |
227 char rdbuf[TMFFS_STRING_SIZE], ffspath_child[TMFFS_STRING_SIZE*2]; | 227 char rdbuf[MAX_FN_COMPONENT+1], ffspath_child[MAX_FULL_PATHNAME+1]; |
228 char *childp; | |
228 char hostpath_child[MAXPATHLEN]; | 229 char hostpath_child[MAXPATHLEN]; |
229 int nument, i, rc; | 230 int nument, i, rc, childerr; |
230 | 231 |
231 printf("dir %s\n", ffspath_dir); | 232 printf("dir %s\n", ffspath_dir); |
232 rc = host_mkdir(hostpath_dir); | 233 rc = host_mkdir(hostpath_dir); |
233 if (rc) | 234 if (rc) |
234 return(rc); | 235 return(rc); |
235 rc = do_opendir(ffspath_dir, rdstate, &nument); | 236 rc = do_opendir(ffspath_dir, rdstate, &nument); |
236 if (rc) | 237 if (rc) |
237 return(rc); | 238 return(rc); |
239 if (!nument) | |
240 return(0); | |
241 childp = pathname_for_ffs_child(ffspath_dir, ffspath_child); | |
242 if (!childp) { | |
243 printf("error: non-empty dir at the limit of pathname depth\n"); | |
244 return(ERROR_TARGET); | |
245 } | |
246 childerr = 0; | |
238 for (i = 0; i < nument; i++) { | 247 for (i = 0; i < nument; i++) { |
239 rc = do_readdir(rdstate, rdbuf); | 248 rc = do_readdir(rdstate, rdbuf); |
240 if (rc) | 249 if (rc) |
241 return(rc); | 250 return(rc); |
242 mk_ffs_child_path_from_readdir(ffspath_dir, rdbuf, | 251 if (index(rdbuf, '/')) { |
243 ffspath_child); | 252 printf("error: readdir result contains a slash\n"); |
253 return(ERROR_TARGET); | |
254 } | |
255 strcpy(childp, rdbuf); | |
244 if (rdbuf[0] == '.') { | 256 if (rdbuf[0] == '.') { |
245 printf("skipping %s\n", ffspath_child); | 257 printf("skipping %s\n", ffspath_child); |
246 return(0); | 258 continue; |
247 } | 259 } |
248 if (strlen(hostpath_dir) + strlen(rdbuf) + 2 > | 260 if (strlen(hostpath_dir) + strlen(rdbuf) + 2 > |
249 sizeof hostpath_child) { | 261 sizeof hostpath_child) { |
250 fprintf(stderr, | 262 fprintf(stderr, |
251 "error: host side pathname buffer overflow\n"); | 263 "error: host side pathname buffer overflow\n"); |
252 return(ERROR_UNIX); | 264 return(ERROR_UNIX); |
253 } | 265 } |
254 sprintf(hostpath_child, "%s/%s", hostpath_dir, rdbuf); | 266 sprintf(hostpath_child, "%s/%s", hostpath_dir, rdbuf); |
255 rc = cpout_object(ffspath_child, hostpath_child); | 267 rc = cpout_object(ffspath_child, hostpath_child); |
268 if (rc && rc != ERROR_TARGET) | |
269 return(rc); | |
256 if (rc) | 270 if (rc) |
257 return(rc); | 271 childerr = rc; |
258 } | 272 } |
259 return(0); | 273 return(childerr); |
260 } | 274 } |
261 | 275 |
262 cmd_cpout(argc, argv) | 276 cmd_cpout(argc, argv) |
263 char **argv; | 277 char **argv; |
264 { | 278 { |
279 if (validate_ffs_pathname(argv[1]) < 0) | |
280 return(ERROR_USAGE); /* err msg already printed */ | |
265 return cpout_object(argv[1], argv[2]); | 281 return cpout_object(argv[1], argv[2]); |
266 } | 282 } |
283 | |
284 cmd_cpout_file(argc, argv) | |
285 char **argv; | |
286 { | |
287 return cpout_file(argv[1], argv[2]); | |
288 } |