⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net.c

📁 操作系统源代码
💻 C
字号:
/* net.c * * This file is part of ftp. * * * 01/25/96 Initial Release	Michael Temari, <temari@ix.netcom.com> */#include <sys/types.h>#include <sys/ioctl.h>#include <sys/wait.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <signal.h>#include <errno.h>#include <net/netlib.h>#include <net/hton.h>#include <net/gen/netdb.h>#include <net/gen/in.h>#include <net/gen/inet.h>#include <net/gen/tcp.h>#include <net/gen/tcp_io.h>#include "ftp.h"#include "file.h"#include "net.h"_PROTOTYPE(void donothing, (int sig));static int ftpcomm_fd;static ipaddr_t myip;static ipaddr_t hostip;static char host[256];static int lpid;void NETinit(){int s;char *tcp_device;int tcp_fd;nwio_tcpconf_t nwio_tcpconf;   /* All this just to get our ip address */   if((tcp_device = getenv("TCP_DEVICE")) == (char *)NULL)	tcp_device = TCP_DEVICE;   tcp_fd = open(tcp_device, O_RDWR);   if(tcp_fd < 0) {	perror("ftp: Could not open tcp_device");	exit(-1);   }   s = ioctl(tcp_fd, NWIOGTCPCONF, &nwio_tcpconf);   if(s < 0) {	perror("ftp: Could not get tcp configuration");	exit(-1);   }   myip = nwio_tcpconf.nwtc_locaddr;   close(tcp_fd);}int DOopen(){nwio_tcpconf_t tcpconf;nwio_tcpcl_t tcpcopt;char *tcp_device;tcpport_t port;int s;struct hostent *hp;struct servent *servent;   if(linkopen) {	printf("Use \"CLOSE\" to close the connection first.\n");	return(0);   }   if(cmdargc < 2)	readline("Host: ", host, sizeof(host));   else	strncpy(host, cmdargv[1], sizeof(host));   if((servent = getservbyname("ftp", "tcp")) == (struct servent *)NULL) {   	fprintf(stderr, "ftp: Could not find ftp tcp service\n");   	return(-1);   }   port = (tcpport_t)servent->s_port;   hp = gethostbyname(host);   if (hp == (struct hostent *)NULL) {	hostip = (ipaddr_t)0;	printf("Unresolved host %s\n", host);	return(0);   } else	memcpy((char *) &hostip, (char *) hp->h_addr, hp->h_length);   /* This HACK allows the server to establish data connections correctly */   /* when using the loopback device to talk to ourselves */   if(hostip == inet_addr("127.0.0.1"))	hostip = myip;   if((tcp_device = getenv("TCP_DEVICE")) == NULL)	tcp_device = "/dev/tcp";   if((ftpcomm_fd = open(tcp_device, O_RDWR)) < 0) {	perror("ftp: open error on tcp device");	return(-1);   }   tcpconf.nwtc_flags = NWTC_LP_SEL | NWTC_SET_RA | NWTC_SET_RP;   tcpconf.nwtc_remaddr = hostip;   tcpconf.nwtc_remport = port;   s = ioctl(ftpcomm_fd, NWIOSTCPCONF, &tcpconf);   if(s < 0) {	perror("ftp: ioctl error on NWIOSTCPCONF");	close(ftpcomm_fd);	return(s);   }   tcpcopt.nwtcl_flags = 0;   s = ioctl(ftpcomm_fd, NWIOTCPCONN, &tcpcopt);   if(s < 0) {	perror("ftp: ioctl error on NWIOTCPCONN");	close(ftpcomm_fd);	return(s);   }   s = ioctl(ftpcomm_fd, NWIOGTCPCONF, &tcpconf);   if(s < 0) {	perror("ftp: ioctl error on NWIOGTCPCONF");	close(ftpcomm_fd);	return(s);   }   fpcommin  = fdopen(ftpcomm_fd, "r");   fpcommout = fdopen(ftpcomm_fd, "w");   s = DOgetreply();   if(s < 0) {	fclose(fpcommin);	fclose(fpcommout);	close(ftpcomm_fd);	return(s);   }   if(s != 220) {	fclose(fpcommin);	fclose(fpcommout);	close(ftpcomm_fd);	return(0);   }   linkopen = 1;   return(s);}int DOclose(){   if(!linkopen) {	printf("You can't close a connection that isn't open.\n");	return(0);   }   fclose(fpcommin);   fclose(fpcommout);   close(ftpcomm_fd);   linkopen = 0;   loggedin = 0;   return(0);}int DOquit(){int s;   if(linkopen) {	s = DOcommand("QUIT", "");	s = DOclose();   }   printf("FTP done.\n");   exit(0);}void donothing(sig)int sig;{}int DOdata(datacom, file, direction, fd)char *datacom;char *file;int direction;  /* RETR or STOR */int fd;{nwio_tcpconf_t tcpconf;nwio_tcpcl_t tcplopt, tcpcopt;char *tcp_device;int ftpdata_fd;char *buff;ipaddr_t ripaddr;tcpport_t rport;static tcpport_t lport = HTONS(0xF000);int s;int i;int cs;int pfd[2];char dummy;char port[32];   ripaddr = hostip;   rport = HTONS(20);   /* here we set up a connection to listen on if not passive mode */   /* otherwise we use this to connect for passive mode */   if((tcp_device = getenv("TCP_DEVICE")) == NULL)	tcp_device = "/dev/tcp";   if((ftpdata_fd = open(tcp_device, O_RDWR)) < 0) {	perror("ftp: open error on tcp device");	return(-1);   }   if(passive) {	s = DOcommand("PASV", "");	if(s != 227) {		close(ftpdata_fd);		return(s);	}	/* decode host and port */	buff = reply;	while(*buff && (*buff != '(')) buff++;	buff++;	ripaddr = (ipaddr_t)0;	for(i = 0; i < 4; i++) {		ripaddr = (ripaddr << 8) + (ipaddr_t)atoi(buff);		if((buff = strchr(buff, ',')) == (char *)0) {			printf("Could not parse PASV reply\n");			return(-1);		}		buff++;	}	rport = (tcpport_t)atoi(buff);	if((buff = strchr(buff, ',')) == (char *)0) {		printf("Could not parse PASV reply\n");		return(-1);	}	buff++;	rport = (rport << 8) + (tcpport_t)atoi(buff);	ripaddr = ntohl(ripaddr);	rport = ntohs(rport);   }   for (;;) {	tcpconf.nwtc_flags = NWTC_SET_RA | NWTC_SET_RP;	if (passive || ntohs(lport) >= 0xF000) {		tcpconf.nwtc_flags |= NWTC_LP_SEL;	} else {		/* For no good reason Sun hosts don't like it if they have to		 * connect to the same port twice in a short time...		 */		lport = htons(ntohs(lport) + 1);		tcpconf.nwtc_flags |= NWTC_LP_SET;		tcpconf.nwtc_locport = lport;	}	tcpconf.nwtc_remaddr = ripaddr;	tcpconf.nwtc_remport = rport;	s = ioctl(ftpdata_fd, NWIOSTCPCONF, &tcpconf);	if(s < 0) {		if (errno == EADDRINUSE) continue;		perror("ftp: ioctl error on NWIOSTCPCONF");		close(ftpdata_fd);		return(s);	}	break;   }   s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf);   if(s < 0) {	perror("ftp: ioctl error on NWIOGTCPCONF");	close(ftpdata_fd);	return(s);   }   lport = tcpconf.nwtc_locport;   if(passive) {	tcplopt.nwtcl_flags = 0;	s = ioctl(ftpdata_fd, NWIOTCPCONN, &tcpcopt);	if(s < 0) {		perror("ftp: error on ioctl NWIOTCPCONN");		close(ftpdata_fd);		return(0);	}	s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf);	if(s < 0) {		perror("ftp: error on ioctl NWIOGTCPCONF");		close(ftpdata_fd);		return(0);	}   } else {	tcplopt.nwtcl_flags = 0;	if (pipe(pfd) < 0) {		perror("ftp: could not create a pipe");		return(s);	}	lpid = fork();	if(lpid < 0) {		perror("ftp: could not fork listener");		close(ftpdata_fd);		close(pfd[0]);		close(pfd[1]);		return(s);	} else if(lpid == 0) {		close(pfd[0]);		signal(SIGALRM, donothing);		alarm(15);		close(pfd[1]);		s = ioctl(ftpdata_fd, NWIOTCPLISTEN, &tcplopt);		alarm(0);		if(s < 0)			if(errno == EINTR)				exit(1);	/* timed out */			else				exit(-1);	/* error */		else			exit(0);		/* connection made */	}	/* Wait for the pipe to close, then the listener is ready (almost). */	close(pfd[1]);	(void) read(pfd[0], &dummy, 1);	close(pfd[0]);	while(1) {		signal(SIGALRM, donothing);		alarm(1);		s = ioctl(ftpdata_fd, NWIOGTCPCONF, &tcpconf);		alarm(0);		if(s == -1) break;	}   }#define hiword(x)       ((u16_t)((x) >> 16))#define loword(x)       ((u16_t)(x & 0xffff)) #define hibyte(x)       (((x) >> 8) & 0xff)#define lobyte(x)       ((x) & 0xff)   if(!passive) {	sprintf(port, "%u,%u,%u,%u,%u,%u",		hibyte(hiword(ntohl(myip))), lobyte(hiword(ntohl(myip))),		hibyte(loword(ntohl(myip))), lobyte(loword(ntohl(myip))),		hibyte(ntohs(lport)), lobyte(ntohs(lport)));	s = DOcommand("PORT", port);	if(s != 200) {		close(ftpdata_fd);		kill(lpid, SIGKILL);		return(s);	}   }   s = DOcommand(datacom, file);   if(s == 125 || s == 150) {	if(!passive) {		while(1) {			s = wait(&cs);			if(s < 0 || s == lpid)				break;		}		if(s < 0) {			perror("wait error:");			close(ftpdata_fd);			kill(lpid, SIGKILL);			return(s);		}		if((cs & 0x00ff)) {			printf("Child listener failed %04x\n", cs);			close(ftpdata_fd);			return(-1);		}		cs = (cs >> 8) & 0x00ff;		if(cs == 1) {			printf("Child listener timed out\n");			return(DOgetreply());		} else if(cs) {			printf("Child listener returned %02x\n", cs);			close(ftpdata_fd);			return(-1);		}	}	switch(direction) {		case RETR:			s = recvfile(fd, ftpdata_fd);			break;		case STOR:			s = sendfile(fd, ftpdata_fd);			break;	}	close(ftpdata_fd);	s = DOgetreply();   } else {	if(!passive)		kill(lpid, SIGKILL);	close(ftpdata_fd);   }   return(s);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -