freebsd-src/usr.sbin/sysinstall/ftp.c
Jordan K. Hubbard 7ccad8a96a 1. Bring in the first cut of Poul's ftp routines. We still don't
use them yet, but it's close (we're working on the last wrinkles
   in the CD install for now).
2. Complete the CDROM installation strategy code.
3. Simplify the distribtuion loading code.
4. General error message cleanup.
5. Write the /etc/fstab file now and split those routines into config.c
6. Clean up the menus a little more.
1995-05-23 02:41:18 +00:00

253 lines
4.1 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <netdb.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include "ftp.h"
#include "sysinstall.h"
static void
debug(FTP_t ftp, const char *fmt, ...)
{
char p[BUFSIZ];
va_list ap;
va_start(ap, fmt);
(void) vsnprintf(p, sizeof p, fmt, ap);
va_end(ap);
#if 0
write(ftp->fd_debug,p,strlen(p));
#else
msgDebug(p);
#endif
}
static int
writes(int fd, char *s)
{
int i = strlen(s);
if (i != write(fd,s,i))
return errno ? errno : -1;
return 0;
}
static char*
get_a_line(FTP_t ftp)
{
static char buf[BUFSIZ];
int i,j;
for(i=0;i<BUFSIZ;) {
j = read(ftp->fd_ctrl,buf+i,1);
if (j != 1)
return 0;
if (buf[i] == '\r' || buf[i] == '\n') {
if (!i)
continue;
buf[i] = '\0';
debug(ftp,"LIBFTP: received <%s>\n",buf);
return buf;
}
i++;
}
}
int
get_a_number(FTP_t ftp)
{
char *p;
while(1) {
p = get_a_line(ftp);
if (p[3] != ' ' && p[3] != ' ')
continue;
return atoi(p);
}
}
static int
cmd(FTP_t ftp, const char *fmt, ...)
{
char p[BUFSIZ];
int i;
va_list ap;
va_start(ap, fmt);
(void) vsnprintf(p, sizeof p, fmt, ap);
va_end(ap);
debug(ftp,"LIBFTP: send <%s>\n",p);
if (writes(ftp->fd_ctrl,p))
return -1;
if (writes(ftp->fd_ctrl,"\r\n"))
return -1;
i = get_a_number(ftp);
debug(ftp, "LIBFTP: got %d\n",i);
return i;
}
FTP_t
FtpInit()
{
FTP_t ftp;
ftp = malloc(sizeof *ftp);
if (!ftp)
return ftp;
memset(ftp, 0, sizeof *ftp);
ftp->fd_ctrl = -1;
ftp->fd_debug = -1;
return ftp;
}
#if 0
void
FtpDebug(FTP_t ftp, int i)
{
ftp->fd_debug = i;
}
#endif
int
FtpOpen(FTP_t ftp, char *host, char *user, char *passwd)
{
struct hostent *he, hdef;
struct servent *se, sdef;
struct sockaddr_in sin;
int s;
char a,*p,buf[BUFSIZ];
if (!user)
user = "ftp";
if (!passwd)
passwd = "??@??(FreeBSD:libftp)"; /* XXX */
he = gethostbyname(host);
if (!he)
return ENOENT;
se = getservbyname("ftp","tcp");
if (!se)
return ENOENT;
ftp->addrtype = sin.sin_family = he->h_addrtype;
bcopy(he->h_addr, (char *)&sin.sin_addr, he->h_length);
sin.sin_port = se->s_port;
if ((s = socket(he->h_addrtype, SOCK_STREAM, 0)) < 0)
return s;
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
(void)close(s);
return -1;
}
ftp->fd_ctrl = s;
debug(ftp, "LIBFTP: open (%d)\n",get_a_number(ftp));
cmd(ftp,"USER %s",user);
cmd(ftp,"PASS %s",passwd);
return 0;
fail:
close(ftp->fd_ctrl);
ftp->fd_ctrl = -1;
return -1;
}
int
FtpChdir(FTP_t ftp, char *dir)
{
cmd(ftp,"CWD %s",dir);
return 0;
}
int
FtpGet(FTP_t ftp, char *file)
{
int fd,i,j,s;
char p[BUFSIZ],*q;
unsigned char addr[6];
struct sockaddr_in sin;
if(ftp->binary) {
cmd(ftp,"TYPE I");
} else {
return -1;
}
if(ftp->passive) {
if (writes(ftp->fd_ctrl,"PASV\r\n"))
return -1;
q = get_a_line(ftp);
if (strncmp(q,"227 ",4))
return -1;
q = strchr(q,'(');
if (!q)
return -1;
for(i=0;i<6;i++) {
q++;
addr[i] = strtol(q,&q,10);
debug(ftp,"ADDR[%d] = %d (%c)\n",i,addr[i],*q);
}
if (*q != ')')
return -1;
sin.sin_family = ftp->addrtype;
bcopy(addr, (char *)&sin.sin_addr, 4);
bcopy(addr+4, (char *)&sin.sin_port, 2);
if ((s = socket(ftp->addrtype, SOCK_STREAM, 0)) < 0)
return -1;
debug(ftp,"Getsocket = %d\n",s);
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
(void)close(s);
debug(ftp,"connect, errno = %d\n",errno);
return -1;
}
cmd(ftp,"RETR %s",file);
return s;
} else {
return -1;
}
}
int
FtpEOF(FTP_t ftp)
{
get_a_number(ftp);
}
#ifdef STANDALONE_FTP
/* main.c */
int
main(int argc, char **argv)
{
FTP_t ftp;
int i;
char c;
ftp = FtpInit();
if (!ftp) err(1,"FtpInit()");
FtpDebug(ftp,1);
i = FtpOpen(ftp, "ref", "ftp", "phk-libftp@");
if (i) err(1,"FtpOpen(%d)",i);
FtpBinary(ftp,1);
FtpPassive(ftp,1);
FtpChdir(ftp,"/pub");
FtpChdir(ftp,"CTM");
i = FtpGet(ftp,"README_CTM_MOVED");
while(1 == read(i,&c,1))
putchar(c);
FtpEOF(ftp);
return 0;
}
#endif /*STANDALONE_FTP*/