示例#1
0
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;
	}
}
示例#2
0
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;
	}
}
示例#3
0
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;
	}
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
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);
}