Beispiel #1
0
/**
 * Save torrent file to the given path.
 *
 * @param path the path to save torrent file to
 * @param rctx the context containing torrent data
 */
void save_torrent_to(const char* path, rhash_context* rctx)
{
	FILE* fd;
	struct rsh_stat_struct stat_buf;
	size_t text_len;
	char *str;

	/* get torrent file content */
	text_len = rhash_transmit(RMSG_BT_GET_TEXT, rctx, RHASH_STR2UPTR(&str), 0);
	assert(text_len != RHASH_ERROR);

	if(rsh_stat(path, &stat_buf) >= 0) {
		/* make backup copy of the existing torrent file */
		char *bak_path = str_append(path, ".bak");
		unlink(bak_path);
		rename(path, bak_path);
		free(bak_path);
	}

	/* write torrent file */
	fd = rsh_fopen_bin(path, "wb");
	if(fd && text_len == fwrite(str, 1, text_len, fd) &&
		!ferror(fd) && !fflush(fd))
	{
		log_msg(_("%s saved\n"), path);
	} else {
		log_file_error(path);
	}
	if(fd) fclose(fd);
}
Beispiel #2
0
/**
 * Output SFV-formated file header.
 */
static void preprocess_files(void)
{
	int i;

	/* print SFV file header */
	if(opt.fmt == FMT_SFV && opt.mode == 0) {
		print_sfv_banner(rhash_data.out);

		for(i = 0; i < opt.n_files; i++) {
			char *path = opt.files[i];
			if(opt.flags & OPT_RECURSIVE) {
				struct rsh_stat_struct stat_buf;
				if(rsh_stat(path, &stat_buf) < 0) {
					continue; /* don't report error here, it'll be reported later */
				}
				/* if file is a directory, then walk it recursively */
				if(S_ISDIR(stat_buf.st_mode)) {
					find_file(path, find_file_callback, 0, opt.find_max_depth, (void*)1);
					continue;
				}
			}
			print_sfv_header_line(rhash_data.out, path, path);
		}
		fflush(rhash_data.out);
	}
}
Beispiel #3
0
/**
 * Search for config file.
 *
 * @return the relative path to config file
 */
static const char* find_conf_file(void)
{
# define CONF_FILE_NAME "rhashrc"
	struct rsh_stat_struct st;
	char *dir1, *path;

#ifndef _WIN32 /* Linux/Unix part */
	/* first check for $HOME/.rhashrc file */
	if( (dir1 = getenv("HOME")) ) {
		path = make_path(dir1, ".rhashrc");
		if(rsh_stat(path, &st) >= 0) {
			rsh_vector_add_ptr(opt.mem, path);
			return (conf_opt.config_file = path);
		}
		free(path);
	}
	/* then check for global config */
	if(rsh_stat( (path = "/etc/" CONF_FILE_NAME), &st) >= 0) {
		return (conf_opt.config_file = path);
	}

#else /* _WIN32 */

	/* first check for the %APPDATA%\RHash\rhashrc config */
	if( (dir1 = getenv("APPDATA")) ) {
		dir1 = make_path(dir1, "RHash");
		rsh_vector_add_ptr(opt.mem, path = make_path(dir1, CONF_FILE_NAME));
		free(dir1);
		if(rsh_stat(path, &st) >= 0) {
			return (conf_opt.config_file = path);
		}
	}

	/* then check for %HOMEDRIVE%%HOMEPATH%\rhashrc */
	/* note that %USERPROFILE% is generally not a user home dir */
	if( (dir1 = getenv("HOMEDRIVE")) && (path = getenv("HOMEPATH"))) {
		dir1 = make_path(dir1, path);
		rsh_vector_add_ptr(opt.mem, path = make_path(dir1, CONF_FILE_NAME));
		free(dir1);
		if(rsh_stat(path, &st) >= 0) {
			return (conf_opt.config_file = path);
		}
	}
#endif /* _WIN32 */

	return (conf_opt.config_file = NULL); /* config file not found */
}
/**
 * Calculate hash sums simultaneously, according to the info->sums_flags.
 * Calculated hashes are stored in info->rctx.
 *
 * @param info file data. The info->full_path can be "-" to denote stdin
 * @return 0 on success, -1 on fail with error code stored in errno
 */
