/***************************************************************************/
/***************************************************************************/
/* */
/* (c) 1995-1999. The Regents of the University of California. All */
/* rights reserved. */
/* */
/* This work was produced at the University of California, Lawrence */
/* Livermore National Laboratory (UC LLNL) under contract no. */
/* W-7405-ENG-48 (Contract 48) between the U.S. Department of Energy */
/* (DOE) and The Regents of the University of California (University) */
/* for the operation of UC LLNL. Copyright is reserved to the */
/* University for purposes of controlled dissemination, */
/* commercialization through formal licensing, or other disposition */
/* under terms of Contract 48; DOE policies, regulations and orders; */
/* and U.S. statutes. The rights of the Federal Government are */
/* reserved under Contract 48 subject to the restrictions agreed upon */
/* by the DOE and University. */
/* */
/* */
/* DISCLAIMER */
/* */
/* This software was prepared as an account of work sponsored by an */
/* agency of the United States Government. Neither the United States */
/* Government nor the University of California nor any of their */
/* employees, makes any warranty, express or implied, or assumes any */
/* liability or responsibility for the accuracy, completeness, or */
/* usefulness of any information, apparatus, product, or process */
/* disclosed, or represents that its specific commercial products, */
/* process, or service by trade name, trademark, manufacturer, or */
/* otherwise, does not necessarily constitute or imply its */
/* endorsement, recommendation, or favoring by the United States */
/* Government or the University of California. The views and opinions */
/* of the authors expressed herein do not necessarily state or reflect */
/* those of the United States Government or the University of */
/* California, and shall not be used for advertising or product */
/* endorsement purposes. */
/* */
/* Permission to use, copy, modify and distribute this software and its */
/* documentation for any non-commercial purpose, without fee, is */
/* hereby granted, provided that the above copyright notice and this */
/* permission notice appear in all copies of the software and */
/* supporting documentation, and that all UC LLNL identification in */
/* the user interface remain unchanged. The title to copyright LLNL */
/* XDIR shall at all times remain with The Regents of the University */
/* of California and users agree to preserve same. Users seeking the */
/* right to make derivative works with LLNL XDIR for commercial */
/* purposes may obtain a license from the Lawrence Livermore National */
/* Laboratory's Technology Transfer Office, P.O. Box 808, L-795, */
/* Livermore, CA 94550. */
/* */
/***************************************************************************/
/***************************************************************************/
#include <Xm/Xm.h>
#include "xdir.h"
#include "xfer.h"
#include "str.h"
extern struct xfer_ctrl_block xc;
extern struct st_host_info hinfo[];
extern int diagnostics;
extern int store_unique;
extern int maxt;
extern int preserve_vms_ver_nums;
long extract_file_len();
/*
* init_remote_copy - Initialize transfer of file from remote host to
* remote host. "xc" is used for input and
* output. Returns 0 if successful, -3 for lost
* source connection, -4 for lost sink connection,
* -5 for lost source and sink connections, -6 for
* stop button pressed, and -1 for other errors.
* The transfer will work only if at least one of
* the FTP servers supports the PASV command.
*/
init_remote_copy()
{
char *src_dir;
char *src_file;
char *snk_dir;
char *snk_file;
char *port;
char *q;
char cmd[MAXPATHLEN+5];
char reply[MAXFTPREPLY];
int code;
int retval;
int src_scode = 0;
int snk_scode = 0;
long file_len;
int passive_mode_host;
char *src_path;
char *snk_path;
/* "cd" into source directory */
src_paths_of_xfer_node(xc.current_node, NULL, &src_path);
parse_path(xc.src_host_system, src_path, &src_dir, &src_file);
XtFree(src_path);
retval = remote_cd(xc.src_dirwin->host, src_dir, True);
XtFree(src_dir);
switch (retval) {
case 0:
break;
case -3:
case -6:
XtFree(src_file);
return retval;
default:
XtFree(src_file);
return -1;
}
/* "cd" into sink directory */
snk_paths_of_xfer_node(xc.current_node, NULL, &snk_path);
parse_path(xc.snk_host_system, snk_path, &snk_dir, &snk_file);
XtFree(snk_path);
if ((xc.src_host_system == SYS_VMS) && !preserve_vms_ver_nums) {
if ((q = strrchr(snk_file, ';')))
*q = '\0';
}
retval = remote_cd(xc.snk_dirwin->host, snk_dir, True);
XtFree(snk_dir);
switch (retval) {
case 0:
break;
case -3:
XtFree(src_file);
XtFree(snk_file);
return -4;
case -6:
XtFree(src_file);
XtFree(snk_file);
return -6;
default:
XtFree(src_file);
XtFree(snk_file);
return -1;
}
/* Try to put either sink or source host into passive mode */
if ((hinfo[xc.snk_dirwin->host].server != SERVER_UNIX_UNITREE) &&
(hinfo[xc.snk_dirwin->host].server != SERVER_UNIX_NSL_UNITREE) &&
(hinfo[xc.src_dirwin->host].server != SERVER_NT) &&
(retval = ftp_passive(xc.snk_dirwin->host, &port)) == 0) {
passive_mode_host = xc.snk_dirwin->host;
if ((retval = ftp_port(xc.src_dirwin->host, port)) < 0) {
XtFree(src_file);
XtFree(snk_file);
XtFree(port);
switch (retval) {
case -6:
abort_rcopy(False, True);
return -6;
case -2:
report_client_timeout(xc.src_dirwin->host);
case -1:
return abort_rcopy(False, True);
case -3:
switch (abort_rcopy(False, True)) {
case -6:
return -6;
case -3:
return -5;
default:
return -3;
}
}
}
} else if (retval == -6) {
XtFree(src_file);
XtFree(src_file);
return -6;
} else if ((hinfo[xc.snk_dirwin->host].server != SERVER_UNIX_UNITREE) &&
(hinfo[xc.snk_dirwin->host].server != SERVER_UNIX_NSL_UNITREE) &&
(retval == -3)) {
XtFree(src_file);
XtFree(snk_file);
return -4;
} else if ((retval = ftp_passive(xc.src_dirwin->host, &port)) == 0) {
passive_mode_host = xc.src_dirwin->host;
if ((retval = ftp_port(xc.snk_dirwin->host, port)) < 0) {
XtFree(src_file);
XtFree(snk_file);
XtFree(port);
switch (retval) {
case -6:
abort_rcopy(True, False);
return -6;
case -2:
report_client_timeout(xc.snk_dirwin->host, port);
case -1:
return abort_rcopy(True, False);
case -3:
switch (abort_rcopy(True, False)) {
case -6:
return -6;
case -3:
return -5;
default:
return -4;
}
}
}
} else {
XtFree(src_file);
XtFree(snk_file);
return retval;
}
XtFree(port);
if (passive_mode_host == xc.src_dirwin->host) {
/* Send STOR command to sink FTP server */
if (store_unique)
sprintf(cmd, "STOU %s", snk_file);
else
sprintf(cmd, "STOR %s", snk_file);
XtFree(snk_file);
switch (send_ftp_cmd(xc.snk_dirwin->host, cmd)) {
case -6:
XtFree(src_file);
abort_rcopy(True, False);
return -6;
case -2:
report_client_timeout(xc.snk_dirwin->host);
case -1:
XtFree(src_file);
return abort_rcopy(True, False);
case -3:
XtFree(src_file);
switch (abort_rcopy(True, False)) {
case -6:
return -6;
case -3:
return -5;
default:
return -4;
}
}
/* Get STOR reply from sink FTP server */
snk_scode = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY,
&code, maxt);
switch (snk_scode) {
case -6:
XtFree(src_file);
abort_rcopy(True, True);
return -6;
case -3:
XtFree(src_file);
switch (abort_rcopy(True, False)) {
case -3:
return -5;
case -6:
return -6;
default:
return -4;
}
case 1:
break;
case -2:
report_client_timeout(xc.snk_dirwin->host);
default:
if (snk_scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(xc.snk_dirwin->host, reply);
XtFree(src_file);
return abort_rcopy(True, False);
}
/* Send RETR command to source FTP server */
sprintf(cmd, "RETR %s", src_file);
XtFree(src_file);
switch (send_ftp_cmd(xc.src_dirwin->host, cmd)) {
case -6:
abort_rcopy(True, True);
return -6;
case -2:
report_client_timeout(xc.src_dirwin->host);
case -1:
return abort_rcopy(True, True);
case -3:
switch (abort_rcopy(False, True)) {
case -6:
return -6;
case -4:
return -5;
default:
return -3;
}
}
/* Get RETR reply from source FTP server */
src_scode = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY,
&code, maxt);
switch (src_scode) {
case -6:
abort_rcopy(True, True);
return -6;
case -3:
switch (abort_rcopy(False, True)) {
case -6:
return -6;
case -4:
return -5;
default:
return -3;
}
case 1:
file_len = extract_file_len(reply);
xc.substate = 0; /* Need to wait for file source response */
xc.file_index = -1;
xc.file_len = file_len;
return 0;
case -2:
report_client_timeout(xc.src_dirwin->host);
default:
if (src_scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(xc.src_dirwin->host, reply);
return abort_rcopy(True, True);
}
} else { /* Sink host is in passive mode */
/* Send RETR command to source FTP server */
sprintf(cmd, "RETR %s", src_file);
XtFree(src_file);
switch (send_ftp_cmd(xc.src_dirwin->host, cmd)) {
case -6:
XtFree(snk_file);
abort_rcopy(True, True);
return -6;
case -3:
XtFree(snk_file);
switch (abort_rcopy(False, True)) {
case -6:
return -6;
case -4:
return -5;
default:
return -3;
}
case -2:
report_client_timeout(xc.src_dirwin->host);
case -1:
XtFree(snk_file);
return abort_rcopy(False, True);
}
/* Get RETR reply from source FTP server */
src_scode = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY,
&code, maxt);
switch (src_scode) {
case -6:
XtFree(snk_file);
abort_rcopy(True, True);
return -6;
case -3:
XtFree(snk_file);
switch (abort_rcopy(False, True)) {
case -4:
return -5;
case -6:
return -6;
default:
return -3;
}
case 1:
file_len = extract_file_len(reply);
break;
case -2:
report_client_timeout(xc.src_dirwin->host);
default:
if (src_scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(xc.src_dirwin->host, reply);
XtFree(snk_file);
return abort_rcopy(False, True);
}
/* Send STOR command to sink FTP server */
if (store_unique)
sprintf(cmd, "STOU %s", snk_file);
else
sprintf(cmd, "STOR %s", snk_file);
XtFree(snk_file);
switch (send_ftp_cmd(xc.snk_dirwin->host, cmd)) {
case -6:
abort_rcopy(True, True);
return -6;
case -2:
report_client_timeout(xc.snk_dirwin->host);
case -1:
return abort_rcopy(True, True);
case -3:
switch (abort_rcopy(True, False)) {
case -6:
return -6;
case -3:
return -5;
default:
return -4;
}
}
/* Get STOR reply from sink FTP server */
snk_scode = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY,
&code, maxt);
switch (snk_scode) {
case -6:
abort_rcopy(True, True);
return -6;
case -3:
switch (abort_rcopy(True, False)) {
case -6:
return -6;
case -3:
return -5;
default:
return -4;
}
case 1:
xc.substate = 0; /* Need to wait for file source response */
xc.file_index = -1;
xc.file_len = file_len;
return 0;
case -2:
report_client_timeout(xc.snk_dirwin->host);
default:
if (snk_scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(xc.snk_dirwin->host, reply);
return abort_rcopy(True, False);
}
}
}
/*
* do_remote_copy - Transfer next part of file from remote host to remote
* host. "xc" is used for input and output.
* Returns 0 if file transfer complete, 1 if file
* transfer not complete, -3 for lost source connection,
* -4 for lost sink connection, -5 for lost source and
* sink connections, -7 for a "552" reply (for UniTree
* retry mechanism), -6 for stop button pressed, and -1
* for other errors.
*/
do_remote_copy()
{
char reply[MAXFTPREPLY];
int code;
int scode;
/* Get final response from source FTP server */
if (xc.substate == 0) {
scode = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY, &code,
DELTA);
switch (scode) {
case -6:
abort_rcopy(True, True);
return -6;
case -3:
switch (abort_rcopy(False, True)) {
case -6:
return -6;
case -4:
return -5;
default:
return -3;
}
case -2:
return 1;
case 2:
xc.substate = 1;
break;
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(xc.src_dirwin->host, reply);
return abort_rcopy(False, True);
}
}
/* Get final response from sink FTP server */
scode = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY, &code,
DELTA);
switch (scode) {
case -6:
abort_rcopy(False, True);
return -6;
case -3:
return -4;
case -2:
return 1;
case 2:
return 0;
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(xc.snk_dirwin->host, reply);
if (code == 552) /* UniTree retry logic */
return -7;
else
return -1;
}
}
/*
* abort_remote_copy - Abort transfer of file from remote host to remote
* host. "xc" is used for input and output.
*/
void
abort_remote_copy()
{
abort_rcopy(True, True);
}
/*
* abort_rcopy - Abort transfer of file from remote host to remote host.
* "abort_src" specifies whether to send abort request to
* source host. "abort_snk" specifies whether to send
* abort request to sink host. "xc" is used for
* all other input and output. Returns -3 for lost source
* connection, -4 for lost sink connection, -5 for lost
* source and sink connections, -6 for stop button pressed,
* else -1.
*/
abort_rcopy(abort_src, abort_snk)
int abort_src;
int abort_snk;
{
char reply[MAXFTPREPLY];
int code;
int src_scode = 0;
int snk_scode = 0;
int stop_was_pressed = False;
int retval;
/* Pop up abort dialog */
show_abort_dialog();
/* Is the source FTP server already done? */
if (abort_src) {
src_scode = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY,
&code, 5);
switch (src_scode) {
case -6:
stop_was_pressed = True;
break;
case 2:
case 4:
case 5:
abort_src = False;
src_scode = 0;
break;
case -3:
abort_src = False;
}
}
/* Is the sink FTP server already done? */
if (abort_snk) {
snk_scode = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY,
&code, 5);
switch (snk_scode) {
case -6:
stop_was_pressed = True;
break;
case 2:
case 4:
case 5:
abort_snk = False;
snk_scode = 0;
break;
case -3:
abort_snk = False;
}
}
/* Send abort request to source FTP server */
if (abort_src)
if (urgent_abort(xc.src_dirwin->host) == -6)
stop_was_pressed = True;
/* Send abort request to sink FTP server */
if (abort_snk)
if (urgent_abort(xc.snk_dirwin->host) == -6)
stop_was_pressed = True;
/* Get responses from source FTP server */
if (abort_src) {
src_scode = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY,
&code, 15);
if (src_scode == -6) {
stop_was_pressed = True;
src_scode = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY,
&code, 15);
}
if (src_scode == 2) {
retval = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY,
&code, 5);
if (retval == -6) {
stop_was_pressed = True;
get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY, &code,
5);
}
} else if (src_scode > 0) {
src_scode = get_ftp_reply(xc.src_dirwin->host, reply, MAXFTPREPLY,
&code, 15);
if (src_scode == -6) {
stop_was_pressed = True;
src_scode = get_ftp_reply(xc.src_dirwin->host, reply,
MAXFTPREPLY, &code, 15);
}
}
if (src_scode == -2) {
report_client_timeout(xc.src_dirwin->host);
src_scode = -3;
}
}
/* Get responses from sink FTP server */
if (abort_snk) {
snk_scode = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY,
&code, 15);
if (snk_scode == -6) {
stop_was_pressed = True;
snk_scode = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY,
&code, 15);
}
if (snk_scode == 2) {
retval = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY,
&code, 5);
if (retval == -6) {
stop_was_pressed = True;
get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY, &code,
5);
}
} else if (snk_scode > 0) {
snk_scode = get_ftp_reply(xc.snk_dirwin->host, reply, MAXFTPREPLY,
&code, 15);
if (snk_scode == -6) {
stop_was_pressed = True;
snk_scode = get_ftp_reply(xc.snk_dirwin->host, reply,
MAXFTPREPLY, &code, 15);
}
}
if (snk_scode == -2) {
report_client_timeout(xc.snk_dirwin->host);
snk_scode = -3;
}
}
/* Want to check for lost host before issuing next command */
hinfo[xc.src_dirwin->host].last_reply_time = 0;
hinfo[xc.snk_dirwin->host].last_reply_time = 0;
/* Hide abort dialog */
hide_abort_dialog();
/* Return appropriate error value */
if (stop_was_pressed)
return -6;
if (src_scode == -3 && snk_scode == -3)
return -5;
else if (src_scode == -3)
return -3;
else if (snk_scode == -3)
return -4;
else
return -1;
}
syntax highlighted by Code2HTML, v. 0.9.1