#include "ftptool.h"

#pragma ident   "@(#)dofuncs.c 1.9     94/08/23"

#ifdef USE_PROTOTYPES
int	doconnect(void)
#else
int	doconnect()
#endif
{
	char	*ftphost;
	char	*proxyhost;
	char	*login;
	char	*password;
	char	*account;
	char	crap[50];
	int		rval;
	int		port;

#ifdef notdef
	if (!openlook_mode || (xv_get(host_window.frame, FRAME_CMD_PIN_STATE)
		== FRAME_CMD_PIN_OUT)) {
		xv_set(host_window.frame,
			XV_SHOW, FALSE,
			FRAME_CMD_PIN_STATE, FRAME_CMD_PIN_OUT,
			NULL);
	}
#endif
	textsw_reset(session_window.log, 0, 0);
	/* used to make sure we are connected */
	/* with PANEL_INACTIVE, don't need to anymore */
	footer_message("");
	local_footer_message("");
	password = (char *)xv_get(host_window.basic.password, PANEL_VALUE);
	if (*password == '\0')
		password = anonftp_password;

	login = (char *)xv_get(host_window.basic.login, PANEL_VALUE);
	if (*login == '\0') {
		login = "anonymous";
	}

	account = (char *)xv_get(host_window.basic.account, PANEL_VALUE);
	if (*account == '\0') {
		account = NULL;
	}

	ftphost = (char *)xv_get(host_window.basic.host, PANEL_VALUE);
	port = ftp_port;
	ftphost = parse_hostname(ftphost, &port);
	if (ftphost == NULL)
		return (-1);
	rval = openhost(ftphost, login, password, account, port);
	if (rval != 1)
		return (rval);
	if (!try_proxy)
		return (1);
	proxyhost = (char *)xv_get(host_window.advanced.proxy, PANEL_VALUE);
	/* crap for Iftp */
	/* login must be 'user@ftphost' */
	sprintf(crap, "%s@%s", login, ftphost);
	return (openhost(proxyhost, crap, password, account,
	    ftp_passthru_port));
}

#ifdef USE_PROTOTYPES
int openhost(char *ftphost, char *login, char *password,
	char *account, short port)
