ReactOS 0.4.15-dev-8100-g1887773
ftp.c File Reference
#include "syshdrs.h"
Include dependency graph for ftp.c:

Go to the source code of this file.

Macros

#define _libncftp_ftp_c_
 
#define UC(x)   (int) (((int) x) & 0xff)
 

Functions

static struct hostentGetHostEntry (char *host, struct in_addr *ip_address)
 
int GetOurHostName (char *host, size_t siz)
 
void CloseControlConnection (const FTPCIPtr cip)
 
static int GetSocketAddress (const FTPCIPtr cip, int sockfd, struct sockaddr_in *saddr)
 
int SetKeepAlive (const FTPCIPtr cip, int sockfd)
 
int SetLinger (const FTPCIPtr cip, int sockfd, int onoff)
 
int OpenControlConnection (const FTPCIPtr cip, char *host, unsigned int port)
 
void CloseDataConnection (const FTPCIPtr cip)
 
int SetStartOffset (const FTPCIPtr cip, longest_int restartPt)
 
static int SendPort (const FTPCIPtr cip, struct sockaddr_in *saddr)
 
static int Passive (const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
 
static int BindToEphemeralPortNumber (int sockfd, struct sockaddr_in *addrp, int ephemLo, int ephemHi)
 
int OpenDataConnection (const FTPCIPtr cip, int mode)
 
void SetLinger (cip, dataSocket, 1)
 
void SetKeepAlive (cip, dataSocket)
 
 return (0)
 
 return (result)
 
int AcceptDataConnection (const FTPCIPtr cip)
 
void HangupOnServer (const FTPCIPtr cip)
 
void SendTelnetInterrupt (const FTPCIPtr cip)
 

Variables

char gLibNcFTPVersion [64] = kLibraryVersion
 
char gNoSignalsMarker [] = "@(#) LibNcFTP - NO_SIGNALS"
 
static char gCopyright [] = "@(#) LibNcFTP Copyright 1995-2000, by Mike Gleason. All rights reserved."
 
cip dataSocket = dataSocket
 
bad __pad0__
 

Macro Definition Documentation

◆ _libncftp_ftp_c_

#define _libncftp_ftp_c_

Definition at line 8 of file ftp.c.

◆ UC

#define UC (   x)    (int) (((int) x) & 0xff)

Function Documentation

◆ AcceptDataConnection()

int AcceptDataConnection ( const FTPCIPtr  cip)

Definition at line 1249 of file ftp.c.

1250{
1251 int newSocket;
1252#ifndef NO_SIGNALS
1253 int len;
1254#endif
1255 unsigned short remoteDataPort;
1256 unsigned short remoteCtrlPort;
1257
1258 /* If we did a PORT, we have some things to finish up.
1259 * If we did a PASV, we're ready to go.
1260 */
1261 if (cip->dataPortMode == kSendPortMode) {
1262 /* Accept will give us back the server's data address; at the
1263 * moment we don't do anything with it though.
1264 */
1265 memset(&cip->servDataAddr, 0, sizeof(cip->servDataAddr));
1266
1267#ifdef NO_SIGNALS
1268 newSocket = SAccept(cip->dataSocket, &cip->servDataAddr, (int) cip->connTimeout);
1269#else /* NO_SIGNALS */
1270 len = (int) sizeof(cip->servDataAddr);
1271 if (cip->connTimeout > 0)
1272 (void) alarm(cip->connTimeout);
1273 newSocket = accept(cip->dataSocket, (struct sockaddr *) &cip->servDataAddr, &len);
1274 if (cip->connTimeout > 0)
1275 (void) alarm(0);
1276#endif /* NO_SIGNALS */
1277
1278 (void) closesocket(cip->dataSocket);
1279 if (newSocket < 0) {
1280 Error(cip, kDoPerror, "Could not accept a data connection.\n");
1283 return (kErrAcceptDataSocket);
1284 }
1285
1286 if (cip->require20 != 0) {
1287 remoteDataPort = ntohs(cip->servDataAddr.sin_port);
1288 remoteCtrlPort = ntohs(cip->servCtlAddr.sin_port);
1289 if ((int) remoteDataPort != ((int) remoteCtrlPort - 1)) {
1290 Error(cip, kDontPerror, "Data connection did not originate on correct port!\n");
1291 (void) closesocket(newSocket);
1294 return (kErrAcceptDataSocket);
1295 } else if (memcmp(&cip->servDataAddr.sin_addr.s_addr, &cip->servCtlAddr.sin_addr.s_addr, sizeof(cip->servDataAddr.sin_addr.s_addr)) != 0) {
1296 Error(cip, kDontPerror, "Data connection did not originate from remote server!\n");
1297 (void) closesocket(newSocket);
1300 return (kErrAcceptDataSocket);
1301 }
1302 }
1303
1304 cip->dataSocket = newSocket;
1305 }
1306
1307 return (0);
1308} /* AcceptDataConnection */
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
BOOL Error
Definition: chkdsk.c:66
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
GLenum GLsizei len
Definition: glext.h:6722
#define ntohs(x)
Definition: module.h:210
#define kDoPerror
Definition: util.h:44
#define kDontPerror
Definition: util.h:45
#define kClosedFileDescriptor
Definition: util.h:47
#define SAccept
Definition: sio.h:81
#define kSendPortMode
Definition: ncftp.h:295
#define closesocket
Definition: ncftp.h:477
#define kErrAcceptDataSocket
Definition: ncftp_errno.h:33
#define memset(x, y, z)
Definition: compat.h:39
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
struct sockaddr_in servDataAddr
Definition: ncftp.h:182
unsigned int connTimeout
Definition: ncftp.h:142
int dataPortMode
Definition: ncftp.h:152
struct sockaddr_in servCtlAddr
Definition: ncftp.h:181

Referenced by FTPStartDataCmd().

◆ BindToEphemeralPortNumber()

static int BindToEphemeralPortNumber ( int  sockfd,
struct sockaddr_in addrp,
int  ephemLo,
int  ephemHi 
)
static

Definition at line 1011 of file ftp.c.

1012{
1013 int i;
1014 int result;
1015 int rangesize;
1016 unsigned short port;
1017
1018 addrp->sin_family = AF_INET;
1019 if (((int) ephemLo == 0) || ((int) ephemLo >= (int) ephemHi)) {
1020 /* Do it the normal way. System will
1021 * pick one, typically in the range
1022 * of 1024-4999.
1023 */
1024 addrp->sin_port = 0; /* Let system pick one. */
1025
1026 result = bind(sockfd, (struct sockaddr *) addrp, sizeof(struct sockaddr_in));
1027 } else {
1028 rangesize = (int) ((int) ephemHi - (int) ephemLo);
1029 result = 0;
1030 for (i=0; i<10; i++) {
1031 port = (unsigned short) (((int) rand() % rangesize) + (int) ephemLo);
1032 addrp->sin_port = port;
1033
1034 result = bind(sockfd, (struct sockaddr *) addrp, sizeof(struct sockaddr_in));
1035 if (result == 0)
1036 break;
1037 if ((errno != 999)
1038 /* This next line is just fodder to
1039 * shut the compiler up about variable
1040 * not being used.
1041 */
1042 && (gCopyright[0] != '\0'))
1043 break;
1044 }
1045 }
1046 return (result);
1047} /* BindToEphemeralPortNumber */
USHORT port
Definition: uri.c:228
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define AF_INET
Definition: tcpip.h:117
GLuint64EXT * result
Definition: glext.h:11304
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
static char gCopyright[]
Definition: ftp.c:28
#define errno
Definition: errno.h:18
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511

Referenced by OpenDataConnection().

◆ CloseControlConnection()

void CloseControlConnection ( const FTPCIPtr  cip)

Definition at line 197 of file ftp.c.

198{
199 /* This will close each file, if it was open. */
200#ifdef NO_SIGNALS
201 SClose(cip->ctrlSocketR, 3);
205#else /* NO_SIGNALS */
206 if (cip->ctrlTimeout > 0)
207 (void) alarm(cip->ctrlTimeout);
208 CloseFile(&cip->cin);
209 CloseFile(&cip->cout);
212 if (cip->ctrlTimeout > 0)
213 (void) alarm(0);
214#endif /* NO_SIGNALS */
215 cip->connected = 0;
216 cip->loggedIn = 0;
217} /* CloseControlConnection */
int SClose(int sfd, int tlen)
Definition: SClose.c:9
void CloseFile(FILE **f)
Definition: util.c:327
void DisposeSReadlineInfo(SReadlineInfo *)
Definition: SReadline.c:57
FILE * cout
Definition: ncftp.h:189
SReadlineInfo ctrlSrl
Definition: ncftp.h:240
unsigned int ctrlTimeout
Definition: ncftp.h:143
FILE * cin
Definition: ncftp.h:188

Referenced by FTPCloseHost(), FTPShutdownHost(), HangupOnServer(), and RunBatch().

◆ CloseDataConnection()

void CloseDataConnection ( const FTPCIPtr  cip)

Definition at line 831 of file ftp.c.

832{
833 if (cip->dataSocket != kClosedFileDescriptor) {
834#ifdef NO_SIGNALS
835 SClose(cip->dataSocket, 3);
836#else /* NO_SIGNALS */
837 if (cip->xferTimeout > 0)
838 (void) alarm(cip->xferTimeout);
840 if (cip->xferTimeout > 0)
841 (void) alarm(0);
842#endif /* NO_SIGNALS */
844 }
845 memset(&cip->ourDataAddr, 0, sizeof(cip->ourDataAddr));
846 memset(&cip->servDataAddr, 0, sizeof(cip->servDataAddr));
847} /* CloseDataConnection */
unsigned int xferTimeout
Definition: ncftp.h:141
struct sockaddr_in ourDataAddr
Definition: ncftp.h:184

Referenced by FTPAbortDataTransfer(), FTPEndDataCmd(), FTPShutdownHost(), HangupOnServer(), and OpenDataConnection().

◆ GetHostEntry()

static struct hostent * GetHostEntry ( char host,
struct in_addr ip_address 
)
static

Definition at line 53 of file ftp.c.

54{
55 struct in_addr ip;
56 struct hostent *hp;
57
58 /* See if the host was given in the dotted IP format, like "36.44.0.2."
59 * If it was, inet_addr will convert that to a 32-bit binary value;
60 * it not, inet_addr will return (-1L).
61 */
62 ip.s_addr = inet_addr(host);
63 if (ip.s_addr != INADDR_NONE) {
64 hp = NULL;
65 } else {
66 /* No IP address, so it must be a hostname, like ftp.wustl.edu. */
67 hp = gethostbyname(host);
68 if (hp != NULL)
69 (void) memcpy(&ip.s_addr, hp->h_addr_list[0], (size_t) hp->h_length);
70 }
71 if (ip_address != NULL)
72 *ip_address = ip;
73 return (hp);
74} /* GetHostEntry */
#define INADDR_NONE
Definition: tcp.c:42
#define NULL
Definition: types.h:112
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
#define inet_addr(cp)
Definition: inet.h:98
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
short h_length
Definition: winsock.h:137
char ** h_addr_list
Definition: winsock.h:138
Definition: tcpip.h:126
Definition: dhcpd.h:62
char * host
Definition: whois.c:55

Referenced by LookupCmd(), and OpenControlConnection().

◆ GetOurHostName()

int GetOurHostName ( char host,
size_t  siz 
)

Definition at line 81 of file ftp.c.

82{
83#ifdef HOSTNAME
84 /* You can hardcode in the name if this routine doesn't work
85 * the way you want it to.
86 */
87 Strncpy(host, HOSTNAME, siz);
88 return (1); /* Success */
89#else
90 struct hostent *hp;
91 int result;
92 char **curAlias;
93 char domain[64];
94 char *cp;
95 int rc;
96
97 host[0] = '\0';
98 result = gethostname(host, (int) siz);
99 if ((result < 0) || (host[0] == '\0')) {
100 return (-1);
101 }
102
103 if (strchr(host, '.') != NULL) {
104 /* gethostname returned full name (like "cse.unl.edu"), instead
105 * of just the node name (like "cse").
106 */
107 return (2); /* Success */
108 }
109
110 hp = gethostbyname(host);
111 if (hp != NULL) {
112 /* Maybe the host entry has the full name. */
113 cp = strchr((char *) hp->h_name, '.');
114 if ((cp != NULL) && (cp[1] != '\0')) {
115 /* The 'name' field for the host entry had full name. */
116 (void) Strncpy(host, (char *) hp->h_name, siz);
117 return (3); /* Success */
118 }
119
120 /* Now try the list of aliases, to see if any of those look real. */
121 for (curAlias = hp->h_aliases; *curAlias != NULL; curAlias++) {
122 cp = strchr(*curAlias, '.');
123 if ((cp != NULL) && (cp[1] != '\0')) {
124 (void) Strncpy(host, *curAlias, siz);
125 return (4); /* Success */
126 }
127 }
128 }
129
130 /* Otherwise, we just have the node name. See if we can get the
131 * domain name ourselves.
132 */
133#ifdef DOMAINNAME
135 rc = 5;
136#else
137 rc = -1;
138 domain[0] = '\0';
139# if defined(HAVE_RES_INIT) && defined(HAVE__RES_DEFDNAME)
140 if (domain[0] == '\0') {
141 (void) res_init();
142 if ((_res.defdname != NULL) && (_res.defdname[0] != '\0')) {
143 (void) STRNCPY(domain, _res.defdname);
144 rc = 6;
145 }
146 }
147# endif /* HAVE_RES_INIT && HAVE__RES_DEFDNAME */
148
149 if (domain[0] == '\0') {
150 FILE *fp;
151 char line[256];
152 char *tok;
153
154 fp = fopen("/etc/resolv.conf", "r");
155 if (fp != NULL) {
156 (void) memset(line, 0, sizeof(line));
157 while (fgets(line, sizeof(line) - 1, fp) != NULL) {
158 if (!isalpha((int) line[0]))
159 continue; /* Skip comment lines. */
160 tok = strtok(line, " \t\n\r");
161 if (tok == NULL)
162 continue; /* Impossible */
163 if (strcmp(tok, "domain") == 0) {
164 tok = strtok(NULL, " \t\n\r");
165 if (tok == NULL)
166 continue; /* syntax error */
167 (void) STRNCPY(domain, tok);
168 rc = 7;
169 break; /* Done. */
170 }
171 }
172 (void) fclose(fp);
173 }
174 }
175#endif /* DOMAINNAME */
176
177 if (domain[0] != '\0') {
178 /* Supposedly, it's legal for a domain name with
179 * a period at the end.
180 */
181 cp = domain + strlen(domain) - 1;
182 if (*cp == '.')
183 *cp = '\0';
184 if (domain[0] != '.')
185 (void) Strncat(host, ".", siz);
186 (void) Strncat(host, domain, siz);
187 }
188 if (rc < 0)
189 host[0] = '\0';
190 return(rc); /* Success */
191#endif /* !HOSTNAME */
192} /* GetOurHostName */
char * Strncat(char *const, const char *const, const size_t)
Definition: Strncat.c:13
char * Strncpy(char *const, const char *const, const size_t)
Definition: Strncpy.c:11
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define isalpha(c)
Definition: acclib.h:74
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
INT WSAAPI gethostname(OUT char FAR *name, IN INT namelen)
Definition: getxbyxx.c:397
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
POINT cp
Definition: magnifier.c:59
#define DOMAINNAME
Definition: options.h:45
#define HOSTNAME
Definition: options.h:42
Definition: cookie.c:42
char * h_name
Definition: winsock.h:134
char ** h_aliases
Definition: winsock.h:135
Definition: parser.c:49

Referenced by FTPInitializeOurHostName().

◆ GetSocketAddress()

static int GetSocketAddress ( const FTPCIPtr  cip,
int  sockfd,
struct sockaddr_in saddr 
)
static

Definition at line 222 of file ftp.c.

223{
224 int len = (int) sizeof (struct sockaddr_in);
225 int result = 0;
226
227 if (getsockname(sockfd, (struct sockaddr *)saddr, &len) < 0) {
228 Error(cip, kDoPerror, "Could not get socket name.\n");
229 cip->errNo = kErrGetSockName;
231 }
232 return (result);
233} /* GetSocketAddress */
#define kErrGetSockName
Definition: ncftp_errno.h:27
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213

Referenced by OpenControlConnection(), and OpenDataConnection().

◆ HangupOnServer()

void HangupOnServer ( const FTPCIPtr  cip)

Definition at line 1314 of file ftp.c.

1315{
1316 /* Since we want to close both sides of the connection for each
1317 * socket, we can just have them closed with close() instead of
1318 * using shutdown().
1319 */
1322} /* HangupOnServer */
void CloseDataConnection(const FTPCIPtr cip)
Definition: ftp.c:831
void CloseControlConnection(const FTPCIPtr cip)
Definition: ftp.c:197

◆ OpenControlConnection()

int OpenControlConnection ( const FTPCIPtr  cip,
char host,
unsigned int  port 
)

Definition at line 347 of file ftp.c.

348{
349 struct in_addr ip_address;
350 int err = 0;
351 int result;
352 int oerrno;
353 volatile int sockfd = -1;
354 volatile int sock2fd = -1;
355 ResponsePtr rp;
356 char **volatile curaddr;
357 struct hostent *hp;
358 char *volatile fhost;
359 unsigned int fport;
360#ifndef NO_SIGNALS
361 volatile FTPSigProc osigint;
362 volatile FTPSigProc osigalrm;
363 volatile FTPCIPtr vcip;
364 int sj;
365#endif /* NO_SIGNALS */
366 const char *firstLine, *secondLine, *srvr;
367
370#ifdef NO_SIGNALS
372#endif /* NO_SIGNALS */
373
374 if (cip->firewallType == kFirewallNotInUse) {
375 fhost = host;
376 fport = port;
377 } else {
378 fhost = cip->firewallHost;
379 fport = cip->firewallPort;
380 }
381 if (fport == 0)
382 fport = cip->lip->defaultPort;
383
384 /* Since we're the client, we just have to get a socket() and
385 * connect() it.
386 */
387 (void) ZERO(cip->servCtlAddr);
388 cip->cin = NULL;
389 cip->cout = NULL;
390
391 /* Make sure we use network byte-order. */
392 fport = (unsigned int) htons((unsigned short) fport);
393
394 cip->servCtlAddr.sin_port = (unsigned short) fport;
395
396 hp = GetHostEntry(fhost, &ip_address);
397
398 if (hp == NULL) {
399 /* Okay, no Host entry, but maybe we have a numeric address
400 * in ip_address we can try.
401 */
402 if (ip_address.s_addr == INADDR_NONE) {
403 Error(cip, kDontPerror, "%s: unknown host.\n", fhost);
404 cip->errNo = kErrHostUnknown;
405 return (kErrHostUnknown);
406 }
407 cip->servCtlAddr.sin_family = AF_INET;
408 cip->servCtlAddr.sin_addr.s_addr = ip_address.s_addr;
409 } else {
410 cip->servCtlAddr.sin_family = hp->h_addrtype;
411 /* We'll fill in the rest of the structure below. */
412 }
413
414 /* After obtaining a socket, try to connect it to a remote
415 * address. If we didn't get a host entry, we will only have
416 * one thing to try (ip_address); if we do have one, we can try
417 * every address in the list from the host entry.
418 */
419
420 if (hp == NULL) {
421 /* Since we're given a single raw address, and not a host entry,
422 * we can only try this one address and not any other addresses
423 * that could be present for a site with a host entry.
424 */
425
426 if ((sockfd = socket(cip->servCtlAddr.sin_family, SOCK_STREAM, 0)) < 0) {
427 Error(cip, kDoPerror, "Could not get a socket.\n");
429 return (kErrNewStreamSocket);
430 }
431
432 /* This doesn't do anything if you left these
433 * at their defaults (zero). Otherwise it
434 * tries to set the buffer size to the
435 * size specified.
436 */
438
439#ifdef NO_SIGNALS
440 err = SConnect(sockfd, &cip->servCtlAddr, (int) cip->connTimeout);
441
442 if (err < 0) {
443 oerrno = errno;
444 (void) SClose(sockfd, 3);
445 errno = oerrno;
446 sockfd = -1;
447 }
448#else /* NO_SIGNALS */
449 osigint = (volatile FTPSigProc) signal(SIGINT, CancelConnect);
450 if (cip->connTimeout > 0) {
451 osigalrm = (volatile FTPSigProc) signal(SIGALRM, CancelConnect);
452 (void) alarm(cip->connTimeout);
453 }
454
455 vcip = cip;
456
457#ifdef HAVE_SIGSETJMP
458 sj = sigsetjmp(gCancelConnectJmp, 1);
459#else
460 sj = setjmp(gCancelConnectJmp);
461#endif /* HAVE_SIGSETJMP */
462
463 if (sj != 0) {
464 /* Interrupted by a signal. */
465 (void) closesocket(sockfd);
466 (void) signal(SIGINT, (FTPSigProc) osigint);
467 if (vcip->connTimeout > 0) {
468 (void) alarm(0);
469 (void) signal(SIGALRM, (FTPSigProc) osigalrm);
470 }
471 if (gGotSig == SIGINT) {
473 Error(vcip, kDontPerror, "Connection attempt canceled.\n");
474 (void) kill(getpid(), SIGINT);
475 } else if (gGotSig == SIGALRM) {
477 Error(vcip, kDontPerror, "Connection attempt timed-out.\n");
478 (void) kill(getpid(), SIGALRM);
479 } else {
481 Error(vcip, kDontPerror, "Connection attempt failed due to an unexpected signal (%d).\n", gGotSig);
482 }
483 return (result);
484 } else {
485 err = connect(sockfd, (struct sockaddr *) &cip->servCtlAddr,
486 (int) sizeof (cip->servCtlAddr));
487 if (cip->connTimeout > 0) {
488 (void) alarm(0);
489 (void) signal(SIGALRM, (FTPSigProc) osigalrm);
490 }
491 (void) signal(SIGINT, (FTPSigProc) osigint);
492 }
493
494 if (err < 0) {
495 oerrno = errno;
496 (void) closesocket(sockfd);
497 errno = oerrno;
498 sockfd = -1;
499 }
500#endif /* NO_SIGNALS */
501 } else {
502 /* We can try each address in the list. We'll quit when we
503 * run out of addresses to try or get a successful connection.
504 */
505 for (curaddr = hp->h_addr_list; *curaddr != NULL; curaddr++) {
506 if ((sockfd = socket(cip->servCtlAddr.sin_family, SOCK_STREAM, 0)) < 0) {
507 Error(cip, kDoPerror, "Could not get a socket.\n");
509 return (kErrNewStreamSocket);
510 }
511 /* This could overwrite the address field in the structure,
512 * but this is okay because the structure has a junk field
513 * just for this purpose.
514 */
515 (void) memcpy(&cip->servCtlAddr.sin_addr, *curaddr, (size_t) hp->h_length);
516
517 /* This doesn't do anything if you left these
518 * at their defaults (zero). Otherwise it
519 * tries to set the buffer size to the
520 * size specified.
521 */
523
524#ifdef NO_SIGNALS
525 err = SConnect(sockfd, &cip->servCtlAddr, (int) cip->connTimeout);
526
527 if (err == 0)
528 break;
529 oerrno = errno;
530 (void) SClose(sockfd, 3);
531 errno = oerrno;
532 sockfd = -1;
533#else /* NO_SIGNALS */
534
535 osigint = (volatile FTPSigProc) signal(SIGINT, CancelConnect);
536 if (cip->connTimeout > 0) {
537 osigalrm = (volatile FTPSigProc) signal(SIGALRM, CancelConnect);
538 (void) alarm(cip->connTimeout);
539 }
540
541 vcip = cip;
542#ifdef HAVE_SIGSETJMP
543 sj = sigsetjmp(gCancelConnectJmp, 1);
544#else
545 sj = setjmp(gCancelConnectJmp);
546#endif /* HAVE_SIGSETJMP */
547
548 if (sj != 0) {
549 /* Interrupted by a signal. */
550 (void) closesocket(sockfd);
551 (void) signal(SIGINT, (FTPSigProc) osigint);
552 if (vcip->connTimeout > 0) {
553 (void) alarm(0);
554 (void) signal(SIGALRM, (FTPSigProc) osigalrm);
555 }
556 if (gGotSig == SIGINT) {
558 Error(vcip, kDontPerror, "Connection attempt canceled.\n");
559 (void) kill(getpid(), SIGINT);
560 } else if (gGotSig == SIGALRM) {
562 Error(vcip, kDontPerror, "Connection attempt timed-out.\n");
563 (void) kill(getpid(), SIGALRM);
564 } else {
566 Error(vcip, kDontPerror, "Connection attempt failed due to an unexpected signal (%d).\n", gGotSig);
567 }
568 return (result);
569 } else {
570 err = connect(sockfd, (struct sockaddr *) &cip->servCtlAddr,
571 (int) sizeof (cip->servCtlAddr));
572 if (cip->connTimeout > 0) {
573 (void) alarm(0);
574 (void) signal(SIGALRM, (FTPSigProc) osigalrm);
575 }
576 (void) signal(SIGINT, (FTPSigProc) osigint);
577 }
578
579 if (err == 0)
580 break;
581 oerrno = errno;
582 (void) closesocket(sockfd);
583 errno = oerrno;
584 sockfd = -1;
585#endif /* NO_SIGNALS */
586 }
587 }
588
589 if (err < 0) {
590 /* Could not connect. Close up shop and go home. */
591
592 /* If possible, tell the caller if they should bother
593 * calling back later.
594 */
595 switch (errno) {
596#ifdef ENETDOWN
597 case ENETDOWN:
598#elif defined(WSAENETDOWN)
599 case WSAENETDOWN:
600#endif
601#ifdef ENETUNREACH
602 case ENETUNREACH:
603#elif defined(WSAENETUNREACH)
604 case WSAENETUNREACH:
605#endif
606#ifdef ECONNABORTED
607 case ECONNABORTED:
608#elif defined(WSAECONNABORTED)
609 case WSAECONNABORTED:
610#endif
611#ifdef ETIMEDOUT
612 case ETIMEDOUT:
613#elif defined(WSAETIMEDOUT)
614 case WSAETIMEDOUT:
615#endif
616#ifdef EHOSTDOWN
617 case EHOSTDOWN:
618#elif defined(WSAEHOSTDOWN)
619 case WSAEHOSTDOWN:
620#endif
621#ifdef ECONNRESET
622 case ECONNRESET:
623#elif defined(WSAECONNRESET)
624 case WSAECONNRESET:
625#endif
626 Error(cip, kDoPerror, "Could not connect to %s -- try again later.\n", fhost);
628 break;
629#ifdef ECONNREFUSED
630 case ECONNREFUSED:
631#elif defined(WSAECONNREFUSED)
632 case WSAECONNREFUSED:
633#endif
634 Error(cip, kDoPerror, "Could not connect to %s.\n", fhost);
636 break;
637 default:
638 Error(cip, kDoPerror, "Could not connect to %s.\n", fhost);
640 }
641 goto fatal;
642 }
643
644 /* Get our end of the socket address for later use. */
645 if ((result = GetSocketAddress(cip, sockfd, &cip->ourCtlAddr)) < 0)
646 goto fatal;
647
648#ifdef SO_OOBINLINE
649 /* We want Out-of-band data to appear in the regular stream,
650 * since we can handle TELNET.
651 */
652 (void) SetInlineOutOfBandData(cip, sockfd);
653#endif
654 (void) SetKeepAlive(cip, sockfd);
655 (void) SetLinger(cip, sockfd, 0); /* Don't need it for ctrl. */
656
657#if defined(IP_TOS) && defined(IPTOS_LOWDELAY)
658 /* Control connection is somewhat interactive, so quick response
659 * is desired.
660 */
661 (void) SetTypeOfService(cip, sockfd, IPTOS_LOWDELAY);
662#endif
663
664#ifdef NO_SIGNALS
665 cip->ctrlSocketR = sockfd;
666 cip->ctrlSocketW = sockfd;
667 cip->cout = NULL;
668 cip->cin = NULL;
669 sock2fd = kClosedFileDescriptor;
670
671 if (InitSReadlineInfo(&cip->ctrlSrl, sockfd, cip->srlBuf, sizeof(cip->srlBuf), (int) cip->ctrlTimeout, 1) < 0) {
673 cip->errNo = kErrFdopenW;
674 Error(cip, kDoPerror, "Could not fdopen.\n");
675 goto fatal;
676 }
677#else /* NO_SIGNALS */
678 if ((sock2fd = dup(sockfd)) < 0) {
680 cip->errNo = kErrDupSocket;
681 Error(cip, kDoPerror, "Could not duplicate a file descriptor.\n");
682 goto fatal;
683 }
684
685 /* Now setup the FILE pointers for use with the Std I/O library
686 * routines.
687 */
688 if ((cip->cin = fdopen(sockfd, "r")) == NULL) {
690 cip->errNo = kErrFdopenR;
691 Error(cip, kDoPerror, "Could not fdopen.\n");
692 goto fatal;
693 }
694
695 if ((cip->cout = fdopen(sock2fd, "w")) == NULL) {
697 cip->errNo = kErrFdopenW;
698 Error(cip, kDoPerror, "Could not fdopen.\n");
699 CloseFile(&cip->cin);
700 sockfd = kClosedFileDescriptor;
701 goto fatal;
702 }
703
704 cip->ctrlSocketR = sockfd;
705 cip->ctrlSocketW = sockfd;
706
707 /* We'll be reading and writing lines, so use line buffering. This
708 * is necessary since the stdio library will use full buffering
709 * for all streams not associated with the tty.
710 */
711#ifdef HAVE_SETLINEBUF
712 setlinebuf(cip->cin);
713 setlinebuf(cip->cout);
714#else
715 (void) SETVBUF(cip->cin, NULL, _IOLBF, (size_t) BUFSIZ);
716 (void) SETVBUF(cip->cout, NULL, _IOLBF, (size_t) BUFSIZ);
717#endif
718#endif /* NO_SIGNALS */
719
720#ifdef HAVE_INET_NTOP /* Mostly to workaround bug in IRIX 6.5's inet_ntoa */
721 (void) memset(cip->ip, 0, sizeof(cip->ip));
722 (void) inet_ntop(AF_INET, &cip->servCtlAddr.sin_addr, cip->ip, sizeof(cip->ip) - 1);
723#else
724 (void) STRNCPY(cip->ip, inet_ntoa(cip->servCtlAddr.sin_addr));
725#endif
726 if ((hp == NULL) || (hp->h_name == NULL))
727 (void) STRNCPY(cip->actualHost, fhost);
728 else
729 (void) STRNCPY(cip->actualHost, (char *) hp->h_name);
730
731 /* Read the startup message from the server. */
732 rp = InitResponse();
733 if (rp == NULL) {
734 Error(cip, kDontPerror, "Malloc failed.\n");
735 cip->errNo = kErrMallocFailed;
736 result = cip->errNo;
737 goto fatal;
738 }
739
740 result = GetResponse(cip, rp);
741 if ((result < 0) && (rp->msg.first == NULL)) {
742 goto fatal;
743 }
744 if (rp->msg.first != NULL) {
746 srvr = NULL;
747 firstLine = rp->msg.first->line;
748 secondLine = NULL;
749 if (rp->msg.first->next != NULL)
750 secondLine = rp->msg.first->next->line;
751
752 if (strstr(firstLine, "Version wu-") != NULL) {
754 srvr = "wu-ftpd";
755 } else if (strstr(firstLine, "NcFTPd") != NULL) {
757 srvr = "NcFTPd Server";
758 } else if (STRNEQ("ProFTPD", firstLine, 7)) {
760 srvr = "ProFTPD";
761 } else if (strstr(firstLine, "Microsoft FTP Service") != NULL) {
763 srvr = "Microsoft FTP Service";
764 } else if (strstr(firstLine, "(NetWare ") != NULL) {
766 srvr = "NetWare FTP Service";
767 } else if (STRNEQ("WFTPD", firstLine, 5)) {
769 srvr = "WFTPD";
770 } else if (STRNEQ("Serv-U FTP", firstLine, 10)) {
772 srvr = "Serv-U FTP-Server";
773 } else if (strstr(firstLine, "VFTPD") != NULL) {
775 srvr = "VFTPD";
776 } else if (STRNEQ("FTP-Max", firstLine, 7)) {
778 srvr = "FTP-Max";
779 } else if (strstr(firstLine, "Roxen") != NULL) {
781 srvr = "Roxen";
782 } else if (strstr(firstLine, "WS_FTP") != NULL) {
784 srvr = "WS_FTP Server";
785 } else if ((secondLine != NULL) && (strstr(secondLine, "WarFTP") != NULL)) {
787 srvr = "WarFTPd";
788 }
789
790 if (srvr != NULL)
791 PrintF(cip, "Remote server is running %s.\n", srvr);
792
793 /* Do the application's connect message callback, if present. */
794 if ((cip->onConnectMsgProc != 0) && (rp->codeType < 4))
795 (*cip->onConnectMsgProc)(cip, rp);
796 }
797
798 if (rp->codeType >= 4) {
799 /* They probably hung up on us right away. That's too bad,
800 * but we can tell the caller that they can call back later
801 * and try again.
802 */
803 DoneWithResponse(cip, rp);
805 Error(cip, kDontPerror, "Server hungup immediately after connect.\n");
807 goto fatal;
808 }
809 if (result < 0) /* Some other error occurred during connect message */
810 goto fatal;
811 cip->connected = 1;
812 DoneWithResponse(cip, rp);
813 return (kNoErr);
814
815fatal:
816 if (sockfd > 0)
817 (void) closesocket(sockfd);
818 if (sock2fd > 0)
819 (void) closesocket(sock2fd);
820 CloseFile(&cip->cin);
821 CloseFile(&cip->cout);
824 return (result);
825} /* OpenControlConnection */
int SConnect(int sfd, const struct sockaddr_in *const addr, int tlen)
Definition: SConnect.c:9
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define ZERO
Definition: arc.cc:50
#define setjmp
Definition: setjmp.h:209
#define SIGINT
Definition: signal.h:23
#define IPTOS_LOWDELAY
Definition: dhcpd.h:87
#define ENETUNREACH
Definition: errno.h:112
#define ECONNABORTED
Definition: errno.h:114
#define ETIMEDOUT
Definition: errno.h:121
#define EHOSTDOWN
Definition: errno.h:123
#define ENETDOWN
Definition: errno.h:111
#define ECONNREFUSED
Definition: errno.h:122
#define ECONNRESET
Definition: errno.h:115
#define SOCK_STREAM
Definition: tcpip.h:118
int SetTypeOfService(const FTPCIPtr, int, int)
int SetInlineOutOfBandData(const FTPCIPtr, int)
_Check_return_ _CRTIMP FILE *__cdecl fdopen(_In_ int _FileHandle, _In_z_ const char *_Format)
#define _IOLBF
Definition: stdio.h:128
#define inet_ntoa(addr)
Definition: inet.h:100
#define dup
Definition: syshdrs.h:51
#define htons(x)
Definition: module.h:215
static int GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr_in *saddr)
Definition: ftp.c:222
char gLibNcFTPVersion[64]
Definition: ftp.c:11
int SetLinger(const FTPCIPtr cip, int sockfd, int onoff)
Definition: ftp.c:262
char gNoSignalsMarker[]
Definition: ftp.c:14
static struct hostent * GetHostEntry(char *host, struct in_addr *ip_address)
Definition: ftp.c:53
int SetKeepAlive(const FTPCIPtr cip, int sockfd)
Definition: ftp.c:239
int SetSockBufSize(int sockfd, size_t rsize, size_t ssize)
Definition: util.c:572
void PrintF(const FTPCIPtr cip, const char *const fmt,...)
Definition: util.c:340
#define STRNEQ(a, b, s)
Definition: util.h:21
#define SETVBUF
Definition: util.h:70
int gGotSig
Definition: cmds.c:65
int InitSReadlineInfo(SReadlineInfo *, int, char *, size_t, int, int)
Definition: SReadline.c:24
int sigsetjmp(sigjmp_buf buf, int savesigs)
#define kServerTypeWFTPD
Definition: ncftp.h:468
#define kServerTypeVFTPD
Definition: ncftp.h:469
#define kFirewallNotInUse
Definition: ncftp.h:388
void(* FTPSigProc)(int)
Definition: ncftp.h:76
#define kServerTypeWS_FTP
Definition: ncftp.h:473
#define kServerTypeNcFTPd
Definition: ncftp.h:463
#define kServerTypeWuFTPd
Definition: ncftp.h:462
void DoneWithResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:114
#define kServerTypeNetWareFTP
Definition: ncftp.h:472
#define kServerTypeFTP_Max
Definition: ncftp.h:470
#define kServerTypeServ_U
Definition: ncftp.h:467
int GetResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:287
#define kServerTypeProFTPD
Definition: ncftp.h:464
#define kServerTypeMicrosoftFTP
Definition: ncftp.h:465
#define LIBNCFTP_USE_VAR(a)
Definition: ncftp.h:521
ResponsePtr InitResponse(void)
Definition: rcmd.c:38
#define kServerTypeWarFTPd
Definition: ncftp.h:466
#define kServerTypeUnknown
Definition: ncftp.h:461
#define kServerTypeRoxen
Definition: ncftp.h:471
#define kErrConnectRetryableErr
Definition: ncftp_errno.h:36
#define kErrHostUnknown
Definition: ncftp_errno.h:22
#define kNoErr
Definition: ncftp_errno.h:9
#define kErrMallocFailed
Definition: ncftp_errno.h:40
#define kErrDupSocket
Definition: ncftp_errno.h:24
#define kErrFdopenW
Definition: ncftp_errno.h:26
#define kErrNewStreamSocket
Definition: ncftp_errno.h:23
#define kErrConnectMiscErr
Definition: ncftp_errno.h:35
#define kErrFdopenR
Definition: ncftp_errno.h:25
#define kErrConnectRefused
Definition: ncftp_errno.h:37
#define BUFSIZ
Definition: nsplookup.c:25
#define err(...)
int signal
Definition: except.c:82
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
int firewallType
Definition: ncftp.h:221
struct sockaddr_in ourCtlAddr
Definition: ncftp.h:183
unsigned int firewallPort
Definition: ncftp.h:220
char srlBuf[768]
Definition: ncftp.h:239
char firewallHost[64]
Definition: ncftp.h:217
size_t ctrlSocketRBufSize
Definition: ncftp.h:228
FTPConnectMessageProc onConnectMsgProc
Definition: ncftp.h:224
size_t ctrlSocketSBufSize
Definition: ncftp.h:229
char ip[32]
Definition: ncftp.h:154
FTPLIPtr lip
Definition: ncftp.h:149
char actualHost[64]
Definition: ncftp.h:153
unsigned int defaultPort
Definition: ncftp.h:117
LinePtr first
Definition: ncftp.h:85
char * line
Definition: ncftp.h:81
LinePtr next
Definition: ncftp.h:80
Definition: ncftp.h:89
int codeType
Definition: ncftp.h:91
LineList msg
Definition: ncftp.h:90
short h_addrtype
Definition: winsock.h:136
const char *WSAAPI inet_ntop(int af, const void *src, char *dst, size_t cnt)
Definition: unix_func.c:8
#define WSAECONNABORTED
Definition: winerror.h:1966
#define WSAENETDOWN
Definition: winerror.h:1963
#define WSAETIMEDOUT
Definition: winerror.h:1973
#define WSAECONNRESET
Definition: winerror.h:1967
#define WSAEHOSTDOWN
Definition: winerror.h:1977
#define WSAENETUNREACH
Definition: winerror.h:1964
#define WSAECONNREFUSED
Definition: winerror.h:1974
void fatal(const char *msg)
#define getpid
Definition: wintirpc.h:52
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList

