]>
diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/uip/ftpsbr.c
1 /* ftpsbr.c - simple FTP client library (why doesn't BSD have one?!?) */
4 static char ident
[] = "@(#)$Id: ftpsbr.c,v 1.13 1993/08/25 17:25:27 jromine Exp $";
12 #undef NULLVP /* stdio.h */
23 static int command(int arg1
, ...);
28 static int ftp_quit(), ftp_read(), initconn(),
29 dataconn(), _command(), getreply();
33 #define v_debug debugsw
34 #define v_verbose verbosw
37 static int ftp_fd
= NOTOK
;
38 static int data_fd
= NOTOK
;
47 #if defined(SYS5) && defined(AUX)
48 #define u_short ushort
52 #include <sys/types.h>
53 #include <sys/socket.h>
54 #include <netinet/in.h>
57 #if defined(BIND) && !defined(h_addr)
58 #define h_addr h_addr_list[0]
61 #define inaddr_copy(hp,sin) \
62 bcopy ((hp) -> h_addr, (char *) &((sin) -> sin_addr), (hp) -> h_length)
65 struct hostent
*gethostbystring ();
72 extern char *sys_errlist
[];
76 #define start_tcp_client(sock,priv) \
77 socket (AF_INET, SOCK_STREAM, 0)
79 #define join_tcp_server(fd, sock) \
80 connect ((fd), (struct sockaddr *) (sock), sizeof *(sock))
85 static int start_tcp_server (sock
, backlog
, opt1
, opt2
)
86 struct sockaddr_in
*sock
;
94 if ((sd
= socket (AF_INET
, SOCK_STREAM
, 0)) == NOTOK
)
97 if (bind (sd
, (struct sockaddr
*) sock
, sizeof *sock
) == NOTOK
) {
103 (void) listen (sd
, backlog
);
109 #define join_tcp_client(fd,sock) \
110 accept ((fd), (struct sockaddr *) (sock), \
111 (__len__ = sizeof *(sock), &__len__))
114 #define read_tcp_socket read
115 #define write_tcp_socket write
116 #define close_tcp_socket close
120 static void _asprintf (bp
, what
, ap
) /* fmt, args, ... */
131 fmt
= va_arg (ap
, char *);
140 bzero ((char *) &iob
, sizeof iob
);
143 iob
._flag
= _IOWRT
| _IOSTRG
;
144 #if !defined(vax) && !defined(pyr) && !defined(sequent)
145 iob
._ptr
= (unsigned char *) bp
;
150 _doprnt (fmt
, ap
, &iob
);
151 (void) putc ('\0', &iob
);
153 (void) vsprintf (bp
, fmt
, ap
);
161 (void) sprintf (bp
, " %s: ", what
);
164 if (0 < eindex
&& eindex
< sys_nerr
)
165 (void) strcpy (bp
, sys_errlist
[eindex
]);
167 (void) sprintf (bp
, "Error %d", eindex
);
176 int ftp_get (host
, user
, password
, cwd
, remote
, local
, ascii
, stayopen
)
186 return ftp_trans (host
, user
, password
, cwd
, remote
, local
, "RETR", ascii
,
192 int ftp_trans (host
, user
, password
, cwd
, remote
, local
, cmd
, ascii
,
207 result
= ftp_quit ();
212 if (ftp_fd
== NOTOK
) {
213 struct sockaddr_in in_socket
;
214 register struct hostent
*hp
;
215 register struct servent
*sp
;
217 if ((sp
= getservbyname ("ftp", "tcp")) == NULL
) {
218 fprintf (stderr
, "tcp/ftp: unknown service");
221 if ((hp
= gethostbystring (host
)) == NULL
) {
222 fprintf (stderr
, "%s: unknown host\n", host
);
225 in_socket
.sin_family
= hp
-> h_addrtype
;
226 inaddr_copy (hp
, &in_socket
);
227 in_socket
.sin_port
= sp
-> s_port
;
229 if ((ftp_fd
= start_tcp_client ((struct sockaddr_in
*) NULL
, 0))
234 if (join_tcp_server (ftp_fd
, &in_socket
) == NOTOK
) {
236 (void) close_tcp_socket (ftp_fd
), ftp_fd
= NOTOK
;
239 (void) getreply (1, 0);
242 fprintf (stdout
, "Connected to %s\n", host
);
243 (void) fflush (stdout
);
247 if ((result
= command (0, "USER %s", user
)) == CONTINUE
)
248 result
= command (1, "PASS %s", password
);
249 if (result
!= COMPLETE
) {
259 if (cwd
&& ((result
= command (0, "CWD %s", cwd
)) != COMPLETE
260 && result
!= CONTINUE
)) {
265 if (command (1, ascii
? "TYPE A" : "TYPE I") != COMPLETE
) {
270 result
= ftp_read (remote
, local
, cmd
, ascii
);
273 if (result
!= OK
|| !stayopen
)
281 static int ftp_quit ()
288 n
= command (1, "QUIT");
290 (void) close_tcp_socket (ftp_fd
), ftp_fd
= NOTOK
;
292 return (n
== 0 || n
== COMPLETE
? OK
: NOTOK
);
297 static int ftp_read (remote
, local
, cmd
, ascii
)
306 int expectingreply
= 0;
310 if (initconn () == NOTOK
)
314 if (command (-1, *remote
? "%s %s" : "%s", cmd
, remote
) != PRELIM
)
318 if (dataconn () == NOTOK
) {
322 if (data_fd
!= NOTOK
)
323 (void) close_tcp_socket (data_fd
), data_fd
= NOTOK
;
325 (void) getreply (-2, 0);
330 istore
= !strcmp (cmd
, "STOR");
332 if (istdio
= !strcmp (local
, "-"))
333 fp
= istore
? stdin
: stdout
;
335 if ((fp
= fopen (local
, istore
? "r" : "w")) == NULL
) {
345 if (!(out
= fdopen (data_fd
, "w"))) {
350 while ((c
= getc (fp
)) != EOF
) {
352 (void) putc ('\r', out
);
353 if (putc (c
, out
) == EOF
) {
365 while ((cc
= fread (buffer
, sizeof *buffer
, sizeof buffer
, fp
)) >0)
366 if (write_tcp_socket (data_fd
, buffer
, cc
) != cc
) {
367 perror ("write_tcp_socket");
371 (void) close_tcp_socket (data_fd
), data_fd
= NOTOK
;
379 if (!(in
= fdopen (data_fd
, "r"))) {
384 while ((c
= getc (in
)) != EOF
) {
386 switch (c
= getc (in
)) {
396 (void) putc ('\r', fp
);
400 if (putc (c
, fp
) == EOF
) {
412 while ((cc
= read_tcp_socket (data_fd
, buffer
, sizeof buffer
)) > 0)
413 if (fwrite (buffer
, sizeof *buffer
, cc
, fp
) == 0) {
418 perror ("read_tcp_socket");
422 (void) close_tcp_socket (data_fd
), data_fd
= NOTOK
;
430 return (getreply (1, 0) == COMPLETE
? OK
: NOTOK
);
435 static int initconn ()
440 struct sockaddr_in in_socket
;
442 if (getsockname (ftp_fd
, (struct sockaddr
*) &in_socket
,
443 (len
= sizeof in_socket
, &len
)) == NOTOK
) {
444 perror ("getsockname");
447 in_socket
.sin_port
= 0;
448 if ((data_fd
= start_tcp_server (&in_socket
, 1, 0, 0)) == NOTOK
) {
449 perror ("start_tcp_server");
453 if (getsockname (data_fd
, (struct sockaddr
*) &in_socket
,
454 (len
= sizeof in_socket
, &len
)) == NOTOK
) {
455 perror ("getsockname");
459 a
= (char *) &in_socket
.sin_addr
;
460 p
= (char *) &in_socket
.sin_port
;
462 #define UC(b) (((int) b) & 0xff)
463 if (command (1, "PORT %d,%d,%d,%d,%d,%d",
464 UC(a
[0]), UC(a
[1]), UC(a
[2]), UC(a
[3]),
465 UC(p
[0]), UC(p
[1])) == COMPLETE
)
473 static int dataconn ()
476 struct sockaddr_in in_socket
;
478 if ((fd
= join_tcp_client (data_fd
, &in_socket
)) == NOTOK
) {
479 perror ("join_tcp_client");
482 (void) close_tcp_socket (data_fd
);
492 static int command (int arg1
, ...)
499 val
= _command (arg1
, ap
);
506 static int command (va_alist
)
514 val
= va_arg (ap
, int);
515 val
= _command (val
, ap
);
523 static int _command (complete
, ap
)
533 _asprintf (buffer
, NULLCP
, ap
);
535 fprintf (stderr
, "<--- %s\n", buffer
);
537 (void) strcat (buffer
, "\r\n");
538 len
= strlen (buffer
);
540 if (write_tcp_socket (ftp_fd
, buffer
, len
) != len
) {
541 perror ("write_tcp_socket");
545 return (getreply (complete
, !strcmp (buffer
, "QUIT")));
550 static int command (complete
, fmt
)
554 return command (complete
, fmt
);
560 static int getreply (complete
, expecteof
)
572 code
= dig
= n
= continuation
= 0;
578 if (read_tcp_socket (ftp_fd
, &c
, 1) < 1) {
582 perror ("read_tcp_socket");
587 *bp
++ = c
!= '\r' ? c
: '\0';
592 code
= code
* 10 + (c
- '0');
593 else /* XXX: naughty FTP... */
598 if (dig
== 4 && c
== '-')
605 fprintf (stderr
, "---> %s\n", buffer
);
612 fprintf (stdout
, "%s\n", buffer
);
613 (void) fflush (stdout
);
617 if ((complete
== -1 && n
!= PRELIM
)
618 || (complete
== 0 && n
!= CONTINUE
&& n
!= COMPLETE
)
619 || (complete
== 1 && n
!= COMPLETE
))
620 fprintf (stderr
, "%s\n", buffer
);