2 * Copyright (c) 1985, 1989 Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * Copyright (C) 1998 by the FundsXpress, INC.
37 * All rights reserved.
39 * Export of this software from the United States of America may require
40 * a specific license from the United States Government. It is the
41 * responsibility of any person or organization contemplating export to
42 * obtain such a license before exporting.
44 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
45 * distribute this software and its documentation for any purpose and
46 * without fee is hereby granted, provided that the above copyright
47 * notice appear in all copies and that both that copyright notice and
48 * this permission notice appear in supporting documentation, and that
49 * the name of FundsXpress. not be used in advertising or publicity pertaining
50 * to distribution of the software without specific, written prior
51 * permission. FundsXpress makes no representations about the suitability of
52 * this software for any purpose. It is provided "as is" without express
53 * or implied warranty.
55 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
56 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
57 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
61 static char sccsid[] = "@(#)ftp.c 5.38 (Berkeley) 4/22/91";
67 #include <sys/param.h>
69 #include <sys/ioctl.h>
70 #ifndef KRB5_KRB4_COMPAT
71 /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
72 #include <sys/socket.h>
76 #ifdef HAVE_SYS_SELECT_H
77 #include <sys/select.h>
80 #include <netinet/in.h>
81 #include <netinet/in_systm.h>
82 #include <netinet/ip.h>
84 #include <arpa/telnet.h>
90 #ifndef KRB5_KRB4_COMPAT
91 /* krb.h gets this, and Ultrix doesn't protect vs multiple inclusion */
97 #if (defined(__STDC__) && ! defined(VARARGS)) || defined(HAVE_STDARG_H)
114 #ifdef KRB5_KRB4_COMPAT
119 Key_schedule schedule;
121 #endif /* KRB5_KRB4_COMPAT */
123 #include <gssapi/gssapi.h>
124 /* need to include the krb5 file, because we're doing manual fallback
125 from the v2 mech to the v2 mech. Once there's real negotiation,
126 we can be generic again. */
127 #include <gssapi/gssapi_generic.h>
128 #include <gssapi/gssapi_krb5.h>
129 gss_ctx_id_t gcontext;
132 static int kerror; /* XXX needed for all auth types */
134 char *auth_type; /* Authentication succeeded? If so, what type? */
136 unsigned int maxbuf, actualbuf;
137 unsigned char *ucbuf;
142 #define sig_t my_sig_t
143 #define sigtype krb5_sigtype
144 typedef sigtype (*sig_t)();
146 struct sockaddr_in hisctladdr;
147 struct sockaddr_in hisdataaddr;
148 struct sockaddr_in data_addr;
152 struct sockaddr_in myctladdr;
155 off_t restart_point = 0;
157 #define strerror(error) (sys_errlist[error])
158 #ifdef NEED_SYS_ERRLIST
159 extern char *sys_errlist[];
162 extern int connected;
164 #define herror() printf("unknown host\n")
174 register struct hostent *hp = 0;
176 static char hostnamebuf[80];
178 memset((char *)&hisctladdr, 0, sizeof (hisctladdr));
179 hisctladdr.sin_addr.s_addr = inet_addr(host);
180 if (hisctladdr.sin_addr.s_addr != -1) {
181 hisctladdr.sin_family = AF_INET;
182 (void) strncpy(hostnamebuf, host, sizeof(hostnamebuf));
184 hp = gethostbyname(host);
186 fprintf(stderr, "ftp: %s: ", host);
191 hisctladdr.sin_family = hp->h_addrtype;
192 memcpy((caddr_t)&hisctladdr.sin_addr, hp->h_addr_list[0],
193 sizeof(hisctladdr.sin_addr));
194 (void) strncpy(hostnamebuf, hp->h_name, sizeof(hostnamebuf));
196 hostname = hostnamebuf;
197 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
199 perror("ftp: socket");
203 hisctladdr.sin_port = port;
204 while (connect(s, (struct sockaddr *)&hisctladdr, sizeof (hisctladdr)) < 0) {
205 if (hp && hp->h_addr_list[1]) {
207 extern char *inet_ntoa();
209 fprintf(stderr, "ftp: connect to address %s: ",
210 inet_ntoa(hisctladdr.sin_addr));
214 memcpy((caddr_t)&hisctladdr.sin_addr,
216 sizeof(hisctladdr.sin_addr));
217 fprintf(stdout, "Trying %s...\n",
218 inet_ntoa(hisctladdr.sin_addr));
220 s = socket(hisctladdr.sin_family, SOCK_STREAM, 0);
222 perror("ftp: socket");
228 perror("ftp: connect");
232 len = sizeof (myctladdr);
233 if (getsockname(s, (struct sockaddr *)&myctladdr, &len) < 0) {
234 perror("ftp: getsockname");
239 #ifdef IPTOS_LOWDELAY
240 tos = IPTOS_LOWDELAY;
241 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
242 perror("ftp: setsockopt TOS (ignored)");
245 cin = fdopen(s, "r");
246 cout = fdopen(s, "w");
247 if (cin == NULL || cout == NULL) {
248 fprintf(stderr, "ftp: fdopen failed.\n");
257 printf("Connected to %s.\n", hostname);
258 if (getreply(0) > 2) { /* read startup message from server */
270 if (setsockopt(s, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(on))
272 perror("ftp: setsockopt");
275 #endif /* SO_OOBINLINE */
287 char *user, *pass, *acct, *getenv(), *getlogin(), *mygetpass();
290 user = pass = acct = 0;
291 if (ruserpass(host, &user, &pass, &acct) < 0) {
295 while (user == NULL) {
298 myname = getenv("LOGNAME");
300 myname = getenv("USER");
303 if (myname == NULL) {
304 struct passwd *pp = getpwuid(getuid());
307 myname = pp->pw_name;
310 printf("Name (%s:%s): ", host, myname);
312 printf("Name (%s): ", host);
313 (void) fgets(tmp, sizeof(tmp) - 1, stdin);
314 tmp[strlen(tmp) - 1] = '\0';
320 n = command("USER %s", user);
322 /* determine if we need to send a dummy password */
323 int oldverbose = verbose;
326 if (command("PWD") != COMPLETE) {
327 verbose = oldverbose;
328 command("PASS dummy");
330 verbose = oldverbose;
333 else if (n == CONTINUE) {
338 pass = mygetpass("Password:");
343 n = command("PASS %s", pass);
345 /* level may have changed */
346 if (clevel == PROT_P) clevel = oldclevel;
351 acct = mygetpass("Account:");
352 n = command("ACCT %s", acct);
355 fprintf(stderr, "Login failed.\n");
358 if (!aflag && acct != NULL)
359 (void) command("ACCT %s", acct);
362 for (n = 0; n < macnum; ++n) {
363 if (!strcmp("init", macros[n].mac_name)) {
364 (void) strcpy(line, "$init");
366 domacro(margc, margv);
377 extern jmp_buf ptabort;
380 (void) fflush(stdout);
389 char in[FTP_BUFSIZ], out[FTP_BUFSIZ];
392 if (auth_type && clevel != PROT_C) {
393 #ifdef KRB5_KRB4_COMPAT
394 if (strcmp(auth_type, "KERBEROS_V4") == 0)
395 if ((length = clevel == PROT_P ?
396 krb_mk_priv((unsigned char *)cmd, (unsigned char *)out,
397 strlen(cmd), schedule,
398 &cred.session, &myctladdr, &hisctladdr)
399 : krb_mk_safe((unsigned char *)cmd, (unsigned char *)out,
400 strlen(cmd), &cred.session,
401 &myctladdr, &hisctladdr)) == -1) {
402 fprintf(stderr, "krb_mk_%s failed for KERBEROS_V4\n",
403 clevel == PROT_P ? "priv" : "safe");
406 #endif /* KRB5_KRB4_COMPAT */
408 /* secure_command (based on level) */
409 if (strcmp(auth_type, "GSSAPI") == 0) {
410 gss_buffer_desc in_buf, out_buf;
411 OM_uint32 maj_stat, min_stat;
413 /* clevel = PROT_P; */
415 in_buf.length = strlen(cmd) + 1;
416 maj_stat = gss_seal(&min_stat, gcontext,
417 (clevel==PROT_P), /* private */
419 &in_buf, &conf_state,
421 if (maj_stat != GSS_S_COMPLETE) {
422 /* generally need to deal */
423 user_gss_error(maj_stat, min_stat,
425 "gss_seal ENC didn't complete":
426 "gss_seal MIC didn't complete");
427 } else if ((clevel == PROT_P) && !conf_state) {
429 "GSSAPI didn't encrypt message");
432 fprintf(stderr, "sealed (%s) %d bytes\n",
433 clevel==PROT_P?"ENC":"MIC",
435 memcpy(out, out_buf.value,
436 length=out_buf.length);
437 gss_release_buffer(&min_stat, &out_buf);
441 /* Other auth types go here ... */
442 if (kerror = radix_encode(out, in, &length, 0)) {
443 fprintf(stderr,"Couldn't base 64 encode command (%s)\n",
444 radix_error(kerror));
447 fprintf(cout, "%s %s", clevel == PROT_P ? "ENC" : "MIC", in);
449 fprintf(stderr, "secure_command(%s)\nencoding %d bytes %s %s\n",
450 cmd, length, clevel==PROT_P ? "ENC" : "MIC", in);
451 } else fputs(cmd, cout);
452 fprintf(cout, "\r\n");
458 command(char *fmt, ...)
476 if (proxflag) printf("%s ", hostname);
482 fmt = va_arg(ap, char *);
484 if (strncmp("PASS ", fmt, 5) == 0)
487 vfprintf(stdout, fmt, ap);
490 (void) fflush(stdout);
493 perror ("No control connection for command");
497 oldintr = signal(SIGINT, cmdabort);
502 fmt = va_arg(ap, char *);
504 vsprintf(in, fmt, ap);
506 again: if (secure_command(in) == 0)
509 r = getreply(!strcmp(fmt, "QUIT"));
511 if (r == 533 && clevel == PROT_P) {
513 "ENC command not supported at server; retrying under MIC...\n");
518 if (abrtflag && oldintr != SIG_IGN)
520 (void) signal(SIGINT, oldintr);
524 char reply_string[FTP_BUFSIZ]; /* last line of previous reply */
526 /* for parsing replies to the ADAT command */
527 char *reply_parse, reply_buf[FTP_BUFSIZ], *reply_ptr;
534 register int i, c, n;
537 int originalcode = 0, continuation = 0;
542 char ibuf[FTP_BUFSIZ], obuf[FTP_BUFSIZ];
544 extern char *strpbrk(), *strstr();
547 if (reply_parse) reply_ptr = reply_buf;
548 oldintr = signal(SIGINT, cmdabort);
551 dig = n = code = i = 0;
553 while ((c = ibuf[0] ? ibuf[i++] : getc(cin)) != '\n') {
554 if (c == IAC) { /* handle telnet commands */
555 switch (c = getc(cin)) {
559 fprintf(cout, "%c%c%c", IAC, DONT, c);
565 fprintf(cout, "%c%c%c", IAC, WONT, c);
576 (void) signal(SIGINT,oldintr);
582 printf("421 Service not available, remote server has closed connection\n");
583 (void) fflush(stdout);
590 if (auth_type && !ibuf[0] &&
591 (n == '6' || continuation)) {
592 if (c != '\r' && dig > 4)
595 if (auth_type && !ibuf[0] && dig == 1 && verbose)
596 printf("Unauthenticated reply received from server:\n");
597 if (reply_parse) *reply_ptr++ = c;
598 if (c != '\r' && (verbose > 0 ||
599 (verbose > -1 && n == '5' && dig > 4))) {
601 (dig == 1 || dig == 5 && verbose == 0))
602 printf("%s:",hostname);
606 if (auth_type && !ibuf[0] && n != '6') continue;
607 if (dig < 4 && isdigit(c))
608 code = code * 10 + (c - '0');
609 if (!pflag && code == 227)
611 if (dig > 4 && pflag == 1 && isdigit(c))
614 if (c != '\r' && c != ')')
621 if (dig == 4 && c == '-' && n != '6') {
626 if (cp < &reply_string[sizeof(reply_string) - 1])
629 if (auth_type && !ibuf[0] && n != '6')
630 return(getreply(expecteof));
631 ibuf[0] = obuf[i] = '\0';
632 if (code && n == '6')
633 if (code != 631 && code != 632 && code != 633) {
634 printf("Unknown reply: %d %s\n", code, obuf);
636 } else safe = (code == 631);
637 if (obuf[0]) /* if there is a string to decode */
639 printf("Cannot decode reply:\n%d %s\n", code, obuf);
643 else if (code == 632) {
644 printf("Cannot decrypt %d reply: %s\n", code, obuf);
648 #ifdef NOCONFIDENTIAL
649 else if (code == 633) {
650 printf("Cannot decrypt %d reply: %s\n", code, obuf);
656 if (kerror = radix_encode(obuf, ibuf, &len, 1)) {
657 printf("Can't base 64 decode reply %d (%s)\n\"%s\"\n",
658 code, radix_error(kerror), obuf);
661 #ifdef KRB5_KRB4_COMPAT
662 else if (strcmp(auth_type, "KERBEROS_V4") == 0)
664 krb_rd_safe((unsigned char *)ibuf, len,
666 &hisctladdr, &myctladdr, &msg_data)
667 : krb_rd_priv((unsigned char *)ibuf, len,
668 schedule, &cred.session,
669 &hisctladdr, &myctladdr, &msg_data))
671 printf("%d reply %s! (krb_rd_%s: %s)\n", code,
672 safe ? "modified" : "garbled",
673 safe ? "safe" : "priv",
674 krb_get_err_text(kerror));
677 if (debug) printf("%c:", safe ? 'S' : 'P');
678 memcpy(ibuf, msg_data.app_data,
679 msg_data.app_length);
680 strcpy(&ibuf[msg_data.app_length], "\r\n");
685 else if (strcmp(auth_type, "GSSAPI") == 0) {
686 gss_buffer_desc xmit_buf, msg_buf;
687 OM_uint32 maj_stat, min_stat;
689 xmit_buf.value = ibuf;
690 xmit_buf.length = len;
691 /* decrypt/verify the message */
693 maj_stat = gss_unseal(&min_stat, gcontext,
696 if (maj_stat != GSS_S_COMPLETE) {
697 user_gss_error(maj_stat, min_stat,
698 "failed unsealing reply");
701 memcpy(ibuf, msg_buf.value,
703 strcpy(&ibuf[msg_buf.length], "\r\n");
704 gss_release_buffer(&min_stat,&msg_buf);
709 /* Other auth types go here... */
712 if (verbose > 0 || verbose > -1 && n == '5') {
714 (void) fflush (stdout);
716 if (continuation && code != originalcode) {
717 if (originalcode == 0)
724 (void) signal(SIGINT,oldintr);
725 if (code == 421 || originalcode == 421)
727 if (abrtflag && oldintr != cmdabort && oldintr != SIG_IGN)
731 if (reply_ptr = strstr(reply_buf, reply_parse)) {
732 reply_parse = reply_ptr + strlen(reply_parse);
733 if (reply_ptr = strpbrk(reply_parse, " \r"))
735 } else reply_parse = reply_ptr;
747 t.tv_sec = (long) sec;
749 return(select(32, mask, (fd_set *) 0, (fd_set *) 0, &t));
761 printf("\nsend aborted\nwaiting for remote to finish abort\n");
762 (void) fflush(stdout);
763 longjmp(sendabort, 1);
767 secure_error(char *fmt, ...)
770 secure_error(fmt, p1, p2, p3, p4, p5)
778 vfprintf(stderr, fmt, ap);
781 fprintf(stderr, fmt, p1, p2, p3, p4, p5);
786 #define HASHBYTES 1024
788 sendrequest(cmd, local, remote, printnames)
789 char *cmd, *local, *remote;
793 struct timeval start, stop;
795 FILE *fin, *dout = 0, *popen();
796 int (*closefunc)(), pclose(), fclose();
797 sig_t oldintr, oldintp;
798 long bytes = 0, hashbytes = HASHBYTES;
799 char *lmode, buf[FTP_BUFSIZ], *bufp;
802 if (verbose && printnames) {
803 if (local && *local != '-')
804 printf("local: %s ", local);
806 printf("remote: %s\n", remote);
809 proxtrans(cmd, local, remote);
818 if (setjmp(sendabort)) {
827 (void) signal(SIGINT,oldintr);
829 (void) signal(SIGPIPE,oldintp);
833 oldintr = signal(SIGINT, abortsend);
834 if (strcmp(local, "-") == 0)
836 else if (*local == '|') {
837 oldintp = signal(SIGPIPE,SIG_IGN);
838 fin = popen(local + 1, "r");
841 (void) signal(SIGINT, oldintr);
842 (void) signal(SIGPIPE, oldintp);
848 fin = fopen(local, "r");
850 fprintf(stderr, "local: %s: %s\n", local,
852 (void) signal(SIGINT, oldintr);
857 if (fstat(fileno(fin), &st) < 0 ||
858 (st.st_mode&S_IFMT) != S_IFREG) {
859 fprintf(stdout, "%s: not a plain file.\n", local);
860 (void) signal(SIGINT, oldintr);
867 (void) signal(SIGINT, oldintr);
869 (void) signal(SIGPIPE, oldintp);
871 if (closefunc != NULL)
875 if (setjmp(sendabort))
879 (strcmp(cmd, "STOR") == 0 || strcmp(cmd, "APPE") == 0)) {
880 if (fseek(fin, (long) restart_point, 0) < 0) {
881 fprintf(stderr, "local: %s: %s\n", local,
884 if (closefunc != NULL)
888 if (command("REST %ld", (long) restart_point)
891 if (closefunc != NULL)
899 if (command("%s %s", cmd, remote) != PRELIM) {
900 (void) signal(SIGINT, oldintr);
902 (void) signal(SIGPIPE, oldintp);
903 if (closefunc != NULL)
908 if (command("%s", cmd) != PRELIM) {
909 (void) signal(SIGINT, oldintr);
911 (void) signal(SIGPIPE, oldintp);
912 if (closefunc != NULL)
916 dout = dataconn(lmode);
919 (void) gettimeofday(&start, (struct timezone *)0);
920 oldintp = signal(SIGPIPE, SIG_IGN);
926 while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
928 for (bufp = buf; c > 0; c -= d, bufp += d)
929 if ((d = secure_write(fileno(dout), bufp, c)) <= 0)
932 while (bytes >= hashbytes) {
934 hashbytes += HASHBYTES;
936 (void) fflush(stdout);
941 if (hash && bytes > 0) {
942 if (bytes < HASHBYTES)
944 (void) putchar('\n');
945 (void) fflush(stdout);
948 fprintf(stderr, "local: %s: %s\n", local,
950 if (d < 0 || (d = secure_flush(fileno(dout))) < 0) {
951 if (d == -1 && errno != EPIPE)
958 while ((c = getc(fin)) != EOF) {
960 while (hash && (bytes >= hashbytes)) {
962 (void) fflush(stdout);
963 hashbytes += HASHBYTES;
966 secure_putc('\r', dout) < 0)
970 if (secure_putc(c, dout) < 0)
973 /* if (c == '\r') { */
974 /* (void) putc('\0', dout); /* this violates rfc */
979 if (bytes < hashbytes)
981 (void) putchar('\n');
982 (void) fflush(stdout);
985 fprintf(stderr, "local: %s: %s\n", local,
988 if (ferror(dout) || (d = secure_flush(fileno(dout))) < 0) {
989 if ((ferror(dout) || d == -1) && errno != EPIPE)
995 (void) gettimeofday(&stop, (struct timezone *)0);
996 if (closefunc != NULL)
1000 (void) signal(SIGINT, oldintr);
1002 (void) signal(SIGPIPE, oldintp);
1004 ptransfer("sent", bytes, &start, &stop);
1007 (void) gettimeofday(&stop, (struct timezone *)0);
1008 (void) signal(SIGINT, oldintr);
1010 (void) signal(SIGPIPE, oldintp);
1020 (void) fclose(dout);
1023 if (closefunc != NULL && fin != NULL)
1026 ptransfer("sent", bytes, &start, &stop);
1038 printf("\nreceive aborted\nwaiting for remote to finish abort\n");
1039 (void) fflush(stdout);
1040 longjmp(recvabort, 1);
1043 recvrequest(cmd, local, remote, lmode, printnames)
1044 char *cmd, *local, *remote, *lmode;
1046 FILE *fout, *din = 0, *popen();
1047 int (*closefunc)(), pclose(), fclose();
1048 sig_t oldintr, oldintp;
1049 int is_retr, tcrflag, bare_lfs = 0;
1054 long bytes = 0, hashbytes = HASHBYTES;
1056 struct timeval start, stop;
1059 sigtype abortrecv();
1061 is_retr = strcmp(cmd, "RETR") == 0;
1062 if (is_retr && verbose && printnames) {
1063 if (local && *local != '-')
1064 printf("local: %s ", local);
1066 printf("remote: %s\n", remote);
1068 if (proxy && is_retr) {
1069 proxtrans(cmd, local, remote);
1075 tcrflag = !crflag && is_retr;
1076 if (setjmp(recvabort)) {
1085 (void) signal(SIGINT, oldintr);
1089 oldintr = signal(SIGINT, abortrecv);
1090 if (strcmp(local, "-") && *local != '|') {
1091 if (access(local, 2) < 0) {
1092 char *dir = strrchr(local, '/');
1094 if (errno != ENOENT && errno != EACCES) {
1095 fprintf(stderr, "local: %s: %s\n", local,
1097 (void) signal(SIGINT, oldintr);
1103 d = access(dir ? local : ".", 2);
1107 fprintf(stderr, "local: %s: %s\n", local,
1109 (void) signal(SIGINT, oldintr);
1113 if (!runique && errno == EACCES &&
1114 chmod(local, 0600) < 0) {
1115 fprintf(stderr, "local: %s: %s\n", local,
1117 (void) signal(SIGINT, oldintr);
1118 (void) signal(SIGINT, oldintr);
1122 if (runique && errno == EACCES &&
1123 (local = gunique(local)) == NULL) {
1124 (void) signal(SIGINT, oldintr);
1129 else if (runique && (local = gunique(local)) == NULL) {
1130 (void) signal(SIGINT, oldintr);
1136 if (curtype != TYPE_A)
1137 changetype(TYPE_A, 0);
1138 } else if (curtype != type)
1139 changetype(type, 0);
1141 (void) signal(SIGINT, oldintr);
1145 if (setjmp(recvabort))
1147 if (is_retr && restart_point &&
1148 command("REST %ld", (long) restart_point) != CONTINUE)
1151 if (command("%s %s", cmd, remote) != PRELIM) {
1152 (void) signal(SIGINT, oldintr);
1156 if (command("%s", cmd) != PRELIM) {
1157 (void) signal(SIGINT, oldintr);
1161 din = dataconn("r");
1164 if (strcmp(local, "-") == 0)
1166 else if (*local == '|') {
1167 oldintp = signal(SIGPIPE, SIG_IGN);
1168 fout = popen(local + 1, "w");
1175 fout = fopen(local, lmode);
1177 fprintf(stderr, "local: %s: %s\n", local,
1183 blksize = FTP_BUFSIZ;
1185 if (fstat(fileno(fout), &st) == 0 && st.st_blksize != 0)
1186 blksize = st.st_blksize;
1188 if (blksize > bufsize) {
1191 buf = (char *)malloc((unsigned)blksize);
1199 (void) gettimeofday(&start, (struct timezone *)0);
1204 if (restart_point &&
1205 lseek(fileno(fout), (long) restart_point, L_SET) < 0) {
1206 fprintf(stderr, "local: %s: %s\n", local,
1208 if (closefunc != NULL)
1213 while ((c = secure_read(fileno(din), buf, bufsize)) > 0) {
1214 if ((d = write(fileno(fout), buf, c)) != c)
1218 while (bytes >= hashbytes) {
1219 (void) putchar('#');
1220 hashbytes += HASHBYTES;
1222 (void) fflush(stdout);
1225 if (hash && bytes > 0) {
1226 if (bytes < HASHBYTES)
1227 (void) putchar('#');
1228 (void) putchar('\n');
1229 (void) fflush(stdout);
1232 if (c == -1 && errno != EPIPE)
1238 fprintf(stderr, "local: %s: %s\n", local,
1241 fprintf(stderr, "%s: short write\n", local);
1246 if (restart_point) {
1247 register int i, n, ch;
1249 if (fseek(fout, 0L, L_SET) < 0)
1252 for (i = 0; i++ < n;) {
1253 if ((ch = getc(fout)) == EOF)
1258 if (fseek(fout, 0L, L_INCR) < 0) {
1260 fprintf(stderr, "local: %s: %s\n", local,
1262 if (closefunc != NULL)
1267 while ((c = secure_getc(din)) >= 0) {
1271 while (hash && (bytes >= hashbytes)) {
1272 (void) putchar('#');
1273 (void) fflush(stdout);
1274 hashbytes += HASHBYTES;
1277 if ((c = secure_getc(din)) != '\n' || tcrflag) {
1280 (void) putc('\r', fout);
1288 (void) putc(c, fout);
1294 printf("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
1295 printf("File may not have transferred correctly.\n");
1298 if (bytes < hashbytes)
1299 (void) putchar('#');
1300 (void) putchar('\n');
1301 (void) fflush(stdout);
1308 if (ferror(fout) || c == -2) {
1310 fprintf(stderr, "local: %s: %s\n", local,
1316 if (closefunc != NULL)
1318 (void) signal(SIGINT, oldintr);
1320 (void) signal(SIGPIPE, oldintp);
1321 (void) gettimeofday(&stop, (struct timezone *)0);
1324 if (bytes > 0 && is_retr)
1325 ptransfer("received", bytes, &start, &stop);
1329 /* abort using RFC959 recommended IP,SYNC sequence */
1331 (void) gettimeofday(&stop, (struct timezone *)0);
1333 (void) signal(SIGPIPE, oldintr);
1334 (void) signal(SIGINT, SIG_IGN);
1337 (void) signal(SIGINT, oldintr);
1347 if (closefunc != NULL && fout != NULL)
1352 ptransfer("received", bytes, &start, &stop);
1353 (void) signal(SIGINT, oldintr);
1357 * Need to start a listen on the data channel before we send the command,
1358 * otherwise the server's connect may fail.
1362 register char *p, *a;
1363 int result, len, tmpno = 0;
1365 #ifndef NO_PASSIVE_MODE
1366 int a1,a2,a3,a4,p1,p2;
1369 data = socket(AF_INET, SOCK_STREAM, 0);
1371 perror("ftp: socket");
1374 if (options & SO_DEBUG &&
1375 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
1376 perror("ftp: setsockopt (ignored)");
1377 if (command("PASV") != COMPLETE) {
1378 printf("Passive mode refused. Turning off passive mode.\n");
1384 * What we've got at this point is a string of comma separated
1385 * one-byte unsigned integer values, separated by commas.
1386 * The first four are the an IP address. The fifth is the MSB
1387 * of the port number, the sixth is the LSB. From that we'll
1388 * prepare a sockaddr_in.
1391 if (sscanf(pasv,"%d,%d,%d,%d,%d,%d",&a1,&a2,&a3,&a4,&p1,&p2) != 6) {
1392 printf("Passive mode address scan failure. Shouldn't happen!\n");
1396 data_addr.sin_family = AF_INET;
1397 data_addr.sin_addr.s_addr = htonl((a1<<24)|(a2<<16)|(a3<<8)|a4);
1398 data_addr.sin_port = htons((p1<<8)|p2);
1400 if (connect(data, (struct sockaddr *) &data_addr, sizeof(data_addr))<0) {
1401 perror("ftp: connect");
1405 #ifdef IPTOS_THROUGHPUT
1406 on = IPTOS_THROUGHPUT;
1407 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
1408 perror("ftp: setsockopt TOS (ignored)");
1411 hisdataaddr = data_addr;
1417 data_addr = myctladdr;
1419 data_addr.sin_port = 0; /* let system pick one */
1422 data = socket(AF_INET, SOCK_STREAM, 0);
1424 perror("ftp: socket");
1430 if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
1431 perror("ftp: setsockopt (reuse address)");
1434 if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
1435 perror("ftp: bind");
1438 if (options & SO_DEBUG &&
1439 setsockopt(data, SOL_SOCKET, SO_DEBUG, (char *)&on, sizeof (on)) < 0)
1440 perror("ftp: setsockopt (ignored)");
1441 len = sizeof (data_addr);
1442 if (getsockname(data, (struct sockaddr *)&data_addr, &len) < 0) {
1443 perror("ftp: getsockname");
1446 if (listen(data, 1) < 0)
1447 perror("ftp: listen");
1449 a = (char *)&data_addr.sin_addr;
1450 p = (char *)&data_addr.sin_port;
1451 #define UC(b) (((int)b)&0xff)
1453 command("PORT %d,%d,%d,%d,%d,%d",
1454 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
1455 UC(p[0]), UC(p[1]));
1456 if (result == ERROR && sendport == -1) {
1461 return (result != COMPLETE);
1466 #ifdef IPTOS_THROUGHPUT
1467 on = IPTOS_THROUGHPUT;
1468 if (setsockopt(data, IPPROTO_IP, IP_TOS, (char *)&on, sizeof(int)) < 0)
1469 perror("ftp: setsockopt TOS (ignored)");
1474 (void) close(data), data = -1;
1484 int s, fromlen = sizeof (hisdataaddr), tos;
1486 #ifndef NO_PASSIVE_MODE
1488 return (fdopen(data, lmode));
1490 s = accept(data, (struct sockaddr *) &hisdataaddr, &fromlen);
1492 perror("ftp: accept");
1493 (void) close(data), data = -1;
1499 #ifdef IPTOS_THROUGHPUT
1500 tos = IPTOS_THROUGHPUT;
1501 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
1502 perror("ftp: setsockopt TOS (ignored)");
1505 return (fdopen(data, lmode));
1508 ptransfer(direction, bytes, t0, t1)
1511 struct timeval *t0, *t1;
1518 s = td.tv_sec + (td.tv_usec / 1000000.);
1519 #define nz(x) ((x) == 0 ? 1 : (x))
1520 kbs = (bytes / nz(s))/1024.0;
1521 printf("%ld bytes %s in %.2g seconds (%.2g Kbytes/s)\n",
1522 bytes, direction, s, kbs);
1527 struct timeval *tsum, *t0;
1530 tsum->tv_sec += t0->tv_sec;
1531 tsum->tv_usec += t0->tv_usec;
1532 if (tsum->tv_usec > 1000000)
1533 tsum->tv_sec++, tsum->tv_usec -= 1000000;
1536 tvsub(tdiff, t1, t0)
1537 struct timeval *tdiff, *t1, *t0;
1540 tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
1541 tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
1542 if (tdiff->tv_usec < 0)
1543 tdiff->tv_sec--, tdiff->tv_usec += 1000000;
1550 extern int abrtflag;
1558 extern int proxy, abrtflag;
1560 static struct comvars {
1562 char name[MAXHOSTNAMELEN];
1563 struct sockaddr_in mctl;
1564 struct sockaddr_in hctl;
1577 char mi[MAXPATHLEN];
1578 char mo[MAXPATHLEN];
1582 #ifdef KRB5_KRB4_COMPAT
1584 Key_schedule schedule;
1585 #endif /* KRB5_KRB4_COMPAT */
1586 } proxstruct, tmpstruct;
1587 struct comvars *ip, *op;
1590 oldintr = signal(SIGINT, psabort);
1604 ip->connect = connected;
1605 connected = op->connect;
1607 (void) strncpy(ip->name, hostname, sizeof(ip->name) - 1);
1608 ip->name[strlen(ip->name)] = '\0';
1611 hostname = op->name;
1612 ip->hctl = hisctladdr;
1613 hisctladdr = op->hctl;
1614 ip->mctl = myctladdr;
1615 myctladdr = op->mctl;
1622 ip->curtpe = curtype;
1623 curtype = op->curtpe;
1626 ip->sunqe = sunique;
1627 sunique = op->sunqe;
1628 ip->runqe = runique;
1629 runique = op->runqe;
1634 (void) strncpy(ip->nti, ntin, 16);
1635 (ip->nti)[strlen(ip->nti)] = '\0';
1636 (void) strcpy(ntin, op->nti);
1637 (void) strncpy(ip->nto, ntout, 16);
1638 (ip->nto)[strlen(ip->nto)] = '\0';
1639 (void) strcpy(ntout, op->nto);
1640 ip->mapflg = mapflag;
1641 mapflag = op->mapflg;
1642 (void) strncpy(ip->mi, mapin, MAXPATHLEN - 1);
1643 (ip->mi)[strlen(ip->mi)] = '\0';
1644 (void) strcpy(mapin, op->mi);
1645 (void) strncpy(ip->mo, mapout, MAXPATHLEN - 1);
1646 (ip->mo)[strlen(ip->mo)] = '\0';
1647 (void) strcpy(mapout, op->mo);
1648 ip->authtype = auth_type;
1649 auth_type = op->authtype;
1658 #ifdef KRB5_KRB4_COMPAT
1659 memcpy(ip->session, cred.session, sizeof(cred.session));
1660 memcpy(cred.session, op->session, sizeof(cred.session));
1661 memcpy(ip->schedule, schedule, sizeof(schedule));
1662 memcpy(schedule, op->schedule, sizeof(schedule));
1663 #endif /* KRB5_KRB4_COMPAT */
1664 (void) signal(SIGINT, oldintr);
1679 (void) fflush(stdout);
1683 longjmp(ptabort, 1);
1686 proxtrans(cmd, local, remote)
1687 char *cmd, *local, *remote;
1690 int secndflag = 0, prox_type, nfnd;
1691 extern jmp_buf ptabort;
1696 if (strcmp(cmd, "RETR"))
1699 cmd2 = runique ? "STOU" : "STOR";
1700 if ((prox_type = type) == 0) {
1701 if (unix_server && unix_proxy)
1706 if (curtype != prox_type)
1707 changetype(prox_type, 1);
1708 if (command("PASV") != COMPLETE) {
1709 printf("proxy server does not support third party transfers.\n");
1714 printf("No primary connection\n");
1719 if (curtype != prox_type)
1720 changetype(prox_type, 1);
1721 if (command("PORT %s", pasv) != COMPLETE) {
1725 if (setjmp(ptabort))
1727 oldintr = signal(SIGINT, abortpt);
1728 if (command("%s %s", cmd, remote) != PRELIM) {
1729 (void) signal(SIGINT, oldintr);
1736 if (command("%s %s", cmd2, local) != PRELIM)
1742 (void) signal(SIGINT, oldintr);
1745 printf("local: %s remote: %s\n", local, remote);
1748 (void) signal(SIGINT, SIG_IGN);
1750 if (strcmp(cmd, "RETR") && !proxy)
1752 else if (!strcmp(cmd, "RETR") && proxy)
1754 if (!cpend && !secndflag) { /* only here if cmd = "STOR" (proxy=1) */
1755 if (command("%s %s", cmd2, local) != PRELIM) {
1758 abort_remote((FILE *) NULL);
1763 (void) signal(SIGINT, oldintr);
1767 abort_remote((FILE *) NULL);
1769 if (!cpend && !secndflag) { /* only if cmd = "RETR" (proxy=1) */
1770 if (command("%s %s", cmd2, local) != PRELIM) {
1773 abort_remote((FILE *) NULL);
1777 (void) signal(SIGINT, oldintr);
1782 abort_remote((FILE *) NULL);
1786 FD_SET(fileno(cin), &mask);
1787 if ((nfnd = empty(&mask, 10)) <= 0) {
1803 (void) signal(SIGINT, oldintr);
1813 FD_SET(fileno(cin), &mask);
1814 if ((nfnd = empty(&mask,0)) < 0) {
1829 static char new[MAXPATHLEN];
1830 char *cp = strrchr(local, '/');
1836 d = access(cp ? local : ".", 2);
1840 fprintf(stderr, "local: %s: %s\n", local, strerror(errno));
1843 (void) strcpy(new, local);
1844 cp = new + strlen(new);
1847 if (++count == 100) {
1848 printf("runique: can't find unique file name.\n");
1857 if ((d = access(new, 0)) < 0)
1861 else if (*(cp - 2) == '.')
1864 *(cp - 2) = *(cp - 2) + 1;
1871 #ifdef KRB5_KRB4_COMPAT
1872 char realm[REALM_SZ + 1];
1873 #endif /* KRB5_KRB4_COMPAT */
1877 const gss_OID_desc * const * mech_type;
1880 { &gss_mech_krb5_v2, "ftp" },
1881 { &gss_mech_krb5, "ftp" },
1882 { &gss_mech_krb5_v2, "host" },
1883 { &gss_mech_krb5, "host" },
1885 int n_gss_trials = sizeof(gss_trials)/sizeof(gss_trials[0]);
1890 extern int setsafe();
1891 int oldverbose = verbose;
1892 #ifdef KRB5_KRB4_COMPAT
1893 char *service, inst[INST_SZ];
1894 u_long cksum, checksum = (u_long) getpid();
1895 #endif /* KRB5_KRB4_COMPAT */
1896 #if defined(KRB5_KRB4_COMPAT) || defined(GSSAPI)
1897 u_char out_buf[FTP_BUFSIZ];
1899 #endif /* KRB5_KRB4_COMPAT */
1901 if (auth_type) return(1); /* auth already succeeded */
1903 /* Other auth types go here ... */
1906 if (command("AUTH %s", "GSSAPI") == CONTINUE) {
1907 OM_uint32 maj_stat, min_stat;
1908 gss_name_t target_name;
1909 gss_buffer_desc send_tok, recv_tok, *token_ptr;
1910 char stbuf[FTP_BUFSIZ];
1912 struct gss_channel_bindings_struct chan;
1913 chan.initiator_addrtype = GSS_C_AF_INET; /* OM_uint32 */
1914 chan.initiator_address.length = 4;
1915 chan.initiator_address.value = &myctladdr.sin_addr.s_addr;
1916 chan.acceptor_addrtype = GSS_C_AF_INET; /* OM_uint32 */
1917 chan.acceptor_address.length = 4;
1918 chan.acceptor_address.value = &hisctladdr.sin_addr.s_addr;
1919 chan.application_data.length = 0;
1920 chan.application_data.value = 0;
1923 printf("GSSAPI accepted as authentication type\n");
1925 /* blob from gss-client */
1927 for (trial = 0; trial < n_gss_trials; trial++) {
1928 /* ftp@hostname first, the host@hostname */
1929 /* the V5 GSSAPI binding canonicalizes this for us... */
1930 sprintf(stbuf, "%s@%s", gss_trials[trial].service_name, hostname);
1932 fprintf(stderr, "Trying to authenticate to <%s>\n", stbuf);
1934 send_tok.value = stbuf;
1935 send_tok.length = strlen(stbuf) + 1;
1936 maj_stat = gss_import_name(&min_stat, &send_tok,
1937 gss_nt_service_name, &target_name);
1939 if (maj_stat != GSS_S_COMPLETE) {
1940 user_gss_error(maj_stat, min_stat, "parsing name");
1941 secure_error("name parsed <%s>\n", stbuf);
1945 token_ptr = GSS_C_NO_BUFFER;
1946 gcontext = GSS_C_NO_CONTEXT; /* structure copy */
1950 fprintf(stderr, "calling gss_init_sec_context\n");
1952 gss_init_sec_context(&min_stat,
1953 GSS_C_NO_CREDENTIAL,
1956 *gss_trials[trial].mech_type,
1957 GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG |
1958 (forward ? GSS_C_DELEG_FLAG : 0),
1960 &chan, /* channel bindings */
1962 NULL, /* ignore mech type */
1964 NULL, /* ignore ret_flags */
1965 NULL); /* ignore time_rec */
1968 if (maj_stat!=GSS_S_COMPLETE && maj_stat!=GSS_S_CONTINUE_NEEDED){
1969 if (trial == n_gss_trials-1)
1970 user_gss_error(maj_stat, min_stat, "initializing context");
1971 (void) gss_release_name(&min_stat, &target_name);
1972 /* could just be that we missed on the service name */
1976 if (send_tok.length != 0) {
1977 int len = send_tok.length;
1978 reply_parse = "ADAT="; /* for command() later */
1979 oldverbose = verbose;
1980 verbose = (trial == n_gss_trials-1)?0:-1;
1981 kerror = radix_encode(send_tok.value, out_buf, &len, 0);
1983 fprintf(stderr, "Base 64 encoding failed: %s\n",
1984 radix_error(kerror));
1985 } else if ((comcode = command("ADAT %s", out_buf))!=COMPLETE
1986 /* && comcode != 3 (335)*/) {
1987 if (trial == n_gss_trials-1) {
1988 fprintf(stderr, "GSSAPI ADAT failed\n");
1989 /* force out of loop */
1990 maj_stat = GSS_S_FAILURE;
1992 /* backoff to the v1 gssapi is still possible. Send
1993 a new AUTH command. If that fails, terminate the
1995 if (command("AUTH %s", "GSSAPI") != CONTINUE) {
1997 "GSSAPI ADAT failed, AUTH restart failed\n");
1998 /* force out of loop */
1999 maj_stat = GSS_S_FAILURE;
2002 } else if (!reply_parse) {
2004 "No authentication data received from server\n");
2005 if (maj_stat == GSS_S_COMPLETE) {
2006 fprintf(stderr, "...but no more was needed\n");
2007 goto gss_complete_loop;
2009 user_gss_error(maj_stat, min_stat, "no reply, huh?");
2010 goto gss_complete_loop;
2012 } else if (kerror = radix_encode(reply_parse,out_buf,&i,1)) {
2013 fprintf(stderr, "Base 64 decoding failed: %s\n",
2014 radix_error(kerror));
2016 /* everything worked */
2017 token_ptr = &recv_tok;
2018 recv_tok.value = out_buf;
2019 recv_tok.length = i;
2023 /* get out of loop clean */
2025 trial = n_gss_trials-1;
2026 gss_release_buffer(&min_stat, &send_tok);
2027 gss_release_name(&min_stat, &target_name);
2030 } while (maj_stat == GSS_S_CONTINUE_NEEDED);
2032 if (maj_stat == GSS_S_COMPLETE)
2035 verbose = oldverbose;
2036 if (maj_stat == GSS_S_COMPLETE) {
2037 printf("GSSAPI authentication succeeded\n");
2039 auth_type = "GSSAPI";
2042 fprintf(stderr, "GSSAPI authentication failed\n");
2043 verbose = oldverbose;
2048 #ifdef KRB5_KRB4_COMPAT
2049 if (command("AUTH %s", "KERBEROS_V4") == CONTINUE) {
2051 printf("%s accepted as authentication type\n", "KERBEROS_V4");
2053 strcpy(inst, (char *) krb_get_phost(hostname));
2054 if (realm[0] == '\0')
2055 strcpy(realm, (char *) krb_realmofhost(hostname));
2056 if ((kerror = krb_mk_req(&ticket, service = "ftp",
2057 inst, realm, checksum))
2058 && (kerror != KDC_PR_UNKNOWN ||
2059 (kerror = krb_mk_req(&ticket, service = "rcmd",
2060 inst, realm, checksum))))
2061 fprintf(stderr, "Kerberos V4 krb_mk_req failed: %s\n",
2062 krb_get_err_text(kerror));
2063 else if (kerror = krb_get_cred(service, inst, realm, &cred))
2064 fprintf(stderr, "Kerberos V4 krb_get_cred failed: %s\n",
2065 krb_get_err_text(kerror));
2067 key_sched(cred.session, schedule);
2068 reply_parse = "ADAT=";
2069 oldverbose = verbose;
2072 if (kerror = radix_encode(ticket.dat, out_buf, &i, 0))
2073 fprintf(stderr, "Base 64 encoding failed: %s\n",
2074 radix_error(kerror));
2075 else if (command("ADAT %s", out_buf) != COMPLETE)
2076 fprintf(stderr, "Kerberos V4 authentication failed\n");
2077 else if (!reply_parse)
2079 "No authentication data received from server\n");
2080 else if (kerror = radix_encode(reply_parse, out_buf, &i, 1))
2081 fprintf(stderr, "Base 64 decoding failed: %s\n",
2082 radix_error(kerror));
2083 else if (kerror = krb_rd_safe(out_buf, i, &cred.session,
2084 &hisctladdr, &myctladdr, &msg_data))
2085 fprintf(stderr, "Kerberos V4 krb_rd_safe failed: %s\n",
2086 krb_get_err_text(kerror));
2088 /* fetch the (modified) checksum */
2089 (void) memcpy(&cksum, msg_data.app_data, sizeof(cksum));
2090 if (ntohl(cksum) == checksum + 1) {
2091 verbose = oldverbose;
2093 printf("Kerberos V4 authentication succeeded\n");
2095 auth_type = "KERBEROS_V4";
2097 } else fprintf(stderr,
2098 "Kerberos V4 mutual authentication failed\n");
2100 verbose = oldverbose;
2103 } else fprintf(stderr, "%s rejected as an authentication type\n",
2105 #endif /* KRB5_KRB4_COMPAT */
2107 /* Other auth types go here ... */
2117 if (ucbuf) (void) free(ucbuf);
2119 while ((ucbuf = (unsigned char *)malloc(actualbuf)) == NULL)
2123 perror("Error while trying to malloc PROT buffer:");
2126 oldverbose = verbose;
2128 reply_parse = "PBSZ=";
2129 if (command("PBSZ %u", actualbuf) != COMPLETE)
2130 fatal("Cannot set PROT buffer size");
2132 if ((maxbuf = (unsigned int) atol(reply_parse)) > actualbuf)
2134 } else maxbuf = actualbuf;
2136 verbose = oldverbose;
2142 char buf[FTP_BUFSIZ];
2147 * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
2148 * after urgent byte rather than before as is protocol now
2150 sprintf(buf, "%c%c%c", IAC, IP, IAC);
2151 if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
2154 (void) secure_command("ABOR");
2156 FD_SET(fileno(cin), &mask);
2158 FD_SET(fileno(din), &mask);
2160 if ((nfnd = empty(&mask, 10)) <= 0) {
2168 if (din && FD_ISSET(fileno(din), &mask)) {
2169 /* Security: No threat associated with this read. */
2170 while (read(fileno(din), buf, FTP_BUFSIZ) > 0)
2173 if (getreply(0) == ERROR && code == 552) {
2174 /* 552 needed for nic style abort */
2180 user_gss_error(maj_stat, min_stat, s)
2181 OM_uint32 maj_stat, min_stat;
2184 /* a lot of work just to report the error */
2185 OM_uint32 gmaj_stat, gmin_stat;
2186 gss_buffer_desc msg;
2190 gmaj_stat = gss_display_status(&gmin_stat, maj_stat,
2194 if ((gmaj_stat == GSS_S_COMPLETE)||
2195 (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
2196 fprintf(stderr, "GSSAPI error major: %s\n",
2198 (void) gss_release_buffer(&gmin_stat, &msg);
2200 if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
2205 gmaj_stat = gss_display_status(&gmin_stat, min_stat,
2209 if ((gmaj_stat == GSS_S_COMPLETE)||
2210 (gmaj_stat == GSS_S_CONTINUE_NEEDED)) {
2211 fprintf(stderr, "GSSAPI error minor: %s\n",
2213 (void) gss_release_buffer(&gmin_stat, &msg);
2215 if (gmaj_stat != GSS_S_CONTINUE_NEEDED)
2218 fprintf(stderr, "GSSAPI error: %s\n", s);
2221 secure_gss_error(maj_stat, min_stat, s)
2222 OM_uint32 maj_stat, min_stat;
2225 return user_gss_error(maj_stat, min_stat, s);