static int calc_sums(struct file_info *info)
{
	FILE* fd = stdin; /* stdin */
	int res;
	uint64_t initial_size;

	if(IS_DASH_STR(info->full_path)) {
		info->print_path = "(stdin)";

#ifdef _WIN32
		/* using 0 instead of _fileno(stdin). _fileno() is undefined under 'gcc -ansi' */
		if(setmode(0, _O_BINARY) < 0) {
			return -1;
		}
#endif
	} else {
		struct rsh_stat_struct stat_buf;
		/* skip non-existing files */
		if(rsh_stat(info->full_path, &stat_buf) < 0) {
			return -1;
		}

		if((opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) && S_ISDIR(stat_buf.st_mode)) {
			errno = EISDIR;
			return -1;
		}

		info->size = stat_buf.st_size; /* total size, in bytes */
		IF_WINDOWS(win32_set_filesize64(info->full_path, &info->size)); /* set correct filesize for large files under win32 */

		if(!info->sums_flags) return 0;

		/* skip files opened with exclusive rights without reporting an error */
		fd = rsh_fopen_bin(info->full_path, "rb");
		if(!fd) {
			return -1;
		}
	}

	re_init_rhash_context(info);
	initial_size = info->rctx->msg_size;

	if(percents_output->update != 0) {
		rhash_set_callback(info->rctx, (rhash_callback_t)percents_output->update, info);
	}

	/* read and hash file content */
	if((res = rhash_file_update(info->rctx, fd)) != -1) {
		if(!opt.bt_batch_file) {
			rhash_final(info->rctx, 0); /* finalize hashing */
		}
	}
	info->size = info->rctx->msg_size - initial_size;
	rhash_data.total_size += info->size;

	if(fd != stdin) fclose(fd);
	return res;
}
Beispiel #5
0
/**
 * Hash, check or update files according to work mode.
 */
static void process_files(void)
{
	timedelta_t timer;
	struct rsh_stat_struct stat_buf;
	int i;
	rhash_timer_start(&timer);
	rhash_data.processed = 0;

	/* process filenames */
	for(i = 0; i < opt.n_files; i++) {
		int res = 0;
		char* filepath = opt.files[i];
		stat_buf.st_mode = 0;

		if(!IS_DASH_STR(filepath) && rsh_stat(filepath, &stat_buf) < 0) {
			log_file_error(filepath);
			continue;
		}
		if(opt.flags & OPT_RECURSIVE) {
			if(S_ISDIR(stat_buf.st_mode)) {
				find_file(filepath, find_file_callback, 0, opt.find_max_depth, NULL);
				continue;
			}
		} else {
			if(S_ISDIR(stat_buf.st_mode)){
				if(opt.flags & OPT_VERBOSE){
					log_warning(_("%s: is a directory\n"), filepath);
				}
				continue;
			}
		}

		if(opt.mode & (MODE_CHECK | MODE_CHECK_EMBEDDED)) {
			res = check_hash_file(filepath, 0);
		} else if(opt.mode & MODE_UPDATE) {
			res = update_hash_file(filepath);
		} else {
			res = calculate_and_print_sums(rhash_data.out, filepath, filepath, &stat_buf);
			rhash_data.processed++;
		}
		if(res < 0) rhash_data.error_flag = 1;
	}

	if((opt.mode & MODE_CHECK_EMBEDDED) && rhash_data.processed > 1) {
		print_check_stats();
	}

	if((opt.flags & OPT_SPEED) && !(opt.mode&(MODE_CHECK | MODE_UPDATE)) &&
		rhash_data.processed > 1) {
			double time = rhash_timer_stop(&timer);
			print_time_stats(time, rhash_data.total_size, 1);
	}
}
Beispiel #6
0
/**
 * Fill file information in the file_t structure.
 *
 * @param file the file information
 * @param use_lstat nonzero if lstat() shall be used
 * @return 0 on success, -1 on error
 */
int rsh_file_stat2(file_t* file, int use_lstat)
{
	struct rsh_stat_struct st;
	int res = -1;

#ifdef _WIN32
	int i;
	(void)use_lstat; /* ignore on windows */

	if(file->wpath) {
		free(file->wpath);
		file->wpath = NULL;
	}

	for(i = 0; i < 2; i++) {
		wchar_t* wpath = c2w(file->path, i);
		if(wpath == NULL) continue;
		res = clib_wstat(wpath, &st);
		if(res == 0 || errno != ENOENT) {
			file->wpath = wpath;
			file->size  = st.st_size;

			/* set correct filesize for large files under win32 */
			win32_set_filesize64(file->path, &file->size);
			break;
		}
		free(wpath);
	}
#else
	res = (use_lstat ? lstat(file->path, &st) :
		rsh_stat(file->path, &st));
	file->size  = st.st_size;
#endif /* _WIN32 */

	file->mtime = st.st_mtime;
	return res;
}