Referenced by FTPOpenHost(), and FTPOpenHostNoLogin().

◆ OpenDataConnection()

int OpenDataConnection ( const FTPCIPtr  cip,
int  mode 
)

Definition at line 1053 of file ftp.c.

1054{
1055 int dataSocket;
1056 int weirdPort;
1057 int result;
1058
1059 /* Before we can transfer any data, and before we even ask the
1060 * remote server to start transferring via RETR/NLST/etc, we have
1061 * to setup the connection.
1062 */
1063
1064tryPort2:
1065 weirdPort = 0;
1066 result = 0;
1067 CloseDataConnection(cip); /* In case we didn't before... */
1068
1070 if (dataSocket < 0) {
1071 Error(cip, kDoPerror, "Could not get a data socket.\n");
1074 return result;
1075 }
1076
1077 /* This doesn't do anything if you left these
1078 * at their defaults (zero). Otherwise it
1079 * tries to set the buffer size to the
1080 * size specified.
1081 */
1083
1084 if ((cip->hasPASV == kCommandNotAvailable) || (mode == kSendPortMode)) {
1085tryPort:
1086 cip->ourDataAddr = cip->ourCtlAddr;
1087 cip->ourDataAddr.sin_family = AF_INET;
1088
1089#ifdef HAVE_LIBSOCKS
1090 cip->ourDataAddr.sin_port = 0;
1091 if (Rbind(dataSocket, (struct sockaddr *) &cip->ourDataAddr,
1092 (int) sizeof (cip->ourDataAddr),
1093 cip->servCtlAddr.sin_addr.s_addr) < 0)
1094#else
1095 if (BindToEphemeralPortNumber(dataSocket, &cip->ourDataAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0)
1096#endif
1097 {
1098 Error(cip, kDoPerror, "Could not bind the data socket");
1101 goto bad;
1102 }
1103
1104 /* Need to do this so we can figure out which port the system
1105 * gave to us.
1106 */
1107 if ((result = GetSocketAddress(cip, dataSocket, &cip->ourDataAddr)) < 0)
1108 goto bad;
1109
1110 if (listen(dataSocket, 1) < 0) {
1111 Error(cip, kDoPerror, "listen failed");
1114 goto bad;
1115 }
1116
1117 if ((result = SendPort(cip, &cip->ourDataAddr)) < 0)
1118 goto bad;
1119
1121 } else {
1122 /* Passive mode. Let the other side decide where to send. */
1123
1124 cip->servDataAddr = cip->servCtlAddr;
1125 cip->servDataAddr.sin_family = AF_INET;
1126 cip->ourDataAddr = cip->ourCtlAddr;
1127 cip->ourDataAddr.sin_family = AF_INET;
1128
1129 if (Passive(cip, &cip->servDataAddr, &weirdPort) < 0) {
1130 Error(cip, kDontPerror, "Passive mode refused.\n");
1132
1133 /* We can try using regular PORT commands, which are required
1134 * by all FTP protocol compliant programs, if you said so.
1135 *
1136 * We don't do this automatically, because if your host
1137 * is running a firewall you (probably) do not want SendPort
1138 * FTP for security reasons.
1139 */
1141 goto tryPort;
1144 goto bad;
1145 }
1146
1147#ifdef HAVE_LIBSOCKS
1148 cip->ourDataAddr.sin_port = 0;
1149 if (Rbind(dataSocket, (struct sockaddr *) &cip->ourDataAddr,
1150 (int) sizeof (cip->ourDataAddr),
1151 cip->servCtlAddr.sin_addr.s_addr) < 0)
1152#else
1153 if (BindToEphemeralPortNumber(dataSocket, &cip->ourDataAddr, (int) cip->ephemLo, (int) cip->ephemHi) < 0)
1154#endif
1155 {
1156 Error(cip, kDoPerror, "Could not bind the data socket");
1159 goto bad;
1160 }
1161
1162#ifdef NO_SIGNALS
1163 result = SConnect(dataSocket, &cip->servDataAddr, (int) cip->connTimeout);
1164#else /* NO_SIGNALS */
1165 if (cip->connTimeout > 0)
1166 (void) alarm(cip->connTimeout);
1167
1168 result = connect(dataSocket, (struct sockaddr *) &cip->servDataAddr, (int) sizeof(cip->servDataAddr));
1169 if (cip->connTimeout > 0)
1170 (void) alarm(0);
1171#endif /* NO_SIGNALS */
1172
1173#ifdef NO_SIGNALS
1174 if (result == kTimeoutErr) {
1176 Error(cip, kDontPerror, "Data connection timed out.\n");
1177 Error(cip, kDontPerror, "Falling back to PORT instead of PASV mode.\n");
1180 goto tryPort2;
1181 }
1182 Error(cip, kDontPerror, "Data connection timed out.\n");
1185 } else
1186#endif /* NO_SIGNALS */
1187
1188 if (result < 0) {
1189#ifdef ECONNREFUSED
1190 if ((weirdPort > 0) && (errno == ECONNREFUSED)) {
1191#elif defined(WSAECONNREFUSED)
1192 if ((weirdPort > 0) && (errno == WSAECONNREFUSED)) {
1193#endif
1194 Error(cip, kDontPerror, "Server sent back a bogus port number.\nI will fall back to PORT instead of PASV mode.\n");
1198 goto tryPort2;
1199 }
1202 goto bad;
1203 }
1205 Error(cip, kDoPerror, "connect failed.\n");
1206 Error(cip, kDontPerror, "Falling back to PORT instead of PASV mode.\n");
1209 goto tryPort2;
1210 }
1211 Error(cip, kDoPerror, "connect failed.\n");
1214 goto bad;
1215 }
1216
1217 /* Need to do this so we can figure out which port the system
1218 * gave to us.
1219 */
1220 if ((result = GetSocketAddress(cip, dataSocket, &cip->ourDataAddr)) < 0)
1221 goto bad;
1222
1225 }
GLenum mode
Definition: glext.h:6217
static int Passive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
Definition: ftp.c:939
cip dataSocket
Definition: ftp.c:1238
static int SendPort(const FTPCIPtr cip, struct sockaddr_in *saddr)
Definition: ftp.c:899
static int BindToEphemeralPortNumber(int sockfd, struct sockaddr_in *addrp, int ephemLo, int ephemHi)
Definition: ftp.c:1011
#define kTimeoutErr
Definition: sio.h:58
#define kCommandAvailable
Definition: ncftp.h:380
#define kPassiveMode
Definition: ncftp.h:296
#define kFallBackToSendPortMode
Definition: ncftp.h:297
#define kCommandNotAvailable
Definition: ncftp.h:381
#define kErrBindDataSocket
Definition: ncftp_errno.h:28
#define kErrListenDataSocket
Definition: ncftp_errno.h:29
#define kErrServerSentBogusPortNumber
Definition: ncftp_errno.h:31
#define kErrPassiveModeFailed
Definition: ncftp_errno.h:30
#define kErrConnectDataSocket
Definition: ncftp_errno.h:32
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
unsigned short ephemHi
Definition: ncftp.h:195
unsigned short ephemLo
Definition: ncftp.h:194
size_t dataSocketRBufSize
Definition: ncftp.h:230
size_t dataSocketSBufSize
Definition: ncftp.h:231

