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);