Example #1
0
static int DISPLAY (const char *line)
{
    if      (matchstr (&line, "ON"))     clear_inhibit_frame (IHF_SCROLLLOCK);
    else if (matchstr (&line, "OFF"))    set_inhibit_frame (IHF_SCROLLLOCK);
    else if (matchstr (&line, "TOGGLE")) toggle_inhibit_frame (IHF_SCROLLLOCK);
    else return RC_ERROR;
    return RC_OK;
}
Example #2
0
static int GET_VERSION (const char *line)
{
    if (matchstr (&line, "STRING")) {
	sprintf (RESULT,
		 PACKAGE_NAME "-" PACKAGE_VERSION " by Richard Drummond & contributors, "
		 "Amiga Port based on work by Samuel Devulder.");
    } else if (matchstr (&line, "NUM")) {
	sprintf (RESULT, "%d", UAEMAJOR * 10000 + UAEMINOR * 100 + UAESUBREV);
    } else if (matchstr (&line, "AUTHOR")) {
	sprintf (RESULT," by Richard Drummond & contributors");
    } else if (matchstr (&line, "PORT")) {
	sprintf (RESULT, "Amiga Port based on work by Samuel Devulder");
    } else return RC_ERROR;
    return RC_OK;
}
Example #3
0
/*!
 * \brief Compares 'name' and node's name.
 *
 * \return 0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY.
 */
