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

📄 gena_device.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 5 页
字号:
    int headers_size;
    int return_code = GENA_SUCCESS;
    char *UDN_copy = NULL;
    char *servId_copy = NULL;
    int *reference_count = NULL;
    struct Handle_Info *handle_info;
    ThreadPoolJob job;

    subscription *finger = NULL;

    notify_thread_struct *thread_struct = NULL;

    service_info *service = NULL;

    reference_count = ( int * )malloc( sizeof( int ) );

    if( reference_count == NULL ) {
        return UPNP_E_OUTOF_MEMORY;
    }

    ( *reference_count = 0 );

    UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );

    if( UDN_copy == NULL ) {
        free( reference_count );
        return UPNP_E_OUTOF_MEMORY;
    }

    servId_copy = ( char * )malloc( strlen( servId ) + 1 );
    if( servId_copy == NULL ) {
        free( UDN_copy );
        free( reference_count );
        return UPNP_E_OUTOF_MEMORY;
    }

    strcpy( UDN_copy, UDN );
    strcpy( servId_copy, servId );

    if( ( return_code = GeneratePropertySet( VarNames, VarValues,
                                             var_count,
                                             &propertySet ) ) !=
        XML_SUCCESS ) {
        free( UDN_copy );
        free( servId_copy );
        free( reference_count );
        return return_code;
    }

    headers_size = strlen( "CONTENT-TYPE text/xml\r\n" ) +
        strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
        strlen( "NT: upnp:event\r\n" ) +
        strlen( "NTS: upnp:propchange\r\n" ) + 1;

    headers = ( char * )malloc( headers_size );
    if( headers == NULL ) {
        free( UDN_copy );
        free( servId_copy );
        ixmlFreeDOMString( propertySet );
        free( reference_count );
        return UPNP_E_OUTOF_MEMORY;
    }
    //changed to add null terminator at end of content
    //content length = (length in bytes of property set) + null char
    sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\nNT:"
             " upnp:event\r\nNTS: upnp:propchange\r\n",
             strlen( propertySet ) + 1 );

    HandleLock(  );

    if( GetHandleInfo( device_handle, &handle_info ) != HND_DEVICE ) {
        return_code = GENA_E_BAD_HANDLE;
    } else {
        if( ( service = FindServiceId( &handle_info->ServiceTable,
                                       servId, UDN ) ) != NULL ) {
            finger = GetFirstSubscription( service );

            while( finger ) {
                thread_struct =
                    ( notify_thread_struct * )
                    malloc( sizeof( notify_thread_struct ) );
                if( thread_struct == NULL ) {
                    return_code = UPNP_E_OUTOF_MEMORY;
                    break;
                }
                ( *reference_count )++;
                thread_struct->reference_count = reference_count;
                thread_struct->UDN = UDN_copy;
                thread_struct->servId = servId_copy;
                thread_struct->headers = headers;
                thread_struct->propertySet = propertySet;
                strcpy( thread_struct->sid, finger->sid );
                thread_struct->eventKey = finger->eventKey++;
                thread_struct->device_handle = device_handle;
                //if overflow, wrap to 1
                if( finger->eventKey < 0 ) {
                    finger->eventKey = 1;
                }

                TPJobInit( &job, ( start_routine ) genaNotifyThread,
                           thread_struct );
                TPJobSetFreeFunction( &job,
                                      ( free_routine )
                                      free_notify_struct );
                TPJobSetPriority( &job, MED_PRIORITY );

                if( ( return_code =
                      ThreadPoolAdd( &gSendThreadPool, &job, NULL ) )
                    != 0 ) {
                    if( return_code == EOUTOFMEM ) {
                        return_code = UPNP_E_OUTOF_MEMORY;
                        break;
                    }
                }

                finger = GetNextSubscription( service, finger );

            }
        } else {
            return_code = GENA_E_BAD_SERVICE;
        }
    }

    if( ( *reference_count ) == 0 ) {
        free( reference_count );
        free( headers );
        ixmlFreeDOMString( propertySet );
        free( UDN_copy );
        free( servId_copy );
    }
    HandleUnlock(  );

    return return_code;
}

