ReactOS  0.4.12-dev-43-g63b00d8
ftp.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1985, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley. The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17 
18 #include "precomp.h"
19 
20 #include <signal.h>
21 
22 #define L_SET SEEK_SET
23 #define L_INCR SEEK_CUR
24 #define caddr_t void *
25 
26 #ifndef lint
27 static char sccsid[] = "@(#)ftp.c 5.28 (Berkeley) 4/20/89";
28 #endif /* not lint */
29 
30 #ifndef MAXHOSTNAMELEN
31 #define MAXHOSTNAMELEN 64
32 #endif
33 
34 #ifdef NOVFPRINTF
35 #define vfprintf(a,b,c) _doprnt(b,c,a)
36 #endif
37 
38 #ifdef sun
39 /* FD_SET wasn't defined until 4.0. its a cheap test for uid_t presence */
40 #ifndef FD_SET
41 #define NBBY 8 /* number of bits in a byte */
42 /*
43  * Select uses bit masks of file descriptors in longs.
44  * These macros manipulate such bit fields (the filesystem macros use chars).
45  * FD_SETSIZE may be defined by the user, but the default here
46  * should be >= NOFILE (param.h).
47  */
48 #ifndef FD_SETSIZE
49 #define FD_SETSIZE 256
50 #endif
51 
52 typedef long fd_mask;
53 #define NFDBITS (sizeof(fd_mask) * NBBY) /* bits per mask */
54 #ifndef howmany
55 #define howmany(x, y) (((x)+((y)-1))/(y))
56 #endif
57 
58 #define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
59 #define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
60 #define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
61 #define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
62 
63 typedef int uid_t;
64 typedef int gid_t;
65 #endif
66 #endif
67 
70 int data = -1;
71 int abrtflag = 0;
72 int ptflag = 0;
75 uid_t getuid();
76 #ifdef __REACTOS__
77 void lostpeer(void);
78 #else
79 sig_t lostpeer();
80 #endif
82 
84 int dataconn(const char *mode);
85 
86 int command(const char *fmt, ...);
87 
88 char *hostname;
89 
90 typedef void (*Sig_t)(int);
91 
92 // Signal Handlers
93 
94 void psabort(int sig);
95 
96 char *hookup(const char *host, int port)
97 {
98  register struct hostent *hp = 0;
99  int len;
100  SOCKET s;
101  static char hostnamebuf[80];
102 
103  bzero((char *)&hisctladdr, sizeof (hisctladdr));
104  hisctladdr.sin_addr.s_addr = inet_addr(host);
105  if (hisctladdr.sin_addr.s_addr != (unsigned long)-1) {
106  hisctladdr.sin_family = AF_INET;
107  (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
108  } else {
109  hp = gethostbyname(host);
110  if (hp == NULL) {
111  fprintf(stderr, "ftp: %s: ", host);
112  herror((char *)NULL);
113  code = -1;
114  return((char *) 0);
115  }
116  hisctladdr.sin_family = hp->h_addrtype;
117  bcopy(hp->h_addr_list[0],
118  (caddr_t)&hisctladdr.sin_addr, hp->h_length);
119  (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
120  }
121  hostname = hostnamebuf;
122  s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
123  if (s == INVALID_SOCKET) {
124  perror("ftp: socket");
125  code = -1;
126  return (0);
127  }
128  hisctladdr.sin_port = port;
129  while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
130  if (hp && hp->h_addr_list[1]) {
131  int oerrno = errno;
132 
133  fprintf(stderr, "ftp: connect to address %s: ",
134  inet_ntoa(hisctladdr.sin_addr));
135  errno = oerrno;
136  perror((char *) 0);
137  hp->h_addr_list++;
138  bcopy(hp->h_addr_list[0],
139  (caddr_t)&hisctladdr.sin_addr, hp->h_length);
140  fprintf(stdout, "Trying %s...\n",
141  inet_ntoa(hisctladdr.sin_addr));
142  (void) fflush(stdout);
143  (void) close(s);
144  s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
145  if (s == INVALID_SOCKET) {
146  perror("ftp: socket");
147  code = -1;
148  return (0);
149  }
150  continue;
151  }
152  perror("ftp: connect");
153  code = -1;
154  goto bad;
155  }
156  len = sizeof (myctladdr);
157  if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
158  perror("ftp: getsockname");
159  code = -1;
160  goto bad;
161  }
162  cin = cout = s;
163  if (verbose) {
164  printf("Connected to %s.\n", hostname);
165  (void) fflush(stdout);
166  }
167  if (getreply(0) > 2) { /* read startup message from server */
168  closesocket(cin);
169  code = -1;
170  goto bad;
171  }
172 #ifdef SO_OOBINLINE
173  {
174  int on = 1;
175 
176  if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (const char *) &on, sizeof(on))
177  < 0 && debug) {
178  perror("ftp: setsockopt");
179  }
180  }
181 #endif //SO_OOBINLINE
182 
183  return (hostname);
184 bad:
185  (void) close(s);
186  return ((char *)0);
187 }
188 
189 int login(const char *host)
190 {
191  char tmp[80];
192  char *puser, *ppass, *pacct;
193  const char *user, *pass, *acct;
194  int n, aflag = 0;
195 
196  user = pass = acct = 0;
197  n = ruserpass(host, &puser, &ppass, &pacct);
198  if (n < 0) {
199  code = -1;
200  return(0);
201  }
202  if (0 != n) {
203  user = puser;
204  pass = ppass;
205  acct = pacct;
206  }
207  while (user == NULL) {
208  const char *myname = "none"; // This needs to become the username env
209 
210  if (myname)
211  printf("Name (%s:%s): ", host, myname);
212  else
213  printf("Name (%s): ", host);
214  (void) fflush(stdout);
215  (void) fgets(tmp, sizeof(tmp) - 1, stdin);
216  tmp[strlen(tmp) - 1] = '\0';
217  if (*tmp == '\0')
218  user = myname;
219  else
220  user = tmp;
221  }
222  n = command("USER %s", user);
223  if (n == CONTINUE) {
224  if (pass == NULL)
225  pass = getpass("Password:");
226  n = command("PASS %s", pass);
227  fflush(stdin);
228  }
229  if (n == CONTINUE) {
230  aflag++;
231  acct = getpass("Account:");
232  n = command("ACCT %s", acct);
233  }
234  if (n != COMPLETE) {
235  fprintf(stderr, "Login failed.\n");
236  return (0);
237  }
238  if (!aflag && acct != NULL)
239  (void) command("ACCT %s", acct);
240  if (proxy)
241  return(1);
242  for (n = 0; n < macnum; ++n) {
243  if (!strcmp("init", macros[n].mac_name)) {
244  (void) strcpy(line, "$init");
245  makeargv();
246  domacro(margc, margv);
247  break;
248  }
249  }
250  return (1);
251 }
252 
253 static void
254 cmdabort(int sig)
255 {
256  extern jmp_buf ptabort;
257 
258  printf("\n");
259  (void) fflush(stdout);
260  abrtflag++;
261  if (ptflag)
262  longjmp(ptabort,1);
263 }
264 
265 /*VARARGS1*/
266 int command(const char *fmt, ...)
267 {
268  va_list ap;
269  int r;
270  void (*oldintr)(int);
271 
272  abrtflag = 0;
273  if (debug) {
274  printf("---> ");
275  va_start(ap, fmt);
276  vfprintf(stdout, fmt, ap);
277  va_end(ap);
278  printf("\n");
279  (void) fflush(stdout);
280  }
281  if (cout == 0) {
282  perror ("No control connection for command");
283  code = -1;
284  return (0);
285  }
286  oldintr = signal(SIGINT,cmdabort);
287  {
288  char buffer[1024];
289 
290  va_start(ap, fmt);
291  vsprintf(buffer, fmt, ap);
292  va_end(ap);
293 //DLJ: to work through firewalls - send the command as a single message
294  strcat(buffer,"\r\n");
295  fprintfSocket(cout, buffer);
296  }
297 //DLJ: the following two lines are replaced by the strcat above - seems to
298 // make it work through firewalls.
299 // fprintfSocket(cout, "\r\n");
300 // (void) fflush(cout);
301  cpend = 1;
302  r = getreply(!strcmp(fmt, "QUIT"));
303  if (abrtflag && oldintr != SIG_IGN)
304  (*oldintr)(SIGINT);
305 // (void) signal(SIGINT, oldintr);
306  return(r);
307 }
308 
309 char reply_string[BUFSIZ]; /* last line of previous reply */
310 
311 #include <ctype.h>
312 
313 int
314 getreply(expecteof)
315  int expecteof;
316 {
317  register int c, n;
318  register int dig;
319  register char *cp;
320  int originalcode = 0, continuation = 0;
321  void (*oldintr)(int);
322  int pflag = 0;
323  char *pt = pasv;
324 
325  oldintr = signal(SIGINT,cmdabort);
326  for (;;) {
327  dig = n = code = 0;
328  cp = reply_string;
329  while ((c = fgetcSocket(cin)) != '\n') {
330  if (c == IAC) { /* handle telnet commands */
331  switch (fgetcSocket(cin)) {
332  case WILL:
333  case WONT:
334  c = fgetcSocket(cin);
335  fprintfSocket(cout, "%c%c%c",IAC,DONT,c);
336  break;
337  case DO:
338  case DONT:
339  c = fgetcSocket(cin);
340  fprintfSocket(cout, "%c%c%c",IAC,WONT,c);
341  break;
342  default:
343  break;
344  }
345  continue;
346  }
347  dig++;
348  if (c == EOF) {
349  if (expecteof) {
350 // (void) signal(SIGINT,oldintr);
351  code = 221;
352  return (0);
353  }
354  lostpeer();
355  if (verbose) {
356  printf("421 Service not available, remote server has closed connection\n");
357  (void) fflush(stdout);
358  }
359  code = 421;
360  return(4);
361  }
362  if (c != '\r' && (verbose > 0 ||
363  (verbose > -1 && n == '5' && dig > 4))) {
364  if (proxflag &&
365  ((dig == 1 || dig == 5) && verbose == 0))
366  printf("%s:",hostname);
367  (void) putchar(c);
368  (void) fflush(stdout);
369  }
370  if (dig < 4 && isdigit(c))
371  code = code * 10 + (c - '0');
372  if (!pflag && code == 227)
373  pflag = 1;
374  if (dig > 4 && pflag == 1 && isdigit(c))
375  pflag = 2;
376  if (pflag == 2) {
377  if (c != '\r' && c != ')')
378  *pt++ = c;
379  else {
380  *pt = '\0';
381  pflag = 3;
382  }
383  }
384  if (dig == 4 && c == '-') {
385  if (continuation)
386  code = 0;
387  continuation++;
388  }
389  if (n == 0)
390  n = c;
391  if (cp < &reply_string[sizeof(reply_string) - 1])
392  *cp++ = c;
393  }
394  if (verbose > 0 || (verbose > -1 && n == '5')) {
395  (void) putchar(c);
396  (void) fflush (stdout);
397  }
398  if (continuation && code != originalcode) {
399  if (originalcode == 0)
400  originalcode = code;
401  continue;
402  }
403  *cp = '\0';
404  if (n != '1')
405  cpend = 0;
406  (void) signal(SIGINT,oldintr);
407  if (code == 421 || originalcode == 421)
408  lostpeer();
409  if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
410  (*oldintr)(SIGINT);
411  return (n - '0');
412  }
413 }
414 
415 static int
416 empty(mask, sec)
417  struct fd_set *mask;
418  int sec;
419 {
420  struct timeval t;
421 
422  t.tv_sec = (long) sec;
423  t.tv_usec = 0;
424  return(select(32, mask, (struct fd_set *) 0, (struct fd_set *) 0, &t));
425 }
426 
428 
429 #if 0
430 void abortsend()
431 {
432 
433  mflag = 0;
434  abrtflag = 0;
435  printf("\nsend aborted\n");
436  (void) fflush(stdout);
437  longjmp(sendabort, 1);
438 }
439 #endif
440 
441 #define HASHBYTES 1024
442 
443 void sendrequest(const char *cmd, const char *local, const char *remote, int printnames)
444 {
445  FILE *fin;
446  int dout = 0;
447  int (*closefunc)();
448  sig_t (*oldintr)(), (*oldintp)();
449  char buf[BUFSIZ], *bufp;
450  long bytes = 0, hashbytes = HASHBYTES;
451  register int c, d;
452  struct stat st;
453  struct timeval start, stop;
454  const char *mode;
455 
456  if (verbose && printnames) {
457  if (local && *local != '-')
458  printf("local: %s ", local);
459  if (remote)
460  printf("remote: %s\n", remote);
461  (void) fflush(stdout);
462  }
463  if (proxy) {
464  proxtrans(cmd, local, remote);
465  return;
466  }
467  closefunc = NULL;
468  oldintr = NULL;
469  oldintp = NULL;
470  mode = "w";
471  if (setjmp(sendabort)) {
472  while (cpend) {
473  (void) getreply(0);
474  }
475  if (data >= 0) {
476  (void) close(data);
477  data = -1;
478  }
479  if (oldintr)
480 null();// (void) signal(SIGINT,oldintr);
481  if (oldintp)
482 null();// (void) signal(SIGPIPE,oldintp);
483  code = -1;
484  return;
485  }
486 null();// oldintr = signal(SIGINT, abortsend);
487  if (strcmp(local, "-") == 0)
488  fin = stdin;
489  else if (*local == '|') {
490 null();// oldintp = signal(SIGPIPE,SIG_IGN);
491  fin = _popen(local + 1, "r");
492  if (fin == NULL) {
493  perror(local + 1);
494 null();// (void) signal(SIGINT, oldintr);
495 null();// (void) signal(SIGPIPE, oldintp);
496  code = -1;
497  return;
498  }
499  closefunc = _pclose;
500  } else {
501  fin = fopen(local, "r");
502  if (fin == NULL) {
503  perror(local);
504 null();// (void) signal(SIGINT, oldintr);
505  code = -1;
506  return;
507  }
508  closefunc = fclose;
509  if (fstat(fileno(fin), &st) < 0 ||
510  (st.st_mode&S_IFMT) != S_IFREG) {
511  fprintf(stdout, "%s: not a plain file.\n", local);
512  (void) fflush(stdout);
513 null();// (void) signal(SIGINT, oldintr);
514  fclose(fin);
515  code = -1;
516  return;
517  }
518  }
519  if (initconn()) {
520 null();// (void) signal(SIGINT, oldintr);
521  if (oldintp)
522 null();// (void) signal(SIGPIPE, oldintp);
523  code = -1;
524  if (closefunc != NULL)
525  (*closefunc)(fin);
526  return;
527  }
528  if (setjmp(sendabort))
529  goto abort;
530 
531  if (restart_point &&
532  (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
533  if (fseek(fin, (long) restart_point, 0) < 0) {
534  perror(local);
535  restart_point = 0;
536  if (closefunc != NULL)
537  (*closefunc)(fin);
538  return;
539  }
540  if (command("REST %ld", (long) restart_point)
541  != CONTINUE) {
542  restart_point = 0;
543  if (closefunc != NULL)
544  (*closefunc)(fin);
545  return;
546  }
547  restart_point = 0;
548  mode = "r+w";
549  }
550  if (remote) {
551  if (command("%s %s", cmd, remote) != PRELIM) {
552 null();// (void) signal(SIGINT, oldintr);
553  if (oldintp)
554 null();// (void) signal(SIGPIPE, oldintp);
555  if (closefunc != NULL)
556  (*closefunc)(fin);
557  return;
558  }
559  } else
560  if (command("%s", cmd) != PRELIM) {
561 null();// (void) signal(SIGINT, oldintr);
562  if (oldintp)
563 null();// (void) signal(SIGPIPE, oldintp);
564  if (closefunc != NULL)
565  (*closefunc)(fin);
566  return;
567  }
568  dout = dataconn(mode);
569  if (!dout)
570  goto abort;
571  (void) gettimeofday(&start, (struct timezone *)0);
572 null();// oldintp = signal(SIGPIPE, SIG_IGN);
573  switch (type) {
574 
575  case TYPE_I:
576  case TYPE_L:
577  errno = d = 0;
578  while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
579  bytes += c;
580  for (bufp = buf; c > 0; c -= d, bufp += d)
581  if ((d = send(dout, bufp, c, 0)) <= 0)
582  break;
583  if (hash) {
584  while (bytes >= hashbytes) {
585  (void) putchar('#');
586  hashbytes += HASHBYTES;
587  }
588  (void) fflush(stdout);
589  }
590  }
591  if (hash && bytes > 0) {
592  if (bytes < HASHBYTES)
593  (void) putchar('#');
594  (void) putchar('\n');
595  (void) fflush(stdout);
596  }
597  if (c < 0)
598  perror(local);
599  if (d <= 0) {
600  if (d == 0)
601  fprintf(stderr, "netout: write returned 0?\n");
602  else if (errno != EPIPE)
603  perror("netout");
604  bytes = -1;
605  }
606  break;
607 
608  case TYPE_A:
609  {
610  char buf[1024];
611  static int bufsize = 1024;
612  int ipos=0;
613 
614  while ((c = getc(fin)) != EOF) {
615  if (c == '\n') {
616  while (hash && (bytes >= hashbytes)) {
617  (void) putchar('#');
618  (void) fflush(stdout);
619  hashbytes += HASHBYTES;
620  }
621 // Szurgot: The following code is unnecessary on Win32.
622 // (void) fputcSocket(dout, '\r');
623 // bytes++;
624  }
625 
626  if (ipos >= bufsize) {
627  fputSocket(dout,buf,ipos);
628  if(!hash) (void) putchar('.');
629  ipos=0;
630  }
631  buf[ipos]=c; ++ipos;
632  bytes++;
633  }
634  if (ipos) {
635  fputSocket(dout,buf,ipos);
636  ipos=0;
637  }
638  if (hash) {
639  if (bytes < hashbytes)
640  (void) putchar('#');
641  (void) putchar('\n');
642  (void) fflush(stdout);
643  }
644  else {
645  (void) putchar('.');
646  (void) putchar('\n');
647  (void) fflush(stdout);
648  }
649  if (ferror(fin))
650  perror(local);
651 // if (ferror(dout)) {
652 // if (errno != EPIPE)
653 // perror("netout");
654 // bytes = -1;
655 // }
656  break;
657  }
658  }
659  (void) gettimeofday(&stop, (struct timezone *)0);
660  if (closefunc != NULL)
661  (*closefunc)(fin);
662  if(closesocket(dout)) {
663  int iret=WSAGetLastError ();
664  fprintf(stdout,"Error closing socket(%d)\n",iret);
665  (void) fflush(stdout);
666  }
667  (void) getreply(0);
668 null();// (void) signal(SIGINT, oldintr);
669  if (oldintp)
670 null();// (void) signal(SIGPIPE, oldintp);
671  if (bytes > 0)
672  ptransfer("sent", bytes, &start, &stop);
673  return;
674 abort:
675  (void) gettimeofday(&stop, (struct timezone *)0);
676 null();// (void) signal(SIGINT, oldintr);
677  if (oldintp)
678 null();// (void) signal(SIGPIPE, oldintp);
679  if (!cpend) {
680  code = -1;
681  (*closefunc)(fin);
682  return;
683  }
684  if (data >= 0) {
685  (void) close(data);
686  data = -1;
687  }
688  if (dout)
689  if(closesocket(dout)) {
690  int iret=WSAGetLastError ();
691  fprintf(stdout,"Error closing socket(%d)\n",iret);
692  (void) fflush(stdout);
693  }
694 
695  (void) getreply(0);
696  code = -1;
697  if (closefunc != NULL && fin != NULL)
698  (*closefunc)(fin);
699  if (bytes > 0)
700  ptransfer("sent", bytes, &start, &stop);
701 }
702 
704 
705 #if 0
706 void abortrecv()
707 {
708 
709  mflag = 0;
710  abrtflag = 0;
711  printf("\n");
712  (void) fflush(stdout);
713  longjmp(recvabort, 1);
714 }
715 #endif
716 
717 void recvrequest(const char *cmd, const char *local, const char *remote, const char *mode,
718  int printnames)
719 {
720  FILE *fout = stdout;
721  int din = 0;
722  int (*closefunc)();
723  void (*oldintr)(int), (*oldintp)(int);
724  int oldverbose = 0, oldtype = 0, is_retr, tcrflag, nfnd, bare_lfs = 0;
725  char msg;
726 // static char *buf; // Szurgot: Shouldn't this go SOMEWHERE?
727  char buf[1024];
728  static int bufsize = 1024;
729  long bytes = 0, hashbytes = HASHBYTES;
730 // struct
731  fd_set mask;
732  register int c;
733  struct timeval start, stop;
734 // struct stat st;
735 
736  is_retr = strcmp(cmd, "RETR") == 0;
737  if (is_retr && verbose && printnames) {
738  if (local && *local != '-')
739  printf("local: %s ", local);
740  if (remote)
741  printf("remote: %s\n", remote);
742  (void) fflush(stdout);
743  }
744  if (proxy && is_retr) {
745  proxtrans(cmd, local, remote);
746  return;
747  }
748  closefunc = NULL;
749  oldintr = NULL;
750  oldintp = NULL;
751  tcrflag = !crflag && is_retr;
752  if (setjmp(recvabort)) {
753  while (cpend) {
754  (void) getreply(0);
755  }
756  if (data >= 0) {
757  (void) close(data);
758  data = -1;
759  }
760  if (oldintr)
761 null();// (void) signal(SIGINT, oldintr);
762  code = -1;
763  return;
764  }
765 null();// oldintr = signal(SIGINT, abortrecv);
766  if (strcmp(local, "-") && *local != '|') {
767 #ifndef _WIN32
768  register int d;
769 // This whole thing is a problem... access Won't work on non-existent files
770  if (access(local, 2) < 0) {
771  char *dir = rindex(local, '/');
772 
773  if (errno != ENOENT && errno != EACCES) {
774  perror(local);
775  (void) signal(SIGINT, oldintr);
776  code = -1;
777  return;
778  }
779  if (dir != NULL)
780  *dir = 0;
781  d = access(dir ? local : ".", 2);
782  if (dir != NULL)
783  *dir = '/';
784  if (d < 0) {
785  perror(local);
786  (void) signal(SIGINT, oldintr);
787  code = -1;
788  return;
789  }
790  if (!runique && errno == EACCES &&
791  chmod(local, 0600) < 0) {
792  perror(local);
793  (void) signal(SIGINT, oldintr);
794  code = -1;
795  return;
796  }
797  if (runique && errno == EACCES &&
798  (local = gunique(local)) == NULL) {
799  (void) signal(SIGINT, oldintr);
800  code = -1;
801  return;
802  }
803  }
804  else if (runique && (local = gunique(local)) == NULL) {
805  (void) signal(SIGINT, oldintr);
806  code = -1;
807  return;
808  }
809 #endif
810  }
811  if (initconn()) {
812 null();// (void) signal(SIGINT, oldintr);
813  code = -1;
814  return;
815  }
816  if (setjmp(recvabort))
817  goto abort;
818  if (!is_retr) {
819  if (type != TYPE_A && (allbinary == 0 || type != TYPE_I)) {
820  oldtype = type;
821  oldverbose = verbose;
822  if (!debug)
823  verbose = 0;
824  setascii(0, NULL);
825  verbose = oldverbose;
826  }
827  } else if (restart_point) {
828  if (command("REST %ld", (long) restart_point) != CONTINUE)
829  return;
830  }
831  if (remote) {
832  if (command("%s %s", cmd, remote) != PRELIM) {
833 null();// (void) signal(SIGINT, oldintr);
834  if (oldtype) {
835  if (!debug)
836  verbose = 0;
837  switch (oldtype) {
838  case TYPE_I:
839  setbinary(0, NULL);
840  break;
841  case TYPE_E:
842  setebcdic();
843  break;
844  case TYPE_L:
845  settenex(0, NULL);
846  break;
847  }
848  verbose = oldverbose;
849  }
850  return;
851  }
852  } else {
853  if (command("%s", cmd) != PRELIM) {
854 null();// (void) signal(SIGINT, oldintr);
855  if (oldtype) {
856  if (!debug)
857  verbose = 0;
858  switch (oldtype) {
859  case TYPE_I:
860  setbinary(0, NULL);
861  break;
862  case TYPE_E:
863  setebcdic();
864  break;
865  case TYPE_L:
866  settenex(0, NULL);
867  break;
868  }
869  verbose = oldverbose;
870  }
871  return;
872  }
873  }
874  din = dataconn("r");
875  if (!din)
876  goto abort;
877  if (strcmp(local, "-") == 0)
878  fout = stdout;
879  else if (*local == '|') {
880 null();// oldintp = signal(SIGPIPE, SIG_IGN);
881  fout = _popen(local + 1, "w");
882  if (fout == NULL) {
883  perror(local+1);
884  goto abort;
885  }
886  closefunc = _pclose;
887  } else {
888  fout = fopen(local, mode);
889  if (fout == NULL) {
890  perror(local);
891  goto abort;
892  }
893  closefunc = fclose;
894  }
895  (void) gettimeofday(&start, (struct timezone *)0);
896  switch (type) {
897 
898  case TYPE_I:
899  case TYPE_L:
900  if (restart_point &&
901  lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
902  perror(local);
903  if (closefunc != NULL)
904  (*closefunc)(fout);
905  return;
906  }
907  errno = 0;
908 // while ((c = recv(din, buf, bufsize, 1)) > 0) {
909 // if ((d = write(fileno(fout), buf, c)) != c)
910 // if ((d = write(fileno(fout), buf, c)) != c)
911 // break;
912  while ((c = recv(din, buf, bufsize, 0)) > 0) {
913  write(fileno(fout), buf, c);
914  bytes += c;
915  if (hash) {
916  while (bytes >= hashbytes) {
917  (void) putchar('#');
918  hashbytes += HASHBYTES;
919  }
920  (void) fflush(stdout);
921  }
922  }
923  if (hash && bytes > 0) {
924  if (bytes < HASHBYTES)
925  (void) putchar('#');
926  (void) putchar('\n');
927  (void) fflush(stdout);
928  }
929 // if (c < 0) {
930 // if (errno != EPIPE)
931 // perror("netin");
932 // bytes = -1;
933 // }
934 // if (d < c) {
935 // if (d < 0)
936 // perror(local);
937 // else
938 // fprintf(stderr, "%s: short write\n", local);
939 // }
940  break;
941 
942  case TYPE_A:
943  if (restart_point) {
944  register int i, n, c;
945 
946  if (fseek(fout, 0L, L_SET) < 0)
947  goto done;
948  n = restart_point;
949  i = 0;
950  while (i++ < n) {
951  if ((c=getc(fout)) == EOF)
952  goto done;
953  if (c == '\n')
954  i++;
955  }
956  if (fseek(fout, 0L, L_INCR) < 0) {
957 done:
958  perror(local);
959  if (closefunc != NULL)
960  (*closefunc)(fout);
961  return;
962  }
963  }
964  while ((c = fgetcSocket(din)) != EOF) {
965  if (c == '\n')
966  bare_lfs++;
967  while (c == '\r') {
968  while (hash && (bytes >= hashbytes)) {
969  (void) putchar('#');
970  (void) fflush(stdout);
971  hashbytes += HASHBYTES;
972  }
973  bytes++;
974  if ((c = fgetcSocket(din)) != '\n' || tcrflag) {
975  if (ferror(fout))
976  goto break2;
977  (void) putc('\r', fout);
978  if (c == '\0') {
979  bytes++;
980  goto contin2;
981  }
982  if (c == EOF)
983  goto contin2;
984  }
985  }
986  (void) putc(c, fout);
987  bytes++;
988  contin2: ;
989  }
990 break2:
991  if (bare_lfs) {
992  printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
993  printf("File may not have transferred correctly.\n");
994  (void) fflush(stdout);
995  }
996  if (hash) {
997  if (bytes < hashbytes)
998  (void) putchar('#');
999  (void) putchar('\n');
1000  (void) fflush(stdout);
1001  }
1002 // if (ferror(din)) {
1003 // if (errno != EPIPE)
1004 // perror("netin");
1005 // bytes = -1;
1006 // }
1007  if (ferror(fout))
1008  perror(local);
1009  break;
1010  }
1011  if (closefunc != NULL)
1012  (*closefunc)(fout);
1013 null();// (void) signal(SIGINT, oldintr);
1014  if (oldintp)
1015 null();// (void) signal(SIGPIPE, oldintp);
1016  (void) gettimeofday(&stop, (struct timezone *)0);
1017  if(closesocket(din)) {
1018  int iret=WSAGetLastError ();
1019  fprintf(stdout,"Error closing socket(%d)\n",iret);
1020  (void) fflush(stdout);
1021  }
1022 
1023  (void) getreply(0);
1024  if (bytes > 0 && is_retr)
1025  ptransfer("received", bytes, &start, &stop);
1026  if (oldtype) {
1027  if (!debug)
1028  verbose = 0;
1029  switch (oldtype) {
1030  case TYPE_I:
1031  setbinary(0, NULL);
1032  break;
1033  case TYPE_E:
1034  setebcdic();
1035  break;
1036  case TYPE_L:
1037  settenex(0, NULL);
1038  break;
1039  }
1040  verbose = oldverbose;
1041  }
1042  return;
1043 abort:
1044 
1045 /* abort using RFC959 recommended IP,SYNC sequence */
1046 
1047  (void) gettimeofday(&stop, (struct timezone *)0);
1048  if (oldintp)
1049 null();// (void) signal(SIGPIPE, oldintr);
1050 null();// (void) signal(SIGINT,SIG_IGN);
1051  if (oldtype) {
1052  if (!debug)
1053  verbose = 0;
1054  switch (oldtype) {
1055  case TYPE_I:
1056  setbinary(0, NULL);
1057  break;
1058  case TYPE_E:
1059  setebcdic();
1060  break;
1061  case TYPE_L:
1062  settenex(0, NULL);
1063  break;
1064  }
1065  verbose = oldverbose;
1066  }
1067  if (!cpend) {
1068  code = -1;
1069 null();// (void) signal(SIGINT,oldintr);
1070  return;
1071  }
1072 
1073  fprintfSocket(cout,"%c%c",IAC,IP);
1074  msg = (char)IAC;
1075 /* send IAC in urgent mode instead of DM because UNIX places oob mark */
1076 /* after urgent byte rather than before as now is protocol */
1077  if (send(cout,&msg,1,MSG_OOB) != 1) {
1078  perror("abort");
1079  }
1080  fprintfSocket(cout,"%cABOR\r\n",DM);
1081  FD_ZERO(&mask);
1082  FD_SET(cin, &mask); // Need to correct this
1083  if (din) {
1084  FD_SET(din, &mask); // Need to correct this
1085  }
1086  if ((nfnd = empty(&mask,10)) <= 0) {
1087  if (nfnd < 0) {
1088  perror("abort");
1089  }
1090  code = -1;
1091  lostpeer();
1092  }
1093  if (din && FD_ISSET(din, &mask)) {
1094  while (recv(din, buf, bufsize, 0) > 0)
1095  ;
1096  }
1097  if (getreply(0) == ERROR && code == 552) { /* needed for nic style abort */
1098  if (data >= 0) {
1099  (void) close(data);
1100  data = -1;
1101  }
1102  (void) getreply(0);
1103  }
1104  (void) getreply(0);
1105  code = -1;
1106  if (data >= 0) {
1107  (void) close(data);
1108  data = -1;
1109  }
1110  if (closefunc != NULL && fout != NULL)
1111  (*closefunc)(fout);
1112  if (din)
1113  if(closesocket(din)) {
1114  int iret=WSAGetLastError ();
1115  fprintf(stdout,"Error closing socket(%d)\n",iret);
1116  (void) fflush(stdout);
1117  }
1118 
1119  if (bytes > 0)
1120  ptransfer("received", bytes, &start, &stop);
1121 null();// (void) signal(SIGINT,oldintr);
1122 }
1123 
1124 int
1126 {
1127  register char *p, *a;
1128  int result, len, tmpno = 0;
1129  int on = 1;
1130  int a0, a1, a2, a3, p0, p1;
1131 
1132 
1133  if (passivemode) {
1134  data = socket(AF_INET, SOCK_STREAM, 0);
1135  if (data < 0) {
1136  perror("ftp: socket");
1137  return(1);
1138  }
1139  if ((options & SO_DEBUG) &&
1140  setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on,
1141  sizeof (on)) < 0)
1142  perror("ftp: setsockopt (ignored)");
1143  if (command("PASV") != COMPLETE) {
1144  printf("Passive mode refused.\n");
1145  goto bad;
1146  }
1147 
1148  /*
1149  * What we've got at this point is a string of comma
1150  * separated one-byte unsigned integer values.
1151  * The first four are the an IP address. The fifth is
1152  * the MSB of the port number, the sixth is the LSB.
1153  * From that we'll prepare a sockaddr_in.
1154  */
1155 
1156  if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",
1157  &a0, &a1, &a2, &a3, &p0, &p1) != 6) {
1158  printf("Passive mode address scan failure. Shouldn't happen!\n");
1159  goto bad;
1160  }
1161 
1162  bzero(&data_addr, sizeof(data_addr));
1163  data_addr.sin_family = AF_INET;
1164  a = (char *)&data_addr.sin_addr.s_addr;
1165  a[0] = a0 & 0xff;
1166  a[1] = a1 & 0xff;
1167  a[2] = a2 & 0xff;
1168  a[3] = a3 & 0xff;
1169  p = (char *)&data_addr.sin_port;
1170  p[0] = p0 & 0xff;
1171  p[1] = p1 & 0xff;
1172 
1173  if (connect(data, (struct sockaddr *)&data_addr,
1174  sizeof(data_addr)) < 0) {
1175  perror("ftp: connect");
1176  goto bad;
1177  }
1178  return(0);
1179  }
1180 
1181 
1182 noport:
1183  data_addr = myctladdr;
1184  if (sendport)
1185  data_addr.sin_port = 0; /* let system pick one */
1186  if (data != -1)
1187  (void) close (data);
1188  data = socket(AF_INET, SOCK_STREAM, 0);
1189  if (data < 0) {
1190  perror("ftp: socket");
1191  if (tmpno)
1192  sendport = 1;
1193  return (1);
1194  }
1195  if (!sendport)
1196  if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
1197  perror("ftp: setsockopt (reuse address)");
1198  goto bad;
1199  }
1200  if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
1201  perror("ftp: bind");
1202  goto bad;
1203  }
1204  if (options & SO_DEBUG &&
1205  setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
1206  perror("ftp: setsockopt (ignored)");
1207  len = sizeof (data_addr);
1208  if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
1209  perror("ftp: getsockname");
1210  goto bad;
1211  }
1212  if (listen(data, 1) < 0)
1213  perror("ftp: listen");
1214  if (sendport) {
1215  a = (char *)&data_addr.sin_addr;
1216  p = (char *)&data_addr.sin_port;
1217 #define UC(b) (((int)b)&0xff)
1218  result =
1219  command("PORT %d,%d,%d,%d,%d,%d",
1220  UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
1221  UC(p[0]), UC(p[1]));
1222  if (result == ERROR && sendport == -1) {
1223  sendport = 0;
1224  tmpno = 1;
1225  goto noport;
1226  }
1227  return (result != COMPLETE);
1228  }
1229  if (tmpno)
1230  sendport = 1;
1231  return (0);
1232 bad:
1233  (void) fflush(stdout);
1234  (void) close(data), data = -1;
1235  if (tmpno)
1236  sendport = 1;
1237  return (1);
1238 }
1239 
1240 int dataconn(const char *mode)
1241 {
1242  struct sockaddr_in from;
1243  int s, fromlen = sizeof (from);
1244 
1245  if (passivemode)
1246  return (data);
1247 
1248  s = accept(data, (struct sockaddr *) &from, &fromlen);
1249  if (s < 0) {
1250  perror("ftp: accept");
1251  (void) closesocket(data), data = -1;
1252  return 0;
1253  }
1254  if(closesocket(data)) {
1255  int iret=WSAGetLastError ();
1256  fprintf(stdout,"Error closing socket(%d)\n",iret);
1257  (void) fflush(stdout);
1258  }
1259 
1260  data = s;
1261  return (data);
1262 }
1263 
1264 void ptransfer(direction, bytes, t0, t1)
1265  const char *direction;
1266  long bytes;
1267  struct timeval *t0, *t1;
1268 {
1269  struct timeval td;
1270  double s, bs;
1271 
1272  if (verbose) {
1273  tvsub(&td, t1, t0);
1274  s = td.tv_sec + (td.tv_usec / 1000000.);
1275 #define nz(x) ((x) == 0 ? 1 : (x))
1276  bs = bytes / nz(s);
1277  printf("%ld bytes %s in %.1f seconds (%.0f Kbytes/s)\n",
1278  bytes, direction, s, bs / 1024.);
1279  (void) fflush(stdout);
1280  }
1281 }
1282 
1283 /*tvadd(tsum, t0)
1284  struct timeval *tsum, *t0;
1285 {
1286 
1287  tsum->tv_sec += t0->tv_sec;
1288  tsum->tv_usec += t0->tv_usec;
1289  if (tsum->tv_usec > 1000000)
1290  tsum->tv_sec++, tsum->tv_usec -= 1000000;
1291 } */
1292 
1293 void tvsub(tdiff, t1, t0)
1294  struct timeval *tdiff, *t1, *t0;
1295 {
1296 
1297  tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
1298  tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
1299  if (tdiff->tv_usec < 0)
1300  tdiff->tv_sec--, tdiff->tv_usec += 1000000;
1301 }
1302 
1303 void psabort(int flag)
1304 {
1305  extern int abrtflag;
1306 
1307  abrtflag++;
1308 }
1309 
1310 void pswitch(int flag)
1311 {
1312  extern int proxy, abrtflag;
1313  Sig_t oldintr;
1314  static struct comvars {
1315  int connect;
1316  char name[MAXHOSTNAMELEN];
1317  struct sockaddr_in mctl;
1318  struct sockaddr_in hctl;
1319  SOCKET in;
1320  SOCKET out;
1321  int tpe;
1322  int cpnd;
1323  int sunqe;
1324  int runqe;
1325  int mcse;
1326  int ntflg;
1327  char nti[17];
1328  char nto[17];
1329  int mapflg;
1330  char mi[MAXPATHLEN];
1331  char mo[MAXPATHLEN];
1332  } proxstruct, tmpstruct;
1333  struct comvars *ip, *op;
1334 
1335  abrtflag = 0;
1336  oldintr = signal(SIGINT, psabort);
1337  if (flag) {
1338  if (proxy)
1339  return;
1340  ip = &tmpstruct;
1341  op = &proxstruct;
1342  proxy++;
1343  }
1344  else {
1345  if (!proxy)
1346  return;
1347  ip = &proxstruct;
1348  op = &tmpstruct;
1349  proxy = 0;
1350  }
1351  ip->connect = connected;
1352  connected = op->connect;
1353  if (hostname) {
1354  (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
1355  ip->name[strlen(ip->name)] = '\0';
1356  } else
1357  ip->name[0] = 0;
1358  hostname = op->name;
1359  ip->hctl = hisctladdr;
1360  hisctladdr = op->hctl;
1361  ip->mctl = myctladdr;
1362  myctladdr = op->mctl;
1363  ip->in = cin;
1364  cin = op->in;
1365  ip->out = cout;
1366  cout = op->out;
1367  ip->tpe = type;
1368  type = op->tpe;
1369  if (!type)
1370  type = 1;
1371  ip->cpnd = cpend;
1372  cpend = op->cpnd;
1373  ip->sunqe = sunique;
1374  sunique = op->sunqe;
1375  ip->runqe = runique;
1376  runique = op->runqe;
1377  ip->mcse = mcase;
1378  mcase = op->mcse;
1379  ip->ntflg = ntflag;
1380  ntflag = op->ntflg;
1381  (void) strncpy(ip->nti, ntin, 16);
1382  (ip->nti)[strlen(ip->nti)] = '\0';
1383  (void) strcpy(ntin, op->nti);
1384  (void) strncpy(ip->nto, ntout, 16);
1385  (ip->nto)[strlen(ip->nto)] = '\0';
1386  (void) strcpy(ntout, op->nto);
1387  ip->mapflg = mapflag;
1388  mapflag = op->mapflg;
1389  (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
1390  (ip->mi)[strlen(ip->mi)] = '\0';
1391  (void) strcpy(mapin, op->mi);
1392  (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
1393  (ip->mo)[strlen(ip->mo)] = '\0';
1394  (void) strcpy(mapout, op->mo);
1395 // (void) signal(SIGINT, oldintr);
1396  if (abrtflag) {
1397  abrtflag = 0;
1398  (*oldintr)(1);
1399  }
1400 }
1401 
1404 
1405 #if 0
1406 void
1407 abortpt()
1408 {
1409  printf("\n");
1410  (void) fflush(stdout);
1411  ptabflg++;
1412  mflag = 0;
1413  abrtflag = 0;
1414  longjmp(ptabort, 1);
1415 }
1416 #endif
1417 
1418 void proxtrans(cmd, local, remote)
1419  const char *cmd, *local, *remote;
1420 {
1421 // void (*oldintr)(int);
1422  int tmptype, oldtype = 0, secndflag = 0, nfnd;
1423  extern jmp_buf ptabort;
1424  const char *cmd2;
1425 // struct
1426  fd_set mask;
1427 
1428  if (strcmp(cmd, "RETR"))
1429  cmd2 = "RETR";
1430  else
1431  cmd2 = runique ? "STOU" : "STOR";
1432  if (command("PASV") != COMPLETE) {
1433  printf("proxy server does not support third part transfers.\n");
1434  (void) fflush(stdout);
1435  return;
1436  }
1437  tmptype = type;
1438  pswitch(0);
1439  if (!connected) {
1440  printf("No primary connection\n");
1441  (void) fflush(stdout);
1442  pswitch(1);
1443  code = -1;
1444  return;
1445  }
1446  if (type != tmptype) {
1447  oldtype = type;
1448  switch (tmptype) {
1449  case TYPE_A:
1450  setascii(0, NULL);
1451  break;
1452  case TYPE_I:
1453  setbinary(0, NULL);
1454  break;
1455  case TYPE_E:
1456  setebcdic();
1457  break;
1458  case TYPE_L:
1459  settenex(0, NULL);
1460  break;
1461  }
1462  }
1463  if (command("PORT %s", pasv) != COMPLETE) {
1464  switch (oldtype) {
1465  case 0:
1466  break;
1467  case TYPE_A:
1468  setascii(0, NULL);
1469  break;
1470  case TYPE_I:
1471  setbinary(0, NULL);
1472  break;
1473  case TYPE_E:
1474  setebcdic();
1475  break;
1476  case TYPE_L:
1477  settenex(0, NULL);
1478  break;
1479  }
1480  pswitch(1);
1481  return;
1482  }
1483  if (setjmp(ptabort))
1484  goto abort;
1485 null();// oldintr = signal(SIGINT, abortpt);
1486  if (command("%s %s", cmd, remote) != PRELIM) {
1487 null();// (void) signal(SIGINT, oldintr);
1488  switch (oldtype) {
1489  case 0:
1490  break;
1491  case TYPE_A:
1492  setascii(0, NULL);
1493  break;
1494  case TYPE_I:
1495  setbinary(0, NULL);
1496  break;
1497  case TYPE_E:
1498  setebcdic();
1499  break;
1500  case TYPE_L:
1501  settenex(0, NULL);
1502  break;
1503  }
1504  pswitch(1);
1505  return;
1506  }
1507  sleep(2);
1508  pswitch(1);
1509  secndflag++;
1510  if (command("%s %s", cmd2, local) != PRELIM)
1511  goto abort;
1512  ptflag++;
1513  (void) getreply(0);
1514  pswitch(0);
1515  (void) getreply(0);
1516 null();// (void) signal(SIGINT, oldintr);
1517  switch (oldtype) {
1518  case 0:
1519  break;
1520  case TYPE_A:
1521  setascii(0, NULL);
1522  break;
1523  case TYPE_I:
1524  setbinary(0, NULL);
1525  break;
1526  case TYPE_E:
1527  setebcdic();
1528  break;
1529  case TYPE_L:
1530  settenex(0, NULL);
1531  break;
1532  }
1533  pswitch(1);
1534  ptflag = 0;
1535  printf("local: %s remote: %s\n", local, remote);
1536  (void) fflush(stdout);
1537  return;
1538 abort:
1539 null();// (void) signal(SIGINT, SIG_IGN);
1540  ptflag = 0;
1541  if (strcmp(cmd, "RETR") && !proxy)
1542  pswitch(1);
1543  else if (!strcmp(cmd, "RETR") && proxy)
1544  pswitch(0);
1545  if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
1546  if (command("%s %s", cmd2, local) != PRELIM) {
1547  pswitch(0);
1548  switch (oldtype) {
1549  case 0:
1550  break;
1551  case TYPE_A:
1552  setascii(0, NULL);
1553  break;
1554  case TYPE_I:
1555  setbinary(0, NULL);
1556  break;
1557  case TYPE_E:
1558  setebcdic();
1559  break;
1560  case TYPE_L:
1561  settenex(0, NULL);
1562  break;
1563  }
1564  if (cpend) {
1565  char msg[2];
1566 
1567  fprintfSocket(cout,"%c%c",IAC,IP);
1568  *msg = (char) IAC;
1569  *(msg+1) = (char) DM;
1570  if (send(cout,msg,2,MSG_OOB) != 2)
1571  perror("abort");
1572  fprintfSocket(cout,"ABOR\r\n");
1573  FD_ZERO(&mask);
1574 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this
1575  if ((nfnd = empty(&mask,10)) <= 0) {
1576  if (nfnd < 0) {
1577  perror("abort");
1578  }
1579  if (ptabflg)
1580  code = -1;
1581  lostpeer();
1582  }
1583  (void) getreply(0);
1584  (void) getreply(0);
1585  }
1586  }
1587  pswitch(1);
1588  if (ptabflg)
1589  code = -1;
1590 null();// (void) signal(SIGINT, oldintr);
1591  return;
1592  }
1593  if (cpend) {
1594  char msg[2];
1595 
1596  fprintfSocket(cout,"%c%c",IAC,IP);
1597  *msg = (char)IAC;
1598  *(msg+1) = (char)DM;
1599  if (send(cout,msg,2,MSG_OOB) != 2)
1600  perror("abort");
1601  fprintfSocket(cout,"ABOR\r\n");
1602  FD_ZERO(&mask);
1603 // FD_SET(fileno(cin), &mask); // Chris: Need to correct this...
1604  if ((nfnd = empty(&mask,10)) <= 0) {
1605  if (nfnd < 0) {
1606  perror("abort");
1607  }
1608  if (ptabflg)
1609  code = -1;
1610  lostpeer();
1611  }
1612  (void) getreply(0);
1613  (void) getreply(0);
1614  }
1615  pswitch(!proxy);
1616  if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
1617  if (command("%s %s", cmd2, local) != PRELIM) {
1618  pswitch(0);
1619  switch (oldtype) {
1620  case 0:
1621  break;
1622  case TYPE_A:
1623  setascii(0, NULL);
1624  break;
1625  case TYPE_I:
1626  setbinary(0, NULL);
1627  break;
1628  case TYPE_E:
1629  setebcdic();
1630  break;
1631  case TYPE_L:
1632  settenex(0, NULL);
1633  break;
1634  }
1635  if (cpend) {
1636  char msg[2];
1637 
1638  fprintfSocket(cout,"%c%c",IAC,IP);
1639  *msg = (char)IAC;
1640  *(msg+1) = (char)DM;
1641  if (send(cout,msg,2,MSG_OOB) != 2)
1642  perror("abort");
1643  fprintfSocket(cout,"ABOR\r\n");
1644  FD_ZERO(&mask);
1645 // FD_SET(fileno(cin), &mask); // Chris:
1646  if ((nfnd = empty(&mask,10)) <= 0) {
1647  if (nfnd < 0) {
1648  perror("abort");
1649  }
1650  if (ptabflg)
1651  code = -1;
1652  lostpeer();
1653  }
1654  (void) getreply(0);
1655  (void) getreply(0);
1656  }
1657  pswitch(1);
1658  if (ptabflg)
1659  code = -1;
1660 null();// (void) signal(SIGINT, oldintr);
1661  return;
1662  }
1663  }
1664  if (cpend) {
1665  char msg[2];
1666 
1667  fprintfSocket(cout,"%c%c",IAC,IP);
1668  *msg = (char)IAC;
1669  *(msg+1) = (char)DM;
1670  if (send(cout,msg,2,MSG_OOB) != 2)
1671  perror("abort");
1672  fprintfSocket(cout,"ABOR\r\n");
1673  FD_ZERO(&mask);
1674 // FD_SET(fileno(cin), &mask); // Chris:
1675  if ((nfnd = empty(&mask,10)) <= 0) {
1676  if (nfnd < 0) {
1677  perror("abort");
1678  }
1679  if (ptabflg)
1680  code = -1;
1681  lostpeer();
1682  }
1683  (void) getreply(0);
1684  (void) getreply(0);
1685  }
1686  pswitch(!proxy);
1687  if (cpend) {
1688  FD_ZERO(&mask);
1689 // FD_SET(fileno(cin), &mask); // Chris:
1690  if ((nfnd = empty(&mask,10)) <= 0) {
1691  if (nfnd < 0) {
1692  perror("abort");
1693  }
1694  if (ptabflg)
1695  code = -1;
1696  lostpeer();
1697  }
1698  (void) getreply(0);
1699  (void) getreply(0);
1700  }
1701  if (proxy)
1702  pswitch(0);
1703  switch (oldtype) {
1704  case 0:
1705  break;
1706  case TYPE_A:
1707  setascii(0, NULL);
1708  break;
1709  case TYPE_I:
1710  setbinary(0, NULL);
1711  break;
1712  case TYPE_E:
1713  setebcdic();
1714  break;
1715  case TYPE_L:
1716  settenex(0, NULL);
1717  break;
1718  }
1719  pswitch(1);
1720  if (ptabflg)
1721  code = -1;
1722 null();// (void) signal(SIGINT, oldintr);
1723 }
1724 
1725 void reset(int argc, const char *argv[])
1726 {
1727 // struct
1728  fd_set mask;
1729  int nfnd = 1;
1730 
1731  FD_ZERO(&mask);
1732  while (nfnd > 0) {
1733 // FD_SET(fileno(cin), &mask); // Chris
1734  if ((nfnd = empty(&mask,0)) < 0) {
1735  perror("reset");
1736  code = -1;
1737  lostpeer();
1738  }
1739  else if (nfnd) {
1740  (void) getreply(0);
1741  }
1742  }
1743 }
1744 
1745 #if 0
1746 char *
1747 gunique(local)
1748  char *local;
1749 {
1750  static char new[MAXPATHLEN];
1751  char *cp = rindex(local, '/');
1752  int d, count=0;
1753  char ext = '1';
1754 
1755  if (cp)
1756  *cp = '\0';
1757  d = access(cp ? local : ".", 2);
1758  if (cp)
1759  *cp = '/';
1760  if (d < 0) {
1761  perror(local);
1762  return((char *) 0);
1763  }
1764  (void) strcpy(new, local);
1765  cp = new + strlen(new);
1766  *cp++ = '.';
1767  while (!d) {
1768  if (++count == 100) {
1769  printf("runique: can't find unique file name.\n");
1770  (void) fflush(stdout);
1771  return((char *) 0);
1772  }
1773  *cp++ = ext;
1774  *cp = '\0';
1775  if (ext == '9')
1776  ext = '0';
1777  else
1778  ext++;
1779  if ((d = access(new, 0)) < 0)
1780  break;
1781  if (ext != '0')
1782  cp--;
1783  else if (*(cp - 2) == '.')
1784  *(cp - 1) = '1';
1785  else {
1786  *(cp - 2) = *(cp - 2) + 1;
1787  cp--;
1788  }
1789  }
1790  return(new);
1791 }
1792 #endif
1793 
1794 int null(void)
1795 {
1796  return 0;
1797 }
Definition: winsock.h:66
#define EPIPE
Definition: acclib.h:91
static int argc
Definition: ServiceArgs.c:12
int sunique
Definition: main.c:70
void setbinary(int argc, const char *argv[])
Definition: cmds.c:202
int getreply(int expecteof)
Definition: ftp.c:314
_Check_return_ _CRTIMP int __cdecl ferror(_In_ FILE *_File)
char ** h_addr_list
Definition: winsock.h:138
struct sockaddr_in hisctladdr
Definition: ftp.c:68
int proxy
Definition: main.c:67
static const struct update_accum a3
Definition: msg.c:600
#define sleep
Definition: syshdrs.h:37
int abrtflag
Definition: ftp.c:71
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:47
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
int ntflag
Definition: main.c:73
#define inet_addr(cp)
Definition: inet.h:98
sig_t lostpeer()
Definition: main.c:254
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
Definition: netstat.c:29
void recvrequest(const char *cmd, const char *local, const char *remote, const char *mode, int printnames)
Definition: ftp.c:717
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
Definition: ftp_var.h:139
#define pt(x, y)
Definition: drawing.c:79
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
#define DONT
Definition: ftp_var.h:14
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
char * h_name
Definition: winsock.h:134
int crflag
Definition: main.c:76
GLuint GLuint GLsizei count
Definition: gl.h:1545
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define TYPE_E
Definition: ftp_var.h:38
__kernel_off_t off_t
Definition: linux.h:201
void setascii(int argc, const char *argv[])
Definition: cmds.c:212
#define SO_OOBINLINE
Definition: winsock.h:186
unsigned long tv_sec
Definition: linux.h:1738
char * host
Definition: whois.c:55
_Check_return_opt_ _CRTIMP int __cdecl _pclose(_Inout_ FILE *_File)
#define TYPE_L
Definition: ftp_var.h:39
_Check_return_ _CRTIMP FILE *__cdecl _popen(_In_z_ const char *_Command, _In_z_ const char *_Mode)
#define WILL
Definition: ftp_var.h:17
_Check_return_ _CRTIMP int __cdecl getc(_Inout_ FILE *_File)
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
void tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0)
Definition: ftp.c:1293
GLuint buffer
Definition: glext.h:5915
static void cmdabort(int sig)
Definition: ftp.c:254
char * cmd
Definition: vfdcmd.c:85
FILE * stdin
#define BUFSIZ
Definition: nsplookup.c:26
_Check_return_opt_ _CRTIMP long __cdecl lseek(_In_ int _FileHandle, _In_ long _Offset, _In_ int _Origin)
#define COMPLETE
Definition: main.h:128
static MONITORINFO mi
Definition: win.c:7331
void(* Sig_t)(int)
Definition: ftp.c:90
#define S_IFREG
Definition: ext2fs.h:356
#define SIGINT
Definition: signal.h:23
int login(const char *host)
Definition: ftp.c:189
int ruserpass(const char *host, char **aname, char **apass, char **aacct)
Definition: ruserpass.c:58
int errno
#define ERROR(err)
Definition: vbo_exec_api.c:413
int mflag
Definition: finger.c:66
#define SOL_SOCKET
Definition: winsock.h:398
#define FD_ZERO(set)
Definition: winsock.h:96
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
#define FD_SET(fd, set)
Definition: winsock.h:89
long uid_t
Definition: various.h:8
char * caddr_t
Definition: rosdhcp.h:36
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
GLuint const GLubyte mask[]
Definition: s_context.h:57
static char ** argv
Definition: ServiceArgs.c:11
#define L_INCR
Definition: ftp.c:23
FILE * stdout
void setebcdic()
Definition: cmds.c:232
#define HASHBYTES
Definition: ftp.c:441
#define DO
Definition: ftp_var.h:15
#define verbose
Definition: rosglue.h:36
GLuint n
Definition: s_context.h:57
#define write
Definition: acwin.h:73
pass
Definition: typegen.h:24
#define gettimeofday(tv, tz)
Definition: adns_win32.h:159
struct sockaddr_in data_addr
Definition: ftp.c:69
char * getpass(const char *prompt)
Definition: fake.c:231
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define S_IFMT
Definition: ext2fs.h:353
GLenum GLint GLuint mask
Definition: glext.h:6028
#define rindex(s, c)
Definition: various.h:30
static unsigned char bytes[4]
Definition: adnsresfilter.c:74
#define va_end(ap)
Definition: acmsvcex.h:90
#define closesocket
Definition: main.c:39
UINT op
Definition: effect.c:223
jmp_buf sendabort
Definition: ftp.c:427
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
#define MSG_OOB
Definition: winsock.h:221
#define PRELIM
Definition: ftp_var.h:41
#define FD_ISSET(fd, set)
Definition: winsock.h:100
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define a
Definition: ke_i.h:78
int allbinary
Definition: ftp.c:73
jmp_buf ptabort
Definition: ftp.c:1402
void proxtrans(char *cmd, char *local, char *remote) const
Definition: ftp.c:1418
int fputSocket(int s, char *buffer, int len)
Definition: fake.c:151
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
static char sccsid[]
Definition: ftp.c:27
int putchar(int c)
Definition: crtsupp.c:12
short h_length
Definition: winsock.h:137
char reply_string[BUFSIZ]
Definition: ftp.c:309
UINT msg
Definition: msvc.h:92
smooth NULL
Definition: ftsmooth.c:416
unsigned long tv_usec
Definition: linux.h:1739
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
char ext[3]
Definition: mkdosfs.c:358
const GLfloat * p0
Definition: s_aatritemp.h:42
unsigned char
Definition: typeof.h:27
#define SO_REUSEADDR
Definition: winsock.h:180
Definition: parser.c:48
int mcase
Definition: main.c:72
char * va_list
Definition: acmsvcex.h:78
void reset(int argc, const char *argv[])
Definition: ftp.c:1725
#define gid_t
Definition: types.h:67
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
unsigned int dir
Definition: maze.c:112
int longjmp(jmp_buf buf, int retval)
char pasv[64]
Definition: main.c:77
#define isdigit(c)
Definition: acclib.h:68
void makeargv(void)
Definition: main.c:384
#define inet_ntoa(addr)
Definition: inet.h:100
#define uid_t
Definition: types.h:66
char * hookup(const char *host, int port)
Definition: ftp.c:96
int proxflag
Definition: main.c:69
_Check_return_opt_ _CRTIMP int __cdecl putc(_In_ int _Ch, _Inout_ FILE *_File)
PHOSTENT WSAAPI gethostbyname(IN const char FAR *name)
Definition: getxbyxx.c:221
int ptabflg
Definition: ftp.c:1403
void ptransfer(char *direction, long bytes, struct timeval *t0, struct timeval *t1) const
Definition: ftp.c:1264
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint 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 GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean flag
Definition: glfuncs.h:72
#define INVALID_SOCKET
Definition: winsock.h:332
#define d
Definition: ke_i.h:81
SOCKET cin
Definition: ftp.c:83
_Check_return_ _CRTIMP int __cdecl fileno(_In_ FILE *_File)
#define bcopy(s1, s2, n)
Definition: various.h:25
int fgetcSocket(int s)
Definition: fake.c:89
static const struct update_accum a2
Definition: msg.c:586
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
unsigned long
Definition: typeof.h:99
_Check_return_ _CRTIMP int __cdecl chmod(_In_z_ const char *_Filename, _In_ int _AccessMode)
static FILE * out
Definition: regtests2xml.c:44
int runique
Definition: main.c:71
int null(void)
Definition: ftp.c:1794
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
const char * margv[20]
Definition: main.c:102
int margc
Definition: main.c:101
void psabort(int sig)
Definition: ftp.c:1303
int herror(char *string)
Definition: fake.c:46
Definition: arc.h:34
int signal
Definition: xcptfil.c:12
static const WCHAR L[]
Definition: oid.c:1087
unsigned short st_mode
Definition: stat.h:58
Definition: stat.h:55
GLenum GLsizei len
Definition: glext.h:6722
GLdouble s
Definition: gl.h:2039
#define nz(x)
#define MAXPATHLEN
Definition: ftp_var.h:35
_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)
int sendport
Definition: main.c:117
#define close
Definition: acwin.h:74
int passivemode
Definition: main.c:68
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
GLenum mode
Definition: glext.h:6217
int code
Definition: i386-dis.c:3591
SOCKET cout
Definition: ftp.c:83
GLfloat CONST GLvector4f * in
Definition: m_xform.h:122
short h_addrtype
Definition: winsock.h:136
#define CONTINUE
Definition: ftp_var.h:43
#define local
Definition: zutil.h:30
char * hostname
Definition: ftp.c:88
int connected
Definition: main.c:61
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
char ntin[17]
Definition: main.c:79
#define MAXHOSTNAMELEN
Definition: ftp.c:31
#define TYPE_I
Definition: ftp_var.h:37
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
struct macel macros[16]
Definition: main.c:109
int __cdecl vsprintf(char *_Dest, const char *_Format, va_list _Args)
Definition: sprintf.c:733
void domacro(int argc, const char *argv[])
Definition: domacro.c:26
#define abort()
Definition: i386-dis.c:35
int ptflag
Definition: ftp.c:72
#define va_start(ap, A)
Definition: acmsvcex.h:91
Definition: arc.h:46
uid_t getuid()
Definition: uid.c:27
int cpend
Definition: main.c:103
#define setjmp
Definition: setjmp.h:183
jmp_buf recvabort
Definition: ftp.c:703
#define IAC
Definition: ftp_var.h:13
void settenex(int argc, const char *argv[])
Definition: cmds.c:222
int mapflag
Definition: main.c:74
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
void sendrequest(const char *cmd, const char *local, const char *remote, int printnames)
Definition: ftp.c:443
void pswitch(int flag)
Definition: ftp.c:1310
int command(const char *fmt,...)
Definition: ftp.c:266
#define msg(x)
Definition: auth_time.c:54
#define EOF
Definition: stdio.h:24
int macnum
Definition: main.c:108
#define UC(b)
POINT cp
Definition: magnifier.c:60
Definition: name.c:36
void int int ULONGLONG int va_list * ap
Definition: winesup.h:32
#define bzero(s, n)
Definition: various.h:27
_CRTIMP int __cdecl fstat(int _Desc, struct stat *_Stat)
Definition: stat.h:341
#define DM
Definition: ftp_var.h:26
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define c
Definition: ke_i.h:80
FILE * stderr
#define AF_INET
Definition: tcpip.h:117
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char mapin[MAXPATHLEN]
Definition: main.c:82
#define debug(msg)
Definition: key_call.c:71
#define WONT
Definition: ftp_var.h:16
UINT_PTR SOCKET
Definition: winsock.h:47
static const struct update_accum a1
Definition: msg.c:578
long jmp_buf[100]
Definition: of.h:11
struct sockaddr_in myctladdr
Definition: ftp.c:74
#define SOCK_STREAM
Definition: tcpip.h:118
Definition: fake.h:14
const char * fprintfSocket(int s, const char *format,...)
Definition: fake.c:114
GLfloat GLfloat p
Definition: glext.h:8902
const GLfloat * p1
Definition: s_aatritemp.h:43
CardRegion * from
Definition: spigame.cpp:19
#define L_SET
Definition: ftp.c:22
#define SIG_IGN
Definition: signal.h:48
int sig_t
Definition: ftp_var.h:161
_Check_return_opt_ _CRTIMP int __cdecl vfprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format, va_list _ArgList)
static struct msdos_boot_sector bs
Definition: mkdosfs.c:539
off_t restart_point
Definition: ftp.c:81
Definition: _hash_fun.h:40
char mapout[MAXPATHLEN]
Definition: main.c:83
USHORT port
Definition: uri.c:227
GLuint64EXT * result
Definition: glext.h:11304
#define TYPE_A
Definition: ftp_var.h:36
int dataconn(const char *mode)
Definition: ftp.c:1240
void user(int argc, const char *argv[])
Definition: cmds.c:1350
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
Definition: dsound.c:943
INT WSAAPI getsockname(IN SOCKET s, OUT LPSOCKADDR name, IN OUT INT FAR *namelen)
Definition: sockctrl.c:213
static int empty(struct fd_set *mask, int sec)
Definition: ftp.c:416
_CRTIMP int __cdecl read(_In_ int _FileHandle, _Out_writes_bytes_(_MaxCharCount) void *_DstBuf, _In_ unsigned int _MaxCharCount)
#define printf
Definition: config.h:203
#define SO_DEBUG
Definition: winsock.h:178
char ntout[17]
Definition: main.c:80
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:29
int initconn()
Definition: ftp.c:1125