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

📄 uri.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 3 页
字号:
*	Parameters :
*		token * in ;	token
*
*	Description : Function useful in debugging for printing a token.
*		Compiled out with DBGONLY macro. 
*
*	Return : void ;
*
*	Note :
************************************************************************/
DBGONLY( void print_token( token * in ) {
         int i = 0;
         printf( "Token Size : %d\n\'", in->size );
         for( i = 0; i < in->size; i++ ) {
         putchar( in->buff[i] );}
         putchar( '\'' ); putchar( '\n' );}

 )

/************************************************************************
*	Function :	token_string_casecmp
*
*	Parameters :
*		token * in1 ;	Token object whose buffer is to be compared
*		char * in2 ;	string of characters to compare with
*
*	Description :	Compares buffer in the token object with the buffer 
*		in in2
*
*	Return : int ;
*		< 0 string1 less than string2 
*		0 string1 identical to string2 
*		> 0 string1 greater than string2 
*
*	Note :
************************************************************************/
    int token_string_casecmp( token * in1,
                              char *in2 ) {
    int in2_length = strlen( in2 );

    if( in1->size != in2_length )
        return 1;
    else
        return strncasecmp( in1->buff, in2, in1->size );
}

/************************************************************************
*	Function :	token_string_cmp
*
*	Parameters :
*		token * in1 ;	Token object whose buffer is to be compared
*		char * in2 ;	string of characters to compare with
*
*	Description : Compares a null terminated string to a token (exact)	
*
*	Return : int ;
*		< 0 string1 less than string2 
*		0 string1 identical to string2 
*		> 0 string1 greater than string2 
*
*	Note :
************************************************************************/
int
token_string_cmp( token * in1,
                  char *in2 )
{
    int in2_length = strlen( in2 );

    if( in1->size != in2_length )
        return 1;
    else
        return strncmp( in1->buff, in2, in1->size );
}

/************************************************************************
*	Function :	token_cmp
*
*	Parameters :
*		token *in1 ;	First token object whose buffer is to be compared
*		token *in2 ;	Second token object used for the comparison
*
*	Description : Compares two tokens	
*
*	Return : int ;
*		< 0 string1 less than string2 
*		0 string1 identical to string2 
*		> 0 string1 greater than string2 
*
*	Note :
************************************************************************/
int
token_cmp( token * in1,
           token * in2 )
{
    if( in1->size != in2->size )
        return 1;
    else
        return memcmp( in1->buff, in2->buff, in1->size );
}

/************************************************************************
*	Function :	parse_port
*
*	Parameters :
*		int max ;	sets a maximum limit
*		char * port ;	port to be parsed.
*		unsigned short * out ;	 out parameter where the port is parsed 
*							and converted into network format
*
*	Description : parses a port (i.e. '4000') and converts it into a 
*		network ordered unsigned short int.
*
*	Return : int ;
*
*	Note :
************************************************************************/
int
parse_port( int max,
            char *port,
            unsigned short *out )
{

    char *finger = port; // current location
    char *max_ptr = finger + max;
    unsigned short temp = 0; // area where port string is converted to integer

    while( ( finger < max_ptr ) && ( isdigit( *finger ) ) ) {
        temp = temp * 10;
        temp += ( *finger ) - '0';
        finger++;
    }

    *out = htons( temp );
    return finger - port; // return the number of bytes parsed
}

#ifdef _WIN32
void
copy_port_name(int max,
		 char *inport,
		 char *outport )
{
    char *finger = inport; // current location
    char *max_ptr = finger + max;

    while( ( finger < max_ptr ) && ( isdigit( *finger ) ) ) {
		*outport = *finger;
		outport++;
        finger++;
    }
	*outport = 0;

}
#endif

