]> git.pld-linux.org Git - packages/cups.git/blob - cups-avahi-5-services.patch
00328805100fa814c103378f276b6fc4c6c045ad
[packages/cups.git] / cups-avahi-5-services.patch
1 diff --git a/scheduler/client.c b/scheduler/client.c
2 index e4c9b01..984dcc5 100644
3 --- a/scheduler/client.c
4 +++ b/scheduler/client.c
5 @@ -4987,7 +4987,7 @@ valid_host(cupsd_client_t *con)           /* I - Client connection */
6             !strncmp(host, "[::1]:", 6));
7    }
8  
9 -#ifdef HAVE_DNSSD
10 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
11   /*
12    * Check if the hostname is something.local (Bonjour); if so, allow it.
13    */
14 @@ -4996,7 +4996,7 @@ valid_host(cupsd_client_t *con)           /* I - Client connection */
15        (!_cups_strcasecmp(end, ".local") || !_cups_strncasecmp(end, ".local:", 7) ||
16         !_cups_strcasecmp(end, ".local.") || !_cups_strncasecmp(end, ".local.:", 8)))
17      return (1);
18 -#endif /* HAVE_DNSSD */
19 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
20  
21   /*
22    * Check if the hostname is an IP address...
23 diff --git a/scheduler/conf.c b/scheduler/conf.c
24 index badc630..c1edd39 100644
25 --- a/scheduler/conf.c
26 +++ b/scheduler/conf.c
27 @@ -648,7 +648,7 @@ cupsdReadConfiguration(void)
28    Browsing                 = CUPS_DEFAULT_BROWSING;
29    DefaultShared            = CUPS_DEFAULT_DEFAULT_SHARED;
30  
31 -#ifdef HAVE_DNSSD
32 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
33    cupsdSetString(&DNSSDRegType, "_ipp._tcp,_cups");
34  #endif /* HAVE_DNSSD */
35  
36 diff --git a/scheduler/dirsvc.c b/scheduler/dirsvc.c
37 index eb3c862..48dcef9 100644
38 --- a/scheduler/dirsvc.c
39 +++ b/scheduler/dirsvc.c
40 @@ -27,6 +27,7 @@
41   *                             remote printers.
42   *   cupsdRegisterPrinter()   - Start sending broadcast information for a
43   *                             printer or update the broadcast contents.
44 + *   cupsdStartAvahiClient()    - Start an Avahi client if needed
45   *   cupsdStartBrowsing()     - Start sending and receiving broadcast
46   *                             information.
47   *   cupsdStopBrowsing()      - Stop sending and receiving broadcast
48 @@ -45,6 +46,8 @@
49   *                             printer.
50   *   dnssdPackTxtRecord()     - Pack an array of key/value pairs into the TXT
51   *                             record format.
52 + *   avahiPackTxtRecord()       - Pack an array of key/value pairs into an
53 + *                                AvahiStringList.
54   *   dnssdRegisterCallback()  - DNSServiceRegister callback.
55   *   dnssdRegisterPrinter()   - Start sending broadcast information for a
56   *                             printer or update the broadcast contents.
57 @@ -83,6 +86,7 @@
58   */
59  
60  #include "cupsd.h"
61 +#include <assert.h>
62  #include <grp.h>
63  
64  #ifdef HAVE_DNSSD
65 @@ -97,6 +101,17 @@
66  #    endif /* HAVE_SYSTEMCONFIGURATION */
67  #  endif /* __APPLE__ */
68  #endif /* HAVE_DNSSD */
69 +#ifdef HAVE_AVAHI
70 +#  include <avahi-common/domain.h>
71 +#endif /* HAVE_AVAHI */
72 +
73 +
74 +#ifdef HAVE_DNSSD
75 +typedef char *cupsd_txt_record_t;
76 +#endif /* HAVE_DNSSD */
77 +#ifdef HAVE_AVAHI
78 +typedef AvahiStringList *cupsd_txt_record_t;
79 +#endif /* HAVE_AVAHI */
80  
81  
82  /*
83 @@ -159,26 +174,39 @@ static void       update_polling(void);
84  static void    update_smb(int onoff);
85  
86  
87 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
88 +static cupsd_txt_record_t dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
89 +                                             int for_lpd);
90 +static int     dnssdComparePrinters(cupsd_printer_t *a, cupsd_printer_t *b);
91 +static void    dnssdDeregisterPrinter(cupsd_printer_t *p);
92 +static void    dnssdRegisterPrinter(cupsd_printer_t *p);
93 +static void    dnssdStop(void);
94 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
95 +
96  #ifdef HAVE_DNSSD
97  #  ifdef HAVE_COREFOUNDATION
98  static void    dnssdAddAlias(const void *key, const void *value,
99                               void *context);
100  #  endif /* HAVE_COREFOUNDATION */
101 -static char    *dnssdBuildTxtRecord(int *txt_len, cupsd_printer_t *p,
102 -                                    int for_lpd);
103 -static void    dnssdDeregisterPrinter(cupsd_printer_t *p);
104 -static char    *dnssdPackTxtRecord(int *txt_len, char *keyvalue[][2],
105 -                                   int count);
106  static void    dnssdRegisterCallback(DNSServiceRef sdRef,
107                                       DNSServiceFlags flags,
108                                       DNSServiceErrorType errorCode,
109                                       const char *name, const char *regtype,
110                                       const char *domain, void *context);
111 -static void    dnssdRegisterPrinter(cupsd_printer_t *p);
112 -static void    dnssdStop(void);
113  static void    dnssdUpdate(void);
114  #endif /* HAVE_DNSSD */
115  
116 +#ifdef HAVE_AVAHI
117 +static AvahiStringList *avahiPackTxtRecord(char *keyvalue[][2],
118 +                                          int count);
119 +static void    avahi_entry_group_cb (AvahiEntryGroup *group,
120 +                                     AvahiEntryGroupState state,
121 +                                     void *userdata);
122 +static void    avahi_client_cb (AvahiClient *client,
123 +                                AvahiClientState state,
124 +                                void *userdata);
125 +#endif /* HAVE_AVAHI */
126 +
127  
128  /*
129   * 'cupsdDeregisterPrinter()' - Stop sending broadcast information for a
130 @@ -283,10 +310,10 @@ cupsdDeregisterPrinter(
131      ldap_dereg_printer(p);
132  #endif /* HAVE_LDAP */
133  
134 -#ifdef HAVE_DNSSD
135 -  if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
136 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
137 +  if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD))
138      dnssdDeregisterPrinter(p);
139 -#endif /* HAVE_DNSSD */
140 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
141  }
142  
143  
144 @@ -702,10 +729,10 @@ cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
145      slpRegisterPrinter(p); */
146  #endif /* HAVE_LIBSLP */
147  
148 -#ifdef HAVE_DNSSD
149 -  if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
150 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
151 +  if ((BrowseLocalProtocols & BROWSE_DNSSD))
152      dnssdRegisterPrinter(p);
153 -#endif /* HAVE_DNSSD */
154 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
155  }
156  
157  
158 @@ -1419,6 +1446,27 @@ ldap_disconnect(LDAP *ld)                /* I - LDAP handle */
159  #endif /* HAVE_LDAP */
160  
161  
162 +#ifdef HAVE_AVAHI
163 +/*
164 + * 'cupsdStartAvahiClient()' - Start an Avahi client if needed
165 + */
166 +
167 +void
168 +cupsdStartAvahiClient(void)
169 +{
170 +  if (!AvahiCupsClient && !AvahiCupsClientConnecting)
171 +  {
172 +    if (!AvahiCupsPollHandle)
173 +      AvahiCupsPollHandle = avahi_cups_poll_new ();
174 +
175 +    if (AvahiCupsPollHandle)
176 +      avahi_client_new (avahi_cups_poll_get (AvahiCupsPollHandle),
177 +                       AVAHI_CLIENT_NO_FAIL, avahi_client_cb, NULL, NULL);
178 +  }
179 +}
180 +#endif /* HAVE_AVAHI */
181 +
182 +  
183  /*
184   * 'cupsdStartBrowsing()' - Start sending and receiving broadcast information.
185   */
186 @@ -1542,13 +1590,16 @@ cupsdStartBrowsing(void)
187    else
188      BrowseSocket = -1;
189  
190 -#ifdef HAVE_DNSSD
191 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
192    if (BrowseLocalProtocols & BROWSE_DNSSD)
193    {
194 +#ifdef HAVE_DNSSD
195      DNSServiceErrorType error;         /* Error from service creation */
196 +#endif /* HAVE_DNSSD */
197      cupsd_listener_t   *lis;           /* Current listening socket */
198  
199  
200 +#ifdef HAVE_DNSSD
201     /*
202      * First create a "master" connection for all registrations...
203      */
204 @@ -1573,6 +1624,7 @@ cupsdStartBrowsing(void)
205        fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
206  
207        cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
208 +#endif /* HAVE_DNSSD */
209  
210       /*
211        * Then get the port we use for registrations.  If we are not listening
212 @@ -1606,9 +1658,16 @@ cupsdStartBrowsing(void)
213        */
214  
215        cupsdUpdateDNSSDName();
216 +
217 +#ifdef HAVE_AVAHI
218 +      cupsdStartAvahiClient ();
219 +#endif /* HAVE_AVAHI */
220 +
221 +#ifdef HAVE_DNSSD
222      }
223 -  }
224  #endif /* HAVE_DNSSD */
225 +  }
226 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
227  
228   /*
229    * Enable LPD and SMB printer sharing as needed through external programs...
230 @@ -1834,10 +1893,10 @@ cupsdStopBrowsing(void)
231      BrowseSocket = -1;
232    }
233  
234 -#ifdef HAVE_DNSSD
235 -  if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDRef)
236 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
237 +  if ((BrowseLocalProtocols & BROWSE_DNSSD))
238      dnssdStop();
239 -#endif /* HAVE_DNSSD */
240 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
241  
242  #ifdef HAVE_LIBSLP
243    if (((BrowseLocalProtocols | BrowseRemoteProtocols) & BROWSE_SLP) &&
244 @@ -1902,7 +1961,7 @@ cupsdStopPolling(void)
245  }
246  
247  
248 -#ifdef HAVE_DNSSD
249 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
250  /*
251   * 'cupsdUpdateDNSSDName()' - Update the computer name we use for browsing...
252   */
253 @@ -1910,8 +1969,14 @@ cupsdStopPolling(void)
254  void
255  cupsdUpdateDNSSDName(void)
256  {
257 +#ifdef HAVE_DNSSD
258    DNSServiceErrorType error;           /* Error from service creation */
259    char         webif[1024];            /* Web interface share name */
260 +#endif /* HAVE_DNSSD */
261 +#ifdef HAVE_AVAHI
262 +  int          ret;                    /* Error from service creation */
263 +  char         webif[AVAHI_LABEL_MAX]; /* Web interface share name */
264 +#endif /* HAVE_AVAHI */
265  #  ifdef HAVE_SYSTEMCONFIGURATION
266    SCDynamicStoreRef sc;                        /* Context for dynamic store */
267    CFDictionaryRef btmm;                        /* Back-to-My-Mac domains */
268 @@ -2042,6 +2107,7 @@ cupsdUpdateDNSSDName(void)
269      else
270        strlcpy(webif, "CUPS Web Interface", sizeof(webif));
271  
272 +#ifdef HAVE_DNSSD
273      if (WebIFRef)
274        DNSServiceRefDeallocate(WebIFRef);
275  
276 @@ -2054,9 +2120,45 @@ cupsdUpdateDNSSDName(void)
277                                     NULL)) != kDNSServiceErr_NoError)
278        cupsdLogMessage(CUPSD_LOG_ERROR,
279                       "DNS-SD web interface registration failed: %d", error);
280 +#endif /* HAVE_DNSSD */
281 +
282 +#ifdef HAVE_AVAHI
283 +    if (!AvahiCupsClient)
284 +     /*
285 +      * Client not yet running.
286 +      */
287 +      return;
288 +
289 +    if (AvahiWebIFGroup)
290 +      avahi_entry_group_reset (AvahiWebIFGroup);
291 +    else
292 +      AvahiWebIFGroup = avahi_entry_group_new (AvahiCupsClient,
293 +                                              avahi_entry_group_cb,
294 +                                              NULL);
295 +
296 +    if (AvahiWebIFGroup)
297 +    {
298 +      ret = avahi_entry_group_add_service (AvahiWebIFGroup,
299 +                                          AVAHI_IF_UNSPEC,
300 +                                          AVAHI_PROTO_UNSPEC,
301 +                                          0, /* flags */
302 +                                          webif, /* name */
303 +                                          "_http._tcp", /* type */
304 +                                          NULL, /* domain */
305 +                                          NULL, /* host */
306 +                                          DNSSDPort, /* port */
307 +                                          "path=/", NULL);
308 +      if (ret == 0)
309 +       ret = avahi_entry_group_commit (AvahiWebIFGroup);
310 +
311 +      if (ret != 0)
312 +       cupsdLogMessage (CUPSD_LOG_ERROR,
313 +                        "Avahi web interface registration failed: %d", ret);
314 +    }
315 +#endif /* HAVE_AVAHI */
316    }
317  }
318 -#endif /* HAVE_DNSSD */
319 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
320  
321  
322  #ifdef HAVE_LDAP
323 @@ -2334,13 +2436,15 @@ dnssdAddAlias(const void *key,          /* I - Key */
324                      "Bad Back to My Mac domain in dynamic store!");
325  }
326  #  endif /* HAVE_COREFOUNDATION */
327 +#endif /* HAVE_DNSSD */
328  
329  
330 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
331  /*
332   * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
333   */
334  
335 -static char *                          /* O - TXT record */
336 +static cupsd_txt_record_t              /* O - TXT record */
337  dnssdBuildTxtRecord(
338      int             *txt_len,          /* O - TXT record length */
339      cupsd_printer_t *p,                        /* I - Printer information */
340 @@ -2379,7 +2483,12 @@ dnssdBuildTxtRecord(
341    keyvalue[i  ][0] = "ty";
342    keyvalue[i++][1] = p->make_model ? p->make_model : "Unknown";
343  
344 -  snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.", DNSSDHostName);
345 +  snprintf(admin_hostname, sizeof(admin_hostname),
346 +          "%s.local"
347 +#ifdef HAVE_DNSSD
348 +          "." /* terminating dot no good for Avahi */
349 +#endif /* HAVE_DNSSD */
350 +          , DNSSDHostName);
351    httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str),
352                     "http", NULL, admin_hostname, DNSSDPort, "/%s/%s",
353                    (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
354 @@ -2462,7 +2571,12 @@ dnssdBuildTxtRecord(
355    * Then pack them into a proper txt record...
356    */
357  
358 +#ifdef HAVE_DNSSD
359    return (dnssdPackTxtRecord(txt_len, keyvalue, i));
360 +#endif /* HAVE_DNSSD */
361 +#ifdef HAVE_AVAHI
362 +  return (avahiPackTxtRecord(keyvalue, i));
363 +#endif /* HAVE_AVAHI */
364  }
365  
366  
367 @@ -2489,6 +2612,10 @@ dnssdDeregisterPrinter(
368  {
369    cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdDeregisterPrinter(%s)", p->name);
370  
371 +#ifdef HAVE_DNSSD
372 +  if (!DNSSDRef)
373 +    return;
374 +
375   /*
376    * Closing the socket deregisters the service
377    */
378 @@ -2524,6 +2651,24 @@ dnssdDeregisterPrinter(
379      free(p->printer_txt);
380      p->printer_txt = NULL;
381    }
382 +#endif /* HAVE_DNSSD */
383 +
384 +#ifdef HAVE_AVAHI
385 +  if (p->avahi_group)
386 +    {
387 +      avahi_entry_group_reset (p->avahi_group);
388 +      avahi_entry_group_free (p->avahi_group);
389 +      p->avahi_group = NULL;
390 +
391 +      if (p->ipp_txt)
392 +       avahi_string_list_free (p->ipp_txt);
393 +
394 +      if (p->printer_txt)
395 +       avahi_string_list_free (p->printer_txt);
396 +
397 +      p->ipp_txt = p->printer_txt = NULL;
398 +    }
399 +#endif /* HAVE_AVAHI */
400  
401   /*
402    * Remove the printer from the array of DNS-SD printers, then clear the
403 @@ -2533,8 +2678,10 @@ dnssdDeregisterPrinter(
404    cupsArrayRemove(DNSSDPrinters, p);
405    cupsdClearString(&p->reg_name);
406  }
407 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
408  
409  
410 +#ifdef HAVE_DNSSD
411  /*
412   * 'dnssdPackTxtRecord()' - Pack an array of key/value pairs into the
413   *                          TXT record format.
414 @@ -2644,8 +2791,10 @@ dnssdRegisterCallback(
415      LastEvent |= CUPSD_EVENT_PRINTER_MODIFIED;
416    }
417  }
418 +#endif /* HAVE_DNSSD */
419  
420  
421 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
422  /*
423   * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer
424   *                           or update the broadcast contents.
425 @@ -2654,20 +2803,40 @@ dnssdRegisterCallback(
426  static void
427  dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
428  {
429 +#ifdef HAVE_DNSSD
430    DNSServiceErrorType  se;             /* dnssd errors */
431    char                 *ipp_txt,       /* IPP TXT record buffer */
432                         *printer_txt,   /* LPD TXT record buffer */
433 -                       name[1024],     /* Service name */
434 -                       *nameptr;       /* Pointer into name */
435 +                       name[1024];     /* Service name */
436    int                  ipp_len,        /* IPP TXT record length */
437                         printer_len,    /* LPD TXT record length */
438                         printer_port;   /* LPD port number */
439 +#endif /* HAVE_DNSSD */
440 +#ifdef HAVE_AVAHI
441 +  int                  ret;            /* Error code */
442 +  AvahiStringList      *ipp_txt,       /* IPP TXT record */
443 +                       *printer_txt;   /* LPD TXT record */
444 +  char                 name[AVAHI_LABEL_MAX],  /* Service name */
445 +                       fullsubtype[AVAHI_LABEL_MAX]; /* Full subtype */
446 +  char                 *regtype_copy,  /* Writeable copy of reg type */
447 +                       *subtype,       /* Current service sub type */
448 +                       *nextsubtype;   /* Next service sub type */
449 +#endif /* HAVE_AVAHI */
450 +  char                 *nameptr;       /* Pointer into name */
451    const char           *regtype;       /* Registration type */
452  
453  
454 +#ifdef HAVE_DNSSD
455 +  if (!DNSSDRef)
456 +    return;
457 +
458    cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
459                    !p->ipp_ref ? "new" : "update");
460 -
461 +#endif /* HAVE_DNSSD */
462 +#ifdef HAVE_AVAHI
463 +  cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
464 +                 !p->avahi_group ? "new" : "update");
465 +#endif /* HAVE_AVAHI */
466   /*
467    * If per-printer sharing was just disabled make sure we're not
468    * registered before returning.
469 @@ -2686,12 +2855,36 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
470    if (p->info && strlen(p->info) > 0)
471    {
472      if (DNSSDComputerName)
473 -      snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName);
474 +    {
475 +     /*
476 +      * Make sure there is room for at least 15 characters of
477 +      * DNSSDComputerName.
478 +      */
479 +
480 +      assert(sizeof(name) >= 15 + 4);
481 +      nameptr = name + strlcpy(name, p->info,
482 +                              sizeof(name) - 4 -
483 +                              strnlen(DNSSDComputerName, 15));
484 +      nameptr += strlcpy(nameptr, " @ ", sizeof(name) - (nameptr - name));
485 +      strlcpy(nameptr, DNSSDComputerName, sizeof(name) - (nameptr - name));
486 +    }
487      else
488        strlcpy(name, p->info, sizeof(name));
489    }
490    else if (DNSSDComputerName)
491 -    snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
492 +  {
493 +   /*
494 +    * Make sure there is room for at least 15 characters of
495 +    * DNSSDComputerName.
496 +    */
497 +
498 +    assert(sizeof(name) >= 15 + 4);
499 +    nameptr = name + strlcpy(name, p->info,
500 +                            sizeof(name) - 4 -
501 +                            strnlen(DNSSDComputerName, 15));
502 +    nameptr += strlcpy(nameptr, " @ ", sizeof(name) - (nameptr - name));
503 +    strlcpy(nameptr, DNSSDComputerName, sizeof(name) - (nameptr - name));
504 +  }
505    else
506      strlcpy(name, p->name, sizeof(name));
507  
508 @@ -2712,6 +2905,7 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
509    * Register IPP and (optionally) LPD...
510    */
511  
512 +#ifdef HAVE_DNSSD
513    ipp_len = 0;                         /* anti-compiler-warning-code */
514    ipp_txt = dnssdBuildTxtRecord(&ipp_len, p, 0);
515  
516 @@ -2884,6 +3078,209 @@ dnssdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
517  
518    if (printer_txt)
519      free(printer_txt);
520 +#endif /* HAVE_DNSSD */
521 +#ifdef HAVE_AVAHI
522 +  if (!AvahiCupsClient)
523 +   /*
524 +    * Client not running yet.  The client callback will call us again later.
525 +    */
526 +    return;
527 +
528 +  ipp_txt = dnssdBuildTxtRecord(NULL, p, 0);
529 +  printer_txt = dnssdBuildTxtRecord(NULL, p, 1);
530 +  regtype = (p->type & CUPS_PRINTER_FAX) ? "_fax-ipp._tcp" : DNSSDRegType;
531 +
532 +  if (p->avahi_group && p->ipp_txt && ipp_txt &&
533 +      !avahi_string_list_equal (p->ipp_txt, ipp_txt))
534 +  {
535 +   /*
536 +    * Update the existing registration...
537 +    */
538 +
539 +    avahi_string_list_free (p->ipp_txt);
540 +
541 +    if (p->printer_txt)
542 +      avahi_string_list_free (p->printer_txt);
543 +
544 +   /*
545 +    * Update the service group entry.
546 +    */
547 +
548 +    regtype_copy = strdup (regtype);
549 +    subtype = strchr (regtype_copy, ',');
550 +    if (subtype)
551 +      *subtype = '\0';
552 +
553 +    cupsdLogMessage (CUPSD_LOG_DEBUG,
554 +                    "Updating TXT record for %s (%s)", name, regtype_copy);
555 +    ret = avahi_entry_group_update_service_txt_strlst (p->avahi_group,
556 +                                                      AVAHI_IF_UNSPEC,
557 +                                                      AVAHI_PROTO_UNSPEC,
558 +                                                      0, name,
559 +                                                      regtype_copy,
560 +                                                      NULL, ipp_txt);
561 +    free (regtype_copy);
562 +
563 +    if (ret < 0)
564 +      goto update_failed;
565 +
566 +    p->ipp_txt = ipp_txt;
567 +    ipp_txt = NULL;
568 +
569 +    if (BrowseLocalProtocols & BROWSE_LPD)
570 +    {
571 +      ret = avahi_entry_group_update_service_txt_strlst (p->avahi_group,
572 +                                                        AVAHI_IF_UNSPEC,
573 +                                                        AVAHI_PROTO_UNSPEC,
574 +                                                        0, name,
575 +                                                        "_printer._tcp", NULL,
576 +                                                        printer_txt);
577 +      if (ret < 0)
578 +       goto update_failed;
579 +
580 +      p->printer_txt = printer_txt;
581 +      printer_txt = NULL;
582 +    }
583 +
584 +    ret = avahi_entry_group_commit (p->avahi_group);
585 +    if (ret < 0)
586 +    {
587 +    update_failed:
588 +      cupsdLogMessage (CUPSD_LOG_ERROR,
589 +                      "Failed to update TXT record for %s: %d",
590 +                      name, ret);
591 +      avahi_entry_group_reset (p->avahi_group);
592 +      avahi_entry_group_free (p->avahi_group);
593 +      p->avahi_group = NULL;
594 +      ipp_txt = p->ipp_txt;
595 +      p->ipp_txt = NULL;
596 +    }
597 +  }
598 +
599 +  if (!p->avahi_group)
600 +  {
601 +   /*
602 +    * Initial registration.  Use the _fax subtype for fax queues...
603 +    */
604 +
605 +    p->avahi_group = avahi_entry_group_new (AvahiCupsClient,
606 +                                           avahi_entry_group_cb,
607 +                                           p);
608 +
609 +    cupsdLogMessage(CUPSD_LOG_DEBUG,
610 +                   "Registering Avahi printer %s with name \"%s\" and "
611 +                   "type \"%s\"", p->name, name, regtype);
612 +
613 +    if (!p->avahi_group)
614 +    {
615 +      ret = 0;
616 +      goto add_failed;
617 +    }
618 +
619 +   /*
620 +    * Add each service type (DNSSDRegType may contain several,
621 +    * separated by commas).
622 +    */
623 +
624 +    subtype = regtype_copy = strdup (regtype);
625 +    while (subtype && *subtype)
626 +    {
627 +      nextsubtype = strchr (subtype, ',');
628 +      if (nextsubtype)
629 +       *nextsubtype++ = '\0';
630 +
631 +      if (subtype == regtype_copy)
632 +      {
633 +       /*
634 +       * Main type entry.
635 +       */
636 +
637 +       cupsdLogMessage (CUPSD_LOG_DEBUG,
638 +                        "Adding TXT record for %s (%s)", name, regtype_copy);
639 +       ret = avahi_entry_group_add_service_strlst (p->avahi_group,
640 +                                                   AVAHI_IF_UNSPEC,
641 +                                                   AVAHI_PROTO_UNSPEC,
642 +                                                   0, name, regtype_copy,
643 +                                                   NULL, NULL,
644 +                                                   DNSSDPort,
645 +                                                   ipp_txt);
646 +      }
647 +      else
648 +      {
649 +       /*
650 +       * Sub-type entry.
651 +       */
652 +
653 +       snprintf (fullsubtype, sizeof(fullsubtype),
654 +                 "%s._sub.%s", subtype, regtype_copy);
655 +       cupsdLogMessage (CUPSD_LOG_DEBUG,
656 +                        "Adding TXT record for %s (%s)", name, fullsubtype);
657 +       ret = avahi_entry_group_add_service_subtype (p->avahi_group,
658 +                                                    AVAHI_IF_UNSPEC,
659 +                                                    AVAHI_PROTO_UNSPEC,
660 +                                                    0, name,
661 +                                                    regtype_copy,
662 +                                                    NULL, fullsubtype);
663 +      }
664 +
665 +      if (ret < 0)
666 +      {
667 +       free (regtype_copy);
668 +       goto add_failed;
669 +      }
670 +
671 +      subtype = nextsubtype;
672 +    }
673 +
674 +    free (regtype_copy);
675 +    p->ipp_txt = ipp_txt;
676 +    ipp_txt = NULL;
677 +
678 +    if (BrowseLocalProtocols & BROWSE_LPD)
679 +    {
680 +      cupsdLogMessage(CUPSD_LOG_DEBUG,
681 +                     "Registering Avahi printer %s with name \"%s\" and "
682 +                     "type \"_printer._tcp\"", p->name, name);
683 +
684 +      ret = avahi_entry_group_add_service_strlst (p->avahi_group,
685 +                                                 AVAHI_IF_UNSPEC,
686 +                                                 AVAHI_PROTO_UNSPEC,
687 +                                                 0, name,
688 +                                                 "_printer._tcp", NULL, NULL,
689 +                                                 515,
690 +                                                 printer_txt);
691 +      if (ret < 0)
692 +       goto add_failed;
693 +
694 +      p->printer_txt = printer_txt;
695 +      printer_txt = NULL;
696 +    }
697 +
698 +    ret = avahi_entry_group_commit (p->avahi_group);
699 +
700 +    if (ret < 0)
701 +    {
702 +    add_failed:
703 +      cupsdLogMessage (CUPSD_LOG_ERROR,
704 +                      "Failed to add Avahi entry for %s: %d",
705 +                      name, ret);
706 +      if (p->avahi_group)
707 +      {
708 +       avahi_entry_group_reset (p->avahi_group);
709 +       avahi_entry_group_free (p->avahi_group);
710 +       p->avahi_group = NULL;
711 +      }
712 +      ipp_txt = p->ipp_txt;
713 +      p->ipp_txt = NULL;
714 +    }
715 +  }
716 +
717 +  if (ipp_txt)
718 +    avahi_string_list_free (ipp_txt);
719 +
720 +  if (printer_txt)
721 +    avahi_string_list_free (printer_txt);
722 +#endif /* HAVE_AVAHI */
723  }
724  
725  
726 @@ -2896,6 +3293,10 @@ dnssdStop(void)
727  {
728    cupsd_printer_t      *p;             /* Current printer */
729  
730 +#ifdef HAVE_DNSSD
731 +  if (!DNSSDRef)
732 +    return;
733 +#endif /* HAVE_DNSSD */
734  
735   /*
736    * De-register the individual printers
737 @@ -2906,6 +3307,7 @@ dnssdStop(void)
738         p = (cupsd_printer_t *)cupsArrayNext(Printers))
739      dnssdDeregisterPrinter(p);
740  
741 +#ifdef HAVE_DNSSD
742   /*
743    * Shutdown the rest of the service refs...
744    */
745 @@ -2926,14 +3328,17 @@ dnssdStop(void)
746  
747    DNSServiceRefDeallocate(DNSSDRef);
748    DNSSDRef = NULL;
749 +#endif /* HAVE_DNSSD */
750  
751    cupsArrayDelete(DNSSDPrinters);
752    DNSSDPrinters = NULL;
753  
754    DNSSDPort = 0;
755  }
756 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
757  
758  
759 +#ifdef HAVE_DNSSD
760  /*
761   * 'dnssdUpdate()' - Handle DNS-SD queries.
762   */
763 @@ -2955,6 +3360,147 @@ dnssdUpdate(void)
764  #endif /* HAVE_DNSSD */
765  
766  
767 +#ifdef HAVE_AVAHI
768 +/*
769 + * 'avahiPackTxtRecord()' - Pack an array of key/value pairs into an
770 + *                          AvahiStringList.
771 + */
772 +
773 +static AvahiStringList *               /* O - new string list */
774 +avahiPackTxtRecord(char *keyvalue[][2],        /* I - Table of key value pairs */
775 +                  int count)           /* I - Number of items in table */
776 +{
777 +  AvahiStringList *strlst = NULL;
778 +  char **elements;
779 +  size_t len;
780 +  int i = 0;
781 +
782 +  elements = malloc ((1 + count) * sizeof (char *));
783 +  if (!elements)
784 +    goto cleanup;
785 +
786 +  for (i = 0; i < count; i++)
787 +    {
788 +      len = (1 + strlen (keyvalue[i][0]) +
789 +            (keyvalue[i][1] ? 1 + strlen (keyvalue[i][1]) : 1));
790 +      elements[i] = malloc (len * sizeof (char));
791 +      if (!elements[i])
792 +       goto cleanup;
793 +
794 +      snprintf (elements[i], len, "%s=%s", keyvalue[i][0], keyvalue[i][1]);
795 +    }
796 +
797 +  strlst = avahi_string_list_new_from_array ((const char **) elements, count);
798 +
799 +cleanup:
800 +  while (--i >= 0)
801 +    free (elements[i]);
802 +
803 +  free (elements);
804 +  return (strlst);
805 +}
806 +
807 +
808 +/*
809 + * 'avahi_entry_group_cb()' - Avahi entry group callback function.
810 + */
811 +static void
812 +avahi_entry_group_cb (AvahiEntryGroup *group,
813 +                     AvahiEntryGroupState state,
814 +                     void *userdata)
815 +{
816 +  char *name;
817 +
818 +  if (userdata)
819 +    name = ((cupsd_printer_t *) userdata)->reg_name;
820 +  else
821 +    name = "CUPS web interface";
822 +
823 +  switch (state)
824 +  {
825 +  case AVAHI_ENTRY_GROUP_UNCOMMITED:
826 +  case AVAHI_ENTRY_GROUP_REGISTERING:
827 +    break;
828 +
829 +  case AVAHI_ENTRY_GROUP_ESTABLISHED:
830 +    cupsdLogMessage (CUPSD_LOG_DEBUG,
831 +                    "Avahi entry group established for %s", name);
832 +    break;
833 +
834 +  default:
835 +    cupsdLogMessage (CUPSD_LOG_DEBUG,
836 +                    "Avahi entry group %s has state %d",
837 +                    name, state);
838 +    break;
839 +  }
840 +}
841 +
842 +
843 +/*
844 + * 'avahi_client_cb()' - Avahi client callback function.
845 + */
846 +static void
847 +avahi_client_cb (AvahiClient *client,
848 +                AvahiClientState state,
849 +                void *userdata)
850 +{
851 +  cupsd_printer_t *printer;
852 +  switch (state)
853 +  {
854 +  case AVAHI_CLIENT_S_RUNNING:
855 +   /*
856 +    * Avahi client started successfully.
857 +    */
858 +    AvahiCupsClient = client;
859 +    AvahiCupsClientConnecting = 0;
860 +    cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client started");
861 +
862 +    cupsdUpdateDNSSDName ();
863 +
864 +    for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
865 +        printer;
866 +        printer = (cupsd_printer_t *)cupsArrayNext(Printers))
867 +      if (Browsing && (BrowseLocalProtocols & BROWSE_DNSSD) &&
868 +         (!(printer->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_IMPLICIT |
869 +                             CUPS_PRINTER_SCANNER))) && printer->shared)
870 +       dnssdRegisterPrinter (printer);
871 +
872 +    break;
873 +
874 +  case AVAHI_CLIENT_CONNECTING:
875 +   /*
876 +    * No Avahi daemon, client is waiting.
877 +    */
878 +    AvahiCupsClientConnecting = 1;
879 +    cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client connecting");
880 +    break;
881 +
882 +  case AVAHI_CLIENT_FAILURE:
883 +   /*
884 +    * Avahi client failed, close it to allow a clean restart.
885 +    */
886 +    cupsdLogMessage (CUPSD_LOG_ERROR,
887 +                    "Avahi client failed, "
888 +                    "closing client to allow a clean restart");
889 +
890 +    for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
891 +        printer;
892 +        printer = (cupsd_printer_t *)cupsArrayNext(Printers))
893 +      dnssdDeregisterPrinter (printer);
894 +
895 +    avahi_client_free(client);
896 +    AvahiCupsClientConnecting = 0;
897 +    AvahiCupsClient = NULL;
898 +
899 +    break;
900 +
901 +  default:
902 +    cupsdLogMessage (CUPSD_LOG_DEBUG, "Avahi client state: %d", state);
903 +  }
904 +}
905 +#endif /* HAVE_AVAHI */
906 +
907 +
908  /*
909   * 'get_auth_info_required()' - Get the auth-info-required value to advertise.
910   */
911 diff --git a/scheduler/dirsvc.h b/scheduler/dirsvc.h
912 index 99079bd..d53a179 100644
913 --- a/scheduler/dirsvc.h
914 +++ b/scheduler/dirsvc.h
915 @@ -31,6 +31,10 @@
916   *   file is missing or damaged, see the license at "http://www.cups.org/".
917   */
918  
919 +#ifdef HAVE_AVAHI
920 +#  include <avahi-client/publish.h>
921 +#endif /* HAVE_AVAHI */
922 +
923  /*
924   * Browse protocols...
925   */
926 @@ -131,19 +135,22 @@ VAR int                   PollPipe        VALUE(0);
927                         BrowseLocalProtocols
928                                         VALUE(BROWSE_ALL);
929                                         /* Protocols to support for local printers */
930 -#ifdef HAVE_DNSSD
931 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
932  VAR char               *DNSSDComputerName VALUE(NULL),
933                                         /* Computer/server name */
934                         *DNSSDHostName  VALUE(NULL),
935                                         /* Hostname */
936                         *DNSSDRegType VALUE(NULL);
937                                         /* Bonjour registration type */
938 -VAR cups_array_t       *DNSSDAlias     VALUE(NULL);
939 -                                       /* List of dynamic ServerAlias's */
940  VAR int                        DNSSDPort       VALUE(0);
941                                         /* Port number to register */
942  VAR cups_array_t       *DNSSDPrinters  VALUE(NULL);
943                                         /* Printers we have registered */
944 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
945 +
946 +#ifdef HAVE_DNSSD
947 +VAR cups_array_t       *DNSSDAlias     VALUE(NULL);
948 +                                       /* List of dynamic ServerAlias's */
949  VAR DNSServiceRef      DNSSDRef        VALUE(NULL),
950                                         /* Master DNS-SD service reference */
951                         WebIFRef        VALUE(NULL);
952 @@ -152,6 +159,17 @@ VAR DNSServiceRef  DNSSDRef        VALUE(NULL),
953                                         /* Remote printer browse reference */
954  #endif /* HAVE_DNSSD */
955  
956 +#ifdef HAVE_AVAHI
957 +VAR AvahiCupsPoll      *AvahiCupsPollHandle    VALUE(NULL);
958 +                                       /* AvahiCupsPoll object */
959 +VAR AvahiClient                *AvahiCupsClient        VALUE(NULL);
960 +                                       /* AvahiClient object */
961 +VAR int                        AvahiCupsClientConnecting       VALUE(0);
962 +                                       /* Is AvahiClient object connecting? */
963 +VAR AvahiEntryGroup    *AvahiWebIFGroup        VALUE(NULL);
964 +                                       /* Web interface entry group */
965 +#endif /* HAVE_AVAHI */
966 +
967  VAR char               *LPDConfigFile  VALUE(NULL),
968                                         /* LPD configuration file */
969                         *SMBConfigFile  VALUE(NULL);
970 @@ -195,11 +213,12 @@ extern void       cupsdRegisterPrinter(cupsd_printer_t *p);
971  
972  extern void    cupsdDeregisterPrinter(cupsd_printer_t *p, int removeit);
973  extern void    cupsdRegisterPrinter(cupsd_printer_t *p);
974 +extern void    cupsdStartAvahiClient(void);
975  extern void    cupsdStartBrowsing(void);
976  extern void    cupsdStopBrowsing(void);
977 -#ifdef HAVE_DNSSD
978 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
979  extern void    cupsdUpdateDNSSDName(void);
980 -#endif /* HAVE_DNSSD */
981 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
982  
983  
984  /*
985 diff --git a/scheduler/ipp.c b/scheduler/ipp.c
986 index a048baa..9a3ab11 100644
987 --- a/scheduler/ipp.c
988 +++ b/scheduler/ipp.c
989 @@ -6087,7 +6087,7 @@ copy_printer_attrs(
990      ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
991                 ippTimeToDate(curtime));
992  
993 -#ifdef HAVE_DNSSD
994 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
995    if (!ra || cupsArrayFind(ra, "printer-dns-sd-name"))
996    {
997      if (printer->reg_name)
998 @@ -6097,7 +6097,7 @@ copy_printer_attrs(
999        ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
1000                     "printer-dns-sd-name", 0);
1001    }
1002 -#endif /* HAVE_DNSSD */
1003 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1004  
1005    if (!ra || cupsArrayFind(ra, "printer-error-policy"))
1006      ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
1007 diff --git a/scheduler/main.c b/scheduler/main.c
1008 index 1e60572..6c210e6 100644
1009 --- a/scheduler/main.c
1010 +++ b/scheduler/main.c
1011 @@ -120,6 +120,10 @@ main(int  argc,                            /* I - Number of command-line args */
1012    cupsd_listener_t     *lis;           /* Current listener */
1013    time_t               current_time,   /* Current time */
1014                         activity,       /* Client activity timer */
1015 +#ifdef HAVE_AVAHI
1016 +                       avahi_client_time, /* Time for next Avahi client
1017 +                                             check */
1018 +#endif /* HAVE_AVAHI */
1019                         senddoc_time,   /* Send-Document time */
1020                         expire_time,    /* Subscription expire time */
1021                         report_time,    /* Malloc/client/job report time */
1022 @@ -662,6 +666,9 @@ main(int  argc,                             /* I - Number of command-line args */
1023    */
1024  
1025    current_time  = time(NULL);
1026 +#ifdef HAVE_AVAHI
1027 +  avahi_client_time = current_time;
1028 +#endif /* HAVE_AVAHI */
1029    event_time    = current_time;
1030    expire_time   = current_time;
1031    fds           = 1;
1032 @@ -884,6 +891,16 @@ main(int  argc,                            /* I - Number of command-line args */
1033      tmo = cupsdNextTimeout (&tmo_delay);
1034      if (tmo && tmo_delay == 0)
1035        cupsdRunTimeout (tmo);
1036 +
1037 +   /*
1038 +    * Try to restart the Avahi client every 10 seconds if needed...
1039 +    */
1040 +
1041 +    if ((current_time - avahi_client_time) >= 10)
1042 +    {
1043 +      avahi_client_time = current_time;
1044 +      cupsdStartAvahiClient();
1045 +    }
1046  #endif /* HAVE_AVAHI */
1047  
1048  #ifndef __APPLE__
1049 diff --git a/scheduler/printers.c b/scheduler/printers.c
1050 index 4686c4c..fac7bbc 100644
1051 --- a/scheduler/printers.c
1052 +++ b/scheduler/printers.c
1053 @@ -883,9 +883,9 @@ cupsdDeletePrinter(
1054    cupsdClearString(&p->alert);
1055    cupsdClearString(&p->alert_description);
1056  
1057 -#ifdef HAVE_DNSSD
1058 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1059    cupsdClearString(&p->pdl);
1060 -#endif /* HAVE_DNSSD */
1061 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1062  
1063    cupsArrayDelete(p->filetypes);
1064  
1065 @@ -3765,7 +3765,7 @@ add_printer_formats(cupsd_printer_t *p)   /* I - Printer */
1066      attr->values[i].string.text = _cupsStrAlloc(mimetype);
1067    }
1068  
1069 -#ifdef HAVE_DNSSD
1070 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1071    {
1072      char               pdl[1024];      /* Buffer to build pdl list */
1073      mime_filter_t      *filter;        /* MIME filter looping var */
1074 @@ -3821,7 +3821,7 @@ add_printer_formats(cupsd_printer_t *p)   /* I - Printer */
1075  
1076      cupsdSetString(&p->pdl, pdl);
1077    }
1078 -#endif /* HAVE_DNSSD */
1079 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1080  }
1081  
1082  
1083 diff --git a/scheduler/printers.h b/scheduler/printers.h
1084 index 1751578..fb04651 100644
1085 --- a/scheduler/printers.h
1086 +++ b/scheduler/printers.h
1087 @@ -16,6 +16,9 @@
1088  #ifdef HAVE_DNSSD
1089  #  include <dns_sd.h>
1090  #endif /* HAVE_DNSSD */
1091 +#ifdef HAVE_AVAHI
1092 +#  include "avahi.h"
1093 +#endif /* HAVE_AVAHI */
1094  #include <cups/pwg-private.h>
1095  
1096  
1097 @@ -95,16 +98,23 @@ struct cupsd_printer_s
1098    time_t       marker_time;            /* Last time marker attributes were updated */
1099    _ppd_cache_t *pc;                    /* PPD cache and mapping data */
1100  
1101 -#ifdef HAVE_DNSSD
1102 +#if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
1103    char         *reg_name,              /* Name used for service registration */
1104 -               *pdl,                   /* pdl value for TXT record */
1105 -               *ipp_txt,               /* IPP TXT record contents */
1106 +               *pdl;                   /* pdl value for TXT record */
1107 +#endif /* defined(HAVE_DNSSD) || defined(HAVE_AVAHI) */
1108 +#ifdef HAVE_DNSSD
1109 +  char         *ipp_txt,               /* IPP TXT record contents */
1110                 *printer_txt;           /* LPD TXT record contents */
1111    int          ipp_len,                /* IPP TXT record length */
1112                 printer_len;            /* LPD TXT record length */
1113    DNSServiceRef        ipp_ref,                /* Reference for _ipp._tcp,_cups */
1114                 printer_ref;            /* Reference for _printer._tcp */
1115  #endif /* HAVE_DNSSD */
1116 +#ifdef HAVE_AVAHI
1117 +  AvahiStringList *ipp_txt,            /* IPP TXT record */
1118 +               *printer_txt;           /* LPD TXT record */
1119 +  AvahiEntryGroup *avahi_group;                /* Avahi entry group */
1120 +#endif /* HAVE_AVAHI */
1121  };
1122  
1123  
This page took 0.163224 seconds and 3 git commands to generate.