示例#1
0
/* this is run once a second. */
static void WANIPConnection_Update(timer_t t, PService psvc)
{
    PWANIPConnectionData pdata = (PWANIPConnectionData) psvc->opaque;

    if (igd_config_generation != pdata->igd_generation) {
	pdata->igd_generation = igd_config_generation;
	mapmgr_update();
	if (pdata->nportmappings != mapmgr_port_map_count()) {
	    pdata->nportmappings = mapmgr_port_map_count();
	    mark_changed(psvc, VAR_PortMappingNumberOfEntries);
	}
    }

    update_external_address(psvc);
    update_connection_status(psvc);

    if ((psvc->flags & VAR_CHANGED) == VAR_CHANGED) {
	update_all_subscriptions(psvc);
    }
}
示例#2
0
/*
  Parse up the "Body>".  The element immediately after
  that will be the name of the action to invoke,
  possibly preceded by a namespace.

  The action name may be followed by whitespace and
  other attributes, like namespace, etc., or it may
  immediatly by followed by the closing angle-bracket
  '>'.

  The elements contains within the action name are the
  arguments, also possibly preceded by a namespace
  (although the SOAP spec says they should not be)

  The list of argument will be terminated by a closing
  element that corresponds to the action name, also
  possibly preceded by a namespace.

*/
void soap_action(UFILE *up, PService psvc, char *soapaction, char *body)
{
    char *ac, *u, *actstart, *colon;
    var_entry_t args[10];
    int nargs = 0;
    char *argstart, *argend;
    char *valstart, *valend;
    char *sp, *eb;
    char pattern[80];

    // split out the action name.
    if (soapaction != NULL && (ac = index(soapaction, '#')) != NULL) {
	ac++;

	snprintf(pattern, sizeof(pattern), ":Body>");
	if ((u = strstr(body, pattern)) != NULL) {
	    body = u + 1;
	    if ((u = strstr(body, "<")) != NULL) {
		body = u + 1;
		actstart = body;
		sp = index(body, ' ');
		eb = index(body, '>');
		if (sp && eb) {
		    if (sp < eb) 
			*sp = '\0';
		    body = eb + 1;
		    if (body[-2] != '/') {
			snprintf(pattern, sizeof(pattern), "</%s", actstart);
			do {
			    // parse each argument and put it into a list of <name, value> pointers.
			    if ((argstart = strstr(body, "<")) == NULL) 
				break;

			    // if we are at the end of the argument list, 
			    // break out of the loop.
			    if (strncmp(argstart, pattern, strlen(pattern)) == 0) 
				break;
			    
			    argstart++;  // advance over the '<'

			    // although it is contrary to the spec, 
			    // some argument elements may have a namespace prefix.
			    // in partcular, QueryStateVariable actions from windows XP
			    // appear to do this but actions from Messenger do not.
			    // In any case, be prepared to skip the namespace prefix.
			    sp = index(argstart, ' ');
			    eb = index(argstart, '>');
			    if (sp && eb && sp < eb) 
				*sp = '\0';
			    *eb = '\0';
			    argend = eb;
			    
			    // DO NOT move this above the setting of argend to '/0'!!!!
			    if ((colon = index(argstart, ':')) != NULL) 
				argstart = colon + 1;
			    
			    if (argend[-1] == '/') {
				valstart = valend = argend;
			    } else {
				valstart = argend + 1;
				if ((valend = index(valstart, '<')) == NULL) 
				    break;
				*valend = '\0';
			    }

			    // put this argument into the arg list.
			    args[nargs].name = argstart;
			    args[nargs].value = valstart;
			    nargs++;
			    
			    // point to the beginning of the next argument.
			    body = valend + 1;
			} while (*body);
		    }
		}
	    }
	}

	// invoke that action
	UPNP_ACTION(psvc, ac, args, nargs);

	if ( strcmp(ac, "QueryStateVariable") == 0 ) {
	    QueryStateVariable( up, psvc, ac, args, nargs);
	} else {
	    dispatch( up, psvc, ac, args, nargs );
	}
	if ((psvc->flags & VAR_CHANGED) == VAR_CHANGED) {
	    update_all_subscriptions(psvc);
	}

    } else {
	soap_error( up, SOAP_INVALID_ACTION );
    }
}