9 date 93.08.25.17.25.27; author jromine; state Exp;
14 date 93.08.20.15.49.47; author jromine; state Exp;
19 date 93.03.17.00.18.56; author jromine; state Exp;
24 date 92.12.03.16.50.27; author jromine; state Exp;
29 date 92.12.03.16.28.56; author jromine; state Exp;
34 date 92.11.24.18.24.30; author jromine; state Exp;
39 date 92.11.12.00.41.28; author jromine; state Exp;
44 date 92.11.11.20.56.53; author jromine; state Exp;
49 date 92.11.02.21.35.10; author jromine; state Exp;
54 date 92.11.02.17.01.49; author jromine; state Exp;
59 date 92.10.20.16.31.05; author jromine; state Exp;
64 date 92.05.19.21.03.01; author jromine; state Exp;
69 date 92.01.31.16.28.15; author jromine; state Exp;
81 @off_t fixes for BSD44
84 @/* ftpsbr.c - simple FTP client library (why doesn't BSD have one?!?) */
87 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.12 1993/08/20 15:49:47 jromine Exp jromine $";
95 #undef NULLVP /* stdio.h */
106 static int command(int arg1, ...);
108 static int command();
111 static int ftp_quit(), ftp_read(), initconn(),
112 dataconn(), _command(), getreply();
116 #define v_debug debugsw
117 #define v_verbose verbosw
120 static int ftp_fd = NOTOK;
121 static int data_fd = NOTOK;
126 extern int v_verbose;
130 #if defined(SYS5) && defined(AUX)
131 #define u_short ushort
135 #include <sys/types.h>
136 #include <sys/socket.h>
137 #include <netinet/in.h>
140 #if defined(BIND) && !defined(h_addr)
141 #define h_addr h_addr_list[0]
144 #define inaddr_copy(hp,sin) \
145 bcopy ((hp) -> h_addr, (char *) &((sin) -> sin_addr), (hp) -> h_length)
148 struct hostent *gethostbystring ();
155 extern char *sys_errlist[];
159 #define start_tcp_client(sock,priv) \
160 socket (AF_INET, SOCK_STREAM, 0)
162 #define join_tcp_server(fd, sock) \
163 connect ((fd), (struct sockaddr *) (sock), sizeof *(sock))
168 static int start_tcp_server (sock, backlog, opt1, opt2)
169 struct sockaddr_in *sock;
177 if ((sd = socket (AF_INET, SOCK_STREAM, 0)) == NOTOK)
180 if (bind (sd, (struct sockaddr *) sock, sizeof *sock) == NOTOK) {
186 (void) listen (sd, backlog);
192 #define join_tcp_client(fd,sock) \
193 accept ((fd), (struct sockaddr *) (sock), \
194 (__len__ = sizeof *(sock), &__len__))
197 #define read_tcp_socket read
198 #define write_tcp_socket write
199 #define close_tcp_socket close
203 static void _asprintf (bp, what, ap) /* fmt, args, ... */
214 fmt = va_arg (ap, char *);
223 bzero ((char *) &iob, sizeof iob);
226 iob._flag = _IOWRT | _IOSTRG;
227 #if !defined(vax) && !defined(pyr) && !defined(sequent)
228 iob._ptr = (unsigned char *) bp;
233 _doprnt (fmt, ap, &iob);
234 (void) putc ('\0', &iob);
236 (void) vsprintf (bp, fmt, ap);
244 (void) sprintf (bp, " %s: ", what);
247 if (0 < eindex && eindex < sys_nerr)
248 (void) strcpy (bp, sys_errlist[eindex]);
250 (void) sprintf (bp, "Error %d", eindex);
259 int ftp_get (host, user, password, cwd, remote, local, ascii, stayopen)
269 return ftp_trans (host, user, password, cwd, remote, local, "RETR", ascii,
275 int ftp_trans (host, user, password, cwd, remote, local, cmd, ascii,
290 result = ftp_quit ();
295 if (ftp_fd == NOTOK) {
296 struct sockaddr_in in_socket;
297 register struct hostent *hp;
298 register struct servent *sp;
300 if ((sp = getservbyname ("ftp", "tcp")) == NULL) {
301 fprintf (stderr, "tcp/ftp: unknown service");
304 if ((hp = gethostbystring (host)) == NULL) {
305 fprintf (stderr, "%s: unknown host\n", host);
308 in_socket.sin_family = hp -> h_addrtype;
309 inaddr_copy (hp, &in_socket);
310 in_socket.sin_port = sp -> s_port;
312 if ((ftp_fd = start_tcp_client ((struct sockaddr_in *) NULL, 0))
317 if (join_tcp_server (ftp_fd, &in_socket) == NOTOK) {
319 (void) close_tcp_socket (ftp_fd), ftp_fd = NOTOK;
322 (void) getreply (1, 0);
325 fprintf (stdout, "Connected to %s\n", host);
326 (void) fflush (stdout);
330 if ((result = command (0, "USER %s", user)) == CONTINUE)
331 result = command (1, "PASS %s", password);
332 if (result != COMPLETE) {
342 if (cwd && ((result = command (0, "CWD %s", cwd)) != COMPLETE
343 && result != CONTINUE)) {
348 if (command (1, ascii ? "TYPE A" : "TYPE I") != COMPLETE) {
353 result = ftp_read (remote, local, cmd, ascii);
356 if (result != OK || !stayopen)
364 static int ftp_quit ()
371 n = command (1, "QUIT");
373 (void) close_tcp_socket (ftp_fd), ftp_fd = NOTOK;
375 return (n == 0 || n == COMPLETE ? OK : NOTOK);
380 static int ftp_read (remote, local, cmd, ascii)
389 int expectingreply = 0;
393 if (initconn () == NOTOK)
397 if (command (-1, *remote ? "%s %s" : "%s", cmd, remote) != PRELIM)
401 if (dataconn () == NOTOK) {
405 if (data_fd != NOTOK)
406 (void) close_tcp_socket (data_fd), data_fd = NOTOK;
408 (void) getreply (-2, 0);
413 istore = !strcmp (cmd, "STOR");
415 if (istdio = !strcmp (local, "-"))
416 fp = istore ? stdin : stdout;
418 if ((fp = fopen (local, istore ? "r" : "w")) == NULL) {
428 if (!(out = fdopen (data_fd, "w"))) {
433 while ((c = getc (fp)) != EOF) {
435 (void) putc ('\r', out);
436 if (putc (c, out) == EOF) {
448 while ((cc = fread (buffer, sizeof *buffer, sizeof buffer, fp)) >0)
449 if (write_tcp_socket (data_fd, buffer, cc) != cc) {
450 perror ("write_tcp_socket");
454 (void) close_tcp_socket (data_fd), data_fd = NOTOK;
462 if (!(in = fdopen (data_fd, "r"))) {
467 while ((c = getc (in)) != EOF) {
469 switch (c = getc (in)) {
479 (void) putc ('\r', fp);
483 if (putc (c, fp) == EOF) {
495 while ((cc = read_tcp_socket (data_fd, buffer, sizeof buffer)) > 0)
496 if (fwrite (buffer, sizeof *buffer, cc, fp) == 0) {
501 perror ("read_tcp_socket");
505 (void) close_tcp_socket (data_fd), data_fd = NOTOK;
513 return (getreply (1, 0) == COMPLETE ? OK : NOTOK);
518 static int initconn ()
523 struct sockaddr_in in_socket;
525 if (getsockname (ftp_fd, (struct sockaddr *) &in_socket,
526 (len = sizeof in_socket, &len)) == NOTOK) {
527 perror ("getsockname");
530 in_socket.sin_port = 0;
531 if ((data_fd = start_tcp_server (&in_socket, 1, 0, 0)) == NOTOK) {
532 perror ("start_tcp_server");
536 if (getsockname (data_fd, (struct sockaddr *) &in_socket,
537 (len = sizeof in_socket, &len)) == NOTOK) {
538 perror ("getsockname");
542 a = (char *) &in_socket.sin_addr;
543 p = (char *) &in_socket.sin_port;
545 #define UC(b) (((int) b) & 0xff)
546 if (command (1, "PORT %d,%d,%d,%d,%d,%d",
547 UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
548 UC(p[0]), UC(p[1])) == COMPLETE)
556 static int dataconn ()
559 struct sockaddr_in in_socket;
561 if ((fd = join_tcp_client (data_fd, &in_socket)) == NOTOK) {
562 perror ("join_tcp_client");
565 (void) close_tcp_socket (data_fd);
575 static int command (int arg1, ...)
582 val = _command (arg1, ap);
589 static int command (va_alist)
597 val = va_arg (ap, int);
598 val = _command (val, ap);
606 static int _command (complete, ap)
616 _asprintf (buffer, NULLCP, ap);
618 fprintf (stderr, "<--- %s\n", buffer);
620 (void) strcat (buffer, "\r\n");
621 len = strlen (buffer);
623 if (write_tcp_socket (ftp_fd, buffer, len) != len) {
624 perror ("write_tcp_socket");
628 return (getreply (complete, !strcmp (buffer, "QUIT")));
633 static int command (complete, fmt)
637 return command (complete, fmt);
643 static int getreply (complete, expecteof)
655 code = dig = n = continuation = 0;
661 if (read_tcp_socket (ftp_fd, &c, 1) < 1) {
665 perror ("read_tcp_socket");
670 *bp++ = c != '\r' ? c : '\0';
675 code = code * 10 + (c - '0');
676 else /* XXX: naughty FTP... */
681 if (dig == 4 && c == '-')
688 fprintf (stderr, "---> %s\n", buffer);
695 fprintf (stdout, "%s\n", buffer);
696 (void) fflush (stdout);
700 if ((complete == -1 && n != PRELIM)
701 || (complete == 0 && n != CONTINUE && n != COMPLETE)
702 || (complete == 1 && n != COMPLETE))
703 fprintf (stderr, "%s\n", buffer);
714 @added gethostbystring() routine (deals with numbers and names)
715 added support for writing files, etc.
721 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.11 1993/03/17 00:18:56 jromine Exp jromine $";
729 @fix varargs - argument passing order is not defined in C
734 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.10 1992/12/03 16:50:27 jromine Exp jromine $";
737 /* taken from ISODE's compat/internet.c */
743 struct in_addr inet_addr ();
747 static char *empty = NULL;
749 static char *addrs[2] = { NULL };
752 static struct hostent *gethostbystring (s)
755 register struct hostent *h;
759 static struct in_addr iaddr;
761 static struct hostent hs;
763 iaddr = inet_addr (s);
765 if (iaddr == NOTOK && strcmp (s, "255.255.255.255"))
767 if (iaddr.s_addr == NOTOK && strcmp (s, "255.255.255.255"))
769 return gethostbyname (s);
773 h -> h_aliases = ∅
774 h -> h_addrtype = AF_INET;
775 h -> h_length = sizeof (iaddr);
777 h -> h_addr_list = addrs;
778 bzero ((char *) addrs, sizeof addrs);
780 h -> h_addr = (char *) &iaddr;
788 result = ftp_read (remote, local, ascii);
791 static int ftp_read (remote, local, ascii)
801 if (command (-1, "RETR %s", remote) != PRELIM)
805 if ((fp = fopen (local, "w")) == NULL) {
815 if (!(in = fdopen (data_fd, "r"))) {
818 while ((c = getc (in)) != EOF) {
820 switch (c = getc (in)) {
832 (void) putc ('\r', fp);
837 if (putc (c, fp) == EOF) {
850 while ((cc = read_tcp_socket (data_fd, buffer, sizeof buffer)) > 0)
851 if (fwrite (buffer, sizeof *buffer, cc, fp) == 0) {
856 perror ("read_tcp_socket");
861 (void) close_tcp_socket (data_fd), data_fd = NOTOK;
870 @put u_short ifdef under #if AUX
875 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.9 1992/12/03 16:28:56 jromine Exp jromine $";
878 val = _command (va_arg (ap, int), ap);
884 @u_short AUX changes from Jim Guyton
889 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.8 1992/11/24 18:24:30 jromine Exp jromine $";
903 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.7 1992/11/12 00:41:28 jromine Exp jromine $";
916 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.6 1992/11/11 20:56:53 jromine Exp jromine $";
923 @VSPRINTF fixups for aix
928 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.5 1992/11/02 21:35:10 jromine Exp jromine $";
935 if ((iob = malloc(sizeof iob)) == NULL)
936 adios(NULLCP, "unable to allocate buffer");
942 @iob->_ptr ifdef sequent (type problem)
947 /* ftp.c - simple FTP client library (why doesn't BSD have one?!?) */
950 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.4 1992/11/02 17:01:49 jromine Exp jromine $";
964 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.3 1992/10/20 16:31:05 jromine Exp jromine $";
967 #if !defined(vax) && !defined(pyr)
978 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.2 1992/05/19 21:03:01 jromine Exp $";
990 static char ident[] = "@@(#)$Id: ftpsbr.c,v 1.1 1992/01/31 16:28:15 jromine Exp jromine $";
1000 originalcode = continuation = 0;
1008 if (dig < 4 && isdigit(c))
1009 code = code * 10 + (c - '0');
1010 if (dig == 4 && c == '-')
1013 if (continuation && code != originalcode) {
1014 if (originalcode == 0)
1015 originalcode = code;
1029 static char ident[] = "@@(#)$Id$";
1037 (void) putc (NULL, &iob);
1044 val = _command (ap);
1048 static int _command (ap)
1055 complete = va_arg (ap, int);
1059 *bp++ = c != '\r' ? c : NULL;