I realized that this fix only took into account one case.  Attached is a
more thorough patch.

-  
Hugh Greenberg
Los Alamos National Laboratory, CCS-1
Email: [email protected]
Phone: (505) 665-6471


On Wed, 2008-12-17 at 12:10 -0700, Hugh Greenberg wrote:
> This patch fixes the file not found error when multiple sources are
> specified that share a base path. 
> 
> Signed-off-by: Hugh Greenberg <[email protected]
> 
> 
Index: xget.c
===================================================================
--- xget.c	(revision 750)
+++ xget.c	(working copy)
@@ -845,11 +845,15 @@
 		sname++;
 	else 
 		sname = name;
-	
+		
+	if ((ret = check_existance(parent, sname)))
+		return ret;
+
+			
 	ret = spfile_alloc(parent, sname, mode, qpath, ops, aux);
 	if (!ret)
 		return NULL;
-
+	
 	if (parent) {
 		if (parent->dirlast) {
 			parent->dirlast->next = ret;
@@ -922,6 +926,11 @@
 	f->progress = time(NULL);
 	f->retries = 0;
 	f->dir = create_file(parent, nname, 0555 | Dmdir, (qp << 8), &dir_ops, usr, grp, f);
+	if (check_existance(f->dir, "data")) {
+		free(f);
+		return NULL;
+	}
+
 	f->dir->mtime = f->dir->atime = mtime;
 	f->datafile = create_file(f->dir, "data", mode, (qp << 8) | Qdata, &data_ops, usr, grp, f);
 	f->datafile->length = datasize;
@@ -1065,6 +1074,23 @@
 	return NULL;
 }
 
+static Spfile *
+check_existance(Spfile *parent, char *name) {
+	Spfile *p, *dir;
+
+	dir = NULL;
+	for (p = parent->dirfirst; p != NULL; p = p->next) {
+		if (!strcmp(p->name, name)) {
+			dir = p;
+			break;
+		}
+	}
+
+	return dir;
+}
+	
+	
+	
 static void
 respondreqs(File *f)
 {
@@ -1248,6 +1274,15 @@
 	if (!buf)
 		return -1;
 
+	file = filealloc(dir, nname, lname, len, 0, mtime, 0, npmode, 
+			 usr, grp);
+	if (!file) {
+		if (sp_haserror())
+			goto error;
+		
+		return 0;
+	}
+
 	sprintf(buf, "%s/checksum", nname);
 	checksumfid = spc_open(masterfs, buf, Oread);
 	if (!checksumfid)
@@ -1260,10 +1295,6 @@
 	buf[n] = '\0';
 	checksum = strtoul(buf, NULL, 0);
 	spc_close(checksumfid);
-	file = filealloc(dir, nname, lname, len, 0, mtime, 0, npmode, 
-			 usr, grp);
-	if (!file)
-		goto error;
 
 	file->fs = NULL;
 	file->datafid = NULL;
@@ -1554,7 +1585,7 @@
 {
 	int i;
 	char *s, *p, *nprefix;
-	Spfile *dir;
+	Spfile *dir, *t;
 
 	path = sp_malloc(strlen(fpath) + 1);
 	strcpy(path, fpath);
@@ -1566,21 +1597,26 @@
 
 	for(i = strlen(outname) - 1; i >= 0 && outname[i] == '/'; i--)
 		;
+	
 	outname[i+1] = '\0';
-
+	p = path;
 	dir = root;
-	p = path;
 	if (*p == '/')
 		p++;
 
 	while ((s = strchr(p, '/')) != NULL) {
 		*s = '\0';
-		dir = create_file(dir, p, Dmdir|0770, qpath++ * 16,
-				  &dir_ops, NULL, NULL, NULL);
+		t = check_existance(dir, p);
+		if (!t)
+			dir = create_file(dir, p, Dmdir|0770, qpath++ * 16,
+					  &dir_ops, NULL, NULL, NULL);
+		else
+			dir = t;
 
-		if (!dir)
+		if (!dir) {
+			free(p);
 			return -1;
-	       
+		}
 
 		*s = '/';
 		p = s + 1;
@@ -1589,11 +1625,22 @@
 	if (p == path)
 		nprefix = "";
 	else {
-		nprefix = path;
+		s = strrchr(path, '/');
+		if (s) {
+		        nprefix = sp_malloc(s - path + 1);
+			snprintf(nprefix, s - path + 1, "%s", path);
+		} else {
+			nprefix = sp_malloc(strlen(path) + 1);
+			strcpy(nprefix, path);
+		}
+
 		*(p-1) = '\0';
 	}
 	
 	i = netread(dir, outname, nprefix, p);
+	if (strlen(nprefix) > 0) 
+		free(nprefix);
+
 	return i;
 }
 
@@ -1721,6 +1768,7 @@
 	}
 
 	signal(SIGHUP, reload);
+	
 	if (netaddress) {
 		if (netmount(netaddress, user, port) < 0) {
 			fprintf(stderr, "Could not connect to server\n");
@@ -1796,12 +1844,19 @@
 				goto error;
 			}
 		}
-		
-		if(!S_ISDIR(st.st_mode) && fileargs > 2) {
-			debug(Dbgfn, "Plural sources and nondirectory destination.\n");
-			usage(argv[0]);
+
+		if(!stat(outname, &st)) {
+			if(!S_ISDIR(st.st_mode) && fileargs > 2) {
+				debug(Dbgfn, "Plural sources and nondirectory destination.\n");
+				usage(argv[0]);
+			}
+		} else {
+			sp_uerror(errno);
+			debug(Dbgfn, "Destination does not exist and cannot be created.\n");
+			goto error;
 		}
 
+
 		for(i = optind; i < argc - 1; i++) {
 			dlname = argv[i];
 			if (!strcmp(".", dlname))
Index: xget.h
===================================================================
--- xget.h	(revision 750)
+++ xget.h	(working copy)
@@ -114,3 +114,4 @@
 static int      file_finalize(File *f, int write);
 u32 crc32(const void *buf, size_t size);
 u32 fcrc32(int fd, u64 size);
+static Spfile   *check_existance(Spfile *parent, char *name);

Reply via email to