/***************************************************************************/
/***************************************************************************/
/* */
/* (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 <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#if defined(SYSV) || defined(SVR4)
#include <netdb.h>
#endif
#include <ctype.h>
#include <X11/Intrinsic.h>
#include "xdir.h"
#include "str.h"
extern int max_ftp_retries;
extern int diagnostics;
extern struct st_host_info hinfo[];
extern int maxt;
/*
* remote_cd - Change remote working directory to specified directory.
* "host" is the host id. Set print_error_msg to True if
* FTP-generated error messages are to be written to the
* log when not in verbose mode. Returns 0 if successful,
* -3 for broken connection, -6 for stop button pushed,
* and -1 for other errors.
*/
remote_cd(host, directory, print_error_msg)
int host;
char *directory;
int print_error_msg;
{
char reply[MAXFTPREPLY];
char cmd[MAXPATHLEN+5];
int code;
int retval;
int retries = 0;
int scode;
retry:
/* Send CWD command to FTP server */
sprintf(cmd, "CWD %s", directory);
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
return 0;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("Change directory");
goto retry;
}
if (diagnostics < VERBOSE && print_error_msg)
report_ftp_reply(host, reply);
return -1;
case -6:
abort_ftp_cmd(host);
return -6;
case -3:
return -3;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE && print_error_msg)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* remote_mkdir - Create remote directory. "host" is the host id. Returns
* 0 if successful, -3 for broken connection, -6 for stop
* button pushed, and -1 for other errors.
*/
remote_mkdir(host, path)
int host;
char *path;
{
char reply[MAXFTPREPLY];
char cmd[MAXPATHLEN+5];
int code;
int retval;
char *dir;
char *entry;
int retries = 0;
int scode;
retry:
/* "cd" into directory */
parse_path(hinfo[host].system, path, &dir, &entry);
retval = remote_cd(host, dir, True);
XtFree(dir);
switch (retval) {
case 0:
break;
case -3:
case -6:
XtFree(entry);
return retval;
default:
XtFree(entry);
return -1;
}
/* Send MKD command to FTP server */
if (hinfo[host].system == SYS_VMS)
sprintf(cmd, "MKD %s", path);
else {
sprintf(cmd, "MKD %s", entry);
XtFree(entry);
}
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
return 0;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("Make directory");
goto retry;
}
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* remote_delete - Delete file/directory from remote host. "host" is
* the host id. Returns 0 if successful, -3 for broken
* connection, -6 for stop button pushed, and -1 for
* other errors.
*/
remote_delete(host, path)
int host;
char *path;
{
char reply[MAXFTPREPLY];
char cmd[MAXPATHLEN+6];
int code;
int retval;
char *dir;
char *entry;
int retries = 0;
int scode;
retry:
/* "cd" into directory */
parse_path(hinfo[host].system, path, &dir, &entry);
retval = remote_cd(host, dir, True);
XtFree(dir);
switch (retval) {
case 0:
break;
case -6:
XtFree(entry);
return retval;
default:
XtFree(entry);
return -1;
}
/* Send DELE command to FTP server */
sprintf(cmd, "DELE %s", entry);
XtFree(entry);
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return -1;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
return 0;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("Delete");
goto retry;
}
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* remote_rmdir - Remove remote directory. "host" is the host id.
* Returns 0 if successful, -3 for broken connection,
* -6 for stop button pushed, and -1 for other errors.
*/
remote_rmdir(host, path)
int host;
char *path;
{
char reply[MAXFTPREPLY];
char cmd[MAXPATHLEN+5];
int code;
int retval;
char *dir;
char *entry;
int retries = 0;
int scode;
retry:
/* "cd" into directory */
parse_path(hinfo[host].system, path, &dir, &entry);
retval = remote_cd(host, dir, True);
XtFree(dir);
switch (retval) {
case 0:
break;
case -3:
case -6:
XtFree(entry);
return retval;
default:
XtFree(entry);
return -1;
}
/* Send RMD command to FTP server */
sprintf(cmd, "RMD %s", entry);
XtFree(entry);
if (hinfo[host].server == SERVER_VMS_3_0)
strcat(cmd, ";1");
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return -1;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
return 0;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("Remove directory");
goto retry;
}
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* remote_pwd - Get remote working directory name. If successful, "name"
* is set to point to a string allocated by remote_pwd, else
* "name" is undefined. "host" is the host id.
* Use XtFree() to release memory pointed to by "name".
* Returns 0 if successful, -3 for broken connection, -6 for
* stop button pressed, and -1 for other errors.
*/
remote_pwd(host, name)
int host;
char **name;
{
char reply[MAXFTPREPLY];
int code;
int nbytes;
char *start;
char *end;
int retval;
int retries = 0;
int len;
retry:
/* Send PWD command to FTP server */
if ((retval = send_ftp_cmd(host, "PWD")) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
retval = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (retval) {
case 2:
break;
case 1:
case 3:
case 5:
return -1;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("Print working directory");
goto retry;
}
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
case -2:
report_client_timeout(host);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
default:
if (retval > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return retval;
}
/* Extract directory path */
if ((start = strchr(reply, '\"'))) {
start++;
if ((end = strrchr(reply, '\"')) == NULL)
return -1;
if ((nbytes = end-start) <= 0)
return -1;
*name = XtMalloc(nbytes+1);
bcopy(start, *name, nbytes);
(*name)[nbytes] = '\0';
} else {
if (strtok(reply, " ") == NULL)
return -1;
if ((start = strtok(NULL, " ")) == NULL)
return -1;
*name = XtNewString(start);
}
/* Kludge for NCSA Telnet FTP server on Mac */
if (hinfo[host].server == SERVER_MAC_NCSATELNET) {
len = strlen(*name);
if ((len>1) && (((*name)[len-1] == '/') || ((*name)[len-1] == '\001')))
(*name)[len-1] = '\0';
}
/* If VMS, convert to lower case */
if (hinfo[host].system == SYS_VMS)
cvt_to_lower(*name);
return 0;
}
/*
* remote_rename - Rename/move a directory entry from "old_path" to
* "new_path". "host" is the host id. Returns 0 if
* successful, -3 for broken connection, -6 for stop
* button pushed, and -1 for other errors.
*/
remote_rename(host, old_path, new_path)
int host;
char *old_path;
char *new_path;
{
char reply[MAXFTPREPLY];
char cmd[MAXPATHLEN+6];
int code;
int retval;
int retries = 0;
int scode;
char *dir;
char *entry;
retry:
/* Send RNFR command to FTP server */
if (hinfo[host].server == SERVER_MAC_VERSATERM ||
hinfo[host].server == SERVER_WINDOWS_WFTPD) {
parse_path(hinfo[host].system, old_path, &dir, &entry);
retval = remote_cd(host, dir, True);
XtFree(dir);
switch (retval) {
case 0:
break;
case -3:
case -6:
XtFree(entry);
return retval;
default:
XtFree(entry);
return -1;
}
sprintf(cmd, "RNFR %s", entry);
XtFree(entry);
} else
sprintf(cmd, "RNFR %s", old_path);
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 3:
break;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("Rename");
goto retry;
}
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
/* Send RNTO command to FTP server */
if (hinfo[host].server == SERVER_MAC_VERSATERM ||
hinfo[host].server == SERVER_WINDOWS_WFTPD) {
parse_path(hinfo[host].system, new_path, &dir, &entry);
retval = remote_cd(host, dir, True);
XtFree(dir);
switch (retval) {
case 0:
break;
case -3:
XtFree(entry);
return -3;
case -6:
XtFree(entry);
abort_ftp_cmd(host);
return -6;
default:
XtFree(entry);
return -1;
}
sprintf(cmd, "RNTO %s", entry);
XtFree(entry);
} else
sprintf(cmd, "RNTO %s", new_path);
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval == -6) {
abort_ftp_cmd(host);
return -6;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
return 0;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("Rename");
goto retry;
} else {
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* quote_cmd - Send command to ftp server. "host" is the host id. Returns
* 0 if successful, -3 for broken connection, -6 for stop button
* pushed, and -1 for other errors.
*/
quote_cmd(host, cmd)
int host;
char *cmd;
{
char reply[MAXFTPREPLY];
int code;
int retval;
/* Send command to FTP server */
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval == -6)
return -6;
else if (retval < 0)
return -1;
/* Get response from FTP server */
while (1)
switch (get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt)) {
case 1:
case 3:
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
continue;
case -1:
return -1;
case -2:
report_client_timeout(host);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
default:
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return 0;
}
}
/*
* remote_noop - Send no-op command to ftp server. Returns 0 if
* successful, -3 for broken connection, -6 for stop
* button pushed, -2 for timeout, and -1 for other errors.
*/
remote_noop(host)
int host;
{
char reply[MAXFTPREPLY];
int code;
int retval;
int retries = 0;
retry:
/* Send NOOP command to FTP server */
if ((retval = send_ftp_cmd(host, "NOOP")) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
retval = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (retval) {
case 2:
return 0;
case 4:
if (code >= 450 && code < 460 && retries++ < max_ftp_retries) {
if (diagnostics >= VERBOSE)
report_retry("No-op command");
goto retry;
}
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
return -2;
default:
if (retval > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* stage_file - Tell Unitree or HPSS server to stage the file specified by
* "path". "host" is the host id. Returns 0 if file is already
* on disk, 1 if stage is successfully initiated, -3 for lost
* connection, -6 for stop button pushed, and -1 for other errors.
*/
stage_file(host, path)
int host;
char *path;
{
/* Send STAGE command to FTP server */
switch (hinfo[host].server) {
case SERVER_UNIX_UNITREE:
case SERVER_UNIX_NSL_UNITREE:
return stage_unitree_file(host, path);
case SERVER_UNIX_HPSS:
return stage_hpss_file(host, path);
default: /* Sanity check */
fatal_error("Bug in stage_file()");
return 0; /* keep compiler happy */
}
}
/*
* stage_unitree_file - Tell Unitree server to stage the file specified by
* "path". "host" is the host id. Returns 0 if file
* is already on disk, 1 if stage is successfully
* initiated, -3 for lost connection, -6 for stop
* button pushed, and -1 for other errors.
*/
stage_unitree_file(host, path)
int host;
char *path;
{
char reply[MAXFTPREPLY];
char cmd[MAXPATHLEN+9];
int code;
int retval;
int scode;
/* Send STAGE command to FTP server */
sprintf(cmd, "STAGE 1 %s", path);
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
return 0;
case 4:
case 5:
if (code == 405 || code == 505)
return 1;
if (diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* stage_hpss_file - Tell HPSS server to stage the file specified by
* "path". "host" is the host id. Returns 0 if file
* is already on disk, 1 if stage is successfully
* initiated, -3 for lost connection, -6 for stop
* button pushed, and -1 for other errors.
*/
stage_hpss_file(host, path)
int host;
char *path;
{
char reply[MAXFTPREPLY];
char cmd[MAXPATHLEN+14];
int code;
int retval;
int scode;
/* Send STAGE command to FTP server */
sprintf(cmd, "SITE STAGE %s", path);
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
if (strstr(reply, "ready for other processing"))
return 0;
else
return 1;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
/*
* set_hpss_wait - Set wait mode for HPSS server to "no wait". Returns
* 0 for success, -3 for broken connection, -6 for stop
* button pressed, and -1 for other errors.
*/
set_hpss_wait(host)
int host;
{
char reply[MAXFTPREPLY];
char cmd[15];
int code;
int retval;
int scode;
/* Sanity check */
if (hinfo[host].server != SERVER_UNIX_HPSS) {
fatal_error("Bug in set_hpss_wait()");
}
/* Send WAIT command to FTP server */
sprintf(cmd, "SITE WAIT 0");
if ((retval = send_ftp_cmd(host, cmd)) == -2) {
report_client_timeout(host);
return -1;
} else if (retval < 0)
return retval;
/* Get response from FTP server */
scode = get_ftp_reply(host, reply, MAXFTPREPLY, &code, maxt);
switch (scode) {
case 2:
return 0;
case -3:
return -3;
case -6:
abort_ftp_cmd(host);
return -6;
case -2:
report_client_timeout(host);
default:
if (scode > 0 && diagnostics < VERBOSE)
report_ftp_reply(host, reply);
return -1;
}
}
syntax highlighted by Code2HTML, v. 0.9.1