#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