INT64_T chirp_multi_mkdir(const char *volume, char const *path, INT64_T mode, time_t stoptime) { char lpath[CHIRP_PATH_MAX]; if(chirp_multi_lpath(volume, path, lpath, stoptime)) { return chirp_reli_mkdir(current_volume->host, lpath, mode, stoptime); } else { return -1; } }
static INT64_T do_put_one_dir(const char *hostport, const char *source_file, const char *target_file, int mode, time_t stoptime) { char new_source_file[CHIRP_PATH_MAX]; char new_target_file[CHIRP_PATH_MAX]; struct list *work_list; const char *name; INT64_T result; INT64_T total = 0; struct dirent *d; DIR *dir; work_list = list_create(); result = chirp_reli_mkdir(hostport, target_file, mode, stoptime); if(result == 0 || errno == EEXIST) { result = 0; dir = opendir(source_file); if(dir) { while((d = readdir(dir))) { if(!strcmp(d->d_name, ".")) continue; if(!strcmp(d->d_name, "..")) continue; list_push_tail(work_list, strdup(d->d_name)); } closedir(dir); while((name = list_pop_head(work_list))) { sprintf(new_source_file, "%s/%s", source_file, name); sprintf(new_target_file, "%s/%s", target_file, name); result = chirp_recursive_put(hostport, new_source_file, new_target_file, stoptime); free((char *) name); if(result < 0) break; total += result; } } else { result = -1; } } else { result = -1; } while((name = list_pop_head(work_list))) free((char *) name); list_delete(work_list); if(result < 0) { return -1; } else { return total; } }
INT64_T chirp_global_mkdir(const char *host, const char *path, INT64_T mode, time_t stoptime) { if(is_multi_path(host)) { char mhost[CHIRP_PATH_MAX]; char mpath[CHIRP_PATH_MAX]; parse_multi_path(path, mhost, mpath); return chirp_multi_mkdir(mhost, mpath, mode, stoptime); } else if(not_empty(path)) { return chirp_reli_mkdir(host, path, mode, stoptime); } else { errno = EACCES; return -1; } }
static INT64_T do_mkdir(int argc, char **argv) { char full_path[CHIRP_PATH_MAX]; int result; int create_parents = (argc == 3 && strcmp(argv[1], "-p") == 0); if(create_parents) { complete_remote_path(argv[2], full_path); result = chirp_reli_mkdir_recursive(current_host, full_path, 0777, stoptime); } else { complete_remote_path(argv[1], full_path); result = chirp_reli_mkdir(current_host, full_path, 0777, stoptime); } if(result < 0 && errno == EEXIST) result = 0; return result; }
static INT64_T chirp_thirdput_recursive(const char *subject, const char *lpath, const char *hostname, const char *rpath, const char *hostsubject, time_t stoptime) { struct chirp_stat info; INT64_T size = 0, result; char newlpath[CHIRP_PATH_MAX]; char newrpath[CHIRP_PATH_MAX]; int save_errno; int my_target_acl = 0; result = cfs->lstat(lpath, &info); if(result < 0) return result; if(S_ISDIR(info.cst_mode)) { CHIRP_FILE *aclfile; struct chirp_dir *dir; struct chirp_dirent *d; char aclsubject[CHIRP_PATH_MAX]; int aclflags; if(!chirp_acl_check_dir(lpath, subject, CHIRP_ACL_LIST)) return -1; // create the directory, but do not fail if it already exists result = chirp_reli_mkdir(hostname, rpath, 0700, stoptime); if(result < 0 && errno != EEXIST) return result; // set the access control to include the initiator result = chirp_reli_setacl(hostname, rpath, subject, "rwldax", stoptime); if(result < 0 && errno != EACCES) return result; // transfer each of the directory contents recurisvely dir = cfs->opendir(lpath); while((d = cfs->readdir(dir))) { if(!strcmp(d->name, ".")) continue; if(!strcmp(d->name, "..")) continue; if(!strncmp(d->name, ".__", 3)) continue; sprintf(newlpath, "%s/%s", lpath, d->name); sprintf(newrpath, "%s/%s", rpath, d->name); result = chirp_thirdput_recursive(subject, newlpath, hostname, newrpath, hostsubject, stoptime); if(result >= 0) { size += result; } else { result = -1; break; } } save_errno = errno; // finally, set the acl to duplicate the source directory, // but do not take away permissions from me or the initiator cfs->closedir(dir); aclfile = chirp_acl_open(lpath); if(!aclfile) return -1; while(chirp_acl_read(aclfile, aclsubject, &aclflags)) { // wait until the last minute to take away my permissions if(!strcmp(aclsubject, hostsubject)) { my_target_acl = aclflags; } // do not take permissions away from the initiator if(!strcmp(aclsubject, subject)) { continue; } chirp_reli_setacl(hostname, rpath, aclsubject, chirp_acl_flags_to_text(aclflags), stoptime); } chirp_acl_close(aclfile); // after setting everything else, then set my permissions from the ACL chirp_reli_setacl(hostname, rpath, hostsubject, chirp_acl_flags_to_text(my_target_acl), stoptime); errno = save_errno; if(result >= 0) { return size; } else { return -1; } } else if(S_ISLNK(info.cst_mode)) { if(!chirp_acl_check(lpath, subject, CHIRP_ACL_READ)) return -1; result = cfs->readlink(lpath, newlpath, sizeof(newlpath)); if(result < 0) return -1; return chirp_reli_symlink(hostname, newlpath, rpath, stoptime); } else if(S_ISREG(info.cst_mode)) { if(!chirp_acl_check(lpath, subject, CHIRP_ACL_READ)) return -1; int fd = cfs->open(lpath, O_RDONLY, 0); if(fd >= 0) { struct chirp_file *F = chirp_reli_open(hostname, rpath, O_WRONLY|O_CREAT|O_TRUNC, info.cst_mode, stoptime); if(F) { char buffer[65536]; INT64_T offset = 0; INT64_T nread; while ((nread = cfs->pread(fd, buffer, sizeof(buffer), offset)) > 0) { INT64_T nwritten = 0; while (nwritten < nread) { INT64_T nwrite = chirp_reli_pwrite(F, buffer+nwritten, nread-nwritten, offset, stoptime); if (nwrite == -1) { save_errno = errno; cfs->close(fd); chirp_reli_close(F, stoptime); errno = save_errno; return -1; } nwritten += nwrite; offset += nwrite; } } if(nread == -1) offset = -1; save_errno = errno; cfs->close(fd); chirp_reli_close(F, stoptime); errno = save_errno; return offset; } else { save_errno = errno; cfs->close(fd); errno = save_errno; return -1; } } else { return -1; } } else { return 0; } return -1; }
struct chirp_matrix *chirp_matrix_create(const char *host, const char *path, int width, int height, int element_size, int nhosts, time_t stoptime) { char host_file[CHIRP_LINE_MAX]; int result; unsigned int i; char **hosts; int nfiles = nhosts; while(1) { INT64_T n_row_per_file = height / nfiles; if(height % nfiles) n_row_per_file++; INT64_T file_size = n_row_per_file * width * element_size; if(file_size > GIGABYTE) { nfiles *= 2; continue; } else { break; } } char line[CHIRP_LINE_MAX * nfiles]; FILE *file = NULL; if(getenv("CHIRP_HOSTS")) { sprintf(host_file, "%s", getenv("CHIRP_HOSTS")); file = fopen(host_file, "r"); } if(!file) { if(getenv("HOME")) { sprintf(host_file, "%s/.chirp/hosts", getenv("HOME")); file = fopen(host_file, "r"); } } if(!file) { sprintf(host_file, "./chirp_hosts"); file = fopen(host_file, "r"); if(!file) { file = fopen(host_file, "w"); char hostname[CHIRP_LINE_MAX]; gethostname(hostname, CHIRP_LINE_MAX - 1); // get hostname, this may not have domain name, though! fprintf(file, "%s\n", hostname); fclose(file); file = fopen(host_file, "r"); } } if(!file) { debug(D_NOTICE | D_CHIRP, "matrix: could not open host list in %s: %s\n", host_file, strerror(errno)); errno = EINVAL; return 0; } hosts = malloc(sizeof(*hosts) * nhosts); for(i = 0; (int) i < nhosts; i++) { if(!fgets(line, sizeof(line), file)) { rewind(file); fgets(line, sizeof(line), file); } hosts[i] = strdup(line); int len = strlen(hosts[i]); hosts[i][len - 1] = '\0'; } fclose(file); sprintf(line, "%d\n%d\n%d\n%d\n%d\n", width, height, element_size, nhosts, nfiles); char datapath1[CHIRP_LINE_MAX]; char datapath2[CHIRP_LINE_MAX]; char datapath3[CHIRP_LINE_MAX]; char username[USERNAME_MAX]; char cookie[16]; username_get(username); string_cookie(cookie, sizeof(cookie)); sprintf(datapath1, "/%s", username); sprintf(datapath2, "/%s/matrixdata", username); sprintf(datapath3, "/%s/matrixdata/%s", username, cookie); for(i = 0; (int) i < nfiles; i++) { const char *datahost = hosts[i % nhosts]; result = chirp_reli_mkdir(datahost, datapath1, 0700, stoptime); result = chirp_reli_mkdir(datahost, datapath2, 0700, stoptime); result = chirp_reli_mkdir(datahost, datapath3, 0700, stoptime); sprintf(&line[strlen(line)], "%s %s/data.%d\n", datahost, datapath3, i); } for(i = 0; (int) i < nhosts; i++) { free(hosts[i]); } free(hosts); char metapath[CHIRP_LINE_MAX]; strcpy(metapath, path); result = chirp_reli_putfile_buffer(host, path, line, 0700, strlen(line), stoptime); if(result < 0) { for(i = 1; i < strlen(metapath); i++) if(metapath[i] == '/') { metapath[i] = '\0'; result = chirp_reli_mkdir(host, metapath, 0700, stoptime); if(result < 0 && errno != EEXIST) { debug(D_CHIRP, "matrix: could not build directory /chirp/%s/%s to create metadata file: %s\n", host, metapath, strerror(errno)); return 0; } metapath[i] = '/'; } result = chirp_reli_putfile_buffer(host, path, line, 0700, strlen(line), stoptime); if(result < 0) { debug(D_CHIRP, "matrix: could not create metadata file /chirp/%s/%s: %s\n", host, path, strerror(errno)); return 0; } } debug(D_CHIRP, "matrix: created matrix %s/%s -- now opening\n", host, path); return chirp_matrix_open(host, path, stoptime); }