Home | History | Annotate | Download | only in patches
      1 --- /usr/tmp/clean/avahi-0.6.12/avahi-core/entry.c	2006-03-02 01:30:17.000000000 +0000
      2 +++ avahi-0.6.12/avahi-core/entry.c	2006-08-28 14:26:37.958555000 +0100
      3 @@ -52,6 +52,33 @@
      4  #include "rr-util.h"
      5  #include "domain-util.h"
      6  
      7 +#ifdef HAVE_BONJOUR
      8 +
      9 +struct AvahiService {
     10 +    AvahiServer *server;
     11 +    AvahiSEntryGroup *group;
     12 +
     13 +    int dead;
     14 +
     15 +    AvahiPublishFlags flags;
     16 +    AvahiIfIndex interface;
     17 +    AvahiProtocol protocol;
     18 +
     19 +    char *name;
     20 +    char *type;
     21 +    char *domain;
     22 +    char *host;
     23 +    uint16_t port;
     24 +
     25 +    AvahiWatch *watch;
     26 +    DNSServiceRef client;
     27 +    size_t txtlen;
     28 +    uint8_t *txtrecord;
     29 +
     30 +    AVAHI_LLIST_FIELDS(AvahiService, services);
     31 +};
     32 +#endif
     33 +
     34  static void transport_flags_from_domain(AvahiServer *s, AvahiPublishFlags *flags, const char *domain) {
     35      assert(flags);
     36      assert(domain);
     37 @@ -71,13 +98,146 @@
     38          *flags |= AVAHI_PUBLISH_USE_WIDE_AREA;
     39  }
     40  
     41 +#ifdef HAVE_BONJOUR
     42 +static void register_service_reply(DNSServiceRef client, const DNSServiceFlags flags, DNSServiceErrorType errorCode,
     43 +        const char *name, const char *regtype, const char *domain, void *context) {
     44 +    AvahiService *as = context;
     45 +
     46 +    switch (errorCode) {
     47 +        case kDNSServiceErr_NoError:
     48 +            as->group->n_probing--;
     49 +            if (as->group->n_probing == 0) {
     50 +                avahi_s_entry_group_change_state(as->group, AVAHI_ENTRY_GROUP_ESTABLISHED);
     51 +            }
     52 +            break;
     53 +        case kDNSServiceErr_NameConflict:
     54 +            avahi_s_entry_group_change_state(as->group, AVAHI_ENTRY_GROUP_COLLISION);
     55 +            break;
     56 +        default: 
     57 +            avahi_s_entry_group_change_state(as->group, AVAHI_ENTRY_GROUP_FAILURE);
     58 +    }
     59 +}
     60 +
     61 +static void register_service_socket_event(AvahiWatch *w, int fd, AvahiWatchEvent events, void *userdata) {
     62 +    AvahiService *as = userdata;
     63 +    DNSServiceErrorType ret;
     64 +
     65 +    assert(w);
     66 +    assert(fd >= 0);
     67 +    assert(events & AVAHI_WATCH_IN);
     68 +
     69 +    assert (fd == DNSServiceRefSockFD(as->client));
     70 +    ret = DNSServiceProcessResult(as->client);
     71 +    if (ret != kDNSServiceErr_NoError) {
     72 +        if (as->watch) {
     73 +            as->server->poll_api->watch_free(as->watch);
     74 +            as->watch = NULL;
     75 +        }
     76 +        DNSServiceRefDeallocate(as->client);
     77 +        as->client = NULL;
     78 +        avahi_s_entry_group_change_state(as->group, AVAHI_ENTRY_GROUP_FAILURE);
     79 +    }
     80 +}
     81 +
     82 +static void avahi_service_free(AvahiServer*s, AvahiService *as) {
     83 +    AvahiService *t;
     84 +
     85 +    assert(s);
     86 +    assert(as);
     87 +
     88 +    /* Remove from linked list */
     89 +    AVAHI_LLIST_REMOVE(AvahiService, services, s->services, as);
     90 +
     91 +    /* Remove from associated group */
     92 +    if (as->group)
     93 +        AVAHI_LLIST_REMOVE(AvahiService, services, as->group->services, as);
     94 +
     95 +    if (as->name)
     96 +        avahi_free(as->name);
     97 +
     98 +    if (as->type)
     99 +        avahi_free(as->type);
    100 +
    101 +    if (as->domain)
    102 +        avahi_free(as->domain);
    103 +
    104 +    if (as->host)
    105 +        avahi_free(as->host);
    106 +
    107 +    if (as->watch)
    108 +        s->poll_api->watch_free(as->watch);
    109 +    
    110 +    if (as->client)
    111 +        DNSServiceRefDeallocate (as->client);
    112 +
    113 +    if (as->txtrecord)
    114 +        avahi_free(as->txtrecord);
    115 +
    116 +    avahi_free(as);
    117 +}
    118 +
    119 +static void avahi_register_service(AvahiServer *s, AvahiService *as) {
    120 +    DNSServiceErrorType ret;
    121 +
    122 +    ret = DNSServiceRegister(&as->client, 
    123 +              as->interface == AVAHI_IF_UNSPEC ? 
    124 +                  kDNSServiceInterfaceIndexAny :
    125 +                  as->interface,
    126 +              0, 
    127 +              as->name,
    128 +              as->type,
    129 +              as->domain,
    130 +              as->host,
    131 +              htons(as->port),
    132 +              as->txtlen,
    133 +              as->txtrecord,
    134 +              register_service_reply,
    135 +              as);
    136 +    if (ret == kDNSServiceErr_NoError) {
    137 +        if  (!as->client) {
    138 +            avahi_s_entry_group_change_state(as->group, AVAHI_ENTRY_GROUP_FAILURE);
    139 +        } else {
    140 +            as->group->n_probing++;
    141 +            as->watch = s->poll_api->watch_new(s->poll_api, DNSServiceRefSockFD(as->client), AVAHI_WATCH_IN, register_service_socket_event, as);
    142 +        } 
    143 +    } else {
    144 +        if (ret == kDNSServiceErr_NameConflict) {
    145 +            avahi_s_entry_group_change_state(as->group, AVAHI_ENTRY_GROUP_COLLISION);
    146 +        }
    147 +        else {
    148 +            avahi_s_entry_group_change_state(as->group, AVAHI_ENTRY_GROUP_FAILURE);
    149 +        }
    150 +    }
    151 +}
    152 +
    153 +static void register_record_reply(DNSServiceRef client, DNSRecordRef recordref, const DNSServiceFlags flags, DNSServiceErrorType errorCode, void *context) {
    154 +    AvahiEntry *e = context;
    155 +    DNSServiceErrorType ret;
    156 +    
    157 +    switch (errorCode) {
    158 +        case kDNSServiceErr_NoError:
    159 +            break;
    160 +        case kDNSServiceErr_NameConflict:
    161 +            e->recordref = NULL;
    162 +            avahi_server_set_errno(e->server, AVAHI_ERR_COLLISION);
    163 +            break;
    164 +        default: 
    165 +            e->recordref = NULL;
    166 +            avahi_server_set_errno(e->server, AVAHI_ERR_FAILURE);
    167 +            break;
    168 +    }
    169 +}
    170 +#endif
    171 +
    172  void avahi_entry_free(AvahiServer*s, AvahiEntry *e) {
    173      AvahiEntry *t;
    174  
    175      assert(s);
    176      assert(e);
    177  
    178 +#ifndef HAVE_BONJOUR
    179      avahi_goodbye_entry(s, e, 1, 1);
    180 +#endif
    181  
    182      /* Remove from linked list */
    183      AVAHI_LLIST_REMOVE(AvahiEntry, entries, s->entries, e);
    184 @@ -104,6 +264,15 @@
    185  
    186      while (g->entries)
    187          avahi_entry_free(s, g->entries);
    188 +#ifdef HAVE_BONJOUR
    189 +    while (g->services)
    190 +        avahi_service_free(s, g->services);
    191 +
    192 +    if (g->record_connection) {
    193 +        DNSServiceRefDeallocate(g->record_connection);
    194 +        g->record_connection = NULL;
    195 +    }
    196 +#endif
    197  
    198      if (g->register_time_event)
    199          avahi_time_event_free(g->register_time_event);
    200 @@ -141,6 +310,21 @@
    201          s->need_entry_cleanup = 0;
    202      }
    203  
    204 +#ifdef HAVE_BONJOUR
    205 +    if (s->need_service_cleanup) {
    206 +        AvahiService *as, *next;
    207 +        
    208 +        for (as = s->services; as; as = next) {
    209 +            next = as->services_next;
    210 +            
    211 +            if (as->dead)
    212 +                avahi_service_free(s, as);
    213 +        }
    214 +
    215 +        s->need_service_cleanup = 0;
    216 +    }
    217 +#endif
    218 +
    219      if (s->need_browser_cleanup)
    220          avahi_browser_cleanup(s);
    221  }
    222 @@ -226,7 +410,7 @@
    223          int is_first = 1;
    224          
    225          /* Update and existing record */
    226 -
    227 + 
    228          /* Find the first matching entry */
    229          for (e = avahi_hashmap_lookup(s->entries_by_key, r->key); e; e = e->by_key_next) {
    230              if (!e->dead && e->group == g && e->interface == interface && e->protocol == protocol)
    231 @@ -237,8 +421,54 @@
    232  
    233          /* Hmm, nothing found? */
    234          if (!e) {
    235 +#ifdef HAVE_BONJOUR
    236 +            /*
    237 +             * Assume that we are updating a service's primary TXT record
    238 +             * so find the service
    239 +             */
    240 +            DNSServiceErrorType ret;
    241 +            uint16_t rlen;
    242 +            uint8_t rdata[AVAHI_DNS_RDATA_MAX];
    243 +            size_t l;
    244 +            AvahiService *as;
    245 +            int found_as = 0;
    246 +
    247 +            for (as = g->services; as; as = as->services_next) {
    248 +                int a_ret = AVAHI_OK;
    249 +                char svc_name[AVAHI_DOMAIN_NAME_MAX];
    250 +
    251 +                if ((a_ret = avahi_service_name_join(svc_name, sizeof(svc_name), as->name, as->type, as->domain ? as->domain : s->domain_name)) < 0) {
    252 +                      avahi_server_set_errno(s, a_ret);
    253 +                      return NULL;
    254 +                }
    255 +                if (!strcmp(svc_name, r->key->name)) {
    256 +                    found_as = 1;
    257 +                    break;
    258 +                }
    259 +            }
    260 +
    261 +            if (!found_as) {
    262 +                avahi_server_set_errno(s, AVAHI_ERR_NOT_FOUND);
    263 +                return NULL;
    264 +            }
    265 +            if ((l = avahi_rdata_serialize(r, rdata, sizeof(rdata))) == (size_t) -1) {
    266 +                avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    267 +                return NULL;
    268 +            }
    269 +            ret = DNSServiceUpdateRecord(as->client,
    270 +                                         NULL,
    271 +                                         0,
    272 +                                         l,
    273 +                                         rdata,
    274 +                                         r->ttl);
    275 +            if (ret != kDNSServiceErr_NoError) {
    276 +                avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    277 +            }
    278 +            return NULL;
    279 +#else
    280              avahi_server_set_errno(s, AVAHI_ERR_NOT_FOUND);
    281              return NULL;
    282 +#endif
    283          }
    284  
    285          /* Update the entry */
    286 @@ -248,6 +478,36 @@
    287  
    288          /* Announce our changes when needed */
    289          if (!avahi_record_equal_no_ttl(old_record, r) && (!g || g->state != AVAHI_ENTRY_GROUP_UNCOMMITED)) {
    290 +#ifdef HAVE_BONJOUR
    291 +            DNSServiceErrorType ret;
    292 +            uint16_t rlen;
    293 +            uint8_t rdata[AVAHI_DNS_RDATA_MAX];
    294 +            size_t l;
    295 +
    296 +            if (!g->record_connection) {
    297 +                if (DNSServiceCreateConnection(&g->record_connection) != kDNSServiceErr_NoError) {
    298 +                    avahi_entry_free(s, e);
    299 +                    avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    300 +                    return NULL;
    301 +                }
    302 +            }
    303 +            if ((l = avahi_rdata_serialize(r, rdata, sizeof(rdata))) == (size_t) -1) {
    304 +                avahi_entry_free(s, e);
    305 +                avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    306 +                return NULL;
    307 +            }
    308 +            ret = DNSServiceUpdateRecord(g->record_connection,
    309 +                                         e->recordref,
    310 +                                         0,
    311 +                                         l,
    312 +                                         rdata,
    313 +                                         r->ttl);
    314 +            if (ret != kDNSServiceErr_NoError) {
    315 +                avahi_entry_free(s, e);
    316 +                avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    317 +                return NULL;
    318 +            }
    319 +#else
    320  
    321              /* Remove the old entry from all caches, if needed */
    322              if (!(e->flags & AVAHI_PUBLISH_UNIQUE))
    323 @@ -255,6 +515,7 @@
    324  
    325              /* Reannounce our updated entry */
    326              avahi_reannounce_entry(s, e);
    327 +#endif
    328          }
    329  
    330          /* If we were the first entry in the list, we need to update the key */
    331 @@ -265,6 +526,14 @@
    332  
    333      } else {
    334          AvahiEntry *t;
    335 +#ifdef HAVE_BONJOUR
    336 +        DNSServiceErrorType ret;
    337 +        DNSServiceFlags bflags;
    338 +        uint16_t rlen;
    339 +        uint8_t rdata[AVAHI_DNS_RDATA_MAX];
    340 +        size_t l;
    341 +        char *record_name;
    342 +#endif
    343  
    344          /* Add a new record */
    345      
    346 @@ -299,7 +568,69 @@
    347          if (g)
    348              AVAHI_LLIST_PREPEND(AvahiEntry, by_group, g->entries, e); 
    349          
    350 +#ifdef HAVE_BONJOUR
    351 +        e->recordref = NULL; 
    352 +        if (!g->record_connection) {
    353 +            if (DNSServiceCreateConnection(&g->record_connection) != kDNSServiceErr_NoError) {
    354 +                avahi_entry_free(s, e);
    355 +                avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    356 +                return NULL;
    357 +            }
    358 +        }
    359 +        bflags = 0;
    360 +        if (flags & AVAHI_PUBLISH_ALLOW_MULTIPLE)
    361 +            bflags |= kDNSServiceFlagsShared;
    362 +        else
    363 +            bflags |= kDNSServiceFlagsUnique;
    364 +
    365 +        switch (r->key->type) {
    366 +            case AVAHI_DNS_TYPE_A:
    367 +            case AVAHI_DNS_TYPE_AAAA:
    368 +                record_name = avahi_strdup(r->key->name);
    369 +                break;
    370 +            default:
    371 +                record_name = avahi_malloc(strlen(r->key->name) + strlen(s->host_name_fqdn) + 2);
    372 +                strcpy(record_name, r->key->name);
    373 +                strcat(record_name, ".");
    374 +                strcat(record_name, s->host_name_fqdn);
    375 +                break;
    376 +        }
    377 +
    378 +        if ((l = avahi_rdata_serialize(r, rdata, sizeof(rdata))) == (size_t) -1) {
    379 +            avahi_entry_free(s, e);
    380 +            avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    381 +            return NULL;
    382 +        }
    383 +
    384 +        ret = DNSServiceRegisterRecord(g->record_connection,
    385 +                  &e->recordref,
    386 +                  bflags,
    387 +                  interface == AVAHI_IF_UNSPEC ? 
    388 +                      kDNSServiceInterfaceIndexAny :
    389 +                      interface,
    390 +                  record_name,
    391 +                  r->key->type,
    392 +                  r->key->clazz,
    393 +                  l,
    394 +                  rdata,
    395 +                  r->ttl,
    396 +                  register_record_reply,
    397 +                  e);
    398 +        if (ret == kDNSServiceErr_NoError) {
    399 +            ret = DNSServiceProcessResult(g->record_connection);
    400 +            if (ret != kDNSServiceErr_NoError || e->recordref == NULL) {
    401 +                avahi_entry_free(s, e);
    402 +                return NULL;
    403 +            }
    404 +        } else {
    405 +            avahi_entry_free(s, e);
    406 +            avahi_server_set_errno(s, AVAHI_ERR_FAILURE);
    407 +            return NULL;
    408 +        }
    409 +        avahi_free(record_name);
    410 +#else
    411          avahi_announce_entry(s, e);
    412 +#endif
    413      }
    414  
    415      return e;
    416 @@ -575,7 +906,10 @@
    417      AvahiRecord *r = NULL;
    418      int ret = AVAHI_OK;
    419      AvahiEntry *srv_entry = NULL, *txt_entry = NULL, *ptr_entry = NULL, *enum_entry = NULL;
    420 -    
    421 +#ifdef HAVE_BONJOUR
    422 +    AvahiService *as;
    423 +#endif
    424 + 
    425      assert(s);
    426      assert(type);
    427      assert(name);
    428 @@ -595,6 +929,36 @@
    429      if (!domain)
    430          domain = s->domain_name;
    431  
    432 +#ifdef HAVE_BONJOUR
    433 +    as = avahi_new (AvahiService, 1);
    434 +    as->server = s;
    435 +    as->group = g;
    436 +    as->dead = 0;
    437 +    as->flags = flags;
    438 +    as->interface = interface;
    439 +    as->protocol = protocol;
    440 +    as->name = avahi_strdup(name);
    441 +    as->type = avahi_strdup(type);
    442 +    as->domain = avahi_strdup(domain);
    443 +    as->host = avahi_strdup(host);
    444 +    as->port = port;
    445 +    as->watch = NULL;
    446 +    as->client = NULL;
    447 +    as->txtlen = avahi_string_list_serialize(strlst, NULL, 0);
    448 +    if (as->txtlen > 0) {
    449 +        as->txtrecord = avahi_new(uint8_t, as->txtlen);
    450 +        if (as->txtrecord == NULL) {
    451 +            as->txtlen = 0;
    452 +            ret = avahi_server_set_errno(s, AVAHI_ERR_NO_MEMORY);
    453 +            goto fail;
    454 +        }
    455 +        avahi_string_list_serialize(strlst, as->txtrecord, as->txtlen);
    456 +    } else
    457 +        as->txtrecord = NULL;
    458 +
    459 +    AVAHI_LLIST_PREPEND(AvahiService, services, s->services, as);
    460 +    AVAHI_LLIST_PREPEND(AvahiService, services, g->services, as);
    461 +#else
    462      if (!host)
    463          host = s->host_name_fqdn;
    464  
    465 @@ -659,6 +1023,7 @@
    466          ret = avahi_server_errno(s);
    467          goto fail;
    468      }
    469 +#endif
    470  
    471  fail:
    472      if (ret != AVAHI_OK && !(flags & AVAHI_PUBLISH_UPDATE)) {
    473 @@ -938,6 +1303,18 @@
    474      return e;
    475  }
    476  
    477 +#ifdef HAVE_BONJOUR
    478 +static void server_cleanup_time_event_callback(AVAHI_GCC_UNUSED AvahiTimeEvent *e, void* userdata) {
    479 +    AvahiServer *s = userdata;
    480 +    assert(s);
    481 +
    482 +    avahi_time_event_free(s->cleanup_time_event);
    483 +    s->cleanup_time_event = NULL;
    484 +    
    485 +    avahi_cleanup_dead_entries(s);
    486 +}
    487 +#endif
    488 +
    489  int avahi_server_add_dns_server_address(
    490      AvahiServer *s,
    491      AvahiSEntryGroup *g,
    492 @@ -1005,7 +1382,11 @@
    493      if (g->state == state)
    494          return;
    495  
    496 +#ifdef HAVE_BONJOUR
    497 +    assert(state <= AVAHI_ENTRY_GROUP_FAILURE);
    498 +#else
    499      assert(state <= AVAHI_ENTRY_GROUP_COLLISION);
    500 +#endif
    501  
    502      if (g->state == AVAHI_ENTRY_GROUP_ESTABLISHED) {
    503  
    504 @@ -1050,6 +1431,10 @@
    505      g->register_time.tv_sec = 0;
    506      g->register_time.tv_usec = 0;
    507      AVAHI_LLIST_HEAD_INIT(AvahiEntry, g->entries);
    508 +#ifdef HAVE_BONJOUR
    509 +    AVAHI_LLIST_HEAD_INIT(AvahiService, g->services);
    510 +    g->record_connection = NULL;
    511 +#endif
    512  
    513      AVAHI_LLIST_PREPEND(AvahiSEntryGroup, groups, s->groups, g);
    514      return g;
    515 @@ -1057,16 +1442,26 @@
    516  
    517  void avahi_s_entry_group_free(AvahiSEntryGroup *g) {
    518      AvahiEntry *e;
    519 +#ifdef HAVE_BONJOUR
    520 +    AvahiService *s;
    521 +#endif
    522      
    523      assert(g);
    524      assert(g->server);
    525  
    526      for (e = g->entries; e; e = e->by_group_next) {
    527          if (!e->dead) {
    528 +#ifndef HAVE_BONJOUR
    529              avahi_goodbye_entry(g->server, e, 1, 1);
    530 +#endif
    531              e->dead = 1;
    532          }
    533      }
    534 +#ifdef HAVE_BONJOUR
    535 +    for (s = g->services; s; s = s->services_next) {
    536 +        s->dead = 1;
    537 +    }
    538 +#endif
    539  
    540      if (g->register_time_event) {
    541          avahi_time_event_free(g->register_time_event);
    542 @@ -1077,9 +1472,17 @@
    543      
    544      g->server->need_group_cleanup = 1;
    545      g->server->need_entry_cleanup = 1;
    546 +#ifdef HAVE_BONJOUR
    547 +    g->server->need_service_cleanup = 1;
    548 +    if (!g->server->cleanup_time_event)
    549 +        g->server->cleanup_time_event = avahi_time_event_new(g->server->time_event_queue, NULL, server_cleanup_time_event_callback, g->server);
    550 +#endif
    551  }
    552  
    553  static void entry_group_commit_real(AvahiSEntryGroup *g) {
    554 +#ifdef HAVE_BONJOUR
    555 +    AvahiService *s;
    556 +#endif
    557      assert(g);
    558  
    559      gettimeofday(&g->register_time, NULL);
    560 @@ -1089,8 +1492,15 @@
    561      if (g->dead)
    562          return;
    563  
    564 +#ifdef HAVE_BONJOUR
    565 +    assert(g->server);
    566 +    for (s = g->services; s; s = s->services_next)
    567 +        if (!s->dead)
    568 +            avahi_register_service(g->server, s);
    569 +#else
    570      avahi_announce_group(g->server, g);
    571      avahi_s_entry_group_check_probed(g, 0);
    572 +#endif
    573  }
    574  
    575  static void entry_group_register_time_event_callback(AVAHI_GCC_UNUSED AvahiTimeEvent *e, void* userdata) {
    576 @@ -1143,16 +1553,29 @@
    577  
    578  void avahi_s_entry_group_reset(AvahiSEntryGroup *g) {
    579      AvahiEntry *e;
    580 +#ifdef HAVE_BONJOUR
    581 +    AvahiService *s;
    582 +#endif
    583      assert(g);
    584      
    585      for (e = g->entries; e; e = e->by_group_next) {
    586          if (!e->dead) {
    587 +#ifndef HAVE_BONJOUR
    588              avahi_goodbye_entry(g->server, e, 1, 1);
    589 +#endif
    590              e->dead = 1;
    591          }
    592      }
    593      g->server->need_entry_cleanup = 1;
    594  
    595 +#ifdef HAVE_BONJOUR
    596 +    for (s = g->services; s; s = s->services_next) {
    597 +        s->dead = 1;
    598 +    }
    599 +    g->server->need_service_cleanup = 1;
    600 +    if (!g->server->cleanup_time_event)
    601 +        g->server->cleanup_time_event = avahi_time_event_new(g->server->time_event_queue, NULL, server_cleanup_time_event_callback, g->server);
    602 +#endif
    603      g->n_probing = 0;
    604 
    605      avahi_s_entry_group_change_state(g, AVAHI_ENTRY_GROUP_UNCOMMITED);
    606 @@ -1195,12 +1618,23 @@
    607  
    608  int avahi_s_entry_group_is_empty(AvahiSEntryGroup *g) {
    609      AvahiEntry *e;
    610 +#ifdef HAVE_BONJOUR
    611 +    AvahiService *s;
    612 +#endif
    613 +
    614      assert(g);
    615  
    616 +#ifdef HAVE_BONJOUR
    617 +    for (s = g->services; s; s = s->services_next)
    618 +        if (!s->dead)
    619 +            return 0;
    620 +#else
    621      /* Look for an entry that is not dead */
    622      for (e = g->entries; e; e = e->by_group_next)
    623          if (!e->dead)
    624              return 0;
    625 +#endif
    626  
    627      return 1;
    628  }
    629 +
    630