Пример #1
0
static int sn_ticket (confuga *C, const struct confuga_host *host)
{
	static const char SQL[] =
		"UPDATE Confuga.StorageNode"
		"	SET ticket = ?2"
		"	WHERE hostport = ?1;"
		;

	int rc;
	sqlite3 *db = C->db;
	sqlite3_stmt *stmt = NULL;
	const char *current = SQL;
	time_t stoptime = STOPTIME_SHORT;

	char ticket[PATH_MAX];
	char path[CHIRP_PATH_MAX];
	struct stat info;
	FILE *stream = NULL;

	CATCHUNIX(snprintf(ticket, sizeof(ticket), "%s/ticket", C->root));
	CATCHUNIX(chirp_reli_ticket_register(host->hostport, ticket, "self", TICKET_DURATION, stoptime));

	/* The list permission is necessary because chirp_fs_local_scheduler.c:geturl does a stat. */
	CATCHUNIX(snprintf(path, sizeof(path), "%s/file", host->root));
	CATCHUNIX(chirp_reli_ticket_modify(host->hostport, ticket, path, "lr", stoptime));

	/* Add write permission because a putfile may need retried. */
	CATCHUNIX(snprintf(path, sizeof(path), "%s/open", host->root));
	CATCHUNIX(chirp_reli_ticket_modify(host->hostport, ticket, path, "pw", stoptime));

	CATCHUNIX(snprintf(path, sizeof(path), "%s/ticket", host->root));
	stream = fopen(ticket, "r");
	CATCHUNIX(stream ? 0 : -1);
	CATCHUNIX(fstat(fileno(stream), &info));
	CATCHUNIX(chirp_reli_putfile(host->hostport, path, stream, S_IRUSR, info.st_size, stoptime));

	sqlcatch(sqlite3_prepare_v2(db, current, -1, &stmt, &current));
	sqlcatch(sqlite3_bind_text(stmt, 1, host->hostport, -1, SQLITE_STATIC));
	sqlcatch(sqlite3_bind_blob(stmt, 2, C->ticket, sizeof(C->ticket), SQLITE_STATIC));
	sqlcatchcode(sqlite3_step(stmt), SQLITE_DONE);
	sqlcatch(sqlite3_finalize(stmt); stmt = NULL);

	rc = 0;
	goto out;
out:
	if (stream)
		fclose(stream);
	sqlite3_finalize(stmt);
	return rc;
}
Пример #2
0
INT64_T chirp_multi_putfile(const char *volume, const char *path, FILE * stream, INT64_T mode, INT64_T length, time_t stoptime)
{
	struct file_info info;
	struct chirp_file *file;

	if(!chirp_multi_lookup(volume, path, &info, stoptime)) {
		file = chirp_multi_create(volume, path, O_CREAT | O_TRUNC | O_WRONLY, mode, stoptime);
		if(!file)
			return -1;
		chirp_multi_close(file, stoptime);
		if(!chirp_multi_lookup(volume, path, &info, stoptime))
			return -1;
	}
	return chirp_reli_putfile(info.rhost, info.rpath, stream, mode, length, stoptime);
}
Пример #3
0
static INT64_T do_put_one_file(const char *hostport, const char *source_file, const char *target_file, int mode, INT64_T length, time_t stoptime)
{
	FILE *file;
	int save_errno;

	file = fopen64(source_file, "r");
	if(!file)
		return -1;

	length = chirp_reli_putfile(hostport, target_file, file, mode, length, stoptime);

	if(length >= 0) {
		fclose(file);
		return length;
	} else {
		save_errno = errno;
		fclose(file);
		errno = save_errno;
		return -1;
	}
}
Пример #4
0
INT64_T chirp_global_putfile(const char *host, const char *path, FILE * stream, INT64_T mode, INT64_T length, 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_putfile(mhost, mpath, stream, mode, length, stoptime);
	} else if(not_empty(path)) {
		return chirp_reli_putfile(host, path, stream, mode, length, stoptime);
	} else if(not_empty(host)) {
		if(server_lookup(host, stoptime)) {
			errno = EISDIR;
			return -1;
		} else {
			errno = EACCES;
			return -1;
		}
	} else {
		errno = EACCES;
		return -1;
	}
}
Пример #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 = chirp_alloc_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 = chirp_alloc_opendir(lpath);
		while((d = chirp_alloc_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
		chirp_alloc_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 = chirp_alloc_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 = chirp_alloc_open(lpath, O_RDONLY, 0);
		if(fd >= 0) {
			FILE *stream = fdopen(fd, "r");
			if(stream) {
				result = chirp_reli_putfile(hostname, rpath, stream, info.cst_mode, info.cst_size, stoptime);
				save_errno = errno;
				fclose(stream);
				errno = save_errno;
				return result;
			} else {
				result = -1;
			}
		} else {
			return -1;
		}
	} else {
		return 0;
	}

	return -1;
}