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

📄 webserver.c

📁 电驴下载工具eMule0.47aVeryCD的源代码,可作分析测试也可用于P2P软件的开发研究.
💻 C
📖 第 1 页 / 共 4 页
字号:
*				caller (doesn't even have to be malloc()d .)					
*	alias_content:	the xml doc; this is allocated by the caller; and	
*					freed by the web server											
*	alias_content_length: length of alias body in bytes					
*	last_modified:	time when the contents of alias were last			
*					changed (local time)											
*																		
* Description: Replaces current alias with the given alias. To remove	
*	the current alias, set alias_name to NULL.							
*																		
* Returns:																
*	0 - OK																
*	UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here			
************************************************************************/
int
web_server_set_alias( IN const char *alias_name,
                      IN const char *alias_content,
                      IN size_t alias_content_length,
                      IN time_t last_modified )
{
    int ret_code;
    struct xml_alias_t alias;

#ifdef _ALIASDOC
    alias_release( &gAliasDoc );
#endif

    if( alias_name == NULL ) {
        // don't serve aliased doc anymore
        return 0;
    }

    assert( alias_content != NULL );

    membuffer_init( &alias.doc );
    membuffer_init( &alias.name );
    alias.ct = NULL;

    do {
        // insert leading /, if missing
        if( *alias_name != '/' ) {
            if( membuffer_assign_str( &alias.name, "/" ) != 0 ) {
                break;          // error; out of mem
            }
        }

        ret_code = membuffer_append_str( &alias.name, alias_name );
        if( ret_code != 0 ) {
            break;              // error
        }

        if( ( alias.ct = ( int * )malloc( sizeof( int ) ) ) == NULL ) {
            break;              // error
        }
        *alias.ct = 1;
        membuffer_attach( &alias.doc, ( char * )alias_content,
                          alias_content_length );

        alias.last_modified = last_modified;

        // save in module var
        ithread_mutex_lock( &gWebMutex );
#ifdef _ALIASDOC
	gAliasDoc = alias;
#else
	memcpy( &(gAliasDict[numAliasDictEntries]), &alias, sizeof( struct xml_alias_t ) );
	numAliasDictEntries++;
#endif
        ithread_mutex_unlock( &gWebMutex );

        return 0;
    } while( FALSE );

    // error handler

    // free temp alias
    membuffer_destroy( &alias.name );
    membuffer_destroy( &alias.doc );
    free( alias.ct );
    return UPNP_E_OUTOF_MEMORY;
}

/************************************************************************
* Function: web_server_init												
*																		
* Parameters:															
*	none																
*																		
* Description: Initilialize the different documents. Initialize the		
*	memory for root directory for web server. Call to initialize global 
*	XML document. Sets bWebServerState to WEB_SERVER_ENABLED			
*																		
* Returns:																
*	0 - OK																
*	UPNP_E_OUTOF_MEMORY: note: alias_content is not freed here			
************************************************************************/
int
web_server_init( void )
{
    int ret_code;

    if( bWebServerState == WEB_SERVER_DISABLED ) {
        media_list_init(  );    // decode media list
        membuffer_init( &gDocumentRootDir );
        glob_alias_init(  );

        pVirtualDirList = NULL;

        ret_code = ithread_mutex_init( &gWebMutex, NULL );
        if( ret_code == -1 ) {
            return UPNP_E_OUTOF_MEMORY;
        }
        bWebServerState = WEB_SERVER_ENABLED;
    }

    return 0;
}

/************************************************************************
* Function: web_server_destroy											
*																		
* Parameters:															
*	none																
*																		
* Description: Release memory allocated for the global web server root	
*	directory and the global XML document								
*	Resets the flag bWebServerState to WEB_SERVER_DISABLED				
*																		
* Returns:																
*	void																
************************************************************************/
void
web_server_destroy( void )
{
    int ret;

    if( bWebServerState == WEB_SERVER_ENABLED ) {
        membuffer_destroy( &gDocumentRootDir );
#ifdef _ALIASDOC
        alias_release( &gAliasDoc );

        ithread_mutex_lock( &gWebMutex );
        memset( &gAliasDoc, 0, sizeof( struct xml_alias_t ) );
        ithread_mutex_unlock( &gWebMutex );
#endif

        ret = ithread_mutex_destroy( &gWebMutex );
        assert( ret == 0 );
        bWebServerState = WEB_SERVER_DISABLED;
    }
}

/************************************************************************
* Function: get_file_info												
*																		
* Parameters:															
*	IN const char* filename ; 	Filename having the description document
*	OUT struct File_Info * info ; File information object having file 
*								  attributes such as filelength, when was 
*								  the file last modified, whether a file 
*								  or a directory and whether the file or
*								  directory is readable. 
*																		
* Description: Release memory allocated for the global web server root	
*	directory and the global XML document								
*	Resets the flag bWebServerState to WEB_SERVER_DISABLED				
*																		
* Returns:																
*	int																	
************************************************************************/
static int
get_file_info( IN const char *filename,
               OUT struct File_Info *info )
{
    int code;
    struct stat s;
    FILE *fp;
    int rc = 0;

    info->content_type = NULL;

    code = stat( filename, &s );
    if( code == -1 ) {
        return -1;
    }

#ifndef _WIN32
    if( S_ISDIR( s.st_mode ) ) {
#else
    if( S_IFDIR & s.st_mode ) {
#endif
        info->is_directory = TRUE;
#ifndef _WIN32
    } else if( S_ISREG( s.st_mode ) ) {
#else
    } else if( S_IFREG & s.st_mode ) {
#endif
        info->is_directory = FALSE;
    } else {
        return -1;
    }

    // check readable
    fp = fopen( filename, "r" );
    info->is_readable = ( fp != NULL );
    if( fp ) {
        fclose( fp );
    }

    info->file_length = s.st_size;
    info->last_modified = s.st_mtime;

    rc = get_content_type( filename, &info->content_type );

    DBGONLY( UpnpPrintf( UPNP_INFO, HTTP, __FILE__, __LINE__,
                         "file info: %s, length: %d, last_mod=%s readable=%d\n",
                         filename, info->file_length,
                         asctime( gmtime( &info->last_modified ) ),
                         info->is_readable ); )

        return rc;
}

/************************************************************************
* Function: web_server_set_root_dir										
*																		
* Parameters:															
*	IN const char* root_dir ; String having the root directory for the 
*								document		 						
*																		
* Description: Assign the path specfied by the IN const char* root_dir	
*	parameter to the global Document root directory. Also check for		
*	path names ending in '/'											
*																		
* Returns:																
*	int																	
************************************************************************/
int
web_server_set_root_dir( IN const char *root_dir )
{
    int index;
    int ret;

    ret = membuffer_assign_str( &gDocumentRootDir, root_dir );
    if( ret != 0 ) {
        return ret;
    }
    // remove trailing '/', if any
    if( gDocumentRootDir.length > 0 ) {
        index = gDocumentRootDir.length - 1;    // last char
        if( gDocumentRootDir.buf[index] == '/' ) {
            membuffer_delete( &gDocumentRootDir, index, 1 );
        }
    }

    return 0;
}

#ifndef _ALIASDOC
/************************************************************************
 * Function: getAliasFromDict(
*									
* Parameters:															
*	IN const char* request_file ; request file passed in to be compared with
*	OUT struct xml_alias_t* alias ; xml alias object which has a file name 
*		stored
*   OUT struct File_Info * info	 ; File information object which will be 
*		filled up if the file comparison succeeds										
*							
* Description: Compare the files names between the one on the XML alias 
*	the one passed in as the input parameter. If equal extract file 
*	information
*
* Returns:																
*	TRUE - On Success													
*	FALSE if request is not an alias									
************************************************************************/
static xboolean
getAliasFromDict(IN const char *request_file,
		 OUT struct xml_alias_t *alias,
		 OUT struct File_Info *info )
{
    int i;
    // traverse dictionary looking for the alias
    ithread_mutex_lock( &gWebMutex );
    for (i = 0; i < numAliasDictEntries; i++) {
	if (strcmp(gAliasDict[i].name.buf, request_file) == 0) {
	    memcpy( alias, &(gAliasDict[i]), sizeof( struct xml_alias_t ) );
	    (*(alias->ct))++;
	    // fill up info
	    info->file_length = alias->doc.length;
	    info->is_readable = TRUE;
	    info->is_directory = FALSE;
	    info->last_modified = alias->last_modified;
	    ithread_mutex_unlock( &gWebMutex );
	    return TRUE;
	}
    }
    ithread_mutex_unlock( &gWebMutex );
    return FALSE;
}
#endif

/************************************************************************
* Function: get_alias													
*																		
* Parameters:															
*	IN const char* request_file ; request file passed in to be compared with
*	OUT struct xml_alias_t* alias ; xml alias object which has a file name 
*									stored										
*   OUT struct File_Info * info	 ; File information object which will be 
*									filled up if the file comparison 
*									succeeds										
*																		
* Description: Compare the files names between the one on the XML alias 
*	the one passed in as the input parameter. If equal extract file 
*	information
*																		
* Returns:																
*	TRUE - On Success													
*	FALSE if request is not an alias									
************************************************************************/
static XINLINE xboolean
get_alias( IN const char *request_file,
           OUT struct xml_alias_t *alias,
           OUT struct File_Info *info )
{
    int cmp;

    cmp = strcmp( alias->name.buf, request_file );
    if( cmp == 0 ) {
        // fill up info
        info->file_length = alias->doc.length;
        info->is_readable = TRUE;
        info->is_directory = FALSE;
        info->last_modified = alias->last_modified;
    }

    return cmp == 0;
}

/************************************************************************
* Function: isFileInVirtualDir											
*																		
* Parameters:															
*	IN char *filePath ; directory path to be tested for virtual directory
*																		
* Description: Compares filePath with paths from the list of virtual
*				directory lists
*																		
* Returns:																
*	BOOLEAN																
************************************************************************/
int
isFileInVirtualDir( IN char *filePath )
{
    virtualDirList *pCurVirtualDir;
    int webDirLen;

    pCurVirtualDir = pVirtualDirList;
    while( pCurVirtualDir != NULL ) {
        webDirLen = strlen( pCurVirtualDir->dirName );
        if( pCurVirtualDir->dirName[webDirLen - 1] == '/' ) {
            if( strncmp( pCurVirtualDir->dirName, filePath, webDirLen ) ==
                0 )
                return TRUE;
        } else {
            if( ( strncmp( pCurVirtualDir->dirName, filePath, webDirLen )
                  == 0 ) && ( filePath[webDirLen] == '/' ) )
                return TRUE;
        }

        pCurVirtualDir = pCurVirtualDir->next;
    }

    return FALSE;
}

/************************************************************************
* Function: ToUpperCase													
*																		
* Parameters:															
*	INOUT char * Str ; Input string to be converted					
*																		
* Description: Converts input string to upper case						
*																		
* Returns:																
*	int																	
************************************************************************/
int
ToUpperCase( char *Str )
{
    int i;

    for( i = 0; i < ( int )strlen( Str ); i++ )
        Str[i] = toupper( Str[i] );
    return 1;

}

/************************************************************************
* Function: StrStr														
*																		
* Parameters:															
*	IN char * S1 ; Input string
*	IN char * S2 ; Input sub-string										
*																		
* Description: Finds a substring from a string							
*																		
* Returns:																
*	char * ptr - pointer to the first occurence of S2 in S1				
************************************************************************/
char *
StrStr( char *S1,
        char *S2 )
{
    char *Str1,
     *Str2;
    char *Ptr,
     *Ret;
    int Pos;

    Str1 = ( char * )malloc( strlen( S1 ) + 2 );
    Str2 = ( char * )malloc( strlen( S2 ) + 2 );
    if( !Str1 || !Str2 )
        return NULL;

    strcpy( Str1, S1 );
    strcpy( Str2, S2 );

    ToUpperCase( Str1 );
    ToUpperCase( Str2 );
    Ptr = strstr( Str1, Str2 );
    if( Ptr == NULL )
        return NULL;

    Pos = Ptr - Str1;

    Ret = S1 + Pos;

    free( Str1 );
    free( Str2 );
    return Ret;

}

/************************************************************************
* Function: StrTok														
*																		
* Parameters:															
*	IN char ** Src ; String containing the token													
*	IN char * del ; Set of delimiter characters														
*																		
* Description: Finds next token in a string							
*																		
* Returns:																
*	char * ptr - pointer to the first occurence of S2 in S1				
************************************************************************/
char *

⌨️ 快捷键说明

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