示例#1
0
char *
gfs_utimes(const char *gfarm_url, const struct gfarm_timespec *tsp)
{
	char *e, *gfarm_file;
	struct gfarm_path_info pi;
	struct timeval now;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		return (e);
	e = gfarm_path_info_get(gfarm_file, &pi);
	free(gfarm_file);
	if (e != NULL)
		return (e);
	e = gfarm_path_info_access(&pi, GFS_W_OK);
	if (e != NULL)
		return (e);

	gettimeofday(&now, NULL);
	if (tsp == NULL) {
		pi.status.st_atimespec.tv_sec = 
		pi.status.st_mtimespec.tv_sec = now.tv_sec;
		pi.status.st_atimespec.tv_nsec = 
		pi.status.st_mtimespec.tv_nsec = now.tv_usec * 1000;
	} else {
		pi.status.st_atimespec = tsp[0];
		pi.status.st_mtimespec = tsp[1];
	}
	pi.status.st_ctimespec.tv_sec = now.tv_sec;
	pi.status.st_ctimespec.tv_nsec = now.tv_usec * 1000;
	e = gfarm_path_info_replace(pi.pathname, &pi);
	gfarm_path_info_free(&pi);
	return (e);
}
示例#2
0
char *
gfs_pio_open(const char *url, int flags, GFS_File *gfp)
{
	char *e, *pathname;
	GFS_File gf;
	gfarm_timerval_t t1, t2;

	gfs_profile(gfarm_gettimerval(&t1));

	if ((flags & GFARM_FILE_ACCMODE) != GFARM_FILE_RDONLY) {
#if 0 /*  XXX - ROOT I/O opens a new file with O_CREAT|O_RDRW mode. */
		e = GFARM_ERR_OPERATION_NOT_SUPPORTED; /* XXX */
		goto finish;
#else
		flags |= GFARM_FILE_CREATE;
#endif
	}
	e = gfarm_url_make_path(url, &pathname);
	if (e != NULL)
		goto finish;
	e = gfs_file_alloc(&gf);
	if (e != NULL) {
		free(pathname);
		goto finish;
	}
	gf->open_flags = flags;
	gf->mode |= GFS_FILE_MODE_READ;
	if (((flags & GFARM_FILE_ACCMODE) == GFARM_FILE_RDWR)
	    || ((flags & GFARM_FILE_ACCMODE) == GFARM_FILE_WRONLY))
		gf->mode |= GFS_FILE_MODE_WRITE;
	e = gfarm_path_info_get(pathname, &gf->pi);
	free(pathname);
	if (e != NULL)
		goto finish;
	e = gfarm_path_info_access(&gf->pi, GFS_R_OK);
	if (e != NULL) {
		gfarm_path_info_free(&gf->pi);
		gfs_file_free(gf);
		goto finish;
	}
	if (!GFARM_S_ISREG(gf->pi.status.st_mode)) {
		if (GFARM_S_ISDIR(gf->pi.status.st_mode))
			e = GFARM_ERR_IS_A_DIRECTORY;
		else
			e = GFARM_ERR_OPERATION_NOT_SUPPORTED;
		gfarm_path_info_free(&gf->pi);
		gfs_file_free(gf);
		goto finish;
	}
	gf->mode |= GFS_FILE_MODE_NSEGMENTS_FIXED;
	*gfp = gf;

	e = NULL;
 finish:
	gfs_profile(gfarm_gettimerval(&t2));
	gfs_profile(gfs_pio_open_time += gfarm_timerval_sub(&t2, &t1));

	return (e);
}
示例#3
0
char *
gfarm_url_section_replicate_from_to(char *gfarm_url, char *section,
	char *srchost, char *dsthost)
{
	char *e, *gfarm_file, *canonical_hostname, *if_hostname;
	struct sockaddr peer_addr;
	struct gfarm_path_info pi;
	struct gfarm_file_section_info si;
	gfarm_mode_t mode_allowed = 0;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		goto finish;
	e = gfarm_path_info_get(gfarm_file, &pi);
	if (e != NULL)
		goto finish_gfarm_file;
	e = gfarm_file_section_info_get(gfarm_file, section, &si);
	if (e != NULL)
		goto finish_path_info;

	e = gfarm_host_get_canonical_name(srchost, &canonical_hostname);
	if (e != NULL)
		goto finish_canonical_hostname;

	/* reflect "address_use" directive in the `srchost' */
	e = gfarm_host_address_get(srchost, gfarm_spool_server_port,
	    &peer_addr, &if_hostname);
	if (e != NULL)
		goto finish_section_info;
	/*
	 * XXX - if the owner of a file is not the same, permit a
	 * group/other write access - This should be fixed in the next
	 * major release.
	 */
	if (strcmp(pi.status.st_user, gfarm_get_global_username()) != 0) {
		e = gfarm_path_info_access(&pi, GFS_R_OK);
		if (e != NULL)
			goto finish_path_info;
		mode_allowed = 022;
	}
	e = gfarm_file_section_replicate_from_to_internal(
	    gfarm_file, section,
	    (pi.status.st_mode | mode_allowed) & GFARM_S_ALLPERM, si.filesize,
	    canonical_hostname, if_hostname, dsthost);

	free(if_hostname);
finish_canonical_hostname:
	free(canonical_hostname);
finish_section_info:
	gfarm_file_section_info_free(&si);
finish_path_info:
	gfarm_path_info_free(&pi);
finish_gfarm_file:
	free(gfarm_file);
finish:
	return (e);
}
示例#4
0
char *
gfs_access(const char *gfarm_url, int mode)
{
	char *e, *gfarm_file;
	struct gfarm_path_info pi;
	gfarm_mode_t stat_mode;
	int stat_nsections, nsections;
	struct gfarm_file_section_info *sections;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		return (e);
	e = gfarm_path_info_get(gfarm_file, &pi);
	if (e != NULL) {
		free(gfarm_file);
		return (e);
	}
	stat_mode = pi.status.st_mode;
	stat_nsections = pi.status.st_nsections;
	e = gfarm_path_info_access(&pi, mode);
	gfarm_path_info_free(&pi);
	if (e != NULL) {
		free(gfarm_file);
		return (e);
	}
	if (GFARM_S_ISDIR(stat_mode)) {
		free(gfarm_file);
		return (NULL);
	}
	/*
	 * Check all fragments are ready or not.
	 * XXX - is this check necessary?
	 */
	e = gfarm_file_section_info_get_all_by_file(
		gfarm_file, &nsections, &sections);
	free(gfarm_file);
	if (e != NULL)
		return (e);
	gfarm_file_section_info_free_all(nsections, sections);
	if (!GFARM_S_IS_PROGRAM(stat_mode)
	    && nsections != stat_nsections)
		e = GFARM_ERR_FRAGMENT_NUMBER_DOES_NOT_MATCH;
	return (e);
}
示例#5
0
char *
gfarm_url_section_replicate_to(char *gfarm_url, char *section, char *dsthost)
{
	char *e, *gfarm_file;
	struct gfarm_path_info pi;
	struct gfarm_file_section_info si;
	gfarm_mode_t mode_allowed = 0;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		goto finish;
	e = gfarm_path_info_get(gfarm_file, &pi);
	if (e != NULL)
		goto finish_gfarm_file;
	e = gfarm_file_section_info_get(gfarm_file, section, &si);
	if (e != NULL)
		goto finish_path_info;
	/*
	 * XXX - if the owner of a file is not the same, permit a
	 * group/other write access - This should be fixed in the next
	 * major release.
	 */
	if (strcmp(pi.status.st_user, gfarm_get_global_username()) != 0) {
		e = gfarm_path_info_access(&pi, GFS_R_OK);
		if (e != NULL)
			goto finish_path_info;
		mode_allowed = 022;
	}
	e = gfarm_file_section_replicate_to_internal(
	    gfarm_file, section,
	    (pi.status.st_mode | mode_allowed) & GFARM_S_ALLPERM, si.filesize,
	    dsthost);

	gfarm_file_section_info_free(&si);
finish_path_info:
	gfarm_path_info_free(&pi);
finish_gfarm_file:
	free(gfarm_file);
finish:
	return (e);
}
示例#6
0
static char *
gfs_pio_open_check_perm(GFS_File gf)
{
	char *e;
	int check= 0;

	if ((gf->mode & GFS_FILE_MODE_READ) != 0)
		check |= GFS_R_OK;
	if ((gf->mode & GFS_FILE_MODE_WRITE) != 0 ||
	    (gf->open_flags & GFARM_FILE_TRUNC) != 0)
		check |= GFS_W_OK;
	e = gfarm_path_info_access(&gf->pi, check);
	if (e != NULL)
		return (e);
	if (!GFARM_S_ISREG(gf->pi.status.st_mode)) {
		if (GFARM_S_ISDIR(gf->pi.status.st_mode))
			return (GFARM_ERR_IS_A_DIRECTORY);
		else
			return (GFARM_ERR_OPERATION_NOT_SUPPORTED);
	}
	return (NULL);
}
示例#7
0
char *
gfs_access(char *gfarm_url, int mode)
{
	char *e, *gfarm_file;
	struct gfarm_path_info pi;
	int nsections;
	struct gfarm_file_section_info *sections;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		return (e);
	e = gfarm_path_info_get(gfarm_file, &pi);
	if (e != NULL) {
		free(gfarm_file);
		return (e);
	}
	/*
	 * Check whether the gfarm_url can be accessible by other
	 * processes or not.
	 *
	 * XXX - temporal solution until file locking will be implemented.
	 */
	e = gfarm_file_section_info_get_all_by_file(gfarm_file,
	    &nsections, &sections);
	free(gfarm_file);
	if (e != NULL) {
		return (e);
	}
	gfarm_file_section_info_free_all(nsections, sections);

	if (!GFARM_S_IS_PROGRAM(pi.status.st_mode)
	    && nsections != pi.status.st_nsections)
		return (GFARM_ERR_FRAGMENT_NUMBER_DOES_NOT_MATCH);

	e = gfarm_path_info_access(&pi, mode);
	gfarm_path_info_free(&pi);

	return (e);
}
示例#8
0
文件: url.c 项目: krichter722/gfarm
char *
gfarm_canonical_path_for_creation(const char *gfarm_file, char **canonic_pathp)
{
	const char *basename, *p0;
	char *e, *p1, *dir, *dir_canonic, *lastc, cwd[PATH_MAX + 1];

	*canonic_pathp = NULL; /* cause SEGV, if return value is ignored */

	/* '' or 'gfarm:' case */
	if (gfarm_file[0] == '\0') {
		e = gfs_getcwd(cwd, sizeof(cwd));
		if (e != NULL)
			return (e);
		p0 = cwd;
	}
	else
		p0 = gfarm_file;

	/* Expand '~'. */
	e = gfarm_path_expand_home(p0, &p1);
	if (e != NULL)
		return (e);

	/* Eliminate unnecessary '/'s following the basename. */
	lastc = &p1[strlen(p1) - 1];
	if (*lastc == '/') {
		while (p1 < lastc && *lastc == '/')
			--lastc;
		if (p1 == lastc) {
			/*
			 * In this case, given gfarm_file is '/' or contains
			 * only several '/'s.  This means to attempt to create
			 * the root directory.  Because the root directory
			 * should exist, the attempt will fail with the error
			 * of 'already exist'.  However, this case such that
			 * the canonical name is "" causes many problems.
			 * That is why the error of 'already exist' is
			 * returned here.
			 */
			free(p1);
			return (GFARM_ERR_ALREADY_EXISTS);
		}
		else {
			*(lastc + 1) = '\0';
		}
	}

	basename = gfarm_path_dir_skip(p1);
	if (basename == p1)	     /* "filename" */
		dir = ".";
	else if (basename == p1 + 1) /* "/filename" */
		dir = "/";
	else {			     /* /.../.../filename */
		p1[basename - 1 - p1] = '\0';
		dir = p1;
	}
	/* Check the existence of the parent directory. */
	e = gfarm_canonical_path(dir, &dir_canonic);
	if (e != NULL)
		goto free_p1;

	/*
	 * check whether parent directory is writable or not.
	 * XXX this isn't enough yet, due to missing X-bits check.
	 */
	if (dir_canonic[0] != '\0') { /* XXX "/" is always OK for now */
		struct gfarm_path_info pi;

		e = gfarm_path_info_get(dir_canonic, &pi);
		if (e != NULL)
			goto free_dir_canonic;

		e = gfarm_path_info_access(&pi, GFS_W_OK);
		gfarm_path_info_free(&pi);
		if (e != NULL)
			goto free_dir_canonic;
	}

	*canonic_pathp = malloc(strlen(dir_canonic) + 1 +
				strlen(basename) + 1); 
	if (*canonic_pathp == NULL) {
		e = GFARM_ERR_NO_MEMORY;
		goto free_dir_canonic;
	}

	/*
	 * When the 'dir_canonic' is a null string, *canonic_pathp
	 * will start with '/' incorrectly.
	 */
	if (dir_canonic[0] == '\0')
		strcpy(*canonic_pathp, basename);
	else
		sprintf(*canonic_pathp, "%s/%s", dir_canonic, basename);
	e = NULL;
free_dir_canonic:
	free(dir_canonic);
free_p1:
	free(p1);
	return (e);
}
示例#9
0
char *
gfs_pio_create(const char *url, int flags, gfarm_mode_t mode, GFS_File *gfp)
{
	char *e, *pathname;
	GFS_File gf;
	int pi_available = 0;
	mode_t mask;
	char *user;
	gfarm_timerval_t t1, t2;

	gfs_profile(gfarm_gettimerval(&t1));

	user = gfarm_get_global_username();
	if (user == NULL) {
		e = "gfarm_pio_create(): programming error, "
		    "gfarm library isn't properly initialized";
		goto finish;
	}
#if 0 /*  XXX - ROOT I/O opens a new file with O_CREAT|O_RDRW mode. */
	if ((flags & GFARM_FILE_ACCMODE) != GFARM_FILE_WRONLY) {
		e = GFARM_ERR_OPERATION_NOT_SUPPORTED; /* XXX */
		goto finish;
	}
#endif

	mask = umask(0);
	umask(mask);
	mode &= ~mask;

	e = gfarm_url_make_path_for_creation(url, &pathname);
	if (e != NULL)
		goto finish;
	e = gfs_file_alloc(&gf);
	if (e != NULL) {
		free(pathname);
		goto finish;
	}

	/* gfs_pio_create() always assumes CREATE, TRUNC */
	flags |= GFARM_FILE_CREATE | GFARM_FILE_TRUNC;

	if ((flags & (GFARM_FILE_TRUNC|GFARM_FILE_SEQUENTIAL)) !=
	    (GFARM_FILE_TRUNC|GFARM_FILE_SEQUENTIAL)) {
		/* MODE_READ is needed to re-calculate checksum. */
		flags = (flags & ~GFARM_FILE_ACCMODE) | GFARM_FILE_RDWR;
	} else if ((flags & ~GFARM_FILE_ACCMODE) == GFARM_FILE_RDONLY) {
		flags = (flags & ~GFARM_FILE_ACCMODE) | GFARM_FILE_WRONLY;
	} 
	gf->open_flags = flags;

	gf->mode = GFS_FILE_MODE_WRITE;
	if ((flags & GFARM_FILE_ACCMODE) == GFARM_FILE_RDWR)
		gf->mode |= GFS_FILE_MODE_READ;
	e = gfarm_path_info_get(pathname, &gf->pi);
	if (e != NULL && e != GFARM_ERR_NO_SUCH_OBJECT) {
		free(pathname);
		gfs_file_free(gf);
		goto finish;
	}
	if (e == NULL) {
		/* XXX unlink and re-create the file? */
		free(pathname);
		e = gfarm_path_info_access(&gf->pi, GFS_W_OK);
		if (e != NULL) {
			gfarm_path_info_free(&gf->pi);
			gfs_file_free(gf);
			goto finish;
		}
		if (!GFARM_S_ISREG(gf->pi.status.st_mode)) {
			if (GFARM_S_ISDIR(gf->pi.status.st_mode))
				e = GFARM_ERR_IS_A_DIRECTORY;
			else
				e = GFARM_ERR_OPERATION_NOT_SUPPORTED;
			gfarm_path_info_free(&gf->pi);
			gfs_file_free(gf);
			goto finish;
		}
		/*
		 * XXX should check the follows:
		 * - the mode is consistent among same job
		 * - creator of the metainfo has same job id
		 * - O_TRUNC / !O_TRUNC case
		 */
		mode |= GFARM_S_IFREG;
		if (GFARM_S_IS_PROGRAM(mode) != GFS_FILE_IS_PROGRAM(gf)) {
			gfarm_path_info_free(&gf->pi);
			gfs_file_free(gf);
			e = GFARM_ERR_OPERATION_NOT_PERMITTED;
			goto finish;
		}
		pi_available = 1;
	}
	if (!pi_available) {
		struct timeval now;

		gettimeofday(&now, NULL);
		gf->pi.pathname = pathname;
		gf->pi.status.st_mode = (GFARM_S_IFREG | mode);
		gf->pi.status.st_user = strdup(user); /* XXX NULL check */
		gf->pi.status.st_group = strdup("*"); /* XXX for now */
		gf->pi.status.st_atimespec.tv_sec =
		gf->pi.status.st_mtimespec.tv_sec =
		gf->pi.status.st_ctimespec.tv_sec = now.tv_sec;
		gf->pi.status.st_atimespec.tv_nsec =
		gf->pi.status.st_mtimespec.tv_nsec =
		gf->pi.status.st_ctimespec.tv_nsec = now.tv_usec * 1000;
		gf->pi.status.st_size = 0;
		gf->pi.status.st_nsections = 0;
	}
	*gfp = gf;
	gfs_uncachedir();

	e = NULL;
 finish:
	gfs_profile(gfarm_gettimerval(&t2));
	gfs_profile(gfs_pio_create_time += gfarm_timerval_sub(&t2, &t1));

	return (e);
}
示例#10
0
char *
gfarm_url_fragments_replicate(char *gfarm_url, int ndsthosts, char **dsthosts)
{
	char *e, *gfarm_file, **srchosts, **edsthosts;
	int nsrchosts;
	gfarm_mode_t mode;
	int i, pid, *pids;
	struct gfarm_path_info pi;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		return (e);

	e = gfarm_path_info_get(gfarm_file, &pi);
	if (e != NULL)
		goto finish_gfarm_file;

	mode = pi.status.st_mode;
	gfarm_path_info_free(&pi);
	if (!GFARM_S_IS_FRAGMENTED_FILE(mode)) {
		e = GFARM_ERR_OPERATION_NOT_PERMITTED;
		goto finish_gfarm_file;
	}
	/*
	 * XXX - if the owner of a file is not the same, permit a
	 * group/other write access - This should be fixed in the next
	 * major release.
	 */
	if (strcmp(pi.status.st_user, gfarm_get_global_username()) != 0) {
		e = gfarm_path_info_access(&pi, GFS_R_OK);
		if (e != NULL) {
			gfarm_path_info_free(&pi);
			free(gfarm_file);
			return (e);
		}
		mode |= 022;
	}
	e = gfarm_url_hosts_schedule(gfarm_url, "", &nsrchosts, &srchosts);
	if (e != NULL)
		goto finish_gfarm_file;

	edsthosts = malloc(sizeof(*edsthosts) * nsrchosts);
	if (edsthosts == NULL) {
		e = GFARM_ERR_NO_MEMORY;
		goto finish_srchosts;
	}
	gfarm_strings_expand_cyclic(ndsthosts, dsthosts, nsrchosts, edsthosts);

	pids = malloc(sizeof(int) * nsrchosts);
	if (pids == NULL) {
		e = GFARM_ERR_NO_MEMORY;
		goto finish_edsthosts;
	}
	/*
	 * To use different connection for each metadb access.
	 *
	 * XXX: FIXME layering violation
	 */
	e = gfarm_metadb_terminate();
	if (e != NULL)
		goto finish_pids;

	for (i = 0; i < nsrchosts; i++) {
		struct sockaddr peer_addr;
		char *if_hostname;
		char section_string[GFARM_INT32STRLEN + 1];
		struct gfarm_file_section_info si;

		pid = fork();
		if (pid < 0)
			break;
		if (pid) {
			/* parent */
			pids[i] = pid;
			continue;
		}
		/* child */

		/*
		 * use different connection for each metadb access.
		 *
		 * XXX: FIXME layering violation
		 */
		e = gfarm_metadb_initialize();
		if (e != NULL)
			_exit(1);

		/* reflect "address_use" directive in the `srchosts[i]' */
		e = gfarm_host_address_get(srchosts[i],
		    gfarm_spool_server_port, &peer_addr, &if_hostname);
		if (e != NULL)
			_exit(2);

		sprintf(section_string, "%d", i);
		e = gfarm_file_section_info_get(gfarm_file, section_string,
		    &si);
		if (e != NULL)
			_exit(3);

		e = gfarm_file_section_replicate_from_to_internal(
		    gfarm_file, section_string,
		    mode & GFARM_S_ALLPERM, si.filesize,
		    srchosts[i], if_hostname, edsthosts[i]);
		if (e != NULL)
			_exit(1);
		_exit(0);
	}
	while (--i >= 0) {
		int rv, s;

		while ((rv = waitpid(pids[i], &s, 0)) == -1 && errno == EINTR)
			;
		if (rv == -1) {
			if (e == NULL)
				e = gfarm_errno_to_error(errno);
		} else if (WIFEXITED(s) && WEXITSTATUS(s) != 0) {
			e = "error happens on replication";
		}
	}
	/*
	 * recover temporary closed metadb connection
	 *
	 * XXX: FIXME layering violation
	 */
	if (e != NULL) {
		gfarm_metadb_initialize();
	} else {
		e = gfarm_metadb_initialize();
	}
 finish_pids:
	free(pids);
 finish_edsthosts:
	free(edsthosts);
 finish_srchosts:
	gfarm_strings_free_deeply(nsrchosts, srchosts);
 finish_gfarm_file:
	free(gfarm_file);
	return (e);
}
示例#11
0
char *
gfarm_url_program_deliver(const char *gfarm_url, int nhosts, char **hosts,
			  char ***delivered_paths)
{
	char *e, **dp, *gfarm_file, *root, *arch, **canonical_hostnames;
	gfarm_mode_t mode;
	int i;
	struct gfarm_path_info pi;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		return (e);

	e = gfarm_path_info_get(gfarm_file, &pi);
	if (e != NULL) {
		free(gfarm_file);
		return (e);
	}
	mode = pi.status.st_mode;
	if (!GFARM_S_IS_PROGRAM(mode)) {
		gfarm_path_info_free(&pi);
		free(gfarm_file);
		return ("gfarm_url_program_deliver(): not a program");
	}
	/*
	 * XXX - if the owner of a file is not the same, permit a
	 * group/other write access - This should be fixed in the next
	 * major release.
	 */
	if (strcmp(pi.status.st_user, gfarm_get_global_username()) != 0) {
		e = gfarm_path_info_access(&pi, GFS_X_OK);
		if (e != NULL) {
			gfarm_path_info_free(&pi);
			free(gfarm_file);
			return (e);
		}
		mode |= 022;
	}
	gfarm_path_info_free(&pi);
	dp = malloc(sizeof(char *) * (nhosts + 1));
	if (dp == NULL) {
		free(gfarm_file);
		return (GFARM_ERR_NO_MEMORY);
	}
	dp[nhosts] = NULL;

	e = gfarm_host_get_canonical_names(nhosts, hosts,
	    &canonical_hostnames);
	if (e != NULL) {
		free(dp);
		free(gfarm_file);
		return (e);
	}

	/* XXX - this is too slow */
	for (i = 0; i < nhosts; i++) {
		struct sockaddr peer_addr;
		struct gfs_connection *gfs_server;
		struct gfarm_file_section_info si;

		dp[i] = NULL; /* for error handling */
		arch = gfarm_host_info_get_architecture_by_host(
		    canonical_hostnames[i]);
		if (arch == NULL) {
			/* architecture of the hosts[i] is not registered */
			e = "cannot deliver program to an unregistered host";
			goto error;
		}

		/* XXX - which to use? `hosts[i]' vs `copies[j].hostname' */
		e = gfarm_host_address_get(hosts[i],
		    gfarm_spool_server_port, &peer_addr, NULL);
		if (e != NULL) {
			free(arch);
			goto error;
		}

		e = gfs_client_connection(canonical_hostnames[i], &peer_addr,
		    &gfs_server);
		if (e != NULL) {
			free(arch);
			goto error;
		}
		e = gfs_client_get_spool_root(gfs_server, &root);
		if (e != NULL) {
			free(arch);
			goto error;
		}
		e = gfarm_full_path_file_section(root, gfarm_file,
		    arch, &dp[i]);
		free(root);
		if (e != NULL) {
			free(arch);
			goto error;
		}
		e = gfarm_file_section_info_get(gfarm_file, arch, &si);
		if (e != NULL) {
			free(arch);
			goto error;
		}

		/*
		 * replicate the program
		 */
		e = gfarm_file_section_replicate_to_internal(gfarm_file, arch,
		    mode & GFARM_S_ALLPERM, si.filesize, hosts[i]);
		gfarm_file_section_info_free(&si);
		free(arch);
		if (e != NULL)
			goto error;
	}

	gfarm_strings_free_deeply(nhosts, canonical_hostnames);
	free(gfarm_file);
	*delivered_paths = dp;
	return (NULL);

error:
	gfarm_strings_free_deeply(nhosts, canonical_hostnames);
	free(gfarm_file);
	gfarm_strings_free_deeply(i + 1, dp);
	*delivered_paths = NULL;
	return (e);
}
示例#12
0
文件: gfs_dir.c 项目: eterps/pwrake
gfarm_error_t
gfs_chdir_canonical(const char *canonic_dir)
{
	static int cwd_len = 0;
	static char env_name[] = "GFS_PWD=";
	static char *env = NULL;
	static int env_len = 0;
	int len, old_len;
	char *e, *tmp, *old_env;
	struct gfarm_path_info pi;

	e = gfarm_path_info_get(canonic_dir, &pi);
	if (e == NULL) {
		e = gfarm_path_info_access(&pi, X_OK);
		gfarm_path_info_free(&pi);
	}
	if (e != NULL)
		return (e);

	len = 1 + strlen(canonic_dir) + 1;
	if (cwd_len < len) {
		GFARM_REALLOC_ARRAY(tmp, gfarm_current_working_directory, len);
		if (tmp == NULL)
			return (GFARM_ERR_NO_MEMORY);
		gfarm_current_working_directory = tmp;
		cwd_len = len;
	}
	sprintf(gfarm_current_working_directory, "/%s", canonic_dir);

	len += sizeof(env_name) - 1 + GFARM_URL_PREFIX_LENGTH;
	tmp = getenv("GFS_PWD");
	if (tmp == NULL || tmp != env + sizeof(env_name) - 1) {
		/*
		 * changed by an application instead of this function, and
		 * probably it's already free()ed.  In this case, realloc()
		 * does not work well at least using bash.  allocate it again.
		 */
		env = NULL;
		env_len = 0;
	}
	old_env = env;
	old_len = env_len;
	if (env_len < len) {
		/*
		 * We cannot use realloc(env, ...) here, because `env' may be
		 * still pointed by environ[somewhere] (at least with glibc),
		 * and realloc() may break the memory.  So, allocate different
		 * memory.
		 */
		GFARM_MALLOC_ARRAY(tmp, len);
		if (tmp == NULL)
			return (GFARM_ERR_NO_MEMORY);
		env = tmp;
		env_len = len;
	}
	sprintf(env, "%s%s%s",
	    env_name, GFARM_URL_PREFIX, gfarm_current_working_directory);

	if (putenv(env) != 0) {
		if (env != old_env && env != NULL)
			free(env);
		env = old_env;
		env_len = old_len;
		return (gfarm_errno_to_error(errno));
	}
	if (old_env != env && old_env != NULL)
		free(old_env);

	return (NULL);
}