/* wwwcli.c */ /* This source is to be compiled by UNIX gcc. */ /* wwwcli URL : Directly from server wwwcli URL -h : Don't output header wwwcli URL -c : "Content-Type:" header wwwcli URL -H : "HEAD" method */ #include #include #include #include #include #include #include #include #include #include #define WWW_PORT 80 #define PROG_DNS "nslookup" /* "/export/home1/johnkoji/bin/dns" */ /* "/usr/sbin/nslookup" */ #define HEADER_TYPE "Content-Type:" void Err_Exit( char *x ) { fputs("client- ", stderr ) ; perror( x ) ; exit(1) ; } void Err( char *x ) { fputs("client- ", stderr ) ; perror( x ) ; } /* From "130.54.54.194" IP address string, set 4-byte sin_addr */ int set_ip_addr( u_char *sin_addr, char *ip_text ) { u_int i, n_ip[4] ; if( sscanf( ip_text,"%u.%u.%u.%u", n_ip, n_ip+1, n_ip+2, n_ip+3 )!= 4 ) return -1 ; for( i=0 ; i<4 ; i++ ) sin_addr[i] = n_ip[i] & 0xff ; return 0 ; /* OK */ } /* From "www.kyoto-u.ac.jp" domain name address string, get IP address by 'nslookup' command and set 4-byte sin_addr */ int nslookup( u_char *sin_addr, char *dn_text ) { u_int i, n_ip[4] ; char line_buf[128] ; FILE *fp ; #ifdef DNS_TMP_FILE char tmp_fn[24] ; sprintf( tmp_fn,"/tmp/nslookup%04x.tmp", getpid() ) ; sprintf( line_buf,"%s \"%s.\" > %s", PROG_DNS, dn_text, tmp_fn ) ; if( system( line_buf )!= 0 ) return -1 ; if( (fp = fopen( tmp_fn,"rt"))== NULL ) return -2 ; #else sprintf( line_buf,"%s \"%s.\"", PROG_DNS, dn_text ) ; if( (fp = popen( line_buf,"r"))== NULL ) return -1 ; #endif while( fgets( line_buf, 128, fp )!= NULL ) { if( strncmp( line_buf,"Name:", 5 )== 0 && fgets( line_buf, 128, fp )!= NULL && ( strncmp( line_buf,"Address:", 8 )== 0 || strncmp( line_buf,"Addresses:", 10 )== 0 )&& sscanf(line_buf,"%*s %u.%u.%u.%u",n_ip,n_ip+1,n_ip+2,n_ip+3)==4 ) { for( i=0 ; i<4 ; i++ ) sin_addr[i] = n_ip[i] & 0xff ; #ifdef DNS_TMP_FILE fclose( fp ) ; remove( tmp_fn ) ; #else pclose( fp ) ; #endif return 0 ; /* OK */ } } #ifdef DNS_TMP_FILE fclose( fp ) ; remove( tmp_fn ) ; #else pclose( fp ) ; #endif return -3 ; } FILE *open_http( char *url, char *mode, struct sockaddr_in *remote_s ) { int i, socket_id, serv_port=WWW_PORT ; #if defined(GETHOSTBYNAME) struct hostent *shost ; #endif char hostname[128], send_message[1024] ; char *filename, *file_mode ; u_char *cp ; FILE *fp ; /* Get hostname/filename/port No. from URL */ if( strncmp( url,"http://",7 )== 0 ) cp = url+7 ; else cp = url ; i = strcspn( cp,"/" ) ; strncpy( hostname, cp, i ) ; if( (filename = strchr( cp,'/'))==NULL ) { fprintf( stderr,"URL Error:\n%s\n", url ) ; return NULL ; } hostname[i] ='\0' ; if( (cp = strrchr( hostname,':'))!= NULL && sscanf( cp+1,"%u", &i )==1 ) { serv_port = i ; *cp = '\0' ; } /* Create a socket */ if( (socket_id = socket(PF_INET, SOCK_STREAM, 0)) <0 ) { Err("socket"); return NULL ; } bzero( (char *)remote_s, sizeof( struct sockaddr_in ) ) ; remote_s->sin_family = PF_INET ; remote_s->sin_port = htons( serv_port ) ; /* Set IP address */ cp = (char *)&(remote_s->sin_addr) ; if( set_ip_addr( cp, hostname )!= 0 && nslookup( cp, hostname )!= 0 ) { fprintf( stderr,"Unknown host: %s\n", hostname ) ; return NULL ; } if( connect( socket_id, remote_s, sizeof( struct sockaddr_in ) ) != 0 ) { Err("connect") ; return NULL ; } /* HTTP command */ if( (file_mode = strdup( mode ))== NULL ){ Err("strdup") ; return NULL ; } if( (cp = strchr( file_mode,'H'))!= NULL ){ sprintf( send_message,"HEAD %s HTTP/1.0\nUser-Agent: WWW Client(UNIX)\n\n", filename ) ; *cp = '\0' ; }else{ sprintf( send_message,"GET %s HTTP/1.0\nUser-Agent: WWW Client(UNIX)\n\n", filename ) ; } send( socket_id, send_message, strlen(send_message), 0 ); if( (fp = fdopen( socket_id, file_mode ))== NULL ) { Err("fdopen") ; free( file_mode ) ; return NULL; } free( file_mode ) ; return fp ; } #define C_BUF_SIZE 512 int main( int argc, char **argv ) { char c_buf[C_BUF_SIZE] ; char *url, *file_mode = "rb" ; int i, mode = 255 ; FILE *fp ; struct sockaddr_in socket_name ; if( argc == 1 ) { fprintf( stderr,"Usage: \"%s URL\"\n", argv[0] ) ; exit(1) ; } url = argv[1] ; if( url[0] == '/') /* PATH_INFO */ url ++ ; if( argc > 2 ) { if( strchr( argv[2],'c')!= NULL ){ /* "Content-Type:" only */ mode = 1 ; }else if( strchr( argv[2],'h')!= NULL ){ /* No header */ mode = 0 ; }else if( strchr( argv[2],'H')!= NULL ){ /* "HEAD" method */ mode = 255 ; file_mode = "rbH" ; }else{ mode = 255 ; } } if( (fp = open_http( url, file_mode, &socket_name ))== NULL ) exit(1) ; while( fgets( c_buf, C_BUF_SIZE, fp )!= NULL && strlen( c_buf ) > 2 ) { if( mode == 1 && strncmp( c_buf,HEADER_TYPE,strlen(HEADER_TYPE) )== 0 ) fputs( c_buf, stdout ) ; /* Output "Content-Type:" */ else if( mode == 255 ) fputs( c_buf, stdout ) ; } if( mode != 0 ) /* Output "\n" */ fputs( c_buf, stdout ) ; while( (i = fread( c_buf, 1, C_BUF_SIZE, fp )) > 0 ) fwrite( c_buf, 1, i, stdout ) ; fclose( fp ) ; return 0 ; }