Referenced by FTPStartDataCmd().

◆ Passive()

static int Passive ( const FTPCIPtr  cip,
struct sockaddr_in saddr,
int weird 
)
static

Definition at line 939 of file ftp.c.

940{
941 ResponsePtr rp;
942 int i[6], j;
943 unsigned char n[6];
944 char *cp;
945 int result;
946
947 rp = InitResponse();
948 if (rp == NULL) {
949 Error(cip, kDontPerror, "Malloc failed.\n");
950 cip->errNo = kErrMallocFailed;
951 return (cip->errNo);
952 }
953
954 result = RCmd(cip, rp, "PASV");
955 if (result < 0)
956 goto done;
957
958 if (rp->codeType != 2) {
959 /* Didn't understand or didn't want passive port selection. */
960 cip->errNo = result = kErrPASVFailed;
961 goto done;
962 }
963
964 /* The other side returns a specification in the form of
965 * an internet address as the first four integers (each
966 * integer stands for 8-bits of the real 32-bit address),
967 * and two more integers for the port (16-bit port).
968 *
969 * It should give us something like:
970 * "Entering Passive Mode (129,93,33,1,10,187)", so look for
971 * digits with sscanf() starting 24 characters down the string.
972 */
973 for (cp = rp->msg.first->line; ; cp++) {
974 if (*cp == '\0') {
975 Error(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
976 goto done;
977 }
978 if (isdigit((int) *cp))
979 break;
980 }
981
982 if (sscanf(cp, "%d,%d,%d,%d,%d,%d",
983 &i[0], &i[1], &i[2], &i[3], &i[4], &i[5]) != 6) {
984 Error(cip, kDontPerror, "Cannot parse PASV response: %s\n", rp->msg.first->line);
985 goto done;
986 }
987
988 for (j=0, *weird = 0; j<6; j++) {
989 /* Some ftp servers return bogus port octets, such as
990 * boombox.micro.umn.edu. Let the caller know if we got a
991 * weird looking octet.
992 */
993 if ((i[j] < 0) || (i[j] > 255))
994 *weird = *weird + 1;
995 n[j] = (unsigned char) (i[j] & 0xff);
996 }
997
998 (void) memcpy(&saddr->sin_addr, &n[0], (size_t) 4);
999 (void) memcpy(&saddr->sin_port, &n[4], (size_t) 2);
1000
1001 result = kNoErr;
1002done:
1003 DoneWithResponse(cip, rp);
1004 return (result);
1005} /* Passive */
#define isdigit(c)
Definition: acclib.h:68
unsigned char
Definition: typeof.h:29
GLdouble n
Definition: glext.h:7729
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
int RCmd(const FTPCIPtr, ResponsePtr, const char *,...)
Definition: rcmd.c:718
#define kErrPASVFailed
Definition: ncftp_errno.h:80
struct in_addr sin_addr
Definition: winsock.h:512

Referenced by OpenDataConnection().

◆ return() [1/2]

return ( )

◆ return() [2/2]

return ( result  )

◆ SendPort()

static int SendPort ( const FTPCIPtr  cip,
struct sockaddr_in saddr 
)
static

Definition at line 899 of file ftp.c.

900{
901 char *a, *p;
902 int result;
903 ResponsePtr rp;
904
905 rp = InitResponse();
906 if (rp == NULL) {
907 Error(cip, kDontPerror, "Malloc failed.\n");
908 cip->errNo = kErrMallocFailed;
909 return (cip->errNo);
910 }
911
912 /* These will point to data in network byte order. */
913 a = (char *) &saddr->sin_addr;
914 p = (char *) &saddr->sin_port;
915#define UC(x) (int) (((int) x) & 0xff)
916
917 /* Need to tell the other side which host (the address) and
918 * which process (port) on that host to send data to.
919 */
920 result = RCmd(cip, rp, "PORT %d,%d,%d,%d,%d,%d",
921 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]), UC(p[0]), UC(p[1]));
922
923 if (result < 0) {
924 return (result);
925 } else if (result != 2) {
926 /* A 500'ish response code means the PORT command failed. */
927 DoneWithResponse(cip, rp);
928 cip->errNo = kErrPORTFailed;
929 return (cip->errNo);
930 }
931 DoneWithResponse(cip, rp);
932 return (kNoErr);
933} /* SendPort */
#define UC(b)
GLfloat GLfloat p
Definition: glext.h:8902
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define a
Definition: ke_i.h:78
#define kErrPORTFailed
Definition: ncftp_errno.h:79

