ReactOS  0.4.14-dev-552-g2fad488
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
14 char gNoSignalsMarker[] = "@(#) LibNcFTP - NO_SIGNALS";
15 #else
16 
17 static int gGotSig = 0;
18 #ifdef HAVE_SIGSETJMP
19 static sigjmp_buf gCancelConnectJmp;
20 #else
21 static jmp_buf gCancelConnectJmp;
22 #endif
23 
24 #endif
25 
26 
27 #ifndef lint
28 static 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 
52 static struct hostent *
53 GetHostEntry(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. */
80 int
81 GetOurHostName(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
134  (void) STRNCPY(domain, 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 
196 void
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 
221 static int
222 GetSocketAddress(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 
238 int
239 SetKeepAlive(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 
261 int
262 SetLinger(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
293 int
294 SetTypeOfService(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
312 int
313 SetInlineOutOfBandData(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 
331 static void
332 CancelConnect(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 
346 int
347 OpenControlConnection(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");
428  cip->errNo = kErrNewStreamSocket;
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) {
472  result = vcip->errNo = kErrConnectMiscErr;
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 {
480  result = vcip->errNo = kErrConnectMiscErr;
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");
508  cip->errNo = kErrNewStreamSocket;
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) {
557  result = vcip->errNo = kErrConnectMiscErr;
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 {
565  result = vcip->errNo = kErrConnectMiscErr;
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 
815 fatal:
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 
830 void
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);
839  (void) closesocket(cip->dataSocket);
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 
852 int
853 SetStartOffset(const FTPCIPtr cip, longest_int restartPt)
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) {
880  cip->hasREST = kCommandAvailable;
881  DoneWithResponse(cip, rp);
882  } else if (UNIMPLEMENTED_CMD(rp->code)) {
884  DoneWithResponse(cip, rp);
885  cip->errNo = kErrSetStartPoint;
886  return (kErrSetStartPoint);
887  } else {
888  DoneWithResponse(cip, rp);
889  cip->errNo = kErrSetStartPoint;
890  return (kErrSetStartPoint);
891  }
892  }
893  return (0);
894 } /* SetStartOffset */
895 
896 
897 
898 static int
899 SendPort(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 
938 static int
939 Passive(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;
1002 done:
1003  DoneWithResponse(cip, rp);
1004  return (result);
1005 } /* Passive */
1006 
1007 
1008 
1009 
1010 static int
1011 BindToEphemeralPortNumber(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 
1052 int
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 
1064 tryPort2:
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");
1073  cip->errNo = kErrNewStreamSocket;
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)) {
1085 tryPort:
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");
1100  cip->errNo = kErrBindDataSocket;
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");
1113  cip->errNo = kErrListenDataSocket;
1114  goto bad;
1115  }
1116 
1117  if ((result = SendPort(cip, &cip->ourDataAddr)) < 0)
1118  goto bad;
1119 
1120  cip->dataPortMode = kSendPortMode;
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");
1158  cip->errNo = kErrBindDataSocket;
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) {
1175  if (mode == kFallBackToSendPortMode) {
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");
1195  if (mode == kFallBackToSendPortMode) {
1198  goto tryPort2;
1199  }
1202  goto bad;
1203  }
1204  if (mode == kFallBackToSendPortMode) {
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 
1223  cip->dataPortMode = kPassiveMode;
1224  cip->hasPASV = kCommandAvailable;
1225  }
1226 
1227  (void) SetLinger(cip, dataSocket, 1);
1228  (void) SetKeepAlive(cip, dataSocket);
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);
1240 bad:
1242  return (result);
1243 } /* OpenDataConnection */
1244 
1245 
1246 
1247 
1248 int
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");
1282  cip->errNo = kErrAcceptDataSocket;
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);
1293  cip->errNo = kErrAcceptDataSocket;
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);
1299  cip->errNo = kErrAcceptDataSocket;
1300  return (kErrAcceptDataSocket);
1301  }
1302  }
1303 
1304  cip->dataSocket = newSocket;
1305  }
1306 
1307  return (0);
1308 } /* AcceptDataConnection */
1309 
1310 
1311 
1312 
1313 void
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  */
1321  CloseDataConnection(cip);
1322 } /* HangupOnServer */
1323 
1324 
1325 
1326 
1327 void
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 */
void DisposeSReadlineInfo(SReadlineInfo *)
Definition: SReadline.c:57
#define kServerTypeWarFTPd
Definition: ncftp.h:466
#define IP_TOS
Definition: winsock.h:325
#define kServerTypeWuFTPd
Definition: ncftp.h:462
FILE * cin
Definition: ncftp.h:188
unsigned int ctrlTimeout
Definition: ncftp.h:143
#define kErrBindDataSocket
Definition: ncftp_errno.h:28
char ** h_addr_list
Definition: winsock.h:138
jmp_buf sigjmp_buf
Definition: port.h:324
#define EHOSTDOWN
Definition: errno.h:123
#define IPTOS_THROUGHPUT
Definition: ip.h:111
#define kServerTypeWS_FTP
Definition: ncftp.h:473
#define UC(x)
static char gCopyright[]
Definition: ftp.c:28
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define kErrAcceptDataSocket
Definition: ncftp_errno.h:33
#define kCommandAvailable
Definition: ncftp.h:380
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define ECONNABORTED
Definition: errno.h:114
#define inet_addr(cp)
Definition: inet.h:98
int gGotSig
Definition: shell.c:60
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
Definition: netstat.c:32
int RCmd(const FTPCIPtr, ResponsePtr, const char *,...)
Definition: rcmd.c:718
int SetStartOffset(const FTPCIPtr cip, longest_int restartPt)
Definition: ftp.c:853
#define kServerTypeNcFTPd
Definition: ncftp.h:463
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define closesocket
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
int InitSReadlineInfo(SReadlineInfo *, int, char *, size_t, int, int)
Definition: SReadline.c:24
void CloseDataConnection(const FTPCIPtr cip)
Definition: ftp.c:831
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
char * h_name
Definition: winsock.h:134
u_short l_linger
Definition: winsock.h:143
void CloseControlConnection(const FTPCIPtr cip)
Definition: ftp.c:197
#define INADDR_NONE
Definition: tcp.c:42
#define SO_OOBINLINE
Definition: winsock.h:186
char * host
Definition: whois.c:55
#define kServerTypeServ_U
Definition: ncftp.h:467
unsigned short ephemHi
Definition: ncftp.h:195
char ** h_aliases
Definition: winsock.h:135
void DoneWithResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:114
GLdouble n
Definition: glext.h:7729
#define kErrSetStartPoint
Definition: ncftp_errno.h:34
#define SO_KEEPALIVE
Definition: winsock.h:181
LinePtr next
Definition: ncftp.h:80
#define STRNCPY(dst, src, n)
Definition: rdesktop.h:168
char gNoSignalsMarker[]
Definition: ftp.c:14
#define isalpha(c)
Definition: acclib.h:74
void SendTelnetInterrupt(const FTPCIPtr cip)
Definition: ftp.c:1328
#define kPassiveMode
Definition: ncftp.h:296
#define kErrSetTypeOfService
Definition: ncftp_errno.h:20
#define BUFSIZ
Definition: nsplookup.c:26
static int GetSocketAddress(const FTPCIPtr cip, int sockfd, struct sockaddr_in *saddr)
Definition: ftp.c:222
#define SETVBUF
Definition: util.h:70
#define kErrMallocFailed
Definition: ncftp_errno.h:40
#define SIGINT
Definition: signal.h:23
int errno
#define kFirewallNotInUse
Definition: ncftp.h:388
#define SAccept
Definition: sio.h:81
#define SOL_SOCKET
Definition: winsock.h:398
#define SO_LINGER
Definition: winsock.h:185
#define LIBNCFTP_USE_VAR(a)
Definition: ncftp.h:521
#define kErrPORTFailed
Definition: ncftp_errno.h:79
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
u32_t s_addr
Definition: inet.h:45
int SConnect(int sfd, const struct sockaddr_in *const addr, int tlen)
Definition: SConnect.c:9
unsigned short ephemLo
Definition: ncftp.h:194
struct sockaddr_in ourCtlAddr
Definition: ncftp.h:183
#define ntohs(x)
Definition: module.h:208
#define ECONNREFUSED
Definition: errno.h:122
size_t dataSocketSBufSize
Definition: ncftp.h:231
#define kErrHostUnknown
Definition: ncftp_errno.h:22
#define ENETUNREACH
Definition: errno.h:112
char * Strncat(char *const, const char *const, const size_t)
Definition: Strncat.c:13
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:93
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
#define kServerTypeNetWareFTP
Definition: ncftp.h:472
#define kErrPassiveModeFailed
Definition: ncftp_errno.h:30
FTPLIPtr lip
Definition: ncftp.h:149
#define MSG_OOB
Definition: winsock.h:221
#define ECONNRESET
Definition: errno.h:115
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define UNIMPLEMENTED_CMD(a)
Definition: ncftp.h:373
_Check_return_ int __cdecl rand(void)
Definition: rand.c:10
#define a
Definition: ke_i.h:78
#define kSendPortMode
Definition: ncftp.h:295
INT WSAAPI gethostname(OUT char FAR *name, IN INT namelen)
Definition: getxbyxx.c:397
#define kServerTypeVFTPD
Definition: ncftp.h:469
int GetOurHostName(char *host, size_t siz)
Definition: ftp.c:81
#define kErrSetLinger
Definition: ncftp_errno.h:19
#define kErrServerSentBogusPortNumber
Definition: ncftp_errno.h:31
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 ip[4]
Definition: rtl.c:1176
char firewallHost[64]
Definition: ncftp.h:217
cip dataSocket
Definition: ftp.c:1238
short h_length
Definition: winsock.h:137
FTPConnectMessageProc onConnectMsgProc
Definition: ncftp.h:224
smooth NULL
Definition: ftsmooth.c:416
static struct hostent * GetHostEntry(char *host, struct in_addr *ip_address)
Definition: ftp.c:53
#define kTimeoutErr
Definition: sio.h:58
unsigned char
Definition: typeof.h:29
#define kServerTypeMicrosoftFTP
Definition: ncftp.h:465
int firewallType
Definition: ncftp.h:221
Definition: parser.c:48
#define kServerTypeUnknown
Definition: ncftp.h:461
size_t ctrlSocketSBufSize
Definition: ncftp.h:229
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define kErrConnectRefused
Definition: ncftp_errno.h:37
#define kFallBackToSendPortMode
Definition: ncftp.h:297
u_short l_onoff
Definition: winsock.h:142
#define WSAETIMEDOUT
Definition: winerror.h:1973
int longjmp(jmp_buf buf, int retval)
#define isdigit(c)
Definition: acclib.h:68
#define kServerTypeRoxen
Definition: ncftp.h:471
#define inet_ntoa(addr)
Definition: inet.h:100
#define IPPROTO_IP
Definition: winsock.h:255
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
#define DOMAINNAME
Definition: options.h:45
int code
Definition: ncftp.h:92
void siglongjmp(sigjmp_buf buf, int val)
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
int OpenDataConnection(const FTPCIPtr cip, int mode)
Definition: ftp.c:1053
_CRTIMP int __cdecl getpid(void)
Definition: dhcpd.h:61
#define WSAEHOSTDOWN
Definition: winerror.h:1977
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#define longest_int
Definition: ncftp.h:68
#define kErrDupSocket
Definition: ncftp_errno.h:24
Definition: tcpip.h:125
int sigsetjmp(sigjmp_buf buf, int savesigs)
#define IPTOS_LOWDELAY
Definition: dhcpd.h:87
unsigned int defaultPort
Definition: ncftp.h:117
#define WSAENETDOWN
Definition: winerror.h:1963
BOOL Error
Definition: chkdsk.c:66
char ip[32]
Definition: ncftp.h:154
void(* FTPSigProc)(int)
Definition: ncftp.h:76
int codeType
Definition: ncftp.h:91
Definition: texture.c:1662
#define kErrFdopenR
Definition: ncftp_errno.h:25
Definition: ncftp.h:89
#define kErrGetSockName
Definition: ncftp_errno.h:27
int SetTypeOfService(const FTPCIPtr, int, int)
#define kErrConnectDataSocket
Definition: ncftp_errno.h:32
int signal
Definition: xcptfil.c:12
unsigned int xferTimeout
Definition: ncftp.h:141
#define kServerTypeWFTPD
Definition: ncftp.h:468
#define WSAENETUNREACH
Definition: winerror.h:1964
int SClose(int sfd, int tlen)
Definition: SClose.c:9
static int Passive(const FTPCIPtr cip, struct sockaddr_in *saddr, int *weird)
Definition: ftp.c:939
#define kClosedFileDescriptor
Definition: util.h:47
#define kDontPerror
Definition: util.h:45
#define kDoPerror
Definition: util.h:44
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
FILE * cout
Definition: ncftp.h:189
LinePtr first
Definition: ncftp.h:85
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
#define err(...)
int AcceptDataConnection(const FTPCIPtr cip)
Definition: ftp.c:1249
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
GLenum mode
Definition: glext.h:6217
char actualHost[64]
Definition: ncftp.h:153
size_t dataSocketRBufSize
Definition: ncftp.h:230
#define kCommandNotAvailable
Definition: ncftp.h:381
int OpenControlConnection(const FTPCIPtr cip, char *host, unsigned int port)
Definition: ftp.c:347
int SetSockBufSize(int sockfd, size_t rsize, size_t ssize)
Definition: util.c:572
#define kErrSetKeepAlive
Definition: ncftp_errno.h:69
#define kErrConnectMiscErr
Definition: ncftp_errno.h:35
int GetResponse(const FTPCIPtr, ResponsePtr)
Definition: rcmd.c:287
short h_addrtype
Definition: winsock.h:136
struct in_addr sin_addr
Definition: winsock.h:512
struct sockaddr_in servDataAddr
Definition: ncftp.h:182
LineList msg
Definition: ncftp.h:90
struct sockaddr_in ourDataAddr
Definition: ncftp.h:184
void PrintF(const FTPCIPtr cip, const char *const fmt,...)
Definition: util.c:340
int SetKeepAlive(const FTPCIPtr cip, int sockfd)
Definition: ftp.c:239
void fatal(const char *msg)
int SetInlineOutOfBandData(const FTPCIPtr, int)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
#define WSAECONNABORTED
Definition: winerror.h:1966
size_t ctrlSocketRBufSize
Definition: ncftp.h:228
struct sockaddr_in servCtlAddr
Definition: ncftp.h:181
#define STRNEQ(a, b, s)
Definition: util.h:21
char gLibNcFTPVersion[64]
Definition: ftp.c:11
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
char * Strncpy(char *const, const char *const, const size_t)
Definition: Strncpy.c:11
static int SendPort(const FTPCIPtr cip, struct sockaddr_in *saddr)
Definition: ftp.c:899
#define HOSTNAME
Definition: options.h:42
#define WSAECONNRESET
Definition: winerror.h:1967
_Check_return_ _CRTIMP FILE *__cdecl fdopen(_In_ int _FileHandle, _In_z_ const char *_Format)
void HangupOnServer(const FTPCIPtr cip)
Definition: ftp.c:1314
#define kErrNewStreamSocket
Definition: ncftp_errno.h:23
unsigned int firewallPort
Definition: ncftp.h:220
static int BindToEphemeralPortNumber(int sockfd, struct sockaddr_in *addrp, int ephemLo, int ephemHi)
Definition: ftp.c:1011
#define setjmp
Definition: setjmp.h:183
#define ENETDOWN
Definition: errno.h:111
#define IAC
Definition: ftp_var.h:13
char * strtok(char *String, const char *Delimiters)
Definition: utclib.c:338
#define PRINTF_LONG_LONG
Definition: wincfg.h:31
char srlBuf[768]
Definition: ncftp.h:239
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
int SetLinger(const FTPCIPtr cip, int sockfd, int onoff)
Definition: ftp.c:262
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define msg(x)
Definition: auth_time.c:54
void CloseFile(FILE **f)
Definition: util.c:327
POINT cp
Definition: magnifier.c:59
_Check_return_ _CRTIMP int __cdecl dup(_In_ int _FileHandle)
#define WSAECONNREFUSED
Definition: winerror.h:1974
#define DM
Definition: ftp_var.h:26
#define kNoErr
Definition: ncftp_errno.h:9
#define AF_INET
Definition: tcpip.h:117
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define ETIMEDOUT
Definition: errno.h:121
const char *WSAAPI inet_ntop(int af, const void *src, char *dst, size_t cnt)
Definition: unix_func.c:8
#define kErrListenDataSocket
Definition: ncftp_errno.h:29
static const char * onoff(int bool)
Definition: cmds.c:777
#define kErrConnectRetryableErr
Definition: ncftp_errno.h:36
long jmp_buf[100]
Definition: of.h:11
#define SOCK_STREAM
Definition: tcpip.h:118
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
#define htons(x)
Definition: module.h:213
SReadlineInfo ctrlSrl
Definition: ncftp.h:240
#define kLibraryVersion
Definition: ncftp.h:11
ResponsePtr InitResponse(void)
Definition: rcmd.c:38
USHORT port
Definition: uri.c:228
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
unsigned int connTimeout
Definition: ncftp.h:142
char * line
Definition: ncftp.h:81
#define kErrSetOutOfBandInline
Definition: ncftp_errno.h:21
short sin_family
Definition: winsock.h:510
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
#define kErrPASVFailed
Definition: ncftp_errno.h:80
#define kServerTypeProFTPD
Definition: ncftp.h:464
#define _IOLBF
Definition: stdio.h:129
#define kServerTypeFTP_Max
Definition: ncftp.h:470
int dataPortMode
Definition: ncftp.h:152
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
#define kErrFdopenW
Definition: ncftp_errno.h:26