/***************************************************************************/
/***************************************************************************/
/* */
/* (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/TextF.h>
#include <netdb.h>
#include "xdir.h"
#ifdef __osf__
#include <netdnet/dnetdb.h>
#endif
#include "list.h"
#include "str.h"
#define FTPCTRLPORT 21
extern struct st_host_info hinfo[];
extern int diagnostics;
extern struct sl_struct *proxy_domains_list;
char *encrypt_password();
char *decrypt_password();
char *get_password();
char *get_account();
char *system_name();
char *server_name();
/*
* do_connect - Establish connection to remote host. Use password
* and account fields of hinfo[host] if non-null, otherwise
* prompt user for them. Returns 0 if successful, -2 if
* user cancels out from within password dialog, -6 if stop
* button pressed, else -1. "dirwin" is the directory window
* to center auxiliary dialogs on.
*/
do_connect(host, dirwin)
int host;
struct dirwin_st *dirwin;
{
char *acct = NULL;
char *passwrd = NULL;
int i;
int use;
int retval;
int len_hostname;
int len_domain;
char *temp;
char *host_part;
int port_part;
char *homedir;
char *uname;
#ifdef KERBEROS
int first_time = True;
int use_kerberos;
#endif
/* This might take some time */
use_busy_cursor();
/* Initialize FTP server information */
hinfo[host].system = SYS_UNIX;
hinfo[host].server = SERVER_UNKNOWN;
#ifdef KERBEROS
retry:
#endif
/* Use a proxy server? */
if (hinfo[host].use_proxy) {
use = True;
for (i=0; i<proxy_domains_list->nentries; i++) {
temp = XtNewString(hinfo[host].hostname);
cvt_to_lower(temp);
if (!strcmp(temp, proxy_domains_list->entries[i])) {
use = False;
XtFree(temp);
break;
}
len_hostname = strlen(temp);
len_domain = strlen(proxy_domains_list->entries[i]);
if (len_hostname > len_domain &&
temp[len_hostname-len_domain-1] == '.' &&
!strcmp(&(temp[len_hostname-len_domain]),
proxy_domains_list->entries[i])) {
use = False;
XtFree(temp);
break;
}
XtFree(temp);
}
} else
use = False;
/* Open connection with FTP server */
if (use) {
retval = ftp_open(host, hinfo[host].proxy_host, hinfo[host].proxy_port);
hinfo[host].system = SYS_UNIX;
hinfo[host].server = SERVER_UNKNOWN;
} else {
if (parse_hostname(hinfo[host].hostname, &host_part, &port_part))
fatal_error("Bug in do_connect()");
retval = ftp_open(host, host_part, port_part);
XtFree(host_part);
}
if (retval == -6) {
restore_prev_cursor();
return -6;
} else if (retval < 0) {
restore_prev_cursor();
return -1;
}
/* Try to login user */
if (use) {
uname = XtMalloc(
strlen(hinfo[host].username)+strlen(hinfo[host].hostname)+2);
sprintf(uname, "%s@%s", hinfo[host].username, hinfo[host].hostname);
} else
uname = XtNewString(hinfo[host].username);
retval = ftp_user(host, uname);
XtFree(uname);
switch (retval) {
case 0:
goto logged_on;
case 1:
#ifdef KERBEROS
use_kerberos = False;
#endif
break;
#ifdef KERBEROS
case 2:
if (first_time)
use_kerberos = True;
else
use_kerberos = False;
first_time = False;
break;
#endif
case -6:
restore_prev_cursor();
close(hinfo[host].ctrl_fd);
return -6;
default:
restore_prev_cursor();
close(hinfo[host].ctrl_fd);
return -1;
}
/* Need some sort of authorization */
#ifdef KERBEROS
if (use_kerberos) {
switch (ftp_kerberos_ticket(host)) {
case -6:
restore_prev_cursor();
close(hinfo[host].ctrl_fd);
return -6;
case 0:
goto logged_on;
case 1:
break;
default:
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
goto retry;
}
} else {
#endif
if (hinfo[host].password) /* Use last password */
passwrd = decrypt_password(hinfo[host].password);
else { /* Get password from user */
hide_stop_button();
passwrd = get_password(dirwin);
show_stop_button(dirwin);
if (passwrd == NULL) {
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
return -2;
}
}
switch (ftp_password(host, passwrd)) {
case 0:
goto logged_on;
case 1:
break;
case -6:
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
bzero(passwrd, (int)strlen(passwrd));
XtFree(passwrd);
return -6;
default:
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
bzero(passwrd, (int)strlen(passwrd));
XtFree(passwrd);
return -1;
}
#ifdef KERBEROS
}
#endif
/* Account required. Get it from user */
if (hinfo[host].account) /* Use last account */
acct = XtNewString(hinfo[host].account);
else { /* Get account from user */
hide_stop_button();
acct = get_account(dirwin);
show_stop_button(dirwin);
if (acct == NULL) {
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
bzero(passwrd, (int)strlen(passwrd));
XtFree(passwrd);
return -1;
}
}
/* Send account to FTP server */
if ((retval = ftp_account(host, acct)) < 0) {
XtFree(acct);
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
bzero(passwrd, (int)strlen(passwrd));
XtFree(passwrd);
if (retval == -6)
return -6;
else
return -1;
}
logged_on:
/* Try to determine system type. If failure, assume Unix */
if (ftp_system(host, False) == -6) {
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
XtFree(acct);
return -6;
}
if (diagnostics == DEBUG) {
write_log("*** System is ");
write_log(system_name(hinfo[host].system));
write_log("\n");
write_log("*** Server is ");
write_log(server_name(hinfo[host].server));
write_log("\n");
}
/* Set wait mode of HPSS server to "no wait" */
if (hinfo[host].server == SERVER_UNIX_HPSS &&
(retval = set_hpss_wait(host)) < 0) {
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
XtFree(acct);
if (retval == -6)
return -6;
else {
record_warning("Unable to set HPSS wait mode.");
return -1;
}
}
/* What is the home directory? Get actual name */
if ((retval = remote_pwd(host, &homedir)) < 0) {
close(hinfo[host].ctrl_fd);
restore_prev_cursor();
XtFree(acct);
if (retval == -6)
return -6;
else {
record_warning("Unable to get home directory.");
return -1;
}
}
XtFree(hinfo[host].homedir);
hinfo[host].homedir = homedir;
/* Success */
XtFree(hinfo[host].password);
if (passwrd) {
hinfo[host].password = encrypt_password(passwrd);
bzero(passwrd, (int)strlen(passwrd));
XtFree(passwrd);
} else
hinfo[host].password = NULL;
XtFree(hinfo[host].account);
hinfo[host].account = acct;
restore_prev_cursor();
return 0;
}
/*
* parse_hostname - Parse "hostname" into its host name and port address
* components. "hostname" can either consist of a blank-
* delimited host name / port address pair, or just a
* host name. If the port address part is not given,
* the default control connection port will be used.
* If successful, "host_part" is set to point to a
* string (which the caller can free by calling XtFree()),
* "port_part" is set to the specified port, and a value
* of 0 is returned. If no host name is given, -1 is
* returned. If an invalid port designator is given,
* -2 is returned.
*/
parse_hostname(hostname, host_part, port_part)
char *hostname;
char **host_part;
int *port_part;
{
char *temp;
char *hp;
char *pp;
int port;
int len;
int i;
/* Make copy of hostname */
temp = XtNewString(hostname);
/* Get host part */
if ((hp = strtok(temp, " ")) == NULL) {
XtFree(temp);
return -1;
}
/* Get port part */
if ((pp = strtok(NULL, " ")) == NULL)
port = FTPCTRLPORT;
else {
port = 0;
len = strlen(pp);
for (i=0; i<len; i++)
if (pp[i] >= '0' && pp[i] <= '9')
port = 10*port+(pp[i]-'0');
else {
XtFree(temp);
return -2;
}
if (strtok(NULL, " ") != NULL) {
XtFree(temp);
return -2;
}
}
/* Everything looks good */
*host_part = XtNewString(hp);
XtFree(temp);
*port_part = port;
return 0;
}
/*
* parse_hostuser - Parse the hostname/username pair in "hostuser" to
* "host_part" and "user_part". Use XtFree() to free
* returned memory. Returns -1 if either part is null,
* otherwise 0 is returned.
*/
parse_hostuser(hostuser, host_part, user_part)
char *hostuser;
char **host_part;
char **user_part;
{
int i;
char *p;
char *text = XtNewString(hostuser);
/* Host comes before the first "(" */
if ((p = strtok(text, "(")) == NULL) {
XtFree(text);
return -1;
}
for (i=strlen(p)-1; i>=0; i--)
if (p[i] == ' ')
p[i] = '\0';
else
break;
if (strlen(p) == 0) {
XtFree(text);
return -1;
}
*host_part = XtNewString(p);
/* Get user name. Spaces must be embedded */
if ((p = strtok(NULL, "()")) == NULL) {
XtFree(text);
XtFree(*host_part);
return -1;
}
while (*p == ' ')
p++;
for (i=strlen(p)-1; i>=0; i--)
if (p[i] == ' ')
p[i] = '\0';
else
break;
if (strlen(p) == 0) {
XtFree(text);
XtFree(*host_part);
return -1;
}
*user_part = XtNewString(p);
XtFree(text);
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1