Referenced by OpenDataConnection().

◆ SendTelnetInterrupt()

void SendTelnetInterrupt ( const FTPCIPtr  cip)

Definition at line 1328 of file ftp.c.

1329{
1330 char msg[4];
1331
1332 /* 1. User system inserts the Telnet "Interrupt Process" (IP) signal
1333 * in the Telnet stream.
1334 */
1335
1336 if (cip->cout != NULL)
1337 (void) fflush(cip->cout);
1338
1339 msg[0] = (char) (unsigned char) IAC;
1340 msg[1] = (char) (unsigned char) IP;
1341 (void) send(cip->ctrlSocketW, msg, 2, 0);
1342
1343 /* 2. User system sends the Telnet "Sync" signal. */
1344#if 1
1345 msg[0] = (char) (unsigned char) IAC;
1346 msg[1] = (char) (unsigned char) DM;
1347 if (send(cip->ctrlSocketW, msg, 2, MSG_OOB) != 2)
1348 Error(cip, kDoPerror, "Could not send an urgent message.\n");
1349#else
1350 /* "Send IAC in urgent mode instead of DM because UNIX places oob mark
1351 * after urgent byte rather than before as now is protocol," says
1352 * the BSD ftp code.
1353 */
1354 msg[0] = (char) (unsigned char) IAC;
1355 if (send(cip->ctrlSocketW, msg, 1, MSG_OOB) != 1)
1356 Error(cip, kDoPerror, "Could not send an urgent message.\n");
1357 (void) fprintf(cip->cout, "%c", DM);
1358 (void) fflush(cip->cout);
1359#endif
1360} /* SendTelnetInterrupt */
#define msg(x)
Definition: auth_time.c:54
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#define IAC
Definition: ftp_var.h:13
#define DM
Definition: ftp_var.h:26
#define IP
Definition: ftp_var.h:24
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
#define MSG_OOB
Definition: winsock.h:221

