Changeset 1783


Ignore:
Timestamp:
Apr 23, 2007, 7:47:49 PM (15 years ago)
Author:
joshe
Message:

Merge r1762 from trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/0.7x/libtransmission/upnp.c

    r1720 r1783  
    3131#define SSDP_FIRST_DELAY        3750    /* 3 3/4 seconds */
    3232#define SSDP_MAX_DELAY          1800000 /* 30 minutes */
    33 #define UPNP_SERVICE_TYPE       "urn:schemas-upnp-org:service:WANIPConnection:1"
     33#define SERVICE_TYPE_IP         "urn:schemas-upnp-org:service:WANIPConnection:1"
     34#define SERVICE_TYPE_PPP        "urn:schemas-upnp-org:service:WANPPPConnection:1"
    3435#define SOAP_ENVELOPE           "http://schemas.xmlsoap.org/soap/envelope/"
    3536#define LOOP_DETECT_THRESHOLD   10 /* error on 10 add/get/del state changes */
     
    4647{
    4748    char * name;
    48     char * action;
    4949    int    len;
    5050    struct { char * name; char * var; char dir; } * args;
     
    5757    char                    * root;
    5858    int                       port;
     59    int                       ppp;
    5960    char                    * soap;
    6061    char                    * scpd;
     
    123124static int
    124125parseRoot( const char * root, const char *buf, int len,
    125            char ** soap, char ** scpd );
     126           char ** soap, char ** scpd, int * ppp );
    126127static void
    127128addUrlbase( const char * base, char ** path );
     
    138139static tr_http_t *
    139140soapRequest( int retry, const char * host, int port, const char * path,
    140              tr_upnp_action_t * action, ... );
     141             const char * type, tr_upnp_action_t * action, ... );
    141142static void
    142143actionSetup( tr_upnp_action_t * action, const char * name, int prealloc );
     
    674675            }
    675676            else if( parseRoot( dev->root, body, len,
    676                                 &dev->soap, &dev->scpd ) )
     677                                &dev->soap, &dev->scpd, &dev->ppp ) )
    677678            {
    678679                tr_dbg( "upnp device %s: parse root failed", dev->host );
     
    823824{
    824825    tr_http_t  * ret;
    825     char numstr[6];
     826    char         numstr[6];
     827    const char * type;
    826828
    827829    ret = NULL;
     
    847849            }
    848850            snprintf( numstr, sizeof( numstr ), "%i", dev->mappedport );
     851            type = ( dev->ppp ? SERVICE_TYPE_PPP : SERVICE_TYPE_IP );
    849852            ret = soapRequest( dev->soapretry, dev->host, dev->port, dev->soap,
    850                                &dev->addcmd,
     853                               type, &dev->addcmd,
    851854                               "PortMappingEnabled", "1",
    852855                               "PortMappingLeaseDuration", "0",
     
    861864        case UPNPDEV_STATE_GET:
    862865            snprintf( numstr, sizeof( numstr ), "%i", dev->mappedport );
     866            type = ( dev->ppp ? SERVICE_TYPE_PPP : SERVICE_TYPE_IP );
    863867            ret = soapRequest( dev->soapretry, dev->host, dev->port, dev->soap,
    864                                &dev->getcmd,
     868                               type, &dev->getcmd,
    865869                               "RemoteHost", "",
    866870                               "ExternalPort", numstr,
     
    870874        case UPNPDEV_STATE_DEL:
    871875            snprintf( numstr, sizeof( numstr ), "%i", dev->mappedport );
     876            type = ( dev->ppp ? SERVICE_TYPE_PPP : SERVICE_TYPE_IP );
    872877            ret = soapRequest( dev->soapretry, dev->host, dev->port, dev->soap,
    873                                &dev->delcmd,
     878                               type, &dev->delcmd,
    874879                               "RemoteHost", "",
    875880                               "ExternalPort", numstr,
     
    952957static int
    953958parseRoot( const char * root, const char *buf, int len,
    954            char ** soap, char ** scpd )
     959           char ** soap, char ** scpd, int * ppp )
    955960{
    956961    const char * end, * ii, * jj, * kk, * urlbase;
     
    9991004                buf = tr_xmlTagContents( kk, end );
    10001005                if( !tr_xmlFindTagVerifyContents( buf, end, "serviceType",
    1001                                                   UPNP_SERVICE_TYPE, 1 ) )
     1006                                                  SERVICE_TYPE_IP, 1 ) )
    10021007                {
    10031008                    *soap = tr_xmlDupTagContents( buf, end, "controlURL");
    10041009                    *scpd = tr_xmlDupTagContents( buf, end, "SCPDURL");
     1010                    *ppp  = 0;
     1011                    break;
     1012                }
     1013                /* XXX we should save all services of both types and
     1014                   try adding mappings for each in turn */
     1015                else if( !tr_xmlFindTagVerifyContents( buf, end, "serviceType",
     1016                                                       SERVICE_TYPE_PPP, 1 ) )
     1017                {
     1018                    *soap = tr_xmlDupTagContents( buf, end, "controlURL");
     1019                    *scpd = tr_xmlDupTagContents( buf, end, "SCPDURL");
     1020                    *ppp  = 1;
    10051021                    break;
    10061022                }
     
    12081224static tr_http_t *
    12091225soapRequest( int retry, const char * host, int port, const char * path,
    1210              tr_upnp_action_t * action, ... )
     1226             const char * type, tr_upnp_action_t * action, ... )
    12111227{
    12121228    tr_http_t  * http;
     
    12141230    const char * name, * value;
    12151231    int          method;
     1232    char       * actstr;
    12161233
    12171234    method = ( retry ? TR_HTTP_M_POST : TR_HTTP_POST );
     
    12211238        tr_httpAddHeader( http, "Content-type",
    12221239                          "text/xml; encoding=\"utf-8\"" );
    1223         tr_httpAddHeader( http, "SOAPAction", action->action );
     1240        actstr = NULL;
     1241        asprintf( &actstr, "\"%s#%s\"", type, action->name );
     1242        tr_httpAddHeader( http, "SOAPAction", actstr );
     1243        free( actstr );
    12241244        if( retry )
    12251245        {
     
    12321252"    s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
    12331253"  <s:Body>"
    1234 "    <u:%s xmlns:u=\"" UPNP_SERVICE_TYPE "\">", action->name );
     1254"    <u:%s xmlns:u=\%s\">", action->name, type );
    12351255
    12361256        va_start( ap, action );
     
    12711291{
    12721292    action->name = strdup( name );
    1273     action->action = NULL;
    1274     asprintf( &action->action, "\"%s#%s\"", UPNP_SERVICE_TYPE, name );
    12751293    assert( NULL == action->args );
    12761294    action->args = malloc( sizeof( *action->args ) * prealloc );
     
    12831301{
    12841302    free( act->name );
    1285     free( act->action );
    12861303    while( 0 < act->len )
    12871304    {
     
    13611378    return NULL;
    13621379}
     1380
     1381#if 0
     1382/* this code is used for standalone root parsing for debugging purposes */
     1383/* cc -g -Wall -D__TRANSMISSION__ -o upnp upnp.c xml.c utils.c */
     1384int
     1385main( int argc, char * argv[] )
     1386{
     1387    struct stat sb;
     1388    char      * data, * soap, * scpd;
     1389    int         fd, ppp;
     1390    ssize_t     res;
     1391
     1392    if( 3 != argc )
     1393    {
     1394        printf( "usage: %s root-url root-file\n", argv[0] );
     1395        return 0;
     1396    }
     1397
     1398    tr_msgInit();
     1399    tr_setMessageLevel( 9 );
     1400
     1401    if( 0 > stat( argv[2], &sb ) )
     1402    {
     1403        tr_err( "failed to stat file %s: %s", argv[2], strerror( errno ) );
     1404        return 1;
     1405    }
     1406
     1407    data = malloc( sb.st_size );
     1408    if( NULL == data )
     1409    {
     1410        tr_err( "failed to malloc %zd bytes", ( size_t )sb.st_size );
     1411        return 1;
     1412    }
     1413
     1414    fd = open( argv[2], O_RDONLY );
     1415    if( 0 > fd )
     1416    {
     1417        tr_err( "failed to open file %s: %s", argv[2], strerror( errno ) );
     1418        free( data );
     1419        return 1;
     1420    }
     1421
     1422    res = read( fd, data, sb.st_size );
     1423    if( sb.st_size > res )
     1424    {
     1425        tr_err( "failed to read file %s: %s", argv[2],
     1426                ( 0 > res ? strerror( errno ) : "short read count" ) );
     1427        close( fd );
     1428        free( data );
     1429        return 1;
     1430    }
     1431
     1432    close( fd );
     1433
     1434    if( parseRoot( argv[1], data, sb.st_size, &soap, &scpd, &ppp ) )
     1435    {
     1436        tr_err( "root parsing failed" );
     1437    }
     1438    else
     1439    {
     1440        tr_err( "soap=%s scpd=%s ppp=%s", soap, scpd, ( ppp ? "yes" : "no" ) );
     1441        free( soap );
     1442        free( scpd );
     1443    }
     1444    free( data );
     1445
     1446    return 0;
     1447}
     1448
     1449int  tr_netMcastOpen( int port, struct in_addr addr ) { assert( 0 ); }
     1450int  tr_netBind    ( int port, int type ) { assert( 0 ); }
     1451void tr_netClose   ( int s ) { assert( 0 ); }
     1452int  tr_netRecvFrom( int s, uint8_t * buf, int size, struct sockaddr_in * sin ) { assert( 0 ); }
     1453int         tr_httpRequestType( const char * data, int len,
     1454                                char ** method, char ** uri ) { assert( 0 ); }
     1455int         tr_httpResponseCode( const char * data, int len ) { assert( 0 ); }
     1456char *      tr_httpParse( const char * data, int len, tr_http_header_t *headers ) { assert( 0 ); }
     1457int         tr_httpIsUrl( const char * u, int l ) { assert( 0 ); }
     1458int         tr_httpParseUrl( const char * u, int l, char ** h, int * p, char ** q ) { assert( 0 ); }
     1459tr_http_t   * tr_httpClient( int t, const char * h, int p, const char * u, ... ) { assert( 0 ); }
     1460tr_http_t   * tr_httpClientUrl( int t, const char * u, ... ) { assert( 0 ); }
     1461void          tr_httpAddHeader( tr_http_t * h, const char * n, const char * v ) { assert( 0 ); }
     1462void          tr_httpAddBody( tr_http_t * h, const char * b, ... ) { assert( 0 ); }
     1463tr_tristate_t tr_httpPulse( tr_http_t * h, const char ** b, int * l ) { assert( 0 ); }
     1464char        * tr_httpWhatsMyAddress( tr_http_t * h ) { assert( 0 ); }
     1465void          tr_httpClose( tr_http_t * h ) { assert( 0 ); }
     1466
     1467void tr_lockInit     ( tr_lock_t * l ) {}
     1468int  pthread_mutex_lock( pthread_mutex_t * m ) { return 0; }
     1469int  pthread_mutex_unlock( pthread_mutex_t * m ) { return 0; }
     1470
     1471#endif
Note: See TracChangeset for help on using the changeset viewer.