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 }