Referenced by FTPAbortDataTransfer().

◆ SetKeepAlive() [1/2]

void SetKeepAlive ( cip  ,
dataSocket   
)

◆ SetKeepAlive() [2/2]

int SetKeepAlive ( const FTPCIPtr  cip,
int  sockfd 
)

Definition at line 239 of file ftp.c.

240{
241#ifndef SO_KEEPALIVE
242 cip->errNo = kErrSetKeepAlive;
243 return (kErrSetKeepAlive);
244#else
245 int opt;
246
247 opt = 1;
248
249 if (setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, (int) sizeof(opt)) < 0) {
250 /* Error(cip, kDoPerror, "Could not set keep-alive mode.\n"); */
251 cip->errNo = kErrSetKeepAlive;
252 return (kErrSetKeepAlive);
253 }
254 return (kNoErr);
255#endif /* SO_KEEPALIVE */
256} /* SetKeepAlive */
#define kErrSetKeepAlive
Definition: ncftp_errno.h:69
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
#define SO_KEEPALIVE
Definition: winsock.h:181
#define SOL_SOCKET
Definition: winsock.h:398

Referenced by OpenControlConnection().

◆ SetLinger() [1/2]

void SetLinger ( cip  ,
dataSocket  ,
 
)

◆ SetLinger() [2/2]