/****************************************************************************
*	Function :	genaNotifyBroadcast
*
*	Parameters :
*		IN UpnpDevice_Handle device_handle : Device handle
*		IN char *UDN :	Device udn
*		IN char *servId :	Service ID
*	    IN char **VarNames : array of varible names
*	    IN char **VarValues :	array of variable values
*		IN int var_count	 :	number of variables
*
*	Description : 	This function broadcasts a notification 
*
*	Return :	int
*
****************************************************************************/
int
genaNotifyBroadcast( IN UpnpDevice_Handle device_handle,
               IN char *UDN,
               IN char *servId,
               IN char **VarNames,
               IN char **VarValues,
               IN int var_count )
{
    char *headers = NULL;
    char *propertySet = NULL;
    int headers_size;
    int return_code = GENA_SUCCESS;
    char *UDN_copy = NULL;
    int *reference_count = NULL;
//    struct Handle_Info *handle_info;
//    ThreadPoolJob job;

    notify_thread_struct *thread_struct = NULL;

    reference_count = ( int * )malloc( sizeof( int ) );

    if( reference_count == NULL ) {
        return UPNP_E_OUTOF_MEMORY;
    }

    ( *reference_count = 0 );

    UDN_copy = ( char * )malloc( strlen( UDN ) + 1 );

    if( UDN_copy == NULL ) {
        free( reference_count );
        return UPNP_E_OUTOF_MEMORY;
    }

    strcpy( UDN_copy, UDN );

    if( ( return_code = GeneratePropertySet( VarNames, VarValues,
                                             var_count,
                                             &propertySet ) ) !=
        XML_SUCCESS ) {
        free( UDN_copy );
        free( reference_count );
        return return_code;
    }

    headers_size = strlen( "CONTENT-TYPE text/xml\r\n" ) +
        strlen( "CONTENT-LENGTH: \r\n" ) + MAX_CONTENT_LENGTH +
        strlen( "NT: \r\n" ) + strlen(UDN) +
        strlen( "NTS: \r\n" ) + strlen(servId) + 1;

    headers = ( char * )malloc( headers_size );
    if( headers == NULL ) {
        free( UDN_copy );
        ixmlFreeDOMString( propertySet );
        free( reference_count );
        return UPNP_E_OUTOF_MEMORY;
    }
    //changed to add null terminator at end of content
    //content length = (length in bytes of property set) + null char
    sprintf( headers, "CONTENT-TYPE: text/xml\r\nCONTENT-LENGTH: %d\r\nNT:"
             " %s\r\nNTS: %s\r\n",
             strlen( propertySet ) + 1, UDN, servId );

    HandleLock(  );

    thread_struct =
	( notify_thread_struct * )
	malloc( sizeof( notify_thread_struct ) );
    if( thread_struct == NULL ) {
	return_code = UPNP_E_OUTOF_MEMORY;
    }
    thread_struct->reference_count = reference_count;
    thread_struct->UDN = UDN_copy;
    thread_struct->headers = headers;
    thread_struct->propertySet = propertySet;

/*
    TPJobInit( &job, ( start_routine ) genaNotifyBroadcastThread,
	       thread_struct );
    TPJobSetFreeFunction( &job,
			  ( free_routine )
			  free_notifyMulticast_struct );
    TPJobSetPriority( &job, MED_PRIORITY );


    if( ( return_code =
	  ThreadPoolAdd( &gSendThreadPool, &job, NULL ) )
	!= 0 ) {
	if( return_code == EOUTOFMEM ) {
	    return_code = UPNP_E_OUTOF_MEMORY;
	}
    } else {
*/
    genaNotifyBroadcastThread( thread_struct );
    *reference_count = 1;
    return_code = UPNP_E_SUCCESS;
//    }
/*
    if( ( *reference_count ) == 0 ) {
	*/
        free( reference_count );
        free( headers );
        ixmlFreeDOMString( propertySet );
        free( UDN_copy );
		/*
    }
*/
    HandleUnlock(  );

    return return_code;
}

