xref: /aosp_15_r20/external/libcups/scheduler/dirsvc.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Directory services routines for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2018 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 1997-2007 by Easy Software Products, all rights reserved.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
8*5e7646d2SAndroid Build Coastguard Worker  * information.
9*5e7646d2SAndroid Build Coastguard Worker  */
10*5e7646d2SAndroid Build Coastguard Worker 
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker  */
14*5e7646d2SAndroid Build Coastguard Worker 
15*5e7646d2SAndroid Build Coastguard Worker #include "cupsd.h"
16*5e7646d2SAndroid Build Coastguard Worker #include <grp.h>
17*5e7646d2SAndroid Build Coastguard Worker 
18*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) && defined(__APPLE__)
19*5e7646d2SAndroid Build Coastguard Worker #  include <nameser.h>
20*5e7646d2SAndroid Build Coastguard Worker #  include <CoreFoundation/CoreFoundation.h>
21*5e7646d2SAndroid Build Coastguard Worker #  include <SystemConfiguration/SystemConfiguration.h>
22*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD && __APPLE__ */
23*5e7646d2SAndroid Build Coastguard Worker 
24*5e7646d2SAndroid Build Coastguard Worker 
25*5e7646d2SAndroid Build Coastguard Worker /*
26*5e7646d2SAndroid Build Coastguard Worker  * Local globals...
27*5e7646d2SAndroid Build Coastguard Worker  */
28*5e7646d2SAndroid Build Coastguard Worker 
29*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_AVAHI
30*5e7646d2SAndroid Build Coastguard Worker static int	avahi_running = 0;
31*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_AVAHI */
32*5e7646d2SAndroid Build Coastguard Worker 
33*5e7646d2SAndroid Build Coastguard Worker 
34*5e7646d2SAndroid Build Coastguard Worker /*
35*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
36*5e7646d2SAndroid Build Coastguard Worker  */
37*5e7646d2SAndroid Build Coastguard Worker 
38*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
39*5e7646d2SAndroid Build Coastguard Worker static char		*get_auth_info_required(cupsd_printer_t *p,
40*5e7646d2SAndroid Build Coastguard Worker 			                        char *buffer, size_t bufsize);
41*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
42*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
43*5e7646d2SAndroid Build Coastguard Worker static int		get_hostconfig(const char *name);
44*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
45*5e7646d2SAndroid Build Coastguard Worker static void		update_lpd(int onoff);
46*5e7646d2SAndroid Build Coastguard Worker static void		update_smb(int onoff);
47*5e7646d2SAndroid Build Coastguard Worker 
48*5e7646d2SAndroid Build Coastguard Worker 
49*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
50*5e7646d2SAndroid Build Coastguard Worker #  ifdef __APPLE__
51*5e7646d2SAndroid Build Coastguard Worker static void		dnssdAddAlias(const void *key, const void *value,
52*5e7646d2SAndroid Build Coastguard Worker 			              void *context);
53*5e7646d2SAndroid Build Coastguard Worker #  endif /* __APPLE__ */
54*5e7646d2SAndroid Build Coastguard Worker static cupsd_txt_t	dnssdBuildTxtRecord(cupsd_printer_t *p, int for_lpd);
55*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_AVAHI
56*5e7646d2SAndroid Build Coastguard Worker static void		dnssdClientCallback(AvahiClient *c, AvahiClientState state, void *userdata);
57*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_AVAHI */
58*5e7646d2SAndroid Build Coastguard Worker static void		dnssdDeregisterAllPrinters(int from_callback);
59*5e7646d2SAndroid Build Coastguard Worker static void		dnssdDeregisterInstance(cupsd_srv_t *srv, int from_callback);
60*5e7646d2SAndroid Build Coastguard Worker static void		dnssdDeregisterPrinter(cupsd_printer_t *p, int clear_name, int from_callback);
61*5e7646d2SAndroid Build Coastguard Worker static const char	*dnssdErrorString(int error);
62*5e7646d2SAndroid Build Coastguard Worker static void		dnssdFreeTxtRecord(cupsd_txt_t *txt);
63*5e7646d2SAndroid Build Coastguard Worker static void		dnssdRegisterAllPrinters(int from_callback);
64*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
65*5e7646d2SAndroid Build Coastguard Worker static void		dnssdRegisterCallback(DNSServiceRef sdRef,
66*5e7646d2SAndroid Build Coastguard Worker 					      DNSServiceFlags flags,
67*5e7646d2SAndroid Build Coastguard Worker 					      DNSServiceErrorType errorCode,
68*5e7646d2SAndroid Build Coastguard Worker 					      const char *name,
69*5e7646d2SAndroid Build Coastguard Worker 					      const char *regtype,
70*5e7646d2SAndroid Build Coastguard Worker 					      const char *domain,
71*5e7646d2SAndroid Build Coastguard Worker 					      void *context);
72*5e7646d2SAndroid Build Coastguard Worker #  else
73*5e7646d2SAndroid Build Coastguard Worker static void		dnssdRegisterCallback(AvahiEntryGroup *p,
74*5e7646d2SAndroid Build Coastguard Worker 					      AvahiEntryGroupState state,
75*5e7646d2SAndroid Build Coastguard Worker 					      void *context);
76*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
77*5e7646d2SAndroid Build Coastguard Worker static int		dnssdRegisterInstance(cupsd_srv_t *srv, cupsd_printer_t *p, char *name, const char *type, const char *subtypes, int port, cupsd_txt_t *txt, int commit, int from_callback);
78*5e7646d2SAndroid Build Coastguard Worker static void		dnssdRegisterPrinter(cupsd_printer_t *p, int from_callback);
79*5e7646d2SAndroid Build Coastguard Worker static void		dnssdStop(void);
80*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
81*5e7646d2SAndroid Build Coastguard Worker static void		dnssdUpdate(void);
82*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
83*5e7646d2SAndroid Build Coastguard Worker static void		dnssdUpdateDNSSDName(int from_callback);
84*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
85*5e7646d2SAndroid Build Coastguard Worker 
86*5e7646d2SAndroid Build Coastguard Worker 
87*5e7646d2SAndroid Build Coastguard Worker /*
88*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdDeregisterPrinter()' - Stop sending broadcast information for a
89*5e7646d2SAndroid Build Coastguard Worker  *				local printer and remove any pending
90*5e7646d2SAndroid Build Coastguard Worker  *                              references to remote printers.
91*5e7646d2SAndroid Build Coastguard Worker  */
92*5e7646d2SAndroid Build Coastguard Worker 
93*5e7646d2SAndroid Build Coastguard Worker void
cupsdDeregisterPrinter(cupsd_printer_t * p,int removeit)94*5e7646d2SAndroid Build Coastguard Worker cupsdDeregisterPrinter(
95*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer to register */
96*5e7646d2SAndroid Build Coastguard Worker     int             removeit)		/* I - Printer being permanently removed */
97*5e7646d2SAndroid Build Coastguard Worker {
98*5e7646d2SAndroid Build Coastguard Worker  /*
99*5e7646d2SAndroid Build Coastguard Worker   * Only deregister if browsing is enabled and it's a local printer...
100*5e7646d2SAndroid Build Coastguard Worker   */
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG,
103*5e7646d2SAndroid Build Coastguard Worker                   "cupsdDeregisterPrinter(p=%p(%s), removeit=%d)", p, p->name,
104*5e7646d2SAndroid Build Coastguard Worker 		  removeit);
105*5e7646d2SAndroid Build Coastguard Worker 
106*5e7646d2SAndroid Build Coastguard Worker   if (!Browsing || !p->shared ||
107*5e7646d2SAndroid Build Coastguard Worker       (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
108*5e7646d2SAndroid Build Coastguard Worker     return;
109*5e7646d2SAndroid Build Coastguard Worker 
110*5e7646d2SAndroid Build Coastguard Worker  /*
111*5e7646d2SAndroid Build Coastguard Worker   * Announce the deletion...
112*5e7646d2SAndroid Build Coastguard Worker   */
113*5e7646d2SAndroid Build Coastguard Worker 
114*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
115*5e7646d2SAndroid Build Coastguard Worker   if (removeit && (BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
116*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterPrinter(p, 1, 0);
117*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
118*5e7646d2SAndroid Build Coastguard Worker }
119*5e7646d2SAndroid Build Coastguard Worker 
120*5e7646d2SAndroid Build Coastguard Worker 
121*5e7646d2SAndroid Build Coastguard Worker /*
122*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdRegisterPrinter()' - Start sending broadcast information for a
123*5e7646d2SAndroid Build Coastguard Worker  *                            printer or update the broadcast contents.
124*5e7646d2SAndroid Build Coastguard Worker  */
125*5e7646d2SAndroid Build Coastguard Worker 
126*5e7646d2SAndroid Build Coastguard Worker void
cupsdRegisterPrinter(cupsd_printer_t * p)127*5e7646d2SAndroid Build Coastguard Worker cupsdRegisterPrinter(cupsd_printer_t *p)/* I - Printer */
128*5e7646d2SAndroid Build Coastguard Worker {
129*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG, "cupsdRegisterPrinter(p=%p(%s))", p,
130*5e7646d2SAndroid Build Coastguard Worker                   p->name);
131*5e7646d2SAndroid Build Coastguard Worker 
132*5e7646d2SAndroid Build Coastguard Worker   if (!Browsing || !BrowseLocalProtocols ||
133*5e7646d2SAndroid Build Coastguard Worker       (p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
134*5e7646d2SAndroid Build Coastguard Worker     return;
135*5e7646d2SAndroid Build Coastguard Worker 
136*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
137*5e7646d2SAndroid Build Coastguard Worker   if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
138*5e7646d2SAndroid Build Coastguard Worker     dnssdRegisterPrinter(p, 0);
139*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
140*5e7646d2SAndroid Build Coastguard Worker }
141*5e7646d2SAndroid Build Coastguard Worker 
142*5e7646d2SAndroid Build Coastguard Worker 
143*5e7646d2SAndroid Build Coastguard Worker /*
144*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdStartBrowsing()' - Start sending and receiving broadcast information.
145*5e7646d2SAndroid Build Coastguard Worker  */
146*5e7646d2SAndroid Build Coastguard Worker 
147*5e7646d2SAndroid Build Coastguard Worker void
cupsdStartBrowsing(void)148*5e7646d2SAndroid Build Coastguard Worker cupsdStartBrowsing(void)
149*5e7646d2SAndroid Build Coastguard Worker {
150*5e7646d2SAndroid Build Coastguard Worker   if (!Browsing || !BrowseLocalProtocols)
151*5e7646d2SAndroid Build Coastguard Worker     return;
152*5e7646d2SAndroid Build Coastguard Worker 
153*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
154*5e7646d2SAndroid Build Coastguard Worker   if (BrowseLocalProtocols & BROWSE_DNSSD)
155*5e7646d2SAndroid Build Coastguard Worker   {
156*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
157*5e7646d2SAndroid Build Coastguard Worker     DNSServiceErrorType error;		/* Error from service creation */
158*5e7646d2SAndroid Build Coastguard Worker 
159*5e7646d2SAndroid Build Coastguard Worker    /*
160*5e7646d2SAndroid Build Coastguard Worker     * First create a "master" connection for all registrations...
161*5e7646d2SAndroid Build Coastguard Worker     */
162*5e7646d2SAndroid Build Coastguard Worker 
163*5e7646d2SAndroid Build Coastguard Worker     if ((error = DNSServiceCreateConnection(&DNSSDMaster))
164*5e7646d2SAndroid Build Coastguard Worker 	    != kDNSServiceErr_NoError)
165*5e7646d2SAndroid Build Coastguard Worker     {
166*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR,
167*5e7646d2SAndroid Build Coastguard Worker 		      "Unable to create master DNS-SD reference: %d", error);
168*5e7646d2SAndroid Build Coastguard Worker 
169*5e7646d2SAndroid Build Coastguard Worker       if (FatalErrors & CUPSD_FATAL_BROWSE)
170*5e7646d2SAndroid Build Coastguard Worker 	cupsdEndProcess(getpid(), 0);
171*5e7646d2SAndroid Build Coastguard Worker     }
172*5e7646d2SAndroid Build Coastguard Worker     else
173*5e7646d2SAndroid Build Coastguard Worker     {
174*5e7646d2SAndroid Build Coastguard Worker      /*
175*5e7646d2SAndroid Build Coastguard Worker       * Add the master connection to the select list...
176*5e7646d2SAndroid Build Coastguard Worker       */
177*5e7646d2SAndroid Build Coastguard Worker 
178*5e7646d2SAndroid Build Coastguard Worker       int fd = DNSServiceRefSockFD(DNSSDMaster);
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker       fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC);
181*5e7646d2SAndroid Build Coastguard Worker 
182*5e7646d2SAndroid Build Coastguard Worker       cupsdAddSelect(fd, (cupsd_selfunc_t)dnssdUpdate, NULL, NULL);
183*5e7646d2SAndroid Build Coastguard Worker     }
184*5e7646d2SAndroid Build Coastguard Worker 
185*5e7646d2SAndroid Build Coastguard Worker    /*
186*5e7646d2SAndroid Build Coastguard Worker     * Set the computer name and register the web interface...
187*5e7646d2SAndroid Build Coastguard Worker     */
188*5e7646d2SAndroid Build Coastguard Worker 
189*5e7646d2SAndroid Build Coastguard Worker     DNSSDPort = 0;
190*5e7646d2SAndroid Build Coastguard Worker     cupsdUpdateDNSSDName();
191*5e7646d2SAndroid Build Coastguard Worker 
192*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
193*5e7646d2SAndroid Build Coastguard Worker     if ((DNSSDMaster = avahi_threaded_poll_new()) == NULL)
194*5e7646d2SAndroid Build Coastguard Worker     {
195*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create DNS-SD thread.");
196*5e7646d2SAndroid Build Coastguard Worker 
197*5e7646d2SAndroid Build Coastguard Worker       if (FatalErrors & CUPSD_FATAL_BROWSE)
198*5e7646d2SAndroid Build Coastguard Worker 	cupsdEndProcess(getpid(), 0);
199*5e7646d2SAndroid Build Coastguard Worker     }
200*5e7646d2SAndroid Build Coastguard Worker     else
201*5e7646d2SAndroid Build Coastguard Worker     {
202*5e7646d2SAndroid Build Coastguard Worker       int error;			/* Error code, if any */
203*5e7646d2SAndroid Build Coastguard Worker 
204*5e7646d2SAndroid Build Coastguard Worker       DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);
205*5e7646d2SAndroid Build Coastguard Worker 
206*5e7646d2SAndroid Build Coastguard Worker       if (DNSSDClient == NULL)
207*5e7646d2SAndroid Build Coastguard Worker       {
208*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR,
209*5e7646d2SAndroid Build Coastguard Worker                         "Unable to communicate with avahi-daemon: %s",
210*5e7646d2SAndroid Build Coastguard Worker                         dnssdErrorString(error));
211*5e7646d2SAndroid Build Coastguard Worker 
212*5e7646d2SAndroid Build Coastguard Worker         if (FatalErrors & CUPSD_FATAL_BROWSE)
213*5e7646d2SAndroid Build Coastguard Worker 	  cupsdEndProcess(getpid(), 0);
214*5e7646d2SAndroid Build Coastguard Worker 
215*5e7646d2SAndroid Build Coastguard Worker         avahi_threaded_poll_free(DNSSDMaster);
216*5e7646d2SAndroid Build Coastguard Worker         DNSSDMaster = NULL;
217*5e7646d2SAndroid Build Coastguard Worker       }
218*5e7646d2SAndroid Build Coastguard Worker       else
219*5e7646d2SAndroid Build Coastguard Worker 	avahi_threaded_poll_start(DNSSDMaster);
220*5e7646d2SAndroid Build Coastguard Worker     }
221*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
222*5e7646d2SAndroid Build Coastguard Worker   }
223*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
224*5e7646d2SAndroid Build Coastguard Worker 
225*5e7646d2SAndroid Build Coastguard Worker  /*
226*5e7646d2SAndroid Build Coastguard Worker   * Enable LPD and SMB printer sharing as needed through external programs...
227*5e7646d2SAndroid Build Coastguard Worker   */
228*5e7646d2SAndroid Build Coastguard Worker 
229*5e7646d2SAndroid Build Coastguard Worker   if (BrowseLocalProtocols & BROWSE_LPD)
230*5e7646d2SAndroid Build Coastguard Worker     update_lpd(1);
231*5e7646d2SAndroid Build Coastguard Worker 
232*5e7646d2SAndroid Build Coastguard Worker   if (BrowseLocalProtocols & BROWSE_SMB)
233*5e7646d2SAndroid Build Coastguard Worker     update_smb(1);
234*5e7646d2SAndroid Build Coastguard Worker 
235*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
236*5e7646d2SAndroid Build Coastguard Worker  /*
237*5e7646d2SAndroid Build Coastguard Worker   * Register the individual printers
238*5e7646d2SAndroid Build Coastguard Worker   */
239*5e7646d2SAndroid Build Coastguard Worker 
240*5e7646d2SAndroid Build Coastguard Worker   dnssdRegisterAllPrinters(0);
241*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
242*5e7646d2SAndroid Build Coastguard Worker }
243*5e7646d2SAndroid Build Coastguard Worker 
244*5e7646d2SAndroid Build Coastguard Worker 
245*5e7646d2SAndroid Build Coastguard Worker /*
246*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdStopBrowsing()' - Stop sending and receiving broadcast information.
247*5e7646d2SAndroid Build Coastguard Worker  */
248*5e7646d2SAndroid Build Coastguard Worker 
249*5e7646d2SAndroid Build Coastguard Worker void
cupsdStopBrowsing(void)250*5e7646d2SAndroid Build Coastguard Worker cupsdStopBrowsing(void)
251*5e7646d2SAndroid Build Coastguard Worker {
252*5e7646d2SAndroid Build Coastguard Worker   if (!Browsing || !BrowseLocalProtocols)
253*5e7646d2SAndroid Build Coastguard Worker     return;
254*5e7646d2SAndroid Build Coastguard Worker 
255*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
256*5e7646d2SAndroid Build Coastguard Worker  /*
257*5e7646d2SAndroid Build Coastguard Worker   * De-register the individual printers
258*5e7646d2SAndroid Build Coastguard Worker   */
259*5e7646d2SAndroid Build Coastguard Worker 
260*5e7646d2SAndroid Build Coastguard Worker   dnssdDeregisterAllPrinters(0);
261*5e7646d2SAndroid Build Coastguard Worker 
262*5e7646d2SAndroid Build Coastguard Worker  /*
263*5e7646d2SAndroid Build Coastguard Worker   * Shut down browsing sockets...
264*5e7646d2SAndroid Build Coastguard Worker   */
265*5e7646d2SAndroid Build Coastguard Worker 
266*5e7646d2SAndroid Build Coastguard Worker   if ((BrowseLocalProtocols & BROWSE_DNSSD) && DNSSDMaster)
267*5e7646d2SAndroid Build Coastguard Worker     dnssdStop();
268*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
269*5e7646d2SAndroid Build Coastguard Worker 
270*5e7646d2SAndroid Build Coastguard Worker  /*
271*5e7646d2SAndroid Build Coastguard Worker   * Disable LPD and SMB printer sharing as needed through external programs...
272*5e7646d2SAndroid Build Coastguard Worker   */
273*5e7646d2SAndroid Build Coastguard Worker 
274*5e7646d2SAndroid Build Coastguard Worker   if (BrowseLocalProtocols & BROWSE_LPD)
275*5e7646d2SAndroid Build Coastguard Worker     update_lpd(0);
276*5e7646d2SAndroid Build Coastguard Worker 
277*5e7646d2SAndroid Build Coastguard Worker   if (BrowseLocalProtocols & BROWSE_SMB)
278*5e7646d2SAndroid Build Coastguard Worker     update_smb(0);
279*5e7646d2SAndroid Build Coastguard Worker }
280*5e7646d2SAndroid Build Coastguard Worker 
281*5e7646d2SAndroid Build Coastguard Worker 
282*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
283*5e7646d2SAndroid Build Coastguard Worker /*
284*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdUpdateDNSSDName()' - Update the computer name we use for browsing...
285*5e7646d2SAndroid Build Coastguard Worker  */
286*5e7646d2SAndroid Build Coastguard Worker 
287*5e7646d2SAndroid Build Coastguard Worker void
cupsdUpdateDNSSDName(void)288*5e7646d2SAndroid Build Coastguard Worker cupsdUpdateDNSSDName(void)
289*5e7646d2SAndroid Build Coastguard Worker {
290*5e7646d2SAndroid Build Coastguard Worker   dnssdUpdateDNSSDName(0);
291*5e7646d2SAndroid Build Coastguard Worker }
292*5e7646d2SAndroid Build Coastguard Worker 
293*5e7646d2SAndroid Build Coastguard Worker 
294*5e7646d2SAndroid Build Coastguard Worker #  ifdef __APPLE__
295*5e7646d2SAndroid Build Coastguard Worker /*
296*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdAddAlias()' - Add a DNS-SD alias name.
297*5e7646d2SAndroid Build Coastguard Worker  */
298*5e7646d2SAndroid Build Coastguard Worker 
299*5e7646d2SAndroid Build Coastguard Worker static void
dnssdAddAlias(const void * key,const void * value,void * context)300*5e7646d2SAndroid Build Coastguard Worker dnssdAddAlias(const void *key,		/* I - Key */
301*5e7646d2SAndroid Build Coastguard Worker               const void *value,	/* I - Value (domain) */
302*5e7646d2SAndroid Build Coastguard Worker 	      void       *context)	/* I - Unused */
303*5e7646d2SAndroid Build Coastguard Worker {
304*5e7646d2SAndroid Build Coastguard Worker   char	valueStr[1024],			/* Domain string */
305*5e7646d2SAndroid Build Coastguard Worker 	hostname[1024],			/* Complete hostname */
306*5e7646d2SAndroid Build Coastguard Worker 	*hostptr;			/* Pointer into hostname */
307*5e7646d2SAndroid Build Coastguard Worker 
308*5e7646d2SAndroid Build Coastguard Worker 
309*5e7646d2SAndroid Build Coastguard Worker   (void)key;
310*5e7646d2SAndroid Build Coastguard Worker   (void)context;
311*5e7646d2SAndroid Build Coastguard Worker 
312*5e7646d2SAndroid Build Coastguard Worker   if (CFGetTypeID((CFStringRef)value) == CFStringGetTypeID() &&
313*5e7646d2SAndroid Build Coastguard Worker       CFStringGetCString((CFStringRef)value, valueStr, sizeof(valueStr),
314*5e7646d2SAndroid Build Coastguard Worker                          kCFStringEncodingUTF8))
315*5e7646d2SAndroid Build Coastguard Worker   {
316*5e7646d2SAndroid Build Coastguard Worker     snprintf(hostname, sizeof(hostname), "%s.%s", DNSSDHostName, valueStr);
317*5e7646d2SAndroid Build Coastguard Worker     hostptr = hostname + strlen(hostname) - 1;
318*5e7646d2SAndroid Build Coastguard Worker     if (*hostptr == '.')
319*5e7646d2SAndroid Build Coastguard Worker       *hostptr = '\0';			/* Strip trailing dot */
320*5e7646d2SAndroid Build Coastguard Worker 
321*5e7646d2SAndroid Build Coastguard Worker     if (!DNSSDAlias)
322*5e7646d2SAndroid Build Coastguard Worker       DNSSDAlias = cupsArrayNew(NULL, NULL);
323*5e7646d2SAndroid Build Coastguard Worker 
324*5e7646d2SAndroid Build Coastguard Worker     cupsdAddAlias(DNSSDAlias, hostname);
325*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG, "Added Back to My Mac ServerAlias %s",
326*5e7646d2SAndroid Build Coastguard Worker 		    hostname);
327*5e7646d2SAndroid Build Coastguard Worker   }
328*5e7646d2SAndroid Build Coastguard Worker   else
329*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR,
330*5e7646d2SAndroid Build Coastguard Worker                     "Bad Back to My Mac domain in dynamic store!");
331*5e7646d2SAndroid Build Coastguard Worker }
332*5e7646d2SAndroid Build Coastguard Worker #  endif /* __APPLE__ */
333*5e7646d2SAndroid Build Coastguard Worker 
334*5e7646d2SAndroid Build Coastguard Worker 
335*5e7646d2SAndroid Build Coastguard Worker /*
336*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdBuildTxtRecord()' - Build a TXT record from printer info.
337*5e7646d2SAndroid Build Coastguard Worker  */
338*5e7646d2SAndroid Build Coastguard Worker 
339*5e7646d2SAndroid Build Coastguard Worker static cupsd_txt_t			/* O - TXT record */
dnssdBuildTxtRecord(cupsd_printer_t * p,int for_lpd)340*5e7646d2SAndroid Build Coastguard Worker dnssdBuildTxtRecord(
341*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer information */
342*5e7646d2SAndroid Build Coastguard Worker     int             for_lpd)		/* I - 1 = LPD, 0 = IPP */
343*5e7646d2SAndroid Build Coastguard Worker {
344*5e7646d2SAndroid Build Coastguard Worker   int		i,			/* Looping var */
345*5e7646d2SAndroid Build Coastguard Worker 		count;			/* Count of key/value pairs */
346*5e7646d2SAndroid Build Coastguard Worker   char		admin_hostname[256],	/* Hostname for admin page */
347*5e7646d2SAndroid Build Coastguard Worker 		adminurl_str[256],	/* URL for the admin page */
348*5e7646d2SAndroid Build Coastguard Worker 		type_str[32],		/* Type to string buffer */
349*5e7646d2SAndroid Build Coastguard Worker 		state_str[32],		/* State to string buffer */
350*5e7646d2SAndroid Build Coastguard Worker 		rp_str[1024],		/* Queue name string buffer */
351*5e7646d2SAndroid Build Coastguard Worker 		air_str[1024],		/* auth-info-required string buffer */
352*5e7646d2SAndroid Build Coastguard Worker 		*keyvalue[32][2],	/* Table of key/value pairs */
353*5e7646d2SAndroid Build Coastguard Worker                 *ptr;                   /* Pointer in string */
354*5e7646d2SAndroid Build Coastguard Worker   cupsd_txt_t	txt;			/* TXT record */
355*5e7646d2SAndroid Build Coastguard Worker   cupsd_listener_t *lis;                /* Current listener */
356*5e7646d2SAndroid Build Coastguard Worker   const char    *admin_scheme = "http"; /* Admin page URL scheme */
357*5e7646d2SAndroid Build Coastguard Worker 
358*5e7646d2SAndroid Build Coastguard Worker 
359*5e7646d2SAndroid Build Coastguard Worker  /*
360*5e7646d2SAndroid Build Coastguard Worker   * Load up the key value pairs...
361*5e7646d2SAndroid Build Coastguard Worker   */
362*5e7646d2SAndroid Build Coastguard Worker 
363*5e7646d2SAndroid Build Coastguard Worker   count = 0;
364*5e7646d2SAndroid Build Coastguard Worker 
365*5e7646d2SAndroid Build Coastguard Worker   if (!for_lpd || (BrowseLocalProtocols & BROWSE_LPD))
366*5e7646d2SAndroid Build Coastguard Worker   {
367*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "txtvers";
368*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = "1";
369*5e7646d2SAndroid Build Coastguard Worker 
370*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "qtotal";
371*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = "1";
372*5e7646d2SAndroid Build Coastguard Worker 
373*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "rp";
374*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = rp_str;
375*5e7646d2SAndroid Build Coastguard Worker     if (for_lpd)
376*5e7646d2SAndroid Build Coastguard Worker       strlcpy(rp_str, p->name, sizeof(rp_str));
377*5e7646d2SAndroid Build Coastguard Worker     else
378*5e7646d2SAndroid Build Coastguard Worker       snprintf(rp_str, sizeof(rp_str), "%s/%s",
379*5e7646d2SAndroid Build Coastguard Worker 	       (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers",
380*5e7646d2SAndroid Build Coastguard Worker 	       p->name);
381*5e7646d2SAndroid Build Coastguard Worker 
382*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "ty";
383*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = p->make_model ? p->make_model : "Unknown";
384*5e7646d2SAndroid Build Coastguard Worker 
385*5e7646d2SAndroid Build Coastguard Worker    /*
386*5e7646d2SAndroid Build Coastguard Worker     * Get the hostname for the admin page...
387*5e7646d2SAndroid Build Coastguard Worker     */
388*5e7646d2SAndroid Build Coastguard Worker 
389*5e7646d2SAndroid Build Coastguard Worker     if (strchr(DNSSDHostName, '.'))
390*5e7646d2SAndroid Build Coastguard Worker     {
391*5e7646d2SAndroid Build Coastguard Worker      /*
392*5e7646d2SAndroid Build Coastguard Worker       * Use the provided hostname, but make sure it ends with a period...
393*5e7646d2SAndroid Build Coastguard Worker       */
394*5e7646d2SAndroid Build Coastguard Worker 
395*5e7646d2SAndroid Build Coastguard Worker       if ((ptr = DNSSDHostName + strlen(DNSSDHostName) - 1) >= DNSSDHostName && *ptr == '.')
396*5e7646d2SAndroid Build Coastguard Worker         strlcpy(admin_hostname, DNSSDHostName, sizeof(admin_hostname));
397*5e7646d2SAndroid Build Coastguard Worker       else
398*5e7646d2SAndroid Build Coastguard Worker         snprintf(admin_hostname, sizeof(admin_hostname), "%s.", DNSSDHostName);
399*5e7646d2SAndroid Build Coastguard Worker     }
400*5e7646d2SAndroid Build Coastguard Worker     else
401*5e7646d2SAndroid Build Coastguard Worker     {
402*5e7646d2SAndroid Build Coastguard Worker      /*
403*5e7646d2SAndroid Build Coastguard Worker       * Unqualified hostname gets ".local." added to it...
404*5e7646d2SAndroid Build Coastguard Worker       */
405*5e7646d2SAndroid Build Coastguard Worker 
406*5e7646d2SAndroid Build Coastguard Worker       snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.", DNSSDHostName);
407*5e7646d2SAndroid Build Coastguard Worker     }
408*5e7646d2SAndroid Build Coastguard Worker 
409*5e7646d2SAndroid Build Coastguard Worker    /*
410*5e7646d2SAndroid Build Coastguard Worker     * Get the URL scheme for the admin page...
411*5e7646d2SAndroid Build Coastguard Worker     */
412*5e7646d2SAndroid Build Coastguard Worker 
413*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_SSL
414*5e7646d2SAndroid Build Coastguard Worker     for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners); lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
415*5e7646d2SAndroid Build Coastguard Worker     {
416*5e7646d2SAndroid Build Coastguard Worker       if (lis->encryption != HTTP_ENCRYPTION_NEVER)
417*5e7646d2SAndroid Build Coastguard Worker       {
418*5e7646d2SAndroid Build Coastguard Worker         admin_scheme = "https";
419*5e7646d2SAndroid Build Coastguard Worker         break;
420*5e7646d2SAndroid Build Coastguard Worker       }
421*5e7646d2SAndroid Build Coastguard Worker     }
422*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_SSL */
423*5e7646d2SAndroid Build Coastguard Worker 
424*5e7646d2SAndroid Build Coastguard Worker     httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str), admin_scheme,  NULL, admin_hostname, DNSSDPort, "/%s/%s", (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name);
425*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "adminurl";
426*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = adminurl_str;
427*5e7646d2SAndroid Build Coastguard Worker 
428*5e7646d2SAndroid Build Coastguard Worker     if (p->location)
429*5e7646d2SAndroid Build Coastguard Worker     {
430*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "note";
431*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = p->location;
432*5e7646d2SAndroid Build Coastguard Worker     }
433*5e7646d2SAndroid Build Coastguard Worker 
434*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "priority";
435*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = for_lpd ? "100" : "0";
436*5e7646d2SAndroid Build Coastguard Worker 
437*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "product";
438*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = p->pc && p->pc->product ? p->pc->product : "Unknown";
439*5e7646d2SAndroid Build Coastguard Worker 
440*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "pdl";
441*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = p->pdl ? p->pdl : "application/postscript";
442*5e7646d2SAndroid Build Coastguard Worker 
443*5e7646d2SAndroid Build Coastguard Worker     if (get_auth_info_required(p, air_str, sizeof(air_str)))
444*5e7646d2SAndroid Build Coastguard Worker     {
445*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "air";
446*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = air_str;
447*5e7646d2SAndroid Build Coastguard Worker     }
448*5e7646d2SAndroid Build Coastguard Worker 
449*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "UUID";
450*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = p->uuid + 9;
451*5e7646d2SAndroid Build Coastguard Worker 
452*5e7646d2SAndroid Build Coastguard Worker   #ifdef HAVE_SSL
453*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "TLS";
454*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = "1.2";
455*5e7646d2SAndroid Build Coastguard Worker   #endif /* HAVE_SSL */
456*5e7646d2SAndroid Build Coastguard Worker 
457*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_FAX)
458*5e7646d2SAndroid Build Coastguard Worker     {
459*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Fax";
460*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = "T";
461*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "rfo";
462*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = rp_str;
463*5e7646d2SAndroid Build Coastguard Worker     }
464*5e7646d2SAndroid Build Coastguard Worker 
465*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_COLOR)
466*5e7646d2SAndroid Build Coastguard Worker     {
467*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Color";
468*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLOR) ? "T" : "F";
469*5e7646d2SAndroid Build Coastguard Worker     }
470*5e7646d2SAndroid Build Coastguard Worker 
471*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_DUPLEX)
472*5e7646d2SAndroid Build Coastguard Worker     {
473*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Duplex";
474*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_DUPLEX) ? "T" : "F";
475*5e7646d2SAndroid Build Coastguard Worker     }
476*5e7646d2SAndroid Build Coastguard Worker 
477*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_STAPLE)
478*5e7646d2SAndroid Build Coastguard Worker     {
479*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Staple";
480*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_STAPLE) ? "T" : "F";
481*5e7646d2SAndroid Build Coastguard Worker     }
482*5e7646d2SAndroid Build Coastguard Worker 
483*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_COPIES)
484*5e7646d2SAndroid Build Coastguard Worker     {
485*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Copies";
486*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_COPIES) ? "T" : "F";
487*5e7646d2SAndroid Build Coastguard Worker     }
488*5e7646d2SAndroid Build Coastguard Worker 
489*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_COLLATE)
490*5e7646d2SAndroid Build Coastguard Worker     {
491*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Collate";
492*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLLATE) ? "T" : "F";
493*5e7646d2SAndroid Build Coastguard Worker     }
494*5e7646d2SAndroid Build Coastguard Worker 
495*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_PUNCH)
496*5e7646d2SAndroid Build Coastguard Worker     {
497*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Punch";
498*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_PUNCH) ? "T" : "F";
499*5e7646d2SAndroid Build Coastguard Worker     }
500*5e7646d2SAndroid Build Coastguard Worker 
501*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_BIND)
502*5e7646d2SAndroid Build Coastguard Worker     {
503*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Bind";
504*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_BIND) ? "T" : "F";
505*5e7646d2SAndroid Build Coastguard Worker     }
506*5e7646d2SAndroid Build Coastguard Worker 
507*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_SORT)
508*5e7646d2SAndroid Build Coastguard Worker     {
509*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Sort";
510*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_SORT) ? "T" : "F";
511*5e7646d2SAndroid Build Coastguard Worker     }
512*5e7646d2SAndroid Build Coastguard Worker 
513*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_MFP)
514*5e7646d2SAndroid Build Coastguard Worker     {
515*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count  ][0] = "Scan";
516*5e7646d2SAndroid Build Coastguard Worker       keyvalue[count++][1] = (p->type & CUPS_PRINTER_MFP) ? "T" : "F";
517*5e7646d2SAndroid Build Coastguard Worker     }
518*5e7646d2SAndroid Build Coastguard Worker 
519*5e7646d2SAndroid Build Coastguard Worker     snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE);
520*5e7646d2SAndroid Build Coastguard Worker     snprintf(state_str, sizeof(state_str), "%d", p->state);
521*5e7646d2SAndroid Build Coastguard Worker 
522*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "printer-state";
523*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = state_str;
524*5e7646d2SAndroid Build Coastguard Worker 
525*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count  ][0] = "printer-type";
526*5e7646d2SAndroid Build Coastguard Worker     keyvalue[count++][1] = type_str;
527*5e7646d2SAndroid Build Coastguard Worker   }
528*5e7646d2SAndroid Build Coastguard Worker 
529*5e7646d2SAndroid Build Coastguard Worker  /*
530*5e7646d2SAndroid Build Coastguard Worker   * Then pack them into a proper txt record...
531*5e7646d2SAndroid Build Coastguard Worker   */
532*5e7646d2SAndroid Build Coastguard Worker 
533*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
534*5e7646d2SAndroid Build Coastguard Worker   TXTRecordCreate(&txt, 0, NULL);
535*5e7646d2SAndroid Build Coastguard Worker 
536*5e7646d2SAndroid Build Coastguard Worker   for (i = 0; i < count; i ++)
537*5e7646d2SAndroid Build Coastguard Worker   {
538*5e7646d2SAndroid Build Coastguard Worker     size_t len = strlen(keyvalue[i][1]);
539*5e7646d2SAndroid Build Coastguard Worker 
540*5e7646d2SAndroid Build Coastguard Worker     if (len < 256)
541*5e7646d2SAndroid Build Coastguard Worker       TXTRecordSetValue(&txt, keyvalue[i][0], (uint8_t)len, keyvalue[i][1]);
542*5e7646d2SAndroid Build Coastguard Worker   }
543*5e7646d2SAndroid Build Coastguard Worker 
544*5e7646d2SAndroid Build Coastguard Worker #  else
545*5e7646d2SAndroid Build Coastguard Worker   for (i = 0, txt = NULL; i < count; i ++)
546*5e7646d2SAndroid Build Coastguard Worker     txt = avahi_string_list_add_printf(txt, "%s=%s", keyvalue[i][0],
547*5e7646d2SAndroid Build Coastguard Worker                                        keyvalue[i][1]);
548*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
549*5e7646d2SAndroid Build Coastguard Worker 
550*5e7646d2SAndroid Build Coastguard Worker   return (txt);
551*5e7646d2SAndroid Build Coastguard Worker }
552*5e7646d2SAndroid Build Coastguard Worker 
553*5e7646d2SAndroid Build Coastguard Worker 
554*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_AVAHI
555*5e7646d2SAndroid Build Coastguard Worker /*
556*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdClientCallback()' - Client callback for Avahi.
557*5e7646d2SAndroid Build Coastguard Worker  *
558*5e7646d2SAndroid Build Coastguard Worker  * Called whenever the client or server state changes...
559*5e7646d2SAndroid Build Coastguard Worker  */
560*5e7646d2SAndroid Build Coastguard Worker 
561*5e7646d2SAndroid Build Coastguard Worker static void
dnssdClientCallback(AvahiClient * c,AvahiClientState state,void * userdata)562*5e7646d2SAndroid Build Coastguard Worker dnssdClientCallback(
563*5e7646d2SAndroid Build Coastguard Worker     AvahiClient      *c,		/* I - Client */
564*5e7646d2SAndroid Build Coastguard Worker     AvahiClientState state,		/* I - Current state */
565*5e7646d2SAndroid Build Coastguard Worker     void             *userdata)		/* I - User data (unused) */
566*5e7646d2SAndroid Build Coastguard Worker {
567*5e7646d2SAndroid Build Coastguard Worker   int	error;				/* Error code, if any */
568*5e7646d2SAndroid Build Coastguard Worker 
569*5e7646d2SAndroid Build Coastguard Worker 
570*5e7646d2SAndroid Build Coastguard Worker   (void)userdata;
571*5e7646d2SAndroid Build Coastguard Worker 
572*5e7646d2SAndroid Build Coastguard Worker   if (!c)
573*5e7646d2SAndroid Build Coastguard Worker     return;
574*5e7646d2SAndroid Build Coastguard Worker 
575*5e7646d2SAndroid Build Coastguard Worker  /*
576*5e7646d2SAndroid Build Coastguard Worker   * Make sure DNSSDClient is already set also if this callback function is
577*5e7646d2SAndroid Build Coastguard Worker   * already running before avahi_client_new() in dnssdStartBrowsing()
578*5e7646d2SAndroid Build Coastguard Worker   * finishes.
579*5e7646d2SAndroid Build Coastguard Worker   */
580*5e7646d2SAndroid Build Coastguard Worker 
581*5e7646d2SAndroid Build Coastguard Worker   if (!DNSSDClient)
582*5e7646d2SAndroid Build Coastguard Worker     DNSSDClient = c;
583*5e7646d2SAndroid Build Coastguard Worker 
584*5e7646d2SAndroid Build Coastguard Worker   switch (state)
585*5e7646d2SAndroid Build Coastguard Worker   {
586*5e7646d2SAndroid Build Coastguard Worker     case AVAHI_CLIENT_S_REGISTERING:
587*5e7646d2SAndroid Build Coastguard Worker     case AVAHI_CLIENT_S_RUNNING:
588*5e7646d2SAndroid Build Coastguard Worker     case AVAHI_CLIENT_S_COLLISION:
589*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_DEBUG, "Avahi server connection now available, registering printers for Bonjour broadcasting.");
590*5e7646d2SAndroid Build Coastguard Worker 
591*5e7646d2SAndroid Build Coastguard Worker        /*
592*5e7646d2SAndroid Build Coastguard Worker 	* Mark that Avahi server is running...
593*5e7646d2SAndroid Build Coastguard Worker 	*/
594*5e7646d2SAndroid Build Coastguard Worker 
595*5e7646d2SAndroid Build Coastguard Worker 	avahi_running = 1;
596*5e7646d2SAndroid Build Coastguard Worker 
597*5e7646d2SAndroid Build Coastguard Worker        /*
598*5e7646d2SAndroid Build Coastguard Worker 	* Set the computer name and register the web interface...
599*5e7646d2SAndroid Build Coastguard Worker 	*/
600*5e7646d2SAndroid Build Coastguard Worker 
601*5e7646d2SAndroid Build Coastguard Worker 	DNSSDPort = 0;
602*5e7646d2SAndroid Build Coastguard Worker 	dnssdUpdateDNSSDName(1);
603*5e7646d2SAndroid Build Coastguard Worker 
604*5e7646d2SAndroid Build Coastguard Worker        /*
605*5e7646d2SAndroid Build Coastguard Worker 	* Register the individual printers
606*5e7646d2SAndroid Build Coastguard Worker 	*/
607*5e7646d2SAndroid Build Coastguard Worker 
608*5e7646d2SAndroid Build Coastguard Worker 	dnssdRegisterAllPrinters(1);
609*5e7646d2SAndroid Build Coastguard Worker 	break;
610*5e7646d2SAndroid Build Coastguard Worker 
611*5e7646d2SAndroid Build Coastguard Worker     case AVAHI_CLIENT_FAILURE:
612*5e7646d2SAndroid Build Coastguard Worker 	if (avahi_client_errno(c) == AVAHI_ERR_DISCONNECTED)
613*5e7646d2SAndroid Build Coastguard Worker 	{
614*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_DEBUG, "Avahi server disappeared, unregistering printers for Bonjour broadcasting.");
615*5e7646d2SAndroid Build Coastguard Worker 
616*5e7646d2SAndroid Build Coastguard Worker 	 /*
617*5e7646d2SAndroid Build Coastguard Worker 	  * Unregister everything and close the client...
618*5e7646d2SAndroid Build Coastguard Worker 	  */
619*5e7646d2SAndroid Build Coastguard Worker 
620*5e7646d2SAndroid Build Coastguard Worker 	  dnssdDeregisterAllPrinters(1);
621*5e7646d2SAndroid Build Coastguard Worker 	  dnssdDeregisterInstance(&WebIFSrv, 1);
622*5e7646d2SAndroid Build Coastguard Worker 	  avahi_client_free(DNSSDClient);
623*5e7646d2SAndroid Build Coastguard Worker 	  DNSSDClient = NULL;
624*5e7646d2SAndroid Build Coastguard Worker 
625*5e7646d2SAndroid Build Coastguard Worker 	 /*
626*5e7646d2SAndroid Build Coastguard Worker 	  * Mark that Avahi server is not running...
627*5e7646d2SAndroid Build Coastguard Worker 	  */
628*5e7646d2SAndroid Build Coastguard Worker 
629*5e7646d2SAndroid Build Coastguard Worker 	  avahi_running = 0;
630*5e7646d2SAndroid Build Coastguard Worker 
631*5e7646d2SAndroid Build Coastguard Worker 	 /*
632*5e7646d2SAndroid Build Coastguard Worker 	  * Renew Avahi client...
633*5e7646d2SAndroid Build Coastguard Worker 	  */
634*5e7646d2SAndroid Build Coastguard Worker 
635*5e7646d2SAndroid Build Coastguard Worker 	  DNSSDClient = avahi_client_new(avahi_threaded_poll_get(DNSSDMaster), AVAHI_CLIENT_NO_FAIL, dnssdClientCallback, NULL, &error);
636*5e7646d2SAndroid Build Coastguard Worker 
637*5e7646d2SAndroid Build Coastguard Worker 	  if (!DNSSDClient)
638*5e7646d2SAndroid Build Coastguard Worker 	  {
639*5e7646d2SAndroid Build Coastguard Worker 	    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to communicate with avahi-daemon: %s", dnssdErrorString(error));
640*5e7646d2SAndroid Build Coastguard Worker 	    if (FatalErrors & CUPSD_FATAL_BROWSE)
641*5e7646d2SAndroid Build Coastguard Worker 	      cupsdEndProcess(getpid(), 0);
642*5e7646d2SAndroid Build Coastguard Worker 	  }
643*5e7646d2SAndroid Build Coastguard Worker 	}
644*5e7646d2SAndroid Build Coastguard Worker 	else
645*5e7646d2SAndroid Build Coastguard Worker 	{
646*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_ERROR, "Communication with avahi-daemon has failed: %s", avahi_strerror(avahi_client_errno(c)));
647*5e7646d2SAndroid Build Coastguard Worker 	  if (FatalErrors & CUPSD_FATAL_BROWSE)
648*5e7646d2SAndroid Build Coastguard Worker 	    cupsdEndProcess(getpid(), 0);
649*5e7646d2SAndroid Build Coastguard Worker 	}
650*5e7646d2SAndroid Build Coastguard Worker 	break;
651*5e7646d2SAndroid Build Coastguard Worker 
652*5e7646d2SAndroid Build Coastguard Worker     default:
653*5e7646d2SAndroid Build Coastguard Worker         break;
654*5e7646d2SAndroid Build Coastguard Worker   }
655*5e7646d2SAndroid Build Coastguard Worker }
656*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_AVAHI */
657*5e7646d2SAndroid Build Coastguard Worker 
658*5e7646d2SAndroid Build Coastguard Worker 
659*5e7646d2SAndroid Build Coastguard Worker /*
660*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdDeregisterAllPrinters()' - Deregister all printers.
661*5e7646d2SAndroid Build Coastguard Worker  */
662*5e7646d2SAndroid Build Coastguard Worker 
663*5e7646d2SAndroid Build Coastguard Worker static void
dnssdDeregisterAllPrinters(int from_callback)664*5e7646d2SAndroid Build Coastguard Worker dnssdDeregisterAllPrinters(
665*5e7646d2SAndroid Build Coastguard Worker     int             from_callback)	/* I - Deregistering because of callback? */
666*5e7646d2SAndroid Build Coastguard Worker {
667*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Current printer */
668*5e7646d2SAndroid Build Coastguard Worker 
669*5e7646d2SAndroid Build Coastguard Worker 
670*5e7646d2SAndroid Build Coastguard Worker   if (!DNSSDMaster)
671*5e7646d2SAndroid Build Coastguard Worker     return;
672*5e7646d2SAndroid Build Coastguard Worker 
673*5e7646d2SAndroid Build Coastguard Worker   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
674*5e7646d2SAndroid Build Coastguard Worker        p;
675*5e7646d2SAndroid Build Coastguard Worker        p = (cupsd_printer_t *)cupsArrayNext(Printers))
676*5e7646d2SAndroid Build Coastguard Worker     if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
677*5e7646d2SAndroid Build Coastguard Worker       dnssdDeregisterPrinter(p, 1, from_callback);
678*5e7646d2SAndroid Build Coastguard Worker }
679*5e7646d2SAndroid Build Coastguard Worker 
680*5e7646d2SAndroid Build Coastguard Worker 
681*5e7646d2SAndroid Build Coastguard Worker /*
682*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdDeregisterInstance()' - Deregister a DNS-SD service instance.
683*5e7646d2SAndroid Build Coastguard Worker  */
684*5e7646d2SAndroid Build Coastguard Worker 
685*5e7646d2SAndroid Build Coastguard Worker static void
dnssdDeregisterInstance(cupsd_srv_t * srv,int from_callback)686*5e7646d2SAndroid Build Coastguard Worker dnssdDeregisterInstance(
687*5e7646d2SAndroid Build Coastguard Worker     cupsd_srv_t     *srv,		/* I - Service */
688*5e7646d2SAndroid Build Coastguard Worker     int             from_callback)	/* I - Called from callback? */
689*5e7646d2SAndroid Build Coastguard Worker {
690*5e7646d2SAndroid Build Coastguard Worker   if (!srv || !*srv)
691*5e7646d2SAndroid Build Coastguard Worker     return;
692*5e7646d2SAndroid Build Coastguard Worker 
693*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
694*5e7646d2SAndroid Build Coastguard Worker   (void)from_callback;
695*5e7646d2SAndroid Build Coastguard Worker 
696*5e7646d2SAndroid Build Coastguard Worker   DNSServiceRefDeallocate(*srv);
697*5e7646d2SAndroid Build Coastguard Worker 
698*5e7646d2SAndroid Build Coastguard Worker   *srv = NULL;
699*5e7646d2SAndroid Build Coastguard Worker 
700*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
701*5e7646d2SAndroid Build Coastguard Worker   if (!from_callback)
702*5e7646d2SAndroid Build Coastguard Worker     avahi_threaded_poll_lock(DNSSDMaster);
703*5e7646d2SAndroid Build Coastguard Worker 
704*5e7646d2SAndroid Build Coastguard Worker   if (*srv)
705*5e7646d2SAndroid Build Coastguard Worker   {
706*5e7646d2SAndroid Build Coastguard Worker     avahi_entry_group_free(*srv);
707*5e7646d2SAndroid Build Coastguard Worker     *srv = NULL;
708*5e7646d2SAndroid Build Coastguard Worker   }
709*5e7646d2SAndroid Build Coastguard Worker 
710*5e7646d2SAndroid Build Coastguard Worker   if (!from_callback)
711*5e7646d2SAndroid Build Coastguard Worker     avahi_threaded_poll_unlock(DNSSDMaster);
712*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
713*5e7646d2SAndroid Build Coastguard Worker }
714*5e7646d2SAndroid Build Coastguard Worker 
715*5e7646d2SAndroid Build Coastguard Worker 
716*5e7646d2SAndroid Build Coastguard Worker /*
717*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdDeregisterPrinter()' - Deregister all services for a printer.
718*5e7646d2SAndroid Build Coastguard Worker  */
719*5e7646d2SAndroid Build Coastguard Worker 
720*5e7646d2SAndroid Build Coastguard Worker static void
dnssdDeregisterPrinter(cupsd_printer_t * p,int clear_name,int from_callback)721*5e7646d2SAndroid Build Coastguard Worker dnssdDeregisterPrinter(
722*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
723*5e7646d2SAndroid Build Coastguard Worker     int             clear_name,		/* I - Clear the name? */
724*5e7646d2SAndroid Build Coastguard Worker     int             from_callback)	/* I - Called from callback? */
725*5e7646d2SAndroid Build Coastguard Worker 
726*5e7646d2SAndroid Build Coastguard Worker {
727*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
728*5e7646d2SAndroid Build Coastguard Worker                   "dnssdDeregisterPrinter(p=%p(%s), clear_name=%d)", p, p->name,
729*5e7646d2SAndroid Build Coastguard Worker                   clear_name);
730*5e7646d2SAndroid Build Coastguard Worker 
731*5e7646d2SAndroid Build Coastguard Worker   if (p->ipp_srv)
732*5e7646d2SAndroid Build Coastguard Worker   {
733*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterInstance(&p->ipp_srv, from_callback);
734*5e7646d2SAndroid Build Coastguard Worker 
735*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
736*5e7646d2SAndroid Build Coastguard Worker #    ifdef HAVE_SSL
737*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterInstance(&p->ipps_srv, from_callback);
738*5e7646d2SAndroid Build Coastguard Worker #    endif /* HAVE_SSL */
739*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterInstance(&p->printer_srv, from_callback);
740*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
741*5e7646d2SAndroid Build Coastguard Worker   }
742*5e7646d2SAndroid Build Coastguard Worker 
743*5e7646d2SAndroid Build Coastguard Worker  /*
744*5e7646d2SAndroid Build Coastguard Worker   * Remove the printer from the array of DNS-SD printers but keep the
745*5e7646d2SAndroid Build Coastguard Worker   * registered name...
746*5e7646d2SAndroid Build Coastguard Worker   */
747*5e7646d2SAndroid Build Coastguard Worker 
748*5e7646d2SAndroid Build Coastguard Worker   cupsArrayRemove(DNSSDPrinters, p);
749*5e7646d2SAndroid Build Coastguard Worker 
750*5e7646d2SAndroid Build Coastguard Worker  /*
751*5e7646d2SAndroid Build Coastguard Worker   * Optionally clear the service name...
752*5e7646d2SAndroid Build Coastguard Worker   */
753*5e7646d2SAndroid Build Coastguard Worker 
754*5e7646d2SAndroid Build Coastguard Worker   if (clear_name)
755*5e7646d2SAndroid Build Coastguard Worker     cupsdClearString(&p->reg_name);
756*5e7646d2SAndroid Build Coastguard Worker }
757*5e7646d2SAndroid Build Coastguard Worker 
758*5e7646d2SAndroid Build Coastguard Worker 
759*5e7646d2SAndroid Build Coastguard Worker /*
760*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdErrorString()' - Return an error string for an error code.
761*5e7646d2SAndroid Build Coastguard Worker  */
762*5e7646d2SAndroid Build Coastguard Worker 
763*5e7646d2SAndroid Build Coastguard Worker static const char *			/* O - Error message */
dnssdErrorString(int error)764*5e7646d2SAndroid Build Coastguard Worker dnssdErrorString(int error)		/* I - Error number */
765*5e7646d2SAndroid Build Coastguard Worker {
766*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
767*5e7646d2SAndroid Build Coastguard Worker   switch (error)
768*5e7646d2SAndroid Build Coastguard Worker   {
769*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NoError :
770*5e7646d2SAndroid Build Coastguard Worker         return ("OK.");
771*5e7646d2SAndroid Build Coastguard Worker 
772*5e7646d2SAndroid Build Coastguard Worker     default :
773*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Unknown :
774*5e7646d2SAndroid Build Coastguard Worker         return ("Unknown error.");
775*5e7646d2SAndroid Build Coastguard Worker 
776*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NoSuchName :
777*5e7646d2SAndroid Build Coastguard Worker         return ("Service not found.");
778*5e7646d2SAndroid Build Coastguard Worker 
779*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NoMemory :
780*5e7646d2SAndroid Build Coastguard Worker         return ("Out of memory.");
781*5e7646d2SAndroid Build Coastguard Worker 
782*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadParam :
783*5e7646d2SAndroid Build Coastguard Worker         return ("Bad parameter.");
784*5e7646d2SAndroid Build Coastguard Worker 
785*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadReference :
786*5e7646d2SAndroid Build Coastguard Worker         return ("Bad service reference.");
787*5e7646d2SAndroid Build Coastguard Worker 
788*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadState :
789*5e7646d2SAndroid Build Coastguard Worker         return ("Bad state.");
790*5e7646d2SAndroid Build Coastguard Worker 
791*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadFlags :
792*5e7646d2SAndroid Build Coastguard Worker         return ("Bad flags.");
793*5e7646d2SAndroid Build Coastguard Worker 
794*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Unsupported :
795*5e7646d2SAndroid Build Coastguard Worker         return ("Unsupported.");
796*5e7646d2SAndroid Build Coastguard Worker 
797*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NotInitialized :
798*5e7646d2SAndroid Build Coastguard Worker         return ("Not initialized.");
799*5e7646d2SAndroid Build Coastguard Worker 
800*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_AlreadyRegistered :
801*5e7646d2SAndroid Build Coastguard Worker         return ("Already registered.");
802*5e7646d2SAndroid Build Coastguard Worker 
803*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NameConflict :
804*5e7646d2SAndroid Build Coastguard Worker         return ("Name conflict.");
805*5e7646d2SAndroid Build Coastguard Worker 
806*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Invalid :
807*5e7646d2SAndroid Build Coastguard Worker         return ("Invalid name.");
808*5e7646d2SAndroid Build Coastguard Worker 
809*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Firewall :
810*5e7646d2SAndroid Build Coastguard Worker         return ("Firewall prevents registration.");
811*5e7646d2SAndroid Build Coastguard Worker 
812*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Incompatible :
813*5e7646d2SAndroid Build Coastguard Worker         return ("Client library incompatible.");
814*5e7646d2SAndroid Build Coastguard Worker 
815*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadInterfaceIndex :
816*5e7646d2SAndroid Build Coastguard Worker         return ("Bad interface index.");
817*5e7646d2SAndroid Build Coastguard Worker 
818*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Refused :
819*5e7646d2SAndroid Build Coastguard Worker         return ("Server prevents registration.");
820*5e7646d2SAndroid Build Coastguard Worker 
821*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NoSuchRecord :
822*5e7646d2SAndroid Build Coastguard Worker         return ("Record not found.");
823*5e7646d2SAndroid Build Coastguard Worker 
824*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NoAuth :
825*5e7646d2SAndroid Build Coastguard Worker         return ("Authentication required.");
826*5e7646d2SAndroid Build Coastguard Worker 
827*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NoSuchKey :
828*5e7646d2SAndroid Build Coastguard Worker         return ("Encryption key not found.");
829*5e7646d2SAndroid Build Coastguard Worker 
830*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NATTraversal :
831*5e7646d2SAndroid Build Coastguard Worker         return ("Unable to traverse NAT boundary.");
832*5e7646d2SAndroid Build Coastguard Worker 
833*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_DoubleNAT :
834*5e7646d2SAndroid Build Coastguard Worker         return ("Unable to traverse double-NAT boundary.");
835*5e7646d2SAndroid Build Coastguard Worker 
836*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadTime :
837*5e7646d2SAndroid Build Coastguard Worker         return ("Bad system time.");
838*5e7646d2SAndroid Build Coastguard Worker 
839*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadSig :
840*5e7646d2SAndroid Build Coastguard Worker         return ("Bad signature.");
841*5e7646d2SAndroid Build Coastguard Worker 
842*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_BadKey :
843*5e7646d2SAndroid Build Coastguard Worker         return ("Bad encryption key.");
844*5e7646d2SAndroid Build Coastguard Worker 
845*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Transient :
846*5e7646d2SAndroid Build Coastguard Worker         return ("Transient error occurred - please try again.");
847*5e7646d2SAndroid Build Coastguard Worker 
848*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_ServiceNotRunning :
849*5e7646d2SAndroid Build Coastguard Worker         return ("Server not running.");
850*5e7646d2SAndroid Build Coastguard Worker 
851*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NATPortMappingUnsupported :
852*5e7646d2SAndroid Build Coastguard Worker         return ("NAT doesn't support NAT-PMP or UPnP.");
853*5e7646d2SAndroid Build Coastguard Worker 
854*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NATPortMappingDisabled :
855*5e7646d2SAndroid Build Coastguard Worker         return ("NAT supports NAT-PNP or UPnP but it is disabled.");
856*5e7646d2SAndroid Build Coastguard Worker 
857*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_NoRouter :
858*5e7646d2SAndroid Build Coastguard Worker         return ("No Internet/default router configured.");
859*5e7646d2SAndroid Build Coastguard Worker 
860*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_PollingMode :
861*5e7646d2SAndroid Build Coastguard Worker         return ("Service polling mode error.");
862*5e7646d2SAndroid Build Coastguard Worker 
863*5e7646d2SAndroid Build Coastguard Worker     case kDNSServiceErr_Timeout :
864*5e7646d2SAndroid Build Coastguard Worker         return ("Service timeout.");
865*5e7646d2SAndroid Build Coastguard Worker   }
866*5e7646d2SAndroid Build Coastguard Worker 
867*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
868*5e7646d2SAndroid Build Coastguard Worker   return (avahi_strerror(error));
869*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
870*5e7646d2SAndroid Build Coastguard Worker }
871*5e7646d2SAndroid Build Coastguard Worker 
872*5e7646d2SAndroid Build Coastguard Worker 
873*5e7646d2SAndroid Build Coastguard Worker /*
874*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdRegisterCallback()' - Free a TXT record.
875*5e7646d2SAndroid Build Coastguard Worker  */
876*5e7646d2SAndroid Build Coastguard Worker 
877*5e7646d2SAndroid Build Coastguard Worker static void
dnssdFreeTxtRecord(cupsd_txt_t * txt)878*5e7646d2SAndroid Build Coastguard Worker dnssdFreeTxtRecord(cupsd_txt_t *txt)	/* I - TXT record */
879*5e7646d2SAndroid Build Coastguard Worker {
880*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
881*5e7646d2SAndroid Build Coastguard Worker   TXTRecordDeallocate(txt);
882*5e7646d2SAndroid Build Coastguard Worker 
883*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
884*5e7646d2SAndroid Build Coastguard Worker   avahi_string_list_free(*txt);
885*5e7646d2SAndroid Build Coastguard Worker   *txt = NULL;
886*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
887*5e7646d2SAndroid Build Coastguard Worker }
888*5e7646d2SAndroid Build Coastguard Worker 
889*5e7646d2SAndroid Build Coastguard Worker 
890*5e7646d2SAndroid Build Coastguard Worker /*
891*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdRegisterAllPrinters()' - Register all printers.
892*5e7646d2SAndroid Build Coastguard Worker  */
893*5e7646d2SAndroid Build Coastguard Worker 
894*5e7646d2SAndroid Build Coastguard Worker static void
dnssdRegisterAllPrinters(int from_callback)895*5e7646d2SAndroid Build Coastguard Worker dnssdRegisterAllPrinters(int from_callback)	/* I - Called from callback? */
896*5e7646d2SAndroid Build Coastguard Worker {
897*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;			/* Current printer */
898*5e7646d2SAndroid Build Coastguard Worker 
899*5e7646d2SAndroid Build Coastguard Worker 
900*5e7646d2SAndroid Build Coastguard Worker   if (!DNSSDMaster)
901*5e7646d2SAndroid Build Coastguard Worker     return;
902*5e7646d2SAndroid Build Coastguard Worker 
903*5e7646d2SAndroid Build Coastguard Worker   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
904*5e7646d2SAndroid Build Coastguard Worker        p;
905*5e7646d2SAndroid Build Coastguard Worker        p = (cupsd_printer_t *)cupsArrayNext(Printers))
906*5e7646d2SAndroid Build Coastguard Worker     if (!(p->type & (CUPS_PRINTER_REMOTE | CUPS_PRINTER_SCANNER)))
907*5e7646d2SAndroid Build Coastguard Worker       dnssdRegisterPrinter(p, from_callback);
908*5e7646d2SAndroid Build Coastguard Worker }
909*5e7646d2SAndroid Build Coastguard Worker 
910*5e7646d2SAndroid Build Coastguard Worker 
911*5e7646d2SAndroid Build Coastguard Worker /*
912*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdRegisterCallback()' - DNSServiceRegister callback.
913*5e7646d2SAndroid Build Coastguard Worker  */
914*5e7646d2SAndroid Build Coastguard Worker 
915*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
916*5e7646d2SAndroid Build Coastguard Worker static void
dnssdRegisterCallback(DNSServiceRef sdRef,DNSServiceFlags flags,DNSServiceErrorType errorCode,const char * name,const char * regtype,const char * domain,void * context)917*5e7646d2SAndroid Build Coastguard Worker dnssdRegisterCallback(
918*5e7646d2SAndroid Build Coastguard Worker     DNSServiceRef	sdRef,		/* I - DNS Service reference */
919*5e7646d2SAndroid Build Coastguard Worker     DNSServiceFlags	flags,		/* I - Reserved for future use */
920*5e7646d2SAndroid Build Coastguard Worker     DNSServiceErrorType	errorCode,	/* I - Error code */
921*5e7646d2SAndroid Build Coastguard Worker     const char		*name,     	/* I - Service name */
922*5e7646d2SAndroid Build Coastguard Worker     const char		*regtype,  	/* I - Service type */
923*5e7646d2SAndroid Build Coastguard Worker     const char		*domain,   	/* I - Domain. ".local" for now */
924*5e7646d2SAndroid Build Coastguard Worker     void		*context)	/* I - Printer */
925*5e7646d2SAndroid Build Coastguard Worker {
926*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t *p = (cupsd_printer_t *)context;
927*5e7646d2SAndroid Build Coastguard Worker 					/* Current printer */
928*5e7646d2SAndroid Build Coastguard Worker 
929*5e7646d2SAndroid Build Coastguard Worker 
930*5e7646d2SAndroid Build Coastguard Worker   (void)sdRef;
931*5e7646d2SAndroid Build Coastguard Worker   (void)flags;
932*5e7646d2SAndroid Build Coastguard Worker   (void)domain;
933*5e7646d2SAndroid Build Coastguard Worker 
934*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterCallback(%s, %s) for %s (%s)",
935*5e7646d2SAndroid Build Coastguard Worker                   name, regtype, p ? p->name : "Web Interface",
936*5e7646d2SAndroid Build Coastguard Worker 		  p ? (p->reg_name ? p->reg_name : "(null)") : "NA");
937*5e7646d2SAndroid Build Coastguard Worker 
938*5e7646d2SAndroid Build Coastguard Worker   if (errorCode)
939*5e7646d2SAndroid Build Coastguard Worker   {
940*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR,
941*5e7646d2SAndroid Build Coastguard Worker 		    "DNSServiceRegister failed with error %d", (int)errorCode);
942*5e7646d2SAndroid Build Coastguard Worker     return;
943*5e7646d2SAndroid Build Coastguard Worker   }
944*5e7646d2SAndroid Build Coastguard Worker   else if (p && (!p->reg_name || _cups_strcasecmp(name, p->reg_name)))
945*5e7646d2SAndroid Build Coastguard Worker   {
946*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_INFO, "Using service name \"%s\" for \"%s\"",
947*5e7646d2SAndroid Build Coastguard Worker                     name, p->name);
948*5e7646d2SAndroid Build Coastguard Worker 
949*5e7646d2SAndroid Build Coastguard Worker     cupsArrayRemove(DNSSDPrinters, p);
950*5e7646d2SAndroid Build Coastguard Worker     cupsdSetString(&p->reg_name, name);
951*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(DNSSDPrinters, p);
952*5e7646d2SAndroid Build Coastguard Worker 
953*5e7646d2SAndroid Build Coastguard Worker     LastEvent |= CUPSD_EVENT_PRINTER_MODIFIED;
954*5e7646d2SAndroid Build Coastguard Worker   }
955*5e7646d2SAndroid Build Coastguard Worker }
956*5e7646d2SAndroid Build Coastguard Worker 
957*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
958*5e7646d2SAndroid Build Coastguard Worker static void
dnssdRegisterCallback(AvahiEntryGroup * srv,AvahiEntryGroupState state,void * context)959*5e7646d2SAndroid Build Coastguard Worker dnssdRegisterCallback(
960*5e7646d2SAndroid Build Coastguard Worker     AvahiEntryGroup      *srv,		/* I - Service */
961*5e7646d2SAndroid Build Coastguard Worker     AvahiEntryGroupState state,		/* I - Registration state */
962*5e7646d2SAndroid Build Coastguard Worker     void                 *context)	/* I - Printer */
963*5e7646d2SAndroid Build Coastguard Worker {
964*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t *p = (cupsd_printer_t *)context;
965*5e7646d2SAndroid Build Coastguard Worker 					/* Current printer */
966*5e7646d2SAndroid Build Coastguard Worker 
967*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
968*5e7646d2SAndroid Build Coastguard Worker                   "dnssdRegisterCallback(srv=%p, state=%d, context=%p) "
969*5e7646d2SAndroid Build Coastguard Worker                   "for %s (%s)", srv, state, context,
970*5e7646d2SAndroid Build Coastguard Worker                   p ? p->name : "Web Interface",
971*5e7646d2SAndroid Build Coastguard Worker 		  p ? (p->reg_name ? p->reg_name : "(null)") : "NA");
972*5e7646d2SAndroid Build Coastguard Worker 
973*5e7646d2SAndroid Build Coastguard Worker   /* TODO: Handle collisions with avahi_alternate_service_name(p->reg_name)? */
974*5e7646d2SAndroid Build Coastguard Worker }
975*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
976*5e7646d2SAndroid Build Coastguard Worker 
977*5e7646d2SAndroid Build Coastguard Worker 
978*5e7646d2SAndroid Build Coastguard Worker /*
979*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdRegisterInstance()' - Register an instance of a printer service.
980*5e7646d2SAndroid Build Coastguard Worker  */
981*5e7646d2SAndroid Build Coastguard Worker 
982*5e7646d2SAndroid Build Coastguard Worker static int				/* O - 1 on success, 0 on failure */
dnssdRegisterInstance(cupsd_srv_t * srv,cupsd_printer_t * p,char * name,const char * type,const char * subtypes,int port,cupsd_txt_t * txt,int commit,int from_callback)983*5e7646d2SAndroid Build Coastguard Worker dnssdRegisterInstance(
984*5e7646d2SAndroid Build Coastguard Worker     cupsd_srv_t     *srv,		/* O - Service */
985*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
986*5e7646d2SAndroid Build Coastguard Worker     char            *name,		/* I - DNS-SD service name */
987*5e7646d2SAndroid Build Coastguard Worker     const char      *type,		/* I - DNS-SD service type */
988*5e7646d2SAndroid Build Coastguard Worker     const char      *subtypes,		/* I - Subtypes to register or NULL */
989*5e7646d2SAndroid Build Coastguard Worker     int             port,		/* I - Port number or 0 */
990*5e7646d2SAndroid Build Coastguard Worker     cupsd_txt_t     *txt,		/* I - TXT record */
991*5e7646d2SAndroid Build Coastguard Worker     int             commit,		/* I - Commit registration? */
992*5e7646d2SAndroid Build Coastguard Worker     int             from_callback)	/* I - Called from callback? */
993*5e7646d2SAndroid Build Coastguard Worker {
994*5e7646d2SAndroid Build Coastguard Worker   char	temp[256],			/* Temporary string */
995*5e7646d2SAndroid Build Coastguard Worker 	*ptr;				/* Pointer into string */
996*5e7646d2SAndroid Build Coastguard Worker   int	error;				/* Any error */
997*5e7646d2SAndroid Build Coastguard Worker 
998*5e7646d2SAndroid Build Coastguard Worker 
999*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
1000*5e7646d2SAndroid Build Coastguard Worker   (void)from_callback;
1001*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
1002*5e7646d2SAndroid Build Coastguard Worker 
1003*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG, "Registering \"%s\" with DNS-SD type \"%s\".", name, type);
1004*5e7646d2SAndroid Build Coastguard Worker 
1005*5e7646d2SAndroid Build Coastguard Worker   if (p && !srv)
1006*5e7646d2SAndroid Build Coastguard Worker   {
1007*5e7646d2SAndroid Build Coastguard Worker    /*
1008*5e7646d2SAndroid Build Coastguard Worker     * Assign the correct pointer for "srv"...
1009*5e7646d2SAndroid Build Coastguard Worker     */
1010*5e7646d2SAndroid Build Coastguard Worker 
1011*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
1012*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(type, "_printer._tcp"))
1013*5e7646d2SAndroid Build Coastguard Worker       srv = &p->printer_srv;		/* Target LPD service */
1014*5e7646d2SAndroid Build Coastguard Worker #    ifdef HAVE_SSL
1015*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(type, "_ipps._tcp"))
1016*5e7646d2SAndroid Build Coastguard Worker       srv = &p->ipps_srv;		/* Target IPPS service */
1017*5e7646d2SAndroid Build Coastguard Worker #    endif /* HAVE_SSL */
1018*5e7646d2SAndroid Build Coastguard Worker     else
1019*5e7646d2SAndroid Build Coastguard Worker       srv = &p->ipp_srv;		/* Target IPP service */
1020*5e7646d2SAndroid Build Coastguard Worker 
1021*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
1022*5e7646d2SAndroid Build Coastguard Worker     srv = &p->ipp_srv;			/* Target service group */
1023*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
1024*5e7646d2SAndroid Build Coastguard Worker   }
1025*5e7646d2SAndroid Build Coastguard Worker 
1026*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
1027*5e7646d2SAndroid Build Coastguard Worker   (void)commit;
1028*5e7646d2SAndroid Build Coastguard Worker 
1029*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
1030*5e7646d2SAndroid Build Coastguard Worker   if (!from_callback)
1031*5e7646d2SAndroid Build Coastguard Worker     avahi_threaded_poll_lock(DNSSDMaster);
1032*5e7646d2SAndroid Build Coastguard Worker 
1033*5e7646d2SAndroid Build Coastguard Worker   if (!*srv)
1034*5e7646d2SAndroid Build Coastguard Worker     *srv = avahi_entry_group_new(DNSSDClient, dnssdRegisterCallback, NULL);
1035*5e7646d2SAndroid Build Coastguard Worker   if (!*srv)
1036*5e7646d2SAndroid Build Coastguard Worker   {
1037*5e7646d2SAndroid Build Coastguard Worker     if (!from_callback)
1038*5e7646d2SAndroid Build Coastguard Worker       avahi_threaded_poll_unlock(DNSSDMaster);
1039*5e7646d2SAndroid Build Coastguard Worker 
1040*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
1041*5e7646d2SAndroid Build Coastguard Worker                     name, dnssdErrorString(avahi_client_errno(DNSSDClient)));
1042*5e7646d2SAndroid Build Coastguard Worker     return (0);
1043*5e7646d2SAndroid Build Coastguard Worker   }
1044*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
1045*5e7646d2SAndroid Build Coastguard Worker 
1046*5e7646d2SAndroid Build Coastguard Worker  /*
1047*5e7646d2SAndroid Build Coastguard Worker   * Make sure the name is <= 63 octets, and when we truncate be sure to
1048*5e7646d2SAndroid Build Coastguard Worker   * properly truncate any UTF-8 characters...
1049*5e7646d2SAndroid Build Coastguard Worker   */
1050*5e7646d2SAndroid Build Coastguard Worker 
1051*5e7646d2SAndroid Build Coastguard Worker   ptr = name + strlen(name);
1052*5e7646d2SAndroid Build Coastguard Worker   while ((ptr - name) > 63)
1053*5e7646d2SAndroid Build Coastguard Worker   {
1054*5e7646d2SAndroid Build Coastguard Worker     do
1055*5e7646d2SAndroid Build Coastguard Worker     {
1056*5e7646d2SAndroid Build Coastguard Worker       ptr --;
1057*5e7646d2SAndroid Build Coastguard Worker     }
1058*5e7646d2SAndroid Build Coastguard Worker     while (ptr > name && (*ptr & 0xc0) == 0x80);
1059*5e7646d2SAndroid Build Coastguard Worker 
1060*5e7646d2SAndroid Build Coastguard Worker     if (ptr > name)
1061*5e7646d2SAndroid Build Coastguard Worker       *ptr = '\0';
1062*5e7646d2SAndroid Build Coastguard Worker   }
1063*5e7646d2SAndroid Build Coastguard Worker 
1064*5e7646d2SAndroid Build Coastguard Worker  /*
1065*5e7646d2SAndroid Build Coastguard Worker   * Register the service...
1066*5e7646d2SAndroid Build Coastguard Worker   */
1067*5e7646d2SAndroid Build Coastguard Worker 
1068*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
1069*5e7646d2SAndroid Build Coastguard Worker   if (subtypes)
1070*5e7646d2SAndroid Build Coastguard Worker     snprintf(temp, sizeof(temp), "%s,%s", type, subtypes);
1071*5e7646d2SAndroid Build Coastguard Worker   else
1072*5e7646d2SAndroid Build Coastguard Worker     strlcpy(temp, type, sizeof(temp));
1073*5e7646d2SAndroid Build Coastguard Worker 
1074*5e7646d2SAndroid Build Coastguard Worker   *srv  = DNSSDMaster;
1075*5e7646d2SAndroid Build Coastguard Worker   error = DNSServiceRegister(srv, kDNSServiceFlagsShareConnection,
1076*5e7646d2SAndroid Build Coastguard Worker 			     0, name, temp, NULL, DNSSDHostName, htons(port),
1077*5e7646d2SAndroid Build Coastguard Worker 			     txt ? TXTRecordGetLength(txt) : 0,
1078*5e7646d2SAndroid Build Coastguard Worker 			     txt ? TXTRecordGetBytesPtr(txt) : NULL,
1079*5e7646d2SAndroid Build Coastguard Worker 			     dnssdRegisterCallback, p);
1080*5e7646d2SAndroid Build Coastguard Worker 
1081*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
1082*5e7646d2SAndroid Build Coastguard Worker   if (txt)
1083*5e7646d2SAndroid Build Coastguard Worker   {
1084*5e7646d2SAndroid Build Coastguard Worker     AvahiStringList *temptxt;
1085*5e7646d2SAndroid Build Coastguard Worker     for (temptxt = *txt; temptxt; temptxt = temptxt->next)
1086*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS_SD \"%s\" %s", name, temptxt->text);
1087*5e7646d2SAndroid Build Coastguard Worker   }
1088*5e7646d2SAndroid Build Coastguard Worker 
1089*5e7646d2SAndroid Build Coastguard Worker   error = avahi_entry_group_add_service_strlst(*srv, AVAHI_IF_UNSPEC,
1090*5e7646d2SAndroid Build Coastguard Worker                                                AVAHI_PROTO_UNSPEC, 0, name,
1091*5e7646d2SAndroid Build Coastguard Worker                                                type, NULL, DNSSDHostName, port,
1092*5e7646d2SAndroid Build Coastguard Worker                                                txt ? *txt : NULL);
1093*5e7646d2SAndroid Build Coastguard Worker   if (error)
1094*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD service add for \"%s\" failed.",
1095*5e7646d2SAndroid Build Coastguard Worker                     name);
1096*5e7646d2SAndroid Build Coastguard Worker 
1097*5e7646d2SAndroid Build Coastguard Worker   if (!error && subtypes)
1098*5e7646d2SAndroid Build Coastguard Worker   {
1099*5e7646d2SAndroid Build Coastguard Worker    /*
1100*5e7646d2SAndroid Build Coastguard Worker     * Register all of the subtypes...
1101*5e7646d2SAndroid Build Coastguard Worker     */
1102*5e7646d2SAndroid Build Coastguard Worker 
1103*5e7646d2SAndroid Build Coastguard Worker     char	*start,			/* Start of subtype */
1104*5e7646d2SAndroid Build Coastguard Worker 		subtype[256];		/* Subtype string */
1105*5e7646d2SAndroid Build Coastguard Worker 
1106*5e7646d2SAndroid Build Coastguard Worker     strlcpy(temp, subtypes, sizeof(temp));
1107*5e7646d2SAndroid Build Coastguard Worker 
1108*5e7646d2SAndroid Build Coastguard Worker     for (start = temp; *start; start = ptr)
1109*5e7646d2SAndroid Build Coastguard Worker     {
1110*5e7646d2SAndroid Build Coastguard Worker      /*
1111*5e7646d2SAndroid Build Coastguard Worker       * Skip leading whitespace...
1112*5e7646d2SAndroid Build Coastguard Worker       */
1113*5e7646d2SAndroid Build Coastguard Worker 
1114*5e7646d2SAndroid Build Coastguard Worker       while (*start && isspace(*start & 255))
1115*5e7646d2SAndroid Build Coastguard Worker         start ++;
1116*5e7646d2SAndroid Build Coastguard Worker 
1117*5e7646d2SAndroid Build Coastguard Worker      /*
1118*5e7646d2SAndroid Build Coastguard Worker       * Grab everything up to the next comma or the end of the string...
1119*5e7646d2SAndroid Build Coastguard Worker       */
1120*5e7646d2SAndroid Build Coastguard Worker 
1121*5e7646d2SAndroid Build Coastguard Worker       for (ptr = start; *ptr && *ptr != ','; ptr ++);
1122*5e7646d2SAndroid Build Coastguard Worker 
1123*5e7646d2SAndroid Build Coastguard Worker       if (*ptr)
1124*5e7646d2SAndroid Build Coastguard Worker         *ptr++ = '\0';
1125*5e7646d2SAndroid Build Coastguard Worker 
1126*5e7646d2SAndroid Build Coastguard Worker       if (!*start)
1127*5e7646d2SAndroid Build Coastguard Worker         break;
1128*5e7646d2SAndroid Build Coastguard Worker 
1129*5e7646d2SAndroid Build Coastguard Worker      /*
1130*5e7646d2SAndroid Build Coastguard Worker       * Register the subtype...
1131*5e7646d2SAndroid Build Coastguard Worker       */
1132*5e7646d2SAndroid Build Coastguard Worker 
1133*5e7646d2SAndroid Build Coastguard Worker       snprintf(subtype, sizeof(subtype), "%s._sub.%s", start, type);
1134*5e7646d2SAndroid Build Coastguard Worker 
1135*5e7646d2SAndroid Build Coastguard Worker       error = avahi_entry_group_add_service_subtype(*srv, AVAHI_IF_UNSPEC,
1136*5e7646d2SAndroid Build Coastguard Worker                                                     AVAHI_PROTO_UNSPEC, 0,
1137*5e7646d2SAndroid Build Coastguard Worker                                                     name, type, NULL, subtype);
1138*5e7646d2SAndroid Build Coastguard Worker       if (error)
1139*5e7646d2SAndroid Build Coastguard Worker       {
1140*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_DEBUG,
1141*5e7646d2SAndroid Build Coastguard Worker                         "DNS-SD subtype %s registration for \"%s\" failed." ,
1142*5e7646d2SAndroid Build Coastguard Worker                         subtype, name);
1143*5e7646d2SAndroid Build Coastguard Worker         break;
1144*5e7646d2SAndroid Build Coastguard Worker       }
1145*5e7646d2SAndroid Build Coastguard Worker     }
1146*5e7646d2SAndroid Build Coastguard Worker   }
1147*5e7646d2SAndroid Build Coastguard Worker 
1148*5e7646d2SAndroid Build Coastguard Worker   if (!error && commit)
1149*5e7646d2SAndroid Build Coastguard Worker   {
1150*5e7646d2SAndroid Build Coastguard Worker     if ((error = avahi_entry_group_commit(*srv)) != 0)
1151*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD commit of \"%s\" failed.",
1152*5e7646d2SAndroid Build Coastguard Worker                       name);
1153*5e7646d2SAndroid Build Coastguard Worker   }
1154*5e7646d2SAndroid Build Coastguard Worker 
1155*5e7646d2SAndroid Build Coastguard Worker   if (!from_callback)
1156*5e7646d2SAndroid Build Coastguard Worker     avahi_threaded_poll_unlock(DNSSDMaster);
1157*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
1158*5e7646d2SAndroid Build Coastguard Worker 
1159*5e7646d2SAndroid Build Coastguard Worker   if (error)
1160*5e7646d2SAndroid Build Coastguard Worker   {
1161*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_WARN, "DNS-SD registration of \"%s\" failed: %s",
1162*5e7646d2SAndroid Build Coastguard Worker                     name, dnssdErrorString(error));
1163*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD type: %s", type);
1164*5e7646d2SAndroid Build Coastguard Worker     if (subtypes)
1165*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG, "DNS-SD sub-types: %s", subtypes);
1166*5e7646d2SAndroid Build Coastguard Worker   }
1167*5e7646d2SAndroid Build Coastguard Worker 
1168*5e7646d2SAndroid Build Coastguard Worker   return (!error);
1169*5e7646d2SAndroid Build Coastguard Worker }
1170*5e7646d2SAndroid Build Coastguard Worker 
1171*5e7646d2SAndroid Build Coastguard Worker 
1172*5e7646d2SAndroid Build Coastguard Worker /*
1173*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdRegisterPrinter()' - Start sending broadcast information for a printer
1174*5e7646d2SAndroid Build Coastguard Worker  *		              or update the broadcast contents.
1175*5e7646d2SAndroid Build Coastguard Worker  */
1176*5e7646d2SAndroid Build Coastguard Worker 
1177*5e7646d2SAndroid Build Coastguard Worker static void
dnssdRegisterPrinter(cupsd_printer_t * p,int from_callback)1178*5e7646d2SAndroid Build Coastguard Worker dnssdRegisterPrinter(
1179*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
1180*5e7646d2SAndroid Build Coastguard Worker     int             from_callback)	/* I - Called from callback? */
1181*5e7646d2SAndroid Build Coastguard Worker {
1182*5e7646d2SAndroid Build Coastguard Worker   char		name[256];		/* Service name */
1183*5e7646d2SAndroid Build Coastguard Worker   int		printer_port;		/* LPD port number */
1184*5e7646d2SAndroid Build Coastguard Worker   int		status;			/* Registration status */
1185*5e7646d2SAndroid Build Coastguard Worker   cupsd_txt_t	ipp_txt,		/* IPP(S) TXT record */
1186*5e7646d2SAndroid Build Coastguard Worker  		printer_txt;		/* LPD TXT record */
1187*5e7646d2SAndroid Build Coastguard Worker 
1188*5e7646d2SAndroid Build Coastguard Worker 
1189*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "dnssdRegisterPrinter(%s) %s", p->name,
1190*5e7646d2SAndroid Build Coastguard Worker                   !p->ipp_srv ? "new" : "update");
1191*5e7646d2SAndroid Build Coastguard Worker 
1192*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_AVAHI
1193*5e7646d2SAndroid Build Coastguard Worker   if (!avahi_running)
1194*5e7646d2SAndroid Build Coastguard Worker     return;
1195*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_AVAHI */
1196*5e7646d2SAndroid Build Coastguard Worker 
1197*5e7646d2SAndroid Build Coastguard Worker  /*
1198*5e7646d2SAndroid Build Coastguard Worker   * Remove the current registrations if we have them and then return if
1199*5e7646d2SAndroid Build Coastguard Worker   * per-printer sharing was just disabled...
1200*5e7646d2SAndroid Build Coastguard Worker   */
1201*5e7646d2SAndroid Build Coastguard Worker 
1202*5e7646d2SAndroid Build Coastguard Worker   dnssdDeregisterPrinter(p, 0, from_callback);
1203*5e7646d2SAndroid Build Coastguard Worker 
1204*5e7646d2SAndroid Build Coastguard Worker   if (!p->shared)
1205*5e7646d2SAndroid Build Coastguard Worker     return;
1206*5e7646d2SAndroid Build Coastguard Worker 
1207*5e7646d2SAndroid Build Coastguard Worker  /*
1208*5e7646d2SAndroid Build Coastguard Worker   * Set the registered name as needed; the registered name takes the form of
1209*5e7646d2SAndroid Build Coastguard Worker   * "<printer-info> @ <computer name>"...
1210*5e7646d2SAndroid Build Coastguard Worker   */
1211*5e7646d2SAndroid Build Coastguard Worker 
1212*5e7646d2SAndroid Build Coastguard Worker   if (!p->reg_name)
1213*5e7646d2SAndroid Build Coastguard Worker   {
1214*5e7646d2SAndroid Build Coastguard Worker     if (p->info && strlen(p->info) > 0)
1215*5e7646d2SAndroid Build Coastguard Worker     {
1216*5e7646d2SAndroid Build Coastguard Worker       if (DNSSDComputerName)
1217*5e7646d2SAndroid Build Coastguard Worker 	snprintf(name, sizeof(name), "%s @ %s", p->info, DNSSDComputerName);
1218*5e7646d2SAndroid Build Coastguard Worker       else
1219*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(name, p->info, sizeof(name));
1220*5e7646d2SAndroid Build Coastguard Worker     }
1221*5e7646d2SAndroid Build Coastguard Worker     else if (DNSSDComputerName)
1222*5e7646d2SAndroid Build Coastguard Worker       snprintf(name, sizeof(name), "%s @ %s", p->name, DNSSDComputerName);
1223*5e7646d2SAndroid Build Coastguard Worker     else
1224*5e7646d2SAndroid Build Coastguard Worker       strlcpy(name, p->name, sizeof(name));
1225*5e7646d2SAndroid Build Coastguard Worker   }
1226*5e7646d2SAndroid Build Coastguard Worker   else
1227*5e7646d2SAndroid Build Coastguard Worker     strlcpy(name, p->reg_name, sizeof(name));
1228*5e7646d2SAndroid Build Coastguard Worker 
1229*5e7646d2SAndroid Build Coastguard Worker  /*
1230*5e7646d2SAndroid Build Coastguard Worker   * Register IPP and LPD...
1231*5e7646d2SAndroid Build Coastguard Worker   *
1232*5e7646d2SAndroid Build Coastguard Worker   * We always must register the "_printer" service type in order to reserve
1233*5e7646d2SAndroid Build Coastguard Worker   * our name, but use port number 0 if we haven't actually configured cups-lpd
1234*5e7646d2SAndroid Build Coastguard Worker   * to share via LPD...
1235*5e7646d2SAndroid Build Coastguard Worker   */
1236*5e7646d2SAndroid Build Coastguard Worker 
1237*5e7646d2SAndroid Build Coastguard Worker   ipp_txt     = dnssdBuildTxtRecord(p, 0);
1238*5e7646d2SAndroid Build Coastguard Worker   printer_txt = dnssdBuildTxtRecord(p, 1);
1239*5e7646d2SAndroid Build Coastguard Worker 
1240*5e7646d2SAndroid Build Coastguard Worker   if (BrowseLocalProtocols & BROWSE_LPD)
1241*5e7646d2SAndroid Build Coastguard Worker     printer_port = 515;
1242*5e7646d2SAndroid Build Coastguard Worker   else
1243*5e7646d2SAndroid Build Coastguard Worker     printer_port = 0;
1244*5e7646d2SAndroid Build Coastguard Worker 
1245*5e7646d2SAndroid Build Coastguard Worker   status = dnssdRegisterInstance(NULL, p, name, "_printer._tcp", NULL, printer_port, &printer_txt, 0, from_callback);
1246*5e7646d2SAndroid Build Coastguard Worker 
1247*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_SSL
1248*5e7646d2SAndroid Build Coastguard Worker   if (status)
1249*5e7646d2SAndroid Build Coastguard Worker     dnssdRegisterInstance(NULL, p, name, "_ipps._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 0, from_callback);
1250*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_SSL */
1251*5e7646d2SAndroid Build Coastguard Worker 
1252*5e7646d2SAndroid Build Coastguard Worker   if (status)
1253*5e7646d2SAndroid Build Coastguard Worker   {
1254*5e7646d2SAndroid Build Coastguard Worker    /*
1255*5e7646d2SAndroid Build Coastguard Worker     * Use the "_fax-ipp" service type for fax queues, otherwise use "_ipp"...
1256*5e7646d2SAndroid Build Coastguard Worker     */
1257*5e7646d2SAndroid Build Coastguard Worker 
1258*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_FAX)
1259*5e7646d2SAndroid Build Coastguard Worker       status = dnssdRegisterInstance(NULL, p, name, "_fax-ipp._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 1, from_callback);
1260*5e7646d2SAndroid Build Coastguard Worker     else
1261*5e7646d2SAndroid Build Coastguard Worker       status = dnssdRegisterInstance(NULL, p, name, "_ipp._tcp", DNSSDSubTypes, DNSSDPort, &ipp_txt, 1, from_callback);
1262*5e7646d2SAndroid Build Coastguard Worker   }
1263*5e7646d2SAndroid Build Coastguard Worker 
1264*5e7646d2SAndroid Build Coastguard Worker   dnssdFreeTxtRecord(&ipp_txt);
1265*5e7646d2SAndroid Build Coastguard Worker   dnssdFreeTxtRecord(&printer_txt);
1266*5e7646d2SAndroid Build Coastguard Worker 
1267*5e7646d2SAndroid Build Coastguard Worker   if (status)
1268*5e7646d2SAndroid Build Coastguard Worker   {
1269*5e7646d2SAndroid Build Coastguard Worker    /*
1270*5e7646d2SAndroid Build Coastguard Worker     * Save the registered name and add the printer to the array of DNS-SD
1271*5e7646d2SAndroid Build Coastguard Worker     * printers...
1272*5e7646d2SAndroid Build Coastguard Worker     */
1273*5e7646d2SAndroid Build Coastguard Worker 
1274*5e7646d2SAndroid Build Coastguard Worker     cupsdSetString(&p->reg_name, name);
1275*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(DNSSDPrinters, p);
1276*5e7646d2SAndroid Build Coastguard Worker   }
1277*5e7646d2SAndroid Build Coastguard Worker   else
1278*5e7646d2SAndroid Build Coastguard Worker   {
1279*5e7646d2SAndroid Build Coastguard Worker    /*
1280*5e7646d2SAndroid Build Coastguard Worker     * Registration failed for this printer...
1281*5e7646d2SAndroid Build Coastguard Worker     */
1282*5e7646d2SAndroid Build Coastguard Worker 
1283*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterInstance(&p->ipp_srv, from_callback);
1284*5e7646d2SAndroid Build Coastguard Worker 
1285*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
1286*5e7646d2SAndroid Build Coastguard Worker #    ifdef HAVE_SSL
1287*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterInstance(&p->ipps_srv, from_callback);
1288*5e7646d2SAndroid Build Coastguard Worker #    endif /* HAVE_SSL */
1289*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterInstance(&p->printer_srv, from_callback);
1290*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
1291*5e7646d2SAndroid Build Coastguard Worker   }
1292*5e7646d2SAndroid Build Coastguard Worker }
1293*5e7646d2SAndroid Build Coastguard Worker 
1294*5e7646d2SAndroid Build Coastguard Worker 
1295*5e7646d2SAndroid Build Coastguard Worker /*
1296*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdStop()' - Stop all DNS-SD registrations.
1297*5e7646d2SAndroid Build Coastguard Worker  */
1298*5e7646d2SAndroid Build Coastguard Worker 
1299*5e7646d2SAndroid Build Coastguard Worker static void
dnssdStop(void)1300*5e7646d2SAndroid Build Coastguard Worker dnssdStop(void)
1301*5e7646d2SAndroid Build Coastguard Worker {
1302*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Current printer */
1303*5e7646d2SAndroid Build Coastguard Worker 
1304*5e7646d2SAndroid Build Coastguard Worker 
1305*5e7646d2SAndroid Build Coastguard Worker  /*
1306*5e7646d2SAndroid Build Coastguard Worker   * De-register the individual printers
1307*5e7646d2SAndroid Build Coastguard Worker   */
1308*5e7646d2SAndroid Build Coastguard Worker 
1309*5e7646d2SAndroid Build Coastguard Worker   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
1310*5e7646d2SAndroid Build Coastguard Worker        p;
1311*5e7646d2SAndroid Build Coastguard Worker        p = (cupsd_printer_t *)cupsArrayNext(Printers))
1312*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterPrinter(p, 1, 0);
1313*5e7646d2SAndroid Build Coastguard Worker 
1314*5e7646d2SAndroid Build Coastguard Worker  /*
1315*5e7646d2SAndroid Build Coastguard Worker   * Shutdown the rest of the service refs...
1316*5e7646d2SAndroid Build Coastguard Worker   */
1317*5e7646d2SAndroid Build Coastguard Worker 
1318*5e7646d2SAndroid Build Coastguard Worker   dnssdDeregisterInstance(&WebIFSrv, 0);
1319*5e7646d2SAndroid Build Coastguard Worker 
1320*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
1321*5e7646d2SAndroid Build Coastguard Worker   cupsdRemoveSelect(DNSServiceRefSockFD(DNSSDMaster));
1322*5e7646d2SAndroid Build Coastguard Worker 
1323*5e7646d2SAndroid Build Coastguard Worker   DNSServiceRefDeallocate(DNSSDMaster);
1324*5e7646d2SAndroid Build Coastguard Worker   DNSSDMaster = NULL;
1325*5e7646d2SAndroid Build Coastguard Worker 
1326*5e7646d2SAndroid Build Coastguard Worker #  else /* HAVE_AVAHI */
1327*5e7646d2SAndroid Build Coastguard Worker   if (DNSSDMaster)
1328*5e7646d2SAndroid Build Coastguard Worker     avahi_threaded_poll_stop(DNSSDMaster);
1329*5e7646d2SAndroid Build Coastguard Worker 
1330*5e7646d2SAndroid Build Coastguard Worker   if (DNSSDClient)
1331*5e7646d2SAndroid Build Coastguard Worker   {
1332*5e7646d2SAndroid Build Coastguard Worker     avahi_client_free(DNSSDClient);
1333*5e7646d2SAndroid Build Coastguard Worker     DNSSDClient = NULL;
1334*5e7646d2SAndroid Build Coastguard Worker   }
1335*5e7646d2SAndroid Build Coastguard Worker 
1336*5e7646d2SAndroid Build Coastguard Worker   if (DNSSDMaster)
1337*5e7646d2SAndroid Build Coastguard Worker   {
1338*5e7646d2SAndroid Build Coastguard Worker     avahi_threaded_poll_free(DNSSDMaster);
1339*5e7646d2SAndroid Build Coastguard Worker     DNSSDMaster = NULL;
1340*5e7646d2SAndroid Build Coastguard Worker   }
1341*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
1342*5e7646d2SAndroid Build Coastguard Worker 
1343*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(DNSSDPrinters);
1344*5e7646d2SAndroid Build Coastguard Worker   DNSSDPrinters = NULL;
1345*5e7646d2SAndroid Build Coastguard Worker 
1346*5e7646d2SAndroid Build Coastguard Worker   DNSSDPort = 0;
1347*5e7646d2SAndroid Build Coastguard Worker }
1348*5e7646d2SAndroid Build Coastguard Worker 
1349*5e7646d2SAndroid Build Coastguard Worker 
1350*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_DNSSD
1351*5e7646d2SAndroid Build Coastguard Worker /*
1352*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdUpdate()' - Handle DNS-SD queries.
1353*5e7646d2SAndroid Build Coastguard Worker  */
1354*5e7646d2SAndroid Build Coastguard Worker 
1355*5e7646d2SAndroid Build Coastguard Worker static void
dnssdUpdate(void)1356*5e7646d2SAndroid Build Coastguard Worker dnssdUpdate(void)
1357*5e7646d2SAndroid Build Coastguard Worker {
1358*5e7646d2SAndroid Build Coastguard Worker   DNSServiceErrorType	sdErr;		/* Service discovery error */
1359*5e7646d2SAndroid Build Coastguard Worker 
1360*5e7646d2SAndroid Build Coastguard Worker 
1361*5e7646d2SAndroid Build Coastguard Worker   if ((sdErr = DNSServiceProcessResult(DNSSDMaster)) != kDNSServiceErr_NoError)
1362*5e7646d2SAndroid Build Coastguard Worker   {
1363*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR,
1364*5e7646d2SAndroid Build Coastguard Worker                     "DNS Service Discovery registration error %d!",
1365*5e7646d2SAndroid Build Coastguard Worker 	            sdErr);
1366*5e7646d2SAndroid Build Coastguard Worker     dnssdStop();
1367*5e7646d2SAndroid Build Coastguard Worker   }
1368*5e7646d2SAndroid Build Coastguard Worker }
1369*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_DNSSD */
1370*5e7646d2SAndroid Build Coastguard Worker 
1371*5e7646d2SAndroid Build Coastguard Worker 
1372*5e7646d2SAndroid Build Coastguard Worker /*
1373*5e7646d2SAndroid Build Coastguard Worker  * 'dnssdUpdateDNSSDName()' - Update the listen port, computer name, and web interface registration.
1374*5e7646d2SAndroid Build Coastguard Worker  */
1375*5e7646d2SAndroid Build Coastguard Worker 
1376*5e7646d2SAndroid Build Coastguard Worker static void
dnssdUpdateDNSSDName(int from_callback)1377*5e7646d2SAndroid Build Coastguard Worker dnssdUpdateDNSSDName(int from_callback)	/* I - Called from callback? */
1378*5e7646d2SAndroid Build Coastguard Worker {
1379*5e7646d2SAndroid Build Coastguard Worker   char		webif[1024];		/* Web interface share name */
1380*5e7646d2SAndroid Build Coastguard Worker #  ifdef __APPLE__
1381*5e7646d2SAndroid Build Coastguard Worker   SCDynamicStoreRef sc;			/* Context for dynamic store */
1382*5e7646d2SAndroid Build Coastguard Worker   CFDictionaryRef btmm;			/* Back-to-My-Mac domains */
1383*5e7646d2SAndroid Build Coastguard Worker   CFStringEncoding nameEncoding;	/* Encoding of computer name */
1384*5e7646d2SAndroid Build Coastguard Worker   CFStringRef	nameRef;		/* Host name CFString */
1385*5e7646d2SAndroid Build Coastguard Worker   char		nameBuffer[1024];	/* C-string buffer */
1386*5e7646d2SAndroid Build Coastguard Worker #  endif /* __APPLE__ */
1387*5e7646d2SAndroid Build Coastguard Worker 
1388*5e7646d2SAndroid Build Coastguard Worker 
1389*5e7646d2SAndroid Build Coastguard Worker  /*
1390*5e7646d2SAndroid Build Coastguard Worker   * Only share the web interface and printers when non-local listening is
1391*5e7646d2SAndroid Build Coastguard Worker   * enabled...
1392*5e7646d2SAndroid Build Coastguard Worker   */
1393*5e7646d2SAndroid Build Coastguard Worker 
1394*5e7646d2SAndroid Build Coastguard Worker   if (!DNSSDPort)
1395*5e7646d2SAndroid Build Coastguard Worker   {
1396*5e7646d2SAndroid Build Coastguard Worker    /*
1397*5e7646d2SAndroid Build Coastguard Worker     * Get the port we use for registrations.  If we are not listening on any
1398*5e7646d2SAndroid Build Coastguard Worker     * non-local ports, there is no sense sharing local printers via Bonjour...
1399*5e7646d2SAndroid Build Coastguard Worker     */
1400*5e7646d2SAndroid Build Coastguard Worker 
1401*5e7646d2SAndroid Build Coastguard Worker     cupsd_listener_t	*lis;		/* Current listening socket */
1402*5e7646d2SAndroid Build Coastguard Worker 
1403*5e7646d2SAndroid Build Coastguard Worker     for (lis = (cupsd_listener_t *)cupsArrayFirst(Listeners);
1404*5e7646d2SAndroid Build Coastguard Worker 	 lis;
1405*5e7646d2SAndroid Build Coastguard Worker 	 lis = (cupsd_listener_t *)cupsArrayNext(Listeners))
1406*5e7646d2SAndroid Build Coastguard Worker     {
1407*5e7646d2SAndroid Build Coastguard Worker       if (httpAddrLocalhost(&(lis->address)))
1408*5e7646d2SAndroid Build Coastguard Worker 	continue;
1409*5e7646d2SAndroid Build Coastguard Worker 
1410*5e7646d2SAndroid Build Coastguard Worker       DNSSDPort = httpAddrPort(&(lis->address));
1411*5e7646d2SAndroid Build Coastguard Worker       break;
1412*5e7646d2SAndroid Build Coastguard Worker     }
1413*5e7646d2SAndroid Build Coastguard Worker   }
1414*5e7646d2SAndroid Build Coastguard Worker 
1415*5e7646d2SAndroid Build Coastguard Worker   if (!DNSSDPort)
1416*5e7646d2SAndroid Build Coastguard Worker     return;
1417*5e7646d2SAndroid Build Coastguard Worker 
1418*5e7646d2SAndroid Build Coastguard Worker  /*
1419*5e7646d2SAndroid Build Coastguard Worker   * Get the computer name as a c-string...
1420*5e7646d2SAndroid Build Coastguard Worker   */
1421*5e7646d2SAndroid Build Coastguard Worker 
1422*5e7646d2SAndroid Build Coastguard Worker #  ifdef __APPLE__
1423*5e7646d2SAndroid Build Coastguard Worker   sc = SCDynamicStoreCreate(kCFAllocatorDefault, CFSTR("cupsd"), NULL, NULL);
1424*5e7646d2SAndroid Build Coastguard Worker 
1425*5e7646d2SAndroid Build Coastguard Worker   if (sc)
1426*5e7646d2SAndroid Build Coastguard Worker   {
1427*5e7646d2SAndroid Build Coastguard Worker    /*
1428*5e7646d2SAndroid Build Coastguard Worker     * Get the computer name from the dynamic store...
1429*5e7646d2SAndroid Build Coastguard Worker     */
1430*5e7646d2SAndroid Build Coastguard Worker 
1431*5e7646d2SAndroid Build Coastguard Worker     cupsdClearString(&DNSSDComputerName);
1432*5e7646d2SAndroid Build Coastguard Worker 
1433*5e7646d2SAndroid Build Coastguard Worker     if ((nameRef = SCDynamicStoreCopyComputerName(sc, &nameEncoding)) != NULL)
1434*5e7646d2SAndroid Build Coastguard Worker     {
1435*5e7646d2SAndroid Build Coastguard Worker       if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
1436*5e7646d2SAndroid Build Coastguard Worker 			     kCFStringEncodingUTF8))
1437*5e7646d2SAndroid Build Coastguard Worker       {
1438*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_DEBUG,
1439*5e7646d2SAndroid Build Coastguard Worker 	                "Dynamic store computer name is \"%s\".", nameBuffer);
1440*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetString(&DNSSDComputerName, nameBuffer);
1441*5e7646d2SAndroid Build Coastguard Worker       }
1442*5e7646d2SAndroid Build Coastguard Worker 
1443*5e7646d2SAndroid Build Coastguard Worker       CFRelease(nameRef);
1444*5e7646d2SAndroid Build Coastguard Worker     }
1445*5e7646d2SAndroid Build Coastguard Worker 
1446*5e7646d2SAndroid Build Coastguard Worker     if (!DNSSDComputerName)
1447*5e7646d2SAndroid Build Coastguard Worker     {
1448*5e7646d2SAndroid Build Coastguard Worker      /*
1449*5e7646d2SAndroid Build Coastguard Worker       * Use the ServerName instead...
1450*5e7646d2SAndroid Build Coastguard Worker       */
1451*5e7646d2SAndroid Build Coastguard Worker 
1452*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG,
1453*5e7646d2SAndroid Build Coastguard Worker                       "Using ServerName \"%s\" as computer name.", ServerName);
1454*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&DNSSDComputerName, ServerName);
1455*5e7646d2SAndroid Build Coastguard Worker     }
1456*5e7646d2SAndroid Build Coastguard Worker 
1457*5e7646d2SAndroid Build Coastguard Worker     if (!DNSSDHostName)
1458*5e7646d2SAndroid Build Coastguard Worker     {
1459*5e7646d2SAndroid Build Coastguard Worker      /*
1460*5e7646d2SAndroid Build Coastguard Worker       * Get the local hostname from the dynamic store...
1461*5e7646d2SAndroid Build Coastguard Worker       */
1462*5e7646d2SAndroid Build Coastguard Worker 
1463*5e7646d2SAndroid Build Coastguard Worker       if ((nameRef = SCDynamicStoreCopyLocalHostName(sc)) != NULL)
1464*5e7646d2SAndroid Build Coastguard Worker       {
1465*5e7646d2SAndroid Build Coastguard Worker 	if (CFStringGetCString(nameRef, nameBuffer, sizeof(nameBuffer),
1466*5e7646d2SAndroid Build Coastguard Worker 			       kCFStringEncodingUTF8))
1467*5e7646d2SAndroid Build Coastguard Worker 	{
1468*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_DEBUG, "Dynamic store host name is \"%s\".", nameBuffer);
1469*5e7646d2SAndroid Build Coastguard Worker 
1470*5e7646d2SAndroid Build Coastguard Worker 	  if (strchr(nameBuffer, '.'))
1471*5e7646d2SAndroid Build Coastguard Worker 	    cupsdSetString(&DNSSDHostName, nameBuffer);
1472*5e7646d2SAndroid Build Coastguard Worker 	  else
1473*5e7646d2SAndroid Build Coastguard Worker 	    cupsdSetStringf(&DNSSDHostName, "%s.local", nameBuffer);
1474*5e7646d2SAndroid Build Coastguard Worker 
1475*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
1476*5e7646d2SAndroid Build Coastguard Worker 	}
1477*5e7646d2SAndroid Build Coastguard Worker 
1478*5e7646d2SAndroid Build Coastguard Worker 	CFRelease(nameRef);
1479*5e7646d2SAndroid Build Coastguard Worker       }
1480*5e7646d2SAndroid Build Coastguard Worker     }
1481*5e7646d2SAndroid Build Coastguard Worker 
1482*5e7646d2SAndroid Build Coastguard Worker     if (!DNSSDHostName)
1483*5e7646d2SAndroid Build Coastguard Worker     {
1484*5e7646d2SAndroid Build Coastguard Worker      /*
1485*5e7646d2SAndroid Build Coastguard Worker       * Use the ServerName instead...
1486*5e7646d2SAndroid Build Coastguard Worker       */
1487*5e7646d2SAndroid Build Coastguard Worker 
1488*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG, "Using ServerName \"%s\" as host name.", ServerName);
1489*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&DNSSDHostName, ServerName);
1490*5e7646d2SAndroid Build Coastguard Worker 
1491*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
1492*5e7646d2SAndroid Build Coastguard Worker     }
1493*5e7646d2SAndroid Build Coastguard Worker 
1494*5e7646d2SAndroid Build Coastguard Worker    /*
1495*5e7646d2SAndroid Build Coastguard Worker     * Get any Back-to-My-Mac domains and add them as aliases...
1496*5e7646d2SAndroid Build Coastguard Worker     */
1497*5e7646d2SAndroid Build Coastguard Worker 
1498*5e7646d2SAndroid Build Coastguard Worker     cupsdFreeAliases(DNSSDAlias);
1499*5e7646d2SAndroid Build Coastguard Worker     DNSSDAlias = NULL;
1500*5e7646d2SAndroid Build Coastguard Worker 
1501*5e7646d2SAndroid Build Coastguard Worker     btmm = SCDynamicStoreCopyValue(sc, CFSTR("Setup:/Network/BackToMyMac"));
1502*5e7646d2SAndroid Build Coastguard Worker     if (btmm && CFGetTypeID(btmm) == CFDictionaryGetTypeID())
1503*5e7646d2SAndroid Build Coastguard Worker     {
1504*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG, "%d Back to My Mac aliases to add.",
1505*5e7646d2SAndroid Build Coastguard Worker 		      (int)CFDictionaryGetCount(btmm));
1506*5e7646d2SAndroid Build Coastguard Worker       CFDictionaryApplyFunction(btmm, dnssdAddAlias, NULL);
1507*5e7646d2SAndroid Build Coastguard Worker     }
1508*5e7646d2SAndroid Build Coastguard Worker     else if (btmm)
1509*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR,
1510*5e7646d2SAndroid Build Coastguard Worker 		      "Bad Back to My Mac data in dynamic store!");
1511*5e7646d2SAndroid Build Coastguard Worker     else
1512*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG, "No Back to My Mac aliases to add.");
1513*5e7646d2SAndroid Build Coastguard Worker 
1514*5e7646d2SAndroid Build Coastguard Worker     if (btmm)
1515*5e7646d2SAndroid Build Coastguard Worker       CFRelease(btmm);
1516*5e7646d2SAndroid Build Coastguard Worker 
1517*5e7646d2SAndroid Build Coastguard Worker     CFRelease(sc);
1518*5e7646d2SAndroid Build Coastguard Worker   }
1519*5e7646d2SAndroid Build Coastguard Worker   else
1520*5e7646d2SAndroid Build Coastguard Worker #  endif /* __APPLE__ */
1521*5e7646d2SAndroid Build Coastguard Worker #  ifdef HAVE_AVAHI
1522*5e7646d2SAndroid Build Coastguard Worker   if (DNSSDClient)
1523*5e7646d2SAndroid Build Coastguard Worker   {
1524*5e7646d2SAndroid Build Coastguard Worker     const char	*host_name = avahi_client_get_host_name(DNSSDClient);
1525*5e7646d2SAndroid Build Coastguard Worker 
1526*5e7646d2SAndroid Build Coastguard Worker     cupsdSetString(&DNSSDComputerName, host_name ? host_name : ServerName);
1527*5e7646d2SAndroid Build Coastguard Worker 
1528*5e7646d2SAndroid Build Coastguard Worker     if (!DNSSDHostName)
1529*5e7646d2SAndroid Build Coastguard Worker     {
1530*5e7646d2SAndroid Build Coastguard Worker       const char *host_fqdn = avahi_client_get_host_name_fqdn(DNSSDClient);
1531*5e7646d2SAndroid Build Coastguard Worker 
1532*5e7646d2SAndroid Build Coastguard Worker       if (host_fqdn)
1533*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetString(&DNSSDHostName, host_fqdn);
1534*5e7646d2SAndroid Build Coastguard Worker       else if (strchr(ServerName, '.'))
1535*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetString(&DNSSDHostName, ServerName);
1536*5e7646d2SAndroid Build Coastguard Worker       else
1537*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
1538*5e7646d2SAndroid Build Coastguard Worker 
1539*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
1540*5e7646d2SAndroid Build Coastguard Worker     }
1541*5e7646d2SAndroid Build Coastguard Worker   }
1542*5e7646d2SAndroid Build Coastguard Worker   else
1543*5e7646d2SAndroid Build Coastguard Worker #  endif /* HAVE_AVAHI */
1544*5e7646d2SAndroid Build Coastguard Worker   {
1545*5e7646d2SAndroid Build Coastguard Worker     cupsdSetString(&DNSSDComputerName, ServerName);
1546*5e7646d2SAndroid Build Coastguard Worker 
1547*5e7646d2SAndroid Build Coastguard Worker     if (!DNSSDHostName)
1548*5e7646d2SAndroid Build Coastguard Worker     {
1549*5e7646d2SAndroid Build Coastguard Worker       if (strchr(ServerName, '.'))
1550*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetString(&DNSSDHostName, ServerName);
1551*5e7646d2SAndroid Build Coastguard Worker       else
1552*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetStringf(&DNSSDHostName, "%s.local", ServerName);
1553*5e7646d2SAndroid Build Coastguard Worker 
1554*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_INFO, "Defaulting to \"DNSSDHostName %s\".", DNSSDHostName);
1555*5e7646d2SAndroid Build Coastguard Worker     }
1556*5e7646d2SAndroid Build Coastguard Worker   }
1557*5e7646d2SAndroid Build Coastguard Worker 
1558*5e7646d2SAndroid Build Coastguard Worker  /*
1559*5e7646d2SAndroid Build Coastguard Worker   * Then (re)register the web interface if enabled...
1560*5e7646d2SAndroid Build Coastguard Worker   */
1561*5e7646d2SAndroid Build Coastguard Worker 
1562*5e7646d2SAndroid Build Coastguard Worker   if (BrowseWebIF)
1563*5e7646d2SAndroid Build Coastguard Worker   {
1564*5e7646d2SAndroid Build Coastguard Worker     if (DNSSDComputerName)
1565*5e7646d2SAndroid Build Coastguard Worker       snprintf(webif, sizeof(webif), "CUPS @ %s", DNSSDComputerName);
1566*5e7646d2SAndroid Build Coastguard Worker     else
1567*5e7646d2SAndroid Build Coastguard Worker       strlcpy(webif, "CUPS", sizeof(webif));
1568*5e7646d2SAndroid Build Coastguard Worker 
1569*5e7646d2SAndroid Build Coastguard Worker     dnssdDeregisterInstance(&WebIFSrv, from_callback);
1570*5e7646d2SAndroid Build Coastguard Worker     dnssdRegisterInstance(&WebIFSrv, NULL, webif, "_http._tcp", "_printer", DNSSDPort, NULL, 1, from_callback);
1571*5e7646d2SAndroid Build Coastguard Worker   }
1572*5e7646d2SAndroid Build Coastguard Worker }
1573*5e7646d2SAndroid Build Coastguard Worker 
1574*5e7646d2SAndroid Build Coastguard Worker 
1575*5e7646d2SAndroid Build Coastguard Worker /*
1576*5e7646d2SAndroid Build Coastguard Worker  * 'get_auth_info_required()' - Get the auth-info-required value to advertise.
1577*5e7646d2SAndroid Build Coastguard Worker  */
1578*5e7646d2SAndroid Build Coastguard Worker 
1579*5e7646d2SAndroid Build Coastguard Worker static char *				/* O - String or NULL if none */
get_auth_info_required(cupsd_printer_t * p,char * buffer,size_t bufsize)1580*5e7646d2SAndroid Build Coastguard Worker get_auth_info_required(
1581*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
1582*5e7646d2SAndroid Build Coastguard Worker     char            *buffer,		/* I - Value buffer */
1583*5e7646d2SAndroid Build Coastguard Worker     size_t          bufsize)		/* I - Size of value buffer */
1584*5e7646d2SAndroid Build Coastguard Worker {
1585*5e7646d2SAndroid Build Coastguard Worker   cupsd_location_t *auth;		/* Pointer to authentication element */
1586*5e7646d2SAndroid Build Coastguard Worker   char		resource[1024];		/* Printer/class resource path */
1587*5e7646d2SAndroid Build Coastguard Worker 
1588*5e7646d2SAndroid Build Coastguard Worker 
1589*5e7646d2SAndroid Build Coastguard Worker  /*
1590*5e7646d2SAndroid Build Coastguard Worker   * If auth-info-required is set for this printer, return that...
1591*5e7646d2SAndroid Build Coastguard Worker   */
1592*5e7646d2SAndroid Build Coastguard Worker 
1593*5e7646d2SAndroid Build Coastguard Worker   if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none"))
1594*5e7646d2SAndroid Build Coastguard Worker   {
1595*5e7646d2SAndroid Build Coastguard Worker     int		i;			/* Looping var */
1596*5e7646d2SAndroid Build Coastguard Worker     char	*bufptr;		/* Pointer into buffer */
1597*5e7646d2SAndroid Build Coastguard Worker 
1598*5e7646d2SAndroid Build Coastguard Worker     for (i = 0, bufptr = buffer; i < p->num_auth_info_required; i ++)
1599*5e7646d2SAndroid Build Coastguard Worker     {
1600*5e7646d2SAndroid Build Coastguard Worker       if (bufptr >= (buffer + bufsize - 2))
1601*5e7646d2SAndroid Build Coastguard Worker 	break;
1602*5e7646d2SAndroid Build Coastguard Worker 
1603*5e7646d2SAndroid Build Coastguard Worker       if (i)
1604*5e7646d2SAndroid Build Coastguard Worker 	*bufptr++ = ',';
1605*5e7646d2SAndroid Build Coastguard Worker 
1606*5e7646d2SAndroid Build Coastguard Worker       strlcpy(bufptr, p->auth_info_required[i], bufsize - (size_t)(bufptr - buffer));
1607*5e7646d2SAndroid Build Coastguard Worker       bufptr += strlen(bufptr);
1608*5e7646d2SAndroid Build Coastguard Worker     }
1609*5e7646d2SAndroid Build Coastguard Worker 
1610*5e7646d2SAndroid Build Coastguard Worker     return (buffer);
1611*5e7646d2SAndroid Build Coastguard Worker   }
1612*5e7646d2SAndroid Build Coastguard Worker 
1613*5e7646d2SAndroid Build Coastguard Worker  /*
1614*5e7646d2SAndroid Build Coastguard Worker   * Figure out the authentication data requirements to advertise...
1615*5e7646d2SAndroid Build Coastguard Worker   */
1616*5e7646d2SAndroid Build Coastguard Worker 
1617*5e7646d2SAndroid Build Coastguard Worker   if (p->type & CUPS_PRINTER_CLASS)
1618*5e7646d2SAndroid Build Coastguard Worker     snprintf(resource, sizeof(resource), "/classes/%s", p->name);
1619*5e7646d2SAndroid Build Coastguard Worker   else
1620*5e7646d2SAndroid Build Coastguard Worker     snprintf(resource, sizeof(resource), "/printers/%s", p->name);
1621*5e7646d2SAndroid Build Coastguard Worker 
1622*5e7646d2SAndroid Build Coastguard Worker   if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL ||
1623*5e7646d2SAndroid Build Coastguard Worker       auth->type == CUPSD_AUTH_NONE)
1624*5e7646d2SAndroid Build Coastguard Worker     auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
1625*5e7646d2SAndroid Build Coastguard Worker 
1626*5e7646d2SAndroid Build Coastguard Worker   if (auth)
1627*5e7646d2SAndroid Build Coastguard Worker   {
1628*5e7646d2SAndroid Build Coastguard Worker     int	auth_type;			/* Authentication type */
1629*5e7646d2SAndroid Build Coastguard Worker 
1630*5e7646d2SAndroid Build Coastguard Worker     if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
1631*5e7646d2SAndroid Build Coastguard Worker       auth_type = cupsdDefaultAuthType();
1632*5e7646d2SAndroid Build Coastguard Worker 
1633*5e7646d2SAndroid Build Coastguard Worker     switch (auth_type)
1634*5e7646d2SAndroid Build Coastguard Worker     {
1635*5e7646d2SAndroid Build Coastguard Worker       case CUPSD_AUTH_NONE :
1636*5e7646d2SAndroid Build Coastguard Worker           return (NULL);
1637*5e7646d2SAndroid Build Coastguard Worker 
1638*5e7646d2SAndroid Build Coastguard Worker       case CUPSD_AUTH_NEGOTIATE :
1639*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(buffer, "negotiate", bufsize);
1640*5e7646d2SAndroid Build Coastguard Worker 	  break;
1641*5e7646d2SAndroid Build Coastguard Worker 
1642*5e7646d2SAndroid Build Coastguard Worker       default :
1643*5e7646d2SAndroid Build Coastguard Worker 	  strlcpy(buffer, "username,password", bufsize);
1644*5e7646d2SAndroid Build Coastguard Worker 	  break;
1645*5e7646d2SAndroid Build Coastguard Worker     }
1646*5e7646d2SAndroid Build Coastguard Worker 
1647*5e7646d2SAndroid Build Coastguard Worker     return (buffer);
1648*5e7646d2SAndroid Build Coastguard Worker   }
1649*5e7646d2SAndroid Build Coastguard Worker 
1650*5e7646d2SAndroid Build Coastguard Worker   return ("none");
1651*5e7646d2SAndroid Build Coastguard Worker }
1652*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
1653*5e7646d2SAndroid Build Coastguard Worker 
1654*5e7646d2SAndroid Build Coastguard Worker 
1655*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
1656*5e7646d2SAndroid Build Coastguard Worker /*
1657*5e7646d2SAndroid Build Coastguard Worker  * 'get_hostconfig()' - Get an /etc/hostconfig service setting.
1658*5e7646d2SAndroid Build Coastguard Worker  */
1659*5e7646d2SAndroid Build Coastguard Worker 
1660*5e7646d2SAndroid Build Coastguard Worker static int				/* O - 1 for YES or AUTOMATIC, 0 for NO */
get_hostconfig(const char * name)1661*5e7646d2SAndroid Build Coastguard Worker get_hostconfig(const char *name)	/* I - Name of service */
1662*5e7646d2SAndroid Build Coastguard Worker {
1663*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*fp;			/* Hostconfig file */
1664*5e7646d2SAndroid Build Coastguard Worker   char		line[1024],		/* Line from file */
1665*5e7646d2SAndroid Build Coastguard Worker 		*ptr;			/* Pointer to value */
1666*5e7646d2SAndroid Build Coastguard Worker   int		state = 1;		/* State of service */
1667*5e7646d2SAndroid Build Coastguard Worker 
1668*5e7646d2SAndroid Build Coastguard Worker 
1669*5e7646d2SAndroid Build Coastguard Worker  /*
1670*5e7646d2SAndroid Build Coastguard Worker   * Try opening the /etc/hostconfig file; if we can't open it, assume that
1671*5e7646d2SAndroid Build Coastguard Worker   * the service is enabled/auto.
1672*5e7646d2SAndroid Build Coastguard Worker   */
1673*5e7646d2SAndroid Build Coastguard Worker 
1674*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen("/etc/hostconfig", "r")) != NULL)
1675*5e7646d2SAndroid Build Coastguard Worker   {
1676*5e7646d2SAndroid Build Coastguard Worker    /*
1677*5e7646d2SAndroid Build Coastguard Worker     * Read lines from the file until we find the service...
1678*5e7646d2SAndroid Build Coastguard Worker     */
1679*5e7646d2SAndroid Build Coastguard Worker 
1680*5e7646d2SAndroid Build Coastguard Worker     while (cupsFileGets(fp, line, sizeof(line)))
1681*5e7646d2SAndroid Build Coastguard Worker     {
1682*5e7646d2SAndroid Build Coastguard Worker       if (line[0] == '#' || (ptr = strchr(line, '=')) == NULL)
1683*5e7646d2SAndroid Build Coastguard Worker         continue;
1684*5e7646d2SAndroid Build Coastguard Worker 
1685*5e7646d2SAndroid Build Coastguard Worker       *ptr++ = '\0';
1686*5e7646d2SAndroid Build Coastguard Worker 
1687*5e7646d2SAndroid Build Coastguard Worker       if (!_cups_strcasecmp(line, name))
1688*5e7646d2SAndroid Build Coastguard Worker       {
1689*5e7646d2SAndroid Build Coastguard Worker        /*
1690*5e7646d2SAndroid Build Coastguard Worker         * Found the service, see if it is set to "-NO-"...
1691*5e7646d2SAndroid Build Coastguard Worker 	*/
1692*5e7646d2SAndroid Build Coastguard Worker 
1693*5e7646d2SAndroid Build Coastguard Worker 	if (!_cups_strncasecmp(ptr, "-NO-", 4))
1694*5e7646d2SAndroid Build Coastguard Worker 	  state = 0;
1695*5e7646d2SAndroid Build Coastguard Worker         break;
1696*5e7646d2SAndroid Build Coastguard Worker       }
1697*5e7646d2SAndroid Build Coastguard Worker     }
1698*5e7646d2SAndroid Build Coastguard Worker 
1699*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(fp);
1700*5e7646d2SAndroid Build Coastguard Worker   }
1701*5e7646d2SAndroid Build Coastguard Worker 
1702*5e7646d2SAndroid Build Coastguard Worker   return (state);
1703*5e7646d2SAndroid Build Coastguard Worker }
1704*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
1705*5e7646d2SAndroid Build Coastguard Worker 
1706*5e7646d2SAndroid Build Coastguard Worker 
1707*5e7646d2SAndroid Build Coastguard Worker /*
1708*5e7646d2SAndroid Build Coastguard Worker  * 'update_lpd()' - Update the LPD configuration as needed.
1709*5e7646d2SAndroid Build Coastguard Worker  */
1710*5e7646d2SAndroid Build Coastguard Worker 
1711*5e7646d2SAndroid Build Coastguard Worker static void
update_lpd(int onoff)1712*5e7646d2SAndroid Build Coastguard Worker update_lpd(int onoff)			/* - 1 = turn on, 0 = turn off */
1713*5e7646d2SAndroid Build Coastguard Worker {
1714*5e7646d2SAndroid Build Coastguard Worker   if (!LPDConfigFile)
1715*5e7646d2SAndroid Build Coastguard Worker     return;
1716*5e7646d2SAndroid Build Coastguard Worker 
1717*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
1718*5e7646d2SAndroid Build Coastguard Worker  /*
1719*5e7646d2SAndroid Build Coastguard Worker   * Allow /etc/hostconfig CUPS_LPD service setting to override cupsd.conf
1720*5e7646d2SAndroid Build Coastguard Worker   * setting for backwards-compatibility.
1721*5e7646d2SAndroid Build Coastguard Worker   */
1722*5e7646d2SAndroid Build Coastguard Worker 
1723*5e7646d2SAndroid Build Coastguard Worker   if (onoff && !get_hostconfig("CUPS_LPD"))
1724*5e7646d2SAndroid Build Coastguard Worker     onoff = 0;
1725*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
1726*5e7646d2SAndroid Build Coastguard Worker 
1727*5e7646d2SAndroid Build Coastguard Worker   if (!strncmp(LPDConfigFile, "xinetd:///", 10))
1728*5e7646d2SAndroid Build Coastguard Worker   {
1729*5e7646d2SAndroid Build Coastguard Worker    /*
1730*5e7646d2SAndroid Build Coastguard Worker     * Enable/disable LPD via the xinetd.d config file for cups-lpd...
1731*5e7646d2SAndroid Build Coastguard Worker     */
1732*5e7646d2SAndroid Build Coastguard Worker 
1733*5e7646d2SAndroid Build Coastguard Worker     char	newfile[1024];		/* New cups-lpd.N file */
1734*5e7646d2SAndroid Build Coastguard Worker     cups_file_t	*ofp,			/* Original file pointer */
1735*5e7646d2SAndroid Build Coastguard Worker 		*nfp;			/* New file pointer */
1736*5e7646d2SAndroid Build Coastguard Worker     char	line[1024];		/* Line from file */
1737*5e7646d2SAndroid Build Coastguard Worker 
1738*5e7646d2SAndroid Build Coastguard Worker 
1739*5e7646d2SAndroid Build Coastguard Worker     snprintf(newfile, sizeof(newfile), "%s.N", LPDConfigFile + 9);
1740*5e7646d2SAndroid Build Coastguard Worker 
1741*5e7646d2SAndroid Build Coastguard Worker     if ((ofp = cupsFileOpen(LPDConfigFile + 9, "r")) == NULL)
1742*5e7646d2SAndroid Build Coastguard Worker     {
1743*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s",
1744*5e7646d2SAndroid Build Coastguard Worker                       LPDConfigFile + 9, strerror(errno));
1745*5e7646d2SAndroid Build Coastguard Worker       return;
1746*5e7646d2SAndroid Build Coastguard Worker     }
1747*5e7646d2SAndroid Build Coastguard Worker 
1748*5e7646d2SAndroid Build Coastguard Worker     if ((nfp = cupsFileOpen(newfile, "w")) == NULL)
1749*5e7646d2SAndroid Build Coastguard Worker     {
1750*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s",
1751*5e7646d2SAndroid Build Coastguard Worker                       newfile, strerror(errno));
1752*5e7646d2SAndroid Build Coastguard Worker       cupsFileClose(ofp);
1753*5e7646d2SAndroid Build Coastguard Worker       return;
1754*5e7646d2SAndroid Build Coastguard Worker     }
1755*5e7646d2SAndroid Build Coastguard Worker 
1756*5e7646d2SAndroid Build Coastguard Worker    /*
1757*5e7646d2SAndroid Build Coastguard Worker     * Copy all of the lines from the cups-lpd file...
1758*5e7646d2SAndroid Build Coastguard Worker     */
1759*5e7646d2SAndroid Build Coastguard Worker 
1760*5e7646d2SAndroid Build Coastguard Worker     while (cupsFileGets(ofp, line, sizeof(line)))
1761*5e7646d2SAndroid Build Coastguard Worker     {
1762*5e7646d2SAndroid Build Coastguard Worker       if (line[0] == '{')
1763*5e7646d2SAndroid Build Coastguard Worker       {
1764*5e7646d2SAndroid Build Coastguard Worker         cupsFilePrintf(nfp, "%s\n", line);
1765*5e7646d2SAndroid Build Coastguard Worker         snprintf(line, sizeof(line), "\tdisable = %s",
1766*5e7646d2SAndroid Build Coastguard Worker 	         onoff ? "no" : "yes");
1767*5e7646d2SAndroid Build Coastguard Worker       }
1768*5e7646d2SAndroid Build Coastguard Worker       else if (!strstr(line, "disable ="))
1769*5e7646d2SAndroid Build Coastguard Worker         cupsFilePrintf(nfp, "%s\n", line);
1770*5e7646d2SAndroid Build Coastguard Worker     }
1771*5e7646d2SAndroid Build Coastguard Worker 
1772*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(nfp);
1773*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(ofp);
1774*5e7646d2SAndroid Build Coastguard Worker     rename(newfile, LPDConfigFile + 9);
1775*5e7646d2SAndroid Build Coastguard Worker   }
1776*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
1777*5e7646d2SAndroid Build Coastguard Worker   else if (!strncmp(LPDConfigFile, "launchd:///", 11))
1778*5e7646d2SAndroid Build Coastguard Worker   {
1779*5e7646d2SAndroid Build Coastguard Worker    /*
1780*5e7646d2SAndroid Build Coastguard Worker     * Enable/disable LPD via the launchctl command...
1781*5e7646d2SAndroid Build Coastguard Worker     */
1782*5e7646d2SAndroid Build Coastguard Worker 
1783*5e7646d2SAndroid Build Coastguard Worker     char	*argv[5],		/* Arguments for command */
1784*5e7646d2SAndroid Build Coastguard Worker 		*envp[MAX_ENV];		/* Environment for command */
1785*5e7646d2SAndroid Build Coastguard Worker     int		pid;			/* Process ID */
1786*5e7646d2SAndroid Build Coastguard Worker 
1787*5e7646d2SAndroid Build Coastguard Worker 
1788*5e7646d2SAndroid Build Coastguard Worker     cupsdLoadEnv(envp, (int)(sizeof(envp) / sizeof(envp[0])));
1789*5e7646d2SAndroid Build Coastguard Worker     argv[0] = (char *)"launchctl";
1790*5e7646d2SAndroid Build Coastguard Worker     argv[1] = (char *)(onoff ? "load" : "unload");
1791*5e7646d2SAndroid Build Coastguard Worker     argv[2] = (char *)"-w";
1792*5e7646d2SAndroid Build Coastguard Worker     argv[3] = LPDConfigFile + 10;
1793*5e7646d2SAndroid Build Coastguard Worker     argv[4] = NULL;
1794*5e7646d2SAndroid Build Coastguard Worker 
1795*5e7646d2SAndroid Build Coastguard Worker     cupsdStartProcess("/bin/launchctl", argv, envp, -1, -1, -1, -1, -1, 1,
1796*5e7646d2SAndroid Build Coastguard Worker                       NULL, NULL, &pid);
1797*5e7646d2SAndroid Build Coastguard Worker   }
1798*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
1799*5e7646d2SAndroid Build Coastguard Worker   else
1800*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_INFO, "Unknown LPDConfigFile scheme!");
1801*5e7646d2SAndroid Build Coastguard Worker }
1802*5e7646d2SAndroid Build Coastguard Worker 
1803*5e7646d2SAndroid Build Coastguard Worker 
1804*5e7646d2SAndroid Build Coastguard Worker /*
1805*5e7646d2SAndroid Build Coastguard Worker  * 'update_smb()' - Update the SMB configuration as needed.
1806*5e7646d2SAndroid Build Coastguard Worker  */
1807*5e7646d2SAndroid Build Coastguard Worker 
1808*5e7646d2SAndroid Build Coastguard Worker static void
update_smb(int onoff)1809*5e7646d2SAndroid Build Coastguard Worker update_smb(int onoff)			/* I - 1 = turn on, 0 = turn off */
1810*5e7646d2SAndroid Build Coastguard Worker {
1811*5e7646d2SAndroid Build Coastguard Worker   if (!SMBConfigFile)
1812*5e7646d2SAndroid Build Coastguard Worker     return;
1813*5e7646d2SAndroid Build Coastguard Worker 
1814*5e7646d2SAndroid Build Coastguard Worker   if (!strncmp(SMBConfigFile, "samba:///", 9))
1815*5e7646d2SAndroid Build Coastguard Worker   {
1816*5e7646d2SAndroid Build Coastguard Worker    /*
1817*5e7646d2SAndroid Build Coastguard Worker     * Enable/disable SMB via the specified smb.conf config file...
1818*5e7646d2SAndroid Build Coastguard Worker     */
1819*5e7646d2SAndroid Build Coastguard Worker 
1820*5e7646d2SAndroid Build Coastguard Worker     char	newfile[1024];		/* New smb.conf.N file */
1821*5e7646d2SAndroid Build Coastguard Worker     cups_file_t	*ofp,			/* Original file pointer */
1822*5e7646d2SAndroid Build Coastguard Worker 		*nfp;			/* New file pointer */
1823*5e7646d2SAndroid Build Coastguard Worker     char	line[1024];		/* Line from file */
1824*5e7646d2SAndroid Build Coastguard Worker     int		in_printers;		/* In [printers] section? */
1825*5e7646d2SAndroid Build Coastguard Worker 
1826*5e7646d2SAndroid Build Coastguard Worker 
1827*5e7646d2SAndroid Build Coastguard Worker     snprintf(newfile, sizeof(newfile), "%s.N", SMBConfigFile + 8);
1828*5e7646d2SAndroid Build Coastguard Worker 
1829*5e7646d2SAndroid Build Coastguard Worker     if ((ofp = cupsFileOpen(SMBConfigFile + 8, "r")) == NULL)
1830*5e7646d2SAndroid Build Coastguard Worker     {
1831*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open \"%s\" - %s",
1832*5e7646d2SAndroid Build Coastguard Worker                       SMBConfigFile + 8, strerror(errno));
1833*5e7646d2SAndroid Build Coastguard Worker       return;
1834*5e7646d2SAndroid Build Coastguard Worker     }
1835*5e7646d2SAndroid Build Coastguard Worker 
1836*5e7646d2SAndroid Build Coastguard Worker     if ((nfp = cupsFileOpen(newfile, "w")) == NULL)
1837*5e7646d2SAndroid Build Coastguard Worker     {
1838*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create \"%s\" - %s",
1839*5e7646d2SAndroid Build Coastguard Worker                       newfile, strerror(errno));
1840*5e7646d2SAndroid Build Coastguard Worker       cupsFileClose(ofp);
1841*5e7646d2SAndroid Build Coastguard Worker       return;
1842*5e7646d2SAndroid Build Coastguard Worker     }
1843*5e7646d2SAndroid Build Coastguard Worker 
1844*5e7646d2SAndroid Build Coastguard Worker    /*
1845*5e7646d2SAndroid Build Coastguard Worker     * Copy all of the lines from the smb.conf file...
1846*5e7646d2SAndroid Build Coastguard Worker     */
1847*5e7646d2SAndroid Build Coastguard Worker 
1848*5e7646d2SAndroid Build Coastguard Worker     in_printers = 0;
1849*5e7646d2SAndroid Build Coastguard Worker 
1850*5e7646d2SAndroid Build Coastguard Worker     while (cupsFileGets(ofp, line, sizeof(line)))
1851*5e7646d2SAndroid Build Coastguard Worker     {
1852*5e7646d2SAndroid Build Coastguard Worker       if (in_printers && strstr(line, "printable ="))
1853*5e7646d2SAndroid Build Coastguard Worker         snprintf(line, sizeof(line), "    printable = %s",
1854*5e7646d2SAndroid Build Coastguard Worker 	         onoff ? "yes" : "no");
1855*5e7646d2SAndroid Build Coastguard Worker 
1856*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(nfp, "%s\n", line);
1857*5e7646d2SAndroid Build Coastguard Worker 
1858*5e7646d2SAndroid Build Coastguard Worker       if (line[0] == '[')
1859*5e7646d2SAndroid Build Coastguard Worker         in_printers = !strcmp(line, "[printers]");
1860*5e7646d2SAndroid Build Coastguard Worker     }
1861*5e7646d2SAndroid Build Coastguard Worker 
1862*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(nfp);
1863*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(ofp);
1864*5e7646d2SAndroid Build Coastguard Worker     rename(newfile, SMBConfigFile + 8);
1865*5e7646d2SAndroid Build Coastguard Worker   }
1866*5e7646d2SAndroid Build Coastguard Worker   else
1867*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_INFO, "Unknown SMBConfigFile scheme!");
1868*5e7646d2SAndroid Build Coastguard Worker }
1869