ReactOS 0.4.15-dev-7961-gdcf9eb0
ftp.c
Go to the documentation of this file.
1/* ftp.c
2 *
3 * Copyright (c) 1996-2001 Mike Gleason, NCEMRSoft.
4 * All rights reserved.
5 *
6 */
7
8#define _libncftp_ftp_c_
9#include "syshdrs.h"
10
12
13#ifdef NO_SIGNALS
14char gNoSignalsMarker[] = "@(#) LibNcFTP - NO_SIGNALS";
15#else
16
17static int gGotSig = 0;
18#ifdef HAVE_SIGSETJMP
19static sigjmp_buf gCancelConnectJmp;
20#else
21static jmp_buf gCancelConnectJmp;
22#endif
23
24#endif
25
26
27#ifndef lint
28static char gCopyright[] = "@(#) LibNcFTP Copyright 1995-2000, by Mike Gleason. All rights reserved.";
29#endif
30
31#ifdef HAVE_LIBSOCKS5
32# define SOCKS 5
33# include <socks.h>
34#else
35# ifdef HAVE_LIBSOCKS
36# define accept Raccept
37# define connect Rconnect
38# define getsockname Rgetsockname
39# define listen Rlisten
40# endif
41#endif
42
43
44
45
46/* On entry, you should have 'host' be set to a symbolic name (like
47 * cse.unl.edu), or set to a numeric address (like 129.93.3.1).
48 * If the function fails, it will return NULL, but if the host was
49 * a numeric style address, you'll have the ip_address to fall back on.
50 */
51
52static struct hostent *
53GetHostEntry(char *host, struct in_addr *ip_address)
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 */
75
76
77
78
79/* Makes every effort to return a fully qualified domain name. */
80int
81GetOurHostName(char *host, size_t siz)
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 */
193
194
195
196void
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 */
218
219
220
221static int
222GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr_in *saddr)
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 */
234
235
236
237
238int
239SetKeepAlive(const FTPCIPtr cip, int sockfd)
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 */
257
258
259
260
261int
262SetLinger(const FTPCIPtr cip, int sockfd, int onoff)
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 */
288
289
290
291
292#ifdef IP_TOS
293int
294SetTypeOfService(const FTPCIPtr cip, int sockfd, int tosType)
295{
296 /* Specify to the router what type of connection this is, so it
297 * can prioritize packets.
298 */
299 if (setsockopt(sockfd, IPPROTO_IP, IP_TOS, (char *) &tosType, (int) sizeof(tosType)) < 0) {
300 /* Error(cip, kDoPerror, "Could not set type of service.\n"); */
302 return (kErrSetTypeOfService);
303 }
304 return (kNoErr);
305} /* SetTypeOfService */
306#endif /* IP_TOS */
307
308
309
310
311#ifdef SO_OOBINLINE
312int
313SetInlineOutOfBandData(const FTPCIPtr cip, int sockfd)
314{
315 int on = 1;
316
317 if (setsockopt(sockfd, SOL_SOCKET, SO_OOBINLINE, (char *) &on, (int) sizeof(on)) < 0) {
318 Error(cip, kDoPerror, "Could not set out of band inline mode.\n");
320 return (kErrSetOutOfBandInline);
321 }
322 return (kNoErr);
323} /* SetInlineOutOfBandData */
324#endif /* SO_OOBINLINE */
325
326
327
328
329#ifndef NO_SIGNALS
330
331static void
332CancelConnect(int signum)
333{
334 gGotSig = signum;
335#ifdef HAVE_SIGSETJMP
336 siglongjmp(gCancelConnectJmp, 1);
337#else
338 longjmp(gCancelConnectJmp, 1);
339#endif /* HAVE_SIGSETJMP */
340} /* CancelConnect */
341
342#endif /* NO_SIGNALS */
343
344
345
346int
347OpenControlConnection(const FTPCIPtr cip, char *host, unsigned int port)
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 */
826
827
828
829
830void
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 */
848
849
850
851
852int
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 */
895
896
897
898static int
899SendPort(const FTPCIPtr cip, struct sockaddr_in *saddr)
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 */
934
935
936
937
938static int
939Passive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
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 */
1006
1007
1008
1009
1010static int
1011BindToEphemeralPortNumber(int sockfd, struct sockaddr_in *addrp, int ephemLo, int ephemHi)
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 */
1048
1049
1050
1051
1052int
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 }
1226
1229
1230#if defined(IP_TOS) && defined(IPTOS_THROUGHPUT)
1231 /* Data connection is a non-interactive data stream, so
1232 * high throughput is desired, at the expense of low
1233 * response time.
1234 */
1236#endif
1237
1239 return (0);
1240bad:
1242 return (result);
1243} /* OpenDataConnection */
1244
1245
1246
1247
1248int
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 */
1309
1310
1311
1312
1313void
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 */
1323
1324
1325
1326
1327void
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 */
1361
1362/* eof FTP.c */
int SClose(int sfd, int tlen)
Definition: SClose.c:9
int SConnect(int sfd, const struct sockaddr_in *const addr, int tlen)
Definition: SConnect.c:9
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
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define isdigit(c)
Definition: acclib.h:68
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 ZERO
Definition: arc.cc:50
#define msg(x)
Definition: auth_time.c:54
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
#define INADDR_NONE
Definition: tcp.c:42
static const char * onoff(int bool)
Definition: cmds.c:777
#define UC(b)
BOOL Error
Definition: chkdsk.c:66
#define setjmp
Definition: setjmp.h:209
_JBTYPE jmp_buf[_JBLEN]
Definition: setjmp.h:186
#define SIGINT
Definition: signal.h:23
#define IPTOS_LOWDELAY
Definition: dhcpd.h:87
#define NULL
Definition: types.h:112
#define IPTOS_THROUGHPUT
Definition: ip.h:111
USHORT port
Definition: uri.c:228
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned char
Definition: typeof.h:29
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#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
#define AF_INET
Definition: tcpip.h:117
int SetTypeOfService(const FTPCIPtr, int, int)
int SetInlineOutOfBandData(const FTPCIPtr, int)
#define IAC
Definition: ftp_var.h:13
#define DM
Definition: ftp_var.h:26
#define IP
Definition: ftp_var.h:24
LARGE_INTEGER li
Definition: fxtimerapi.cpp:235
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
INT WSAAPI gethostname(OUT char FAR *name, IN INT namelen)
Definition: getxbyxx.c:397
GLdouble n
Definition: glext.h:7729
GLenum mode
Definition: glext.h:6217
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
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
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_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)
_Check_return_ _CRTIMP FILE *__cdecl fdopen(_In_ int _FileHandle, _In_z_ const char *_Format)
_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)
#define _IOLBF
Definition: stdio.h:128
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
#define inet_addr(cp)
Definition: inet.h:98
#define inet_ntoa(addr)
Definition: inet.h:100
#define a
Definition: ke_i.h:78
#define dup
Definition: syshdrs.h:51
#define PRINTF_LONG_LONG
Definition: wincfg.h:31
POINT cp
Definition: magnifier.c:59
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:215
#define ntohs(x)
Definition: module.h:210
#define DOMAINNAME
Definition: options.h:45
#define HOSTNAME
Definition: options.h:42
void SendTelnetInterrupt(const FTPCIPtr cip)
Definition: ftp.c:1328
void CloseDataConnection(const FTPCIPtr cip)
Definition: ftp.c:831
static int Passive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
Definition: ftp.c:939
void HangupOnServer(const FTPCIPtr cip)
Definition: ftp.c:1314
static int GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr_in *saddr)
Definition: ftp.c:222
char gLibNcFTPVersion[64]
Definition: ftp.c:11
int OpenDataConnection(const FTPCIPtr cip, int mode)
Definition: ftp.c:1053
int SetStartOffset(const FTPCIPtr cip, longest_int restartPt)
Definition: ftp.c:853
int SetLinger(const FTPCIPtr cip, int sockfd, int onoff)
Definition: ftp.c:262
cip dataSocket
Definition: ftp.c:1238
int GetOurHostName(char *host, size_t siz)
Definition: ftp.c:81
void CloseControlConnection(const FTPCIPtr cip)
Definition: ftp.c:197
char gNoSignalsMarker[]
Definition: ftp.c:14
static struct hostent * GetHostEntry(char *host, struct in_addr *ip_address)
Definition: ftp.c:53
int AcceptDataConnection(const FTPCIPtr cip)
Definition: ftp.c:1249
int OpenControlConnection(const FTPCIPtr cip, char *host, unsigned int port)
Definition: ftp.c:347
int SetKeepAlive(const FTPCIPtr cip, int sockfd)
Definition: ftp.c:239
static int SendPort(const FTPCIPtr cip, struct sockaddr_in *saddr)
Definition: ftp.c:899
static char gCopyright[]
Definition: ftp.c:28
static int BindToEphemeralPortNumber(int sockfd, struct sockaddr_in *addrp, int ephemLo, int ephemHi)
Definition: ftp.c:1011
int SetSockBufSize(int sockfd, size_t rsize, size_t ssize)
Definition: util.c:572
void CloseFile(FILE **f)
Definition: util.c:327
void PrintF(const FTPCIPtr cip, const char *const fmt,...)
Definition: util.c:340
#define kDoPerror
Definition: util.h:44
#define kDontPerror
Definition: util.h:45
#define STRNEQ(a, b, s)
Definition: util.h:21
#define kClosedFileDescriptor
Definition: util.h:47
#define SETVBUF
Definition: util.h:70
int gGotSig
Definition: cmds.c:65
void DisposeSReadlineInfo(SReadlineInfo *)
Definition: SReadline.c:57
#define SAccept
Definition: sio.h:81
int InitSReadlineInfo(SReadlineInfo *, int, char *, size_t, int, int)
Definition: SReadline.c:24
#define kTimeoutErr
Definition: sio.h:58
int sigsetjmp(sigjmp_buf buf, int savesigs)
void siglongjmp(sigjmp_buf buf, int val)
jmp_buf sigjmp_buf
Definition: port.h:324
#define kServerTypeWFTPD
Definition: ncftp.h:468
int RCmd(const FTPCIPtr, ResponsePtr, const char *,...)
Definition: rcmd.c:718
#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 UNIMPLEMENTED_CMD(a)
Definition: ncftp.h:373
#define kCommandAvailable
Definition: ncftp.h:380
#define longest_int
Definition: ncftp.h:68
#define kServerTypeWuFTPd
Definition: ncftp.h:462
void DoneWithResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:114
#define kSendPortMode
Definition: ncftp.h:295
#define kServerTypeNetWareFTP
Definition: ncftp.h:472
#define kServerTypeFTP_Max
Definition: ncftp.h:470
#define kServerTypeServ_U
Definition: ncftp.h:467
#define kPassiveMode
Definition: ncftp.h:296
int GetResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:287
#define kServerTypeProFTPD
Definition: ncftp.h:464
#define kServerTypeMicrosoftFTP
Definition: ncftp.h:465
#define kFallBackToSendPortMode
Definition: ncftp.h:297
#define kCommandNotAvailable
Definition: ncftp.h:381
#define LIBNCFTP_USE_VAR(a)
Definition: ncftp.h:521
#define kLibraryVersion
Definition: ncftp.h:11
ResponsePtr InitResponse(void)
Definition: rcmd.c:38
#define kServerTypeWarFTPd
Definition: ncftp.h:466
#define closesocket
Definition: ncftp.h:477
#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 kErrBindDataSocket
Definition: ncftp_errno.h:28
#define kErrAcceptDataSocket
Definition: ncftp_errno.h:33
#define kErrSetTypeOfService
Definition: ncftp_errno.h:20
#define kErrSetKeepAlive
Definition: ncftp_errno.h:69
#define kNoErr
Definition: ncftp_errno.h:9
#define kErrMallocFailed
Definition: ncftp_errno.h:40
#define kErrDupSocket
Definition: ncftp_errno.h:24
#define kErrListenDataSocket
Definition: ncftp_errno.h:29
#define kErrFdopenW
Definition: ncftp_errno.h:26
#define kErrPASVFailed
Definition: ncftp_errno.h:80
#define kErrServerSentBogusPortNumber
Definition: ncftp_errno.h:31
#define kErrSetLinger
Definition: ncftp_errno.h:19
#define kErrNewStreamSocket
Definition: ncftp_errno.h:23
#define kErrPORTFailed
Definition: ncftp_errno.h:79
#define kErrConnectMiscErr
Definition: ncftp_errno.h:35
#define kErrFdopenR
Definition: ncftp_errno.h:25
#define kErrSetStartPoint
Definition: ncftp_errno.h:34
#define kErrPassiveModeFailed
Definition: ncftp_errno.h:30
#define kErrGetSockName
Definition: ncftp_errno.h:27
#define kErrSetOutOfBandInline
Definition: ncftp_errno.h:21
#define kErrConnectRefused
Definition: ncftp_errno.h:37
#define kErrConnectDataSocket
Definition: ncftp_errno.h:32
#define BUFSIZ
Definition: nsplookup.c:25
#define err(...)
#define errno
Definition: errno.h:18
int signal
Definition: except.c:82
#define memset(x, y, z)
Definition: compat.h:39
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
INT WSAAPI setsockopt(IN SOCKET s, IN INT level, IN INT optname, IN CONST CHAR FAR *optval, IN INT optlen)
Definition: sockctrl.c:421
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
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
FILE * cout
Definition: ncftp.h:189
struct sockaddr_in servDataAddr
Definition: ncftp.h:182
unsigned int firewallPort
Definition: ncftp.h:220
char srlBuf[768]
Definition: ncftp.h:239
unsigned short ephemHi
Definition: ncftp.h:195
unsigned int xferTimeout
Definition: ncftp.h:141
unsigned int connTimeout
Definition: ncftp.h:142
char firewallHost[64]
Definition: ncftp.h:217
unsigned short ephemLo
Definition: ncftp.h:194
size_t dataSocketRBufSize
Definition: ncftp.h:230
int dataPortMode
Definition: ncftp.h:152
size_t ctrlSocketRBufSize
Definition: ncftp.h:228
FTPConnectMessageProc onConnectMsgProc
Definition: ncftp.h:224
struct sockaddr_in servCtlAddr
Definition: ncftp.h:181
size_t ctrlSocketSBufSize
Definition: ncftp.h:229
size_t dataSocketSBufSize
Definition: ncftp.h:231
char ip[32]
Definition: ncftp.h:154
FTPLIPtr lip
Definition: ncftp.h:149
char actualHost[64]
Definition: ncftp.h:153
SReadlineInfo ctrlSrl
Definition: ncftp.h:240
struct sockaddr_in ourDataAddr
Definition: ncftp.h:184
unsigned int ctrlTimeout
Definition: ncftp.h:143
FILE * cin
Definition: ncftp.h:188
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 code
Definition: ncftp.h:92
int codeType
Definition: ncftp.h:91
LineList msg
Definition: ncftp.h:90
Definition: cookie.c:42
char * h_name
Definition: winsock.h:134
short h_length
Definition: winsock.h:137
char ** h_aliases
Definition: winsock.h:135
short h_addrtype
Definition: winsock.h:136
char ** h_addr_list
Definition: winsock.h:138
Definition: tcpip.h:126
u32_t s_addr
Definition: inet.h:45
Definition: dhcpd.h:62
Definition: parser.c:49
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
const char *WSAAPI inet_ntop(int af, const void *src, char *dst, size_t cnt)
Definition: unix_func.c:8
char * host
Definition: whois.c:55
#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 SO_KEEPALIVE
Definition: winsock.h:181
#define SO_OOBINLINE
Definition: winsock.h:186
#define SO_LINGER
Definition: winsock.h:185
#define IP_TOS
Definition: winsock.h:325
#define SOL_SOCKET
Definition: winsock.h:398
#define MSG_OOB
Definition: winsock.h:221
#define IPPROTO_IP
Definition: winsock.h:255
#define getpid
Definition: wintirpc.h:52
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList