diff options
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c')
| -rw-r--r-- | gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c | 3262 |
1 files changed, 1675 insertions, 1587 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c index 4c90ac0e41c..978d67c1703 100644 --- a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c +++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTFTP.c @@ -1,76 +1,76 @@ /* File Transfer Protocol (FTP) Client -** for a WorldWideWeb browser -** =================================== -** -** A cache of control connections is kept. -** -** Note: Port allocation -** -** It is essential that the port is allocated by the system, rather -** than chosen in rotation by us (POLL_PORTS), or the following -** problem occurs. -** -** It seems that an attempt by the server to connect to a port which has -** been used recently by a listen on the same socket, or by another -** socket this or another process causes a hangup of (almost exactly) -** one minute. Therefore, we have to use a rotating port number. -** The problem remains that if the application is run twice in quick -** succession, it will hang for what remains of a minute. -** -** Authors -** TBL Tim Berners-lee <timbl@info.cern.ch> -** DD Denis DeLaRoca 310 825-4580 <CSP1DWD@mvs.oac.ucla.edu> -** LM Lou Montulli <montulli@ukanaix.cc.ukans.edu> -** FM Foteos Macrides <macrides@sci.wfeb.edu> -** History: -** 2 May 91 Written TBL, as a part of the WorldWideWeb project. -** 15 Jan 92 Bug fix: close() was used for NETCLOSE for control soc -** 10 Feb 92 Retry if cached connection times out or breaks -** 8 Dec 92 Bug fix 921208 TBL after DD -** 17 Dec 92 Anon FTP password now just WWWuser@ suggested by DD -** fails on princeton.edu! -** 27 Dec 93 (FM) Fixed up so FTP now works with VMS hosts. Path -** must be Unix-style and cannot include the device -** or top directory. -** ?? ??? ?? (LM) Added code to prompt and send passwords for non -** anonymous FTP -** 25 Mar 94 (LM) Added code to recognize different ftp server types -** and code to parse dates and sizes on most hosts. -** 27 Mar 93 (FM) Added code for getting dates and sizes on VMS hosts. -** -** Notes: -** Portions Copyright 1994 Trustees of Dartmouth College -** Code for recognizing different FTP servers and -** parsing "ls -l" output taken from Macintosh Fetch -** program with permission from Jim Matthews, -** Dartmouth Software Development Team. -*/ + * for a WorldWideWeb browser + * =================================== + * + * A cache of control connections is kept. + * + * Note: Port allocation + * + * It is essential that the port is allocated by the system, rather + * than chosen in rotation by us (POLL_PORTS), or the following + * problem occurs. + * + * It seems that an attempt by the server to connect to a port which has + * been used recently by a listen on the same socket, or by another + * socket this or another process causes a hangup of (almost exactly) + * one minute. Therefore, we have to use a rotating port number. + * The problem remains that if the application is run twice in quick + * succession, it will hang for what remains of a minute. + * + * Authors + * TBL Tim Berners-lee <timbl@info.cern.ch> + * DD Denis DeLaRoca 310 825-4580 <CSP1DWD@mvs.oac.ucla.edu> + * LM Lou Montulli <montulli@ukanaix.cc.ukans.edu> + * FM Foteos Macrides <macrides@sci.wfeb.edu> + * History: + * 2 May 91 Written TBL, as a part of the WorldWideWeb project. + * 15 Jan 92 Bug fix: close() was used for NETCLOSE for control soc + * 10 Feb 92 Retry if cached connection times out or breaks + * 8 Dec 92 Bug fix 921208 TBL after DD + * 17 Dec 92 Anon FTP password now just WWWuser@ suggested by DD + * fails on princeton.edu! + * 27 Dec 93 (FM) Fixed up so FTP now works with VMS hosts. Path + * must be Unix-style and cannot include the device + * or top directory. + * ?? ??? ?? (LM) Added code to prompt and send passwords for non + * anonymous FTP + * 25 Mar 94 (LM) Added code to recognize different ftp server types + * and code to parse dates and sizes on most hosts. + * 27 Mar 93 (FM) Added code for getting dates and sizes on VMS hosts. + * + * Notes: + * Portions Copyright 1994 Trustees of Dartmouth College + * Code for recognizing different FTP servers and + * parsing "ls -l" output taken from Macintosh Fetch + * program with permission from Jim Matthews, + * Dartmouth Software Development Team. + */ /* -BUGS: @@@ Limit connection cache size! - Error reporting to user. - 400 & 500 errors are ack'ed by user with windows. - Use configuration file for user names - -** Note for portability this version does not use select() and -** so does not watch the control and data channels at the -** same time. -*/ + * BUGS: @@@ Limit connection cache size! + * Error reporting to user. + * 400 & 500 errors are ack'ed by user with windows. + * Use configuration file for user names + * + * Note for portability this version does not use select() and + * so does not watch the control and data channels at the + * same time. + */ #include <HTUtils.h> #include <HTAlert.h> -#include <HTFTP.h> /* Implemented here */ +#include <HTFTP.h> /* Implemented here */ #include <HTTCP.h> #include <HTTP.h> #include <HTFont.h> -#define REPEAT_PORT /* Give the port number for each file */ -#define REPEAT_LISTEN /* Close each listen socket and open a new one */ +#define REPEAT_PORT /* Give the port number for each file */ +#define REPEAT_LISTEN /* Close each listen socket and open a new one */ /* define POLL_PORTS If allocation does not work, poll ourselves.*/ -#define LISTEN_BACKLOG 2 /* Number of pending connect requests (TCP)*/ +#define LISTEN_BACKLOG 2 /* Number of pending connect requests (TCP) */ #define FIRST_TCP_PORT 1024 /* Region to try for a listening port */ #define LAST_TCP_PORT 5999 @@ -79,7 +79,7 @@ BUGS: @@@ Limit connection cache size! #include <HTParse.h> #include <HTAnchor.h> -#include <HTFile.h> /* For HTFileFormat() */ +#include <HTFile.h> /* For HTFileFormat() */ #include <HTBTree.h> #include <HTChunk.h> #ifndef IPPORT_FTP @@ -92,16 +92,59 @@ BUGS: @@@ Limit connection cache size! #include <LYLeaks.h> typedef struct _connection { - struct _connection * next; /* Link on list */ - unsigned long addr; /* IP address */ - int socket; /* Socket number for communication */ - BOOL binary; /* Binary mode? */ + struct _connection *next; /* Link on list */ + unsigned long addr; /* IP address */ + int socket; /* Socket number for communication */ + BOOL binary; /* Binary mode? */ } connection; /* Hypertext object building machinery */ #include <HTML.h> +/* + * socklen_t is the standard, but there are many pre-standard variants. + * This ifdef works around a few of those cases. + * + * Information was obtained from header files on these platforms: + * AIX 4.3.2, 5.1 + * HPUX 10.20, 11.00, 11.11 + * IRIX64 6.5 + * Tru64 4.0G, 4.0D, 5.1 + */ +#if defined(SYS_IRIX64) + /* IRIX64 6.5 socket.h may use socklen_t if SGI_SOURCE is not defined */ +# if _NO_XOPEN4 && _NO_XOPEN5 +# define LY_SOCKLEN socklen_t +# elif _ABIAPI +# define LY_SOCKLEN int +# elif _XOPEN5 +# if (_MIPS_SIM != _ABIO32) +# define LY_SOCKLEN socklen_t +# else +# define LY_SOCKLEN int +# endif +# else +# define LY_SOCKLEN size_t +# endif +#elif defined(SYS_HPUX) +# if defined(_XOPEN_SOURCE_EXTENDED) && defined(SO_PROTOTYPE) +# define LY_SOCKLEN socklen_t +# else /* HPUX 10.20, etc. */ +# define LY_SOCKLEN int +# endif +#elif defined(SYS_TRU64) +# if defined(_POSIX_PII_SOCKET) +# define LY_SOCKLEN socklen_t +# elif defined(_XOPEN_SOURCE_EXTENDED) +# define LY_SOCKLEN size_t +# else +# define LY_SOCKLEN int +# endif +#else +# define LY_SOCKLEN socklen_t +#endif + #define PUTC(c) (*targetClass.put_character) (target, c) #define PUTS(s) (*targetClass.put_string) (target, s) #define START(e) (*targetClass.start_element) (target, e, 0, 0, -1, 0) @@ -110,30 +153,30 @@ typedef struct _connection { #define ABORT_TARGET (*targetClass._free) (target) struct _HTStructured { - CONST HTStructuredClass * isa; - /* ... */ + const HTStructuredClass *isa; + /* ... */ }; /* Global Variables -** --------------------- -*/ -PUBLIC int HTfileSortMethod = FILE_BY_NAME; + * --------------------- + */ +int HTfileSortMethod = FILE_BY_NAME; -#ifndef DISABLE_FTP /*This disables everything to end-of-file */ -PRIVATE char ThisYear[8]; -PRIVATE char LastYear[8]; -PRIVATE int TheDate; -PRIVATE BOOLEAN HaveYears = FALSE; +#ifndef DISABLE_FTP /*This disables everything to end-of-file */ +static char ThisYear[8]; +static char LastYear[8]; +static int TheDate; +static BOOLEAN HaveYears = FALSE; /* Module-Wide Variables -** --------------------- -*/ -PRIVATE connection * connections = NULL;/* Linked list of connections */ -PRIVATE char response_text[LINE_LENGTH+1];/* Last response from ftp host */ -PRIVATE connection * control = NULL; /* Current connection */ -PRIVATE int data_soc = -1; /* Socket for data transfer =invalid */ -PRIVATE char *user_entered_password = NULL; -PRIVATE char *last_username_and_host = NULL; + * --------------------- + */ +static connection *connections = NULL; /* Linked list of connections */ +static char response_text[LINE_LENGTH + 1]; /* Last response from ftp host */ +static connection *control = NULL; /* Current connection */ +static int data_soc = -1; /* Socket for data transfer =invalid */ +static char *user_entered_password = NULL; +static char *last_username_and_host = NULL; /* * ProFTPD 1.2.5rc1 is known to have a broken implementation of RETR. If asked @@ -142,60 +185,66 @@ PRIVATE char *last_username_and_host = NULL; * at some point - TD 2004/1/1. */ #define BROKEN_PROFTPD 1 -PRIVATE int ProFTPD_bugs = FALSE; +static int ProFTPD_bugs = FALSE; + +/* + * wu-ftpd 2.6.2(12) is known to have a broken implementation of EPSV. The + * server will hang for a long time when we attempt to connect after issuing + * this command - TD 2004/12/28 + */ +#define BROKEN_WUFTPD 1 +static int WU_FTPD_bugs = FALSE; typedef enum { - GENERIC_SERVER - , MACHTEN_SERVER - , UNIX_SERVER - , VMS_SERVER - , CMS_SERVER - , DCTS_SERVER - , TCPC_SERVER - , PETER_LEWIS_SERVER - , NCSA_SERVER - , WINDOWS_NT_SERVER - , WINDOWS_2K_SERVER - , MS_WINDOWS_SERVER - , MSDOS_SERVER - , APPLESHARE_SERVER - , NETPRESENZ_SERVER - , DLS_SERVER + GENERIC_SERVER + ,MACHTEN_SERVER + ,UNIX_SERVER + ,VMS_SERVER + ,CMS_SERVER + ,DCTS_SERVER + ,TCPC_SERVER + ,PETER_LEWIS_SERVER + ,NCSA_SERVER + ,WINDOWS_NT_SERVER + ,WINDOWS_2K_SERVER + ,MS_WINDOWS_SERVER + ,MSDOS_SERVER + ,APPLESHARE_SERVER + ,NETPRESENZ_SERVER + ,DLS_SERVER } eServerType; -PRIVATE eServerType server_type = GENERIC_SERVER; /* the type of ftp host */ -PRIVATE int unsure_type = FALSE; /* sure about the type? */ -PRIVATE BOOLEAN use_list = FALSE; /* use the LIST command? */ +static eServerType server_type = GENERIC_SERVER; /* the type of ftp host */ +static int unsure_type = FALSE; /* sure about the type? */ +static BOOLEAN use_list = FALSE; /* use the LIST command? */ -PRIVATE int interrupted_in_next_data_char = FALSE; +static int interrupted_in_next_data_char = FALSE; #ifdef POLL_PORTS -PRIVATE PortNumber port_number = FIRST_TCP_PORT; +static PortNumber port_number = FIRST_TCP_PORT; #endif /* POLL_PORTS */ -PRIVATE int master_socket = -1; /* Listening socket = invalid */ -PRIVATE char port_command[255]; /* Command for setting the port */ -PRIVATE fd_set open_sockets; /* Mask of active channels */ -PRIVATE int num_sockets; /* Number of sockets to scan */ -PRIVATE PortNumber passive_port; /* Port server specified for data */ - +static int master_socket = -1; /* Listening socket = invalid */ +static char port_command[255]; /* Command for setting the port */ +static fd_set open_sockets; /* Mask of active channels */ +static int num_sockets; /* Number of sockets to scan */ +static PortNumber passive_port; /* Port server specified for data */ #define NEXT_CHAR HTGetCharacter() /* Use function in HTFormat.c */ #define DATA_BUFFER_SIZE 2048 -PRIVATE char data_buffer[DATA_BUFFER_SIZE]; /* Input data buffer */ -PRIVATE char * data_read_pointer; -PRIVATE char * data_write_pointer; -#define NEXT_DATA_CHAR next_data_char() -PRIVATE int close_connection PARAMS(( - connection * con)); +static char data_buffer[DATA_BUFFER_SIZE]; /* Input data buffer */ +static char *data_read_pointer; +static char *data_write_pointer; +#define NEXT_DATA_CHAR next_data_char() +static int close_connection(connection * con); #ifdef LY_FIND_LEAKS /* -** This function frees module globals. - FM -*/ -PRIVATE void free_FTPGlobals NOARGS + * This function frees module globals. - FM + */ +static void free_FTPGlobals(void) { FREE(user_entered_password); FREE(last_username_and_host); @@ -208,76 +257,76 @@ PRIVATE void free_FTPGlobals NOARGS #endif /* LY_FIND_LEAKS */ /* PUBLIC HTVMS_name() -** CONVERTS WWW name into a VMS name -** ON ENTRY: -** nn Node Name (optional) -** fn WWW file name -** -** ON EXIT: -** returns vms file specification -** -** Bug: Returns pointer to static -- non-reentrant -*/ -PUBLIC char * HTVMS_name ARGS2( - CONST char *, nn, - CONST char *, fn) + * CONVERTS WWW name into a VMS name + * ON ENTRY: + * nn Node Name (optional) + * fn WWW file name + * + * ON EXIT: + * returns vms file specification + * + * Bug: Returns pointer to static -- non-reentrant + */ +char *HTVMS_name(const char *nn, + const char *fn) { - -/* We try converting the filename into Files-11 syntax. That is, we assume -** first that the file is, like us, on a VMS node. We try remote -** (or local) DECnet access. Files-11, VMS, VAX and DECnet -** are trademarks of Digital Equipment Corporation. -** The node is assumed to be local if the hostname WITHOUT DOMAIN -** matches the local one. @@@ -*/ + /* We try converting the filename into Files-11 syntax. That is, we assume + * first that the file is, like us, on a VMS node. We try remote (or + * local) DECnet access. Files-11, VMS, VAX and DECnet are trademarks of + * Digital Equipment Corporation. The node is assumed to be local if the + * hostname WITHOUT DOMAIN matches the local one. @@@ + */ static char *vmsname; - char * filename = (char*)malloc(strlen(fn)+1); - char * nodename = (char*)malloc(strlen(nn)+2+1); /* Copies to hack */ + char *filename = (char *) malloc(strlen(fn) + 1); + char *nodename = (char *) malloc(strlen(nn) + 2 + 1); /* Copies to hack */ char *second; /* 2nd slash */ char *last; /* last slash */ - CONST char * hostname = HTHostName(); + const char *hostname = HTHostName(); if (!filename || !nodename) outofmem(__FILE__, "HTVMSname"); strcpy(filename, fn); strcpy(nodename, ""); /* On same node? Yes if node names match */ if (strncmp(nn, "localhost", 9)) { - CONST char *p; - CONST char *q; + const char *p; + const char *q; + for (p = hostname, q = nn; - *p && *p != '.' && *q && *q != '.'; p++, q++){ + *p && *p != '.' && *q && *q != '.'; p++, q++) { if (TOUPPER(*p) != TOUPPER(*q)) { char *r; + strcpy(nodename, nn); r = strchr(nodename, '.'); /* Mismatch */ if (r) - *r = '\0'; /* Chop domain */ + *r = '\0'; /* Chop domain */ strcat(nodename, "::"); /* Try decnet anyway */ break; } } } - second = strchr(filename+1, '/'); /* 2nd slash */ + second = strchr(filename + 1, '/'); /* 2nd slash */ last = strrchr(filename, '/'); /* last slash */ - if (!second) { /* Only one slash */ + if (!second) { /* Only one slash */ HTSprintf0(&vmsname, "%s%s", nodename, filename + 1); - } else if (second == last) { /* Exactly two slashes */ + } else if (second == last) { /* Exactly two slashes */ *second = '\0'; /* Split filename from disk */ - HTSprintf0(&vmsname, "%s%s:%s", nodename, filename+1, second+1); - *second = '/'; /* restore */ - } else { /* More than two slashes */ - char * p; + HTSprintf0(&vmsname, "%s%s:%s", nodename, filename + 1, second + 1); + *second = '/'; /* restore */ + } else { /* More than two slashes */ + char *p; + *second = '\0'; /* Split disk from directories */ *last = '\0'; /* Split dir from filename */ HTSprintf0(&vmsname, "%s%s:[%s]%s", - nodename, filename+1, second+1, last+1); + nodename, filename + 1, second + 1, last + 1); *second = *last = '/'; /* restore filename */ - for (p = strchr(vmsname, '['); *p!=']'; p++) + for (p = strchr(vmsname, '['); *p != ']'; p++) if (*p == '/') - *p = '.'; /* Convert dir sep. to dots */ + *p = '.'; /* Convert dir sep. to dots */ } FREE(nodename); FREE(filename); @@ -285,23 +334,25 @@ PUBLIC char * HTVMS_name ARGS2( } /* Procedure: Read a character from the data connection -** ---------------------------------------------------- -*/ -PRIVATE int next_data_char NOARGS + * ---------------------------------------------------- + */ +static int next_data_char(void) { int status; + if (data_read_pointer >= data_write_pointer) { status = NETREAD(data_soc, data_buffer, DATA_BUFFER_SIZE); - if (status == HT_INTERRUPTED) - interrupted_in_next_data_char = 1; - if (status <= 0) - return -1; - data_write_pointer = data_buffer + status; - data_read_pointer = data_buffer; + if (status == HT_INTERRUPTED) + interrupted_in_next_data_char = 1; + if (status <= 0) + return -1; + data_write_pointer = data_buffer + status; + data_read_pointer = data_buffer; } #ifdef NOT_ASCII { char c = *data_read_pointer++; + return FROMASCII(c); } #else @@ -309,15 +360,14 @@ PRIVATE int next_data_char NOARGS #endif /* NOT_ASCII */ } - /* Close an individual connection -** -*/ -PRIVATE int close_connection ARGS1( - connection *, con) + * + */ +static int close_connection(connection * con) { - connection * scan; + connection *scan; int status; + CTRACE((tfp, "HTFTP: Closing control socket %d\n", con->socket)); status = NETCLOSE(con->socket); if (TRACE && status != 0) { @@ -337,82 +387,82 @@ PRIVATE int close_connection ARGS1( if (scan->next == con) { scan->next = con->next; /* Unlink */ if (control == con) - control = (connection*)0; + control = (connection *) 0; return status; - } /*if */ - } /* for */ - return -1; /* very strange -- was not on list. */ + } /*if */ + } /* for */ + return -1; /* very strange -- was not on list. */ } -PRIVATE char *help_message_buffer = NULL; /* global :( */ +static char *help_message_buffer = NULL; /* global :( */ -PRIVATE void init_help_message_cache NOARGS +static void init_help_message_cache(void) { FREE(help_message_buffer); } -PRIVATE void help_message_cache_add ARGS1( - char *, string) +static void help_message_cache_add(char *string) { if (help_message_buffer) StrAllocCat(help_message_buffer, string); else StrAllocCopy(help_message_buffer, string); - CTRACE((tfp,"Adding message to help cache: %s\n",string)); + CTRACE((tfp, "Adding message to help cache: %s\n", string)); } -PRIVATE char *help_message_cache_non_empty NOARGS +static char *help_message_cache_non_empty(void) { - return(help_message_buffer); + return (help_message_buffer); } -PRIVATE char *help_message_cache_contents NOARGS +static char *help_message_cache_contents(void) { - return(help_message_buffer); + return (help_message_buffer); } /* Send One Command -** ---------------- -** -** This function checks whether we have a control connection, and sends -** one command if given. -** -** On entry, -** control points to the connection which is established. -** cmd points to a command, or is zero to just get the response. -** -** The command should already be terminated with the CRLF pair. -** -** On exit, -** returns: 1 for success, -** or negative for communication failure (in which case -** the control connection will be closed). -*/ -PRIVATE int write_cmd ARGS1( - char *, cmd) + * ---------------- + * + * This function checks whether we have a control connection, and sends + * one command if given. + * + * On entry, + * control points to the connection which is established. + * cmd points to a command, or is zero to just get the response. + * + * The command should already be terminated with the CRLF pair. + * + * On exit, + * returns: 1 for success, + * or negative for communication failure (in which case + * the control connection will be closed). + */ +static int write_cmd(const char *cmd) { int status; if (!control) { CTRACE((tfp, "HTFTP: No control connection set up!!\n")); - return -99; + return HT_NO_CONNECTION; } if (cmd) { CTRACE((tfp, " Tx: %s", cmd)); #ifdef NOT_ASCII { - char * p; + char *p; + for (p = cmd; *p; p++) { *p = TOASCII(*p); } } #endif /* NOT_ASCII */ - status = NETWRITE(control->socket, cmd, (int)strlen(cmd)); + status = NETWRITE(control->socket, cmd, (int) strlen(cmd)); if (status < 0) { - CTRACE((tfp, "HTFTP: Error %d sending command: closing socket %d\n", - status, control->socket)); + CTRACE((tfp, + "HTFTP: Error %d sending command: closing socket %d\n", + status, control->socket)); close_connection(control); return status; } @@ -421,30 +471,29 @@ PRIVATE int write_cmd ARGS1( } /* Execute Command and get Response -** -------------------------------- -** -** See the state machine illustrated in RFC959, p57. This implements -** one command/reply sequence. It also interprets lines which are to -** be continued, which are marked with a "-" immediately after the -** status code. -** -** Continuation then goes on until a line with a matching reply code -** an a space after it. -** -** On entry, -** control points to the connection which is established. -** cmd points to a command, or is zero to just get the response. -** -** The command must already be terminated with the CRLF pair. -** -** On exit, -** returns: The first digit of the reply type, -** or negative for communication failure. -*/ -PRIVATE int response ARGS1( - char *, cmd) + * -------------------------------- + * + * See the state machine illustrated in RFC959, p57. This implements + * one command/reply sequence. It also interprets lines which are to + * be continued, which are marked with a "-" immediately after the + * status code. + * + * Continuation then goes on until a line with a matching reply code + * an a space after it. + * + * On entry, + * control points to the connection which is established. + * cmd points to a command, or is zero to just get the response. + * + * The command must already be terminated with the CRLF pair. + * + * On exit, + * returns: The first digit of the reply type, + * or negative for communication failure. + */ +static int response(const char *cmd) { - int result; /* Three-digit decimal code */ + int result; /* Three-digit decimal code */ int continuation_response = -1; int status; @@ -453,37 +502,40 @@ PRIVATE int response ARGS1( do { char *p = response_text; + for (;;) { int ich = NEXT_CHAR; + if (((*p++ = (char) ich) == LF) - || (p == &response_text[LINE_LENGTH])) { + || (p == &response_text[LINE_LENGTH])) { char continuation; if (interrupted_in_htgetcharacter) { - CTRACE((tfp, "HTFTP: Interrupted in HTGetCharacter, apparently.\n")); - NETCLOSE (control->socket); + CTRACE((tfp, + "HTFTP: Interrupted in HTGetCharacter, apparently.\n")); + NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; } - *p = '\0'; /* Terminate the string */ + *p = '\0'; /* Terminate the string */ CTRACE((tfp, " Rx: %s", response_text)); /* Check for login or help messages */ - if (!strncmp(response_text,"230-",4) || - !strncmp(response_text,"250-",4) || - !strncmp(response_text,"220-",4)) - help_message_cache_add(response_text+4); + if (!strncmp(response_text, "230-", 4) || + !strncmp(response_text, "250-", 4) || + !strncmp(response_text, "220-", 4)) + help_message_cache_add(response_text + 4); sscanf(response_text, "%d%c", &result, &continuation); - if (continuation_response == -1) { - if (continuation == '-') /* start continuation */ - continuation_response = result; + if (continuation_response == -1) { + if (continuation == '-') /* start continuation */ + continuation_response = result; } else { /* continuing */ - if (continuation_response == result && - continuation == ' ') - continuation_response = -1; /* ended */ + if (continuation_response == result && + continuation == ' ') + continuation_response = -1; /* ended */ } #ifdef BROKEN_PROFTPD if (result == 220 && LYstrstr(response_text, "ProFTPD 1.2.5")) { @@ -491,30 +543,38 @@ PRIVATE int response ARGS1( CTRACE((tfp, "This server is broken (RETR)\n")); } #endif +#ifdef BROKEN_WUFTPD + if (result == 220 && LYstrstr(response_text, + "(Version wu-2.6.2-12)")) { + WU_FTPD_bugs = TRUE; + CTRACE((tfp, "This server is broken (EPSV)\n")); + } +#endif break; - } /* if end of line */ - + } + /* if end of line */ if (interrupted_in_htgetcharacter) { - CTRACE((tfp, "HTFTP: Interrupted in HTGetCharacter, apparently.\n")); - NETCLOSE (control->socket); + CTRACE((tfp, + "HTFTP: Interrupted in HTGetCharacter, apparently.\n")); + NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; } if (ich == EOF) { CTRACE((tfp, "Error on rx: closing socket %d\n", - control->socket)); + control->socket)); strcpy(response_text, "000 *** TCP read error on response\n"); close_connection(control); return -1; /* End of file on response */ } - } /* Loop over characters */ + } /* Loop over characters */ } while (continuation_response != -1); if (result == 421) { CTRACE((tfp, "HTFTP: They close so we close socket %d\n", - control->socket)); + control->socket)); close_connection(control); return -1; } @@ -522,28 +582,28 @@ PRIVATE int response ARGS1( (0 == strncasecomp(cmd, "CWD", 3) || 0 == strcasecomp(cmd, "CDUP"))) { /* - ** Alas, CMS returns 255 on failure to CWD to parent of root. - PG - */ + * Alas, CMS returns 255 on failure to CWD to parent of root. - PG + */ result = 555; } - return result/100; + return result / 100; } -PRIVATE int send_cmd_1 ARGS1(char *, verb) +static int send_cmd_1(const char *verb) { char command[80]; - sprintf(command, "%.*s%c%c", (int) sizeof(command)-4, verb, CR, LF); - return response (command); + sprintf(command, "%.*s%c%c", (int) sizeof(command) - 4, verb, CR, LF); + return response(command); } -PRIVATE int send_cmd_2 ARGS2(char *, verb, char *, param) +static int send_cmd_2(const char *verb, const char *param) { char *command = 0; int status; HTSprintf0(&command, "%s %s%c%c", verb, param, CR, LF); - status = response (command); + status = response(command); FREE(command); return status; @@ -552,21 +612,20 @@ PRIVATE int send_cmd_2 ARGS2(char *, verb, char *, param) #define send_cwd(path) send_cmd_2("CWD", path) /* - * This function should try to set the macintosh server into binary mode. - * Some servers need an additional letter after the MACB command. + * This function should try to set the macintosh server into binary mode. Some + * servers need an additional letter after the MACB command. */ -PRIVATE int set_mac_binary ARGS1( - eServerType, ServerType) +static int set_mac_binary(eServerType ServerType) { /* try to set mac binary mode */ if (ServerType == APPLESHARE_SERVER || ServerType == NETPRESENZ_SERVER) { /* - * Presumably E means "Enable". - KW + * Presumably E means "Enable". - KW */ - return(2 == response("MACB E\r\n")); + return (2 == response("MACB E\r\n")); } else { - return(2 == response("MACB\r\n")); + return (2 == response("MACB\r\n")); } } @@ -574,26 +633,25 @@ PRIVATE int set_mac_binary ARGS1( * determine what kind of host it is */ -PRIVATE void get_ftp_pwd ARGS2( - eServerType *, ServerType, - BOOLEAN *, UseList) +static void get_ftp_pwd(eServerType *ServerType, BOOLEAN *UseList) { - char *cp; + /* get the working directory (to see what it looks like) */ int status = response("PWD\r\n"); + if (status < 0) { return; } else { - cp = strchr(response_text+5,'"'); + cp = strchr(response_text + 5, '"'); if (cp) *cp = '\0'; if (*ServerType == TCPC_SERVER) { *ServerType = ((response_text[5] == '/') ? - NCSA_SERVER : TCPC_SERVER); + NCSA_SERVER : TCPC_SERVER); CTRACE((tfp, "HTFTP: Treating as %s server.\n", - ((*ServerType == NCSA_SERVER) ? - "NCSA" : "TCPC"))); + ((*ServerType == NCSA_SERVER) ? + "NCSA" : "TCPC"))); } else if (response_text[5] == '/') { /* path names beginning with / imply Unix, * right? @@ -602,12 +660,12 @@ PRIVATE void get_ftp_pwd ARGS2( *ServerType = NCSA_SERVER; CTRACE((tfp, "HTFTP: Treating as NCSA server.\n")); } else { - *ServerType = UNIX_SERVER; - *UseList = TRUE; - CTRACE((tfp, "HTFTP: Treating as Unix server.\n")); + *ServerType = UNIX_SERVER; + *UseList = TRUE; + CTRACE((tfp, "HTFTP: Treating as Unix server.\n")); } return; - } else if (response_text[strlen(response_text)-1] == ']') { + } else if (response_text[strlen(response_text) - 1] == ']') { /* path names ending with ] imply VMS, right? */ *ServerType = VMS_SERVER; *UseList = TRUE; @@ -629,17 +687,16 @@ PRIVATE void get_ftp_pwd ARGS2( * Windows NT servers. */ -PRIVATE void set_unix_dirstyle ARGS2( - eServerType *, ServerType, - BOOLEAN *, UseList) +static void set_unix_dirstyle(eServerType *ServerType, BOOLEAN *UseList) { - char *cp; + /* This is a toggle. It seems we have to toggle in order to see * the current state (after toggling), so we may end up toggling * twice. - kw */ int status = response("SITE DIRSTYLE\r\n"); + if (status != 2) { *ServerType = GENERIC_SERVER; CTRACE((tfp, "HTFTP: DIRSTYLE failed, treating as Generic server.\n")); @@ -655,7 +712,7 @@ PRIVATE void set_unix_dirstyle ARGS2( * anyway, under the assumption that it's more likely that * the MSDOS setting was "off" originally. - kw */ - cp = strstr(response_text+4, "MSDOS"); + cp = strstr(response_text + 4, "MSDOS"); if (cp && strstr(cp, " off")) { return; /* already off now. */ } else { @@ -665,35 +722,34 @@ PRIVATE void set_unix_dirstyle ARGS2( } /* Get a valid connection to the host -** ---------------------------------- -** -** On entry, -** arg points to the name of the host in a hypertext address -** On exit, -** returns <0 if error -** socket number if success -** -** This routine takes care of managing timed-out connections, and -** limiting the number of connections in use at any one time. -** -** It ensures that all connections are logged in if they exist. -** It ensures they have the port number transferred. -*/ -PRIVATE int get_connection ARGS2( - CONST char *, arg, - HTParentAnchor *, anchor) + * ---------------------------------- + * + * On entry, + * arg points to the name of the host in a hypertext address + * On exit, + * returns <0 if error + * socket number if success + * + * This routine takes care of managing timed-out connections, and + * limiting the number of connections in use at any one time. + * + * It ensures that all connections are logged in if they exist. + * It ensures they have the port number transferred. + */ +static int get_connection(const char *arg, + HTParentAnchor *anchor) { int status; - char * command = 0; - connection * con; - char * username = NULL; - char * password = NULL; + char *command = 0; + connection *con; + char *username = NULL; + char *password = NULL; static BOOLEAN firstuse = TRUE; if (firstuse) { /* - ** Set up freeing at exit. - FM - */ + * Set up freeing at exit. - FM + */ #ifdef LY_FIND_LEAKS atexit(free_FTPGlobals); #endif @@ -702,8 +758,8 @@ PRIVATE int get_connection ARGS2( if (control) { /* - ** Reuse this object - KW, DW & FM - */ + * Reuse this object - KW, DW & FM + */ if (control->socket != -1) { NETCLOSE(control->socket); } @@ -712,16 +768,18 @@ PRIVATE int get_connection ARGS2( con->binary = FALSE; } else { /* - ** Allocate and init control struct. - */ + * Allocate and init control struct. + */ con = typecalloc(connection); if (con == NULL) outofmem(__FILE__, "get_connection"); } con->socket = -1; - if (!arg) return -1; /* Bad if no name specified */ - if (!*arg) return -1; /* Bad if name had zero length */ + if (!arg) + return -1; /* Bad if no name specified */ + if (!*arg) + return -1; /* Bad if name had zero length */ /* Get node name: */ @@ -729,12 +787,12 @@ PRIVATE int get_connection ARGS2( { char *p1 = HTParse(arg, "", PARSE_HOST); char *p2 = strrchr(p1, '@'); /* user? */ - char * pw = NULL; + char *pw = NULL; if (p2 != NULL) { username = p1; - *p2 = '\0'; /* terminate */ - p1 = p2+1; /* point to host */ + *p2 = '\0'; /* terminate */ + p1 = p2 + 1; /* point to host */ pw = strchr(username, ':'); if (pw != NULL) { *pw++ = '\0'; @@ -744,19 +802,18 @@ PRIVATE int get_connection ARGS2( HTUnEscape(username); /* - * If the password doesn't exist then we are going to have - * to ask the user for it. The only problem is that we - * don't want to ask for it every time, so we will store - * away in a primitive fashion. + * If the password doesn't exist then we are going to have to ask + * the user for it. The only problem is that we don't want to ask + * for it every time, so we will store away in a primitive fashion. */ if (!password) { char *tmp = NULL; HTSprintf0(&tmp, "%s@%s", username, p1); /* - * If the user@host is not equal to the last time through - * or user_entered_password has no data then we need - * to ask the user for the password. + * If the user@host is not equal to the last time through or + * user_entered_password has no data then we need to ask the + * user for the password. */ if (!last_username_and_host || strcmp(tmp, last_username_and_host) || @@ -764,11 +821,11 @@ PRIVATE int get_connection ARGS2( StrAllocCopy(last_username_and_host, tmp); HTSprintf0(&tmp, gettext("Enter password for user %s@%s:"), - username, p1); + username, p1); FREE(user_entered_password); user_entered_password = HTPromptPassword(tmp); - } /* else we already know the password */ + } /* else we already know the password */ password = user_entered_password; FREE(tmp); } @@ -776,51 +833,49 @@ PRIVATE int get_connection ARGS2( if (!username) FREE(p1); - } /* scope of p1 */ + } /* scope of p1 */ - status = HTDoConnect (arg, "FTP", IPPORT_FTP, (int *)&con->socket); + status = HTDoConnect(arg, "FTP", IPPORT_FTP, (int *) &con->socket); if (status < 0) { if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted on connect\n")); } else { CTRACE((tfp, "HTFTP: Unable to connect to remote host for `%s'.\n", - arg)); + arg)); } if (status == HT_INTERRUPTED) { - _HTProgress (CONNECTION_INTERRUPTED); + _HTProgress(CONNECTION_INTERRUPTED); status = HT_NOT_LOADED; } else { HTAlert(gettext("Unable to connect to FTP host.")); } - if (con->socket != -1) - { - NETCLOSE(con->socket); + if (con->socket != -1) { + NETCLOSE(con->socket); } FREE(username); if (control == con) control = NULL; FREE(con); - return status; /* Bad return */ + return status; /* Bad return */ } CTRACE((tfp, "FTP connected, socket %d control %p\n", - con->socket, con)); + con->socket, con)); control = con; /* Current control connection */ /* Initialise buffering for control connection */ HTInitInput(control->socket); init_help_message_cache(); /* Clear the login message buffer. */ - /* Now we log in Look up username, prompt for pw. */ - status = response((char *)0); /* Get greeting */ + status = response((char *) 0); /* Get greeting */ if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted at beginning of login.\n")); - _HTProgress (CONNECTION_INTERRUPTED); + _HTProgress(CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; @@ -849,7 +904,7 @@ PRIVATE int get_connection ARGS2( if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted while sending username.\n")); - _HTProgress (CONNECTION_INTERRUPTED); + _HTProgress(CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; @@ -865,30 +920,27 @@ PRIVATE int get_connection ARGS2( /* * Create and send a mail address as the password. - FM */ + char *the_address; char *user = NULL; - CONST char *host = NULL; - char * cp; - - if (personal_mail_address && *personal_mail_address) { - /* - * We have a non-zero length personal - * mail address, so use that. - FM - */ - StrAllocCopy(user, personal_mail_address); - if ((cp=strchr(user, '@')) != NULL) { - *cp++ = '\0'; - host = cp; - } else { + const char *host = NULL; + char *cp; + + the_address = anonftp_password; + if (isEmpty(the_address)) + the_address = personal_mail_address; + if (isEmpty(the_address)) + the_address = LYGetEnv("USER"); + if (isEmpty(the_address)) + the_address = "WWWuser"; + + StrAllocCopy(user, the_address); + if ((cp = strchr(user, '@')) != NULL) { + *cp++ = '\0'; + if (*cp == '\0') host = HTHostName(); - } - } else { - /* - * Use an environment variable and the host global. - FM - */ - if ((cp=LYGetEnv("USER")) != NULL) - StrAllocCopy(user, cp); else - StrAllocCopy(user, "WWWuser"); + host = cp; + } else { host = HTHostName(); } @@ -906,7 +958,7 @@ PRIVATE int get_connection ARGS2( FREE(command); if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted while sending password.\n")); - _HTProgress (CONNECTION_INTERRUPTED); + _HTProgress(CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; @@ -918,7 +970,7 @@ PRIVATE int get_connection ARGS2( status = send_cmd_1("ACCT noaccount"); if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted while sending password.\n")); - _HTProgress (CONNECTION_INTERRUPTED); + _HTProgress(CONNECTION_INTERRUPTED); NETCLOSE(control->socket); control->socket = -1; return HT_INTERRUPTED; @@ -932,36 +984,37 @@ PRIVATE int get_connection ARGS2( } CTRACE((tfp, "HTFTP: Logged in.\n")); - /** Check for host type **/ + /* Check for host type */ if (server_type != NETPRESENZ_SERVER) server_type = GENERIC_SERVER; /* reset */ - use_list = FALSE; /* reset */ - if ((status=response("SYST\r\n")) == 2) { + use_list = FALSE; /* reset */ + if ((status = response("SYST\r\n")) == 2) { /* we got a line -- what kind of server are we talking to? */ - if (strncmp(response_text+4, + if (strncmp(response_text + 4, "UNIX Type: L8 MAC-OS MachTen", 28) == 0) { server_type = MACHTEN_SERVER; use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as MachTen server.\n")); - } else if (strstr(response_text+4, "UNIX") != NULL || - strstr(response_text+4, "Unix") != NULL) { + } else if (strstr(response_text + 4, "UNIX") != NULL || + strstr(response_text + 4, "Unix") != NULL) { server_type = UNIX_SERVER; - unsure_type = FALSE; /* to the best of out knowledge... */ + unsure_type = FALSE; /* to the best of out knowledge... */ use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as Unix server.\n")); - } else if (strstr(response_text+4, "MSDOS") != NULL) { + } else if (strstr(response_text + 4, "MSDOS") != NULL) { server_type = MSDOS_SERVER; use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as MSDOS (Unix emulation) server.\n")); - } else if (strncmp(response_text+4, "VMS", 3) == 0) { + } else if (strncmp(response_text + 4, "VMS", 3) == 0) { char *tilde = strstr(arg, "/~"); + use_list = TRUE; if (tilde != 0 - && tilde[2] != 0 - && strstr(response_text+4, "MadGoat") != 0) { + && tilde[2] != 0 + && strstr(response_text + 4, "MadGoat") != 0) { server_type = UNIX_SERVER; CTRACE((tfp, "HTFTP: Treating VMS as UNIX server.\n")); } else { @@ -969,64 +1022,64 @@ PRIVATE int get_connection ARGS2( CTRACE((tfp, "HTFTP: Treating as VMS server.\n")); } - } else if ((strncmp(response_text+4, "VM/CMS", 6) == 0) || - (strncmp(response_text+4, "VM ", 3) == 0)) { + } else if ((strncmp(response_text + 4, "VM/CMS", 6) == 0) || + (strncmp(response_text + 4, "VM ", 3) == 0)) { server_type = CMS_SERVER; use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as CMS server.\n")); - } else if (strncmp(response_text+4, "DCTS", 4) == 0) { + } else if (strncmp(response_text + 4, "DCTS", 4) == 0) { server_type = DCTS_SERVER; CTRACE((tfp, "HTFTP: Treating as DCTS server.\n")); - } else if (strstr(response_text+4, "MAC-OS TCP/Connect II") != NULL) { + } else if (strstr(response_text + 4, "MAC-OS TCP/Connect II") != NULL) { server_type = TCPC_SERVER; CTRACE((tfp, "HTFTP: Looks like a TCPC server.\n")); get_ftp_pwd(&server_type, &use_list); unsure_type = TRUE; - } else if (server_type == NETPRESENZ_SERVER) { /* already set above */ + } else if (server_type == NETPRESENZ_SERVER) { /* already set above */ use_list = TRUE; set_mac_binary(server_type); CTRACE((tfp, "HTFTP: Treating as NetPresenz (MACOS) server.\n")); - } else if (strncmp(response_text+4, "MACOS Peter's Server", 20) == 0) { + } else if (strncmp(response_text + 4, "MACOS Peter's Server", 20) == 0) { server_type = PETER_LEWIS_SERVER; use_list = TRUE; set_mac_binary(server_type); CTRACE((tfp, "HTFTP: Treating as Peter Lewis (MACOS) server.\n")); - } else if (strncmp(response_text+4, "Windows_NT", 10) == 0) { + } else if (strncmp(response_text + 4, "Windows_NT", 10) == 0) { server_type = WINDOWS_NT_SERVER; CTRACE((tfp, "HTFTP: Treating as Window_NT server.\n")); set_unix_dirstyle(&server_type, &use_list); - } else if (strncmp(response_text+4, "Windows2000", 11) == 0) { + } else if (strncmp(response_text + 4, "Windows2000", 11) == 0) { server_type = WINDOWS_2K_SERVER; CTRACE((tfp, "HTFTP: Treating as Window_2K server.\n")); set_unix_dirstyle(&server_type, &use_list); - } else if (strncmp(response_text+4, "MS Windows", 10) == 0) { + } else if (strncmp(response_text + 4, "MS Windows", 10) == 0) { server_type = MS_WINDOWS_SERVER; use_list = TRUE; CTRACE((tfp, "HTFTP: Treating as MS Windows server.\n")); - } else if (strncmp(response_text+4, + } else if (strncmp(response_text + 4, "MACOS AppleShare IP FTP Server", 30) == 0) { server_type = APPLESHARE_SERVER; use_list = TRUE; set_mac_binary(server_type); CTRACE((tfp, "HTFTP: Treating as AppleShare server.\n")); - } else { + } else { server_type = GENERIC_SERVER; CTRACE((tfp, "HTFTP: Ugh! A Generic server.\n")); get_ftp_pwd(&server_type, &use_list); unsure_type = TRUE; - } + } } else { /* SYST fails :( try to get the type from the PWD command */ - get_ftp_pwd(&server_type, &use_list); + get_ftp_pwd(&server_type, &use_list); } /* Now we inform the server of the port number we will listen on @@ -1034,24 +1087,24 @@ PRIVATE int get_connection ARGS2( #ifdef NOTREPEAT_PORT { int status = response(port_command); + if (status != 2) { if (control->socket) close_connection(control->socket); - return -status; /* Bad return */ + return -status; /* Bad return */ } CTRACE((tfp, "HTFTP: Port defined.\n")); } #endif /* NOTREPEAT_PORT */ - return con->socket; /* Good return */ + return con->socket; /* Good return */ } - /* Close Master (listening) socket -** ------------------------------- -** -** -*/ -PRIVATE int close_master_socket NOARGS + * ------------------------------- + * + * + */ +static int close_master_socket(void) { int status; @@ -1066,51 +1119,50 @@ PRIVATE int close_master_socket NOARGS return status; } - /* Open a master socket for listening on -** ------------------------------------- -** -** When data is transferred, we open a port, and wait for the server to -** connect with the data. -** -** On entry, -** master_socket Must be negative if not set up already. -** On exit, -** Returns socket number if good -** less than zero if error. -** master_socket is socket number if good, else negative. -** port_number is valid if good. -*/ -PRIVATE int get_listen_socket NOARGS + * ------------------------------------- + * + * When data is transferred, we open a port, and wait for the server to + * connect with the data. + * + * On entry, + * master_socket Must be negative if not set up already. + * On exit, + * Returns socket number if good + * less than zero if error. + * master_socket is socket number if good, else negative. + * port_number is valid if good. + */ +static int get_listen_socket(void) { #ifdef INET6 struct sockaddr_storage soc_address; /* Binary network address */ - struct sockaddr_in* soc_in = (struct sockaddr_in *)&soc_address; + struct sockaddr_in *soc_in = (struct sockaddr_in *) &soc_address; int af; - int slen; + LY_SOCKLEN slen; + #else struct sockaddr_in soc_address; /* Binary network address */ - struct sockaddr_in* soc_in = &soc_address; + struct sockaddr_in *soc_in = &soc_address; #endif /* INET6 */ - int new_socket; /* Will be master_socket */ - + int new_socket; /* Will be master_socket */ FD_ZERO(&open_sockets); /* Clear our record of open sockets */ num_sockets = 0; #ifndef REPEAT_LISTEN if (master_socket >= 0) - return master_socket; /* Done already */ + return master_socket; /* Done already */ #endif /* !REPEAT_LISTEN */ #ifdef INET6 /* query address family of control connection */ slen = sizeof(soc_address); - if (getsockname(control->socket, (struct sockaddr *)&soc_address, - &slen) < 0) { + if (getsockname(control->socket, (struct sockaddr *) &soc_address, + &slen) < 0) { return HTInetStatus("getsockname failed"); } - af = ((struct sockaddr *)&soc_address)->sa_family; + af = ((struct sockaddr *) &soc_address)->sa_family; memset(&soc_address, 0, sizeof(soc_address)); #endif /* INET6 */ @@ -1131,30 +1183,32 @@ PRIVATE int get_listen_socket NOARGS */ #ifdef INET6 memset(&soc_address, 0, sizeof(soc_address)); - ((struct sockaddr *)&soc_address)->sa_family = af; + ((struct sockaddr *) &soc_address)->sa_family = af; switch (af) { case AF_INET: #ifdef SIN6_LEN - ((struct sockaddr *)&soc_address)->sa_len = sizeof(struct sockaddr_in); + ((struct sockaddr *) &soc_address)->sa_len = sizeof(struct sockaddr_in); #endif /* SIN6_LEN */ break; case AF_INET6: #ifdef SIN6_LEN - ((struct sockaddr *)&soc_address)->sa_len = sizeof(struct sockaddr_in6); + ((struct sockaddr *) &soc_address)->sa_len = sizeof(struct sockaddr_in6); #endif /* SIN6_LEN */ break; default: HTInetStatus("AF"); } #else - soc_in->sin_family = AF_INET; /* Family = internet, host order */ - soc_in->sin_addr.s_addr = INADDR_ANY; /* Any peer address */ + soc_in->sin_family = AF_INET; /* Family = internet, host order */ + soc_in->sin_addr.s_addr = INADDR_ANY; /* Any peer address */ #endif /* INET6 */ #ifdef POLL_PORTS { PortNumber old_port_number = port_number; - for (port_number = (old_port_number+1); ; port_number++) { + + for (port_number = (old_port_number + 1);; port_number++) { int status; + if (port_number > LAST_TCP_PORT) port_number = FIRST_TCP_PORT; if (port_number == old_port_number) { @@ -1167,100 +1221,100 @@ PRIVATE int get_listen_socket NOARGS #endif /* INET6 */ #ifdef SOCKS if (socks_flag) - if ((status=Rbind(new_socket, - (struct sockaddr*)&soc_address, - /* Cast to generic sockaddr */ - SOCKADDR_LEN(soc_address) + if ((status = Rbind(new_socket, + (struct sockaddr *) &soc_address, + /* Cast to generic sockaddr */ + SOCKADDR_LEN(soc_address) #ifndef SHORTENED_RBIND - ,socks_bind_remoteAddr + ,socks_bind_remoteAddr #endif /* !SHORTENED_RBIND */ - )) == 0) { + )) == 0) { break; } else #endif /* SOCKS */ - if ((status=bind(new_socket, - (struct sockaddr*)&soc_address, - /* Cast to generic sockaddr */ - SOCKADDR_LEN(soc_address) - )) == 0) { - break; - } + if ((status = bind(new_socket, + (struct sockaddr *) &soc_address, + /* Cast to generic sockaddr */ + SOCKADDR_LEN(soc_address) + )) == 0) { + break; + } CTRACE((tfp, "TCP bind attempt to port %d yields %d, errno=%d\n", - port_number, status, SOCKET_ERRNO)); - } /* for */ + port_number, status, SOCKET_ERRNO)); + } /* for */ } #else { int status; - int address_length = sizeof(soc_address); + LY_SOCKLEN address_length = sizeof(soc_address); + #ifdef SOCKS if (socks_flag) status = Rgetsockname(control->socket, - (struct sockaddr *)&soc_address, - (void *)&address_length); + (struct sockaddr *) &soc_address, + &address_length); else #endif /* SOCKS */ - status = getsockname(control->socket, - (struct sockaddr *)&soc_address, - (void *)&address_length); - if (status<0) return HTInetStatus("getsockname"); + status = getsockname(control->socket, + (struct sockaddr *) &soc_address, + &address_length); + if (status < 0) + return HTInetStatus("getsockname"); #ifdef INET6 CTRACE((tfp, "HTFTP: This host is %s\n", - HTInetString((SockA *)soc_in))); + HTInetString((SockA *) soc_in))); soc_in->sin_port = 0; /* Unspecified: please allocate */ #else CTRACE((tfp, "HTFTP: This host is %s\n", - HTInetString(soc_in))); + HTInetString(soc_in))); soc_address.sin_port = 0; /* Unspecified: please allocate */ #endif /* INET6 */ #ifdef SOCKS if (socks_flag) - status=Rbind(new_socket, - (struct sockaddr*)&soc_address, - /* Cast to generic sockaddr */ - sizeof(soc_address) + status = Rbind(new_socket, + (struct sockaddr *) &soc_address, + /* Cast to generic sockaddr */ + sizeof(soc_address) #ifndef SHORTENED_RBIND -#ifdef INET6 - socks_bind_remoteAddr -#else - ,socks_bind_remoteAddr -#endif /* INET6 */ + ,socks_bind_remoteAddr #endif /* !SHORTENED_RBIND */ - ); + ); else #endif /* SOCKS */ - status=bind(new_socket, - (struct sockaddr*)&soc_address, - /* Cast to generic sockaddr */ - SOCKADDR_LEN(soc_address) - ); - if (status<0) return HTInetStatus("bind"); + status = bind(new_socket, + (struct sockaddr *) &soc_address, + /* Cast to generic sockaddr */ + SOCKADDR_LEN(soc_address) + ); + if (status < 0) + return HTInetStatus("bind"); address_length = sizeof(soc_address); #ifdef SOCKS if (socks_flag) status = Rgetsockname(new_socket, - (struct sockaddr*)&soc_address, - (void *)&address_length); + (struct sockaddr *) &soc_address, + &address_length); else #endif /* SOCKS */ - status = getsockname(new_socket, - (struct sockaddr*)&soc_address, - (void *)&address_length); - if (status<0) return HTInetStatus("getsockname"); + status = getsockname(new_socket, + (struct sockaddr *) &soc_address, + &address_length); + if (status < 0) + return HTInetStatus("getsockname"); } #endif /* POLL_PORTS */ #ifdef INET6 CTRACE((tfp, "HTFTP: bound to port %d on %s\n", - (int)ntohs(soc_in->sin_port), - HTInetString((SockA *)soc_in))); + (int) ntohs(soc_in->sin_port), + HTInetString((SockA *) soc_in))); #else CTRACE((tfp, "HTFTP: bound to port %d on %s\n", - (int)ntohs(soc_in->sin_port), - HTInetString(soc_in))); + (int) ntohs(soc_in->sin_port), + HTInetString(soc_in))); #endif /* INET6 */ #ifdef REPEAT_LISTEN @@ -1272,45 +1326,47 @@ PRIVATE int get_listen_socket NOARGS /* Now we must find out who we are to tell the other guy */ - (void)HTHostName(); /* Make address valid - doesn't work*/ + (void) HTHostName(); /* Make address valid - doesn't work */ #ifdef INET6 - switch (((struct sockaddr *)&soc_address)->sa_family) { + switch (((struct sockaddr *) &soc_address)->sa_family) { case AF_INET: #endif /* INET6 */ sprintf(port_command, "PORT %d,%d,%d,%d,%d,%d%c%c", - (int)*((unsigned char *)(&soc_in->sin_addr)+0), - (int)*((unsigned char *)(&soc_in->sin_addr)+1), - (int)*((unsigned char *)(&soc_in->sin_addr)+2), - (int)*((unsigned char *)(&soc_in->sin_addr)+3), - (int)*((unsigned char *)(&soc_in->sin_port)+0), - (int)*((unsigned char *)(&soc_in->sin_port)+1), - CR, LF); + (int) *((unsigned char *) (&soc_in->sin_addr) + 0), + (int) *((unsigned char *) (&soc_in->sin_addr) + 1), + (int) *((unsigned char *) (&soc_in->sin_addr) + 2), + (int) *((unsigned char *) (&soc_in->sin_addr) + 3), + (int) *((unsigned char *) (&soc_in->sin_port) + 0), + (int) *((unsigned char *) (&soc_in->sin_port) + 1), + CR, LF); #ifdef INET6 break; case AF_INET6: - { - char hostbuf[MAXHOSTNAMELEN]; - char portbuf[MAXHOSTNAMELEN]; - getnameinfo((struct sockaddr *)&soc_address, - SOCKADDR_LEN(soc_address), - hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), - NI_NUMERICHOST | NI_NUMERICSERV); - sprintf(port_command, "EPRT |%d|%s|%s|%c%c", 2, hostbuf, portbuf, - CR, LF); - break; - } + { + char hostbuf[MAXHOSTNAMELEN]; + char portbuf[MAXHOSTNAMELEN]; + + getnameinfo((struct sockaddr *) &soc_address, + SOCKADDR_LEN(soc_address), + hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf), + NI_NUMERICHOST | NI_NUMERICSERV); + sprintf(port_command, "EPRT |%d|%s|%s|%c%c", 2, hostbuf, portbuf, + CR, LF); + break; + } default: sprintf(port_command, "JUNK%c%c", CR, LF); break; } #endif /* INET6 */ - /* Inform TCP that we will accept connections - */ + /* Inform TCP that we will accept connections + */ { int status; + #ifdef SOCKS if (socks_flag) status = Rlisten(master_socket, 1); @@ -1324,40 +1380,42 @@ PRIVATE int get_listen_socket NOARGS } CTRACE((tfp, "TCP: Master socket(), bind() and listen() all OK\n")); FD_SET(master_socket, &open_sockets); - if ((master_socket+1) > num_sockets) - num_sockets = master_socket+1; + if ((master_socket + 1) > num_sockets) + num_sockets = master_socket + 1; - return master_socket; /* Good */ + return master_socket; /* Good */ -} /* get_listen_socket */ +} /* get_listen_socket */ -PRIVATE char * months[12] = { - "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" +static const char *months[12] = +{ + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; /* Procedure: Set the current and last year strings and date integer -** ----------------------------------------------------------------- -** -** Bug: -** This code is for sorting listings by date, if that option -** is selected in Lynx, and doesn't take into account time -** zones or ensure resetting at midnight, so the sort may not -** be perfect, but the actual date isn't changed in the display, -** i.e., the date is still correct. - FM -*/ -PRIVATE void set_years_and_date NOARGS + * ----------------------------------------------------------------- + * + * Bug: + * This code is for sorting listings by date, if that option + * is selected in Lynx, and doesn't take into account time + * zones or ensure resetting at midnight, so the sort may not + * be perfect, but the actual date isn't changed in the display, + * i.e., the date is still correct. - FM + */ +static void set_years_and_date(void) { char day[8], month[8], date[12]; time_t NowTime; int i; NowTime = time(NULL); - strncpy(day, (char *)ctime(&NowTime)+8, 2); + strncpy(day, (char *) ctime(&NowTime) + 8, 2); day[2] = '\0'; if (day[0] == ' ') { day[0] = '0'; } - strncpy(month, (char *)ctime(&NowTime)+4, 3); + strncpy(month, (char *) ctime(&NowTime) + 4, 3); month[3] = '\0'; for (i = 0; i < 12; i++) { if (!strcasecomp(month, months[i])) { @@ -1367,29 +1425,30 @@ PRIVATE void set_years_and_date NOARGS i++; sprintf(date, "9999%02d%.2s", i, day); TheDate = atoi(date); - strcpy(ThisYear, (char *)ctime(&NowTime)+20); + strcpy(ThisYear, (char *) ctime(&NowTime) + 20); ThisYear[4] = '\0'; sprintf(LastYear, "%d", (atoi(ThisYear) - 1)); HaveYears = TRUE; } typedef struct _EntryInfo { - char * filename; - char * type; - char * date; + char *filename; + char *linkname; + char *type; + char *date; unsigned int size; - BOOLEAN display; /* show this entry? */ + BOOLEAN display; /* show this entry? */ } EntryInfo; -PRIVATE void free_entryinfo_struct_contents ARGS1( - EntryInfo *, entry_info) +static void free_entryinfo_struct_contents(EntryInfo *entry_info) { if (entry_info) { FREE(entry_info->filename); + FREE(entry_info->linkname); FREE(entry_info->type); FREE(entry_info->date); } - /* dont free the struct */ + /* dont free the struct */ } /* @@ -1400,8 +1459,7 @@ PRIVATE void free_entryinfo_struct_contents ARGS1( * "Dec 12 1989 " or * "FCv 23 1990 " ... */ -PRIVATE BOOLEAN is_ls_date ARGS1( - char *, s) +static BOOLEAN is_ls_date(char *s) { /* must start with three alpha characters */ if (!isalpha(UCH(*s++)) || !isalpha(UCH(*s++)) || !isalpha(UCH(*s++))) @@ -1463,90 +1521,91 @@ PRIVATE BOOLEAN is_ls_date ARGS1( return FALSE; return TRUE; -} /* is_ls_date() */ +} /* is_ls_date() */ /* - * parse_eplf_line() -- - * Extract the name, size, and date from an EPLF line. - 08-06-96 DJB + * Extract the name, size, and date from an EPLF line. - 08-06-96 DJB */ -PRIVATE void parse_eplf_line ARGS2( - char *, line, - EntryInfo *, info) +static void parse_eplf_line(char *line, + EntryInfo *info) { char *cp = line; char ct[26]; unsigned long size; time_t secs; - static time_t base; /* time() value on this OS in 1970 */ + static time_t base; /* time() value on this OS in 1970 */ static int flagbase = 0; if (!flagbase) { struct tm t; - t.tm_year = 70; t.tm_mon = 0; t.tm_mday = 0; - t.tm_hour = 0; t.tm_min = 0; t.tm_sec = 0; + + t.tm_year = 70; + t.tm_mon = 0; + t.tm_mday = 0; + t.tm_hour = 0; + t.tm_min = 0; + t.tm_sec = 0; t.tm_isdst = -1; - base = mktime(&t); /* could return -1 */ + base = mktime(&t); /* could return -1 */ flagbase = 1; } while (*cp) { - switch(*cp) { - case '\t': - StrAllocCopy(info->filename, cp + 1); - return; - case 's': - size = 0; - while (*(++cp) && (*cp != ',')) - size = (size * 10) + (*cp - '0'); - info->size = size; - break; - case 'm': - secs = 0; - while (*(++cp) && (*cp != ',')) - secs = (secs * 10) + (*cp - '0'); - secs += base; /* assumes that time_t is #seconds */ - strcpy(ct, ctime(&secs)); - ct[24] = 0; - StrAllocCopy(info->date, ct); - break; - case '/': - StrAllocCopy(info->type, ENTRY_IS_DIRECTORY); - /* FALLTHRU */ - default: - while (*cp) { - if (*cp++ == ',') - break; - } - break; + switch (*cp) { + case '\t': + StrAllocCopy(info->filename, cp + 1); + return; + case 's': + size = 0; + while (*(++cp) && (*cp != ',')) + size = (size * 10) + (*cp - '0'); + info->size = size; + break; + case 'm': + secs = 0; + while (*(++cp) && (*cp != ',')) + secs = (secs * 10) + (*cp - '0'); + secs += base; /* assumes that time_t is #seconds */ + strcpy(ct, ctime(&secs)); + ct[24] = 0; + StrAllocCopy(info->date, ct); + break; + case '/': + StrAllocCopy(info->type, ENTRY_IS_DIRECTORY); + /* FALLTHRU */ + default: + while (*cp) { + if (*cp++ == ',') + break; + } + break; } } -} /* parse_eplf_line */ +} /* parse_eplf_line */ /* - * parse_ls_line() -- - * Extract the name, size, and date from an ls -l line. + * Extract the name, size, and date from an ls -l line. */ -PRIVATE void parse_ls_line ARGS2( - char *, line, - EntryInfo *, entry_info) +static void parse_ls_line(char *line, + EntryInfo *entry_info) { - int i, j; - int base=1; - int size_num=0; + int i, j; + int base = 1; + int size_num = 0; for (i = strlen(line) - 1; - (i > 13) && (!isspace(UCH(line[i])) || !is_ls_date(&line[i-12])); i--) - ; /* null body */ + (i > 13) && (!isspace(UCH(line[i])) || !is_ls_date(&line[i - 12])); + i--) ; /* null body */ line[i] = '\0'; if (i > 13) { - StrAllocCopy(entry_info->date, &line[i-12]); + StrAllocCopy(entry_info->date, &line[i - 12]); /* replace the 4th location with nbsp if it is a space or zero */ if (entry_info->date[4] == ' ' || entry_info->date[4] == '0') entry_info->date[4] = HT_NON_BREAK_SPACE; /* make sure year or time is flush right */ if (entry_info->date[11] == ' ') { for (j = 11; j > 6; j--) { - entry_info->date[j] = entry_info->date[j-1]; + entry_info->date[j] = entry_info->date[j - 1]; } } } @@ -1558,35 +1617,33 @@ PRIVATE void parse_ls_line ARGS2( } entry_info->size = size_num; StrAllocCopy(entry_info->filename, &line[i + 1]); -} /* parse_ls_line() */ +} /* parse_ls_line() */ /* - * parse_dls_line() -- - * Extract the name and size info and whether it refers to a - * directory from a LIST line in "dls" format. + * Extract the name and size info and whether it refers to a directory from a + * LIST line in "dls" format. */ -PRIVATE void parse_dls_line ARGS3( - char *, line, - EntryInfo *, entry_info, - char **, pspilledname) +static void parse_dls_line(char *line, + EntryInfo *entry_info, + char **pspilledname) { - short j; - int base=1; - int size_num=0; - int len; + short j; + int base = 1; + int size_num = 0; + int len; char *cps = NULL; - /* README 763 Information about this server\0 - bin/ - \0 - etc/ = \0 - ls-lR 0 \0 - ls-lR.Z 3 \0 - pub/ = Public area\0 - usr/ - \0 - morgan 14 -> ../real/morgan\0 + /* README 763 Information about this server\0 + bin/ - \0 + etc/ = \0 + ls-lR 0 \0 + ls-lR.Z 3 \0 + pub/ = Public area\0 + usr/ - \0 + morgan 14 -> ../real/morgan\0 TIMIT.mostlikely.Z\0 - 79215 \0 - */ + 79215 \0 + */ len = strlen(line); if (len == 0) { @@ -1608,13 +1665,13 @@ PRIVATE void parse_dls_line ARGS3( if (*pspilledname && !*line) { entry_info->filename = *pspilledname; *pspilledname = NULL; - if (entry_info->filename[strlen(entry_info->filename)-1] == '/') + if (entry_info->filename[strlen(entry_info->filename) - 1] == '/') StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); else StrAllocCopy(entry_info->type, ""); } else { StrAllocCopy(entry_info->filename, line); - if (cps && cps != line && *(cps-1) == '/') + if (cps && cps != line && *(cps - 1) == '/') StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); else StrAllocCopy(entry_info->type, ""); @@ -1638,6 +1695,7 @@ PRIVATE void parse_dls_line ARGS3( cps = LYSkipBlanks(&line[23]); if (!strncmp(cps, "-> ", 3) && cps[3] != '\0' && cps[3] != ' ') { StrAllocCopy(entry_info->type, gettext("Symbolic Link")); + StrAllocCopy(entry_info->linkname, LYSkipBlanks(cps + 3)); entry_info->size = 0; /* don't display size */ } @@ -1651,45 +1709,46 @@ PRIVATE void parse_dls_line ARGS3( line = *pspilledname; len = strlen(*pspilledname); } - if (len > 0 && line[len-1] == '/') { - /* - ** It's a dir, remove / and mark it as such. - */ + if (len > 0 && line[len - 1] == '/') { + /* + * It's a dir, remove / and mark it as such. + */ if (len > 1) - line[len-1] = '\0'; + line[len - 1] = '\0'; if (!entry_info->type) StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); } StrAllocCopy(entry_info->filename, line); FREE(*pspilledname); -} /* parse_dls_line() */ +} /* parse_dls_line() */ /* * parse_vms_dir_entry() * Format the name, date, and size from a VMS LIST line * into the EntryInfo structure - FM */ -PRIVATE void parse_vms_dir_entry ARGS2( - char *, line, - EntryInfo *, entry_info) +static void parse_vms_dir_entry(char *line, + EntryInfo *entry_info) { int i, j; unsigned int ialloc; - char *cp, *cpd, *cps, date[16], *sp = " "; + char *cp, *cpd, *cps, date[16]; + const char *sp = " "; - /** Get rid of blank lines, and information lines. **/ - /** Valid lines have the ';' version number token. **/ + /* Get rid of blank lines, and information lines. Valid lines have the ';' + * version number token. + */ if (!strlen(line) || (cp = strchr(line, ';')) == NULL) { entry_info->display = FALSE; return; } - /** Cut out file or directory name at VMS version number. **/ - *cp++ ='\0'; - StrAllocCopy(entry_info->filename,line); + /* Cut out file or directory name at VMS version number. */ + *cp++ = '\0'; + StrAllocCopy(entry_info->filename, line); - /** Cast VMS non-README file and directory names to lowercase. **/ + /* Cast VMS non-README file and directory names to lowercase. */ if (strstr(entry_info->filename, "READ") == NULL) { LYLowerCase(entry_info->filename); i = strlen(entry_info->filename); @@ -1708,20 +1767,21 @@ PRIVATE void parse_vms_dir_entry ARGS2( LYLowerCase(entry_info->filename + i); } - /** Uppercase terminal .z's or _z's. **/ + /* Uppercase terminal .z's or _z's. */ if ((--i > 2) && entry_info->filename[i] == 'z' && - (entry_info->filename[i-1] == '.' || - entry_info->filename[i-1] == '_')) + (entry_info->filename[i - 1] == '.' || + entry_info->filename[i - 1] == '_')) entry_info->filename[i] = 'Z'; - /** Convert any tabs in rest of line to spaces. **/ - cps = cp-1; - while ((cps=strchr(cps+1, '\t')) != NULL) + /* Convert any tabs in rest of line to spaces. */ + cps = cp - 1; + while ((cps = strchr(cps + 1, '\t')) != NULL) *cps = ' '; - /** Collapse serial spaces. **/ - i = 0; j = 1; + /* Collapse serial spaces. */ + i = 0; + j = 1; cps = cp; while (cps[j] != '\0') { if (cps[i] == ' ' && cps[j] == ' ') @@ -1731,60 +1791,60 @@ PRIVATE void parse_vms_dir_entry ARGS2( } cps[++i] = '\0'; - /* Set the years and date, if we don't have them yet. **/ + /* Set the years and date, if we don't have them yet. * */ if (!HaveYears) { set_years_and_date(); } - /** Track down the date. **/ - if ((cpd=strchr(cp, '-')) != NULL && - strlen(cpd) > 9 && isdigit(UCH(*(cpd-1))) && - isalpha(UCH(*(cpd+1))) && *(cpd+4) == '-') { + /* Track down the date. */ + if ((cpd = strchr(cp, '-')) != NULL && + strlen(cpd) > 9 && isdigit(UCH(*(cpd - 1))) && + isalpha(UCH(*(cpd + 1))) && *(cpd + 4) == '-') { - /** Month **/ - *(cpd+2) = (char) TOLOWER(*(cpd+2)); - *(cpd+3) = (char) TOLOWER(*(cpd+3)); - sprintf(date, "%.3s ", cpd+1); + /* Month */ + *(cpd + 2) = (char) TOLOWER(*(cpd + 2)); + *(cpd + 3) = (char) TOLOWER(*(cpd + 3)); + sprintf(date, "%.3s ", cpd + 1); - /** Day **/ - if (isdigit(UCH(*(cpd-2)))) - sprintf(date+4, "%.2s ", cpd-2); + /* Day */ + if (isdigit(UCH(*(cpd - 2)))) + sprintf(date + 4, "%.2s ", cpd - 2); else - sprintf(date+4, "%c%.1s ", HT_NON_BREAK_SPACE, cpd-1); + sprintf(date + 4, "%c%.1s ", HT_NON_BREAK_SPACE, cpd - 1); - /** Time or Year **/ - if (!strncmp(ThisYear, cpd+5, 4) && - strlen(cpd) > 15 && *(cpd+12) == ':') { - sprintf(date+7, "%.5s", cpd+10); + /* Time or Year */ + if (!strncmp(ThisYear, cpd + 5, 4) && + strlen(cpd) > 15 && *(cpd + 12) == ':') { + sprintf(date + 7, "%.5s", cpd + 10); } else { - sprintf(date+7, " %.4s", cpd+5); + sprintf(date + 7, " %.4s", cpd + 5); } StrAllocCopy(entry_info->date, date); } - /** Track down the size **/ - if ((cpd=strchr(cp, '/')) != NULL) { + /* Track down the size */ + if ((cpd = strchr(cp, '/')) != NULL) { /* Appears be in used/allocated format */ cps = cpd; - while (isdigit(UCH(*(cps-1)))) + while (isdigit(UCH(*(cps - 1)))) cps--; if (cps < cpd) *cpd = '\0'; entry_info->size = atoi(cps); - cps = cpd+1; + cps = cpd + 1; while (isdigit(UCH(*cps))) cps++; *cps = '\0'; - ialloc = atoi(cpd+1); + ialloc = atoi(cpd + 1); /* Check if used is in blocks or bytes */ if (entry_info->size <= ialloc) entry_info->size *= 512; - } else if ((cps=strtok(cp, sp)) != NULL) { + } else if ((cps = strtok(cp, sp)) != NULL) { /* We just initialized on the version number */ /* Now let's hunt for a lone, size number */ - while ((cps=strtok(NULL, sp)) != NULL) { + while ((cps = strtok(NULL, sp)) != NULL) { cpd = cps; while (isdigit(UCH(*cpd))) cpd++; @@ -1796,41 +1856,40 @@ PRIVATE void parse_vms_dir_entry ARGS2( } } - /** Wrap it up **/ - CTRACE((tfp, "HTFTP: VMS filename: %s date: %s size: %d\n", - entry_info->filename, - NonNull(entry_info->date), - entry_info->size)); + /* Wrap it up */ + CTRACE((tfp, "HTFTP: VMS filename: %s date: %s size: %u\n", + entry_info->filename, + NonNull(entry_info->date), + entry_info->size)); return; -} /* parse_vms_dir_entry() */ +} /* parse_vms_dir_entry() */ /* * parse_ms_windows_dir_entry() -- * Format the name, date, and size from an MS_WINDOWS LIST line into * the EntryInfo structure (assumes Chameleon NEWT format). - FM */ -PRIVATE void parse_ms_windows_dir_entry ARGS2( - char *, line, - EntryInfo *, entry_info) +static void parse_ms_windows_dir_entry(char *line, + EntryInfo *entry_info) { char *cp = line; char *cps, *cpd, date[16]; char *end = line + strlen(line); - /** Get rid of blank or junk lines. **/ + /* Get rid of blank or junk lines. */ cp = LYSkipBlanks(cp); if (!(*cp)) { entry_info->display = FALSE; return; } - /** Cut out file or directory name. **/ + /* Cut out file or directory name. */ cps = LYSkipNonBlanks(cp); - *cps++ ='\0'; + *cps++ = '\0'; cpd = cps; StrAllocCopy(entry_info->filename, cp); - /** Track down the size **/ + /* Track down the size */ if (cps < end) { cps = LYSkipBlanks(cps); cpd = LYSkipNonBlanks(cps); @@ -1844,38 +1903,38 @@ PRIVATE void parse_ms_windows_dir_entry ARGS2( StrAllocCopy(entry_info->type, ""); } - /* Set the years and date, if we don't have them yet. **/ + /* Set the years and date, if we don't have them yet. * */ if (!HaveYears) { set_years_and_date(); } - /** Track down the date. **/ + /* Track down the date. */ if (cpd < end) { cpd = LYSkipBlanks(cpd); if (strlen(cpd) > 17) { - *(cpd+6) = '\0'; /* Month and Day */ - *(cpd+11) = '\0'; /* Year */ - *(cpd+17) = '\0'; /* Time */ - if (strcmp(ThisYear, cpd+7)) + *(cpd + 6) = '\0'; /* Month and Day */ + *(cpd + 11) = '\0'; /* Year */ + *(cpd + 17) = '\0'; /* Time */ + if (strcmp(ThisYear, cpd + 7)) /* Not this year, so show the year */ - sprintf(date, "%.6s %.4s", cpd, (cpd+7)); + sprintf(date, "%.6s %.4s", cpd, (cpd + 7)); else /* Is this year, so show the time */ - sprintf(date, "%.6s %.5s", cpd, (cpd+12)); + sprintf(date, "%.6s %.5s", cpd, (cpd + 12)); StrAllocCopy(entry_info->date, date); - if (entry_info->date[4] == ' '|| entry_info->date[4] == '0') { + if (entry_info->date[4] == ' ' || entry_info->date[4] == '0') { entry_info->date[4] = HT_NON_BREAK_SPACE; } } } - /** Wrap it up **/ - CTRACE((tfp, "HTFTP: MS Windows filename: %s date: %s size: %d\n", - entry_info->filename, - NonNull(entry_info->date), - entry_info->size)); + /* Wrap it up */ + CTRACE((tfp, "HTFTP: MS Windows filename: %s date: %s size: %u\n", + entry_info->filename, + NonNull(entry_info->date), + entry_info->size)); return; -} /* parse_ms_windows_dir_entry */ +} /* parse_ms_windows_dir_entry */ /* * parse_windows_nt_dir_entry() -- @@ -1883,26 +1942,25 @@ PRIVATE void parse_ms_windows_dir_entry ARGS2( * the EntryInfo structure (assumes Chameleon NEWT format). - FM */ #ifdef NOTDEFINED -PRIVATE void parse_windows_nt_dir_entry ARGS2( - char *, line, - EntryInfo *, entry_info) +static void parse_windows_nt_dir_entry(char *line, + EntryInfo *entry_info) { char *cp = line; char *cps, *cpd, date[16]; char *end = line + strlen(line); int i; - /** Get rid of blank or junk lines. **/ + /* Get rid of blank or junk lines. */ cp = LYSkipBlanks(cp); if (!(*cp)) { entry_info->display = FALSE; return; } - /** Cut out file or directory name. **/ + /* Cut out file or directory name. */ cpd = cp; - cps = LYSkipNonBlanks(end-1); - cp = (cps+1); + cps = LYSkipNonBlanks(end - 1); + cp = (cps + 1); if (!strcmp(cp, ".") || !strcmp(cp, "..")) { entry_info->display = FALSE; return; @@ -1913,37 +1971,37 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2( *cp = '\0'; end = cp; - /* Set the years and date, if we don't have them yet. **/ + /* Set the years and date, if we don't have them yet. * */ if (!HaveYears) { set_years_and_date(); } - /** Cut out the date. **/ + /* Cut out the date. */ cp = cps = cpd; cps = LYSkipNonBlanks(cps); - *cps++ ='\0'; + *cps++ = '\0'; if (cps > end) { entry_info->display = FALSE; return; } cps = LYSkipBlanks(cps); cpd = LYSkipNonBlanks(cps); - *cps++ ='\0'; + *cps++ = '\0'; if (cps > end || cpd == cps || strlen(cpd) < 7) { entry_info->display = FALSE; return; } if (strlen(cp) == 8 && - isdigit(*cp) && isdigit(*(cp+1)) && *(cp+2) == '-' && - isdigit(*(cp+3)) && isdigit(*(cp+4)) && *(cp+5) == '-') { - *(cp+2) = '\0'; /* Month */ + isdigit(*cp) && isdigit(*(cp + 1)) && *(cp + 2) == '-' && + isdigit(*(cp + 3)) && isdigit(*(cp + 4)) && *(cp + 5) == '-') { + *(cp + 2) = '\0'; /* Month */ i = atoi(cp) - 1; - *(cp+5) = '\0'; /* Day */ - sprintf(date, "%.3s %.2s", months[i], (cp+3)); + *(cp + 5) = '\0'; /* Day */ + sprintf(date, "%.3s %.2s", months[i], (cp + 3)); if (date[4] == '0') date[4] = ' '; - cp += 6; /* Year */ - if (strcmp((ThisYear+2), cp)) { + cp += 6; /* Year */ + if (strcmp((ThisYear + 2), cp)) { /* Not this year, so show the year */ if (atoi(cp) < 70) { sprintf(&date[6], " 20%.2s", cp); @@ -1952,19 +2010,19 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2( } } else { /* Is this year, so show the time */ - *(cpd+2) = '\0'; /* Hour */ + *(cpd + 2) = '\0'; /* Hour */ i = atoi(cpd); - if (*(cpd+5) == 'P' || *(cpd+5) == 'p') + if (*(cpd + 5) == 'P' || *(cpd + 5) == 'p') i += 12; - sprintf(&date[6], " %02d:%.2s", i, (cpd+3)); + sprintf(&date[6], " %02d:%.2s", i, (cpd + 3)); } StrAllocCopy(entry_info->date, date); - if (entry_info->date[4] == ' '|| entry_info->date[4] == '0') { + if (entry_info->date[4] == ' ' || entry_info->date[4] == '0') { entry_info->date[4] = HT_NON_BREAK_SPACE; } } - /** Track down the size **/ + /* Track down the size */ if (cps < end) { cps = LYSkipBlanks(cps); cpd = LYSkipNonBlanks(cps); @@ -1978,13 +2036,13 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2( StrAllocCopy(entry_info->type, ""); } - /** Wrap it up **/ + /* Wrap it up */ CTRACE((tfp, "HTFTP: Windows NT filename: %s date: %s size: %d\n", - entry_info->filename, - NonNull(entry_info->date), - entry_info->size)); + entry_info->filename, + NonNull(entry_info->date), + entry_info->size)); return; -} /* parse_windows_nt_dir_entry */ +} /* parse_windows_nt_dir_entry */ #endif /* NOTDEFINED */ /* @@ -1992,9 +2050,8 @@ PRIVATE void parse_windows_nt_dir_entry ARGS2( * Format the name, date, and size from a VM/CMS line into * the EntryInfo structure. - FM */ -PRIVATE void parse_cms_dir_entry ARGS2( - char *, line, - EntryInfo *, entry_info) +static void parse_cms_dir_entry(char *line, + EntryInfo *entry_info) { char *cp = line; char *cps, *cpd, date[16]; @@ -2003,51 +2060,51 @@ PRIVATE void parse_cms_dir_entry ARGS2( int Records = 0; int i; - /** Get rid of blank or junk lines. **/ + /* Get rid of blank or junk lines. */ cp = LYSkipBlanks(cp); if (!(*cp)) { entry_info->display = FALSE; return; } - /** Cut out file or directory name. **/ + /* Cut out file or directory name. */ cps = LYSkipNonBlanks(cp); - *cps++ ='\0'; + *cps++ = '\0'; StrAllocCopy(entry_info->filename, cp); if (strchr(entry_info->filename, '.') != NULL) - /** If we already have a dot, we did an NLST. **/ + /* If we already have a dot, we did an NLST. */ return; cp = LYSkipBlanks(cps); if (!(*cp)) { - /** If we don't have more, we've misparsed. **/ + /* If we don't have more, we've misparsed. */ FREE(entry_info->filename); FREE(entry_info->type); entry_info->display = FALSE; return; } cps = LYSkipNonBlanks(cp); - *cps++ ='\0'; + *cps++ = '\0'; if ((0 == strcasecomp(cp, "DIR")) && (cp - line) > 17) { - /** It's an SFS directory. **/ + /* It's an SFS directory. */ StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); entry_info->size = 0; } else { - /** It's a file. **/ + /* It's a file. */ cp--; *cp = '.'; StrAllocCat(entry_info->filename, cp); - /** Track down the VM/CMS RECFM or type. **/ + /* Track down the VM/CMS RECFM or type. */ cp = cps; if (cp < end) { cp = LYSkipBlanks(cp); cps = LYSkipNonBlanks(cp); *cps++ = '\0'; - /** Check cp here, if it's relevant someday. **/ + /* Check cp here, if it's relevant someday. */ } } - /** Track down the record length or dash. **/ + /* Track down the record length or dash. */ cp = cps; if (cp < end) { cp = LYSkipBlanks(cp); @@ -2058,7 +2115,7 @@ PRIVATE void parse_cms_dir_entry ARGS2( } } - /** Track down the number of records or the dash. **/ + /* Track down the number of records or the dash. */ cp = cps; if (cps < end) { cp = LYSkipBlanks(cp); @@ -2068,38 +2125,38 @@ PRIVATE void parse_cms_dir_entry ARGS2( Records = atoi(cp); } if (Records > 0 && RecordLength > 0) { - /** Compute an approximate size. **/ + /* Compute an approximate size. */ entry_info->size = (Records * RecordLength); } } - /** Set the years and date, if we don't have them yet. **/ + /* Set the years and date, if we don't have them yet. */ if (!HaveYears) { set_years_and_date(); } - /** Track down the date. **/ + /* Track down the date. */ cpd = cps; if (((cps < end) && (cps = strchr(cpd, ':')) != NULL) && (cps < (end - 3) && - isdigit(UCH(*(cps+1))) && isdigit(UCH(*(cps+2))) && *(cps+3) == ':')) { + isdigit(UCH(*(cps + 1))) && isdigit(UCH(*(cps + 2))) && *(cps + 3) == ':')) { cps += 3; *cps = '\0'; if ((cps - cpd) >= 14) { cpd = (cps - 14); - *(cpd+2) = '\0'; /* Month */ - *(cpd+5) = '\0'; /* Day */ - *(cpd+8) = '\0'; /* Year */ + *(cpd + 2) = '\0'; /* Month */ + *(cpd + 5) = '\0'; /* Day */ + *(cpd + 8) = '\0'; /* Year */ cps -= 5; /* Time */ if (*cpd == ' ') *cpd = '0'; i = atoi(cpd) - 1; - sprintf(date, "%.3s %.2s", months[i], (cpd+3)); + sprintf(date, "%.3s %.2s", months[i], (cpd + 3)); if (date[4] == '0') date[4] = ' '; cpd += 6; /* Year */ - if (strcmp((ThisYear+2), cpd)) { + if (strcmp((ThisYear + 2), cpd)) { /* Not this year, so show the year. */ if (atoi(cpd) < 70) { sprintf(&date[6], " 20%.2s", cpd); @@ -2108,321 +2165,317 @@ PRIVATE void parse_cms_dir_entry ARGS2( } } else { /* Is this year, so show the time. */ - *(cps+2) = '\0'; /* Hour */ + *(cps + 2) = '\0'; /* Hour */ i = atoi(cps); - sprintf(&date[6], " %02d:%.2s", i, (cps+3)); + sprintf(&date[6], " %02d:%.2s", i, (cps + 3)); } StrAllocCopy(entry_info->date, date); - if (entry_info->date[4] == ' '|| entry_info->date[4] == '0') { + if (entry_info->date[4] == ' ' || entry_info->date[4] == '0') { entry_info->date[4] = HT_NON_BREAK_SPACE; } } } - /** Wrap it up. **/ - CTRACE((tfp, "HTFTP: VM/CMS filename: %s date: %s size: %d\n", - entry_info->filename, - NonNull(entry_info->date), - entry_info->size)); + /* Wrap it up. */ + CTRACE((tfp, "HTFTP: VM/CMS filename: %s date: %s size: %u\n", + entry_info->filename, + NonNull(entry_info->date), + entry_info->size)); return; -} /* parse_cms_dir_entry */ +} /* parse_cms_dir_entry */ /* - * parse_dir_entry() - * Given a line of LIST/NLST output in entry, return results - * and a file/dir name in entry_info struct + * Given a line of LIST/NLST output in entry, return results and a file/dir + * name in entry_info struct * - * If first is true, this is the first name in a directory. + * If first is true, this is the first name in a directory. */ - -PRIVATE EntryInfo * parse_dir_entry ARGS3( - char *, entry, - BOOLEAN *, first, - char **, pspilledname) +static EntryInfo *parse_dir_entry(char *entry, + BOOLEAN *first, + char **pspilledname) { EntryInfo *entry_info; - int i; - int len; - BOOLEAN remove_size=FALSE; + int i; + int len; + BOOLEAN remove_size = FALSE; char *cp; - entry_info = (EntryInfo *)malloc(sizeof(EntryInfo)); + entry_info = (EntryInfo *) malloc(sizeof(EntryInfo)); + if (entry_info == NULL) outofmem(__FILE__, "parse_dir_entry"); entry_info->filename = NULL; + entry_info->linkname = NULL; entry_info->type = NULL; entry_info->date = NULL; entry_info->size = 0; entry_info->display = TRUE; switch (server_type) { - case DLS_SERVER: + case DLS_SERVER: - /* - ** Interpret and edit LIST output from a Unix server - ** in "dls" format. - ** This one must have claimed to be Unix in order to - ** get here; if the first line looks fishy, we revert - ** to Unix and hope that fits better (this recovery is - ** untested). - kw - */ - - if (*first) { - len = strlen(entry); - if (!len || entry[0] == ' ' || - (len >= 24 && entry[23] != ' ') || - (len < 24 && strchr(entry, ' '))) { - server_type = UNIX_SERVER; - CTRACE((tfp, - "HTFTP: Falling back to treating as Unix server.\n")); - } else { - *first = FALSE; - } - } - - if (server_type == DLS_SERVER) { - /* if still unchanged... */ - parse_dls_line(entry, entry_info, pspilledname); - - if (!entry_info->filename || *entry_info->filename == '\0') { - entry_info->display = FALSE; - return(entry_info); - } - if (!strcmp(entry_info->filename,"..") || - !strcmp(entry_info->filename,".")) - entry_info->display = FALSE; - if (entry_info->type && *entry_info->type == '\0') { - FREE(entry_info->type); - return(entry_info); - } - /* - ** Goto the bottom and get real type. - */ - break; - } /* fall through if server_type changed for *first == TRUE ! */ - - case UNIX_SERVER: - case PETER_LEWIS_SERVER: - case MACHTEN_SERVER: - case MSDOS_SERVER: - case WINDOWS_NT_SERVER: - case WINDOWS_2K_SERVER: - case APPLESHARE_SERVER: - case NETPRESENZ_SERVER: - /* - ** Check for EPLF output (local times). - */ - if (*entry == '+') { - parse_eplf_line(entry, entry_info); - break; - } + /* + * Interpret and edit LIST output from a Unix server in "dls" format. + * This one must have claimed to be Unix in order to get here; if the + * first line looks fishy, we revert to Unix and hope that fits better + * (this recovery is untested). - kw + */ - /* - ** Interpret and edit LIST output from Unix server. - */ + if (*first) { len = strlen(entry); - if (*first) { - /* don't gettext() this -- incoming text: */ - if (!strcmp(entry, "can not access directory .")) { - /* - * Don't reset *first, nothing real will follow. - KW - */ - entry_info->display = FALSE; - return(entry_info); - } + if (!len || entry[0] == ' ' || + (len >= 24 && entry[23] != ' ') || + (len < 24 && strchr(entry, ' '))) { + server_type = UNIX_SERVER; + CTRACE((tfp, + "HTFTP: Falling back to treating as Unix server.\n")); + } else { *first = FALSE; - if (!strncmp(entry, "total ", 6) || - strstr(entry, "not available") != NULL) { - entry_info->display = FALSE; - return(entry_info); - } else if (unsure_type) { - /* this isn't really a unix server! */ - server_type = GENERIC_SERVER; - entry_info->display = FALSE; - return(entry_info); - } } + } - /* - ** Check first character of ls -l output. - */ - if (TOUPPER(entry[0]) == 'D') { - /* - ** It's a directory. - */ - StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); - remove_size=TRUE; /* size is not useful */ - } else if (entry[0] == 'l') { - /* - ** It's a symbolic link, does the user care about - ** knowing if it is symbolic? I think so since - ** it might be a directory. - */ - StrAllocCopy(entry_info->type, gettext("Symbolic Link")); - remove_size=TRUE; /* size is not useful */ - - /* - ** Strip off " -> pathname". - */ - for (i = len - 1; (i > 3) && - (!isspace(UCH(entry[i])) || - (entry[i-1] != '>') || - (entry[i-2] != '-') || - (entry[i-3] != ' ')); i--) - ; /* null body */ - if (i > 3) { - entry[i-3] = '\0'; - len = i - 3; - } - } /* link */ - - parse_ls_line(entry, entry_info); + if (server_type == DLS_SERVER) { + /* if still unchanged... */ + parse_dls_line(entry, entry_info, pspilledname); - if (!strcmp(entry_info->filename,"..") || - !strcmp(entry_info->filename,".")) + if (!entry_info->filename || *entry_info->filename == '\0') { entry_info->display = FALSE; + return (entry_info); + } + if (!strcmp(entry_info->filename, "..") || + !strcmp(entry_info->filename, ".")) + entry_info->display = FALSE; + if (entry_info->type && *entry_info->type == '\0') { + FREE(entry_info->type); + return (entry_info); + } /* - ** Goto the bottom and get real type. - */ + * Goto the bottom and get real type. + */ + break; + } + /* fall through if server_type changed for *first == TRUE ! */ + case UNIX_SERVER: + case PETER_LEWIS_SERVER: + case MACHTEN_SERVER: + case MSDOS_SERVER: + case WINDOWS_NT_SERVER: + case WINDOWS_2K_SERVER: + case APPLESHARE_SERVER: + case NETPRESENZ_SERVER: + /* + * Check for EPLF output (local times). + */ + if (*entry == '+') { + parse_eplf_line(entry, entry_info); break; + } - case VMS_SERVER: - /* - ** Interpret and edit LIST output from VMS server - ** and convert information lines to zero length. - */ - parse_vms_dir_entry(entry, entry_info); + /* + * Interpret and edit LIST output from Unix server. + */ + len = strlen(entry); + if (*first) { + /* don't gettext() this -- incoming text: */ + if (!strcmp(entry, "can not access directory .")) { + /* + * Don't reset *first, nothing real will follow. - KW + */ + entry_info->display = FALSE; + return (entry_info); + } + *first = FALSE; + if (!strncmp(entry, "total ", 6) || + strstr(entry, "not available") != NULL) { + entry_info->display = FALSE; + return (entry_info); + } else if (unsure_type) { + /* this isn't really a unix server! */ + server_type = GENERIC_SERVER; + entry_info->display = FALSE; + return (entry_info); + } + } + /* + * Check first character of ls -l output. + */ + if (TOUPPER(entry[0]) == 'D') { /* - ** Get rid of any junk lines. - */ - if (!entry_info->display) - return(entry_info); + * It's a directory. + */ + StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); + remove_size = TRUE; /* size is not useful */ + } else if (entry[0] == 'l') { + /* + * It's a symbolic link, does the user care about knowing if it is + * symbolic? I think so since it might be a directory. + */ + StrAllocCopy(entry_info->type, gettext("Symbolic Link")); + remove_size = TRUE; /* size is not useful */ /* - ** Trim off VMS directory extensions. - */ - len = strlen(entry_info->filename); - if ((len > 4) && !strcmp(&entry_info->filename[len-4], ".dir")) { - entry_info->filename[len-4] = '\0'; - StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); - remove_size=TRUE; /* size is not useful */ + * Strip off " -> pathname". + */ + for (i = len - 1; (i > 3) && + (!isspace(UCH(entry[i])) || + (entry[i - 1] != '>') || + (entry[i - 2] != '-') || + (entry[i - 3] != ' ')); i--) ; /* null body */ + if (i > 3) { + entry[i - 3] = '\0'; + len = i - 3; + StrAllocCopy(entry_info->linkname, LYSkipBlanks(entry + i)); } - /* - ** Goto the bottom and get real type. - */ - break; + } + /* link */ + parse_ls_line(entry, entry_info); - case MS_WINDOWS_SERVER: - /* - ** Interpret and edit LIST output from MS_WINDOWS server - ** and convert information lines to zero length. - */ - parse_ms_windows_dir_entry(entry, entry_info); + if (!strcmp(entry_info->filename, "..") || + !strcmp(entry_info->filename, ".")) + entry_info->display = FALSE; + /* + * Goto the bottom and get real type. + */ + break; - /* - ** Get rid of any junk lines. - */ - if (!entry_info->display) - return(entry_info); - if (entry_info->type && *entry_info->type == '\0') { - FREE(entry_info->type); - return(entry_info); - } - /* - ** Goto the bottom and get real type. - */ - break; + case VMS_SERVER: + /* + * Interpret and edit LIST output from VMS server and convert + * information lines to zero length. + */ + parse_vms_dir_entry(entry, entry_info); + + /* + * Get rid of any junk lines. + */ + if (!entry_info->display) + return (entry_info); + + /* + * Trim off VMS directory extensions. + */ + len = strlen(entry_info->filename); + if ((len > 4) && !strcmp(&entry_info->filename[len - 4], ".dir")) { + entry_info->filename[len - 4] = '\0'; + StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); + remove_size = TRUE; /* size is not useful */ + } + /* + * Goto the bottom and get real type. + */ + break; + + case MS_WINDOWS_SERVER: + /* + * Interpret and edit LIST output from MS_WINDOWS server and convert + * information lines to zero length. + */ + parse_ms_windows_dir_entry(entry, entry_info); + + /* + * Get rid of any junk lines. + */ + if (!entry_info->display) + return (entry_info); + if (entry_info->type && *entry_info->type == '\0') { + FREE(entry_info->type); + return (entry_info); + } + /* + * Goto the bottom and get real type. + */ + break; #ifdef NOTDEFINED - case WINDOWS_NT_SERVER: - /* - ** Interpret and edit LIST output from MS_WINDOWS server - ** and convert information lines to zero length. - */ - parse_windows_nt_dir_entry(entry, entry_info); + case WINDOWS_NT_SERVER: + /* + * Interpret and edit LIST output from MS_WINDOWS server and convert + * information lines to zero length. + */ + parse_windows_nt_dir_entry(entry, entry_info); - /* - ** Get rid of any junk lines. - */ - if (!entry_info->display) - return(entry_info); - if (entry_info->type && *entry_info->type == '\0') { - FREE(entry_info->type); - return(entry_info); - } - /* - ** Goto the bottom and get real type. - */ - break; + /* + * Get rid of any junk lines. + */ + if (!entry_info->display) + return (entry_info); + if (entry_info->type && *entry_info->type == '\0') { + FREE(entry_info->type); + return (entry_info); + } + /* + * Goto the bottom and get real type. + */ + break; #endif /* NOTDEFINED */ - case CMS_SERVER: - { + case CMS_SERVER: + { /* - ** Interpret and edit LIST output from VM/CMS server - ** and convert any information lines to zero length. - */ + * Interpret and edit LIST output from VM/CMS server and convert + * any information lines to zero length. + */ parse_cms_dir_entry(entry, entry_info); /* - ** Get rid of any junk lines. - */ + * Get rid of any junk lines. + */ if (!entry_info->display) - return(entry_info); + return (entry_info); if (entry_info->type && *entry_info->type == '\0') { FREE(entry_info->type); - return(entry_info); + return (entry_info); } /* - ** Goto the bottom and get real type. - */ + * Goto the bottom and get real type. + */ break; - } + } - case NCSA_SERVER: - case TCPC_SERVER: - /* - ** Directories identified by trailing "/" characters. - */ - StrAllocCopy(entry_info->filename, entry); - len = strlen(entry); - if (entry[len-1] == '/') { - /* - ** It's a dir, remove / and mark it as such. - */ - entry[len-1] = '\0'; - StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); - remove_size=TRUE; /* size is not useful */ - } + case NCSA_SERVER: + case TCPC_SERVER: + /* + * Directories identified by trailing "/" characters. + */ + StrAllocCopy(entry_info->filename, entry); + len = strlen(entry); + if (entry[len - 1] == '/') { /* - ** Goto the bottom and get real type. - */ - break; + * It's a dir, remove / and mark it as such. + */ + entry[len - 1] = '\0'; + StrAllocCopy(entry_info->type, ENTRY_IS_DIRECTORY); + remove_size = TRUE; /* size is not useful */ + } + /* + * Goto the bottom and get real type. + */ + break; - default: - /* - ** We can't tell if it is a directory since we only - ** did an NLST :( List bad file types anyways? NOT! - */ - StrAllocCopy(entry_info->filename, entry); - return(entry_info); /* mostly empty info */ + default: + /* + * We can't tell if it is a directory since we only did an NLST :( List + * bad file types anyways? NOT! + */ + StrAllocCopy(entry_info->filename, entry); + return (entry_info); /* mostly empty info */ - } /* switch (server_type) */ + } /* switch (server_type) */ if (remove_size && entry_info->size) { entry_info->size = 0; } if (entry_info->filename && strlen(entry_info->filename) > 3) { - if (((cp=strrchr(entry_info->filename, '.')) != NULL && + if (((cp = strrchr(entry_info->filename, '.')) != NULL && 0 == strncasecomp(cp, ".me", 3)) && (cp[3] == '\0' || cp[3] == ';')) { /* - ** Don't treat this as application/x-Troff-me - ** if it's a Unix server but has the string - ** "read.me", or if it's not a Unix server. - FM - */ + * Don't treat this as application/x-Troff-me if it's a Unix server + * but has the string "read.me", or if it's not a Unix server. - + * FM + */ if ((server_type != UNIX_SERVER) || (cp > (entry_info->filename + 3) && 0 == strncasecomp((cp - 4), "read.me", 7))) { @@ -2432,18 +2485,19 @@ PRIVATE EntryInfo * parse_dir_entry ARGS3( } /* - ** Get real types eventually. - */ + * Get real types eventually. + */ if (!entry_info->type) { - CONST char *cp2; + const char *cp2; HTFormat format; - HTAtom * encoding; /* @@ not used at all */ + HTAtom *encoding; /* @@ not used at all */ + format = HTFileFormat(entry_info->filename, &encoding, &cp2); if (cp2 == NULL) { - if (!strncmp(HTAtom_name(format), "application",11)) { + if (!strncmp(HTAtom_name(format), "application", 11)) { cp2 = HTAtom_name(format) + 12; - if (!strncmp(cp2,"x-",2)) + if (!strncmp(cp2, "x-", 2)) cp2 += 2; } else { cp2 = HTAtom_name(format); @@ -2453,239 +2507,232 @@ PRIVATE EntryInfo * parse_dir_entry ARGS3( StrAllocCopy(entry_info->type, cp2); } - return(entry_info); -} /* parse_dir_entry */ + return (entry_info); +} /* parse_dir_entry */ -PRIVATE int compare_EntryInfo_structs ARGS2( - EntryInfo *, entry1, - EntryInfo *, entry2) +static int compare_EntryInfo_structs(EntryInfo *entry1, EntryInfo *entry2) { int i, status; char date1[16], date2[16], time1[8], time2[8], month[4]; - switch(HTfileSortMethod) { - case FILE_BY_SIZE: - /* both equal or both 0 */ - if (entry1->size == entry2->size) - return(strcmp(entry1->filename, entry2->filename)); - else - if (entry1->size > entry2->size) - return(1); - else - return(-1); - - case FILE_BY_TYPE: - if (entry1->type && entry2->type) { - status = strcasecomp(entry1->type, entry2->type); - if (status) - return(status); - /* else fall to filename comparison */ - } + switch (HTfileSortMethod) { + case FILE_BY_SIZE: + /* both equal or both 0 */ + if (entry1->size == entry2->size) return (strcmp(entry1->filename, entry2->filename)); + else if (entry1->size > entry2->size) + return (1); + else + return (-1); + + case FILE_BY_TYPE: + if (entry1->type && entry2->type) { + status = strcasecomp(entry1->type, entry2->type); + if (status) + return (status); + /* else fall to filename comparison */ + } + return (strcmp(entry1->filename, entry2->filename)); - case FILE_BY_DATE: - if (entry1->date && entry2->date) { - /* - ** Make sure we have the correct length. - FM - */ - if (strlen(entry1->date) != 12 || strlen(entry2->date) != 12) { - return(strcmp(entry1->filename, entry2->filename)); - } - /* - ** Set the years and date, - ** if we don't have them yet. - */ - if (!HaveYears) { - set_years_and_date(); - } - /* - ** Set up for sorting in reverse - ** chronological order. - FM - */ - if (entry1->date[9] == ':') { - strcpy(date1, "9999"); - strcpy(time1, &entry1->date[7]); - if (time1[0] == ' ') { - time1[0] = '0'; - } - } else { - strcpy(date1, &entry1->date[8]); - strcpy(time1, "00:00"); - } - strncpy(month, entry1->date, 3); - month[3] = '\0'; - for (i = 0; i < 12; i++) { - if (!strcasecomp(month, months[i])) { - break; - } - } - i++; - sprintf(month, "%02d", i); - strcat(date1, month); - strncat(date1, &entry1->date[4], 2); - date1[8] = '\0'; - if (date1[6] == ' ' || date1[6] == HT_NON_BREAK_SPACE) { - date1[6] = '0'; + case FILE_BY_DATE: + if (entry1->date && entry2->date) { + /* + * Make sure we have the correct length. - FM + */ + if (strlen(entry1->date) != 12 || strlen(entry2->date) != 12) { + return (strcmp(entry1->filename, entry2->filename)); + } + /* + * Set the years and date, + * if we don't have them yet. + */ + if (!HaveYears) { + set_years_and_date(); + } + /* + * Set up for sorting in reverse + * chronological order. - FM + */ + if (entry1->date[9] == ':') { + strcpy(date1, "9999"); + strcpy(time1, &entry1->date[7]); + if (time1[0] == ' ') { + time1[0] = '0'; } - /* If no year given, assume last year if it would otherwise - * be in the future by more than one day. The one day - * tolerance is to account for a possible timezone - * difference. - kw */ - if (date1[0] == '9' && atoi(date1) > TheDate + 1) { - for (i = 0; i < 4; i++) { - date1[i] = LastYear[i]; - } + } else { + strcpy(date1, &entry1->date[8]); + strcpy(time1, "00:00"); + } + strncpy(month, entry1->date, 3); + month[3] = '\0'; + for (i = 0; i < 12; i++) { + if (!strcasecomp(month, months[i])) { + break; } - strcat(date1, time1); - if (entry2->date[9] == ':') { - strcpy(date2, "9999"); - strcpy(time2, &entry2->date[7]); - if (time2[0] == ' ') { - time2[0] = '0'; - } - } else { - strcpy(date2, &entry2->date[8]); - strcpy(time2, "00:00"); + } + i++; + sprintf(month, "%02d", i); + strcat(date1, month); + strncat(date1, &entry1->date[4], 2); + date1[8] = '\0'; + if (date1[6] == ' ' || date1[6] == HT_NON_BREAK_SPACE) { + date1[6] = '0'; + } + /* If no year given, assume last year if it would otherwise be in + * the future by more than one day. The one day tolerance is to + * account for a possible timezone difference. - kw + */ + if (date1[0] == '9' && atoi(date1) > TheDate + 1) { + for (i = 0; i < 4; i++) { + date1[i] = LastYear[i]; } - strncpy(month, entry2->date, 3); - month[3] = '\0'; - for (i = 0; i < 12; i++) { - if (!strcasecomp(month, months[i])) { - break; - } + } + strcat(date1, time1); + if (entry2->date[9] == ':') { + strcpy(date2, "9999"); + strcpy(time2, &entry2->date[7]); + if (time2[0] == ' ') { + time2[0] = '0'; } - i++; - sprintf(month, "%02d", i); - strcat(date2, month); - strncat(date2, &entry2->date[4], 2); - date2[8] = '\0'; - if (date2[6] == ' ' || date2[6] == HT_NON_BREAK_SPACE) { - date2[6] = '0'; + } else { + strcpy(date2, &entry2->date[8]); + strcpy(time2, "00:00"); + } + strncpy(month, entry2->date, 3); + month[3] = '\0'; + for (i = 0; i < 12; i++) { + if (!strcasecomp(month, months[i])) { + break; } - /* If no year given, assume last year if it would otherwise - * be in the future by more than one day. The one day - * tolerance is to account for a possible timezone - * difference. - kw */ - if (date2[0] == '9' && atoi(date2) > TheDate + 1) { - for (i = 0; i < 4; i++) { - date2[i] = LastYear[i]; - } + } + i++; + sprintf(month, "%02d", i); + strcat(date2, month); + strncat(date2, &entry2->date[4], 2); + date2[8] = '\0'; + if (date2[6] == ' ' || date2[6] == HT_NON_BREAK_SPACE) { + date2[6] = '0'; + } + /* If no year given, assume last year if it would otherwise be in + * the future by more than one day. The one day tolerance is to + * account for a possible timezone difference. - kw + */ + if (date2[0] == '9' && atoi(date2) > TheDate + 1) { + for (i = 0; i < 4; i++) { + date2[i] = LastYear[i]; } - strcat(date2, time2); - /* - ** Do the comparison. - FM - */ - status = strcasecomp(date2, date1); - if (status) - return(status); - /* else fall to filename comparison */ } - return (strcmp(entry1->filename, entry2->filename)); + strcat(date2, time2); + /* + * Do the comparison. - FM + */ + status = strcasecomp(date2, date1); + if (status) + return (status); + /* else fall to filename comparison */ + } + return (strcmp(entry1->filename, entry2->filename)); - case FILE_BY_NAME: - default: - return (strcmp(entry1->filename, entry2->filename)); + case FILE_BY_NAME: + default: + return (strcmp(entry1->filename, entry2->filename)); } } - /* Read a directory into an hypertext object from the data socket -** -------------------------------------------------------------- -** -** On entry, -** anchor Parent anchor to link the this node to -** address Address of the directory -** On exit, -** returns HT_LOADED if OK -** <0 if error. -*/ -PRIVATE int read_directory ARGS4( - HTParentAnchor *, parent, - CONST char *, address, - HTFormat, format_out, - HTStream *, sink) + * -------------------------------------------------------------- + * + * On entry, + * anchor Parent anchor to link the this node to + * address Address of the directory + * On exit, + * returns HT_LOADED if OK + * <0 if error. + */ +static int read_directory(HTParentAnchor *parent, + const char *address, + HTFormat format_out, + HTStream *sink) { int status; BOOLEAN WasInterrupted = FALSE; - HTStructured* target = HTML_new(parent, format_out, sink); + HTStructured *target = HTML_new(parent, format_out, sink); HTStructuredClass targetClass; char *filename = HTParse(address, "", PARSE_PATH + PARSE_PUNCTUATION); EntryInfo *entry_info; BOOLEAN first = TRUE; char string_buffer[64]; - char *lastpath = NULL;/* prefix for link, either "" (for root) or xxx */ + char *lastpath = NULL; /* prefix for link, either "" (for root) or xxx */ BOOL need_parent_link = FALSE; BOOL tildeIsTop = FALSE; targetClass = *(target->isa); - _HTProgress (gettext("Receiving FTP directory.")); + _HTProgress(gettext("Receiving FTP directory.")); /* - * Force the current Date and Year (TheDate, ThisYear, and LastYear) - * to be recalculated for each directory request. Otherwise we have - * a problem with long-running sessions assuming the wrong date for - * today. - kw + * Force the current Date and Year (TheDate, ThisYear, and LastYear) to be + * recalculated for each directory request. Otherwise we have a problem + * with long-running sessions assuming the wrong date for today. - kw */ HaveYears = FALSE; /* - ** Check whether we always want the home - ** directory treated as Welcome. - FM - */ + * Check whether we always want the home directory treated as Welcome. - + * FM + */ if (server_type == VMS_SERVER) tildeIsTop = TRUE; /* - ** This should always come back FALSE, since the - ** flag is set only for local directory listings - ** if LONG_LIST was defined on compilation, but - ** we could someday set up an equivalent listing - ** for Unix ftp servers. - FM - */ - need_parent_link = HTDirTitles(target, parent, tildeIsTop); + * This should always come back FALSE, since the flag is set only for local + * directory listings if LONG_LIST was defined on compilation, but we could + * someday set up an equivalent listing for Unix ftp servers. - FM + */ + need_parent_link = HTDirTitles(target, parent, format_out, tildeIsTop); data_read_pointer = data_write_pointer = data_buffer; - if (*filename == '\0') { /* Empty filename: use root. */ - StrAllocCopy (lastpath, "/"); - } else if (!strcmp(filename,"/")) { /* Root path. */ - StrAllocCopy (lastpath, "/foo/.."); + if (*filename == '\0') { /* Empty filename: use root. */ + StrAllocCopy(lastpath, "/"); + } else if (!strcmp(filename, "/")) { /* Root path. */ + StrAllocCopy(lastpath, "/foo/.."); } else { - char * p = strrchr(filename, '/'); /* Find the lastslash. */ + char *p = strrchr(filename, '/'); /* Find the lastslash. */ char *cp; if (server_type == CMS_SERVER) { - StrAllocCopy(lastpath, filename); /* Use absolute path for CMS. */ + StrAllocCopy(lastpath, filename); /* Use absolute path for CMS. */ } else { - StrAllocCopy(lastpath, p+1); /* Take slash off the beginning. */ + StrAllocCopy(lastpath, p + 1); /* Take slash off the beginning. */ } - if ((cp = strrchr(lastpath, ';')) != NULL) { /* Trim type= param. */ - if (!strncasecomp((cp+1), "type=", 5)) { - if (TOUPPER(*(cp+6)) == 'D' || - TOUPPER(*(cp+6)) == 'A' || - TOUPPER(*(cp+6)) == 'I') + if ((cp = strrchr(lastpath, ';')) != NULL) { /* Trim type= param. */ + if (!strncasecomp((cp + 1), "type=", 5)) { + if (TOUPPER(*(cp + 6)) == 'D' || + TOUPPER(*(cp + 6)) == 'A' || + TOUPPER(*(cp + 6)) == 'I') *cp = '\0'; } } } - FREE (filename); + FREE(filename); { - HTBTree * bt = HTBTree_new((HTComparer)compare_EntryInfo_structs); + HTBTree *bt = HTBTree_new((HTComparer) compare_EntryInfo_structs); int ic; - HTChunk * chunk = HTChunkCreate(128); + HTChunk *chunk = HTChunkCreate(128); int BytesReceived = 0; int BytesReported = 0; char NumBytes[64]; char *spilledname = NULL; - PUTC('\n'); /* prettier LJM */ + + PUTC('\n'); /* prettier LJM */ for (ic = 0; ic != EOF;) { /* For each entry in the directory */ HTChunkClear(chunk); if (HTCheckForInterrupt()) { CTRACE((tfp, - "read_directory: interrupted after %d bytes\n", - BytesReceived)); + "read_directory: interrupted after %d bytes\n", + BytesReceived)); WasInterrupted = TRUE; if (BytesReceived) { goto unload_btree; /* unload btree */ @@ -2697,32 +2744,32 @@ PRIVATE int read_directory ARGS4( } } - /* read directory entry + /* read directory entry */ interrupted_in_next_data_char = FALSE; - for (;;) { /* Read in one line as filename */ + for (;;) { /* Read in one line as filename */ ic = NEXT_DATA_CHAR; -AgainForMultiNet: + AgainForMultiNet: if (interrupted_in_next_data_char) { CTRACE((tfp, - "read_directory: interrupted_in_next_data_char after %d bytes\n", - BytesReceived)); + "read_directory: interrupted_in_next_data_char after %d bytes\n", + BytesReceived)); WasInterrupted = TRUE; if (BytesReceived) { - goto unload_btree; /* unload btree */ + goto unload_btree; /* unload btree */ } else { ABORT_TARGET; HTBTreeAndObject_free(bt); FREE(spilledname); return HT_INTERRUPTED; } - } else if ((char)ic == CR || (char)ic == LF) { /* Terminator? */ - if (chunk->size != 0) { /* got some text */ + } else if ((char) ic == CR || (char) ic == LF) { /* Terminator? */ + if (chunk->size != 0) { /* got some text */ /* Deal with MultiNet's wrapping of long lines */ if (server_type == VMS_SERVER) { - /* Deal with MultiNet's wrapping of long lines - F.M. */ + /* Deal with MultiNet's wrapping of long lines - F.M. */ if (data_read_pointer < data_write_pointer && - *(data_read_pointer+1) == ' ') + *(data_read_pointer + 1) == ' ') data_read_pointer++; else if (data_read_pointer >= data_write_pointer) { status = NETREAD(data_soc, data_buffer, @@ -2741,17 +2788,15 @@ AgainForMultiNet: data_read_pointer++; else break; - } - else + } else break; - } - else + } else break; /* finish getting one entry */ } } else if (ic == EOF) { - break; /* End of file */ + break; /* End of file */ } else { - HTChunkPutc(chunk, (char)ic); + HTChunkPutc(chunk, (char) ic); } } HTChunkTerminate(chunk); @@ -2759,8 +2804,8 @@ AgainForMultiNet: BytesReceived += chunk->size; if (BytesReceived > BytesReported + 1024) { #ifdef _WINDOWS - sprintf(NumBytes,gettext("Transferred %d bytes (%5d)"), - BytesReceived, ws_read_per_sec); + sprintf(NumBytes, gettext("Transferred %d bytes (%5d)"), + BytesReceived, ws_read_per_sec); #else sprintf(NumBytes, TRANSFERRED_X_BYTES, BytesReceived); #endif @@ -2769,30 +2814,30 @@ AgainForMultiNet: } if (ic == EOF && chunk->size == 1) - /* 1 means empty: includes terminating 0 */ + /* 1 means empty: includes terminating 0 */ break; CTRACE((tfp, "HTFTP: Line in %s is %s\n", - lastpath, chunk->data)); + lastpath, chunk->data)); entry_info = parse_dir_entry(chunk->data, &first, &spilledname); if (entry_info->display) { FREE(spilledname); CTRACE((tfp, "Adding file to BTree: %s\n", - entry_info->filename)); + entry_info->filename)); HTBTree_add(bt, entry_info); } else { free_entryinfo_struct_contents(entry_info); FREE(entry_info); } - } /* next entry */ + } /* next entry */ -unload_btree: + unload_btree: HTChunkFree(chunk); FREE(spilledname); - /* print out the handy help message if it exits :) */ + /* print out the handy help message if it exists :) */ if (help_message_cache_non_empty()) { START(HTML_PRE); START(HTML_HR); @@ -2808,26 +2853,27 @@ unload_btree: /* Put up header */ - /* PUTS(" Date Type Size Filename\n"); + /* PUTS(" Date Type Size Filename\n"); */ /* Run through tree printing out in order */ { -#ifdef SH_EX /* 1997/10/18 (Sat) 14:14:28 */ +#ifdef SH_EX /* 1997/10/18 (Sat) 14:14:28 */ char *p, name_buff[256]; - int name_len, dot_len; + int name_len, dot_len; #define FNAME_WIDTH 30 -#define FILE_GAP 2 +#define FILE_GAP 1 #endif - HTBTElement * ele; + HTBTElement *ele; int i; + for (ele = HTBTree_next(bt, NULL); ele != NULL; ele = HTBTree_next(bt, ele)) { - entry_info = (EntryInfo *)HTBTree_object(ele); + entry_info = (EntryInfo *) HTBTree_object(ele); if (entry_info->date) { PUTS(entry_info->date); @@ -2845,16 +2891,16 @@ unload_btree: /* start the anchor */ HTDirEntry(target, lastpath, entry_info->filename); -#ifdef SH_EX /* 1997/10/18 (Sat) 16:00 */ +#ifdef SH_EX /* 1997/10/18 (Sat) 16:00 */ name_len = strlen(entry_info->filename); - sprintf(name_buff, "%-30s", entry_info->filename); + sprintf(name_buff, "%-*s", FNAME_WIDTH, entry_info->filename); if (name_len < FNAME_WIDTH) { dot_len = FNAME_WIDTH - FILE_GAP - name_len; if (dot_len > 0) { p = name_buff + name_len + 1; - while (dot_len--) + while (dot_len-- > 0) *p++ = '.'; } } else { @@ -2868,43 +2914,46 @@ unload_btree: END(HTML_A); if (entry_info->size) { -#ifdef SH_EX /* 1998/02/02 (Mon) 16:34:52 */ +#ifdef SH_EX /* 1998/02/02 (Mon) 16:34:52 */ if (entry_info->size < 1024) sprintf(string_buffer, "%6d bytes", - entry_info->size); + entry_info->size); else sprintf(string_buffer, "%6d Kb", - entry_info->size/1024); + entry_info->size / 1024); #else if (entry_info->size < 1024) - sprintf(string_buffer, " %d bytes", - entry_info->size); + sprintf(string_buffer, " %u bytes", + entry_info->size); else - sprintf(string_buffer, " %dKb", - entry_info->size/1024); + sprintf(string_buffer, " %uKb", + entry_info->size / 1024); #endif PUTS(string_buffer); + } else if (entry_info->linkname != 0) { + PUTS(" -> "); + PUTS(entry_info->linkname); } - PUTC('\n'); /* end of this entry */ + PUTC('\n'); /* end of this entry */ free_entryinfo_struct_contents(entry_info); } } END(HTML_PRE); + END(HTML_BODY); FREE_TARGET; HTBTreeAndObject_free(bt); } FREE(lastpath); - if (WasInterrupted || data_soc != -1) { /* should always be true */ + if (WasInterrupted || data_soc != -1) { /* should always be true */ /* - * Without closing the data socket first, - * the response(0) later may hang. - * Some servers expect the client to fin/ack the close - * of the data connection before proceeding with the - * conversation on the control connection. - kw + * Without closing the data socket first, the response(0) later may + * hang. Some servers expect the client to fin/ack the close of the + * data connection before proceeding with the conversation on the + * control connection. - kw */ CTRACE((tfp, "HTFTP: Closing data socket %d\n", data_soc)); status = NETCLOSE(data_soc); @@ -2922,12 +2971,13 @@ unload_btree: /* * Setup an FTP connection. */ -PRIVATE int setup_connection ARGS2( - CONST char *, name, - HTParentAnchor *, anchor) +static int setup_connection(const char *name, + HTParentAnchor *anchor) { int retry; /* How many times tried? */ - int status; + int status = HT_NO_CONNECTION; + + CTRACE((tfp, "setup_connection(%s)\n", name)); /* set use_list to NOT since we don't know what kind of server * this is yet. And set the type to GENERIC @@ -2935,138 +2985,160 @@ PRIVATE int setup_connection ARGS2( use_list = FALSE; server_type = GENERIC_SERVER; ProFTPD_bugs = FALSE; + WU_FTPD_bugs = FALSE; - for (retry = 0; retry < 2; retry++) { /* For timed out/broken connections */ + for (retry = 0; retry < 2; retry++) { /* For timed out/broken connections */ status = get_connection(name, anchor); - if (status < 0) - return status; + if (status < 0) { + break; + } if (!ftp_local_passive) { status = get_listen_socket(); if (status < 0) { - NETCLOSE (control->socket); + NETCLOSE(control->socket); control->socket = -1; #ifdef INET6 if (master_socket >= 0) - (void)close_master_socket (); + (void) close_master_socket(); #else - close_master_socket (); + close_master_socket(); #endif /* INET6 */ /* HT_INTERRUPTED would fall through, if we could interrupt somehow in the middle of it, which we currently can't. */ - return status; + break; } - #ifdef REPEAT_PORT - /* Inform the server of the port number we will listen on - */ + /* Inform the server of the port number we will listen on + */ status = response(port_command); if (status == HT_INTERRUPTED) { CTRACE((tfp, "HTFTP: Interrupted in response (port_command)\n")); - _HTProgress (CONNECTION_INTERRUPTED); - NETCLOSE (control->socket); + _HTProgress(CONNECTION_INTERRUPTED); + NETCLOSE(control->socket); control->socket = -1; - close_master_socket (); - return HT_INTERRUPTED; + close_master_socket(); + status = HT_INTERRUPTED; + break; } - if (status != 2) { /* Could have timed out */ + if (status != 2) { /* Could have timed out */ if (status < 0) - continue; /* try again - net error*/ - return -status; /* bad reply */ + continue; /* try again - net error */ + status = -status; /* bad reply */ + break; } CTRACE((tfp, "HTFTP: Port defined.\n")); #endif /* REPEAT_PORT */ } else { /* Tell the server to be passive */ char *command = NULL; - char *p; - int h0, h1, h2, h3, p0, p1; /* Parts of reply */ + const char *p = "?"; + int h0, h1, h2, h3, p0, p1; /* Parts of reply */ + #ifdef INET6 - char dst[LINE_LENGTH+1]; + char dst[LINE_LENGTH + 1]; #endif data_soc = status; #ifdef INET6 - status = send_cmd_1(p = "EPSV"); + /* see RFC 2428 */ + if (WU_FTPD_bugs) + status = 1; + else + status = send_cmd_1(p = "EPSV"); if (status < 0) /* retry or Bad return */ continue; else if (status != 2) { status = send_cmd_1(p = "PASV"); - if (status < 0) /* retry or Bad return */ + if (status < 0) { /* retry or Bad return */ continue; - else if (status != 2) { - return -status; /* bad reply */ + } else if (status != 2) { + status = -status; /* bad reply */ + break; } } if (strcmp(p, "PASV") == 0) { - for (p = response_text; *p && *p != ','; p++) - ; /* null body */ + for (p = response_text; *p && *p != ','; p++) { + ; /* null body */ + } - while (--p > response_text && '0' <= *p && *p <= '9') - ; /* null body */ - status = sscanf(p+1, "%d,%d,%d,%d,%d,%d", - &h0, &h1, &h2, &h3, &p0, &p1); + while (--p > response_text && '0' <= *p && *p <= '9') { + ; /* null body */ + } + status = sscanf(p + 1, "%d,%d,%d,%d,%d,%d", + &h0, &h1, &h2, &h3, &p0, &p1); if (status < 4) { fprintf(tfp, "HTFTP: PASV reply has no inet address!\n"); - return -99; + status = HT_NO_CONNECTION; + break; } - passive_port = (p0<<8) + p1; + passive_port = (p0 << 8) + p1; sprintf(dst, "%d.%d.%d.%d", h0, h1, h2, h3); } else if (strcmp(p, "EPSV") == 0) { - unsigned char c0, c1, c2, c3; + char c0, c1, c2, c3; struct sockaddr_storage ss; - int sslen; + LY_SOCKLEN sslen; /* * EPSV bla (|||port|) */ - for (p = response_text; *p && !isspace(*p); p++) - ; /* null body */ - for (/*nothing*/; *p && *p && *p != '('; p++) /*)*/ - ; /* null body */ + for (p = response_text; *p && !isspace(*p); p++) { + ; /* null body */ + } + for ( /*nothing */ ; + *p && *p && *p != '('; + p++) /*) */ + ; /* null body */ status = sscanf(p, "(%c%c%c%d%c)", &c0, &c1, &c2, &p0, &c3); if (status != 5) { fprintf(tfp, "HTFTP: EPSV reply has invalid format!\n"); - return -99; + status = HT_NO_CONNECTION; + break; } passive_port = p0; sslen = sizeof(ss); - if (getpeername(control->socket, (struct sockaddr *)&ss, - &sslen) < 0) { + if (getpeername(control->socket, (struct sockaddr *) &ss, + &sslen) < 0) { fprintf(tfp, "HTFTP: getpeername(control) failed\n"); - return -99; + status = HT_NO_CONNECTION; + break; } - if (getnameinfo((struct sockaddr *)&ss, sslen, dst, - sizeof(dst), NULL, 0, NI_NUMERICHOST)) { + if (getnameinfo((struct sockaddr *) &ss, sslen, dst, + sizeof(dst), NULL, 0, NI_NUMERICHOST)) { fprintf(tfp, "HTFTP: getnameinfo failed\n"); - return -99; + status = HT_NO_CONNECTION; + break; } } #else status = send_cmd_1("PASV"); if (status != 2) { if (status < 0) - continue; /* retry or Bad return */ - return -status; /* bad reply */ + continue; /* retry or Bad return */ + status = -status; /* bad reply */ + break; + } + for (p = response_text; *p && *p != ','; p++) { + ; /* null body */ } - for (p = response_text; *p && *p != ','; p++) - ; /* null body */ - while (--p > response_text && '0' <= *p && *p <= '9') - ; /* null body */ + while (--p > response_text && '0' <= *p && *p <= '9') { + ; /* null body */ + } - status = sscanf(p+1, "%d,%d,%d,%d,%d,%d", + status = sscanf(p + 1, "%d,%d,%d,%d,%d,%d", &h0, &h1, &h2, &h3, &p0, &p1); if (status < 4) { fprintf(tfp, "HTFTP: PASV reply has no inet address!\n"); - return -99; + status = HT_NO_CONNECTION; + break; } - passive_port = (PortNumber)((p0<<8) + p1); + passive_port = (PortNumber) ((p0 << 8) + p1); #endif /* INET6 */ CTRACE((tfp, "HTFTP: Server is listening on port %d\n", - passive_port)); + passive_port)); /* Open connection for data: */ @@ -3074,7 +3146,7 @@ PRIVATE int setup_connection ARGS2( HTSprintf0(&command, "%s//%s:%d/", STR_FTP_URL, dst, passive_port); #else HTSprintf0(&command, "%s//%d.%d.%d.%d:%d/", - STR_FTP_URL, h0, h1, h2, h3, passive_port); + STR_FTP_URL, h0, h1, h2, h3, passive_port); #endif status = HTDoConnect(command, "FTP data", passive_port, &data_soc); FREE(command); @@ -3082,68 +3154,75 @@ PRIVATE int setup_connection ARGS2( if (status < 0) { (void) HTInetStatus(gettext("connect for data")); NETCLOSE(data_soc); - return status; /* Bad return */ + break; } CTRACE((tfp, "FTP data connected, socket %d\n", data_soc)); } status = 0; - break; /* No more retries */ + break; /* No more retries */ - } /* for retries */ + } /* for retries */ + CTRACE((tfp, "setup_connection returns %d\n", status)); return status; } /* Retrieve File from Server -** ------------------------- -** -** On entry, -** name WWW address of a file: document, including hostname -** On exit, -** returns Socket number for file if good. -** <0 if bad. -*/ -PUBLIC int HTFTPLoad ARGS4( - CONST char *, name, - HTParentAnchor *, anchor, - HTFormat, format_out, - HTStream *, sink) + * ------------------------- + * + * On entry, + * name WWW address of a file: document, including hostname + * On exit, + * returns Socket number for file if good. + * <0 if bad. + */ +int HTFTPLoad(const char *name, + HTParentAnchor *anchor, + HTFormat format_out, + HTStream *sink) { BOOL isDirectory = NO; - HTAtom * encoding = NULL; + HTAtom *encoding = NULL; int status, final_status; int outstanding = 1; /* outstanding control connection responses + that we are willing to wait for, if we get to the point of reading data - kw */ HTFormat format; - CTRACE((tfp, "HTFTPLoad(%s) %s connection\n", name, ftp_local_passive ? "passive" : "normal")); + CTRACE((tfp, "HTFTPLoad(%s) %s connection\n", + name, + (ftp_local_passive + ? "passive" + : "normal"))); - HTReadProgress(0,0); + HTReadProgress(0, 0); status = setup_connection(name, anchor); if (status < 0) return status; /* Failed with this code */ -/* Ask for the file: -*/ + /* Ask for the file: + */ { char *filename = HTParse(name, "", PARSE_PATH + PARSE_PUNCTUATION); - char *fname = filename; /** Save for subsequent free() **/ + char *fname = filename; /* Save for subsequent free() */ char *vmsname = NULL; BOOL binary; - char *type = NULL; + const char *type = NULL; + char *types = NULL; char *cp; if (server_type == CMS_SERVER) { - /** If the unescaped path has a %2f, reject it as illegal. - FM **/ + /* If the unescaped path has a %2f, reject it as illegal. - FM */ if (((cp = strstr(filename, "%2")) != NULL) && TOUPPER(cp[2]) == 'F') { FREE(fname); - init_help_message_cache(); /* to free memory */ + init_help_message_cache(); /* to free memory */ NETCLOSE(control->socket); control->socket = -1; - CTRACE((tfp, "HTFTP: Rejecting path due to illegal escaped slash.\n")); + CTRACE((tfp, + "HTFTP: Rejecting path due to illegal escaped slash.\n")); return -1; } } @@ -3151,22 +3230,22 @@ PUBLIC int HTFTPLoad ARGS4( if (!*filename) { StrAllocCopy(filename, "/"); type = "D"; - } else if ((type = strrchr(filename, ';')) != NULL) { + } else if ((type = types = strrchr(filename, ';')) != NULL) { /* - ** Check and trim the type= parameter. - FM - */ - if (!strncasecomp((type+1), "type=", 5)) { - switch(TOUPPER(*(type+6))) { + * Check and trim the type= parameter. - FM + */ + if (!strncasecomp((type + 1), "type=", 5)) { + switch (TOUPPER(*(type + 6))) { case 'D': - *type = '\0'; + *types = '\0'; type = "D"; break; case 'A': - *type = '\0'; + *types = '\0'; type = "A"; break; case 'I': - *type = '\0'; + *types = '\0'; type = "I"; break; default: @@ -3175,7 +3254,7 @@ PUBLIC int HTFTPLoad ARGS4( } if (!*filename) { *filename = '/'; - *(filename+1) = '\0'; + *(filename + 1) = '\0'; } } if (*type != '\0') { @@ -3186,26 +3265,26 @@ PUBLIC int HTFTPLoad ARGS4( CTRACE((tfp, "HTFTP: UnEscaped %s\n", filename)); if (filename[1] == '~') { /* - ** Check if translation of HOME as tilde is supported, - ** and adjust filename if so. - FM - */ + * Check if translation of HOME as tilde is supported, + * and adjust filename if so. - FM + */ char *cp2 = NULL; char *fn = NULL; - if ((cp2 = strchr((filename+1), '/')) != NULL) { + if ((cp2 = strchr((filename + 1), '/')) != NULL) { *cp2 = '\0'; } status = send_cmd_1("PWD"); if (status == 2 && response_text[5] == '/') { - status = send_cwd(filename+1); + status = send_cwd(filename + 1); if (status == 2) { - StrAllocCopy(fn, (filename+1)); + StrAllocCopy(fn, (filename + 1)); if (cp2) { *cp2 = '/'; - if (fn[strlen(fn)-1] != '/') { + if (fn[strlen(fn) - 1] != '/') { StrAllocCat(fn, cp2); } else { - StrAllocCat(fn, (cp2+1)); + StrAllocCat(fn, (cp2 + 1)); } cp2 = NULL; } @@ -3219,14 +3298,15 @@ PUBLIC int HTFTPLoad ARGS4( } if (strlen(filename) > 3) { char *cp2; - if (((cp2=strrchr(filename, '.')) != NULL && + + if (((cp2 = strrchr(filename, '.')) != NULL && 0 == strncasecomp(cp2, ".me", 3)) && (cp2[3] == '\0' || cp2[3] == ';')) { /* - ** Don't treat this as application/x-Troff-me - ** if it's a Unix server but has the string - ** "read.me", or if it's not a Unix server. - FM - */ + * Don't treat this as application/x-Troff-me if it's a Unix + * server but has the string "read.me", or if it's not a Unix + * server. - FM + */ if ((server_type != UNIX_SERVER) || (cp2 > (filename + 3) && 0 == strncasecomp((cp2 - 4), "read.me", 7))) { @@ -3244,15 +3324,14 @@ PUBLIC int HTFTPLoad ARGS4( } format = HTCharsetFormat(format, anchor, -1); binary = (BOOL) (encoding != HTAtom_for("8bit") && - encoding != HTAtom_for("7bit")); + encoding != HTAtom_for("7bit")); if (!binary && - /* - ** Force binary if we're in source, download or dump - ** mode and this is not a VM/CMS server, so we don't - ** get CRLF instead of LF (or CR) for newlines in text - ** files. Can't do this for VM/CMS or we'll get - ** raw EBCDIC. - FM - */ + /* + * Force binary if we're in source, download or dump mode and this is + * not a VM/CMS server, so we don't get CRLF instead of LF (or CR) for + * newlines in text files. Can't do this for VM/CMS or we'll get raw + * EBCDIC. - FM + */ (format_out == WWW_SOURCE || format_out == HTAtom_for("www/download") || format_out == HTAtom_for("www/dump")) && @@ -3260,126 +3339,178 @@ PUBLIC int HTFTPLoad ARGS4( binary = TRUE; if (!binary && type && *type == 'I') { /* - ** Force binary if we had ;type=I - FM - */ + * Force binary if we had ;type=I - FM + */ binary = TRUE; } else if (binary && type && *type == 'A') { /* - ** Force ASCII if we had ;type=A - FM - */ + * Force ASCII if we had ;type=A - FM + */ binary = FALSE; } if (binary != control->binary) { /* - ** Act on our setting if not already set. - FM - */ - char * mode = binary ? "I" : "A"; + * Act on our setting if not already set. - FM + */ + const char *mode = binary ? "I" : "A"; + status = send_cmd_2("TYPE", mode); if (status != 2) { - init_help_message_cache(); /* to free memory */ + init_help_message_cache(); /* to free memory */ return ((status < 0) ? status : -status); } control->binary = binary; } switch (server_type) { - /* - ** Handle what for Lynx are special case servers, e.g., - ** for which we respect RFC 1738, or which have known - ** conflicts in suffix mappings. - FM - */ + /* + * Handle what for Lynx are special case servers, e.g., for which + * we respect RFC 1738, or which have known conflicts in suffix + * mappings. - FM + */ case VMS_SERVER: - { - char *cp1, *cp2; - BOOL included_device = FALSE; - BOOL found_tilde = FALSE; - /** Accept only Unix-style filename **/ - if (strchr(filename, ':') != NULL || - strchr(filename, '[') != NULL) { - FREE(fname); - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - CTRACE((tfp, "HTFTP: Rejecting path due to non-Unix-style syntax.\n")); - return -1; - } - /** Handle any unescaped "/%2F" path **/ - if (!strncmp(filename, "//", 2)) { - int i; - included_device = TRUE; - for (i = 0; filename[(i+1)]; i++) - filename[i] = filename[(i+1)]; - filename[i] = '\0'; - CTRACE((tfp, "HTFTP: Trimmed '%s'\n", filename)); - cp = HTVMS_name("", filename); - CTRACE((tfp, "HTFTP: VMSized '%s'\n", cp)); - if ((cp1=strrchr(cp, ']')) != NULL) { - strcpy(filename, ++cp1); - CTRACE((tfp, "HTFTP: Filename '%s'\n", filename)); - *cp1 = '\0'; - status = send_cwd(cp); - if (status != 2) { - char *dotslash = 0; - if ((cp1=strchr(cp, '[')) != NULL) { - *cp1++ = '\0'; - status = send_cwd(cp); - if (status != 2) { - FREE(fname); - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); - } - HTSprintf0(&dotslash, "[.%s", cp1); - status = send_cwd(dotslash); - FREE(dotslash); - if (status != 2) { + { + char *cp1, *cp2; + BOOL included_device = FALSE; + BOOL found_tilde = FALSE; + + /* Accept only Unix-style filename */ + if (strchr(filename, ':') != NULL || + strchr(filename, '[') != NULL) { + FREE(fname); + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + CTRACE((tfp, + "HTFTP: Rejecting path due to non-Unix-style syntax.\n")); + return -1; + } + /* Handle any unescaped "/%2F" path */ + if (!strncmp(filename, "//", 2)) { + int i; + + included_device = TRUE; + for (i = 0; filename[(i + 1)]; i++) + filename[i] = filename[(i + 1)]; + filename[i] = '\0'; + CTRACE((tfp, "HTFTP: Trimmed '%s'\n", filename)); + cp = HTVMS_name("", filename); + CTRACE((tfp, "HTFTP: VMSized '%s'\n", cp)); + if ((cp1 = strrchr(cp, ']')) != NULL) { + strcpy(filename, ++cp1); + CTRACE((tfp, "HTFTP: Filename '%s'\n", filename)); + *cp1 = '\0'; + status = send_cwd(cp); + if (status != 2) { + char *dotslash = 0; + + if ((cp1 = strchr(cp, '[')) != NULL) { + *cp1++ = '\0'; + status = send_cwd(cp); + if (status != 2) { + FREE(fname); + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } + HTSprintf0(&dotslash, "[.%s", cp1); + status = send_cwd(dotslash); + FREE(dotslash); + if (status != 2) { + FREE(fname); + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } + } else { FREE(fname); - init_help_message_cache(); /* to free memory */ + init_help_message_cache(); /* to free memory */ NETCLOSE(control->socket); control->socket = -1; return ((status < 0) ? status : -status); } - } else { - FREE(fname); - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); } - } - } else if ((cp1=strchr(cp, ':')) != NULL && - strchr(cp, '[') == NULL && - strchr(cp, ']') == NULL) { - cp1++; - if (*cp1 != '\0') { - strcpy(filename, cp1); - CTRACE((tfp, "HTFTP: Filename '%s'\n", filename)); - HTSprintf0(&vmsname, "%.*s[%s]", cp1-cp, cp, filename); - status = send_cwd(vmsname); - if (status != 2) { - HTSprintf(&vmsname, "%.*s[000000]", cp1-cp, cp); + } else if ((cp1 = strchr(cp, ':')) != NULL && + strchr(cp, '[') == NULL && + strchr(cp, ']') == NULL) { + cp1++; + if (*cp1 != '\0') { + int cplen = (int) (cp1 - cp); + + strcpy(filename, cp1); + CTRACE((tfp, "HTFTP: Filename '%s'\n", filename)); + HTSprintf0(&vmsname, "%.*s[%s]", cplen, cp, filename); status = send_cwd(vmsname); if (status != 2) { - HTSprintf(&vmsname, "%.*s", cp1-cp, cp); + HTSprintf(&vmsname, "%.*s[000000]", cplen, cp); status = send_cwd(vmsname); if (status != 2) { - FREE(fname); - init_help_message_cache(); - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); + HTSprintf(&vmsname, "%.*s", cplen, cp); + status = send_cwd(vmsname); + if (status != 2) { + FREE(fname); + init_help_message_cache(); + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } } + } else { + HTSprintf0(&vmsname, "000000"); + filename = vmsname; } - } else { - HTSprintf0(&vmsname, "000000"); - filename = vmsname; } + } else if (0 == strcmp(cp, (filename + 1))) { + status = send_cwd(cp); + if (status != 2) { + HTSprintf0(&vmsname, "%s:", cp); + status = send_cwd(vmsname); + if (status != 2) { + FREE(fname); + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } + } + HTSprintf0(&vmsname, "000000"); + filename = vmsname; } - } else if (0==strcmp(cp, (filename+1))) { - status = send_cwd(cp); + } + /* Trim trailing slash if filename is not the top directory */ + if (strlen(filename) > 1 && filename[strlen(filename) - 1] == '/') + filename[strlen(filename) - 1] = '\0'; + +#ifdef MAINTAIN_CONNECTION /* Don't need this if always new connection - F.M. */ + if (!included_device) { + /* Get the current default VMS device:[directory] */ + status = send_cmd_1("PWD"); if (status != 2) { - HTSprintf0(&vmsname, "%s:", cp); - status = send_cwd(vmsname); + FREE(fname); + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } + /* Go to the VMS account's top directory */ + if ((cp = strchr(response_text, '[')) != NULL && + (cp1 = strrchr(response_text, ']')) != NULL) { + char *tmp = 0; + unsigned len = 4; + + StrAllocCopy(tmp, cp); + if ((cp2 = strchr(cp, '.')) != NULL && cp2 < cp1) { + len += (cp2 - cp); + } else { + len += (cp1 - cp); + } + tmp[len] = 0; + StrAllocCat(tmp, "]"); + + status = send_cwd(tmp); + FREE(tmp); + if (status != 2) { FREE(fname); init_help_message_cache(); /* to free memory */ @@ -3388,188 +3519,143 @@ PUBLIC int HTFTPLoad ARGS4( return ((status < 0) ? status : -status); } } - HTSprintf0(&vmsname, "000000"); - filename = vmsname; } - } - /** Trim trailing slash if filename is not the top directory **/ - if (strlen(filename) > 1 && filename[strlen(filename)-1] == '/') - filename[strlen(filename)-1] = '\0'; +#endif /* MAINTAIN_CONNECTION */ -#ifdef MAINTAIN_CONNECTION /* Don't need this if always new connection - F.M. */ - if (!included_device) { - /** Get the current default VMS device:[directory] **/ - status = send_cmd_1("PWD"); - if (status != 2) { + /* If we want the VMS account's top directory, list it now */ + if (!(strcmp(filename, "/~")) || + (included_device && 0 == strcmp(filename, "000000")) || + (strlen(filename) == 1 && *filename == '/')) { + isDirectory = YES; + status = send_cmd_1("LIST"); FREE(fname); - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); + if (status != 1) { + /* Action not started */ + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } + /* Big goto! */ + goto listen; } - /** Go to the VMS account's top directory **/ - if ((cp=strchr(response_text, '[')) != NULL && - (cp1=strrchr(response_text, ']')) != NULL) { + /* Otherwise, go to appropriate directory and doctor filename */ + if (!strncmp(filename, "/~", 2)) { + filename += 2; + found_tilde = TRUE; + } + CTRACE((tfp, "check '%s' to translate x/y/ to [.x.y]\n", filename)); + if (!included_device && + (cp = strchr(filename, '/')) != NULL && + (cp1 = strrchr(cp, '/')) != NULL && + (cp1 - cp) > 1) { char *tmp = 0; - unsigned len = 4; - StrAllocCopy(tmp, cp); - if ((cp2=strchr(cp, '.')) != NULL && cp2 < cp1) { - len += (cp2 - cp); - } else { - len += (cp1 - cp); - } - tmp[len] = 0; - StrAllocCat(tmp, "]"); + HTSprintf0(&tmp, "[.%.*s]", (int) (cp1 - cp - 1), cp + 1); + + CTRACE((tfp, "change path '%s'\n", tmp)); + while ((cp2 = strrchr(tmp, '/')) != NULL) + *cp2 = '.'; + CTRACE((tfp, "...to path '%s'\n", tmp)); status = send_cwd(tmp); FREE(tmp); if (status != 2) { FREE(fname); - init_help_message_cache(); /* to free memory */ + init_help_message_cache(); /* to free memory */ NETCLOSE(control->socket); control->socket = -1; return ((status < 0) ? status : -status); } + filename = cp1 + 1; + } else { + if (!included_device && !found_tilde) { + filename += 1; + } } + break; } -#endif /* MAINTAIN_CONNECTION */ - - /** If we want the VMS account's top directory, list it now **/ - if (!(strcmp(filename, "/~")) || - (included_device && 0==strcmp(filename, "000000")) || - (strlen(filename) == 1 && *filename == '/')) { - isDirectory = YES; - status = send_cmd_1("LIST"); - FREE(fname); - if (status != 1) { - /* Action not started */ - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); - } - /** Big goto! **/ - goto listen; - } - /** Otherwise, go to appropriate directory and doctor filename **/ - if (!strncmp(filename, "/~", 2)) { - filename += 2; - found_tilde = TRUE; - } - CTRACE((tfp, "check '%s' to translate x/y/ to [.x.y]\n", filename)); - if (!included_device && - (cp = strchr(filename, '/')) != NULL && - (cp1 = strrchr(cp, '/')) != NULL && - (cp1 - cp) > 1) { - char *tmp = 0; - - HTSprintf0(&tmp, "[.%.*s]", cp1-cp-1, cp+1); - - CTRACE((tfp, "change path '%s'\n", tmp)); - while ((cp2 = strrchr(tmp, '/')) != NULL) - *cp2 = '.'; - CTRACE((tfp, "...to path '%s'\n", tmp)); - - status = send_cwd(tmp); - FREE(tmp); - - if (status != 2) { - FREE(fname); - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); - } - filename = cp1+1; - } else { - if (!included_device && !found_tilde) { - filename += 1; - } - } - break; - } case CMS_SERVER: - { - /* - ** If we want the CMS account's top directory, or a base - ** SFS or anonymous directory path (i.e., without a slash), - ** list it now. FM - */ - if ((strlen(filename) == 1 && *filename == '/') || - ((0 == strncasecomp((filename+1), "vmsysu:", 7)) && - (cp = strchr((filename+1), '.')) != NULL && - strchr(cp, '/') == NULL) || - (0 == strncasecomp(filename+1, "anonymou.", 9) && - strchr(filename+1, '/') == NULL)) { - if (filename[1] != '\0') { - status = send_cwd(filename+1); - if (status != 2) { + { + /* + * If we want the CMS account's top directory, or a base SFS or + * anonymous directory path (i.e., without a slash), list it + * now. FM + */ + if ((strlen(filename) == 1 && *filename == '/') || + ((0 == strncasecomp((filename + 1), "vmsysu:", 7)) && + (cp = strchr((filename + 1), '.')) != NULL && + strchr(cp, '/') == NULL) || + (0 == strncasecomp(filename + 1, "anonymou.", 9) && + strchr(filename + 1, '/') == NULL)) { + if (filename[1] != '\0') { + status = send_cwd(filename + 1); + if (status != 2) { + /* Action not started */ + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } + } + isDirectory = YES; + if (use_list) + status = send_cmd_1("LIST"); + else + status = send_cmd_1("NLST"); + FREE(fname); + if (status != 1) { /* Action not started */ - init_help_message_cache(); /* to free memory */ + init_help_message_cache(); /* to free memory */ NETCLOSE(control->socket); control->socket = -1; return ((status < 0) ? status : -status); } + /* Big goto! */ + goto listen; } - isDirectory = YES; - if (use_list) - status = send_cmd_1("LIST"); - else - status = send_cmd_1("NLST"); - FREE(fname); - if (status != 1) { - /* Action not started */ - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); - } - /** Big goto! **/ - goto listen; - } - filename++; + filename++; - /** Otherwise, go to appropriate directory and adjust filename **/ - while ((cp = strchr(filename, '/')) != NULL) { - *cp++ = '\0'; - status = send_cwd(filename); - if (status == 2) { - if (*cp == '\0') { - isDirectory = YES; - if (use_list) - status = send_cmd_1("LIST"); - else - status = send_cmd_1("NLST"); - FREE(fname); - if (status != 1) { - /** Action not started **/ - init_help_message_cache(); /* to free memory */ - NETCLOSE(control->socket); - control->socket = -1; - return ((status < 0) ? status : -status); + /* Otherwise, go to appropriate directory and adjust filename */ + while ((cp = strchr(filename, '/')) != NULL) { + *cp++ = '\0'; + status = send_cwd(filename); + if (status == 2) { + if (*cp == '\0') { + isDirectory = YES; + if (use_list) + status = send_cmd_1("LIST"); + else + status = send_cmd_1("NLST"); + FREE(fname); + if (status != 1) { + /* Action not started */ + init_help_message_cache(); /* to free memory */ + NETCLOSE(control->socket); + control->socket = -1; + return ((status < 0) ? status : -status); + } + /* Clear any messages from the login directory */ + init_help_message_cache(); + /* Big goto! */ + goto listen; } - /** Clear any messages from the login directory **/ - init_help_message_cache(); - /** Big goto! **/ - goto listen; + filename = cp; } - filename = cp; } + break; } - break; - } default: - /** Shift for any unescaped "/%2F" path **/ + /* Shift for any unescaped "/%2F" path */ if (!strncmp(filename, "//", 2)) filename++; break; } /* - ** Act on a file or listing request, or try to figure out - ** which we're dealing with if we don't know yet. - FM - */ + * Act on a file or listing request, or try to figure out which we're + * dealing with if we don't know yet. - FM + */ if (!(type) || (type && *type != 'D')) { status = send_cmd_2("RETR", filename); #ifdef BROKEN_PROFTPD @@ -3593,7 +3679,7 @@ PUBLIC int HTFTPLoad ARGS4( status = 5; /* Failed status set as flag. - FM */ } if (status != 1) { /* Failed : try to CWD to it */ - /** Clear any login messages if this isn't the login directory **/ + /* Clear any login messages if this isn't the login directory */ if (strcmp(filename, "/")) init_help_message_cache(); @@ -3619,34 +3705,36 @@ PUBLIC int HTFTPLoad ARGS4( } } -listen: - if(!ftp_local_passive) { + listen: + if (!ftp_local_passive) { /* Wait for the connection */ #ifdef INET6 struct sockaddr_storage soc_address; + #else struct sockaddr_in soc_address; #endif /* INET6 */ - int soc_addrlen=sizeof(soc_address); + LY_SOCKLEN soc_addrlen = sizeof(soc_address); + #ifdef SOCKS if (socks_flag) status = Raccept(master_socket, - (struct sockaddr *)&soc_address, - (void *)&soc_addrlen); + (struct sockaddr *) &soc_address, + &soc_addrlen); else #endif /* SOCKS */ - status = accept(master_socket, - (struct sockaddr *)&soc_address, - (void *)&soc_addrlen); + status = accept(master_socket, + (struct sockaddr *) &soc_address, + &soc_addrlen); if (status < 0) { init_help_message_cache(); /* to free memory */ return HTInetStatus("accept"); } CTRACE((tfp, "TCP: Accepted new socket %d\n", status)); data_soc = status; - } /* !ftp_local_passive */ - -#if 0 /* no - this makes the data connection go away too soon (2.8.3dev.22) */ + } + /* !ftp_local_passive */ +#if 0 /* no - this makes the data connection go away too soon (2.8.3dev.22) */ if ((status = send_cmd_nowait("QUIT")) == 1) outstanding++; #endif @@ -3658,7 +3746,7 @@ listen: CTRACE((tfp, "HTFTP: Treating as \"dls\" server.\n")); server_type = DLS_SERVER; } - final_status = read_directory (anchor, name, format_out, sink); + final_status = read_directory(anchor, name, format_out, sink); if (final_status > 0) { if (server_type != CMS_SERVER) if (outstanding-- > 0) { @@ -3674,7 +3762,7 @@ listen: outstanding = 0; } - if (data_soc != -1) { /* normally done in read_directory */ + if (data_soc != -1) { /* normally done in read_directory */ CTRACE((tfp, "HTFTP: Closing data socket %d\n", data_soc)); status = NETCLOSE(data_soc); if (status == -1) @@ -3685,27 +3773,26 @@ listen: int rv; char *FileName = HTParse(name, "", PARSE_PATH + PARSE_PUNCTUATION); - /** Clear any login messages **/ + /* Clear any login messages */ init_help_message_cache(); - /** Fake a Content-Encoding for compressed files. - FM **/ + /* Fake a Content-Encoding for compressed files. - FM */ HTUnEscape(FileName); if (!IsUnityEnc(encoding)) { /* - * We already know from the call to HTFileFormat above that - * this is a compressed file, no need to look at the filename - * again. - kw + * We already know from the call to HTFileFormat above that this is + * a compressed file, no need to look at the filename again. - kw */ StrAllocCopy(anchor->content_type, format->name); StrAllocCopy(anchor->content_encoding, HTAtom_name(encoding)); format = HTAtom_for("www/compressed"); } else { - char *dot; - CompressFileType cft = HTCompressFileType(FileName, "._-", &dot); + int rootlen; + CompressFileType cft = HTCompressFileType(FileName, "._-", &rootlen); if (cft != cftNone) { - *dot = '\0'; + FileName[rootlen] = '\0'; format = HTFileFormat(FileName, &encoding, NULL); format = HTCharsetFormat(format, anchor, -1); StrAllocCopy(anchor->content_type, format->name); @@ -3718,24 +3805,27 @@ listen: case cftGzip: StrAllocCopy(anchor->content_encoding, "x-gzip"); break; + case cftDeflate: + StrAllocCopy(anchor->content_encoding, "x-deflate"); + break; case cftBzip2: StrAllocCopy(anchor->content_encoding, "x-bzip2"); break; - default: + case cftNone: break; } } } FREE(FileName); - _HTProgress (gettext("Receiving FTP file.")); + _HTProgress(gettext("Receiving FTP file.")); rv = HTParseSocket(format, format_out, anchor, data_soc, sink); HTInitInput(control->socket); /* Reset buffering to control connection DD 921208 */ if (rv < 0) { -#if 0 /* any known servers where ABOR would work this way? */ +#if 0 /* any known servers where ABOR would work this way? */ if (rv == HT_INTERRUPTED || rv == -501) if (send_cmd_nowait("ABOR") == 1) { outstanding++; @@ -3752,16 +3842,16 @@ listen: CTRACE((tfp, "HTFTP: Closing data socket %d\n", data_soc)); status = NETCLOSE(data_soc); } else - status = 2; /* data_soc already closed in HTCopy - kw */ + status = 2; /* data_soc already closed in HTCopy - kw */ if (status < 0 && rv != HT_INTERRUPTED && rv != -1) { (void) HTInetStatus("close"); /* Comment only */ } else { if (rv != HT_LOADED && outstanding--) { - status = response(0); /* Pick up final reply */ + status = response(0); /* Pick up final reply */ if (status != 2 && rv != HT_INTERRUPTED && rv != -1) { - data_soc = -1; /* invalidate it */ - init_help_message_cache(); /* to free memory */ + data_soc = -1; /* invalidate it */ + init_help_message_cache(); /* to free memory */ return HTLoadError(sink, 500, response_text); } else if (status <= 0) { outstanding = 0; @@ -3777,7 +3867,7 @@ listen: if (status == 2 && !strncmp(response_text, "221", 3)) break; } - data_soc = -1; /* invalidate it */ + data_soc = -1; /* invalidate it */ CTRACE((tfp, "HTFTPLoad: normal end; ")); if (control->socket < 0) { CTRACE((tfp, "control socket is %d\n", control->socket)); @@ -3788,28 +3878,26 @@ listen: HTInetStatus("control connection close"); /* Comment only */ } control->socket = -1; - init_help_message_cache(); /* to free memory */ - /* returns HT_LOADED (always for file if we get here) or error */ + init_help_message_cache(); /* to free memory */ + /* returns HT_LOADED (always for file if we get here) or error */ return final_status; -} /* open_file_read */ +} /* open_file_read */ /* -** This function frees any user entered password, so that -** it must be entered again for a future request. - FM -*/ -PUBLIC void HTClearFTPPassword NOARGS + * This function frees any user entered password, so that + * it must be entered again for a future request. - FM + */ +void HTClearFTPPassword(void) { /* - ** Need code to check cached documents from - ** non-anonymous ftp accounts and do something - ** to ensure that they no longer can be accessed - ** without a new retrieval. - FM - */ + * Need code to check cached documents from non-anonymous ftp accounts and + * do something to ensure that they no longer can be accessed without a new + * retrieval. - FM + */ /* - ** Now free the current user entered password, - ** if any. - FM - */ + * Now free the current user entered password, if any. - FM + */ FREE(user_entered_password); } |