static int dom_cmp_name(
	/* [in] lookup name. */
	const char *name,
	/* [in] xml node. */
	IXML_Node *node)
{
	const DOMString node_name = NULL;
	memptr nameptr;
	memptr dummy;
	int ret_code;

	assert(name);
	assert(node);

	node_name = ixmlNode_getNodeName(node);
	if (node_name == NULL)
		return UPNP_E_OUTOF_MEMORY;
	if (strcmp(name, node_name) == 0)
		ret_code = 0;
	else if (matchstr((char *)node_name, strlen(node_name),
			  "%s:%s%0", &dummy, &nameptr) == PARSE_OK &&
		 strcmp(nameptr.buf, name) == 0)
		ret_code = 0;
	else
		/* names are not the same */
		ret_code = 1;

	return ret_code;
}
Example #4
0
/****************************************************************************
*	Function :	dom_cmp_name
*
*	Parameters :
*			IN char *name :	lookup name
*			IN IXML_Node *node : xml node
*
*	Description : This function compares 'name' and node's name	
*
*	Return : int
*		0 if both are equal; 1 if not equal, and UPNP_E_OUTOF_MEMORY
*
*	Note :
****************************************************************************/
static int
dom_cmp_name( IN char *name,
              IN IXML_Node * node )
{
    const DOMString node_name = NULL;
    memptr nameptr,
      dummy;
    int ret_code;

    assert( name );
    assert( node );

    node_name = ixmlNode_getNodeName( node );
    if( node_name == NULL ) {
        return UPNP_E_OUTOF_MEMORY;
    }

    if( strcmp( name, node_name ) == 0 ) {
        ret_code = 0;
    } else if( matchstr( ( char * )node_name, strlen( node_name ),
                         "%s:%s%0", &dummy, &nameptr ) == PARSE_OK &&
               strcmp( nameptr.buf, name ) == 0 ) {
        ret_code = 0;
    } else {
        ret_code = 1;           // names are not the same
    }

    return ret_code;
}
Example #5
0
static int SOUND (const char *line)
{
    if (!sound_available) {
	sprintf (RESULT, "Sound not available!");
	return RC_WARN;
    }

    if      (matchstr (&line, "ON"))     currprefs.produce_sound = 2;
    else if (matchstr (&line, "OFF"))    currprefs.produce_sound = 1;
    else if (matchstr (&line, "BEST"))   currprefs.produce_sound = 3;
    else if (matchstr (&line, "TOGGLE"))
	currprefs.produce_sound = currprefs.produce_sound <= 1 ? 2 : 1;
    else return RC_ERROR;

    /* sam: the next 2 lines is a hack and I don't like it */
/*    eventtab[ev_sample].active = (changed_prefs.produce_sound>=2)?1:0;
    events_schedule ();
*/
    return RC_OK;
}
Example #6
0
/****************************************************************************
*	Function :	get_action_name
*
*	Parameters :
*			IN char* action :	string containing action name
*			OUT memptr* name : name of the action	
*
*	Description :	This functions retirves the action name in the buffer
*
*	Return : int
*		returns 0 on success; -1 on error
*
*	Note :
****************************************************************************/
static XINLINE int
get_action_name( IN char *action,
                 OUT memptr * name )
{
    memptr dummy;
    int ret_code;

    ret_code =
        matchstr( action, strlen( action ), " <%s:%s", &dummy, name );

    return ret_code == PARSE_OK ? 0 : -1;
}
int has_xml_content_type(http_message_t *hmsg)
{
	memptr hdr_value;

	assert(hmsg);

	/* find 'content-type' header which must have text/xml */
	if (httpmsg_find_hdr(hmsg, HDR_CONTENT_TYPE, &hdr_value) &&
	    matchstr(hdr_value.buf, hdr_value.length, "%itext%w/%wxml" ) == PARSE_OK) {
		return TRUE;
	}
	return FALSE;
}
Example #8
0
void gena_process_subscription_renewal_request(
	SOCKINFO *info,
	http_message_t *request)
{
    Upnp_SID sid;
    subscription *sub;
    int time_out = 1801;
    service_info *service;
    struct Handle_Info *handle_info;
    UpnpDevice_Handle device_handle;
    memptr temp_hdr;
    membuffer event_url_path;
    memptr timeout_hdr;

    /* if a CALLBACK or NT header is present, then it is an error */
    if( httpmsg_find_hdr( request, HDR_CALLBACK, NULL ) != NULL ||
        httpmsg_find_hdr( request, HDR_NT, NULL ) != NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, request );
        return;
    }
    /* get SID */
    if( httpmsg_find_hdr( request, HDR_SID, &temp_hdr ) == NULL ||
        temp_hdr.length > SID_SIZE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        return;
    }
    memcpy( sid, temp_hdr.buf, temp_hdr.length );
    sid[temp_hdr.length] = '\0';

    /* lookup service by eventURL */
    membuffer_init( &event_url_path );
    if( membuffer_append( &event_url_path, request->uri.pathquery.buff,
                          request->uri.pathquery.size ) != 0 ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        return;
    }

    HandleLock();

    if (GetDeviceHandleInfoForPath(event_url_path.buf, info->foreign_sockaddr.ss_family,
								   &device_handle, &handle_info, &service) != HND_DEVICE ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        membuffer_destroy( &event_url_path );
        HandleUnlock();
        return;
    }
    membuffer_destroy( &event_url_path );

    /* get subscription */
    if( service == NULL ||
        !service->active ||
        ( ( sub = GetSubscriptionSID( sid, service ) ) == NULL ) ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, request );
        HandleUnlock();
        return;
    }

    UpnpPrintf( UPNP_INFO, GENA, __FILE__, __LINE__,
        "Renew request: Number of subscriptions already: %d\n "
        "Max Subscriptions allowed:%d\n",
        service->TotalSubscriptions,
        handle_info->MaxSubscriptions );
    /* too many subscriptions */
    if( handle_info->MaxSubscriptions != -1 &&
            service->TotalSubscriptions > handle_info->MaxSubscriptions ) {
        error_respond( info, HTTP_INTERNAL_SERVER_ERROR, request );
        RemoveSubscriptionSID( sub->sid, service );
        HandleUnlock();
        return;
    }
    /* set the timeout */
    if( httpmsg_find_hdr( request, HDR_TIMEOUT, &timeout_hdr ) != NULL ) {
        if( matchstr( timeout_hdr.buf, timeout_hdr.length,
                      "%iSecond-%d%0", &time_out ) == PARSE_OK ) {

            /*nothing */

        } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) ==
                   0 ) {

            time_out = -1;      /* inifinite timeout */

        } else {
            time_out = DEFAULT_TIMEOUT; /* default is > 1800 seconds */

        }
    }

    /* replace infinite timeout with max timeout, if possible */
    if( handle_info->MaxSubscriptionTimeOut != -1 ) {
        if( time_out == -1 ||
            time_out > handle_info->MaxSubscriptionTimeOut ) {
            time_out = handle_info->MaxSubscriptionTimeOut;
        }
    }

    if( time_out == -1 ) {
        sub->expireTime = 0;
    } else {
        sub->expireTime = time( NULL ) + time_out;
    }

    if( respond_ok( info, time_out, sub, request ) != UPNP_E_SUCCESS ) {
        RemoveSubscriptionSID( sub->sid, service );
    }

    HandleUnlock();
}
/****************************************************************************
*	Function :	get_request_type
*
*	Parameters :
*			IN http_message_t* request :	HTTP request
*			OUT memptr* action_name :	SOAP action name
*
*	Description :	This function retrives the name of the SOAP action
*
*	Return : int
*		0 if successful else returns appropriate error.
*	Note :
****************************************************************************/
static XINLINE int
get_request_type( IN http_message_t * request,
                  OUT memptr * action_name )
{
    memptr value;
    memptr ns_value,
      dummy_quote;
    http_header_t *hdr;
    char save_char;
    char *s;
    membuffer soap_action_name;

    // find soapaction header
    //
    if( request->method == SOAPMETHOD_POST ) {
        if( httpmsg_find_hdr( request, HDR_SOAPACTION, &value )
            == NULL ) {
            return SREQ_HDR_NOT_FOUND;
        }
    } else                      // M-POST
    {
        // get NS value from MAN header
        hdr = httpmsg_find_hdr( request, HDR_MAN, &value );
        if( hdr == NULL ) {
            return SREQ_HDR_NOT_FOUND;
        }

        if( matchstr( value.buf, value.length, "%q%i ; ns = %s",
                      &dummy_quote, &ns_value ) != 0 ) {
            return SREQ_BAD_HDR_FORMAT;
        }
        // create soapaction name header
        membuffer_init( &soap_action_name );
        if( ( membuffer_assign( &soap_action_name,
                                ns_value.buf, ns_value.length )
              == UPNP_E_OUTOF_MEMORY ) ||
            ( membuffer_append_str( &soap_action_name,
                                    "-SOAPACTION" ) ==
              UPNP_E_OUTOF_MEMORY )
             ) {
            membuffer_destroy( &soap_action_name );
            return UPNP_E_OUTOF_MEMORY;
        }

        hdr = httpmsg_find_hdr_str( request, soap_action_name.buf );
        membuffer_destroy( &soap_action_name );
        if( hdr == NULL ) {
            return SREQ_HDR_NOT_FOUND;
        }

        value.buf = hdr->value.buf;
        value.length = hdr->value.length;
    }

    // determine type
    //
    save_char = value.buf[value.length];
    value.buf[value.length] = '\0';

    s = strchr( value.buf, '#' );
    if( s == NULL ) {
        value.buf[value.length] = save_char;
        return SREQ_BAD_HDR_FORMAT;
    }

    s++;                        // move to value

    if( matchstr( s, value.length - ( s - value.buf ), "%s",
                  action_name ) != PARSE_OK ) {
        value.buf[value.length] = save_char;
        return SREQ_BAD_HDR_FORMAT;
    }
    // action name or variable ?
    if( memptr_cmp( action_name, "QueryStateVariable" ) == 0 ) {
        // query variable
        action_name->buf = NULL;
        action_name->length = 0;
    }

    value.buf[value.length] = save_char;    // restore
    return 0;
}
Example #10
0
/************************************************************************
* Function : gena_process_notification_event
*																	
* Parameters:														
*	IN SOCKINFO *info: Socket structure containing the device socket 
*					information
*	IN http_message_t* event: The http message contains the GENA 
*								notification
*
* Description:														
*	This function processes NOTIFY events that are sent by devices. 
*	called by genacallback()
*
* Returns: void
*
* Note : called by genacallback()
****************************************************************************/
void
gena_process_notification_event( IN SOCKINFO * info,
                                 IN http_message_t * event )
{
    struct Upnp_Event event_struct;
    int eventKey;
    token sid;
    client_subscription *subscription;
    IXML_Document *ChangedVars;
    struct Handle_Info *handle_info;
    void *cookie;
    Upnp_FunPtr callback;
    UpnpClient_Handle client_handle;

    memptr sid_hdr;
    memptr nt_hdr,
      nts_hdr;
    memptr seq_hdr;

    // get SID
    if( httpmsg_find_hdr( event, HDR_SID, &sid_hdr ) == NULL ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );

        return;
    }
    sid.buff = sid_hdr.buf;
    sid.size = sid_hdr.length;

    // get event key
    if( httpmsg_find_hdr( event, HDR_SEQ, &seq_hdr ) == NULL ||
        matchstr( seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey )
        != PARSE_OK ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }
    // get NT and NTS headers
    if( httpmsg_find_hdr( event, HDR_NT, &nt_hdr ) == NULL ||
        httpmsg_find_hdr( event, HDR_NTS, &nts_hdr ) == NULL ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }
    // verify NT and NTS headers
    if( memptr_cmp( &nt_hdr, "upnp:event" ) != 0 ||
        memptr_cmp( &nts_hdr, "upnp:propchange" ) != 0 ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );

        return;
    }
    // parse the content (should be XML)
    if( !has_xml_content_type( event ) ||
        event->msg.length == 0 ||
        ( ixmlParseBufferEx( event->entity.buf, &ChangedVars ) ) !=
        IXML_SUCCESS ) {
        error_respond( info, HTTP_BAD_REQUEST, event );

        return;
    }

    HandleLock(  );

    // get client info
    if( GetClientHandleInfo( &client_handle, &handle_info ) != HND_CLIENT ) {
        error_respond( info, HTTP_PRECONDITION_FAILED, event );
        HandleUnlock(  );
        ixmlDocument_free( ChangedVars );

        return;
    }
    // get subscription based on SID
    if( ( subscription = GetClientSubActualSID( handle_info->ClientSubList,
                                                &sid ) ) == NULL ) {
        if( eventKey == 0 ) {
            // wait until we've finished processing a subscription 
            //   (if we are in the middle)
            // this is to avoid mistakenly rejecting the first event if we 
            //   receive it before the subscription response
            HandleUnlock(  );

            // try and get Subscription Lock 
            //   (in case we are in the process of subscribing)
            SubscribeLock(  );

            // get HandleLock again
            HandleLock(  );

            if( GetClientHandleInfo( &client_handle, &handle_info )
                != HND_CLIENT ) {
                error_respond( info, HTTP_PRECONDITION_FAILED, event );
                SubscribeUnlock(  );
                HandleUnlock(  );
                ixmlDocument_free( ChangedVars );

                return;
            }

            if( ( subscription =
                  GetClientSubActualSID( handle_info->ClientSubList,
                                         &sid ) ) == NULL ) {
                error_respond( info, HTTP_PRECONDITION_FAILED, event );
                SubscribeUnlock(  );
                HandleUnlock(  );
                ixmlDocument_free( ChangedVars );

                return;
            }

            SubscribeUnlock(  );
        } else {
            error_respond( info, HTTP_PRECONDITION_FAILED, event );
            HandleUnlock(  );
            ixmlDocument_free( ChangedVars );

            return;
        }
    }

    error_respond( info, HTTP_OK, event );  // success

    // fill event struct
    strcpy( event_struct.Sid, subscription->sid );
    event_struct.EventKey = eventKey;
    event_struct.ChangedVariables = ChangedVars;

    // copy callback
    callback = handle_info->Callback;
    cookie = handle_info->Cookie;

    HandleUnlock(  );

    // make callback with event struct
    // In future, should find a way of mainting
    // that the handle is not unregistered in the middle of a
    // callback
    callback( UPNP_EVENT_RECEIVED, &event_struct, cookie );

    ixmlDocument_free( ChangedVars );
}
Example #11
0
void gena_process_subscription_request(
	SOCKINFO *info,
	http_message_t *request)
{
	UpnpSubscriptionRequest *request_struct = UpnpSubscriptionRequest_new();
	Upnp_SID temp_sid;
	int return_code = 1;
	int time_out = 1801;
	service_info *service;
	subscription *sub;
	uuid_upnp uid;
	struct Handle_Info *handle_info;
	void *cookie;
	Upnp_FunPtr callback_fun;
	UpnpDevice_Handle device_handle;
	memptr nt_hdr;
	char *event_url_path = NULL;
	memptr callback_hdr;
	memptr timeout_hdr;
	int rc = 0;

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"Subscription Request Received:\n");

	if (httpmsg_find_hdr(request, HDR_NT, &nt_hdr) == NULL) {
		error_respond(info, HTTP_BAD_REQUEST, request);
		goto exit_function;
	}

	/* check NT header */
	/* Windows Millenium Interoperability: */
	/* we accept either upnp:event, or upnp:propchange for the NT header */
	if (memptr_cmp_nocase(&nt_hdr, "upnp:event") != 0) {
		error_respond(info, HTTP_PRECONDITION_FAILED, request);
		goto exit_function;
	}

	/* if a SID is present then the we have a bad request "incompatible headers" */
	if (httpmsg_find_hdr(request, HDR_SID, NULL) != NULL) {
		error_respond(info, HTTP_BAD_REQUEST, request);
		goto exit_function;
	}
	/* look up service by eventURL */
	event_url_path = str_alloc(request->uri.pathquery.buff, request->uri.pathquery.size);
	if (event_url_path == NULL) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		goto exit_function;
	}

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"SubscriptionRequest for event URL path: %s\n",
		event_url_path);

	HandleLock();

	if (GetDeviceHandleInfoForPath(event_url_path, info->foreign_sockaddr.ss_family,
								   &device_handle, &handle_info, &service) != HND_DEVICE) {
		free(event_url_path);
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}
	free(event_url_path);

	if (service == NULL || !service->active) {
		error_respond(info, HTTP_NOT_FOUND, request);
		HandleUnlock();
		goto exit_function;
	}

	UpnpPrintf(UPNP_INFO, GENA, __FILE__, __LINE__,
		"Subscription Request: Number of Subscriptions already %d\n "
		"Max Subscriptions allowed: %d\n",
		service->TotalSubscriptions,
		handle_info->MaxSubscriptions);

	/* too many subscriptions */
	if (handle_info->MaxSubscriptions != -1 &&
	    service->TotalSubscriptions >= handle_info->MaxSubscriptions) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}
	/* generate new subscription */
	sub = (subscription *)malloc(sizeof (subscription));
	if (sub == NULL) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}
	sub->ToSendEventKey = 0;
	sub->active = 0;
	sub->next = NULL;
	sub->DeliveryURLs.size = 0;
	sub->DeliveryURLs.URLs = NULL;
	sub->DeliveryURLs.parsedURLs = NULL;
	if (ListInit(&sub->outgoing, 0, free) != 0) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		HandleUnlock();
		goto exit_function;
	}

	/* check for valid callbacks */
	if (httpmsg_find_hdr( request, HDR_CALLBACK, &callback_hdr) == NULL) {
		error_respond(info, HTTP_PRECONDITION_FAILED, request);
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	return_code = create_url_list(&callback_hdr, &sub->DeliveryURLs);
	if (return_code == 0) {
		error_respond(info, HTTP_PRECONDITION_FAILED, request);
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	if (return_code == UPNP_E_OUTOF_MEMORY) {
		error_respond(info, HTTP_INTERNAL_SERVER_ERROR, request);
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	/* set the timeout */
	if (httpmsg_find_hdr(request, HDR_TIMEOUT, &timeout_hdr) != NULL) {
		if (matchstr(timeout_hdr.buf, timeout_hdr.length,
		    "%iSecond-%d%0", &time_out) == PARSE_OK) {
			/* nothing */
		} else if(memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) {
			/* infinite timeout */
			time_out = -1;
		} else {
			/* default is > 1800 seconds */
			time_out = DEFAULT_TIMEOUT;
		}
	}
	/* replace infinite timeout with max timeout, if possible */
	if (handle_info->MaxSubscriptionTimeOut != -1) {
		if (time_out == -1 ||
		    time_out > handle_info->MaxSubscriptionTimeOut) {
			time_out = handle_info->MaxSubscriptionTimeOut;
		}
	}
	if (time_out >= 0) {
		sub->expireTime = time(NULL) + time_out;
	} else {
		/* infinite time */
		sub->expireTime = 0;
	}

	/* generate SID */
	uuid_create(&uid);
	upnp_uuid_unpack(&uid, temp_sid);
	rc = snprintf(sub->sid, sizeof(sub->sid), "uuid:%s", temp_sid);

	/* respond OK */
	if (rc < 0 || (unsigned int) rc >= sizeof(sub->sid) ||
		(respond_ok(info, time_out,
		sub, request) != UPNP_E_SUCCESS)) {
		freeSubscriptionList(sub);
		HandleUnlock();
		goto exit_function;
	}
	/* add to subscription list */
	sub->next = service->subscriptionList;
	service->subscriptionList = sub;
	service->TotalSubscriptions++;

	/* finally generate callback for init table dump */
	UpnpSubscriptionRequest_strcpy_ServiceId(request_struct, service->serviceId);
	UpnpSubscriptionRequest_strcpy_UDN(request_struct, service->UDN);
	UpnpSubscriptionRequest_strcpy_SID(request_struct, sub->sid);

	/* copy callback */
	callback_fun = handle_info->Callback;
	cookie = handle_info->Cookie;

	HandleUnlock();

	/* make call back with request struct */
	/* in the future should find a way of mainting that the handle */
	/* is not unregistered in the middle of a callback */
	callback_fun(UPNP_EVENT_SUBSCRIPTION_REQUEST, request_struct, cookie);

exit_function:
	UpnpSubscriptionRequest_delete(request_struct);
}
Example #12
0
void ssdp_handle_ctrlpt_msg(http_message_t *hmsg, struct sockaddr_storage *dest_addr,
			    int timeout, void *cookie)
{
	int handle;
	struct Handle_Info *ctrlpt_info = NULL;
	memptr hdr_value;
	/* byebye or alive */
	int is_byebye;
	UpnpDiscovery *param = UpnpDiscovery_new();
	int expires;
	int ret;
	SsdpEvent event;
	int nt_found;
	int usn_found;
	int st_found;
	char save_char;
	Upnp_EventType event_type;
	Upnp_FunPtr ctrlpt_callback;
	void *ctrlpt_cookie;
	ListNode *node = NULL;
	SsdpSearchArg *searchArg = NULL;
	int matched = 0;
	SSDPResultData *threadData = NULL;
	ThreadPoolJob job;

	memset(&job, 0, sizeof(job));

	/* we are assuming that there can be only one client supported at a time */
	HandleReadLock();

	if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
		HandleUnlock();
		goto end_ssdp_handle_ctrlpt_msg;
	}
	/* copy */
	ctrlpt_callback = ctrlpt_info->Callback;
	ctrlpt_cookie = ctrlpt_info->Cookie;
	HandleUnlock();
	/* search timeout */
	if (timeout) {
		ctrlpt_callback(UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie);
		goto end_ssdp_handle_ctrlpt_msg;
	}

	UpnpDiscovery_set_ErrCode(param, UPNP_E_SUCCESS);
	/* MAX-AGE, assume error */
	expires = -1;
	UpnpDiscovery_set_Expires(param, expires);
	if (httpmsg_find_hdr(hmsg, HDR_CACHE_CONTROL, &hdr_value) != NULL) {
		ret = matchstr(hdr_value.buf, hdr_value.length,
			"%imax-age = %d%0", &expires);
		UpnpDiscovery_set_Expires(param, expires);
		if (ret != PARSE_OK)
			goto end_ssdp_handle_ctrlpt_msg;
	}
	/* DATE */
	if (httpmsg_find_hdr(hmsg, HDR_DATE, &hdr_value) != NULL) {
		UpnpDiscovery_strcpy_Date(param, hdr_value.buf);
	}
	/* dest addr */
	UpnpDiscovery_set_DestAddr(param, dest_addr);
	/* EXT */
	if (httpmsg_find_hdr(hmsg, HDR_EXT, &hdr_value) != NULL) {
		UpnpDiscovery_strncpy_Ext(param, hdr_value.buf,
					  hdr_value.length);
	}
	/* LOCATION */
	if (httpmsg_find_hdr(hmsg, HDR_LOCATION, &hdr_value) != NULL) {
		UpnpDiscovery_strncpy_Location(param, hdr_value.buf,
					       hdr_value.length);
	}
	/* SERVER / USER-AGENT */
	if (httpmsg_find_hdr(hmsg, HDR_SERVER, &hdr_value) != NULL ||
	    httpmsg_find_hdr(hmsg, HDR_USER_AGENT, &hdr_value) != NULL) {
		UpnpDiscovery_strncpy_Os(param, hdr_value.buf,
					 hdr_value.length);
	}
	/* clear everything */
	event.UDN[0] = '\0';
	event.DeviceType[0] = '\0';
	event.ServiceType[0] = '\0';
	nt_found = FALSE;
	if (httpmsg_find_hdr(hmsg, HDR_NT, &hdr_value) != NULL) {
		save_char = hdr_value.buf[hdr_value.length];
		hdr_value.buf[hdr_value.length] = '\0';
		nt_found = (ssdp_request_type(hdr_value.buf, &event) == 0);
		hdr_value.buf[hdr_value.length] = save_char;
	}
	usn_found = FALSE;
	if (httpmsg_find_hdr(hmsg, HDR_USN, &hdr_value) != NULL) {
		save_char = hdr_value.buf[hdr_value.length];
		hdr_value.buf[hdr_value.length] = '\0';
		usn_found = (unique_service_name(hdr_value.buf, &event) == 0);
		hdr_value.buf[hdr_value.length] = save_char;
	}
	if (nt_found || usn_found) {
		UpnpDiscovery_strcpy_DeviceID(param, event.UDN);
		UpnpDiscovery_strcpy_DeviceType(param, event.DeviceType);
		UpnpDiscovery_strcpy_ServiceType(param, event.ServiceType);
	}
	/* ADVERT. OR BYEBYE */
	if (hmsg->is_request) {
		/* use NTS hdr to determine advert., or byebye */
		if (httpmsg_find_hdr(hmsg, HDR_NTS, &hdr_value) == NULL) {
			/* error; NTS header not found */
			goto end_ssdp_handle_ctrlpt_msg;
		}
		if (memptr_cmp(&hdr_value, "ssdp:alive") == 0) {
			is_byebye = FALSE;
		} else if (memptr_cmp(&hdr_value, "ssdp:byebye") == 0) {
			is_byebye = TRUE;
		} else {
			/* bad value */
			goto end_ssdp_handle_ctrlpt_msg;
		}
		if (is_byebye) {
			/* check device byebye */
			if (!nt_found || !usn_found) {
				/* bad byebye */
				goto end_ssdp_handle_ctrlpt_msg;
			}
			event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE;
		} else {
			/* check advertisement.
			 * Expires is valid if positive. This is for testing
			 * only. Expires should be greater than 1800 (30 mins) */
			if (!nt_found ||
			    !usn_found ||
			    UpnpString_get_Length(UpnpDiscovery_get_Location(param)) == 0 ||
			    UpnpDiscovery_get_Expires(param) <= 0) {
				/* bad advertisement */
				goto end_ssdp_handle_ctrlpt_msg;
			}
			event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
		}
		/* call callback */
		ctrlpt_callback(event_type, param, ctrlpt_cookie);
	} else {
		/* reply (to a SEARCH) */
		/* only checking to see if there is a valid ST header */
		st_found = FALSE;
		if (httpmsg_find_hdr(hmsg, HDR_ST, &hdr_value) != NULL) {
			save_char = hdr_value.buf[hdr_value.length];
			hdr_value.buf[hdr_value.length] = '\0';
			st_found =
			    ssdp_request_type(hdr_value.buf, &event) == 0;
			hdr_value.buf[hdr_value.length] = save_char;
		}
		if (hmsg->status_code != HTTP_OK ||
		    UpnpDiscovery_get_Expires(param) <= 0 ||
		    UpnpString_get_Length(UpnpDiscovery_get_Location(param)) == 0 ||
		    !usn_found || !st_found) {
			/* bad reply */
			goto end_ssdp_handle_ctrlpt_msg;
		}
		/* check each current search */
		HandleLock();
		if (GetClientHandleInfo(&handle, &ctrlpt_info) != HND_CLIENT) {
			HandleUnlock();
			goto end_ssdp_handle_ctrlpt_msg;
		}
		node = ListHead(&ctrlpt_info->SsdpSearchList);
		/* temporary add null termination */
		/*save_char = hdr_value.buf[ hdr_value.length ]; */
		/*hdr_value.buf[ hdr_value.length ] = '\0'; */
		while (node != NULL) {
			searchArg = node->item;
			/* check for match of ST header and search target */
			switch (searchArg->requestType) {
			case SSDP_ALL:
				matched = 1;
				break;
			case SSDP_ROOTDEVICE:
				matched =
				    (event.RequestType == SSDP_ROOTDEVICE);
				break;
			case SSDP_DEVICEUDN:
				matched = !strncmp(searchArg->searchTarget,
						   hdr_value.buf,
						   hdr_value.length);
				break;
			case SSDP_DEVICETYPE:{
					size_t m = min(hdr_value.length,
						       strlen
						       (searchArg->searchTarget));
					matched =
					    !strncmp(searchArg->searchTarget,
						     hdr_value.buf, m);
					break;
				}
			case SSDP_SERVICE:{
					size_t m = min(hdr_value.length,
						       strlen
						       (searchArg->searchTarget));
					matched =
					    !strncmp(searchArg->searchTarget,
						     hdr_value.buf, m);
					break;
				}
			default:
				matched = 0;
				break;
			}
			if (matched) {
				/* schedule call back */
				threadData = SSDPResultData_new();
				if (threadData != NULL) {
					SSDPResultData_set_Param(threadData,
								 param);
					SSDPResultData_set_Cookie(threadData,
								  searchArg->
								  cookie);
					SSDPResultData_set_CtrlptCallback
					    (threadData, ctrlpt_callback);
					TPJobInit(&job, (start_routine)
						  send_search_result,
						  threadData);
					TPJobSetPriority(&job, MED_PRIORITY);
					TPJobSetFreeFunction(&job,
							     (free_routine)
							     SSDPResultData_delete);
					ThreadPoolAdd(&gRecvThreadPool, &job,
						      NULL);
				}
			}
			node = ListNext(&ctrlpt_info->SsdpSearchList, node);
		}

		HandleUnlock();
		/*ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, param, cookie ); */
	}

end_ssdp_handle_ctrlpt_msg:
	UpnpDiscovery_delete(param);
}
Example #13
0
/************************************************************************
* Function : gena_subscribe									
*																	
* Parameters:														
*	IN char *url: url of service to subscribe
*	INOUT int* timeout:subscription time desired (in secs)
*	IN char* renewal_sid:for renewal, this contains a currently h
*						 held subscription SID. For first time 
*						 subscription, this must be NULL
*	OUT char** sid: SID returned by the subscription or renew msg
*
* Description:														
*	This function subscribes or renew subscription
*
* Returns: int
*	return 0 if successful else returns appropriate error
***************************************************************************/
static int
gena_subscribe( IN char *url,
                INOUT int *timeout,
                IN char *renewal_sid,
                OUT char **sid )
{
    int return_code;
    memptr sid_hdr,
      timeout_hdr;
    char timeout_str[25];
    membuffer request;
    uri_type dest_url;
    http_parser_t response;

    *sid = NULL;                // init

    // request timeout to string
    if( ( timeout == NULL ) ||
        ( ( *timeout > 0 )
          && ( *timeout < CP_MINIMUM_SUBSCRIPTION_TIME ) ) ) {
        sprintf( timeout_str, "%d", CP_MINIMUM_SUBSCRIPTION_TIME );
    } else if( *timeout >= 0 ) {
        sprintf( timeout_str, "%d", *timeout );
    } else {
        strcpy( timeout_str, "infinite" );
    }

    // parse url
    return_code = http_FixStrUrl( url, strlen( url ), &dest_url );
    if( return_code != 0 ) {
        return return_code;
    }
    // make request msg
    membuffer_init( &request );
    request.size_inc = 30;
    if( renewal_sid ) {
        // renew subscription
        return_code = http_MakeMessage( &request, 1, 1,
                                        "q" "ssc" "ssc" "c",
                                        HTTPMETHOD_SUBSCRIBE, &dest_url,
                                        "SID: ", renewal_sid,
                                        "TIMEOUT: Second-", timeout_str );
    } else {
        // subscribe
        return_code = http_MakeMessage( &request, 1, 1,
                                        "q" "sssdsscc",
                                        HTTPMETHOD_SUBSCRIBE, &dest_url,
                                        "CALLBACK: <http://", LOCAL_HOST,
                                        ":", LOCAL_PORT,
                                        "/>\r\n" "NT: upnp:event\r\n"
                                        "TIMEOUT: Second-", timeout_str );
    }
    if( return_code != 0 ) {
        return return_code;
    }
    // send request and get reply
    return_code = http_RequestAndResponse( &dest_url, request.buf,
                                           request.length,
                                           HTTPMETHOD_SUBSCRIBE,
                                           HTTP_DEFAULT_TIMEOUT,
                                           &response );

    membuffer_destroy( &request );

    if( return_code != 0 ) {
        httpmsg_destroy( &response.msg );
        return return_code;
    }
    if( response.msg.status_code != HTTP_OK ) {
        httpmsg_destroy( &response.msg );
        return UPNP_E_SUBSCRIBE_UNACCEPTED;
    }
    // get SID and TIMEOUT
    if( httpmsg_find_hdr( &response.msg, HDR_SID, &sid_hdr ) == NULL ||
        sid_hdr.length == 0 ||
        httpmsg_find_hdr( &response.msg,
                          HDR_TIMEOUT, &timeout_hdr ) == NULL ||
        timeout_hdr.length == 0 ) {
        httpmsg_destroy( &response.msg );
        return UPNP_E_BAD_RESPONSE;
    }
    // save timeout
    if( matchstr( timeout_hdr.buf, timeout_hdr.length, "%iSecond-%d%0",
                  timeout ) == PARSE_OK ) {
        // nothing  
    } else if( memptr_cmp_nocase( &timeout_hdr, "Second-infinite" ) == 0 ) {
        *timeout = -1;
    } else {
        httpmsg_destroy( &response.msg );
        return UPNP_E_BAD_RESPONSE;
    }

    // save SID
    *sid = str_alloc( sid_hdr.buf, sid_hdr.length );
    if( *sid == NULL ) {
        httpmsg_destroy( &response.msg );
        return UPNP_E_OUTOF_MEMORY;
    }

    httpmsg_destroy( &response.msg );
    return UPNP_E_SUCCESS;
}
Example #14
0
/*!
 * \brief This function retrives the name of the SOAP action.
 *
 * \return 0 if successful else returns appropriate error.
 */
static UPNP_INLINE int get_request_type(
	/*! [in] HTTP request. */
	http_message_t *request,
	/*! [out] SOAP action name. */
	memptr *action_name)
{
	memptr value;
	memptr ns_value, dummy_quote;
	http_header_t *hdr;
	char save_char;
	char *s;
	membuffer soap_action_name;
	size_t n;

	/* find soapaction header */
	if (request->method == SOAPMETHOD_POST) {
		if (!httpmsg_find_hdr(request, HDR_SOAPACTION, &value))
			return SREQ_HDR_NOT_FOUND;
	} else {
		/* M-POST */
		/* get NS value from MAN header */
		hdr = httpmsg_find_hdr(request, HDR_MAN, &value);
		if (hdr == NULL)
			return SREQ_HDR_NOT_FOUND;
		if (matchstr(value.buf, value.length, "%q%i ; ns = %s",
			     &dummy_quote, &ns_value) != 0)
			return SREQ_BAD_HDR_FORMAT;
		/* create soapaction name header */
		membuffer_init(&soap_action_name);
		if (membuffer_assign(&soap_action_name,
			ns_value.buf, ns_value.length) == UPNP_E_OUTOF_MEMORY ||
		    membuffer_append_str(&soap_action_name,
			"-SOAPACTION") == UPNP_E_OUTOF_MEMORY) {
			membuffer_destroy(&soap_action_name);
			return UPNP_E_OUTOF_MEMORY;
		}
		hdr = httpmsg_find_hdr_str(request, soap_action_name.buf);
		membuffer_destroy(&soap_action_name);
		if (!hdr)
			return SREQ_HDR_NOT_FOUND;
		value.buf = hdr->value.buf;
		value.length = hdr->value.length;
	}
	/* determine type */
	save_char = value.buf[value.length];
	value.buf[value.length] = '\0';
	s = strchr(value.buf, '#');
	if (s == NULL) {
		value.buf[value.length] = save_char;
		return SREQ_BAD_HDR_FORMAT;
	}
	/* move to value */
	s++;
	n = value.length - (size_t)(s - value.buf);
	if (matchstr(s, n, "%s", action_name) != PARSE_OK) {
		value.buf[value.length] = save_char;
		return SREQ_BAD_HDR_FORMAT;
	}
	/* action name or variable ? */
	if (memptr_cmp(action_name, "QueryStateVariable") == 0) {
		/* query variable */
		action_name->buf = NULL;
		action_name->length = 0;
	}
	/* restore */
	value.buf[value.length] = save_char;

	return 0;
}
void gena_process_notification_event(
	SOCKINFO *info,
	http_message_t *event)
{
	struct Upnp_Event event_struct;
	IXML_Document *ChangedVars = NULL;
	int eventKey;
	token sid;
	ClientSubscription *subscription = NULL;
	struct Handle_Info *handle_info;
	void *cookie;
	Upnp_FunPtr callback;
	UpnpClient_Handle client_handle;
	const UpnpString *tmpSID = NULL;

	memptr sid_hdr;
	memptr nt_hdr,
	nts_hdr;
	memptr seq_hdr;

	/* get SID */
	if (httpmsg_find_hdr(event, HDR_SID, &sid_hdr) == NULL) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		goto exit_function;
	}
	sid.buff = sid_hdr.buf;
	sid.size = sid_hdr.length;

	/* get event key */
	if (httpmsg_find_hdr(event, HDR_SEQ, &seq_hdr) == NULL ||
	    matchstr(seq_hdr.buf, seq_hdr.length, "%d%0", &eventKey) != PARSE_OK) {
		error_respond( info, HTTP_BAD_REQUEST, event );
		goto exit_function;
	}

	/* get NT and NTS headers */
	if (httpmsg_find_hdr(event, HDR_NT, &nt_hdr) == NULL ||
	    httpmsg_find_hdr(event, HDR_NTS, &nts_hdr) == NULL) {
		error_respond( info, HTTP_BAD_REQUEST, event );
		goto exit_function;
	}

	/* verify NT and NTS headers */
	if (memptr_cmp(&nt_hdr, "upnp:event") != 0 ||
	    memptr_cmp(&nts_hdr, "upnp:propchange") != 0) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		goto exit_function;
	}

	/* parse the content (should be XML) */
	if (!has_xml_content_type(event) ||
	    event->msg.length == 0 ||
	    ixmlParseBufferEx(event->entity.buf, &ChangedVars) != IXML_SUCCESS) {
		error_respond(info, HTTP_BAD_REQUEST, event);
		goto exit_function;
	}

	HandleLock();

	/* get client info */
	if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
		error_respond(info, HTTP_PRECONDITION_FAILED, event);
		HandleUnlock();
		goto exit_function;
	}

	/* get subscription based on SID */
	subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
	if (subscription == NULL) {
		if (eventKey == 0) {
			/* wait until we've finished processing a subscription  */
			/*   (if we are in the middle) */
			/* this is to avoid mistakenly rejecting the first event if we  */
			/*   receive it before the subscription response */
			HandleUnlock();

			/* try and get Subscription Lock  */
			/*   (in case we are in the process of subscribing) */
			SubscribeLock();

			/* get HandleLock again */
			HandleLock();

			if (GetClientHandleInfo(&client_handle, &handle_info) != HND_CLIENT) {
				error_respond(info, HTTP_PRECONDITION_FAILED, event);
				SubscribeUnlock();
				HandleUnlock();
				goto exit_function;
			}

			subscription = GetClientSubActualSID(handle_info->ClientSubList, &sid);
			if (subscription == NULL) {
				error_respond( info, HTTP_PRECONDITION_FAILED, event );
				SubscribeUnlock();
				HandleUnlock();
				goto exit_function;
			}

			SubscribeUnlock();
		} else {
			error_respond( info, HTTP_PRECONDITION_FAILED, event );
			HandleUnlock();
			goto exit_function;
		}
	}

	/* success */
	error_respond(info, HTTP_OK, event);

	/* fill event struct */
	tmpSID = UpnpClientSubscription_get_SID(subscription);
	memset(event_struct.Sid, 0, sizeof(event_struct.Sid));
	strncpy(event_struct.Sid, UpnpString_get_String(tmpSID),
		sizeof(event_struct.Sid) - 1);
	event_struct.EventKey = eventKey;
	event_struct.ChangedVariables = ChangedVars;

	/* copy callback */
	callback = handle_info->Callback;
	cookie = handle_info->Cookie;

	HandleUnlock();

	/* make callback with event struct */
	/* In future, should find a way of mainting */
	/* that the handle is not unregistered in the middle of a */
	/* callback */
	callback(UPNP_EVENT_RECEIVED, &event_struct, cookie);