int SetLinger ( const FTPCIPtr  cip,
int  sockfd,
int  onoff 
)

Definition at line 262 of file ftp.c.

263{
264#ifndef SO_LINGER
265 cip->errNo = kErrSetLinger;
266 return (kErrSetLinger);
267#else
268 struct linger li;
269
270 if (onoff != 0) {
271 li.l_onoff = 1;
272 li.l_linger = 120; /* 2 minutes, but system ignores field. */
273 } else {
274 li.l_onoff = 0;
275 li.l_linger = 0;
276 }
277 /* Have the system make an effort to deliver any unsent data,
278 * even after we close the connection.
279 */
280 if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *) &li, (int) sizeof(li)) < 0) {
281 /* Error(cip, kDoPerror, "Could not set linger mode.\n"); */
282 cip->errNo = kErrSetLinger;
283 return (kErrSetLinger);
284 }
285 return (kNoErr);
286#endif /* SO_LINGER */
287} /* SetLinger */
static const char * onoff(int bool)
Definition: cmds.c:777
LARGE_INTEGER li
Definition: fxtimerapi.cpp:235
#define kErrSetLinger
Definition: ncftp_errno.h:19
#define SO_LINGER
Definition: winsock.h:185

Referenced by FTPAbortDataTransfer(), FTPShutdownHost(), and OpenControlConnection().

