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