diff 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
line wrap: on
line diff
--- a/rvinterf/etmsync/fsread.c	Sat Mar 01 04:04:20 2014 +0000
+++ b/rvinterf/etmsync/fsread.c	Sat Mar 01 08:01:08 2014 +0000
@@ -14,10 +14,13 @@
 #include "ffs.h"
 #include "tmffs2.h"
 #include "limits.h"
+#include "ffslimits.h"
 #include "localtypes.h"
 #include "localstruct.h"
 #include "exitcodes.h"
 
+extern char *pathname_for_ffs_child();
+
 void
 ll_print_line(pathname, stat)
 	char *pathname;
@@ -44,27 +47,16 @@
 	}
 }
 
-void
-mk_ffs_child_path_from_readdir(dirpath, rdname, buf)
-	char *dirpath, *rdname, *buf;
-{
-	char *tailp;
-
-	tailp = index(dirpath, '\0') - 1;
-	if (*tailp == '/')
-		sprintf(buf, "%s%s", dirpath, rdname);
-	else
-		sprintf(buf, "%s/%s", dirpath, rdname);
-}
-
 cmd_ll(argc, argv)
 	char **argv;
 {
 	struct stat_info stat;
 	u_char rdstate[4];
-	char rdbuf[TMFFS_STRING_SIZE], childpath[TMFFS_STRING_SIZE*2];
+	char rdbuf[MAX_FN_COMPONENT+1], childpath[MAX_FULL_PATHNAME+1], *childp;
 	int nument, i, rc;
 
+	if (validate_ffs_pathname(argv[1]) < 0)
+		return(ERROR_USAGE);	/* err msg already printed */
 	rc = do_xlstat(argv[1], &stat);
 	if (rc)
 		return(rc);
@@ -79,11 +71,20 @@
 		printf("<empty dir>\n");
 		return(0);
 	}
+	childp = pathname_for_ffs_child(argv[1], childpath);
+	if (!childp) {
+		printf("error: non-empty dir at the limit of pathname depth\n");
+		return(ERROR_TARGET);
+	}
 	for (i = 0; i < nument; i++) {
-		rc = do_readdir(rdstate, rdbuf);
+		rc = do_readdir(rdstate, rdbuf, MAX_FN_COMPONENT+1);
 		if (rc)
 			return(rc);
-		mk_ffs_child_path_from_readdir(argv[1], rdbuf, childpath);
+		if (index(rdbuf, '/')) {
+			printf("error: readdir result contains a slash\n");
+			return(ERROR_TARGET);
+		}
+		strcpy(childp, rdbuf);
 		rc = do_xlstat(childpath, &stat);
 		if (rc) {
 			printf("xlstat failed on %s\n", childpath);
@@ -148,7 +149,7 @@
 		return(rc);
 	switch (stat.type) {
 	case OT_FILE:
-		return cpout_file(ffspath, &stat, hostpath);
+		return cpout_file(ffspath, hostpath);
 	case OT_DIR:
 		return cpout_dir(ffspath, hostpath);
 	case OT_LINK:
@@ -160,9 +161,8 @@
 	}
 }
 
-cpout_file(ffspath, stat, hostpath)
+cpout_file(ffspath, hostpath)
 	char *ffspath, *hostpath;
-	struct stat_info *stat;
 {
 	int tfd;
 	FILE *of;
@@ -224,9 +224,10 @@
 	char *ffspath_dir, *hostpath_dir;
 {
 	u_char rdstate[4];
-	char rdbuf[TMFFS_STRING_SIZE], ffspath_child[TMFFS_STRING_SIZE*2];
+	char rdbuf[MAX_FN_COMPONENT+1], ffspath_child[MAX_FULL_PATHNAME+1];
+	char *childp;
 	char hostpath_child[MAXPATHLEN];
-	int nument, i, rc;
+	int nument, i, rc, childerr;
 
 	printf("dir %s\n", ffspath_dir);
 	rc = host_mkdir(hostpath_dir);
@@ -235,15 +236,26 @@
 	rc = do_opendir(ffspath_dir, rdstate, &nument);
 	if (rc)
 		return(rc);
+	if (!nument)
+		return(0);
+	childp = pathname_for_ffs_child(ffspath_dir, ffspath_child);
+	if (!childp) {
+		printf("error: non-empty dir at the limit of pathname depth\n");
+		return(ERROR_TARGET);
+	}
+	childerr = 0;
 	for (i = 0; i < nument; i++) {
 		rc = do_readdir(rdstate, rdbuf);
 		if (rc)
 			return(rc);
-		mk_ffs_child_path_from_readdir(ffspath_dir, rdbuf,
-						ffspath_child);
+		if (index(rdbuf, '/')) {
+			printf("error: readdir result contains a slash\n");
+			return(ERROR_TARGET);
+		}
+		strcpy(childp, rdbuf);
 		if (rdbuf[0] == '.') {
 			printf("skipping %s\n", ffspath_child);
-			return(0);
+			continue;
 		}
 		if (strlen(hostpath_dir) + strlen(rdbuf) + 2 >
 		    sizeof hostpath_child) {
@@ -253,14 +265,24 @@
 		}
 		sprintf(hostpath_child, "%s/%s", hostpath_dir, rdbuf);
 		rc = cpout_object(ffspath_child, hostpath_child);
-		if (rc)
+		if (rc && rc != ERROR_TARGET)
 			return(rc);
+		if (rc)
+			childerr = rc;
 	}
-	return(0);
+	return(childerr);
 }
 
 cmd_cpout(argc, argv)
 	char **argv;
 {
+	if (validate_ffs_pathname(argv[1]) < 0)
+		return(ERROR_USAGE);	/* err msg already printed */
 	return cpout_object(argv[1], argv[2]);
 }
+
+cmd_cpout_file(argc, argv)
+	char **argv;
+{
+	return cpout_file(argv[1], argv[2]);
+}