/****************************************************************************
*	Function :	respond_ok
*
*	Parameters :
*			IN SOCKINFO *info :	socket connection of request
*			IN int time_out : accepted duration
*			IN subscription *sub : accepted subscription
*			IN http_message_t* request : http request
*
*	Description : Function to return OK message in the case 
*		of a subscription request.
*
*	Return :	static int
*		returns UPNP_E_SUCCESS if successful else returns appropriate error
*	Note :
****************************************************************************/
static int
respond_ok( IN SOCKINFO * info,
            IN int time_out,
            IN subscription * sub,
            IN http_message_t * request )
{
    int major,
      minor;
    membuffer response;
    int return_code;
    char timeout_str[100];
    int upnp_timeout = UPNP_TIMEOUT;

    http_CalcResponseVersion( request->major_version,
                              request->minor_version, &major, &minor );

    if( time_out >= 0 ) {
        sprintf( timeout_str, "TIMEOUT: Second-%d", time_out );
    } else {
        strcpy( timeout_str, "TIMEOUT: Second-infinite" );
    }

    membuffer_init( &response );
    response.size_inc = 30;
    if( http_MakeMessage( &response, major, minor,
                          "R" "D" "S" "ssc" "sc" "c",
                          HTTP_OK,
                          "SID: ", sub->sid, timeout_str ) != 0 ) {
        membuffer_destroy( &response );
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        return UPNP_E_OUTOF_MEMORY;
    }

    return_code = http_SendMessage( info, &upnp_timeout, "b",
                                    response.buf, response.length );

    membuffer_destroy( &response );

    return return_code;
}

/****************************************************************************
*	Function :	create_url_list
*
*	Parameters :
*				IN memptr* url_list :	
*				OUT URL_list *out :	
*
*	Description :	Function to parse the Callback header value in 
*		subscription requests takes in a buffer containing URLS delimited by 
*		'<' and '>'. The entire buffer is copied into dynamic memory
*		and stored in the URL_list. Pointers to the individual urls within 
*		this buffer are allocated and stored in the URL_list. Only URLs with 
*		network addresses are considered(i.e. host:port or domain name)
*
*	Return :	int
*		if successful returns the number of URLs parsed 
*		else UPNP_E_OUTOF_MEMORY
*	Note :
****************************************************************************/
static int
create_url_list( IN memptr * url_list,
                 OUT URL_list * out )
{
    int URLcount = 0;
    int i;
    int return_code = 0;
    uri_type temp;
    token urls;
    token *URLS;

    urls.buff = url_list->buf;
    urls.size = url_list->length;
    URLS = &urls;

    out->size = 0;
    out->URLs = NULL;
    out->parsedURLs = NULL;

    for( i = 0; i < URLS->size; i++ ) {
        if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) {
            if( ( ( return_code = parse_uri( &URLS->buff[i + 1],
                                             URLS->size - i + 1,
                                             &temp ) ) == HTTP_SUCCESS )
                && ( temp.hostport.text.size != 0 ) ) {
                URLcount++;
            } else {
                if( return_code == UPNP_E_OUTOF_MEMORY ) {
                    return return_code;
                }
            }
        }
    }

    if( URLcount > 0 ) {
        out->URLs = ( char * )malloc( URLS->size + 1 );
        out->parsedURLs =
            ( uri_type * ) malloc( sizeof( uri_type ) * URLcount );
        if( ( out->URLs == NULL ) || ( out->parsedURLs == NULL ) ) {
            free( out->URLs );
            free( out->parsedURLs );
            out->URLs = NULL;
            out->parsedURLs = NULL;
            return UPNP_E_OUTOF_MEMORY;
        }
        memcpy( out->URLs, URLS->buff, URLS->size );
        out->URLs[URLS->size] = 0;
        URLcount = 0;
        for( i = 0; i < URLS->size; i++ ) {
            if( ( URLS->buff[i] == '<' ) && ( i + 1 < URLS->size ) ) {
                if( ( ( return_code =
                        parse_uri( &out->URLs[i + 1], URLS->size - i + 1,
                                   &out->parsedURLs[URLcount] ) ) ==
                      HTTP_SUCCESS )
                    && ( out->parsedURLs[URLcount].hostport.text.size !=
                         0 ) ) {
                    URLcount++;
                } else {
                    if( return_code == UPNP_E_OUTOF_MEMORY ) {

⌨️ 快捷键说明

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