/************************************************************************
*	Function :	parse_hostport
*
*	Parameters :
*		char *in ;	string of characters representing host and port
*		int max ;	sets a maximum limit
*		hostport_type *out ;	out parameter where the host and port
*					are represented as an internet address
*
*	Description : Parses a string representing a host and port
*		(e.g. "127.127.0.1:80" or "localhost") and fills out a 
*		hostport_type struct with internet address and a token 
*		representing the full host and port.  uses gethostbyname.
*
*	Return : int ;
*
*	Note :
************************************************************************/
int
parse_hostport( char *in,
                int max,
                hostport_type * out )
{
#define BUFFER_SIZE 8192

    int i = 0;
    int begin_port;
    int hostport_size = 0;
    int host_size = 0;

    struct hostent *h = NULL;
    int errcode = 0;
    char *temp_host_name = NULL;
    int last_dot = -1;
#ifdef _WIN32
	struct addrinfo *addrInfoPtr;
	struct sockaddr_in * saiPtr;
	char port_name[32];
	unsigned long temp;
#endif

    out->text.size = 0;
    out->text.buff = NULL;

	out->IPv4address.sin_port = htons( 80 );    //default port is 80
    memset( &out->IPv4address.sin_zero, 0, 8 );
#ifdef _WIN32
	sprintf(port_name, "%d", 80); //default port is 80
#endif

	// look at the input string, up to the first ":" or "/"
	// and find the last "."
    while( ( i < max ) && ( in[i] != ':' ) && ( in[i] != '/' )
           && ( ( isalnum( in[i] ) ) || ( in[i] == '.' )
                || ( in[i] == '-' ) ) ) {
        i++;
        if( in[i] == '.' ) {
            last_dot = i;
        }
    }

    // this is where in the in string the host name ends
    host_size = i;

	// what is hostport_size?
    if( ( i < max ) && ( in[i] == ':' ) ) {
	// there is a port in the address
        begin_port = i + 1;
        //convert port
        if( !( hostport_size = parse_port( max - begin_port,
                                           &in[begin_port],
                                           &out->IPv4address.sin_port ) ) )
        {
            return UPNP_E_INVALID_URL;
        }
        hostport_size += begin_port; // hostport_size is the offset past the port
#ifdef _WIN32
		copy_port_name(max - begin_port, &in[begin_port], port_name);
#endif
    } else
        hostport_size = host_size; // hostport_size is the offset past the port

    //convert to temporary null terminated string
    temp_host_name = ( char * )malloc( host_size + 1 );

    if( temp_host_name == NULL )
        return UPNP_E_OUTOF_MEMORY;

    memcpy( temp_host_name, in, host_size );
    temp_host_name[host_size] = '\0';

    // now temp_host_name has the whole host name, less the port if there is one

    //check to see if host name is an ipv4 address
    if( ( last_dot != -1 ) && ( last_dot + 1 < host_size )
        && ( isdigit( temp_host_name[last_dot + 1] ) ) ) {
	// has a ., so it is a dotted quad
        //must be ipv4 address

#ifndef _WIN32
        errcode = inet_pton( AF_INET,
                             temp_host_name, &out->IPv4address.sin_addr );
        if( errcode == 1 ) {
            out->IPv4address.sin_family = AF_INET;
        } else {
            out->IPv4address.sin_addr.s_addr = 0;
            out->IPv4address.sin_family = AF_INET;
            free( temp_host_name );
            temp_host_name = NULL;
            return UPNP_E_INVALID_URL;
        }
#else
	saiPtr = (struct sockaddr_in *) &(out->IPv4address);
	saiPtr->sin_port = htons(atoi(port_name));
	temp = inet_addr(temp_host_name);
	saiPtr->sin_addr.S_un.S_addr = inet_addr(temp_host_name);
	out->IPv4address.sin_family = AF_INET;
#endif
    } else {
	// it is not ipv4
        int errCode = 0;

        //call gethostbyname_r (reentrant form of gethostbyname)
#ifdef _WIN32
        errcode = getaddrinfo( temp_host_name, port_name, 0, &addrInfoPtr);

		if (errCode == 0 ) {
			if ((addrInfoPtr->ai_family == PF_INET) && ( addrInfoPtr->ai_addrlen == 4 )) {
				out->IPv4address.sin_addr = *((struct in_addr*)(addrInfoPtr->ai_addr));
				out->IPv4address.sin_family = AF_INET;
			}
        } else {
            out->IPv4address.sin_addr.s_addr = 0;
            out->IPv4address.sin_family = AF_INET;
            free( temp_host_name );
            temp_host_name = NULL;
            return UPNP_E_INVALID_URL;
        }
		freeaddrinfo(addrInfoPtr);
#else
        errcode = gethostbyname_r( temp_host_name,
                                   &h_buf,
                                   temp_hostbyname_buff,
                                   BUFFER_SIZE, &h, &errcode );

        if( errcode == 0 ) {
            if( h ) {
                if( ( h->h_addrtype == AF_INET ) && ( h->h_length == 4 ) ) {
                    out->IPv4address.sin_addr =
                        ( *( struct in_addr * )h->h_addr );
                    out->IPv4address.sin_family = AF_INET;

                }
            }
        } else {
            out->IPv4address.sin_addr.s_addr = 0;
            out->IPv4address.sin_family = AF_INET;
            free( temp_host_name );
            temp_host_name = NULL;
            return UPNP_E_INVALID_URL;
        }
#endif
    }

    if( temp_host_name ) {
        free( temp_host_name );
        temp_host_name = NULL;
    }

    out->text.size = hostport_size;
    out->text.buff = in;
    return hostport_size;

}

/************************************************************************
*	Function :	parse_scheme
*
*	Parameters :
*		char * in ;	string of characters representing a scheme
*		int max ;	maximum number of characters
*		token * out ;	output parameter whose buffer is filled in with 
*					the scheme
*
*	Description : parses a uri scheme starting at in[0] as defined in 
*		http://www.ietf.org/rfc/rfc2396.txt (RFC explaining URIs)
*		(e.g. "http:" -> scheme= "http"). 
*		Note, string MUST include ':' within the max charcters
*
*	Return : int ;
*
*	Note :
************************************************************************/
int
parse_scheme( char *in,
              int max,
              token * out )
{
    int i = 0;

    out->size = 0;
    out->buff = NULL;

    if( ( max == 0 ) || ( !isalpha( in[0] ) ) )
        return FALSE;

    i++;
    while( ( i < max ) && ( in[i] != ':' ) ) {

        if( !( isalnum( in[i] ) || ( in[i] == '+' ) || ( in[i] == '-' )
               || ( in[i] == '.' ) ) )
            return FALSE;

        i++;
    }
    if( i < max ) {
        out->size = i;
        out->buff = &in[0];
        return i;
    }

⌨️ 快捷键说明

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