exit_function:
	ixmlDocument_free(ChangedVars);
}
/*!
 * \brief Subscribes or renew subscription.
 *
 * \return 0 if successful, otherwise returns the appropriate error code.
 */
static int gena_subscribe(
	/*! [in] URL of service to subscribe. */
	IN const UpnpString *url,
	/*! [in,out] Subscription time desired (in secs). */
	INOUT int *timeout,
	/*! [in] for renewal, this contains a currently held subscription SID.
	 * For first time subscription, this must be NULL. */
	IN const UpnpString *renewal_sid,
	/*! [out] SID returned by the subscription or renew msg. */
	OUT UpnpString *sid)
{
	int return_code;
	int parse_ret = 0;
	int local_timeout = CP_MINIMUM_SUBSCRIPTION_TIME;
	memptr sid_hdr;
	memptr timeout_hdr;
	char timeout_str[25];
	membuffer request;
	uri_type dest_url;
	http_parser_t response;
	int rc = 0;

	UpnpString_clear(sid);

	/* request timeout to string */
	if (timeout == NULL) {
		timeout = &local_timeout;
	}
	if (*timeout < 0) {
		memset(timeout_str, 0, sizeof(timeout_str));
		strncpy(timeout_str, "infinite", sizeof(timeout_str) - 1);
	} else if(*timeout < CP_MINIMUM_SUBSCRIPTION_TIME) {
		rc = snprintf(timeout_str, sizeof(timeout_str),
			"%d", CP_MINIMUM_SUBSCRIPTION_TIME);
	} else {
		rc = snprintf(timeout_str, sizeof(timeout_str), "%d", *timeout);
	}
	if (rc < 0 || (unsigned int) rc >= sizeof(timeout_str))
		return UPNP_E_OUTOF_MEMORY;

	/* parse url */
	return_code = http_FixStrUrl(
		UpnpString_get_String(url),
		UpnpString_get_Length(url),
		&dest_url);
	if (return_code != 0) {
		return return_code;
	}

	/* make request msg */
	membuffer_init(&request);
	request.size_inc = 30;
	if (renewal_sid) {
		/* renew subscription */
		return_code = http_MakeMessage(
			&request, 1, 1,
			"q" "ssc" "sscc",
			HTTPMETHOD_SUBSCRIBE, &dest_url,
			"SID: ", UpnpString_get_String(renewal_sid),
			"TIMEOUT: Second-", timeout_str );
	} else {
		/* subscribe */
		if (dest_url.hostport.IPaddress.ss_family == AF_INET6) {
			struct sockaddr_in6* DestAddr6 = (struct sockaddr_in6*)&dest_url.hostport.IPaddress;
			return_code = http_MakeMessage(
				&request, 1, 1,
				"q" "sssdsc" "sc" "sscc",
				HTTPMETHOD_SUBSCRIBE, &dest_url,
				"CALLBACK: <http://[",
				(IN6_IS_ADDR_LINKLOCAL(&DestAddr6->sin6_addr) || strlen(gIF_IPV6_ULA_GUA) == 0) ?
					gIF_IPV6 : gIF_IPV6_ULA_GUA,
				"]:", LOCAL_PORT_V6, "/>",
				"NT: upnp:event",
				"TIMEOUT: Second-", timeout_str);
		} else {
			return_code = http_MakeMessage(
				&request, 1, 1,
				"q" "sssdsc" "sc" "sscc",
				HTTPMETHOD_SUBSCRIBE, &dest_url,
				"CALLBACK: <http://", gIF_IPV4, ":", LOCAL_PORT_V4, "/>",
				"NT: upnp:event",
				"TIMEOUT: Second-", timeout_str);
		}
	}
	if (return_code != 0) {
		return return_code;
	}

	/* send request and get reply */
	return_code = http_RequestAndResponse(&dest_url, request.buf,
		request.length,
		HTTPMETHOD_SUBSCRIBE,
		HTTP_DEFAULT_TIMEOUT,
		&response);
	membuffer_destroy(&request);

	if (return_code != 0) {
		httpmsg_destroy(&response.msg);

		return return_code;
	}
	if (response.msg.status_code != HTTP_OK) {
		httpmsg_destroy(&response.msg);

		return UPNP_E_SUBSCRIBE_UNACCEPTED;
	}

	/* get SID and TIMEOUT */
	if (httpmsg_find_hdr(&response.msg, HDR_SID, &sid_hdr) == NULL ||
	    sid_hdr.length == 0 ||
	    httpmsg_find_hdr( &response.msg, HDR_TIMEOUT, &timeout_hdr ) == NULL ||
	    timeout_hdr.length == 0 ) {
		httpmsg_destroy( &response.msg );

		return UPNP_E_BAD_RESPONSE;
	}

	/* save timeout */
	parse_ret = matchstr(timeout_hdr.buf, timeout_hdr.length, "%iSecond-%d%0", timeout);
	if (parse_ret == PARSE_OK) {
		/* nothing to do */
	} else if (memptr_cmp_nocase(&timeout_hdr, "Second-infinite") == 0) {
		*timeout = -1;
	} else {
		httpmsg_destroy( &response.msg );

		return UPNP_E_BAD_RESPONSE;
	}

	/* save SID */
	UpnpString_set_StringN(sid, sid_hdr.buf, sid_hdr.length);
	if (UpnpString_get_String(sid) == NULL) {
		httpmsg_destroy(&response.msg);

		return UPNP_E_OUTOF_MEMORY;
	}
	httpmsg_destroy(&response.msg);

	return UPNP_E_SUCCESS;
}
Example #17
0
static int process_cmd (const char *line)
{
    RESULT[0] = '\0';
    if      (matchstr (&line, "EJECT"))        return EJECT (line);
    else if (matchstr (&line, "INSERT"))       return INSERT (line);
    else if (matchstr (&line, "QUERY"))        return QUERY (line);
    else if (matchstr (&line, "FEEDBACK"))     return FEEDBACK (line);
    else if (matchstr (&line, "VERSION"))      return GET_VERSION (line);
    else if (matchstr (&line, "BYE"))          QUIT ();
    else if (matchstr (&line, "QUIT"))         QUIT ();
    else if (matchstr (&line, "DEBUG"))        return DEBUG ();
    else if (matchstr (&line, "RESET"))        m68k_reset (0);
    else if (matchstr (&line, "DISPLAY"))      return DISPLAY (line);
    else if (matchstr (&line, "FRAMERATE"))    return FRAMERATE( line);
    else if (matchstr (&line, "FAKEJOYSTICK")) return FAKEJOYSTICK (line);
    else if (matchstr (&line, "SOUND"))        return SOUND (line);
    else if (matchstr (&line, "UAEEXE"))       return UAEEXE (line);
    else return RC_ERROR;
    return RC_OK;
}
Example #18
0
/* Basic name -> sysctl MIB translation */
int
_rtld_sysctl(const char *name, void *oldp, size_t *oldlen)
{
	const char *node, *ep;
	struct sysctlnode query, *result, *newresult;
	int mib[CTL_MAXNAME], i, r;
	size_t res_size, n;
	u_int miblen = 0;

	/* Start with 16 entries, will grow it up as needed. */
	res_size = 16 * sizeof(struct sysctlnode);
	result = xmalloc(res_size);
	if (result == NULL)
		return (-1);

	ep = name + strlen(name);
	do {
		i = -1;
		while (*name == '/' || *name == '.')
			name++;
		if (name >= ep)
			break;

		mib[miblen] = CTL_QUERY;
		memset(&query, 0, sizeof(query));
		query.sysctl_flags = SYSCTL_VERSION;

		n = res_size;
		if (sysctl(mib, miblen + 1, result, &n, &query,
		    sizeof(query)) == -1) {
			if (errno != ENOMEM)
				goto bad;
			/* Grow up result */
			res_size = n;
			newresult = xrealloc(result, res_size);
			if (newresult == NULL)
				goto bad;
			result = newresult;
			if (sysctl(mib, miblen + 1, result, &n, &query,
			    sizeof(query)) == -1)
				goto bad;
		}
		n /= sizeof(struct sysctlnode);

		node = getstr(&name, ep, "./");

		for (i = 0; i < n; i++)
			if (matchstr(result[i].sysctl_name, node, name)) {
				mib[miblen] = result[i].sysctl_num;
				miblen++;
				break;
			}
	} while (name < ep && miblen <= CTL_MAXNAME);

	if (name < ep || i == -1)
		goto bad;
	r = SYSCTL_TYPE(result[i].sysctl_flags);

	xfree(result);
	if (sysctl(mib, miblen, oldp, oldlen, NULL, 0) == -1)
		return (-1);
	return r;

bad:
	xfree(result);
	return (-1);
}
/* ------------------------------------------------------------------------------------ */
Procedural* Particles_Create(char *TextureName, geWorld *World, const char *InputParams)
{
    Procedural *Proc;
    int i;
    char ParamWork[8192],*pstr;
    geBitmap	*ppBitmap;

	Proc = GE_RAM_ALLOCATE_STRUCT(Procedural);

	if(!Proc)
		return (Procedural*)NULL;

	memset(Proc, 0, sizeof(Procedural));

	ppBitmap = geWorld_GetBitmapByName(World, TextureName);

	/**** read Params *****/

// changed RF064 by QD
	if(!strcmp(InputParams, "Params_Oil"))
	{
		strcpy(ParamWork, Params_Oil);
	}
	else if(!strcmp(InputParams, "Params_Jet"))
	{
		strcpy(ParamWork,Params_Jet);
	}
	else if(!strcmp(InputParams, "Params_Steam"))
	{
		strcpy(ParamWork,Params_Steam);
	}
	else if(!strcmp(InputParams, "Params_Explosion") || strlen(InputParams) < 20 )
	{
		strcpy(ParamWork,DefaultParams);
	}
// end change RF064 by QD
	else
	{
		strcpy(ParamWork,InputParams);
	}

	pstr = strtok(ParamWork,strbreakers);

	Proc->NumParticles = getint(pstr);
	Proc->NumSources = getint(pstr);

	/**** make Bitmap *****/

	if(!Particles_InitBitmap(ppBitmap))
		goto fail;

	Proc->Bitmap = ppBitmap;

	Proc->SizeX  = geBitmap_Width(Proc->Bitmap);
	Proc->SizeY = geBitmap_Height(Proc->Bitmap);
	geBitmap_GetInfo(Proc->Bitmap, &(Proc->BmInfo), (geBitmap_Info*)NULL);
	Proc->SizeZ = min(Proc->SizeX, Proc->SizeY);

	/**** make Particles *****/

	Proc->Particles = (Particle*)geRam_AllocateClear(Proc->NumParticles * sizeof(Particle));

	if(!(Proc->Particles))
		goto fail;

	for(i=0; i<Proc->NumParticles; i++)
	{
		Proc->Particles[i].shade = -1;
	}

	Proc->NumActiveParticles = 0;

	/**** make Sources *****/

	Proc->Sources = (ParticleSource*)geRam_AllocateClear(Proc->NumSources * sizeof(ParticleSource));

	if(!(Proc->Sources))
		goto fail;

	/**** More Params *****/

	// <> for stock schemes, take a few colors as parameters

	if(matchstr(pstr, "oil"))
	{
		nextparam(pstr);
		Proc->NumColors = Proc->NumShades = 16;
		Proc->PixelRGBA = PixelRGBA_OilColor;
	}
	else if(matchstr(pstr, "fire"))
	{
		nextparam(pstr);
		Proc->NumColors = 1;
		Proc->NumShades = 256;
		Proc->PixelRGBA = PixelRGBA_FireColor;
	}
	else if(matchstr(pstr, "opaquefire"))
	{
		nextparam(pstr);
		Proc->NumColors = 1;
		Proc->NumShades = 256;
		Proc->PixelRGBA = PixelRGBA_OpaqueFireColor;
	}
	else if(matchstr(pstr, "steam"))
	{
		nextparam(pstr);
		Proc->NumColors = 1;
		Proc->NumShades = 256;
		Proc->PixelRGBA = PixelRGBA_SteamColor;
	}
	else
	{
		Proc->NumColors = getint(pstr);
		Proc->NumShades = getint(pstr);
		Proc->PixelRGBA = PixelRGBA_OilColor;
		// <>
		// way to read in general spline of colors ?
	}

	if((Proc->NumColors * Proc->NumShades) < 256)
	{
		Proc->NumColors = min(Proc->NumColors, 256);
		Proc->NumShades = 256 / Proc->NumColors;
	}

	Proc->NumSmoothes	= getint(pstr);
	Proc->SmoothRadius	= getint(pstr);

	if(matchstr(pstr, "bounce"))
	{
		Proc->Capper = Capper_Bounce;
		Proc->SmoothWrap = GE_FALSE;
	}
	else if(matchstr(pstr,"wrap"))
	{
		Proc->Capper = Capper_Wrap;
		Proc->SmoothWrap = GE_TRUE;
	}
	else if(matchstr(pstr,"hard"))
	{
		Proc->Capper = Capper_Hard;
		Proc->SmoothWrap = GE_FALSE;
	}
	else
	{
		goto fail;
	}

	nextparam(pstr);

	Proc->DoMagnetic = getbool(pstr);

	if(Proc->DoMagnetic)
	{
		getvec(pstr, &(Proc->MagneticField));
	}

	Proc->DoAttractor = getbool(pstr);

	if(Proc->DoAttractor)
	{
		Proc->AttractorStrength = getfloat(pstr); // negative for repulsive
		Proc->AttractorIsAxis = getbool(pstr);

		if(Proc->AttractorIsAxis)
		{
			getvec(pstr, &(Proc->AttractorAxis));
			geVec3d_Normalize(&(Proc->AttractorAxis));
		}

		getvec(pstr, &(Proc->AttractorPos));
		scalevec(&(Proc->AttractorPos));
	}

	/**** LUT's *****/

	if(!Particles_InitPalette(Proc))
		goto fail;

	for(i=0; i<Proc->NumSources; i++)
	{
		ParticleSource *pSource;
		Particle *pParticle;

		pSource = Proc->Sources + i;

		// base
		pParticle = &(pSource->Base);

		getvec(pstr, pParticle->p);
		getvec(pstr, pParticle->v);

		scalevec(pParticle->p);
		scalevec(pParticle->v);

		pParticle->DeathTime = getfloat(pstr);
		pParticle->color = getint(pstr);
		pParticle->shade = Proc->NumShades - 1;
		pParticle->CurDeathTime = 0.0f;

		// random
		pParticle = &(pSource->Random);

		getvec(pstr,pParticle->p);
		getvec(pstr,pParticle->v);

		scalevec(pParticle->p);
		scalevec(pParticle->v);

		absvec(pParticle->p);
		absvec(pParticle->v);

		pParticle->DeathTime = getfloat(pstr);
		pParticle->color = getint(pstr);
		pParticle->shade = getint(pstr);
		pParticle->CurDeathTime = 0.0f;

		pSource->RandomVMagnitude = geVec3d_Normalize((geVec3d*)(pParticle->v));

		pSource->Delay = getfloat(pstr); // seconds
		pSource->Base.Drag = getfloat(pstr);
		pSource->CurTime = pSource->Delay;
	}

	return Proc;

fail:

	Particles_Destroy(Proc);
	return (Procedural*)NULL;
}
Example #20
0
static int FEEDBACK (const char *line)
{
    gui_rexx_s *gui = NULL;

    if      (matchstr (&line, "LED_POW"))  gui = &gui_rexx[LED_POW];
    else if (matchstr (&line, "LED_DF0"))  gui = &gui_rexx[LED_DF0];
    else if (matchstr (&line, "LED_DF1"))  gui = &gui_rexx[LED_DF1];
    else if (matchstr (&line, "LED_DF2"))  gui = &gui_rexx[LED_DF2];
    else if (matchstr (&line, "LED_DF3"))  gui = &gui_rexx[LED_DF3];
    else if (matchstr (&line, "NAME_DF0")) gui = &gui_rexx[NAME_DF0];
    else if (matchstr (&line, "NAME_DF1")) gui = &gui_rexx[NAME_DF1];
    else if (matchstr (&line, "NAME_DF2")) gui = &gui_rexx[NAME_DF2];
    else if (matchstr (&line, "NAME_DF3")) gui = &gui_rexx[NAME_DF3];
    else if (matchstr (&line, "ON_EXIT"))  gui = &gui_rexx[ON_EXIT];
    else return RC_ERROR;

    while(1) {
	if (matchstr (&line, "ADDRESS") ||
	    matchstr (&line, "PORT")) {
	    extractstr (&line, gui->port, PORT_LEN);
	} else if (matchstr (&line,"COMMAND") ||
		   matchstr (&line,"CMD") ||
		   matchstr (&line,"CMD_ON")) {
	    extractstr (&line, gui->cmd_on,  CMD_LEN);
	} else if (matchstr(&line,"CMD_OFF")) {
	    extractstr(&line, gui->cmd_off, CMD_LEN);
	} else break;
    }
    return RC_OK;
}
Example #21
0
static int QUERY (const char *line)
{
    const char *res = NULL;

    if      (matchstr (&line, "LED_POW"))      res = led_state[0] ? "1" : "0";
    else if (matchstr (&line, "LED_DF0"))      res = led_state[1] ? "1" : "0";
    else if (matchstr (&line, "LED_DF1"))      res = led_state[2] ? "1" : "0";
    else if (matchstr (&line, "LED_DF2"))      res = led_state[3] ? "1" : "0";
    else if (matchstr (&line, "LED_DF3"))      res = led_state[4] ? "1" : "0";
    else if (matchstr (&line, "NAME_DF0"))     res = currprefs.df[0];
    else if (matchstr (&line, "NAME_DF1"))     res = currprefs.df[1];
    else if (matchstr (&line, "NAME_DF2"))     res = currprefs.df[2];
    else if (matchstr (&line, "NAME_DF3"))     res = currprefs.df[3];
    else if (matchstr (&line, "FAKEJOYSTICK")) res = 0; //res = currprefs.fake_joystick ? "1" : "0";
    else if (matchstr (&line, "DISPLAY"))      res = inhibit_frame ? "0" : "1";
    else if (matchstr (&line, "FRAMERATE")) {
	sprintf (RESULT, "%d", currprefs.gfx_framerate);
	return RC_OK;
    } else if (matchstr (&line, "FRAMENUM")) {
#ifdef USE_AMIGA_GFX
	sprintf (RESULT, "%u", frame_num);
#else
	sprintf (RESULT, "%d", 0);
#endif
	return RC_OK;
    } else if (matchstr (&line, "SOUND")) {
	sprintf (RESULT, "%d", sound_available ? currprefs.produce_sound : -1);
	return RC_OK;
    } else return RC_ERROR;

    if (res)
	strncpy (RESULT, res, RESULT_LEN);

    return RC_OK;
}
Example #22
0
/************************************************************************
* Function : ssdp_handle_ctrlpt_msg											
*																	
* Parameters:														
*	IN http_message_t* hmsg: SSDP message from the device
*	IN struct sockaddr_in* dest_addr: Address of the device
*	IN xboolean timeout: timeout kept by the control point while sending 
*						search message
*	IN void* cookie: Cookie stored by the control point application. 
*					This cookie will be returned to the control point
*					in the callback 
*																	
* Description:														
*	This function handles the ssdp messages from the devices. These 
*	messages includes the search replies, advertisement of device coming 
*	alive and bye byes.
*
* Returns: void
*
***************************************************************************/
void
ssdp_handle_ctrlpt_msg( IN http_message_t * hmsg,
                        IN struct sockaddr_in *dest_addr,
                        IN xboolean timeout,    // only in search reply

                        IN void *cookie )   // only in search reply
{
    int handle;
    struct Handle_Info *ctrlpt_info = NULL;
    memptr hdr_value;
    xboolean is_byebye;         // byebye or alive
    struct Upnp_Discovery param;
    SsdpEvent event;
    xboolean nt_found,
      usn_found,
      st_found;
    char save_char;
    Upnp_EventType event_type;
    Upnp_FunPtr ctrlpt_callback;
    void *ctrlpt_cookie;
    ListNode *node = NULL;
    SsdpSearchArg *searchArg = NULL;
    int matched = 0;
    ResultData *threadData;
    ThreadPoolJob job;

    // we are assuming that there can be only one client supported at a time

    HandleLock(  );

    if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
        HandleUnlock(  );
        return;
    }
    // copy
    ctrlpt_callback = ctrlpt_info->Callback;
    ctrlpt_cookie = ctrlpt_info->Cookie;
    HandleUnlock(  );

    // search timeout
    if( timeout ) {
        ctrlpt_callback( UPNP_DISCOVERY_SEARCH_TIMEOUT, NULL, cookie );
        return;
    }

    param.ErrCode = UPNP_E_SUCCESS;

    // MAX-AGE
    param.Expires = -1;         // assume error
    if( httpmsg_find_hdr( hmsg, HDR_CACHE_CONTROL, &hdr_value ) != NULL ) {
        matchstr( hdr_value.buf, hdr_value.length,
                  "%imax-age = %d%0", &param.Expires );
    }

    // DATE
    param.Date[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_DATE, &hdr_value ) != NULL ) {
        linecopylen( param.Date, hdr_value.buf, hdr_value.length );
    }

    // dest addr
    param.DestAddr = dest_addr;

    // EXT
    param.Ext[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_EXT, &hdr_value ) != NULL ) {
        linecopylen( param.Ext, hdr_value.buf, hdr_value.length );
    }
    // LOCATION
    param.Location[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_LOCATION, &hdr_value ) != NULL ) {
        linecopylen( param.Location, hdr_value.buf, hdr_value.length );
    }
    // SERVER / USER-AGENT
    param.Os[0] = '\0';
    if( httpmsg_find_hdr( hmsg, HDR_SERVER, &hdr_value ) != NULL ||
        httpmsg_find_hdr( hmsg, HDR_USER_AGENT, &hdr_value ) != NULL ) {
        linecopylen( param.Os, hdr_value.buf, hdr_value.length );
    }
    // clear everything
    param.DeviceId[0] = '\0';
    param.DeviceType[0] = '\0';
    param.ServiceType[0] = '\0';

    param.ServiceVer[0] = '\0'; // not used; version is in ServiceType

    event.UDN[0] = '\0';
    event.DeviceType[0] = '\0';
    event.ServiceType[0] = '\0';

    nt_found = FALSE;

    if( httpmsg_find_hdr( hmsg, HDR_NT, &hdr_value ) != NULL ) {
        save_char = hdr_value.buf[hdr_value.length];
        hdr_value.buf[hdr_value.length] = '\0';

        nt_found = ( ssdp_request_type( hdr_value.buf, &event ) == 0 );

        hdr_value.buf[hdr_value.length] = save_char;
    }

    usn_found = FALSE;
    if( httpmsg_find_hdr( hmsg, HDR_USN, &hdr_value ) != NULL ) {
        save_char = hdr_value.buf[hdr_value.length];
        hdr_value.buf[hdr_value.length] = '\0';

        usn_found = ( unique_service_name( hdr_value.buf, &event ) == 0 );

        hdr_value.buf[hdr_value.length] = save_char;
    }

    if( nt_found || usn_found ) {
        strcpy( param.DeviceId, event.UDN );
        strcpy( param.DeviceType, event.DeviceType );
        strcpy( param.ServiceType, event.ServiceType );
    }

    // ADVERT. OR BYEBYE
    if( hmsg->is_request ) {
        // use NTS hdr to determine advert., or byebye
        //
        if( httpmsg_find_hdr( hmsg, HDR_NTS, &hdr_value ) == NULL ) {
            return;             // error; NTS header not found
        }
        if( memptr_cmp( &hdr_value, "ssdp:alive" ) == 0 ) {
            is_byebye = FALSE;
        } else if( memptr_cmp( &hdr_value, "ssdp:byebye" ) == 0 ) {
            is_byebye = TRUE;
        } else {
            return;             // bad value
        }

        if( is_byebye ) {
            // check device byebye
            if( !nt_found || !usn_found ) {
                return;         // bad byebye
            }
            event_type = UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE;
        } else {
            // check advertisement      
            // .Expires is valid if positive. This is for testing
            //  only. Expires should be greater than 1800 (30 mins)
            if( !nt_found ||
                !usn_found ||
                strlen( param.Location ) == 0 || param.Expires <= 0 ) {
                return;         // bad advertisement
            }

            event_type = UPNP_DISCOVERY_ADVERTISEMENT_ALIVE;
        }

        // call callback
        ctrlpt_callback( event_type, &param, ctrlpt_cookie );

    } else                      // reply (to a SEARCH)
    {
        // only checking to see if there is a valid ST header
        st_found = FALSE;
        if( httpmsg_find_hdr( hmsg, HDR_ST, &hdr_value ) != NULL ) {
            save_char = hdr_value.buf[hdr_value.length];
            hdr_value.buf[hdr_value.length] = '\0';
            st_found = ssdp_request_type( hdr_value.buf, &event ) == 0;
            hdr_value.buf[hdr_value.length] = save_char;
        }
        if( hmsg->status_code != HTTP_OK ||
            param.Expires <= 0 ||
            strlen( param.Location ) == 0 || !usn_found || !st_found ) {
            return;             // bad reply
        }
        //check each current search
        HandleLock(  );
        if( GetClientHandleInfo( &handle, &ctrlpt_info ) != HND_CLIENT ) {
            HandleUnlock(  );
            return;
        }
        node = ListHead( &ctrlpt_info->SsdpSearchList );

        //temporary add null termination
        //save_char = hdr_value.buf[ hdr_value.length ];
        //hdr_value.buf[ hdr_value.length ] = '\0';

        while( node != NULL ) {
            searchArg = node->item;
            matched = 0;
            //check for match of ST header and search target
            switch ( searchArg->requestType ) {
                case SSDP_ALL:
                    {
                        matched = 1;
                        break;
                    }
                case SSDP_ROOTDEVICE:
                    {
                        matched = ( event.RequestType == SSDP_ROOTDEVICE );
                        break;
                    }
                case SSDP_DEVICEUDN:
                    {
                        matched = !( strncmp( searchArg->searchTarget,
                                              hdr_value.buf,
                                              hdr_value.length ) );
                        break;
                    }
                case SSDP_DEVICETYPE:
                    {
                        int m = min( hdr_value.length,
                                     strlen( searchArg->searchTarget ) );

                        matched = !( strncmp( searchArg->searchTarget,
                                              hdr_value.buf, m ) );
                        break;
                    }
                case SSDP_SERVICE:
                    {
                        int m = min( hdr_value.length,
                                     strlen( searchArg->searchTarget ) );

                        matched = !( strncmp( searchArg->searchTarget,
                                              hdr_value.buf, m ) );
                        break;
                    }
                default:
                    {
                        matched = 0;
                        break;
                    }
            }

            if( matched ) {
                //schedule call back
                threadData =
                    ( ResultData * ) malloc( sizeof( ResultData ) );
                if( threadData != NULL ) {
                    threadData->param = param;
                    threadData->cookie = searchArg->cookie;
                    threadData->ctrlpt_callback = ctrlpt_callback;
                    TPJobInit( &job, ( start_routine ) send_search_result,
                               threadData );
                    TPJobSetPriority( &job, MED_PRIORITY );
                    TPJobSetFreeFunction( &job, ( free_routine ) free );
                    ThreadPoolAdd( &gRecvThreadPool, &job, NULL );
                }
            }
            node = ListNext( &ctrlpt_info->SsdpSearchList, node );
        }

        HandleUnlock(  );
        //ctrlpt_callback( UPNP_DISCOVERY_SEARCH_RESULT, &param, cookie );
    }
}