DBusHandlerResult avahi_service_resolver_event (AvahiClient *client, AvahiResolverEvent event, DBusMessage *message) {
    AvahiServiceResolver *r = NULL;
    DBusError error;
    const char *path;
    AvahiStringList *strlst = NULL;

    assert(client);
    assert(message);
    
    dbus_error_init (&error);

    if (!(path = dbus_message_get_path(message)))
        goto fail;

    for (r = client->service_resolvers; r; r = r->service_resolvers_next)
        if (strcmp (r->path, path) == 0)
            break;

    if (!r)
        goto fail;

    switch (event) {
        case AVAHI_RESOLVER_FOUND: {
            int j;
            int32_t interface, protocol, aprotocol;
            uint32_t flags;
            char *name, *type, *domain, *host, *address;
            uint16_t port;
            DBusMessageIter iter, sub;
            AvahiAddress a;
            
            if (!dbus_message_get_args(
                    message, &error,
                    DBUS_TYPE_INT32, &interface,
                    DBUS_TYPE_INT32, &protocol,
                    DBUS_TYPE_STRING, &name,
                    DBUS_TYPE_STRING, &type,
                    DBUS_TYPE_STRING, &domain,
                    DBUS_TYPE_STRING, &host,
                    DBUS_TYPE_INT32, &aprotocol,
                    DBUS_TYPE_STRING, &address,
                    DBUS_TYPE_UINT16, &port,
                    DBUS_TYPE_INVALID) ||
                dbus_error_is_set (&error)) {
            
                fprintf(stderr, "Failed to parse resolver event.\n");
                goto fail;
            }
        
            dbus_message_iter_init(message, &iter);
        
            for (j = 0; j < 9; j++)
                dbus_message_iter_next(&iter);
        
            if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
                dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_ARRAY) {
                fprintf(stderr, "Error parsing service resolving message\n");
                goto fail;
            }
        
            strlst = NULL;
            dbus_message_iter_recurse(&iter, &sub);
        
            for (;;) {
                DBusMessageIter sub2;
                int at;
                const uint8_t *k;
                int n;
            
                if ((at = dbus_message_iter_get_arg_type(&sub)) == DBUS_TYPE_INVALID)
                    break;
            
                assert(at == DBUS_TYPE_ARRAY);
            
                if (dbus_message_iter_get_element_type(&sub) != DBUS_TYPE_BYTE) {
                    fprintf(stderr, "Error parsing service resolving message\n");
                    goto fail;
                }
            
                dbus_message_iter_recurse(&sub, &sub2);

                k = NULL; n = 0;
                dbus_message_iter_get_fixed_array(&sub2, &k, &n);
                if (k && n > 0)
                    strlst = avahi_string_list_add_arbitrary(strlst, k, n);
            
                dbus_message_iter_next(&sub);
            }

            dbus_message_iter_next(&iter);

            if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) {
                fprintf(stderr, "Failed to parse resolver event.\n");
                goto fail;
            }

            dbus_message_iter_get_basic(&iter, &flags);
                                    
            assert(address);

            if (address[0] == 0)
                address = NULL;
	    else
            	avahi_address_parse(address, (AvahiProtocol) aprotocol, &a);
    
            r->callback(r, (AvahiIfIndex) interface, (AvahiProtocol) protocol, AVAHI_RESOLVER_FOUND, name, type, domain, host, address ? &a : NULL, port, strlst, (AvahiLookupResultFlags) flags, r->userdata);
        
            avahi_string_list_free(strlst);
            break;
        }
            
        case AVAHI_RESOLVER_FAILURE: {
            char *etxt;
            
            if (!dbus_message_get_args(
                    message, &error,
                    DBUS_TYPE_STRING, &etxt,
                    DBUS_TYPE_INVALID) ||
                dbus_error_is_set (&error)) {
                fprintf(stderr, "Failed to parse resolver event.\n");
                goto fail;
            }
            
            avahi_client_set_errno(r->client, avahi_error_dbus_to_number(etxt));
            r->callback(r, r->interface, r->protocol, event, r->name, r->type, r->domain, NULL, NULL, 0, NULL, 0, r->userdata);
            break;
        }
    }

    return DBUS_HANDLER_RESULT_HANDLED;

    
fail:
    dbus_error_free (&error);
    avahi_string_list_free(strlst);
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
示例#2
0
int main(AVAHI_GCC_UNUSED int argc, AVAHI_GCC_UNUSED char *argv[]) {
    char *t, *v;
    uint8_t data[1024];
    AvahiStringList *a = NULL, *b, *p;
    size_t size, n;
    int r;

    a = avahi_string_list_new("prefix", "a", "b", NULL);
    
    a = avahi_string_list_add(a, "start");
    a = avahi_string_list_add(a, "foo=99");
    a = avahi_string_list_add(a, "bar");
    a = avahi_string_list_add(a, "");
    a = avahi_string_list_add(a, "");
    a = avahi_string_list_add(a, "quux");
    a = avahi_string_list_add(a, "");
    a = avahi_string_list_add_arbitrary(a, (const uint8_t*) "null\0null", 9);
    a = avahi_string_list_add_printf(a, "seven=%i %c", 7, 'x');
    a = avahi_string_list_add_pair(a, "blubb", "blaa");
    a = avahi_string_list_add_pair(a, "uxknurz", NULL);
    a = avahi_string_list_add_pair_arbitrary(a, "uxknurz2", (const uint8_t*) "blafasel\0oerks", 14);
    
    a = avahi_string_list_add(a, "end");

    t = avahi_string_list_to_string(a);
    printf("--%s--\n", t);
    avahi_free(t);
    
    n = avahi_string_list_serialize(a, NULL, 0);
    size = avahi_string_list_serialize(a, data, sizeof(data));
    assert(size == n);

    printf("%u\n", size);

    for (t = (char*) data, n = 0; n < size; n++, t++) {
        if (*t <= 32)
            printf("(%u)", *t);
        else
            printf("%c", *t);
    }

    printf("\n");
    
    assert(avahi_string_list_parse(data, size, &b) == 0);

    printf("equal: %i\n", avahi_string_list_equal(a, b));
    
    t = avahi_string_list_to_string(b);
    printf("--%s--\n", t);
    avahi_free(t);

    avahi_string_list_free(b);

    b = avahi_string_list_copy(a);

    assert(avahi_string_list_equal(a, b));

    t = avahi_string_list_to_string(b);
    printf("--%s--\n", t);
    avahi_free(t);

    p = avahi_string_list_find(a, "seven");
    assert(p);
    
    r = avahi_string_list_get_pair(p, &t, &v, NULL);  
    assert(r >= 0);
    assert(t);
    assert(v);
    
    printf("<%s>=<%s>\n", t, v);
    avahi_free(t);
    avahi_free(v);

    p = avahi_string_list_find(a, "quux");
    assert(p);

    r = avahi_string_list_get_pair(p, &t, &v, NULL);
    assert(r >= 0);
    assert(t);
    assert(!v);

    printf("<%s>=<%s>\n", t, v);
    avahi_free(t);
    avahi_free(v);
    
    avahi_string_list_free(a);
    avahi_string_list_free(b);

    n = avahi_string_list_serialize(NULL, NULL, 0);
    size = avahi_string_list_serialize(NULL, data, sizeof(data));
    assert(size == 1);
    assert(size == n);

    assert(avahi_string_list_parse(data, size, &a) == 0);
    assert(!a);
    
    return 0;
}