/* webget ehg@research.bell-labs.com 6 May 1998 */ /* Unix: cc -o webget webget.c */ /* Windows: cl -DWIN32 webget.c wsock32.lib */ #include #include #include #include #include #include #ifdef WIN32 #include #define Recv(a,b,c) recv(a,b,c,0) #define Send(a,b,c) send(a,b,c,0) #define INDEX_HTML "index.htm" #else #include #include #include #include u_long inet_addr(char*); typedef int SOCKET; #define Recv(a,b,c) read(a,b,c) #define Send(a,b,c) write(a,b,c) #define INDEX_HTML "index.html" #endif #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff #endif #ifndef O_BINARY #define O_BINARY 0 #endif void Error(char*); int active_socklib; void begin_socklib(void) { #ifdef WIN32 WSADATA w; if(WSAStartup(MAKEWORD(2,2),&w)) Error("couldn't start WinSock"); #endif active_socklib = 1; } void end_socklib(void) { #ifdef WIN32 if(active_socklib) WSACleanup(); #endif } SOCKET connectTCP(char *host, char *service) { struct hostent *phe; struct servent *pse; struct sockaddr_in sin; SOCKET s; memset((void*)&sin,0,sizeof(sin)); sin.sin_family = AF_INET; if( pse = getservbyname(service,"tcp") ) sin.sin_port = pse->s_port; else if( (sin.sin_port = htons((u_short)atoi(service)))==0 ) Error("unknown service"); if( phe = gethostbyname(host) ) memcpy((void*)&sin.sin_addr,(void*)phe->h_addr,phe->h_length); else if( (sin.sin_addr.s_addr = inet_addr(host))==INADDR_NONE ) Error("unknown host"); if( (s = socket(PF_INET,SOCK_STREAM,0))<0 ) Error("can't create socket"); if(connect(s,(struct sockaddr*)&sin,sizeof(sin))<0) Error("can't connect"); return(s); } void main(int argc, char **argv) { char *host, *file, *basename, buf[4096]; int c, n, local; SOCKET s; int hdr = 1; /* in HTTP header */ int sol = 1; /* at start of header line */ if( (argc!=2 && argc!=3) || strncmp(argv[1],"http://",7)!=0) Error("usage: webget http://www.foo.com/bar.gz [localname]"); host = argv[1]+7; file = strchr(host,'/'); if(!file) Error("missing / after hostname"); if(file-host>500) Error("hostname implausibly long"); if(argc == 3){ basename = argv[2]; }else{ basename = strrchr(file,'/')+1; if(basename[0]==0) basename = INDEX_HTML; } if((local = open(basename,O_WRONLY|O_CREAT|O_TRUNC|O_BINARY,0666))<0) Error("can't open local file for writing"); begin_socklib(); sprintf(buf,"%.*s",file-host,host); s = connectTCP(buf,"80"); n = sprintf(buf,"GET %s HTTP/1.0\n\n",file); n = strlen(buf); /* needed on SunOS 4.1.3 */ if(n!=Send(s,buf,n)) Error("write error on socket"); while(Recv(s,buf,1)==1){ if((c = buf[0])=='\n'){ if(sol) break; /* last byte of header */ sol = 1; }else if(c!='\r'){ sol = 0; } } while((n = Recv(s,buf,sizeof(buf)))>0) write(local,buf,n); end_socklib(); exit(0); } void Error(char *mess) { fprintf(stderr,"%s\n",mess); end_socklib(); exit(1); }