/***************************************************************************/ /***************************************************************************/ /* */ /* (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 #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; }