◆ SetStartOffset()

int SetStartOffset ( const FTPCIPtr  cip,
longest_int  restartPt 
)

Definition at line 853 of file ftp.c.

854{
855 ResponsePtr rp;
856 int result;
857
858 if (restartPt != (longest_int) 0) {
859 rp = InitResponse();
860 if (rp == NULL) {
861 Error(cip, kDontPerror, "Malloc failed.\n");
862 cip->errNo = kErrMallocFailed;
863 return (cip->errNo);
864 }
865
866 /* Force reset to offset zero. */
867 if (restartPt == (longest_int) -1)
868 restartPt = (longest_int) 0;
869#ifdef PRINTF_LONG_LONG
870 result = RCmd(cip, rp,
871 "REST " PRINTF_LONG_LONG,
872 restartPt);
873#else
874 result = RCmd(cip, rp, "REST %ld", (long) restartPt);
875#endif
876
877 if (result < 0) {
878 return (result);
879 } else if (result == 3) {
881 DoneWithResponse(cip, rp);
882 } else if (UNIMPLEMENTED_CMD(rp->code)) {
884 DoneWithResponse(cip, rp);
886 return (kErrSetStartPoint);
887 } else {
888 DoneWithResponse(cip, rp);
890 return (kErrSetStartPoint);
891 }
892 }
893 return (0);
894} /* SetStartOffset */
#define PRINTF_LONG_LONG
Definition: wincfg.h:31
#define UNIMPLEMENTED_CMD(a)
Definition: ncftp.h:373
#define longest_int
Definition: ncftp.h:68
#define kErrSetStartPoint
Definition: ncftp_errno.h:34
int code
Definition: ncftp.h:92

Referenced by FTPGetOneF(), FTPPutOneF(), and FTPStartDataCmd().

Variable Documentation

◆ __pad0__

bad __pad0__

Definition at line 1240 of file ftp.c.

◆ dataSocket

cip dataSocket = dataSocket

Definition at line 1238 of file ftp.c.

Referenced by OpenDataConnection().

◆ gCopyright

char gCopyright[] = "@(#) LibNcFTP Copyright 1995-2000, by Mike Gleason. All rights reserved."
static

Definition at line 28 of file ftp.c.

Referenced by BindToEphemeralPortNumber(), kbd_rc(), and OpenControlConnection().

◆ gLibNcFTPVersion

char gLibNcFTPVersion[64] = kLibraryVersion

Definition at line 11 of file ftp.c.

Referenced by OpenControlConnection(), OpenTrace(), Usage(), and VersionCmd().

◆ gNoSignalsMarker

char gNoSignalsMarker[] = "@(#) LibNcFTP - NO_SIGNALS"

Definition at line 14 of file ftp.c.

Referenced by OpenControlConnection(), and SRead().