#else
int openhost(ftphost, login, password, account, port)
char	*ftphost;
char	*login;
char	*password;
char	*account;
short	port;
#endif
{
	char	*atsign;
	char	*auto_cd;
	int		rval = 0;

	timedout = 0;
	cursor_busy();
	xv_set(host_window.basic.connect,
		PANEL_INACTIVE, TRUE,
		NULL);
	xv_set(base_window.connect,
		PANEL_INACTIVE, TRUE,
		NULL);

	xv_set(host_window.basic.host,
		PANEL_READ_ONLY, TRUE,
		NULL);
	xv_set(host_window.advanced.proxy,
		PANEL_READ_ONLY, TRUE,
		NULL);
	xv_set(host_window.basic.login,
		PANEL_READ_ONLY, TRUE,
		NULL);
	xv_set(host_window.basic.password,
		PANEL_READ_ONLY, TRUE,
		NULL);
	xv_set(host_window.advanced.remote_auto_cd,
		PANEL_READ_ONLY, TRUE,
		NULL);
	xv_set(host_window.advanced.local_auto_cd,
		PANEL_READ_ONLY, TRUE,
		NULL);

	xv_set(local_window.list,
		PANEL_INACTIVE, TRUE,
		NULL);
	xv_set(local_window.directory,
		PANEL_READ_ONLY, TRUE,
		NULL);

	xv_set(base_window.list,
		PANEL_INACTIVE, TRUE,
		NULL);
	xv_set(base_window.directory,
		PANEL_READ_ONLY, TRUE,
		NULL);
	xv_set(tool_property_window.apply,
		PANEL_INACTIVE, TRUE,
		NULL);
	xv_set(tool_property_window.category,
		PANEL_INACTIVE, TRUE,
		NULL);

	start_busy_cycle();
	footer_message("Connecting...");
	rval = ftp_hookup(ftphost, port);
	switch (rval) {
	case 0:	/* error */
		rval = 2;
		goto out;
		break;
	case 1:
		/* couldn't resolve hostname: try proxy */
		goto out;
		break;
	default:
		rval = 0;
		break;
	}
	if ((rval = ftp_login(login, password, account)) == 0) {
		rval = 2;
		goto out;
	}
	footer_message("Initializing...");

	connected = 1;
	which_up_cmd = -1;

	xv_set(schedule_window.process,
		PANEL_INACTIVE, TRUE,
		NULL);

	update_timestamp();

	(void) strncpy(icon_label, (char *)xv_get(host_window.basic.host,
		PANEL_VALUE), 8);
	icon_label[8] = '\0';

	xv_set(frame_icon,
		ICON_LABEL, icon_label,
		NULL);

	xv_set(base_window.directory,
		PANEL_INACTIVE, FALSE,
		NULL);

	/*
	 * ftphost is not the name of outside machines.
	 * Need to extract outside name from login
	 */
	if ((atsign = index(login, '@')) != NULL)
		sprintf(scratch, "%s - %s", header_name, atsign + 1);
	else
		sprintf(scratch, "%s - %s", header_name, ftphost);
	xv_set(base_window.frame,
		XV_LABEL, scratch,
		NULL);


	remote_os_type = (int)xv_get(host_window.advanced.os_type, PANEL_VALUE);

	if (remote_os_type == REMOTE_OS_OTHER) {
		other_dir_pattern =
		    (char *)xv_get(host_window.advanced.dir_parse,
			PANEL_VALUE);
		if (*other_dir_pattern == '\0') {
			footer_message(
			    "No DIR template specified. Defaulting to UNIX.");
			remote_os_type = REMOTE_OS_UNIX;
			other_dir_pattern = NULL;
		} else if ((other_dir_pattern =
		    dir_parse_to_pattern(other_dir_pattern)) == NULL) {
			footer_message("Defaulting to UNIX.");
			remote_os_type = REMOTE_OS_UNIX;
		} else if (other_dir_pattern[0] == (char)NONUNIX) {
			non_unix = 1;
			remote_sort_mode = SORTBYNAME;
			xv_set(tool_property_window.directory_lists.remote_sort,
				PANEL_VALUE, remote_sort_mode,
				PANEL_INACTIVE, TRUE,
				NULL);
			set_remote_sort_order(SORTBYNAME);
		}
	}

	auto_cd = (char *)xv_get(host_window.advanced.remote_auto_cd,
	    PANEL_VALUE);
	if (*auto_cd == '\0' || change_remote_dir(auto_cd, 0))
		change_remote_dir(".", 0);
	footer_message("");
	auto_cd = expand_dirname((char *)xv_get(
	    host_window.advanced.local_auto_cd, PANEL_VALUE));
	if (auto_cd != NULL) {
		if (*auto_cd != '\0' && strcmp(auto_cd, ".") != 0)
			change_local_dir(auto_cd, 0);
		free(auto_cd);
		local_footer_message("");
	} else {
		local_footer_message("Could not change to local directory");
		log_message(
		    "Could not change to local directory: out of memory.\n");
	}
	change_local_list_menu();

	end_busy_cycle();
	cursor_normal();
	idle_timer_on();

	/* activate buttons */

	/* connect already inactive */
	xv_set(host_window.basic.connect,
		PANEL_INACTIVE, FALSE,
		PANEL_LABEL_STRING, "Disconnect",
		XV_HELP_DATA, "ftptool:DisconnectButton",
		NULL);

	xv_set(base_window.connect,
		PANEL_INACTIVE, FALSE,
		PANEL_LABEL_STRING, "Disconnect",
		XV_HELP_DATA, "ftptool:DisconnectButton",
		NULL);

	xv_set(host_window.basic.host,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.basic.login,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.basic.password,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.advanced.proxy,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.advanced.remote_auto_cd,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.advanced.local_auto_cd,
		PANEL_READ_ONLY, FALSE,
		NULL);

	xv_set(local_window.list,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(base_window.list,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(local_window.directory,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(base_window.directory,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(tool_property_window.apply,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(tool_property_window.category,
		PANEL_INACTIVE, FALSE,
		NULL);

	return (0);
out:
	end_busy_cycle();
	cursor_normal();
	xv_set(host_window.basic.connect,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(base_window.connect,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(host_window.basic.host,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.basic.login,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.basic.password,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.advanced.proxy,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.advanced.remote_auto_cd,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(host_window.advanced.local_auto_cd,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(base_window.list,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(local_window.list,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(local_window.directory,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(base_window.directory,
		PANEL_READ_ONLY, FALSE,
		NULL);
	xv_set(tool_property_window.apply,
		PANEL_INACTIVE, FALSE,
		NULL);
	xv_set(tool_property_window.category,
		PANEL_INACTIVE, FALSE,
		NULL);
	return (rval);
}

#ifdef USE_PROTOTYPES
void	doget(void)
#else
void	doget()
#endif
{
	int 	nitems, row;
	struct dirlist *tmp;
	int		rval;
	int		mode;
	char	*name = NULL;
	int		dirchanged = 0;

	xfer_buttons_inactive();
	abort_transfer = 0;
	if (dirwasmodified()) {
	/*
		goto out;
	*/
	}
	if (ping_server())
		goto out;
	if (show_status)
		xv_set(status_window.frame,
			XV_SHOW, TRUE,
			NULL);
	init_status(sum_remote_size());
	/* loop over each selected element, and do a get, then unselect */
	nitems = xv_get(base_window.list, PANEL_LIST_NROWS);
	for (row = 0; row < nitems; row++)
		if (xv_get(base_window.list, PANEL_LIST_SELECTED, row)) {
			tmp = (struct dirlist *)xv_get(base_window.list,
				PANEL_LIST_CLIENT_DATA, row);
			mode = tmp->mode & S_IFMT;
			if (non_unix) {
				/*
				 * cannot transfer whole directories
				 * on non-unix machines
				 */
				mode = S_IFREG;
			}
			switch (mode) {
			case S_IFDIR:
				dirchanged++;
				if ((rval = get_dir(remote_dircache.first->name,
					local_dircache.first->name,
					tmp->name, tmp->name)) != 0) {
					if (rval == EEXIST) {
						footer_message(
						    "%s already exists.",
						    tmp->name);
					}
					goto out;
				}
				remote_list_ndirs--;
				break;
			case S_IFREG:
				dirchanged++;
				if (get_file(tmp->name, tmp->name, tmp->size))
					goto out;
				remote_list_nfiles--;
				break;
			case S_IFLNK:
				name = linkname(tmp->name);
				if (name == NULL)
					goto out;
				/* try as a file */
				dirchanged++;
				rval = get_file(name, name, -1);
				if (rval == EISDIR) {
					/* try as a directory */
					if ((rval =
					    get_dir(remote_dircache.first->name,
						local_dircache.first->name,
						name, name)) > 1) {
						/*
						if (rval == EEXIST) {
						}
						 */
						goto out;
					}
				} else if (rval != 0) {
					goto out;
				}
				free(name);
				name = NULL;
				remote_list_nfiles--;
				break;
			default:
				remote_list_nothers--;
				footer_message(
				    "Ignoring non-file/directory %s.",
				    tmp->name);
				log_message("Can only transfer files.\n");
				break;
			}
			xv_set(base_window.list,
				PANEL_LIST_SELECT, row, FALSE,
				NULL);
			remote_show_items();
		}

out:
	if (dirchanged)
		change_local_dir(".", 1);
	if (show_status)
		xv_set(status_window.frame,
			XV_SHOW, FALSE,
			NULL);
	update_status_label("Not", "transferring", (size_t)0);
	end_status();
	if (name)
		free(name);
	change_remote_list_menu();
	xfer_buttons_active();
	if (timedout)
		timeout_disconnect();
	return;
}

#ifdef USE_PROTOTYPES
void	doput(void)
#else
void	doput()
#endif
{
	int 	nitems, row;
	struct dirlist *tmp;
	int		rval = 0;
	int		mode;
	char	*name = NULL;
	int		dirchanged = 0;

	xfer_buttons_inactive();
	abort_transfer = 0;
	if (dirwasmodified()) {
		goto out;
	}
	if (ping_server())
		goto out;
	if (show_status)
		xv_set(status_window.frame,
			XV_SHOW, TRUE,
			NULL);
	init_status(sum_local_size());
	/* loop over each selected element, and do a get, then unselect */
	nitems = xv_get(local_window.list, PANEL_LIST_NROWS);
	for (row = 0; row < nitems; row++)
		if (xv_get(local_window.list, PANEL_LIST_SELECTED, row)) {
			tmp = (struct dirlist *)xv_get(local_window.list,
				PANEL_LIST_CLIENT_DATA, row);
			mode = tmp->mode & S_IFMT;
			if (non_unix) {
				/*
				 * cannot transfer whole directories
				 * on non-unix machines
				 */
				mode = S_IFREG;
			}
			switch (mode) {
			case S_IFDIR:
				dirchanged++;
				if ((rval =
				    put_dir(remote_dircache.first->name,
					local_dircache.first->name, tmp->name,
					tmp->name)) != 0) {
					goto out;
				}
				local_list_ndirs--;
				break;
			case S_IFREG:
				dirchanged++;
				if ((rval = put_file(tmp->name, tmp->name,
				    tmp->size)) != 0)
					goto out;
				local_list_nfiles--;
				break;
			case S_IFLNK:
				name = linkname(tmp->name);
				if (name == NULL)
					goto out;
				/* try as a file */
				dirchanged++;
				rval = put_file(name, name, -1);
				if (rval == EPERM) {
					if ((rval =
					    put_dir(remote_dircache.first->name,
						local_dircache.first->name,
						name, name)) != 0) {
						goto out;
					}
				} else if (rval != 0) {
					goto out;
				}
				local_list_nfiles--;
				free(name);
				name = NULL;
				break;
			default:
				local_list_nothers--;
				local_footer_message(
				    "Ignoring non-file/directory %s.",
				    tmp->name);
				log_message("Can only transfer files.\n");
				break;
			}
			xv_set(local_window.list,
				PANEL_LIST_SELECT, row, FALSE,
				NULL);
			local_show_items();
		}

out:
	if (dirchanged)
		change_remote_dir(".", 1);
	if (show_status)
		xv_set(status_window.frame,
			XV_SHOW, FALSE,
			NULL);
	update_status_label("Not", "transferring", (size_t)0);
	end_status();
	if (name)
		free(name);
	change_local_list_menu();
	xfer_buttons_active();
	if (rval == ENOSPC) {
		disconnect();
	}
	if (timedout)
		timeout_disconnect();
	return;
}

#ifdef USE_PROTOTYPES
void	dofileop(int which)
#else
void	dofileop(which)
int		which; /* uncompress or extract */
#endif
{
	int 	nitems, row;
	struct dirlist *tmp;
	int		mode;
	int		dirchanged = 0;
	char	*name = NULL;
	struct extension_info *ext_info;
	struct stat buf;
#ifndef __FreeBSD__
	extern char	*sys_errlist[];
#endif

	xfer_buttons_inactive();
	abort_transfer = 0;
	if (dirwasmodified()) {
	/*
		goto out;
	*/
	}
	if (which == DOGETTARFILENAME) {
		xv_set(tar_frame,
			XV_SHOW, TRUE,
			NULL);
		goto out;
	} else if (which == DOTAR) {
		create_tar_file();
		goto out;
	}
	nitems = xv_get(local_window.list, PANEL_LIST_NROWS);
	/* loop over each selected element, and do a get, then unselect */
	for (row = 0; row < nitems; row++)
		if (xv_get(local_window.list, PANEL_LIST_SELECTED, row)) {
			/* perhaps should recursively get directories? */
			tmp = (struct dirlist *)xv_get(local_window.list,
				PANEL_LIST_CLIENT_DATA, row);
			mode = tmp->mode & S_IFMT;
			if (non_unix) {
				/*
				 * cannot do anything to whole directories
				 * on non-unix machines
				 */
				mode = S_IFREG;
			}
			switch (mode) {
			case S_IFDIR:
				local_footer_message("Ignoring directory.");
				local_list_ndirs--;
				break;
			case S_IFLNK:
			case S_IFREG:
				if (S_ISLNK(mode))
					name = linkname(tmp->name);
				else
					name = strdup(tmp->name);
				if (name == NULL) {
					fprintf(stderr, "Out of memory.\n");
					goto out;
				}
				if (stat(name, &buf) == -1) {
					local_footer_message(
					    "%s: %s.", name,
					    sys_errlist[errno]);
					goto out;
				}
				if (!S_ISREG(buf.st_mode)) {
					local_footer_message(
					    "%s is not a regular file.",
					    name);
					goto out;
				}
				switch (which) {
				case DOUNCOMPRESS:
					if (iscompressed(name)) {
						local_footer_message(
						    "Uncompressing %s.",
						    name);
						uncompress(name);
					} else
						local_footer_message(
						    "%s not compressed.\n",
						    name);
					break;
				case DOEXTRACT:
					if (iscompressed(name)) {
						char *dot;

						local_footer_message(
						    "Uncompressing %s.",
						    name);
						uncompress(name);
						dot = rindex(name, '.');
						if (dot) {
							*dot = '\0';
						}
					}
					ext_info = type_by_extension(name);
					if (ext_info &&
					    !strcmp(ext_info->extension,
					    ".tar")) {
						/* will do tar viewer */
						start_viewer(name, 0);
					} else {
						local_footer_message(
						    "%s is not a tar file.",
						    name);
					}
					break;
				case DOCOMPRESS:
					if (!iscompressed(name)) {
						local_footer_message(
						    "Compressing %s.", name);
						compress(name);
					} else {
						local_footer_message(
						    "%s already compressed.",
						    name);
					}
					break;
				}
				free(name);
				name = NULL;
				local_list_nfiles--;
				dirchanged++;
				break;
			default:
				local_list_nothers--;
				local_footer_message(
				    "Ignoring non-file/directory %s.",
				    tmp->name);
				log_message("Ignoring non-file.\n");
				break;
			}
			xv_set(local_window.list,
				PANEL_LIST_SELECT, row, FALSE,
				NULL);
			local_show_items();
		}

out:
	if (name)
		free(name);
	change_local_list_menu();
	if (dirchanged)
		change_local_dir(".", 1);
	xfer_buttons_active();
	if (timedout)
		timeout_disconnect();
	return;

}

#ifdef USE_PROTOTYPES
void	doview(int which)
#else
void	doview(which)
int		which; /* local or remote */
#endif
{
	int 	nitems, row;
	struct dirlist *tmp;
	Panel	list_panel;
	int		mode;
	int		dirchanged = 0;
	char	*name = NULL;

	xfer_buttons_inactive();
	abort_transfer = 0;
	if (dirwasmodified()) {
	/*
		goto out;
	*/
	}
	if (which == DOREMOTEVIEW) {
		list_panel = base_window.list;
		if (ping_server())
			goto out;
		if (show_status)
			xv_set(status_window.frame,
				XV_SHOW, TRUE,
				NULL);
		init_status(sum_remote_size());
	} else
		list_panel = local_window.list;
	/* loop over each selected element, and do a get, then unselect */
	nitems = xv_get(list_panel, PANEL_LIST_NROWS);
	for (row = 0; row < nitems; row++)
		if (xv_get(list_panel, PANEL_LIST_SELECTED, row)) {
			/* perhaps should recursively get directories? */
			tmp = (struct dirlist *)xv_get(list_panel,
				PANEL_LIST_CLIENT_DATA, row);
			mode = tmp->mode & S_IFMT;
			if (non_unix) {
				/*
				 * can't do anything to whole directories
				 * on non-unix machines
				 */
				mode = S_IFREG;
			}
			switch (mode) {
			case S_IFDIR:
				if (which == DOREMOTEVIEW) {
					footer_message(
					    "Cannot View a directory.");
					remote_list_ndirs--;
				} else {
					local_footer_message(
					    "Can't View a directory.");
					local_list_ndirs--;
				}
				break;
			case S_IFLNK:
			case S_IFREG:
				if (S_ISLNK(mode))
					name = linkname(tmp->name);
				else
					name = strdup(tmp->name);
				if (name == NULL) {
					fprintf(stderr, "Out of memory.\n");
					goto out;
				}
				if (which == DOREMOTEVIEW) {
					if (view_remote_file(name, tmp->size))
						goto out;
					remote_list_nfiles--;
				} else {
					if (view_local_file(name, which,
					    &dirchanged))
						goto out;
					local_list_nfiles--;
				}
				free(name);
				name = NULL;
				break;
			default:
				log_message("Can only transfer files.\n");
				if (which == DOREMOTEVIEW) {
					footer_message(
					    "Ignoring non-file/directory %s.",
					    tmp->name);
					remote_list_nothers--;
				} else {
					local_footer_message(
					    "Ignoring non-file/directory %s.",
					    tmp->name);
					local_list_nothers--;
				}
				break;
			}
			xv_set(list_panel,
				PANEL_LIST_SELECT, row, FALSE,
				NULL);
			local_show_items();
			remote_show_items();
		}

out:
	if (name)
		free(name);
	if (which == DOREMOTEVIEW) {
		change_remote_list_menu();
		if (show_status)
			xv_set(status_window.frame,
				XV_SHOW, FALSE,
				NULL);
	} else
		change_local_list_menu();
	update_status_label("Not", "transferring", (size_t)0);
	end_status();
	if (dirchanged)
		change_local_dir(".", 1);
	xfer_buttons_active();
	if (timedout)
		timeout_disconnect();
	return;
}

#ifdef USE_PROTOTYPES
void create_tar_file(void)
#else
void create_tar_file()
#endif
{
	int 	nitems, row;
	char	*filename = 0;
	struct dirlist *tmp;
	char	**argv;
	char	*slash;
	int		ix;


	xfer_buttons_inactive();

	if (dirwasmodified()) {
	/*
		goto out;
	*/
	}

	filename = (char *)xv_get(tar_text, PANEL_VALUE);
	if (*filename == '\0') {
		local_footer_message("Type in a name for the tar file.");
		goto out;
	}

	local_footer_message("Creating tar file %s.", filename);
	nitems = xv_get(local_window.list, PANEL_LIST_NROWS);
	/* slightly different - take ALL seletctions and put them in a */
	/* tar file */
	if ((argv = (char **)malloc((unsigned int)((3+nitems+1) *
	    sizeof (char *)))) == NULL) {
		fprintf(stderr, "Out of memory.\n");
		goto out;
	}
	ix = 3;
	for (row = 0; row < nitems; row++)
		if (xv_get(local_window.list, PANEL_LIST_SELECTED, row)) {
			tmp = (struct dirlist *)xv_get(local_window.list,
				PANEL_LIST_CLIENT_DATA, row);
			if (!S_ISDIR(tmp->mode) && !S_ISREG(tmp->mode) &&
			    !S_ISLNK(tmp->mode))
				continue;
			argv[ix] = strdup(tmp->name);
			if (argv[ix] == NULL) {
				fprintf(stderr, "Out of memory.\n");
				for (ix--; ix > 2; ix--)
					free(argv[ix]);
				free((char *)argv);
				goto out;
			}
			slash = index(argv[ix], '/');
			if (slash)
				*slash = '\0';
			ix++;
			if (S_ISDIR(tmp->mode))
				local_list_ndirs--;
			else
				local_list_nfiles--;
			xv_set(local_window.list,
				PANEL_LIST_SELECT, row, FALSE,
				NULL);
			local_show_items();
		}
	argv[0] = "tar";
	argv[1] = "cvf";
	argv[2] = filename;
	argv[ix] = NULL;
	if (ix == 2)
		goto out;
	pipe_program(argv);
	xv_set(local_window.list,
		XV_SHOW, TRUE,
		NULL);
	for (ix--; ix > 2; ix--)
		free(argv[ix]);
	free((char *)argv);
	change_local_dir(".", 1);
out:
	xfer_buttons_active();
	if (timedout)
		timeout_disconnect();
	return;
}

#ifdef USE_PROTOTYPES
void	doremotecd(int force)
#else
void	doremotecd(force)
int		force;
#endif
{
	if (which_remote_file == NULL)
		return;
	xfer_buttons_inactive();
	change_remote_dir(which_remote_file, force);
	free(which_remote_file);
	which_remote_file = NULL;
	xfer_buttons_active();
	if (timedout)
		timeout_disconnect();
}


syntax highlighted by Code2HTML, v. 0.9.1