xref: /aosp_15_r20/external/libcups/scheduler/printers.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Printer routines for the CUPS scheduler.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2007-2020 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 <cups/dir.h>
17*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_APPLICATIONSERVICES_H
18*5e7646d2SAndroid Build Coastguard Worker #  include <ApplicationServices/ApplicationServices.h>
19*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_APPLICATIONSERVICES_H */
20*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SYS_MOUNT_H
21*5e7646d2SAndroid Build Coastguard Worker #  include <sys/mount.h>
22*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SYS_MOUNT_H */
23*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SYS_STATVFS_H
24*5e7646d2SAndroid Build Coastguard Worker #  include <sys/statvfs.h>
25*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_SYS_STATFS_H)
26*5e7646d2SAndroid Build Coastguard Worker #  include <sys/statfs.h>
27*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SYS_STATVFS_H */
28*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SYS_VFS_H
29*5e7646d2SAndroid Build Coastguard Worker #  include <sys/vfs.h>
30*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SYS_VFS_H */
31*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
32*5e7646d2SAndroid Build Coastguard Worker #  include <asl.h>
33*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
34*5e7646d2SAndroid Build Coastguard Worker 
35*5e7646d2SAndroid Build Coastguard Worker 
36*5e7646d2SAndroid Build Coastguard Worker /*
37*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
38*5e7646d2SAndroid Build Coastguard Worker  */
39*5e7646d2SAndroid Build Coastguard Worker 
40*5e7646d2SAndroid Build Coastguard Worker static void	add_printer_defaults(cupsd_printer_t *p);
41*5e7646d2SAndroid Build Coastguard Worker static void	add_printer_filter(cupsd_printer_t *p, mime_type_t *type,
42*5e7646d2SAndroid Build Coastguard Worker 				   const char *filter);
43*5e7646d2SAndroid Build Coastguard Worker static void	add_printer_formats(cupsd_printer_t *p);
44*5e7646d2SAndroid Build Coastguard Worker static int	compare_printers(void *first, void *second, void *data);
45*5e7646d2SAndroid Build Coastguard Worker static void	delete_printer_filters(cupsd_printer_t *p);
46*5e7646d2SAndroid Build Coastguard Worker static void	dirty_printer(cupsd_printer_t *p);
47*5e7646d2SAndroid Build Coastguard Worker static void	load_ppd(cupsd_printer_t *p);
48*5e7646d2SAndroid Build Coastguard Worker static ipp_t	*new_media_col(pwg_size_t *size);
49*5e7646d2SAndroid Build Coastguard Worker static void	write_xml_string(cups_file_t *fp, const char *s);
50*5e7646d2SAndroid Build Coastguard Worker 
51*5e7646d2SAndroid Build Coastguard Worker 
52*5e7646d2SAndroid Build Coastguard Worker /*
53*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdAddPrinter()' - Add a printer to the system.
54*5e7646d2SAndroid Build Coastguard Worker  */
55*5e7646d2SAndroid Build Coastguard Worker 
56*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *			/* O - New printer */
cupsdAddPrinter(const char * name)57*5e7646d2SAndroid Build Coastguard Worker cupsdAddPrinter(const char *name)	/* I - Name of printer */
58*5e7646d2SAndroid Build Coastguard Worker {
59*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* New printer */
60*5e7646d2SAndroid Build Coastguard Worker   char			uri[1024],	/* Printer URI */
61*5e7646d2SAndroid Build Coastguard Worker 			uuid[64];	/* Printer UUID */
62*5e7646d2SAndroid Build Coastguard Worker 
63*5e7646d2SAndroid Build Coastguard Worker 
64*5e7646d2SAndroid Build Coastguard Worker  /*
65*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
66*5e7646d2SAndroid Build Coastguard Worker   */
67*5e7646d2SAndroid Build Coastguard Worker 
68*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdAddPrinter(\"%s\")", name);
69*5e7646d2SAndroid Build Coastguard Worker 
70*5e7646d2SAndroid Build Coastguard Worker  /*
71*5e7646d2SAndroid Build Coastguard Worker   * Create a new printer entity...
72*5e7646d2SAndroid Build Coastguard Worker   */
73*5e7646d2SAndroid Build Coastguard Worker 
74*5e7646d2SAndroid Build Coastguard Worker   if ((p = calloc(1, sizeof(cupsd_printer_t))) == NULL)
75*5e7646d2SAndroid Build Coastguard Worker   {
76*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_CRIT, "Unable to allocate memory for printer - %s",
77*5e7646d2SAndroid Build Coastguard Worker                     strerror(errno));
78*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
79*5e7646d2SAndroid Build Coastguard Worker   }
80*5e7646d2SAndroid Build Coastguard Worker 
81*5e7646d2SAndroid Build Coastguard Worker   _cupsRWInit(&p->lock);
82*5e7646d2SAndroid Build Coastguard Worker 
83*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->name, name);
84*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->info, name);
85*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->hostname, ServerName);
86*5e7646d2SAndroid Build Coastguard Worker 
87*5e7646d2SAndroid Build Coastguard Worker   httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
88*5e7646d2SAndroid Build Coastguard Worker 		   ServerName, RemotePort, "/printers/%s", name);
89*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->uri, uri);
90*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->uuid, httpAssembleUUID(ServerName, RemotePort, name, 0,
91*5e7646d2SAndroid Build Coastguard Worker                                             uuid, sizeof(uuid)));
92*5e7646d2SAndroid Build Coastguard Worker   cupsdSetDeviceURI(p, "file:///dev/null");
93*5e7646d2SAndroid Build Coastguard Worker 
94*5e7646d2SAndroid Build Coastguard Worker   p->config_time = time(NULL);
95*5e7646d2SAndroid Build Coastguard Worker   p->state       = IPP_PRINTER_STOPPED;
96*5e7646d2SAndroid Build Coastguard Worker   p->state_time  = time(NULL);
97*5e7646d2SAndroid Build Coastguard Worker   p->accepting   = 0;
98*5e7646d2SAndroid Build Coastguard Worker   p->shared      = DefaultShared;
99*5e7646d2SAndroid Build Coastguard Worker   p->filetype    = mimeAddType(MimeDatabase, "printer", name);
100*5e7646d2SAndroid Build Coastguard Worker 
101*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->job_sheets[0], "none");
102*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->job_sheets[1], "none");
103*5e7646d2SAndroid Build Coastguard Worker 
104*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->error_policy, ErrorPolicy);
105*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->op_policy, DefaultPolicy);
106*5e7646d2SAndroid Build Coastguard Worker 
107*5e7646d2SAndroid Build Coastguard Worker   p->op_policy_ptr = DefaultPolicyPtr;
108*5e7646d2SAndroid Build Coastguard Worker 
109*5e7646d2SAndroid Build Coastguard Worker  /*
110*5e7646d2SAndroid Build Coastguard Worker   * Insert the printer in the printer list alphabetically...
111*5e7646d2SAndroid Build Coastguard Worker   */
112*5e7646d2SAndroid Build Coastguard Worker 
113*5e7646d2SAndroid Build Coastguard Worker   if (!Printers)
114*5e7646d2SAndroid Build Coastguard Worker     Printers = cupsArrayNew(compare_printers, NULL);
115*5e7646d2SAndroid Build Coastguard Worker 
116*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
117*5e7646d2SAndroid Build Coastguard Worker                   "cupsdAddPrinter: Adding %s to Printers", p->name);
118*5e7646d2SAndroid Build Coastguard Worker   cupsArrayAdd(Printers, p);
119*5e7646d2SAndroid Build Coastguard Worker 
120*5e7646d2SAndroid Build Coastguard Worker  /*
121*5e7646d2SAndroid Build Coastguard Worker   * Return the new printer...
122*5e7646d2SAndroid Build Coastguard Worker   */
123*5e7646d2SAndroid Build Coastguard Worker 
124*5e7646d2SAndroid Build Coastguard Worker   return (p);
125*5e7646d2SAndroid Build Coastguard Worker }
126*5e7646d2SAndroid Build Coastguard Worker 
127*5e7646d2SAndroid Build Coastguard Worker 
128*5e7646d2SAndroid Build Coastguard Worker /*
129*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdCreateCommonData()' - Create the common printer data.
130*5e7646d2SAndroid Build Coastguard Worker  */
131*5e7646d2SAndroid Build Coastguard Worker 
132*5e7646d2SAndroid Build Coastguard Worker void
cupsdCreateCommonData(void)133*5e7646d2SAndroid Build Coastguard Worker cupsdCreateCommonData(void)
134*5e7646d2SAndroid Build Coastguard Worker {
135*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
136*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*attr;		/* Attribute data */
137*5e7646d2SAndroid Build Coastguard Worker   cups_dir_t		*dir;		/* Notifier directory */
138*5e7646d2SAndroid Build Coastguard Worker   cups_dentry_t		*dent;		/* Notifier directory entry */
139*5e7646d2SAndroid Build Coastguard Worker   cups_array_t		*notifiers;	/* Notifier array */
140*5e7646d2SAndroid Build Coastguard Worker   char			filename[1024],	/* Filename */
141*5e7646d2SAndroid Build Coastguard Worker 			*notifier;	/* Current notifier */
142*5e7646d2SAndroid Build Coastguard Worker   cupsd_policy_t	*p;		/* Current policy */
143*5e7646d2SAndroid Build Coastguard Worker   int			k_supported;	/* Maximum file size supported */
144*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_STATVFS
145*5e7646d2SAndroid Build Coastguard Worker   struct statvfs	spoolinfo;	/* FS info for spool directory */
146*5e7646d2SAndroid Build Coastguard Worker   double		spoolsize;	/* FS size */
147*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_STATFS)
148*5e7646d2SAndroid Build Coastguard Worker   struct statfs		spoolinfo;	/* FS info for spool directory */
149*5e7646d2SAndroid Build Coastguard Worker   double		spoolsize;	/* FS size */
150*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_STATVFS */
151*5e7646d2SAndroid Build Coastguard Worker   static const char * const page_delivery[] =
152*5e7646d2SAndroid Build Coastguard Worker 		{			/* page-delivery-supported values */
153*5e7646d2SAndroid Build Coastguard Worker 		  "reverse-order",
154*5e7646d2SAndroid Build Coastguard Worker 		  "same-order"
155*5e7646d2SAndroid Build Coastguard Worker 		};
156*5e7646d2SAndroid Build Coastguard Worker   static const char * const print_scaling[] =
157*5e7646d2SAndroid Build Coastguard Worker 		{			/* print-scaling-supported values */
158*5e7646d2SAndroid Build Coastguard Worker 		  "auto",
159*5e7646d2SAndroid Build Coastguard Worker 		  "auto-fit",
160*5e7646d2SAndroid Build Coastguard Worker 		  "fill",
161*5e7646d2SAndroid Build Coastguard Worker 		  "fit",
162*5e7646d2SAndroid Build Coastguard Worker 		  "none"
163*5e7646d2SAndroid Build Coastguard Worker 		};
164*5e7646d2SAndroid Build Coastguard Worker   static const int number_up[] =		/* number-up-supported values */
165*5e7646d2SAndroid Build Coastguard Worker 		{ 1, 2, 4, 6, 9, 16 };
166*5e7646d2SAndroid Build Coastguard Worker   static const char * const number_up_layout[] =
167*5e7646d2SAndroid Build Coastguard Worker 		{			/* number-up-layout-supported values */
168*5e7646d2SAndroid Build Coastguard Worker 		  "btlr",
169*5e7646d2SAndroid Build Coastguard Worker 		  "btrl",
170*5e7646d2SAndroid Build Coastguard Worker 		  "lrbt",
171*5e7646d2SAndroid Build Coastguard Worker 		  "lrtb",
172*5e7646d2SAndroid Build Coastguard Worker 		  "rlbt",
173*5e7646d2SAndroid Build Coastguard Worker 		  "rltb",
174*5e7646d2SAndroid Build Coastguard Worker 		  "tblr",
175*5e7646d2SAndroid Build Coastguard Worker 		  "tbrl"
176*5e7646d2SAndroid Build Coastguard Worker 		};
177*5e7646d2SAndroid Build Coastguard Worker   static const int orients[4] =/* orientation-requested-supported values */
178*5e7646d2SAndroid Build Coastguard Worker 		{
179*5e7646d2SAndroid Build Coastguard Worker 		  IPP_PORTRAIT,
180*5e7646d2SAndroid Build Coastguard Worker 		  IPP_LANDSCAPE,
181*5e7646d2SAndroid Build Coastguard Worker 		  IPP_REVERSE_LANDSCAPE,
182*5e7646d2SAndroid Build Coastguard Worker 		  IPP_REVERSE_PORTRAIT
183*5e7646d2SAndroid Build Coastguard Worker 		};
184*5e7646d2SAndroid Build Coastguard Worker   static const char * const holds[] =	/* job-hold-until-supported values */
185*5e7646d2SAndroid Build Coastguard Worker 		{
186*5e7646d2SAndroid Build Coastguard Worker 		  "no-hold",
187*5e7646d2SAndroid Build Coastguard Worker 		  "indefinite",
188*5e7646d2SAndroid Build Coastguard Worker 		  "day-time",
189*5e7646d2SAndroid Build Coastguard Worker 		  "evening",
190*5e7646d2SAndroid Build Coastguard Worker 		  "night",
191*5e7646d2SAndroid Build Coastguard Worker 		  "second-shift",
192*5e7646d2SAndroid Build Coastguard Worker 		  "third-shift",
193*5e7646d2SAndroid Build Coastguard Worker 		  "weekend"
194*5e7646d2SAndroid Build Coastguard Worker 		};
195*5e7646d2SAndroid Build Coastguard Worker   static const char * const features[] =/* ipp-features-supported values */
196*5e7646d2SAndroid Build Coastguard Worker 		{
197*5e7646d2SAndroid Build Coastguard Worker 		  "subscription-object"
198*5e7646d2SAndroid Build Coastguard Worker 		};
199*5e7646d2SAndroid Build Coastguard Worker   static const char * const versions[] =/* ipp-versions-supported values */
200*5e7646d2SAndroid Build Coastguard Worker 		{
201*5e7646d2SAndroid Build Coastguard Worker 		  "1.0",
202*5e7646d2SAndroid Build Coastguard Worker 		  "1.1",
203*5e7646d2SAndroid Build Coastguard Worker 		  "2.0",
204*5e7646d2SAndroid Build Coastguard Worker 		  "2.1"
205*5e7646d2SAndroid Build Coastguard Worker 		};
206*5e7646d2SAndroid Build Coastguard Worker   static const int	ops[] =		/* operations-supported values */
207*5e7646d2SAndroid Build Coastguard Worker 		{
208*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_PRINT_JOB,
209*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_VALIDATE_JOB,
210*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CREATE_JOB,
211*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_SEND_DOCUMENT,
212*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CANCEL_JOB,
213*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_GET_JOB_ATTRIBUTES,
214*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_GET_JOBS,
215*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_GET_PRINTER_ATTRIBUTES,
216*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_HOLD_JOB,
217*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_RELEASE_JOB,
218*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_PAUSE_PRINTER,
219*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_RESUME_PRINTER,
220*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_PURGE_JOBS,
221*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_SET_PRINTER_ATTRIBUTES,
222*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_SET_JOB_ATTRIBUTES,
223*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_GET_PRINTER_SUPPORTED_VALUES,
224*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CREATE_PRINTER_SUBSCRIPTIONS,
225*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CREATE_JOB_SUBSCRIPTIONS,
226*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_GET_SUBSCRIPTION_ATTRIBUTES,
227*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_GET_SUBSCRIPTIONS,
228*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_RENEW_SUBSCRIPTION,
229*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CANCEL_SUBSCRIPTION,
230*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_GET_NOTIFICATIONS,
231*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_ENABLE_PRINTER,
232*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_DISABLE_PRINTER,
233*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_HOLD_NEW_JOBS,
234*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_RELEASE_HELD_NEW_JOBS,
235*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CANCEL_JOBS,
236*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CANCEL_MY_JOBS,
237*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CLOSE_JOB,
238*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_GET_DEFAULT,
239*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_GET_PRINTERS,
240*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_ADD_MODIFY_PRINTER,
241*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_DELETE_PRINTER,
242*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_GET_CLASSES,
243*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_ADD_MODIFY_CLASS,
244*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_DELETE_CLASS,
245*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_ACCEPT_JOBS,
246*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_REJECT_JOBS,
247*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_SET_DEFAULT,
248*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_GET_DEVICES,
249*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_GET_PPDS,
250*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_MOVE_JOB,
251*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_AUTHENTICATE_JOB,
252*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_GET_PPD,
253*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_CUPS_GET_DOCUMENT,
254*5e7646d2SAndroid Build Coastguard Worker 		  IPP_OP_RESTART_JOB
255*5e7646d2SAndroid Build Coastguard Worker 		};
256*5e7646d2SAndroid Build Coastguard Worker   static const char * const charsets[] =/* charset-supported values */
257*5e7646d2SAndroid Build Coastguard Worker 		{
258*5e7646d2SAndroid Build Coastguard Worker 		  "us-ascii",
259*5e7646d2SAndroid Build Coastguard Worker 		  "utf-8"
260*5e7646d2SAndroid Build Coastguard Worker 		};
261*5e7646d2SAndroid Build Coastguard Worker   static const char * const compressions[] =
262*5e7646d2SAndroid Build Coastguard Worker 		{			/* document-compression-supported values */
263*5e7646d2SAndroid Build Coastguard Worker 		  "none"
264*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_LIBZ
265*5e7646d2SAndroid Build Coastguard Worker 		  ,"gzip"
266*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_LIBZ */
267*5e7646d2SAndroid Build Coastguard Worker 		};
268*5e7646d2SAndroid Build Coastguard Worker   static const char * const media_col_supported[] =
269*5e7646d2SAndroid Build Coastguard Worker 		{			/* media-col-supported values */
270*5e7646d2SAndroid Build Coastguard Worker 		  "media-bottom-margin",
271*5e7646d2SAndroid Build Coastguard Worker 		  "media-left-margin",
272*5e7646d2SAndroid Build Coastguard Worker 		  "media-right-margin",
273*5e7646d2SAndroid Build Coastguard Worker 		  "media-size",
274*5e7646d2SAndroid Build Coastguard Worker 		  "media-source",
275*5e7646d2SAndroid Build Coastguard Worker 		  "media-top-margin",
276*5e7646d2SAndroid Build Coastguard Worker 		  "media-type"
277*5e7646d2SAndroid Build Coastguard Worker 		};
278*5e7646d2SAndroid Build Coastguard Worker   static const char * const multiple_document_handling[] =
279*5e7646d2SAndroid Build Coastguard Worker 		{			/* multiple-document-handling-supported values */
280*5e7646d2SAndroid Build Coastguard Worker 		  "separate-documents-uncollated-copies",
281*5e7646d2SAndroid Build Coastguard Worker 		  "separate-documents-collated-copies"
282*5e7646d2SAndroid Build Coastguard Worker 		};
283*5e7646d2SAndroid Build Coastguard Worker   static const char * const notify_attrs[] =
284*5e7646d2SAndroid Build Coastguard Worker 		{			/* notify-attributes-supported values */
285*5e7646d2SAndroid Build Coastguard Worker 		  "printer-state-change-time",
286*5e7646d2SAndroid Build Coastguard Worker 		  "notify-lease-expiration-time",
287*5e7646d2SAndroid Build Coastguard Worker 		  "notify-subscriber-user-name"
288*5e7646d2SAndroid Build Coastguard Worker 		};
289*5e7646d2SAndroid Build Coastguard Worker   static const char * const notify_events[] =
290*5e7646d2SAndroid Build Coastguard Worker 		{			/* notify-events-supported values */
291*5e7646d2SAndroid Build Coastguard Worker         	  "job-completed",
292*5e7646d2SAndroid Build Coastguard Worker         	  "job-config-changed",
293*5e7646d2SAndroid Build Coastguard Worker         	  "job-created",
294*5e7646d2SAndroid Build Coastguard Worker         	  "job-progress",
295*5e7646d2SAndroid Build Coastguard Worker         	  "job-state-changed",
296*5e7646d2SAndroid Build Coastguard Worker         	  "job-stopped",
297*5e7646d2SAndroid Build Coastguard Worker         	  "printer-added",
298*5e7646d2SAndroid Build Coastguard Worker         	  "printer-changed",
299*5e7646d2SAndroid Build Coastguard Worker         	  "printer-config-changed",
300*5e7646d2SAndroid Build Coastguard Worker         	  "printer-deleted",
301*5e7646d2SAndroid Build Coastguard Worker         	  "printer-finishings-changed",
302*5e7646d2SAndroid Build Coastguard Worker         	  "printer-media-changed",
303*5e7646d2SAndroid Build Coastguard Worker         	  "printer-modified",
304*5e7646d2SAndroid Build Coastguard Worker         	  "printer-restarted",
305*5e7646d2SAndroid Build Coastguard Worker         	  "printer-shutdown",
306*5e7646d2SAndroid Build Coastguard Worker         	  "printer-state-changed",
307*5e7646d2SAndroid Build Coastguard Worker         	  "printer-stopped",
308*5e7646d2SAndroid Build Coastguard Worker         	  "server-audit",
309*5e7646d2SAndroid Build Coastguard Worker         	  "server-restarted",
310*5e7646d2SAndroid Build Coastguard Worker         	  "server-started",
311*5e7646d2SAndroid Build Coastguard Worker         	  "server-stopped"
312*5e7646d2SAndroid Build Coastguard Worker 		};
313*5e7646d2SAndroid Build Coastguard Worker   static const char * const job_creation[] =
314*5e7646d2SAndroid Build Coastguard Worker 		{			/* job-creation-attributes-supported */
315*5e7646d2SAndroid Build Coastguard Worker 		  "copies",
316*5e7646d2SAndroid Build Coastguard Worker 		  "finishings",
317*5e7646d2SAndroid Build Coastguard Worker 		  "finishings-col",
318*5e7646d2SAndroid Build Coastguard Worker 		  "ipp-attribute-fidelity",
319*5e7646d2SAndroid Build Coastguard Worker 		  "job-hold-until",
320*5e7646d2SAndroid Build Coastguard Worker 		  "job-name",
321*5e7646d2SAndroid Build Coastguard Worker 		  "job-priority",
322*5e7646d2SAndroid Build Coastguard Worker 		  "job-sheets",
323*5e7646d2SAndroid Build Coastguard Worker 		  "media",
324*5e7646d2SAndroid Build Coastguard Worker 		  "media-col",
325*5e7646d2SAndroid Build Coastguard Worker 		  "multiple-document-handling",
326*5e7646d2SAndroid Build Coastguard Worker 		  "number-up",
327*5e7646d2SAndroid Build Coastguard Worker 		  "number-up-layout",
328*5e7646d2SAndroid Build Coastguard Worker 		  "orientation-requested",
329*5e7646d2SAndroid Build Coastguard Worker 		  "output-bin",
330*5e7646d2SAndroid Build Coastguard Worker 		  "page-delivery",
331*5e7646d2SAndroid Build Coastguard Worker 		  "page-ranges",
332*5e7646d2SAndroid Build Coastguard Worker 		  "print-color-mode",
333*5e7646d2SAndroid Build Coastguard Worker 		  "print-quality",
334*5e7646d2SAndroid Build Coastguard Worker 		  "print-scaling",
335*5e7646d2SAndroid Build Coastguard Worker 		  "printer-resolution",
336*5e7646d2SAndroid Build Coastguard Worker 		  "sides"
337*5e7646d2SAndroid Build Coastguard Worker 		};
338*5e7646d2SAndroid Build Coastguard Worker   static const char * const job_settable[] =
339*5e7646d2SAndroid Build Coastguard Worker 		{			/* job-settable-attributes-supported */
340*5e7646d2SAndroid Build Coastguard Worker 		  "copies",
341*5e7646d2SAndroid Build Coastguard Worker 		  "finishings",
342*5e7646d2SAndroid Build Coastguard Worker 		  "job-hold-until",
343*5e7646d2SAndroid Build Coastguard Worker 		  "job-name",
344*5e7646d2SAndroid Build Coastguard Worker 		  "job-priority",
345*5e7646d2SAndroid Build Coastguard Worker 		  "media",
346*5e7646d2SAndroid Build Coastguard Worker 		  "media-col",
347*5e7646d2SAndroid Build Coastguard Worker 		  "multiple-document-handling",
348*5e7646d2SAndroid Build Coastguard Worker 		  "number-up",
349*5e7646d2SAndroid Build Coastguard Worker 		  "output-bin",
350*5e7646d2SAndroid Build Coastguard Worker 		  "orientation-requested",
351*5e7646d2SAndroid Build Coastguard Worker 		  "page-ranges",
352*5e7646d2SAndroid Build Coastguard Worker 		  "print-color-mode",
353*5e7646d2SAndroid Build Coastguard Worker 		  "print-quality",
354*5e7646d2SAndroid Build Coastguard Worker 		  "printer-resolution",
355*5e7646d2SAndroid Build Coastguard Worker 		  "sides"
356*5e7646d2SAndroid Build Coastguard Worker 		};
357*5e7646d2SAndroid Build Coastguard Worker   static const char * const pdf_versions[] =
358*5e7646d2SAndroid Build Coastguard Worker 		{			/* pdf-versions-supported */
359*5e7646d2SAndroid Build Coastguard Worker 		  "adobe-1.2",
360*5e7646d2SAndroid Build Coastguard Worker 		  "adobe-1.3",
361*5e7646d2SAndroid Build Coastguard Worker 		  "adobe-1.4",
362*5e7646d2SAndroid Build Coastguard Worker 		  "adobe-1.5",
363*5e7646d2SAndroid Build Coastguard Worker 		  "adobe-1.6",
364*5e7646d2SAndroid Build Coastguard Worker 		  "adobe-1.7",
365*5e7646d2SAndroid Build Coastguard Worker 		  "iso-19005-1_2005",
366*5e7646d2SAndroid Build Coastguard Worker 		  "iso-32000-1_2008",
367*5e7646d2SAndroid Build Coastguard Worker 		  "pwg-5102.3"
368*5e7646d2SAndroid Build Coastguard Worker 		};
369*5e7646d2SAndroid Build Coastguard Worker   static const char * const printer_settable[] =
370*5e7646d2SAndroid Build Coastguard Worker 		{			/* printer-settable-attributes-supported */
371*5e7646d2SAndroid Build Coastguard Worker 		  "printer-geo-location",
372*5e7646d2SAndroid Build Coastguard Worker 		  "printer-info",
373*5e7646d2SAndroid Build Coastguard Worker 		  "printer-location",
374*5e7646d2SAndroid Build Coastguard Worker 		  "printer-organization",
375*5e7646d2SAndroid Build Coastguard Worker 		  "printer-organizational-unit"
376*5e7646d2SAndroid Build Coastguard Worker 	        };
377*5e7646d2SAndroid Build Coastguard Worker   static const char * const which_jobs[] =
378*5e7646d2SAndroid Build Coastguard Worker 		{			/* which-jobs-supported values */
379*5e7646d2SAndroid Build Coastguard Worker 		  "completed",
380*5e7646d2SAndroid Build Coastguard Worker 		  "not-completed",
381*5e7646d2SAndroid Build Coastguard Worker 		  "aborted",
382*5e7646d2SAndroid Build Coastguard Worker 		  "all",
383*5e7646d2SAndroid Build Coastguard Worker 		  "canceled",
384*5e7646d2SAndroid Build Coastguard Worker 		  "pending",
385*5e7646d2SAndroid Build Coastguard Worker 		  "pending-held",
386*5e7646d2SAndroid Build Coastguard Worker 		  "processing",
387*5e7646d2SAndroid Build Coastguard Worker 		  "processing-stopped"
388*5e7646d2SAndroid Build Coastguard Worker 		};
389*5e7646d2SAndroid Build Coastguard Worker 
390*5e7646d2SAndroid Build Coastguard Worker 
391*5e7646d2SAndroid Build Coastguard Worker   if (CommonData)
392*5e7646d2SAndroid Build Coastguard Worker     ippDelete(CommonData);
393*5e7646d2SAndroid Build Coastguard Worker 
394*5e7646d2SAndroid Build Coastguard Worker   CommonData = ippNew();
395*5e7646d2SAndroid Build Coastguard Worker 
396*5e7646d2SAndroid Build Coastguard Worker  /*
397*5e7646d2SAndroid Build Coastguard Worker   * Get the maximum spool size based on the size of the filesystem used for
398*5e7646d2SAndroid Build Coastguard Worker   * the RequestRoot directory.  If the host OS doesn't support the statfs call
399*5e7646d2SAndroid Build Coastguard Worker   * or the filesystem is larger than 2TiB, always report INT_MAX.
400*5e7646d2SAndroid Build Coastguard Worker   */
401*5e7646d2SAndroid Build Coastguard Worker 
402*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_STATVFS
403*5e7646d2SAndroid Build Coastguard Worker   if (statvfs(RequestRoot, &spoolinfo))
404*5e7646d2SAndroid Build Coastguard Worker     k_supported = INT_MAX;
405*5e7646d2SAndroid Build Coastguard Worker   else if ((spoolsize = (double)spoolinfo.f_frsize * spoolinfo.f_blocks / 1024) >
406*5e7646d2SAndroid Build Coastguard Worker                INT_MAX)
407*5e7646d2SAndroid Build Coastguard Worker     k_supported = INT_MAX;
408*5e7646d2SAndroid Build Coastguard Worker   else
409*5e7646d2SAndroid Build Coastguard Worker     k_supported = (int)spoolsize;
410*5e7646d2SAndroid Build Coastguard Worker 
411*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_STATFS)
412*5e7646d2SAndroid Build Coastguard Worker   if (statfs(RequestRoot, &spoolinfo))
413*5e7646d2SAndroid Build Coastguard Worker     k_supported = INT_MAX;
414*5e7646d2SAndroid Build Coastguard Worker   else if ((spoolsize = (double)spoolinfo.f_bsize * spoolinfo.f_blocks / 1024) >
415*5e7646d2SAndroid Build Coastguard Worker                INT_MAX)
416*5e7646d2SAndroid Build Coastguard Worker     k_supported = INT_MAX;
417*5e7646d2SAndroid Build Coastguard Worker   else
418*5e7646d2SAndroid Build Coastguard Worker     k_supported = (int)spoolsize;
419*5e7646d2SAndroid Build Coastguard Worker 
420*5e7646d2SAndroid Build Coastguard Worker #else
421*5e7646d2SAndroid Build Coastguard Worker   k_supported = INT_MAX;
422*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_STATVFS */
423*5e7646d2SAndroid Build Coastguard Worker 
424*5e7646d2SAndroid Build Coastguard Worker  /*
425*5e7646d2SAndroid Build Coastguard Worker   * This list of attributes is sorted to improve performance when the
426*5e7646d2SAndroid Build Coastguard Worker   * client provides a requested-attributes attribute...
427*5e7646d2SAndroid Build Coastguard Worker   */
428*5e7646d2SAndroid Build Coastguard Worker 
429*5e7646d2SAndroid Build Coastguard Worker   /* charset-configured */
430*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY,
431*5e7646d2SAndroid Build Coastguard Worker                "charset-configured", NULL, "utf-8");
432*5e7646d2SAndroid Build Coastguard Worker 
433*5e7646d2SAndroid Build Coastguard Worker   /* charset-supported */
434*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_CHARSET | IPP_TAG_COPY,
435*5e7646d2SAndroid Build Coastguard Worker                 "charset-supported", sizeof(charsets) / sizeof(charsets[0]),
436*5e7646d2SAndroid Build Coastguard Worker 		NULL, charsets);
437*5e7646d2SAndroid Build Coastguard Worker 
438*5e7646d2SAndroid Build Coastguard Worker   /* compression-supported */
439*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
440*5e7646d2SAndroid Build Coastguard Worker         	"compression-supported",
441*5e7646d2SAndroid Build Coastguard Worker 		sizeof(compressions) / sizeof(compressions[0]),
442*5e7646d2SAndroid Build Coastguard Worker 		NULL, compressions);
443*5e7646d2SAndroid Build Coastguard Worker 
444*5e7646d2SAndroid Build Coastguard Worker   /* copies-supported */
445*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER, "copies-supported", 1, MaxCopies);
446*5e7646d2SAndroid Build Coastguard Worker 
447*5e7646d2SAndroid Build Coastguard Worker   /* cups-version */
448*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_TEXT | IPP_TAG_COPY,
449*5e7646d2SAndroid Build Coastguard Worker                "cups-version", NULL, &CUPS_SVERSION[6]);
450*5e7646d2SAndroid Build Coastguard Worker 
451*5e7646d2SAndroid Build Coastguard Worker   /* generated-natural-language-supported (no IPP_TAG_COPY) */
452*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
453*5e7646d2SAndroid Build Coastguard Worker                "generated-natural-language-supported", NULL, DefaultLanguage);
454*5e7646d2SAndroid Build Coastguard Worker 
455*5e7646d2SAndroid Build Coastguard Worker   /* ipp-features-supported */
456*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "ipp-features-supported", sizeof(features) / sizeof(features[0]), NULL, features);
457*5e7646d2SAndroid Build Coastguard Worker 
458*5e7646d2SAndroid Build Coastguard Worker   /* ipp-versions-supported */
459*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
460*5e7646d2SAndroid Build Coastguard Worker                 "ipp-versions-supported", sizeof(versions) / sizeof(versions[0]),
461*5e7646d2SAndroid Build Coastguard Worker 		NULL, versions);
462*5e7646d2SAndroid Build Coastguard Worker 
463*5e7646d2SAndroid Build Coastguard Worker   /* ippget-event-life */
464*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
465*5e7646d2SAndroid Build Coastguard Worker                 "ippget-event-life", 15);
466*5e7646d2SAndroid Build Coastguard Worker 
467*5e7646d2SAndroid Build Coastguard Worker   /* job-cancel-after-supported */
468*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER, "job-cancel-after-supported",
469*5e7646d2SAndroid Build Coastguard Worker               0, INT_MAX);
470*5e7646d2SAndroid Build Coastguard Worker 
471*5e7646d2SAndroid Build Coastguard Worker   /* job-creation-attributes-supported */
472*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
473*5e7646d2SAndroid Build Coastguard Worker                 "job-creation-attributes-supported",
474*5e7646d2SAndroid Build Coastguard Worker 		sizeof(job_creation) / sizeof(job_creation[0]),
475*5e7646d2SAndroid Build Coastguard Worker 		NULL, job_creation);
476*5e7646d2SAndroid Build Coastguard Worker 
477*5e7646d2SAndroid Build Coastguard Worker   /* job-hold-until-supported */
478*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
479*5e7646d2SAndroid Build Coastguard Worker                 "job-hold-until-supported", sizeof(holds) / sizeof(holds[0]),
480*5e7646d2SAndroid Build Coastguard Worker 		NULL, holds);
481*5e7646d2SAndroid Build Coastguard Worker 
482*5e7646d2SAndroid Build Coastguard Worker   /* job-ids-supported */
483*5e7646d2SAndroid Build Coastguard Worker   ippAddBoolean(CommonData, IPP_TAG_PRINTER, "job-ids-supported", 1);
484*5e7646d2SAndroid Build Coastguard Worker 
485*5e7646d2SAndroid Build Coastguard Worker   /* job-k-octets-supported */
486*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER, "job-k-octets-supported", 0,
487*5e7646d2SAndroid Build Coastguard Worker               k_supported);
488*5e7646d2SAndroid Build Coastguard Worker 
489*5e7646d2SAndroid Build Coastguard Worker   /* job-priority-supported */
490*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
491*5e7646d2SAndroid Build Coastguard Worker                 "job-priority-supported", 100);
492*5e7646d2SAndroid Build Coastguard Worker 
493*5e7646d2SAndroid Build Coastguard Worker   /* job-settable-attributes-supported */
494*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
495*5e7646d2SAndroid Build Coastguard Worker                 "job-settable-attributes-supported",
496*5e7646d2SAndroid Build Coastguard Worker 		sizeof(job_settable) / sizeof(job_settable[0]),
497*5e7646d2SAndroid Build Coastguard Worker 		NULL, job_settable);
498*5e7646d2SAndroid Build Coastguard Worker 
499*5e7646d2SAndroid Build Coastguard Worker   /* job-sheets-supported */
500*5e7646d2SAndroid Build Coastguard Worker   if (cupsArrayCount(Banners) > 0)
501*5e7646d2SAndroid Build Coastguard Worker   {
502*5e7646d2SAndroid Build Coastguard Worker    /*
503*5e7646d2SAndroid Build Coastguard Worker     * Setup the job-sheets-supported attribute...
504*5e7646d2SAndroid Build Coastguard Worker     */
505*5e7646d2SAndroid Build Coastguard Worker 
506*5e7646d2SAndroid Build Coastguard Worker     if (Classification && !ClassifyOverride)
507*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddString(CommonData, IPP_TAG_PRINTER,
508*5e7646d2SAndroid Build Coastguard Worker                           IPP_TAG_NAME | IPP_TAG_COPY,
509*5e7646d2SAndroid Build Coastguard Worker                 	  "job-sheets-supported", NULL, Classification);
510*5e7646d2SAndroid Build Coastguard Worker     else
511*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddStrings(CommonData, IPP_TAG_PRINTER,
512*5e7646d2SAndroid Build Coastguard Worker                            IPP_TAG_NAME | IPP_TAG_COPY,
513*5e7646d2SAndroid Build Coastguard Worker                 	   "job-sheets-supported", cupsArrayCount(Banners) + 1,
514*5e7646d2SAndroid Build Coastguard Worker 			   NULL, NULL);
515*5e7646d2SAndroid Build Coastguard Worker 
516*5e7646d2SAndroid Build Coastguard Worker     if (attr == NULL)
517*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_EMERG,
518*5e7646d2SAndroid Build Coastguard Worker                       "Unable to allocate memory for "
519*5e7646d2SAndroid Build Coastguard Worker                       "job-sheets-supported attribute: %s!", strerror(errno));
520*5e7646d2SAndroid Build Coastguard Worker     else if (!Classification || ClassifyOverride)
521*5e7646d2SAndroid Build Coastguard Worker     {
522*5e7646d2SAndroid Build Coastguard Worker       cupsd_banner_t	*banner;	/* Current banner */
523*5e7646d2SAndroid Build Coastguard Worker 
524*5e7646d2SAndroid Build Coastguard Worker 
525*5e7646d2SAndroid Build Coastguard Worker       attr->values[0].string.text = _cupsStrAlloc("none");
526*5e7646d2SAndroid Build Coastguard Worker 
527*5e7646d2SAndroid Build Coastguard Worker       for (i = 1, banner = (cupsd_banner_t *)cupsArrayFirst(Banners);
528*5e7646d2SAndroid Build Coastguard Worker 	   banner;
529*5e7646d2SAndroid Build Coastguard Worker 	   i ++, banner = (cupsd_banner_t *)cupsArrayNext(Banners))
530*5e7646d2SAndroid Build Coastguard Worker 	attr->values[i].string.text = banner->name;
531*5e7646d2SAndroid Build Coastguard Worker     }
532*5e7646d2SAndroid Build Coastguard Worker   }
533*5e7646d2SAndroid Build Coastguard Worker   else
534*5e7646d2SAndroid Build Coastguard Worker     ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
535*5e7646d2SAndroid Build Coastguard Worker                  "job-sheets-supported", NULL, "none");
536*5e7646d2SAndroid Build Coastguard Worker 
537*5e7646d2SAndroid Build Coastguard Worker   /* jpeg-k-octets-supported */
538*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER, "jpeg-k-octets-supported", 0,
539*5e7646d2SAndroid Build Coastguard Worker               k_supported);
540*5e7646d2SAndroid Build Coastguard Worker 
541*5e7646d2SAndroid Build Coastguard Worker   /* jpeg-x-dimension-supported */
542*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER, "jpeg-x-dimension-supported", 0,
543*5e7646d2SAndroid Build Coastguard Worker               65535);
544*5e7646d2SAndroid Build Coastguard Worker 
545*5e7646d2SAndroid Build Coastguard Worker   /* jpeg-y-dimension-supported */
546*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER, "jpeg-y-dimension-supported", 1,
547*5e7646d2SAndroid Build Coastguard Worker               65535);
548*5e7646d2SAndroid Build Coastguard Worker 
549*5e7646d2SAndroid Build Coastguard Worker   /* media-col-supported */
550*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
551*5e7646d2SAndroid Build Coastguard Worker                 "media-col-supported",
552*5e7646d2SAndroid Build Coastguard Worker                 sizeof(media_col_supported) /
553*5e7646d2SAndroid Build Coastguard Worker 		    sizeof(media_col_supported[0]), NULL,
554*5e7646d2SAndroid Build Coastguard Worker 	        media_col_supported);
555*5e7646d2SAndroid Build Coastguard Worker 
556*5e7646d2SAndroid Build Coastguard Worker   /* multiple-document-handling-supported */
557*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
558*5e7646d2SAndroid Build Coastguard Worker                 "multiple-document-handling-supported",
559*5e7646d2SAndroid Build Coastguard Worker                 sizeof(multiple_document_handling) /
560*5e7646d2SAndroid Build Coastguard Worker 		    sizeof(multiple_document_handling[0]), NULL,
561*5e7646d2SAndroid Build Coastguard Worker 	        multiple_document_handling);
562*5e7646d2SAndroid Build Coastguard Worker 
563*5e7646d2SAndroid Build Coastguard Worker   /* multiple-document-jobs-supported */
564*5e7646d2SAndroid Build Coastguard Worker   ippAddBoolean(CommonData, IPP_TAG_PRINTER,
565*5e7646d2SAndroid Build Coastguard Worker                 "multiple-document-jobs-supported", 1);
566*5e7646d2SAndroid Build Coastguard Worker 
567*5e7646d2SAndroid Build Coastguard Worker   /* multiple-operation-time-out */
568*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
569*5e7646d2SAndroid Build Coastguard Worker                 "multiple-operation-time-out", MultipleOperationTimeout);
570*5e7646d2SAndroid Build Coastguard Worker 
571*5e7646d2SAndroid Build Coastguard Worker   /* multiple-operation-time-out-action */
572*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "multiple-operation-time-out-action", NULL, "process-job");
573*5e7646d2SAndroid Build Coastguard Worker 
574*5e7646d2SAndroid Build Coastguard Worker   /* natural-language-configured (no IPP_TAG_COPY) */
575*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
576*5e7646d2SAndroid Build Coastguard Worker                "natural-language-configured", NULL, DefaultLanguage);
577*5e7646d2SAndroid Build Coastguard Worker 
578*5e7646d2SAndroid Build Coastguard Worker   /* notify-attributes-supported */
579*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
580*5e7646d2SAndroid Build Coastguard Worker                 "notify-attributes-supported",
581*5e7646d2SAndroid Build Coastguard Worker 		(int)(sizeof(notify_attrs) / sizeof(notify_attrs[0])),
582*5e7646d2SAndroid Build Coastguard Worker 		NULL, notify_attrs);
583*5e7646d2SAndroid Build Coastguard Worker 
584*5e7646d2SAndroid Build Coastguard Worker   /* notify-lease-duration-supported */
585*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER,
586*5e7646d2SAndroid Build Coastguard Worker               "notify-lease-duration-supported", 0,
587*5e7646d2SAndroid Build Coastguard Worker 	      MaxLeaseDuration ? MaxLeaseDuration : 2147483647);
588*5e7646d2SAndroid Build Coastguard Worker 
589*5e7646d2SAndroid Build Coastguard Worker   /* notify-max-events-supported */
590*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
591*5e7646d2SAndroid Build Coastguard Worker                "notify-max-events-supported", MaxEvents);
592*5e7646d2SAndroid Build Coastguard Worker 
593*5e7646d2SAndroid Build Coastguard Worker   /* notify-events-supported */
594*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
595*5e7646d2SAndroid Build Coastguard Worker                 "notify-events-supported",
596*5e7646d2SAndroid Build Coastguard Worker 		(int)(sizeof(notify_events) / sizeof(notify_events[0])),
597*5e7646d2SAndroid Build Coastguard Worker 		NULL, notify_events);
598*5e7646d2SAndroid Build Coastguard Worker 
599*5e7646d2SAndroid Build Coastguard Worker   /* notify-pull-method-supported */
600*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
601*5e7646d2SAndroid Build Coastguard Worker                "notify-pull-method-supported", NULL, "ippget");
602*5e7646d2SAndroid Build Coastguard Worker 
603*5e7646d2SAndroid Build Coastguard Worker   /* notify-schemes-supported */
604*5e7646d2SAndroid Build Coastguard Worker   snprintf(filename, sizeof(filename), "%s/notifier", ServerBin);
605*5e7646d2SAndroid Build Coastguard Worker   if ((dir = cupsDirOpen(filename)) != NULL)
606*5e7646d2SAndroid Build Coastguard Worker   {
607*5e7646d2SAndroid Build Coastguard Worker     notifiers = cupsArrayNew((cups_array_func_t)strcmp, NULL);
608*5e7646d2SAndroid Build Coastguard Worker 
609*5e7646d2SAndroid Build Coastguard Worker     while ((dent = cupsDirRead(dir)) != NULL)
610*5e7646d2SAndroid Build Coastguard Worker       if (S_ISREG(dent->fileinfo.st_mode) &&
611*5e7646d2SAndroid Build Coastguard Worker           (dent->fileinfo.st_mode & S_IXOTH) != 0)
612*5e7646d2SAndroid Build Coastguard Worker         cupsArrayAdd(notifiers, _cupsStrAlloc(dent->filename));
613*5e7646d2SAndroid Build Coastguard Worker 
614*5e7646d2SAndroid Build Coastguard Worker     if (cupsArrayCount(notifiers) > 0)
615*5e7646d2SAndroid Build Coastguard Worker     {
616*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
617*5e7646d2SAndroid Build Coastguard Worker         	           "notify-schemes-supported",
618*5e7646d2SAndroid Build Coastguard Worker 			   cupsArrayCount(notifiers), NULL, NULL);
619*5e7646d2SAndroid Build Coastguard Worker 
620*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, notifier = (char *)cupsArrayFirst(notifiers);
621*5e7646d2SAndroid Build Coastguard Worker            notifier;
622*5e7646d2SAndroid Build Coastguard Worker 	   i ++, notifier = (char *)cupsArrayNext(notifiers))
623*5e7646d2SAndroid Build Coastguard Worker 	attr->values[i].string.text = notifier;
624*5e7646d2SAndroid Build Coastguard Worker     }
625*5e7646d2SAndroid Build Coastguard Worker 
626*5e7646d2SAndroid Build Coastguard Worker     cupsArrayDelete(notifiers);
627*5e7646d2SAndroid Build Coastguard Worker     cupsDirClose(dir);
628*5e7646d2SAndroid Build Coastguard Worker   }
629*5e7646d2SAndroid Build Coastguard Worker 
630*5e7646d2SAndroid Build Coastguard Worker   /* number-up-supported */
631*5e7646d2SAndroid Build Coastguard Worker   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
632*5e7646d2SAndroid Build Coastguard Worker                  "number-up-supported", sizeof(number_up) / sizeof(number_up[0]), number_up);
633*5e7646d2SAndroid Build Coastguard Worker 
634*5e7646d2SAndroid Build Coastguard Worker   /* number-up-layout-supported */
635*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "number-up-layout-supported", sizeof(number_up_layout) / sizeof(number_up_layout[0]), NULL, number_up_layout);
636*5e7646d2SAndroid Build Coastguard Worker 
637*5e7646d2SAndroid Build Coastguard Worker   /* operations-supported */
638*5e7646d2SAndroid Build Coastguard Worker   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
639*5e7646d2SAndroid Build Coastguard Worker                  "operations-supported", sizeof(ops) / sizeof(ops[0]), ops);
640*5e7646d2SAndroid Build Coastguard Worker 
641*5e7646d2SAndroid Build Coastguard Worker   /* orientation-requested-supported */
642*5e7646d2SAndroid Build Coastguard Worker   ippAddIntegers(CommonData, IPP_TAG_PRINTER, IPP_TAG_ENUM,
643*5e7646d2SAndroid Build Coastguard Worker                  "orientation-requested-supported", 4, orients);
644*5e7646d2SAndroid Build Coastguard Worker 
645*5e7646d2SAndroid Build Coastguard Worker   /* page-delivery-supported */
646*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "page-delivery-supported", sizeof(page_delivery) / sizeof(page_delivery[0]), NULL, page_delivery);
647*5e7646d2SAndroid Build Coastguard Worker 
648*5e7646d2SAndroid Build Coastguard Worker   /* page-ranges-supported */
649*5e7646d2SAndroid Build Coastguard Worker   ippAddBoolean(CommonData, IPP_TAG_PRINTER, "page-ranges-supported", 1);
650*5e7646d2SAndroid Build Coastguard Worker 
651*5e7646d2SAndroid Build Coastguard Worker   /* pdf-k-octets-supported */
652*5e7646d2SAndroid Build Coastguard Worker   ippAddRange(CommonData, IPP_TAG_PRINTER, "pdf-k-octets-supported", 0,
653*5e7646d2SAndroid Build Coastguard Worker               k_supported);
654*5e7646d2SAndroid Build Coastguard Worker 
655*5e7646d2SAndroid Build Coastguard Worker   /* pdf-versions-supported */
656*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
657*5e7646d2SAndroid Build Coastguard Worker                 "pdf-versions-supported",
658*5e7646d2SAndroid Build Coastguard Worker                 sizeof(pdf_versions) / sizeof(pdf_versions[0]), NULL,
659*5e7646d2SAndroid Build Coastguard Worker                 pdf_versions);
660*5e7646d2SAndroid Build Coastguard Worker 
661*5e7646d2SAndroid Build Coastguard Worker   /* pdl-override-supported */
662*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
663*5e7646d2SAndroid Build Coastguard Worker                "pdl-override-supported", NULL, "attempted");
664*5e7646d2SAndroid Build Coastguard Worker 
665*5e7646d2SAndroid Build Coastguard Worker   /* print-scaling-supported */
666*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "print-scaling-supported", sizeof(print_scaling) / sizeof(print_scaling[0]), NULL, print_scaling);
667*5e7646d2SAndroid Build Coastguard Worker 
668*5e7646d2SAndroid Build Coastguard Worker   /* printer-get-attributes-supported */
669*5e7646d2SAndroid Build Coastguard Worker   ippAddString(CommonData, IPP_TAG_PRINTER, IPP_CONST_TAG(IPP_TAG_KEYWORD), "printer-get-attributes-supported", NULL, "document-format");
670*5e7646d2SAndroid Build Coastguard Worker 
671*5e7646d2SAndroid Build Coastguard Worker   /* printer-op-policy-supported */
672*5e7646d2SAndroid Build Coastguard Worker   attr = ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_NAME | IPP_TAG_COPY,
673*5e7646d2SAndroid Build Coastguard Worker                        "printer-op-policy-supported", cupsArrayCount(Policies),
674*5e7646d2SAndroid Build Coastguard Worker 		       NULL, NULL);
675*5e7646d2SAndroid Build Coastguard Worker   for (i = 0, p = (cupsd_policy_t *)cupsArrayFirst(Policies);
676*5e7646d2SAndroid Build Coastguard Worker        p;
677*5e7646d2SAndroid Build Coastguard Worker        i ++, p = (cupsd_policy_t *)cupsArrayNext(Policies))
678*5e7646d2SAndroid Build Coastguard Worker     attr->values[i].string.text = p->name;
679*5e7646d2SAndroid Build Coastguard Worker 
680*5e7646d2SAndroid Build Coastguard Worker   /* printer-settable-attributes-supported */
681*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
682*5e7646d2SAndroid Build Coastguard Worker                 "printer-settable-attributes-supported",
683*5e7646d2SAndroid Build Coastguard Worker 		sizeof(printer_settable) / sizeof(printer_settable[0]),
684*5e7646d2SAndroid Build Coastguard Worker 		NULL, printer_settable);
685*5e7646d2SAndroid Build Coastguard Worker 
686*5e7646d2SAndroid Build Coastguard Worker   /* server-is-sharing-printers */
687*5e7646d2SAndroid Build Coastguard Worker   ippAddBoolean(CommonData, IPP_TAG_PRINTER, "server-is-sharing-printers",
688*5e7646d2SAndroid Build Coastguard Worker                 BrowseLocalProtocols != 0 && Browsing);
689*5e7646d2SAndroid Build Coastguard Worker 
690*5e7646d2SAndroid Build Coastguard Worker   /* which-jobs-supported */
691*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(CommonData, IPP_TAG_PRINTER, IPP_TAG_KEYWORD | IPP_TAG_COPY,
692*5e7646d2SAndroid Build Coastguard Worker                 "which-jobs-supported",
693*5e7646d2SAndroid Build Coastguard Worker                 sizeof(which_jobs) / sizeof(which_jobs[0]), NULL, which_jobs);
694*5e7646d2SAndroid Build Coastguard Worker }
695*5e7646d2SAndroid Build Coastguard Worker 
696*5e7646d2SAndroid Build Coastguard Worker 
697*5e7646d2SAndroid Build Coastguard Worker /*
698*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdDeleteAllPrinters()' - Delete all printers from the system.
699*5e7646d2SAndroid Build Coastguard Worker  */
700*5e7646d2SAndroid Build Coastguard Worker 
701*5e7646d2SAndroid Build Coastguard Worker void
cupsdDeleteAllPrinters(void)702*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteAllPrinters(void)
703*5e7646d2SAndroid Build Coastguard Worker {
704*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Pointer to current printer/class */
705*5e7646d2SAndroid Build Coastguard Worker 
706*5e7646d2SAndroid Build Coastguard Worker 
707*5e7646d2SAndroid Build Coastguard Worker   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
708*5e7646d2SAndroid Build Coastguard Worker        p;
709*5e7646d2SAndroid Build Coastguard Worker        p = (cupsd_printer_t *)cupsArrayNext(Printers))
710*5e7646d2SAndroid Build Coastguard Worker   {
711*5e7646d2SAndroid Build Coastguard Worker     p->op_policy_ptr = DefaultPolicyPtr;
712*5e7646d2SAndroid Build Coastguard Worker     cupsdDeletePrinter(p, 0);
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 /*
718*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdDeletePrinter()' - Delete a printer from the system.
719*5e7646d2SAndroid Build Coastguard Worker  */
720*5e7646d2SAndroid Build Coastguard Worker 
721*5e7646d2SAndroid Build Coastguard Worker int					/* O - 1 if classes affected, 0 otherwise */
cupsdDeletePrinter(cupsd_printer_t * p,int update)722*5e7646d2SAndroid Build Coastguard Worker cupsdDeletePrinter(
723*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer to delete */
724*5e7646d2SAndroid Build Coastguard Worker     int             update)		/* I - Update printers.conf? */
725*5e7646d2SAndroid Build Coastguard Worker {
726*5e7646d2SAndroid Build Coastguard Worker   int	i,				/* Looping var */
727*5e7646d2SAndroid Build Coastguard Worker 	changed = 0;			/* Class changed? */
728*5e7646d2SAndroid Build Coastguard Worker 
729*5e7646d2SAndroid Build Coastguard Worker 
730*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdDeletePrinter(p=%p(%s), update=%d)",
731*5e7646d2SAndroid Build Coastguard Worker                   p, p->name, update);
732*5e7646d2SAndroid Build Coastguard Worker 
733*5e7646d2SAndroid Build Coastguard Worker  /*
734*5e7646d2SAndroid Build Coastguard Worker   * Save the current position in the Printers array...
735*5e7646d2SAndroid Build Coastguard Worker   */
736*5e7646d2SAndroid Build Coastguard Worker 
737*5e7646d2SAndroid Build Coastguard Worker   cupsArraySave(Printers);
738*5e7646d2SAndroid Build Coastguard Worker 
739*5e7646d2SAndroid Build Coastguard Worker  /*
740*5e7646d2SAndroid Build Coastguard Worker   * Stop printing on this printer...
741*5e7646d2SAndroid Build Coastguard Worker   */
742*5e7646d2SAndroid Build Coastguard Worker 
743*5e7646d2SAndroid Build Coastguard Worker   cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, update);
744*5e7646d2SAndroid Build Coastguard Worker 
745*5e7646d2SAndroid Build Coastguard Worker   p->state = IPP_PRINTER_STOPPED;	/* Force for browsed printers */
746*5e7646d2SAndroid Build Coastguard Worker 
747*5e7646d2SAndroid Build Coastguard Worker   if (p->job)
748*5e7646d2SAndroid Build Coastguard Worker     cupsdSetJobState(p->job, IPP_JOB_PENDING, CUPSD_JOB_FORCE,
749*5e7646d2SAndroid Build Coastguard Worker                      update ? "Job stopped due to printer being deleted." :
750*5e7646d2SAndroid Build Coastguard Worker 		              "Job stopped.");
751*5e7646d2SAndroid Build Coastguard Worker 
752*5e7646d2SAndroid Build Coastguard Worker  /*
753*5e7646d2SAndroid Build Coastguard Worker   * Remove the printer from the list...
754*5e7646d2SAndroid Build Coastguard Worker   */
755*5e7646d2SAndroid Build Coastguard Worker 
756*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
757*5e7646d2SAndroid Build Coastguard Worker                   "cupsdDeletePrinter: Removing %s from Printers", p->name);
758*5e7646d2SAndroid Build Coastguard Worker   cupsArrayRemove(Printers, p);
759*5e7646d2SAndroid Build Coastguard Worker 
760*5e7646d2SAndroid Build Coastguard Worker  /*
761*5e7646d2SAndroid Build Coastguard Worker   * If p is the default printer, assign a different one...
762*5e7646d2SAndroid Build Coastguard Worker   */
763*5e7646d2SAndroid Build Coastguard Worker 
764*5e7646d2SAndroid Build Coastguard Worker   if (p == DefaultPrinter)
765*5e7646d2SAndroid Build Coastguard Worker     DefaultPrinter = NULL;
766*5e7646d2SAndroid Build Coastguard Worker 
767*5e7646d2SAndroid Build Coastguard Worker  /*
768*5e7646d2SAndroid Build Coastguard Worker   * Remove this printer from any classes...
769*5e7646d2SAndroid Build Coastguard Worker   */
770*5e7646d2SAndroid Build Coastguard Worker 
771*5e7646d2SAndroid Build Coastguard Worker   changed = cupsdDeletePrinterFromClasses(p);
772*5e7646d2SAndroid Build Coastguard Worker 
773*5e7646d2SAndroid Build Coastguard Worker  /*
774*5e7646d2SAndroid Build Coastguard Worker   * Deregister from any browse protocols...
775*5e7646d2SAndroid Build Coastguard Worker   */
776*5e7646d2SAndroid Build Coastguard Worker 
777*5e7646d2SAndroid Build Coastguard Worker   cupsdDeregisterPrinter(p, 1);
778*5e7646d2SAndroid Build Coastguard Worker 
779*5e7646d2SAndroid Build Coastguard Worker  /*
780*5e7646d2SAndroid Build Coastguard Worker   * Remove support files if this is a temporary queue and deregister color
781*5e7646d2SAndroid Build Coastguard Worker   * profiles...
782*5e7646d2SAndroid Build Coastguard Worker   */
783*5e7646d2SAndroid Build Coastguard Worker 
784*5e7646d2SAndroid Build Coastguard Worker   if (p->temporary)
785*5e7646d2SAndroid Build Coastguard Worker   {
786*5e7646d2SAndroid Build Coastguard Worker     char	filename[1024];		/* Script/PPD filename */
787*5e7646d2SAndroid Build Coastguard Worker 
788*5e7646d2SAndroid Build Coastguard Worker    /*
789*5e7646d2SAndroid Build Coastguard Worker     * Remove any old PPD or script files...
790*5e7646d2SAndroid Build Coastguard Worker     */
791*5e7646d2SAndroid Build Coastguard Worker 
792*5e7646d2SAndroid Build Coastguard Worker     snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd", ServerRoot, p->name);
793*5e7646d2SAndroid Build Coastguard Worker     unlink(filename);
794*5e7646d2SAndroid Build Coastguard Worker     snprintf(filename, sizeof(filename), "%s/ppd/%s.ppd.O", ServerRoot, p->name);
795*5e7646d2SAndroid Build Coastguard Worker     unlink(filename);
796*5e7646d2SAndroid Build Coastguard Worker 
797*5e7646d2SAndroid Build Coastguard Worker     snprintf(filename, sizeof(filename), "%s/%s.png", CacheDir, p->name);
798*5e7646d2SAndroid Build Coastguard Worker     unlink(filename);
799*5e7646d2SAndroid Build Coastguard Worker 
800*5e7646d2SAndroid Build Coastguard Worker     snprintf(filename, sizeof(filename), "%s/%s.data", CacheDir, p->name);
801*5e7646d2SAndroid Build Coastguard Worker     unlink(filename);
802*5e7646d2SAndroid Build Coastguard Worker 
803*5e7646d2SAndroid Build Coastguard Worker    /*
804*5e7646d2SAndroid Build Coastguard Worker     * Unregister color profiles...
805*5e7646d2SAndroid Build Coastguard Worker     */
806*5e7646d2SAndroid Build Coastguard Worker 
807*5e7646d2SAndroid Build Coastguard Worker     cupsdUnregisterColor(p);
808*5e7646d2SAndroid Build Coastguard Worker   }
809*5e7646d2SAndroid Build Coastguard Worker 
810*5e7646d2SAndroid Build Coastguard Worker  /*
811*5e7646d2SAndroid Build Coastguard Worker   * Free all memory used by the printer...
812*5e7646d2SAndroid Build Coastguard Worker   */
813*5e7646d2SAndroid Build Coastguard Worker 
814*5e7646d2SAndroid Build Coastguard Worker   if (p->printers != NULL)
815*5e7646d2SAndroid Build Coastguard Worker     free(p->printers);
816*5e7646d2SAndroid Build Coastguard Worker 
817*5e7646d2SAndroid Build Coastguard Worker   delete_printer_filters(p);
818*5e7646d2SAndroid Build Coastguard Worker 
819*5e7646d2SAndroid Build Coastguard Worker   for (i = 0; i < p->num_reasons; i ++)
820*5e7646d2SAndroid Build Coastguard Worker     _cupsStrFree(p->reasons[i]);
821*5e7646d2SAndroid Build Coastguard Worker 
822*5e7646d2SAndroid Build Coastguard Worker   ippDelete(p->attrs);
823*5e7646d2SAndroid Build Coastguard Worker   ippDelete(p->ppd_attrs);
824*5e7646d2SAndroid Build Coastguard Worker 
825*5e7646d2SAndroid Build Coastguard Worker   _ppdCacheDestroy(p->pc);
826*5e7646d2SAndroid Build Coastguard Worker 
827*5e7646d2SAndroid Build Coastguard Worker   mimeDeleteType(MimeDatabase, p->filetype);
828*5e7646d2SAndroid Build Coastguard Worker   mimeDeleteType(MimeDatabase, p->prefiltertype);
829*5e7646d2SAndroid Build Coastguard Worker 
830*5e7646d2SAndroid Build Coastguard Worker   cupsdFreeStrings(&(p->users));
831*5e7646d2SAndroid Build Coastguard Worker   cupsdFreeQuotas(p);
832*5e7646d2SAndroid Build Coastguard Worker 
833*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->uuid);
834*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->uri);
835*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->hostname);
836*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->name);
837*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->location);
838*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->geo_location);
839*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->make_model);
840*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->info);
841*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->job_sheets[0]);
842*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->job_sheets[1]);
843*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->device_uri);
844*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->sanitized_device_uri);
845*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->port_monitor);
846*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->op_policy);
847*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->error_policy);
848*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->strings);
849*5e7646d2SAndroid Build Coastguard Worker 
850*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->alert);
851*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->alert_description);
852*5e7646d2SAndroid Build Coastguard Worker 
853*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
854*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->pdl);
855*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&p->reg_name);
856*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
857*5e7646d2SAndroid Build Coastguard Worker 
858*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->filetypes);
859*5e7646d2SAndroid Build Coastguard Worker 
860*5e7646d2SAndroid Build Coastguard Worker   cupsFreeOptions(p->num_options, p->options);
861*5e7646d2SAndroid Build Coastguard Worker 
862*5e7646d2SAndroid Build Coastguard Worker   free(p);
863*5e7646d2SAndroid Build Coastguard Worker 
864*5e7646d2SAndroid Build Coastguard Worker  /*
865*5e7646d2SAndroid Build Coastguard Worker   * Restore the previous position in the Printers array...
866*5e7646d2SAndroid Build Coastguard Worker   */
867*5e7646d2SAndroid Build Coastguard Worker 
868*5e7646d2SAndroid Build Coastguard Worker   cupsArrayRestore(Printers);
869*5e7646d2SAndroid Build Coastguard Worker 
870*5e7646d2SAndroid Build Coastguard Worker   return (changed);
871*5e7646d2SAndroid Build Coastguard Worker }
872*5e7646d2SAndroid Build Coastguard Worker 
873*5e7646d2SAndroid Build Coastguard Worker 
874*5e7646d2SAndroid Build Coastguard Worker /*
875*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdDeleteTemporaryPrinters()' - Delete unneeded temporary printers.
876*5e7646d2SAndroid Build Coastguard Worker  */
877*5e7646d2SAndroid Build Coastguard Worker 
878*5e7646d2SAndroid Build Coastguard Worker void
cupsdDeleteTemporaryPrinters(int force)879*5e7646d2SAndroid Build Coastguard Worker cupsdDeleteTemporaryPrinters(int force) /* I - Force deletion instead of auto? */
880*5e7646d2SAndroid Build Coastguard Worker {
881*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t *p;                   /* Current printer */
882*5e7646d2SAndroid Build Coastguard Worker   time_t          unused_time;          /* Last time for printer state change */
883*5e7646d2SAndroid Build Coastguard Worker 
884*5e7646d2SAndroid Build Coastguard Worker 
885*5e7646d2SAndroid Build Coastguard Worker  /*
886*5e7646d2SAndroid Build Coastguard Worker   * Allow temporary printers to stick around for 60 seconds after the last job
887*5e7646d2SAndroid Build Coastguard Worker   * completes.
888*5e7646d2SAndroid Build Coastguard Worker   */
889*5e7646d2SAndroid Build Coastguard Worker 
890*5e7646d2SAndroid Build Coastguard Worker   unused_time = time(NULL) - 60;
891*5e7646d2SAndroid Build Coastguard Worker 
892*5e7646d2SAndroid Build Coastguard Worker   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers); p; p = (cupsd_printer_t *)cupsArrayNext(Printers))
893*5e7646d2SAndroid Build Coastguard Worker   {
894*5e7646d2SAndroid Build Coastguard Worker     if (p->temporary && (force || p->state_time < unused_time))
895*5e7646d2SAndroid Build Coastguard Worker       cupsdDeletePrinter(p, 0);
896*5e7646d2SAndroid Build Coastguard Worker   }
897*5e7646d2SAndroid Build Coastguard Worker }
898*5e7646d2SAndroid Build Coastguard Worker 
899*5e7646d2SAndroid Build Coastguard Worker 
900*5e7646d2SAndroid Build Coastguard Worker /*
901*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdFindDest()' - Find a destination in the list.
902*5e7646d2SAndroid Build Coastguard Worker  */
903*5e7646d2SAndroid Build Coastguard Worker 
904*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *			/* O - Destination in list */
cupsdFindDest(const char * name)905*5e7646d2SAndroid Build Coastguard Worker cupsdFindDest(const char *name)		/* I - Name of printer or class to find */
906*5e7646d2SAndroid Build Coastguard Worker {
907*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	key;		/* Search key */
908*5e7646d2SAndroid Build Coastguard Worker 
909*5e7646d2SAndroid Build Coastguard Worker 
910*5e7646d2SAndroid Build Coastguard Worker   key.name = (char *)name;
911*5e7646d2SAndroid Build Coastguard Worker   return ((cupsd_printer_t *)cupsArrayFind(Printers, &key));
912*5e7646d2SAndroid Build Coastguard Worker }
913*5e7646d2SAndroid Build Coastguard Worker 
914*5e7646d2SAndroid Build Coastguard Worker 
915*5e7646d2SAndroid Build Coastguard Worker /*
916*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdFindPrinter()' - Find a printer in the list.
917*5e7646d2SAndroid Build Coastguard Worker  */
918*5e7646d2SAndroid Build Coastguard Worker 
919*5e7646d2SAndroid Build Coastguard Worker cupsd_printer_t *			/* O - Printer in list */
cupsdFindPrinter(const char * name)920*5e7646d2SAndroid Build Coastguard Worker cupsdFindPrinter(const char *name)	/* I - Name of printer to find */
921*5e7646d2SAndroid Build Coastguard Worker {
922*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Printer in list */
923*5e7646d2SAndroid Build Coastguard Worker 
924*5e7646d2SAndroid Build Coastguard Worker 
925*5e7646d2SAndroid Build Coastguard Worker   if ((p = cupsdFindDest(name)) != NULL && (p->type & CUPS_PRINTER_CLASS))
926*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
927*5e7646d2SAndroid Build Coastguard Worker   else
928*5e7646d2SAndroid Build Coastguard Worker     return (p);
929*5e7646d2SAndroid Build Coastguard Worker }
930*5e7646d2SAndroid Build Coastguard Worker 
931*5e7646d2SAndroid Build Coastguard Worker 
932*5e7646d2SAndroid Build Coastguard Worker /*
933*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdLoadAllPrinters()' - Load printers from the printers.conf file.
934*5e7646d2SAndroid Build Coastguard Worker  */
935*5e7646d2SAndroid Build Coastguard Worker 
936*5e7646d2SAndroid Build Coastguard Worker void
cupsdLoadAllPrinters(void)937*5e7646d2SAndroid Build Coastguard Worker cupsdLoadAllPrinters(void)
938*5e7646d2SAndroid Build Coastguard Worker {
939*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
940*5e7646d2SAndroid Build Coastguard Worker   cups_file_t		*fp;		/* printers.conf file */
941*5e7646d2SAndroid Build Coastguard Worker   int			linenum;	/* Current line number */
942*5e7646d2SAndroid Build Coastguard Worker   char			line[4096],	/* Line from file */
943*5e7646d2SAndroid Build Coastguard Worker 			*value,		/* Pointer to value */
944*5e7646d2SAndroid Build Coastguard Worker 			*valueptr;	/* Pointer into value */
945*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Current printer */
946*5e7646d2SAndroid Build Coastguard Worker 
947*5e7646d2SAndroid Build Coastguard Worker 
948*5e7646d2SAndroid Build Coastguard Worker  /*
949*5e7646d2SAndroid Build Coastguard Worker   * Open the printers.conf file...
950*5e7646d2SAndroid Build Coastguard Worker   */
951*5e7646d2SAndroid Build Coastguard Worker 
952*5e7646d2SAndroid Build Coastguard Worker   snprintf(line, sizeof(line), "%s/printers.conf", ServerRoot);
953*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsdOpenConfFile(line)) == NULL)
954*5e7646d2SAndroid Build Coastguard Worker     return;
955*5e7646d2SAndroid Build Coastguard Worker 
956*5e7646d2SAndroid Build Coastguard Worker  /*
957*5e7646d2SAndroid Build Coastguard Worker   * Read printer configurations until we hit EOF...
958*5e7646d2SAndroid Build Coastguard Worker   */
959*5e7646d2SAndroid Build Coastguard Worker 
960*5e7646d2SAndroid Build Coastguard Worker   linenum = 0;
961*5e7646d2SAndroid Build Coastguard Worker   p       = NULL;
962*5e7646d2SAndroid Build Coastguard Worker 
963*5e7646d2SAndroid Build Coastguard Worker   while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum))
964*5e7646d2SAndroid Build Coastguard Worker   {
965*5e7646d2SAndroid Build Coastguard Worker    /*
966*5e7646d2SAndroid Build Coastguard Worker     * Decode the directive...
967*5e7646d2SAndroid Build Coastguard Worker     */
968*5e7646d2SAndroid Build Coastguard Worker 
969*5e7646d2SAndroid Build Coastguard Worker     if (!_cups_strcasecmp(line, "NextPrinterId"))
970*5e7646d2SAndroid Build Coastguard Worker     {
971*5e7646d2SAndroid Build Coastguard Worker       if (value && (i = atoi(value)) > 0)
972*5e7646d2SAndroid Build Coastguard Worker         NextPrinterId = i;
973*5e7646d2SAndroid Build Coastguard Worker       else
974*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of printers.conf.", linenum);
975*5e7646d2SAndroid Build Coastguard Worker     }
976*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "<Printer") || !_cups_strcasecmp(line, "<DefaultPrinter"))
977*5e7646d2SAndroid Build Coastguard Worker     {
978*5e7646d2SAndroid Build Coastguard Worker      /*
979*5e7646d2SAndroid Build Coastguard Worker       * <Printer name> or <DefaultPrinter name>
980*5e7646d2SAndroid Build Coastguard Worker       */
981*5e7646d2SAndroid Build Coastguard Worker 
982*5e7646d2SAndroid Build Coastguard Worker       if (p == NULL && value)
983*5e7646d2SAndroid Build Coastguard Worker       {
984*5e7646d2SAndroid Build Coastguard Worker        /*
985*5e7646d2SAndroid Build Coastguard Worker         * Add the printer and a base file type...
986*5e7646d2SAndroid Build Coastguard Worker 	*/
987*5e7646d2SAndroid Build Coastguard Worker 
988*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_DEBUG, "Loading printer %s...", value);
989*5e7646d2SAndroid Build Coastguard Worker 
990*5e7646d2SAndroid Build Coastguard Worker         p = cupsdAddPrinter(value);
991*5e7646d2SAndroid Build Coastguard Worker 	p->accepting = 1;
992*5e7646d2SAndroid Build Coastguard Worker 	p->state     = IPP_PRINTER_IDLE;
993*5e7646d2SAndroid Build Coastguard Worker 
994*5e7646d2SAndroid Build Coastguard Worker        /*
995*5e7646d2SAndroid Build Coastguard Worker         * Set the default printer as needed...
996*5e7646d2SAndroid Build Coastguard Worker 	*/
997*5e7646d2SAndroid Build Coastguard Worker 
998*5e7646d2SAndroid Build Coastguard Worker         if (!_cups_strcasecmp(line, "<DefaultPrinter"))
999*5e7646d2SAndroid Build Coastguard Worker 	  DefaultPrinter = p;
1000*5e7646d2SAndroid Build Coastguard Worker       }
1001*5e7646d2SAndroid Build Coastguard Worker       else
1002*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR,
1003*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1004*5e7646d2SAndroid Build Coastguard Worker     }
1005*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "</Printer>") || !_cups_strcasecmp(line, "</DefaultPrinter>"))
1006*5e7646d2SAndroid Build Coastguard Worker     {
1007*5e7646d2SAndroid Build Coastguard Worker       if (p != NULL)
1008*5e7646d2SAndroid Build Coastguard Worker       {
1009*5e7646d2SAndroid Build Coastguard Worker        /*
1010*5e7646d2SAndroid Build Coastguard Worker         * Close out the current printer...
1011*5e7646d2SAndroid Build Coastguard Worker 	*/
1012*5e7646d2SAndroid Build Coastguard Worker 
1013*5e7646d2SAndroid Build Coastguard Worker         if (!p->printer_id)
1014*5e7646d2SAndroid Build Coastguard Worker         {
1015*5e7646d2SAndroid Build Coastguard Worker           p->printer_id = NextPrinterId ++;
1016*5e7646d2SAndroid Build Coastguard Worker           cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
1017*5e7646d2SAndroid Build Coastguard Worker 	}
1018*5e7646d2SAndroid Build Coastguard Worker 
1019*5e7646d2SAndroid Build Coastguard Worker         cupsdSetPrinterAttrs(p);
1020*5e7646d2SAndroid Build Coastguard Worker 
1021*5e7646d2SAndroid Build Coastguard Worker         if (strncmp(p->device_uri, "file:", 5) && p->state != IPP_PRINTER_STOPPED)
1022*5e7646d2SAndroid Build Coastguard Worker 	{
1023*5e7646d2SAndroid Build Coastguard Worker 	 /*
1024*5e7646d2SAndroid Build Coastguard Worker           * See if the backend exists...
1025*5e7646d2SAndroid Build Coastguard Worker 	  */
1026*5e7646d2SAndroid Build Coastguard Worker 
1027*5e7646d2SAndroid Build Coastguard Worker 	  snprintf(line, sizeof(line), "%s/backend/%s", ServerBin, p->device_uri);
1028*5e7646d2SAndroid Build Coastguard Worker 
1029*5e7646d2SAndroid Build Coastguard Worker           if ((valueptr = strchr(line + strlen(ServerBin), ':')) != NULL)
1030*5e7646d2SAndroid Build Coastguard Worker 	    *valueptr = '\0';		/* Chop everything but URI scheme */
1031*5e7646d2SAndroid Build Coastguard Worker 
1032*5e7646d2SAndroid Build Coastguard Worker           if (access(line, 0))
1033*5e7646d2SAndroid Build Coastguard Worker 	  {
1034*5e7646d2SAndroid Build Coastguard Worker 	   /*
1035*5e7646d2SAndroid Build Coastguard Worker 	    * Backend does not exist, stop printer...
1036*5e7646d2SAndroid Build Coastguard Worker 	    */
1037*5e7646d2SAndroid Build Coastguard Worker 
1038*5e7646d2SAndroid Build Coastguard Worker 	    p->state = IPP_PRINTER_STOPPED;
1039*5e7646d2SAndroid Build Coastguard Worker 	    snprintf(p->state_message, sizeof(p->state_message), "Backend %s does not exist!", line);
1040*5e7646d2SAndroid Build Coastguard Worker 	  }
1041*5e7646d2SAndroid Build Coastguard Worker         }
1042*5e7646d2SAndroid Build Coastguard Worker 
1043*5e7646d2SAndroid Build Coastguard Worker         p = NULL;
1044*5e7646d2SAndroid Build Coastguard Worker       }
1045*5e7646d2SAndroid Build Coastguard Worker       else
1046*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR,
1047*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1048*5e7646d2SAndroid Build Coastguard Worker     }
1049*5e7646d2SAndroid Build Coastguard Worker     else if (!p)
1050*5e7646d2SAndroid Build Coastguard Worker     {
1051*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR,
1052*5e7646d2SAndroid Build Coastguard Worker                       "Syntax error on line %d of printers.conf.", linenum);
1053*5e7646d2SAndroid Build Coastguard Worker     }
1054*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "PrinterId"))
1055*5e7646d2SAndroid Build Coastguard Worker     {
1056*5e7646d2SAndroid Build Coastguard Worker       if (value && (i = atoi(value)) > 0)
1057*5e7646d2SAndroid Build Coastguard Worker         p->printer_id = i;
1058*5e7646d2SAndroid Build Coastguard Worker       else
1059*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR, "Bad PrinterId on line %d of printers.conf.", linenum);
1060*5e7646d2SAndroid Build Coastguard Worker     }
1061*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "UUID"))
1062*5e7646d2SAndroid Build Coastguard Worker     {
1063*5e7646d2SAndroid Build Coastguard Worker       if (value && !strncmp(value, "urn:uuid:", 9))
1064*5e7646d2SAndroid Build Coastguard Worker         cupsdSetString(&(p->uuid), value);
1065*5e7646d2SAndroid Build Coastguard Worker       else
1066*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR,
1067*5e7646d2SAndroid Build Coastguard Worker 	                "Bad UUID on line %d of printers.conf.", linenum);
1068*5e7646d2SAndroid Build Coastguard Worker     }
1069*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "AuthInfoRequired"))
1070*5e7646d2SAndroid Build Coastguard Worker     {
1071*5e7646d2SAndroid Build Coastguard Worker       if (!cupsdSetAuthInfoRequired(p, value, NULL))
1072*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1073*5e7646d2SAndroid Build Coastguard Worker 			"Bad AuthInfoRequired on line %d of printers.conf.",
1074*5e7646d2SAndroid Build Coastguard Worker 			linenum);
1075*5e7646d2SAndroid Build Coastguard Worker     }
1076*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Info"))
1077*5e7646d2SAndroid Build Coastguard Worker     {
1078*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->info, value ? value : "");
1079*5e7646d2SAndroid Build Coastguard Worker     }
1080*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "MakeModel"))
1081*5e7646d2SAndroid Build Coastguard Worker     {
1082*5e7646d2SAndroid Build Coastguard Worker       if (value)
1083*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetString(&p->make_model, value);
1084*5e7646d2SAndroid Build Coastguard Worker     }
1085*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Location"))
1086*5e7646d2SAndroid Build Coastguard Worker     {
1087*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->location, value ? value : "");
1088*5e7646d2SAndroid Build Coastguard Worker     }
1089*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "GeoLocation"))
1090*5e7646d2SAndroid Build Coastguard Worker     {
1091*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->geo_location, value ? value : "");
1092*5e7646d2SAndroid Build Coastguard Worker     }
1093*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Organization"))
1094*5e7646d2SAndroid Build Coastguard Worker     {
1095*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->organization, value ? value : "");
1096*5e7646d2SAndroid Build Coastguard Worker     }
1097*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "OrganizationalUnit"))
1098*5e7646d2SAndroid Build Coastguard Worker     {
1099*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->organizational_unit, value ? value : "");
1100*5e7646d2SAndroid Build Coastguard Worker     }
1101*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "DeviceURI"))
1102*5e7646d2SAndroid Build Coastguard Worker     {
1103*5e7646d2SAndroid Build Coastguard Worker       if (value)
1104*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetDeviceURI(p, value);
1105*5e7646d2SAndroid Build Coastguard Worker       else
1106*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1107*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1108*5e7646d2SAndroid Build Coastguard Worker     }
1109*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Option") && value)
1110*5e7646d2SAndroid Build Coastguard Worker     {
1111*5e7646d2SAndroid Build Coastguard Worker      /*
1112*5e7646d2SAndroid Build Coastguard Worker       * Option name value
1113*5e7646d2SAndroid Build Coastguard Worker       */
1114*5e7646d2SAndroid Build Coastguard Worker 
1115*5e7646d2SAndroid Build Coastguard Worker       for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
1116*5e7646d2SAndroid Build Coastguard Worker 
1117*5e7646d2SAndroid Build Coastguard Worker       if (!*valueptr)
1118*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR,
1119*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1120*5e7646d2SAndroid Build Coastguard Worker       else
1121*5e7646d2SAndroid Build Coastguard Worker       {
1122*5e7646d2SAndroid Build Coastguard Worker         for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
1123*5e7646d2SAndroid Build Coastguard Worker 
1124*5e7646d2SAndroid Build Coastguard Worker         p->num_options = cupsAddOption(value, valueptr, p->num_options,
1125*5e7646d2SAndroid Build Coastguard Worker 	                               &(p->options));
1126*5e7646d2SAndroid Build Coastguard Worker       }
1127*5e7646d2SAndroid Build Coastguard Worker     }
1128*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "PortMonitor"))
1129*5e7646d2SAndroid Build Coastguard Worker     {
1130*5e7646d2SAndroid Build Coastguard Worker       if (value && strcmp(value, "none"))
1131*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetString(&p->port_monitor, value);
1132*5e7646d2SAndroid Build Coastguard Worker       else if (value)
1133*5e7646d2SAndroid Build Coastguard Worker         cupsdClearString(&p->port_monitor);
1134*5e7646d2SAndroid Build Coastguard Worker       else
1135*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1136*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1137*5e7646d2SAndroid Build Coastguard Worker     }
1138*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Reason"))
1139*5e7646d2SAndroid Build Coastguard Worker     {
1140*5e7646d2SAndroid Build Coastguard Worker       if (value &&
1141*5e7646d2SAndroid Build Coastguard Worker           strcmp(value, "connecting-to-device") &&
1142*5e7646d2SAndroid Build Coastguard Worker           strcmp(value, "cups-insecure-filter-warning") &&
1143*5e7646d2SAndroid Build Coastguard Worker           strcmp(value, "cups-missing-filter-warning"))
1144*5e7646d2SAndroid Build Coastguard Worker       {
1145*5e7646d2SAndroid Build Coastguard Worker         for (i = 0 ; i < p->num_reasons; i ++)
1146*5e7646d2SAndroid Build Coastguard Worker 	  if (!strcmp(value, p->reasons[i]))
1147*5e7646d2SAndroid Build Coastguard Worker 	    break;
1148*5e7646d2SAndroid Build Coastguard Worker 
1149*5e7646d2SAndroid Build Coastguard Worker         if (i >= p->num_reasons &&
1150*5e7646d2SAndroid Build Coastguard Worker 	    p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
1151*5e7646d2SAndroid Build Coastguard Worker 	{
1152*5e7646d2SAndroid Build Coastguard Worker 	  p->reasons[p->num_reasons] = _cupsStrAlloc(value);
1153*5e7646d2SAndroid Build Coastguard Worker 	  p->num_reasons ++;
1154*5e7646d2SAndroid Build Coastguard Worker 	}
1155*5e7646d2SAndroid Build Coastguard Worker       }
1156*5e7646d2SAndroid Build Coastguard Worker       else
1157*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1158*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1159*5e7646d2SAndroid Build Coastguard Worker     }
1160*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "State"))
1161*5e7646d2SAndroid Build Coastguard Worker     {
1162*5e7646d2SAndroid Build Coastguard Worker      /*
1163*5e7646d2SAndroid Build Coastguard Worker       * Set the initial queue state...
1164*5e7646d2SAndroid Build Coastguard Worker       */
1165*5e7646d2SAndroid Build Coastguard Worker 
1166*5e7646d2SAndroid Build Coastguard Worker       if (value && !_cups_strcasecmp(value, "idle"))
1167*5e7646d2SAndroid Build Coastguard Worker         p->state = IPP_PRINTER_IDLE;
1168*5e7646d2SAndroid Build Coastguard Worker       else if (value && !_cups_strcasecmp(value, "stopped"))
1169*5e7646d2SAndroid Build Coastguard Worker       {
1170*5e7646d2SAndroid Build Coastguard Worker         p->state = IPP_PRINTER_STOPPED;
1171*5e7646d2SAndroid Build Coastguard Worker 
1172*5e7646d2SAndroid Build Coastguard Worker         for (i = 0 ; i < p->num_reasons; i ++)
1173*5e7646d2SAndroid Build Coastguard Worker 	  if (!strcmp("paused", p->reasons[i]))
1174*5e7646d2SAndroid Build Coastguard Worker 	    break;
1175*5e7646d2SAndroid Build Coastguard Worker 
1176*5e7646d2SAndroid Build Coastguard Worker         if (i >= p->num_reasons &&
1177*5e7646d2SAndroid Build Coastguard Worker 	    p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
1178*5e7646d2SAndroid Build Coastguard Worker 	{
1179*5e7646d2SAndroid Build Coastguard Worker 	  p->reasons[p->num_reasons] = _cupsStrAlloc("paused");
1180*5e7646d2SAndroid Build Coastguard Worker 	  p->num_reasons ++;
1181*5e7646d2SAndroid Build Coastguard Worker 	}
1182*5e7646d2SAndroid Build Coastguard Worker       }
1183*5e7646d2SAndroid Build Coastguard Worker       else
1184*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1185*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1186*5e7646d2SAndroid Build Coastguard Worker     }
1187*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "StateMessage"))
1188*5e7646d2SAndroid Build Coastguard Worker     {
1189*5e7646d2SAndroid Build Coastguard Worker      /*
1190*5e7646d2SAndroid Build Coastguard Worker       * Set the initial queue state message...
1191*5e7646d2SAndroid Build Coastguard Worker       */
1192*5e7646d2SAndroid Build Coastguard Worker 
1193*5e7646d2SAndroid Build Coastguard Worker       if (value)
1194*5e7646d2SAndroid Build Coastguard Worker 	strlcpy(p->state_message, value, sizeof(p->state_message));
1195*5e7646d2SAndroid Build Coastguard Worker     }
1196*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "StateTime"))
1197*5e7646d2SAndroid Build Coastguard Worker     {
1198*5e7646d2SAndroid Build Coastguard Worker      /*
1199*5e7646d2SAndroid Build Coastguard Worker       * Set the state time...
1200*5e7646d2SAndroid Build Coastguard Worker       */
1201*5e7646d2SAndroid Build Coastguard Worker 
1202*5e7646d2SAndroid Build Coastguard Worker       if (value)
1203*5e7646d2SAndroid Build Coastguard Worker         p->state_time = atoi(value);
1204*5e7646d2SAndroid Build Coastguard Worker     }
1205*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "ConfigTime"))
1206*5e7646d2SAndroid Build Coastguard Worker     {
1207*5e7646d2SAndroid Build Coastguard Worker      /*
1208*5e7646d2SAndroid Build Coastguard Worker       * Set the config time...
1209*5e7646d2SAndroid Build Coastguard Worker       */
1210*5e7646d2SAndroid Build Coastguard Worker 
1211*5e7646d2SAndroid Build Coastguard Worker       if (value)
1212*5e7646d2SAndroid Build Coastguard Worker         p->config_time = atoi(value);
1213*5e7646d2SAndroid Build Coastguard Worker     }
1214*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Accepting"))
1215*5e7646d2SAndroid Build Coastguard Worker     {
1216*5e7646d2SAndroid Build Coastguard Worker      /*
1217*5e7646d2SAndroid Build Coastguard Worker       * Set the initial accepting state...
1218*5e7646d2SAndroid Build Coastguard Worker       */
1219*5e7646d2SAndroid Build Coastguard Worker 
1220*5e7646d2SAndroid Build Coastguard Worker       if (value &&
1221*5e7646d2SAndroid Build Coastguard Worker           (!_cups_strcasecmp(value, "yes") ||
1222*5e7646d2SAndroid Build Coastguard Worker            !_cups_strcasecmp(value, "on") ||
1223*5e7646d2SAndroid Build Coastguard Worker            !_cups_strcasecmp(value, "true")))
1224*5e7646d2SAndroid Build Coastguard Worker         p->accepting = 1;
1225*5e7646d2SAndroid Build Coastguard Worker       else if (value &&
1226*5e7646d2SAndroid Build Coastguard Worker                (!_cups_strcasecmp(value, "no") ||
1227*5e7646d2SAndroid Build Coastguard Worker         	!_cups_strcasecmp(value, "off") ||
1228*5e7646d2SAndroid Build Coastguard Worker         	!_cups_strcasecmp(value, "false")))
1229*5e7646d2SAndroid Build Coastguard Worker         p->accepting = 0;
1230*5e7646d2SAndroid Build Coastguard Worker       else
1231*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1232*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1233*5e7646d2SAndroid Build Coastguard Worker     }
1234*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Type"))
1235*5e7646d2SAndroid Build Coastguard Worker     {
1236*5e7646d2SAndroid Build Coastguard Worker       if (value)
1237*5e7646d2SAndroid Build Coastguard Worker         p->type = (cups_ptype_t)atoi(value);
1238*5e7646d2SAndroid Build Coastguard Worker       else
1239*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1240*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1241*5e7646d2SAndroid Build Coastguard Worker     }
1242*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Shared"))
1243*5e7646d2SAndroid Build Coastguard Worker     {
1244*5e7646d2SAndroid Build Coastguard Worker      /*
1245*5e7646d2SAndroid Build Coastguard Worker       * Set the initial shared state...
1246*5e7646d2SAndroid Build Coastguard Worker       */
1247*5e7646d2SAndroid Build Coastguard Worker 
1248*5e7646d2SAndroid Build Coastguard Worker       if (value &&
1249*5e7646d2SAndroid Build Coastguard Worker           (!_cups_strcasecmp(value, "yes") ||
1250*5e7646d2SAndroid Build Coastguard Worker            !_cups_strcasecmp(value, "on") ||
1251*5e7646d2SAndroid Build Coastguard Worker            !_cups_strcasecmp(value, "true")))
1252*5e7646d2SAndroid Build Coastguard Worker         p->shared = 1;
1253*5e7646d2SAndroid Build Coastguard Worker       else if (value &&
1254*5e7646d2SAndroid Build Coastguard Worker                (!_cups_strcasecmp(value, "no") ||
1255*5e7646d2SAndroid Build Coastguard Worker         	!_cups_strcasecmp(value, "off") ||
1256*5e7646d2SAndroid Build Coastguard Worker         	!_cups_strcasecmp(value, "false")))
1257*5e7646d2SAndroid Build Coastguard Worker         p->shared = 0;
1258*5e7646d2SAndroid Build Coastguard Worker       else
1259*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1260*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1261*5e7646d2SAndroid Build Coastguard Worker     }
1262*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "JobSheets"))
1263*5e7646d2SAndroid Build Coastguard Worker     {
1264*5e7646d2SAndroid Build Coastguard Worker      /*
1265*5e7646d2SAndroid Build Coastguard Worker       * Set the initial job sheets...
1266*5e7646d2SAndroid Build Coastguard Worker       */
1267*5e7646d2SAndroid Build Coastguard Worker 
1268*5e7646d2SAndroid Build Coastguard Worker       if (value)
1269*5e7646d2SAndroid Build Coastguard Worker       {
1270*5e7646d2SAndroid Build Coastguard Worker 	for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
1271*5e7646d2SAndroid Build Coastguard Worker 
1272*5e7646d2SAndroid Build Coastguard Worker 	if (*valueptr)
1273*5e7646d2SAndroid Build Coastguard Worker           *valueptr++ = '\0';
1274*5e7646d2SAndroid Build Coastguard Worker 
1275*5e7646d2SAndroid Build Coastguard Worker 	cupsdSetString(&p->job_sheets[0], value);
1276*5e7646d2SAndroid Build Coastguard Worker 
1277*5e7646d2SAndroid Build Coastguard Worker 	while (isspace(*valueptr & 255))
1278*5e7646d2SAndroid Build Coastguard Worker           valueptr ++;
1279*5e7646d2SAndroid Build Coastguard Worker 
1280*5e7646d2SAndroid Build Coastguard Worker 	if (*valueptr)
1281*5e7646d2SAndroid Build Coastguard Worker 	{
1282*5e7646d2SAndroid Build Coastguard Worker           for (value = valueptr; *valueptr && !isspace(*valueptr & 255); valueptr ++);
1283*5e7646d2SAndroid Build Coastguard Worker 
1284*5e7646d2SAndroid Build Coastguard Worker 	  if (*valueptr)
1285*5e7646d2SAndroid Build Coastguard Worker             *valueptr = '\0';
1286*5e7646d2SAndroid Build Coastguard Worker 
1287*5e7646d2SAndroid Build Coastguard Worker 	  cupsdSetString(&p->job_sheets[1], value);
1288*5e7646d2SAndroid Build Coastguard Worker 	}
1289*5e7646d2SAndroid Build Coastguard Worker       }
1290*5e7646d2SAndroid Build Coastguard Worker       else
1291*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1292*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1293*5e7646d2SAndroid Build Coastguard Worker     }
1294*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "AllowUser"))
1295*5e7646d2SAndroid Build Coastguard Worker     {
1296*5e7646d2SAndroid Build Coastguard Worker       if (value)
1297*5e7646d2SAndroid Build Coastguard Worker       {
1298*5e7646d2SAndroid Build Coastguard Worker         p->deny_users = 0;
1299*5e7646d2SAndroid Build Coastguard Worker         cupsdAddString(&(p->users), value);
1300*5e7646d2SAndroid Build Coastguard Worker       }
1301*5e7646d2SAndroid Build Coastguard Worker       else
1302*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1303*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1304*5e7646d2SAndroid Build Coastguard Worker     }
1305*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "DenyUser"))
1306*5e7646d2SAndroid Build Coastguard Worker     {
1307*5e7646d2SAndroid Build Coastguard Worker       if (value)
1308*5e7646d2SAndroid Build Coastguard Worker       {
1309*5e7646d2SAndroid Build Coastguard Worker         p->deny_users = 1;
1310*5e7646d2SAndroid Build Coastguard Worker         cupsdAddString(&(p->users), value);
1311*5e7646d2SAndroid Build Coastguard Worker       }
1312*5e7646d2SAndroid Build Coastguard Worker       else
1313*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1314*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1315*5e7646d2SAndroid Build Coastguard Worker     }
1316*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "QuotaPeriod"))
1317*5e7646d2SAndroid Build Coastguard Worker     {
1318*5e7646d2SAndroid Build Coastguard Worker       if (value)
1319*5e7646d2SAndroid Build Coastguard Worker         p->quota_period = atoi(value);
1320*5e7646d2SAndroid Build Coastguard Worker       else
1321*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1322*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1323*5e7646d2SAndroid Build Coastguard Worker     }
1324*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "PageLimit"))
1325*5e7646d2SAndroid Build Coastguard Worker     {
1326*5e7646d2SAndroid Build Coastguard Worker       if (value)
1327*5e7646d2SAndroid Build Coastguard Worker         p->page_limit = atoi(value);
1328*5e7646d2SAndroid Build Coastguard Worker       else
1329*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1330*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1331*5e7646d2SAndroid Build Coastguard Worker     }
1332*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "KLimit"))
1333*5e7646d2SAndroid Build Coastguard Worker     {
1334*5e7646d2SAndroid Build Coastguard Worker       if (value)
1335*5e7646d2SAndroid Build Coastguard Worker         p->k_limit = atoi(value);
1336*5e7646d2SAndroid Build Coastguard Worker       else
1337*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1338*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1339*5e7646d2SAndroid Build Coastguard Worker     }
1340*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "OpPolicy"))
1341*5e7646d2SAndroid Build Coastguard Worker     {
1342*5e7646d2SAndroid Build Coastguard Worker       if (value)
1343*5e7646d2SAndroid Build Coastguard Worker       {
1344*5e7646d2SAndroid Build Coastguard Worker         cupsd_policy_t *pol;		/* Policy */
1345*5e7646d2SAndroid Build Coastguard Worker 
1346*5e7646d2SAndroid Build Coastguard Worker 
1347*5e7646d2SAndroid Build Coastguard Worker         if ((pol = cupsdFindPolicy(value)) != NULL)
1348*5e7646d2SAndroid Build Coastguard Worker 	{
1349*5e7646d2SAndroid Build Coastguard Worker           cupsdSetString(&p->op_policy, value);
1350*5e7646d2SAndroid Build Coastguard Worker 	  p->op_policy_ptr = pol;
1351*5e7646d2SAndroid Build Coastguard Worker 	}
1352*5e7646d2SAndroid Build Coastguard Worker 	else
1353*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_ERROR,
1354*5e7646d2SAndroid Build Coastguard Worker 	                  "Bad policy \"%s\" on line %d of printers.conf",
1355*5e7646d2SAndroid Build Coastguard Worker 			  value, linenum);
1356*5e7646d2SAndroid Build Coastguard Worker       }
1357*5e7646d2SAndroid Build Coastguard Worker       else
1358*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR,
1359*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1360*5e7646d2SAndroid Build Coastguard Worker     }
1361*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "ErrorPolicy"))
1362*5e7646d2SAndroid Build Coastguard Worker     {
1363*5e7646d2SAndroid Build Coastguard Worker       if (value)
1364*5e7646d2SAndroid Build Coastguard Worker       {
1365*5e7646d2SAndroid Build Coastguard Worker 	if (strcmp(value, "retry-current-job") &&
1366*5e7646d2SAndroid Build Coastguard Worker 	    strcmp(value, "abort-job") &&
1367*5e7646d2SAndroid Build Coastguard Worker 	    strcmp(value, "retry-job") &&
1368*5e7646d2SAndroid Build Coastguard Worker 	    strcmp(value, "stop-printer"))
1369*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_ALERT, "Invalid ErrorPolicy \"%s\" on line %d or printers.conf.", ErrorPolicy, linenum);
1370*5e7646d2SAndroid Build Coastguard Worker 	else
1371*5e7646d2SAndroid Build Coastguard Worker 	  cupsdSetString(&p->error_policy, value);
1372*5e7646d2SAndroid Build Coastguard Worker       }
1373*5e7646d2SAndroid Build Coastguard Worker       else
1374*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of printers.conf.", linenum);
1375*5e7646d2SAndroid Build Coastguard Worker     }
1376*5e7646d2SAndroid Build Coastguard Worker     else if (!_cups_strcasecmp(line, "Attribute") && value)
1377*5e7646d2SAndroid Build Coastguard Worker     {
1378*5e7646d2SAndroid Build Coastguard Worker       for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++);
1379*5e7646d2SAndroid Build Coastguard Worker 
1380*5e7646d2SAndroid Build Coastguard Worker       if (!*valueptr)
1381*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_ERROR,
1382*5e7646d2SAndroid Build Coastguard Worker 	                "Syntax error on line %d of printers.conf.", linenum);
1383*5e7646d2SAndroid Build Coastguard Worker       else
1384*5e7646d2SAndroid Build Coastguard Worker       {
1385*5e7646d2SAndroid Build Coastguard Worker         for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0');
1386*5e7646d2SAndroid Build Coastguard Worker 
1387*5e7646d2SAndroid Build Coastguard Worker         if (!p->attrs)
1388*5e7646d2SAndroid Build Coastguard Worker 	  cupsdSetPrinterAttrs(p);
1389*5e7646d2SAndroid Build Coastguard Worker 
1390*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(value, "marker-change-time"))
1391*5e7646d2SAndroid Build Coastguard Worker 	  p->marker_time = atoi(valueptr);
1392*5e7646d2SAndroid Build Coastguard Worker 	else
1393*5e7646d2SAndroid Build Coastguard Worker           cupsdSetPrinterAttr(p, value, valueptr);
1394*5e7646d2SAndroid Build Coastguard Worker       }
1395*5e7646d2SAndroid Build Coastguard Worker     }
1396*5e7646d2SAndroid Build Coastguard Worker     else if (_cups_strcasecmp(line, "Filter") &&
1397*5e7646d2SAndroid Build Coastguard Worker              _cups_strcasecmp(line, "Prefilter") &&
1398*5e7646d2SAndroid Build Coastguard Worker              _cups_strcasecmp(line, "Product"))
1399*5e7646d2SAndroid Build Coastguard Worker     {
1400*5e7646d2SAndroid Build Coastguard Worker      /*
1401*5e7646d2SAndroid Build Coastguard Worker       * Something else we don't understand (and that wasn't used in a prior
1402*5e7646d2SAndroid Build Coastguard Worker       * release of CUPS...
1403*5e7646d2SAndroid Build Coastguard Worker       */
1404*5e7646d2SAndroid Build Coastguard Worker 
1405*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR,
1406*5e7646d2SAndroid Build Coastguard Worker                       "Unknown configuration directive %s on line %d of "
1407*5e7646d2SAndroid Build Coastguard Worker 		      "printers.conf.", line, linenum);
1408*5e7646d2SAndroid Build Coastguard Worker     }
1409*5e7646d2SAndroid Build Coastguard Worker   }
1410*5e7646d2SAndroid Build Coastguard Worker 
1411*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
1412*5e7646d2SAndroid Build Coastguard Worker }
1413*5e7646d2SAndroid Build Coastguard Worker 
1414*5e7646d2SAndroid Build Coastguard Worker 
1415*5e7646d2SAndroid Build Coastguard Worker /*
1416*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdRenamePrinter()' - Rename a printer.
1417*5e7646d2SAndroid Build Coastguard Worker  */
1418*5e7646d2SAndroid Build Coastguard Worker 
1419*5e7646d2SAndroid Build Coastguard Worker void
cupsdRenamePrinter(cupsd_printer_t * p,const char * name)1420*5e7646d2SAndroid Build Coastguard Worker cupsdRenamePrinter(
1421*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
1422*5e7646d2SAndroid Build Coastguard Worker     const char      *name)		/* I - New name */
1423*5e7646d2SAndroid Build Coastguard Worker {
1424*5e7646d2SAndroid Build Coastguard Worker  /*
1425*5e7646d2SAndroid Build Coastguard Worker   * Remove the printer from the array(s) first...
1426*5e7646d2SAndroid Build Coastguard Worker   */
1427*5e7646d2SAndroid Build Coastguard Worker 
1428*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
1429*5e7646d2SAndroid Build Coastguard Worker                   "cupsdRenamePrinter: Removing %s from Printers", p->name);
1430*5e7646d2SAndroid Build Coastguard Worker   cupsArrayRemove(Printers, p);
1431*5e7646d2SAndroid Build Coastguard Worker 
1432*5e7646d2SAndroid Build Coastguard Worker  /*
1433*5e7646d2SAndroid Build Coastguard Worker   * Rename the printer type...
1434*5e7646d2SAndroid Build Coastguard Worker   */
1435*5e7646d2SAndroid Build Coastguard Worker 
1436*5e7646d2SAndroid Build Coastguard Worker   mimeDeleteType(MimeDatabase, p->filetype);
1437*5e7646d2SAndroid Build Coastguard Worker   p->filetype = mimeAddType(MimeDatabase, "printer", name);
1438*5e7646d2SAndroid Build Coastguard Worker 
1439*5e7646d2SAndroid Build Coastguard Worker   if (p->prefiltertype)
1440*5e7646d2SAndroid Build Coastguard Worker   {
1441*5e7646d2SAndroid Build Coastguard Worker     mimeDeleteType(MimeDatabase, p->prefiltertype);
1442*5e7646d2SAndroid Build Coastguard Worker     p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", name);
1443*5e7646d2SAndroid Build Coastguard Worker   }
1444*5e7646d2SAndroid Build Coastguard Worker 
1445*5e7646d2SAndroid Build Coastguard Worker  /*
1446*5e7646d2SAndroid Build Coastguard Worker   * Rename the printer...
1447*5e7646d2SAndroid Build Coastguard Worker   */
1448*5e7646d2SAndroid Build Coastguard Worker 
1449*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&p->name, name);
1450*5e7646d2SAndroid Build Coastguard Worker 
1451*5e7646d2SAndroid Build Coastguard Worker  /*
1452*5e7646d2SAndroid Build Coastguard Worker   * Reset printer attributes...
1453*5e7646d2SAndroid Build Coastguard Worker   */
1454*5e7646d2SAndroid Build Coastguard Worker 
1455*5e7646d2SAndroid Build Coastguard Worker   cupsdSetPrinterAttrs(p);
1456*5e7646d2SAndroid Build Coastguard Worker 
1457*5e7646d2SAndroid Build Coastguard Worker  /*
1458*5e7646d2SAndroid Build Coastguard Worker   * Add the printer back to the printer array(s)...
1459*5e7646d2SAndroid Build Coastguard Worker   */
1460*5e7646d2SAndroid Build Coastguard Worker 
1461*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
1462*5e7646d2SAndroid Build Coastguard Worker                   "cupsdRenamePrinter: Adding %s to Printers", p->name);
1463*5e7646d2SAndroid Build Coastguard Worker   cupsArrayAdd(Printers, p);
1464*5e7646d2SAndroid Build Coastguard Worker }
1465*5e7646d2SAndroid Build Coastguard Worker 
1466*5e7646d2SAndroid Build Coastguard Worker 
1467*5e7646d2SAndroid Build Coastguard Worker /*
1468*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdSaveAllPrinters()' - Save all printer definitions to the printers.conf
1469*5e7646d2SAndroid Build Coastguard Worker  *                            file.
1470*5e7646d2SAndroid Build Coastguard Worker  */
1471*5e7646d2SAndroid Build Coastguard Worker 
1472*5e7646d2SAndroid Build Coastguard Worker void
cupsdSaveAllPrinters(void)1473*5e7646d2SAndroid Build Coastguard Worker cupsdSaveAllPrinters(void)
1474*5e7646d2SAndroid Build Coastguard Worker {
1475*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
1476*5e7646d2SAndroid Build Coastguard Worker   cups_file_t		*fp;		/* printers.conf file */
1477*5e7646d2SAndroid Build Coastguard Worker   char			filename[1024],	/* printers.conf filename */
1478*5e7646d2SAndroid Build Coastguard Worker 			value[2048],	/* Value string */
1479*5e7646d2SAndroid Build Coastguard Worker 			*ptr,		/* Pointer into value */
1480*5e7646d2SAndroid Build Coastguard Worker 			*name;		/* Current user/group name */
1481*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*printer;	/* Current printer class */
1482*5e7646d2SAndroid Build Coastguard Worker   cups_option_t		*option;	/* Current option */
1483*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*marker;	/* Current marker attribute */
1484*5e7646d2SAndroid Build Coastguard Worker 
1485*5e7646d2SAndroid Build Coastguard Worker 
1486*5e7646d2SAndroid Build Coastguard Worker  /*
1487*5e7646d2SAndroid Build Coastguard Worker   * Create the printers.conf file...
1488*5e7646d2SAndroid Build Coastguard Worker   */
1489*5e7646d2SAndroid Build Coastguard Worker 
1490*5e7646d2SAndroid Build Coastguard Worker   snprintf(filename, sizeof(filename), "%s/printers.conf", ServerRoot);
1491*5e7646d2SAndroid Build Coastguard Worker 
1492*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsdCreateConfFile(filename, ConfigFilePerm & 0600)) == NULL)
1493*5e7646d2SAndroid Build Coastguard Worker     return;
1494*5e7646d2SAndroid Build Coastguard Worker 
1495*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_INFO, "Saving printers.conf...");
1496*5e7646d2SAndroid Build Coastguard Worker 
1497*5e7646d2SAndroid Build Coastguard Worker  /*
1498*5e7646d2SAndroid Build Coastguard Worker   * Write a small header to the file...
1499*5e7646d2SAndroid Build Coastguard Worker   */
1500*5e7646d2SAndroid Build Coastguard Worker 
1501*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(fp, "# Printer configuration file for " CUPS_SVERSION "\n");
1502*5e7646d2SAndroid Build Coastguard Worker   cupsFilePrintf(fp, "# Written by cupsd\n");
1503*5e7646d2SAndroid Build Coastguard Worker   cupsFilePuts(fp, "# DO NOT EDIT THIS FILE WHEN CUPSD IS RUNNING\n");
1504*5e7646d2SAndroid Build Coastguard Worker 
1505*5e7646d2SAndroid Build Coastguard Worker   cupsFilePrintf(fp, "NextPrinterId %d\n", NextPrinterId);
1506*5e7646d2SAndroid Build Coastguard Worker 
1507*5e7646d2SAndroid Build Coastguard Worker  /*
1508*5e7646d2SAndroid Build Coastguard Worker   * Write each local printer known to the system...
1509*5e7646d2SAndroid Build Coastguard Worker   */
1510*5e7646d2SAndroid Build Coastguard Worker 
1511*5e7646d2SAndroid Build Coastguard Worker   for (printer = (cupsd_printer_t *)cupsArrayFirst(Printers);
1512*5e7646d2SAndroid Build Coastguard Worker        printer;
1513*5e7646d2SAndroid Build Coastguard Worker        printer = (cupsd_printer_t *)cupsArrayNext(Printers))
1514*5e7646d2SAndroid Build Coastguard Worker   {
1515*5e7646d2SAndroid Build Coastguard Worker    /*
1516*5e7646d2SAndroid Build Coastguard Worker     * Skip printer classes and temporary queues...
1517*5e7646d2SAndroid Build Coastguard Worker     */
1518*5e7646d2SAndroid Build Coastguard Worker 
1519*5e7646d2SAndroid Build Coastguard Worker     if ((printer->type & CUPS_PRINTER_CLASS) || printer->temporary)
1520*5e7646d2SAndroid Build Coastguard Worker       continue;
1521*5e7646d2SAndroid Build Coastguard Worker 
1522*5e7646d2SAndroid Build Coastguard Worker    /*
1523*5e7646d2SAndroid Build Coastguard Worker     * Write printers as needed...
1524*5e7646d2SAndroid Build Coastguard Worker     */
1525*5e7646d2SAndroid Build Coastguard Worker 
1526*5e7646d2SAndroid Build Coastguard Worker     if (printer == DefaultPrinter)
1527*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "<DefaultPrinter %s>\n", printer->name);
1528*5e7646d2SAndroid Build Coastguard Worker     else
1529*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "<Printer %s>\n", printer->name);
1530*5e7646d2SAndroid Build Coastguard Worker 
1531*5e7646d2SAndroid Build Coastguard Worker     if (printer->printer_id)
1532*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "PrinterId %d\n", printer->printer_id);
1533*5e7646d2SAndroid Build Coastguard Worker 
1534*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "UUID %s\n", printer->uuid);
1535*5e7646d2SAndroid Build Coastguard Worker 
1536*5e7646d2SAndroid Build Coastguard Worker     if (printer->num_auth_info_required > 0)
1537*5e7646d2SAndroid Build Coastguard Worker     {
1538*5e7646d2SAndroid Build Coastguard Worker       switch (printer->num_auth_info_required)
1539*5e7646d2SAndroid Build Coastguard Worker       {
1540*5e7646d2SAndroid Build Coastguard Worker         case 1 :
1541*5e7646d2SAndroid Build Coastguard Worker             strlcpy(value, printer->auth_info_required[0], sizeof(value));
1542*5e7646d2SAndroid Build Coastguard Worker 	    break;
1543*5e7646d2SAndroid Build Coastguard Worker 
1544*5e7646d2SAndroid Build Coastguard Worker         case 2 :
1545*5e7646d2SAndroid Build Coastguard Worker             snprintf(value, sizeof(value), "%s,%s",
1546*5e7646d2SAndroid Build Coastguard Worker 	             printer->auth_info_required[0],
1547*5e7646d2SAndroid Build Coastguard Worker 		     printer->auth_info_required[1]);
1548*5e7646d2SAndroid Build Coastguard Worker 	    break;
1549*5e7646d2SAndroid Build Coastguard Worker 
1550*5e7646d2SAndroid Build Coastguard Worker         case 3 :
1551*5e7646d2SAndroid Build Coastguard Worker 	default :
1552*5e7646d2SAndroid Build Coastguard Worker             snprintf(value, sizeof(value), "%s,%s,%s",
1553*5e7646d2SAndroid Build Coastguard Worker 	             printer->auth_info_required[0],
1554*5e7646d2SAndroid Build Coastguard Worker 		     printer->auth_info_required[1],
1555*5e7646d2SAndroid Build Coastguard Worker 		     printer->auth_info_required[2]);
1556*5e7646d2SAndroid Build Coastguard Worker 	    break;
1557*5e7646d2SAndroid Build Coastguard Worker       }
1558*5e7646d2SAndroid Build Coastguard Worker 
1559*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "AuthInfoRequired", value);
1560*5e7646d2SAndroid Build Coastguard Worker     }
1561*5e7646d2SAndroid Build Coastguard Worker 
1562*5e7646d2SAndroid Build Coastguard Worker     if (printer->info)
1563*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Info", printer->info);
1564*5e7646d2SAndroid Build Coastguard Worker 
1565*5e7646d2SAndroid Build Coastguard Worker     if (printer->location)
1566*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Location", printer->location);
1567*5e7646d2SAndroid Build Coastguard Worker 
1568*5e7646d2SAndroid Build Coastguard Worker     if (printer->geo_location)
1569*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "GeoLocation", printer->geo_location);
1570*5e7646d2SAndroid Build Coastguard Worker 
1571*5e7646d2SAndroid Build Coastguard Worker     if (printer->make_model)
1572*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "MakeModel", printer->make_model);
1573*5e7646d2SAndroid Build Coastguard Worker 
1574*5e7646d2SAndroid Build Coastguard Worker     if (printer->organization)
1575*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Organization", printer->organization);
1576*5e7646d2SAndroid Build Coastguard Worker 
1577*5e7646d2SAndroid Build Coastguard Worker     if (printer->organizational_unit)
1578*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "OrganizationalUnit", printer->organizational_unit);
1579*5e7646d2SAndroid Build Coastguard Worker 
1580*5e7646d2SAndroid Build Coastguard Worker     cupsFilePutConf(fp, "DeviceURI", printer->device_uri);
1581*5e7646d2SAndroid Build Coastguard Worker 
1582*5e7646d2SAndroid Build Coastguard Worker     if (printer->port_monitor)
1583*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "PortMonitor", printer->port_monitor);
1584*5e7646d2SAndroid Build Coastguard Worker 
1585*5e7646d2SAndroid Build Coastguard Worker     if (printer->state == IPP_PRINTER_STOPPED)
1586*5e7646d2SAndroid Build Coastguard Worker     {
1587*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "State Stopped\n");
1588*5e7646d2SAndroid Build Coastguard Worker 
1589*5e7646d2SAndroid Build Coastguard Worker       if (printer->state_message[0])
1590*5e7646d2SAndroid Build Coastguard Worker         cupsFilePutConf(fp, "StateMessage", printer->state_message);
1591*5e7646d2SAndroid Build Coastguard Worker     }
1592*5e7646d2SAndroid Build Coastguard Worker     else
1593*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "State Idle\n");
1594*5e7646d2SAndroid Build Coastguard Worker 
1595*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "StateTime %d\n", (int)printer->state_time);
1596*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "ConfigTime %d\n", (int)printer->config_time);
1597*5e7646d2SAndroid Build Coastguard Worker 
1598*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; i < printer->num_reasons; i ++)
1599*5e7646d2SAndroid Build Coastguard Worker       if (strcmp(printer->reasons[i], "connecting-to-device") &&
1600*5e7646d2SAndroid Build Coastguard Worker           strcmp(printer->reasons[i], "cups-insecure-filter-warning") &&
1601*5e7646d2SAndroid Build Coastguard Worker           strcmp(printer->reasons[i], "cups-missing-filter-warning"))
1602*5e7646d2SAndroid Build Coastguard Worker         cupsFilePutConf(fp, "Reason", printer->reasons[i]);
1603*5e7646d2SAndroid Build Coastguard Worker 
1604*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "Type %d\n", printer->type);
1605*5e7646d2SAndroid Build Coastguard Worker 
1606*5e7646d2SAndroid Build Coastguard Worker     if (printer->accepting)
1607*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "Accepting Yes\n");
1608*5e7646d2SAndroid Build Coastguard Worker     else
1609*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "Accepting No\n");
1610*5e7646d2SAndroid Build Coastguard Worker 
1611*5e7646d2SAndroid Build Coastguard Worker     if (printer->shared)
1612*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "Shared Yes\n");
1613*5e7646d2SAndroid Build Coastguard Worker     else
1614*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "Shared No\n");
1615*5e7646d2SAndroid Build Coastguard Worker 
1616*5e7646d2SAndroid Build Coastguard Worker     snprintf(value, sizeof(value), "%s %s", printer->job_sheets[0],
1617*5e7646d2SAndroid Build Coastguard Worker              printer->job_sheets[1]);
1618*5e7646d2SAndroid Build Coastguard Worker     cupsFilePutConf(fp, "JobSheets", value);
1619*5e7646d2SAndroid Build Coastguard Worker 
1620*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "QuotaPeriod %d\n", printer->quota_period);
1621*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "PageLimit %d\n", printer->page_limit);
1622*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "KLimit %d\n", printer->k_limit);
1623*5e7646d2SAndroid Build Coastguard Worker 
1624*5e7646d2SAndroid Build Coastguard Worker     for (name = (char *)cupsArrayFirst(printer->users);
1625*5e7646d2SAndroid Build Coastguard Worker          name;
1626*5e7646d2SAndroid Build Coastguard Worker 	 name = (char *)cupsArrayNext(printer->users))
1627*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, printer->deny_users ? "DenyUser" : "AllowUser", name);
1628*5e7646d2SAndroid Build Coastguard Worker 
1629*5e7646d2SAndroid Build Coastguard Worker     if (printer->op_policy)
1630*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "OpPolicy", printer->op_policy);
1631*5e7646d2SAndroid Build Coastguard Worker     if (printer->error_policy)
1632*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "ErrorPolicy", printer->error_policy);
1633*5e7646d2SAndroid Build Coastguard Worker 
1634*5e7646d2SAndroid Build Coastguard Worker     for (i = printer->num_options, option = printer->options;
1635*5e7646d2SAndroid Build Coastguard Worker          i > 0;
1636*5e7646d2SAndroid Build Coastguard Worker 	 i --, option ++)
1637*5e7646d2SAndroid Build Coastguard Worker     {
1638*5e7646d2SAndroid Build Coastguard Worker       snprintf(value, sizeof(value), "%s %s", option->name, option->value);
1639*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Option", value);
1640*5e7646d2SAndroid Build Coastguard Worker     }
1641*5e7646d2SAndroid Build Coastguard Worker 
1642*5e7646d2SAndroid Build Coastguard Worker     if ((marker = ippFindAttribute(printer->attrs, "marker-colors",
1643*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_NAME)) != NULL)
1644*5e7646d2SAndroid Build Coastguard Worker     {
1645*5e7646d2SAndroid Build Coastguard Worker       snprintf(value, sizeof(value), "%s ", marker->name);
1646*5e7646d2SAndroid Build Coastguard Worker 
1647*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, ptr = value + strlen(value);
1648*5e7646d2SAndroid Build Coastguard Worker            i < marker->num_values && ptr < (value + sizeof(value) - 1);
1649*5e7646d2SAndroid Build Coastguard Worker 	   i ++)
1650*5e7646d2SAndroid Build Coastguard Worker       {
1651*5e7646d2SAndroid Build Coastguard Worker         if (i)
1652*5e7646d2SAndroid Build Coastguard Worker 	  *ptr++ = ',';
1653*5e7646d2SAndroid Build Coastguard Worker 
1654*5e7646d2SAndroid Build Coastguard Worker         strlcpy(ptr, marker->values[i].string.text, (size_t)(value + sizeof(value) - ptr));
1655*5e7646d2SAndroid Build Coastguard Worker         ptr += strlen(ptr);
1656*5e7646d2SAndroid Build Coastguard Worker       }
1657*5e7646d2SAndroid Build Coastguard Worker 
1658*5e7646d2SAndroid Build Coastguard Worker       *ptr = '\0';
1659*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Attribute", value);
1660*5e7646d2SAndroid Build Coastguard Worker     }
1661*5e7646d2SAndroid Build Coastguard Worker 
1662*5e7646d2SAndroid Build Coastguard Worker     if ((marker = ippFindAttribute(printer->attrs, "marker-levels",
1663*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_INTEGER)) != NULL)
1664*5e7646d2SAndroid Build Coastguard Worker     {
1665*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "Attribute %s %d", marker->name,
1666*5e7646d2SAndroid Build Coastguard Worker                      marker->values[0].integer);
1667*5e7646d2SAndroid Build Coastguard Worker       for (i = 1; i < marker->num_values; i ++)
1668*5e7646d2SAndroid Build Coastguard Worker         cupsFilePrintf(fp, ",%d", marker->values[i].integer);
1669*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "\n");
1670*5e7646d2SAndroid Build Coastguard Worker     }
1671*5e7646d2SAndroid Build Coastguard Worker 
1672*5e7646d2SAndroid Build Coastguard Worker     if ((marker = ippFindAttribute(printer->attrs, "marker-low-levels",
1673*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_INTEGER)) != NULL)
1674*5e7646d2SAndroid Build Coastguard Worker     {
1675*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "Attribute %s %d", marker->name,
1676*5e7646d2SAndroid Build Coastguard Worker                      marker->values[0].integer);
1677*5e7646d2SAndroid Build Coastguard Worker       for (i = 1; i < marker->num_values; i ++)
1678*5e7646d2SAndroid Build Coastguard Worker         cupsFilePrintf(fp, ",%d", marker->values[i].integer);
1679*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "\n");
1680*5e7646d2SAndroid Build Coastguard Worker     }
1681*5e7646d2SAndroid Build Coastguard Worker 
1682*5e7646d2SAndroid Build Coastguard Worker     if ((marker = ippFindAttribute(printer->attrs, "marker-high-levels",
1683*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_INTEGER)) != NULL)
1684*5e7646d2SAndroid Build Coastguard Worker     {
1685*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "Attribute %s %d", marker->name,
1686*5e7646d2SAndroid Build Coastguard Worker                      marker->values[0].integer);
1687*5e7646d2SAndroid Build Coastguard Worker       for (i = 1; i < marker->num_values; i ++)
1688*5e7646d2SAndroid Build Coastguard Worker         cupsFilePrintf(fp, ",%d", marker->values[i].integer);
1689*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "\n");
1690*5e7646d2SAndroid Build Coastguard Worker     }
1691*5e7646d2SAndroid Build Coastguard Worker 
1692*5e7646d2SAndroid Build Coastguard Worker     if ((marker = ippFindAttribute(printer->attrs, "marker-message",
1693*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_TEXT)) != NULL)
1694*5e7646d2SAndroid Build Coastguard Worker     {
1695*5e7646d2SAndroid Build Coastguard Worker       snprintf(value, sizeof(value), "%s %s", marker->name,
1696*5e7646d2SAndroid Build Coastguard Worker                marker->values[0].string.text);
1697*5e7646d2SAndroid Build Coastguard Worker 
1698*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Attribute", value);
1699*5e7646d2SAndroid Build Coastguard Worker     }
1700*5e7646d2SAndroid Build Coastguard Worker 
1701*5e7646d2SAndroid Build Coastguard Worker     if ((marker = ippFindAttribute(printer->attrs, "marker-names",
1702*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_NAME)) != NULL)
1703*5e7646d2SAndroid Build Coastguard Worker     {
1704*5e7646d2SAndroid Build Coastguard Worker       snprintf(value, sizeof(value), "%s ", marker->name);
1705*5e7646d2SAndroid Build Coastguard Worker 
1706*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, ptr = value + strlen(value);
1707*5e7646d2SAndroid Build Coastguard Worker            i < marker->num_values && ptr < (value + sizeof(value) - 1);
1708*5e7646d2SAndroid Build Coastguard Worker 	   i ++)
1709*5e7646d2SAndroid Build Coastguard Worker       {
1710*5e7646d2SAndroid Build Coastguard Worker         if (i)
1711*5e7646d2SAndroid Build Coastguard Worker 	  *ptr++ = ',';
1712*5e7646d2SAndroid Build Coastguard Worker 
1713*5e7646d2SAndroid Build Coastguard Worker         strlcpy(ptr, marker->values[i].string.text, (size_t)(value + sizeof(value) - ptr));
1714*5e7646d2SAndroid Build Coastguard Worker         ptr += strlen(ptr);
1715*5e7646d2SAndroid Build Coastguard Worker       }
1716*5e7646d2SAndroid Build Coastguard Worker 
1717*5e7646d2SAndroid Build Coastguard Worker       *ptr = '\0';
1718*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Attribute", value);
1719*5e7646d2SAndroid Build Coastguard Worker     }
1720*5e7646d2SAndroid Build Coastguard Worker 
1721*5e7646d2SAndroid Build Coastguard Worker     if ((marker = ippFindAttribute(printer->attrs, "marker-types",
1722*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_KEYWORD)) != NULL)
1723*5e7646d2SAndroid Build Coastguard Worker     {
1724*5e7646d2SAndroid Build Coastguard Worker       snprintf(value, sizeof(value), "%s ", marker->name);
1725*5e7646d2SAndroid Build Coastguard Worker 
1726*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, ptr = value + strlen(value);
1727*5e7646d2SAndroid Build Coastguard Worker            i < marker->num_values && ptr < (value + sizeof(value) - 1);
1728*5e7646d2SAndroid Build Coastguard Worker 	   i ++)
1729*5e7646d2SAndroid Build Coastguard Worker       {
1730*5e7646d2SAndroid Build Coastguard Worker         if (i)
1731*5e7646d2SAndroid Build Coastguard Worker 	  *ptr++ = ',';
1732*5e7646d2SAndroid Build Coastguard Worker 
1733*5e7646d2SAndroid Build Coastguard Worker         strlcpy(ptr, marker->values[i].string.text, (size_t)(value + sizeof(value) - ptr));
1734*5e7646d2SAndroid Build Coastguard Worker         ptr += strlen(ptr);
1735*5e7646d2SAndroid Build Coastguard Worker       }
1736*5e7646d2SAndroid Build Coastguard Worker 
1737*5e7646d2SAndroid Build Coastguard Worker       *ptr = '\0';
1738*5e7646d2SAndroid Build Coastguard Worker       cupsFilePutConf(fp, "Attribute", value);
1739*5e7646d2SAndroid Build Coastguard Worker     }
1740*5e7646d2SAndroid Build Coastguard Worker 
1741*5e7646d2SAndroid Build Coastguard Worker     if (printer->marker_time)
1742*5e7646d2SAndroid Build Coastguard Worker       cupsFilePrintf(fp, "Attribute marker-change-time %ld\n",
1743*5e7646d2SAndroid Build Coastguard Worker                      (long)printer->marker_time);
1744*5e7646d2SAndroid Build Coastguard Worker 
1745*5e7646d2SAndroid Build Coastguard Worker     if (printer == DefaultPrinter)
1746*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "</DefaultPrinter>\n");
1747*5e7646d2SAndroid Build Coastguard Worker     else
1748*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "</Printer>\n");
1749*5e7646d2SAndroid Build Coastguard Worker   }
1750*5e7646d2SAndroid Build Coastguard Worker 
1751*5e7646d2SAndroid Build Coastguard Worker   cupsdCloseCreatedConfFile(fp, filename);
1752*5e7646d2SAndroid Build Coastguard Worker }
1753*5e7646d2SAndroid Build Coastguard Worker 
1754*5e7646d2SAndroid Build Coastguard Worker 
1755*5e7646d2SAndroid Build Coastguard Worker /*
1756*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdSetAuthInfoRequired()' - Set the required authentication info.
1757*5e7646d2SAndroid Build Coastguard Worker  */
1758*5e7646d2SAndroid Build Coastguard Worker 
1759*5e7646d2SAndroid Build Coastguard Worker int					/* O - 1 if value OK, 0 otherwise */
cupsdSetAuthInfoRequired(cupsd_printer_t * p,const char * values,ipp_attribute_t * attr)1760*5e7646d2SAndroid Build Coastguard Worker cupsdSetAuthInfoRequired(
1761*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
1762*5e7646d2SAndroid Build Coastguard Worker     const char      *values,		/* I - Plain text value (or NULL) */
1763*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *attr)		/* I - IPP attribute value (or NULL) */
1764*5e7646d2SAndroid Build Coastguard Worker {
1765*5e7646d2SAndroid Build Coastguard Worker   int	i;				/* Looping var */
1766*5e7646d2SAndroid Build Coastguard Worker 
1767*5e7646d2SAndroid Build Coastguard Worker 
1768*5e7646d2SAndroid Build Coastguard Worker   p->num_auth_info_required = 0;
1769*5e7646d2SAndroid Build Coastguard Worker 
1770*5e7646d2SAndroid Build Coastguard Worker  /*
1771*5e7646d2SAndroid Build Coastguard Worker   * Do we have a plain text value?
1772*5e7646d2SAndroid Build Coastguard Worker   */
1773*5e7646d2SAndroid Build Coastguard Worker 
1774*5e7646d2SAndroid Build Coastguard Worker   if (values)
1775*5e7646d2SAndroid Build Coastguard Worker   {
1776*5e7646d2SAndroid Build Coastguard Worker    /*
1777*5e7646d2SAndroid Build Coastguard Worker     * Yes, grab the keywords...
1778*5e7646d2SAndroid Build Coastguard Worker     */
1779*5e7646d2SAndroid Build Coastguard Worker 
1780*5e7646d2SAndroid Build Coastguard Worker     const char	*end;			/* End of current value */
1781*5e7646d2SAndroid Build Coastguard Worker 
1782*5e7646d2SAndroid Build Coastguard Worker 
1783*5e7646d2SAndroid Build Coastguard Worker     while (*values && p->num_auth_info_required < 4)
1784*5e7646d2SAndroid Build Coastguard Worker     {
1785*5e7646d2SAndroid Build Coastguard Worker       if ((end = strchr(values, ',')) == NULL)
1786*5e7646d2SAndroid Build Coastguard Worker         end = values + strlen(values);
1787*5e7646d2SAndroid Build Coastguard Worker 
1788*5e7646d2SAndroid Build Coastguard Worker       if ((end - values) == 4 && !strncmp(values, "none", 4))
1789*5e7646d2SAndroid Build Coastguard Worker       {
1790*5e7646d2SAndroid Build Coastguard Worker         if (p->num_auth_info_required != 0 || *end)
1791*5e7646d2SAndroid Build Coastguard Worker 	  return (0);
1792*5e7646d2SAndroid Build Coastguard Worker 
1793*5e7646d2SAndroid Build Coastguard Worker         p->auth_info_required[p->num_auth_info_required] = "none";
1794*5e7646d2SAndroid Build Coastguard Worker 	p->num_auth_info_required ++;
1795*5e7646d2SAndroid Build Coastguard Worker 
1796*5e7646d2SAndroid Build Coastguard Worker 	return (1);
1797*5e7646d2SAndroid Build Coastguard Worker       }
1798*5e7646d2SAndroid Build Coastguard Worker       else if ((end - values) == 9 && !strncmp(values, "negotiate", 9))
1799*5e7646d2SAndroid Build Coastguard Worker       {
1800*5e7646d2SAndroid Build Coastguard Worker         if (p->num_auth_info_required != 0 || *end)
1801*5e7646d2SAndroid Build Coastguard Worker 	  return (0);
1802*5e7646d2SAndroid Build Coastguard Worker 
1803*5e7646d2SAndroid Build Coastguard Worker         p->auth_info_required[p->num_auth_info_required] = "negotiate";
1804*5e7646d2SAndroid Build Coastguard Worker 	p->num_auth_info_required ++;
1805*5e7646d2SAndroid Build Coastguard Worker 
1806*5e7646d2SAndroid Build Coastguard Worker        /*
1807*5e7646d2SAndroid Build Coastguard Worker         * Don't allow sharing of queues that require Kerberos authentication.
1808*5e7646d2SAndroid Build Coastguard Worker 	*/
1809*5e7646d2SAndroid Build Coastguard Worker 
1810*5e7646d2SAndroid Build Coastguard Worker 	if (p->shared)
1811*5e7646d2SAndroid Build Coastguard Worker 	{
1812*5e7646d2SAndroid Build Coastguard Worker 	  cupsdDeregisterPrinter(p, 1);
1813*5e7646d2SAndroid Build Coastguard Worker 	  p->shared = 0;
1814*5e7646d2SAndroid Build Coastguard Worker 	}
1815*5e7646d2SAndroid Build Coastguard Worker       }
1816*5e7646d2SAndroid Build Coastguard Worker       else if ((end - values) == 6 && !strncmp(values, "domain", 6))
1817*5e7646d2SAndroid Build Coastguard Worker       {
1818*5e7646d2SAndroid Build Coastguard Worker         p->auth_info_required[p->num_auth_info_required] = "domain";
1819*5e7646d2SAndroid Build Coastguard Worker 	p->num_auth_info_required ++;
1820*5e7646d2SAndroid Build Coastguard Worker       }
1821*5e7646d2SAndroid Build Coastguard Worker       else if ((end - values) == 8 && !strncmp(values, "password", 8))
1822*5e7646d2SAndroid Build Coastguard Worker       {
1823*5e7646d2SAndroid Build Coastguard Worker         p->auth_info_required[p->num_auth_info_required] = "password";
1824*5e7646d2SAndroid Build Coastguard Worker 	p->num_auth_info_required ++;
1825*5e7646d2SAndroid Build Coastguard Worker       }
1826*5e7646d2SAndroid Build Coastguard Worker       else if ((end - values) == 8 && !strncmp(values, "username", 8))
1827*5e7646d2SAndroid Build Coastguard Worker       {
1828*5e7646d2SAndroid Build Coastguard Worker         p->auth_info_required[p->num_auth_info_required] = "username";
1829*5e7646d2SAndroid Build Coastguard Worker 	p->num_auth_info_required ++;
1830*5e7646d2SAndroid Build Coastguard Worker       }
1831*5e7646d2SAndroid Build Coastguard Worker       else
1832*5e7646d2SAndroid Build Coastguard Worker         return (0);
1833*5e7646d2SAndroid Build Coastguard Worker 
1834*5e7646d2SAndroid Build Coastguard Worker       values = (*end) ? end + 1 : end;
1835*5e7646d2SAndroid Build Coastguard Worker     }
1836*5e7646d2SAndroid Build Coastguard Worker 
1837*5e7646d2SAndroid Build Coastguard Worker     if (p->num_auth_info_required == 0)
1838*5e7646d2SAndroid Build Coastguard Worker     {
1839*5e7646d2SAndroid Build Coastguard Worker       p->auth_info_required[0]  = "none";
1840*5e7646d2SAndroid Build Coastguard Worker       p->num_auth_info_required = 1;
1841*5e7646d2SAndroid Build Coastguard Worker     }
1842*5e7646d2SAndroid Build Coastguard Worker 
1843*5e7646d2SAndroid Build Coastguard Worker    /*
1844*5e7646d2SAndroid Build Coastguard Worker     * Update the printer-type value as needed...
1845*5e7646d2SAndroid Build Coastguard Worker     */
1846*5e7646d2SAndroid Build Coastguard Worker 
1847*5e7646d2SAndroid Build Coastguard Worker     if (p->num_auth_info_required > 1 ||
1848*5e7646d2SAndroid Build Coastguard Worker         strcmp(p->auth_info_required[0], "none"))
1849*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_AUTHENTICATED;
1850*5e7646d2SAndroid Build Coastguard Worker     else
1851*5e7646d2SAndroid Build Coastguard Worker       p->type &= (cups_ptype_t)~CUPS_PRINTER_AUTHENTICATED;
1852*5e7646d2SAndroid Build Coastguard Worker 
1853*5e7646d2SAndroid Build Coastguard Worker     return (1);
1854*5e7646d2SAndroid Build Coastguard Worker   }
1855*5e7646d2SAndroid Build Coastguard Worker 
1856*5e7646d2SAndroid Build Coastguard Worker  /*
1857*5e7646d2SAndroid Build Coastguard Worker   * Grab values from an attribute instead...
1858*5e7646d2SAndroid Build Coastguard Worker   */
1859*5e7646d2SAndroid Build Coastguard Worker 
1860*5e7646d2SAndroid Build Coastguard Worker   if (!attr || attr->num_values > 4)
1861*5e7646d2SAndroid Build Coastguard Worker     return (0);
1862*5e7646d2SAndroid Build Coastguard Worker 
1863*5e7646d2SAndroid Build Coastguard Worker   for (i = 0; i < attr->num_values; i ++)
1864*5e7646d2SAndroid Build Coastguard Worker   {
1865*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(attr->values[i].string.text, "none"))
1866*5e7646d2SAndroid Build Coastguard Worker     {
1867*5e7646d2SAndroid Build Coastguard Worker       if (p->num_auth_info_required != 0 || attr->num_values != 1)
1868*5e7646d2SAndroid Build Coastguard Worker 	return (0);
1869*5e7646d2SAndroid Build Coastguard Worker 
1870*5e7646d2SAndroid Build Coastguard Worker       p->auth_info_required[p->num_auth_info_required] = "none";
1871*5e7646d2SAndroid Build Coastguard Worker       p->num_auth_info_required ++;
1872*5e7646d2SAndroid Build Coastguard Worker 
1873*5e7646d2SAndroid Build Coastguard Worker       return (1);
1874*5e7646d2SAndroid Build Coastguard Worker     }
1875*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(attr->values[i].string.text, "negotiate"))
1876*5e7646d2SAndroid Build Coastguard Worker     {
1877*5e7646d2SAndroid Build Coastguard Worker       if (p->num_auth_info_required != 0 || attr->num_values != 1)
1878*5e7646d2SAndroid Build Coastguard Worker 	return (0);
1879*5e7646d2SAndroid Build Coastguard Worker 
1880*5e7646d2SAndroid Build Coastguard Worker       p->auth_info_required[p->num_auth_info_required] = "negotiate";
1881*5e7646d2SAndroid Build Coastguard Worker       p->num_auth_info_required ++;
1882*5e7646d2SAndroid Build Coastguard Worker 
1883*5e7646d2SAndroid Build Coastguard Worker      /*
1884*5e7646d2SAndroid Build Coastguard Worker       * Don't allow sharing of queues that require Kerberos authentication.
1885*5e7646d2SAndroid Build Coastguard Worker       */
1886*5e7646d2SAndroid Build Coastguard Worker 
1887*5e7646d2SAndroid Build Coastguard Worker       if (p->shared)
1888*5e7646d2SAndroid Build Coastguard Worker       {
1889*5e7646d2SAndroid Build Coastguard Worker 	cupsdDeregisterPrinter(p, 1);
1890*5e7646d2SAndroid Build Coastguard Worker 	p->shared = 0;
1891*5e7646d2SAndroid Build Coastguard Worker       }
1892*5e7646d2SAndroid Build Coastguard Worker 
1893*5e7646d2SAndroid Build Coastguard Worker       return (1);
1894*5e7646d2SAndroid Build Coastguard Worker     }
1895*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(attr->values[i].string.text, "domain"))
1896*5e7646d2SAndroid Build Coastguard Worker     {
1897*5e7646d2SAndroid Build Coastguard Worker       p->auth_info_required[p->num_auth_info_required] = "domain";
1898*5e7646d2SAndroid Build Coastguard Worker       p->num_auth_info_required ++;
1899*5e7646d2SAndroid Build Coastguard Worker     }
1900*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(attr->values[i].string.text, "password"))
1901*5e7646d2SAndroid Build Coastguard Worker     {
1902*5e7646d2SAndroid Build Coastguard Worker       p->auth_info_required[p->num_auth_info_required] = "password";
1903*5e7646d2SAndroid Build Coastguard Worker       p->num_auth_info_required ++;
1904*5e7646d2SAndroid Build Coastguard Worker     }
1905*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(attr->values[i].string.text, "username"))
1906*5e7646d2SAndroid Build Coastguard Worker     {
1907*5e7646d2SAndroid Build Coastguard Worker       p->auth_info_required[p->num_auth_info_required] = "username";
1908*5e7646d2SAndroid Build Coastguard Worker       p->num_auth_info_required ++;
1909*5e7646d2SAndroid Build Coastguard Worker     }
1910*5e7646d2SAndroid Build Coastguard Worker     else
1911*5e7646d2SAndroid Build Coastguard Worker       return (0);
1912*5e7646d2SAndroid Build Coastguard Worker   }
1913*5e7646d2SAndroid Build Coastguard Worker 
1914*5e7646d2SAndroid Build Coastguard Worker   return (1);
1915*5e7646d2SAndroid Build Coastguard Worker }
1916*5e7646d2SAndroid Build Coastguard Worker 
1917*5e7646d2SAndroid Build Coastguard Worker 
1918*5e7646d2SAndroid Build Coastguard Worker /*
1919*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdSetDeviceURI()' - Set the device URI for a printer.
1920*5e7646d2SAndroid Build Coastguard Worker  */
1921*5e7646d2SAndroid Build Coastguard Worker 
1922*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetDeviceURI(cupsd_printer_t * p,const char * uri)1923*5e7646d2SAndroid Build Coastguard Worker cupsdSetDeviceURI(cupsd_printer_t *p,	/* I - Printer */
1924*5e7646d2SAndroid Build Coastguard Worker                   const char      *uri)	/* I - Device URI */
1925*5e7646d2SAndroid Build Coastguard Worker {
1926*5e7646d2SAndroid Build Coastguard Worker   char	buffer[1024],			/* URI buffer */
1927*5e7646d2SAndroid Build Coastguard Worker 	*start,				/* Start of data after scheme */
1928*5e7646d2SAndroid Build Coastguard Worker 	*slash,				/* First slash after scheme:// */
1929*5e7646d2SAndroid Build Coastguard Worker 	*ptr;				/* Pointer into user@host:port part */
1930*5e7646d2SAndroid Build Coastguard Worker 
1931*5e7646d2SAndroid Build Coastguard Worker 
1932*5e7646d2SAndroid Build Coastguard Worker  /*
1933*5e7646d2SAndroid Build Coastguard Worker   * Set the full device URI..
1934*5e7646d2SAndroid Build Coastguard Worker   */
1935*5e7646d2SAndroid Build Coastguard Worker 
1936*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&(p->device_uri), uri);
1937*5e7646d2SAndroid Build Coastguard Worker 
1938*5e7646d2SAndroid Build Coastguard Worker  /*
1939*5e7646d2SAndroid Build Coastguard Worker   * Copy the device URI to a temporary buffer so we can sanitize any auth
1940*5e7646d2SAndroid Build Coastguard Worker   * info in it...
1941*5e7646d2SAndroid Build Coastguard Worker   */
1942*5e7646d2SAndroid Build Coastguard Worker 
1943*5e7646d2SAndroid Build Coastguard Worker   strlcpy(buffer, uri, sizeof(buffer));
1944*5e7646d2SAndroid Build Coastguard Worker 
1945*5e7646d2SAndroid Build Coastguard Worker  /*
1946*5e7646d2SAndroid Build Coastguard Worker   * Find the end of the scheme:// part...
1947*5e7646d2SAndroid Build Coastguard Worker   */
1948*5e7646d2SAndroid Build Coastguard Worker 
1949*5e7646d2SAndroid Build Coastguard Worker   if ((ptr = strchr(buffer, ':')) != NULL)
1950*5e7646d2SAndroid Build Coastguard Worker   {
1951*5e7646d2SAndroid Build Coastguard Worker     for (start = ptr + 1; *start; start ++)
1952*5e7646d2SAndroid Build Coastguard Worker       if (*start != '/')
1953*5e7646d2SAndroid Build Coastguard Worker         break;
1954*5e7646d2SAndroid Build Coastguard Worker 
1955*5e7646d2SAndroid Build Coastguard Worker    /*
1956*5e7646d2SAndroid Build Coastguard Worker     * Find the next slash (/) in the URI...
1957*5e7646d2SAndroid Build Coastguard Worker     */
1958*5e7646d2SAndroid Build Coastguard Worker 
1959*5e7646d2SAndroid Build Coastguard Worker     if ((slash = strchr(start, '/')) == NULL)
1960*5e7646d2SAndroid Build Coastguard Worker       slash = start + strlen(start);	/* No slash, point to the end */
1961*5e7646d2SAndroid Build Coastguard Worker 
1962*5e7646d2SAndroid Build Coastguard Worker    /*
1963*5e7646d2SAndroid Build Coastguard Worker     * Check for an @ sign before the slash...
1964*5e7646d2SAndroid Build Coastguard Worker     */
1965*5e7646d2SAndroid Build Coastguard Worker 
1966*5e7646d2SAndroid Build Coastguard Worker     if ((ptr = strchr(start, '@')) != NULL && ptr < slash)
1967*5e7646d2SAndroid Build Coastguard Worker     {
1968*5e7646d2SAndroid Build Coastguard Worker      /*
1969*5e7646d2SAndroid Build Coastguard Worker       * Found an @ sign and it is before the resource part, so we have
1970*5e7646d2SAndroid Build Coastguard Worker       * an authentication string.  Copy the remaining URI over the
1971*5e7646d2SAndroid Build Coastguard Worker       * authentication string...
1972*5e7646d2SAndroid Build Coastguard Worker       */
1973*5e7646d2SAndroid Build Coastguard Worker 
1974*5e7646d2SAndroid Build Coastguard Worker       _cups_strcpy(start, ptr + 1);
1975*5e7646d2SAndroid Build Coastguard Worker     }
1976*5e7646d2SAndroid Build Coastguard Worker   }
1977*5e7646d2SAndroid Build Coastguard Worker 
1978*5e7646d2SAndroid Build Coastguard Worker  /*
1979*5e7646d2SAndroid Build Coastguard Worker   * Save the sanitized URI...
1980*5e7646d2SAndroid Build Coastguard Worker   */
1981*5e7646d2SAndroid Build Coastguard Worker 
1982*5e7646d2SAndroid Build Coastguard Worker   cupsdSetString(&(p->sanitized_device_uri), buffer);
1983*5e7646d2SAndroid Build Coastguard Worker }
1984*5e7646d2SAndroid Build Coastguard Worker 
1985*5e7646d2SAndroid Build Coastguard Worker 
1986*5e7646d2SAndroid Build Coastguard Worker /*
1987*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdSetPrinterAttr()' - Set a printer attribute.
1988*5e7646d2SAndroid Build Coastguard Worker  */
1989*5e7646d2SAndroid Build Coastguard Worker 
1990*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetPrinterAttr(cupsd_printer_t * p,const char * name,const char * value)1991*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttr(
1992*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
1993*5e7646d2SAndroid Build Coastguard Worker     const char      *name,		/* I - Attribute name */
1994*5e7646d2SAndroid Build Coastguard Worker     const char      *value)		/* I - Attribute value string */
1995*5e7646d2SAndroid Build Coastguard Worker {
1996*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*attr;		/* Attribute */
1997*5e7646d2SAndroid Build Coastguard Worker   int			i,		/* Looping var */
1998*5e7646d2SAndroid Build Coastguard Worker 			count;		/* Number of values */
1999*5e7646d2SAndroid Build Coastguard Worker   char			*temp,		/* Temporary copy of value string */
2000*5e7646d2SAndroid Build Coastguard Worker 			*ptr,		/* Pointer into value */
2001*5e7646d2SAndroid Build Coastguard Worker 			*start,		/* Start of value */
2002*5e7646d2SAndroid Build Coastguard Worker 			quote;		/* Quote character */
2003*5e7646d2SAndroid Build Coastguard Worker   ipp_tag_t		value_tag;	/* Value tag for this attribute */
2004*5e7646d2SAndroid Build Coastguard Worker 
2005*5e7646d2SAndroid Build Coastguard Worker 
2006*5e7646d2SAndroid Build Coastguard Worker  /*
2007*5e7646d2SAndroid Build Coastguard Worker   * Don't allow empty values...
2008*5e7646d2SAndroid Build Coastguard Worker   */
2009*5e7646d2SAndroid Build Coastguard Worker 
2010*5e7646d2SAndroid Build Coastguard Worker   if (!*value && strcmp(name, "marker-message"))
2011*5e7646d2SAndroid Build Coastguard Worker   {
2012*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Ignoring empty \"%s\" attribute", name);
2013*5e7646d2SAndroid Build Coastguard Worker     return;
2014*5e7646d2SAndroid Build Coastguard Worker   }
2015*5e7646d2SAndroid Build Coastguard Worker 
2016*5e7646d2SAndroid Build Coastguard Worker  /*
2017*5e7646d2SAndroid Build Coastguard Worker   * Copy the value string so we can do what we want with it...
2018*5e7646d2SAndroid Build Coastguard Worker   */
2019*5e7646d2SAndroid Build Coastguard Worker 
2020*5e7646d2SAndroid Build Coastguard Worker   if ((temp = strdup(value)) == NULL)
2021*5e7646d2SAndroid Build Coastguard Worker   {
2022*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR,
2023*5e7646d2SAndroid Build Coastguard Worker                     "Unable to duplicate value for \"%s\" attribute.", name);
2024*5e7646d2SAndroid Build Coastguard Worker     return;
2025*5e7646d2SAndroid Build Coastguard Worker   }
2026*5e7646d2SAndroid Build Coastguard Worker 
2027*5e7646d2SAndroid Build Coastguard Worker  /*
2028*5e7646d2SAndroid Build Coastguard Worker   * Count the number of values...
2029*5e7646d2SAndroid Build Coastguard Worker   */
2030*5e7646d2SAndroid Build Coastguard Worker 
2031*5e7646d2SAndroid Build Coastguard Worker   for (count = 1, quote = '\0', ptr = temp;
2032*5e7646d2SAndroid Build Coastguard Worker        *ptr;
2033*5e7646d2SAndroid Build Coastguard Worker        ptr ++)
2034*5e7646d2SAndroid Build Coastguard Worker   {
2035*5e7646d2SAndroid Build Coastguard Worker     if (*ptr == quote)
2036*5e7646d2SAndroid Build Coastguard Worker       quote = '\0';
2037*5e7646d2SAndroid Build Coastguard Worker     else if (quote)
2038*5e7646d2SAndroid Build Coastguard Worker       continue;
2039*5e7646d2SAndroid Build Coastguard Worker     else if (*ptr == '\\' && ptr[1])
2040*5e7646d2SAndroid Build Coastguard Worker       ptr ++;
2041*5e7646d2SAndroid Build Coastguard Worker     else if (*ptr == '\'' || *ptr == '\"')
2042*5e7646d2SAndroid Build Coastguard Worker       quote = *ptr;
2043*5e7646d2SAndroid Build Coastguard Worker     else if (*ptr == ',')
2044*5e7646d2SAndroid Build Coastguard Worker       count ++;
2045*5e7646d2SAndroid Build Coastguard Worker   }
2046*5e7646d2SAndroid Build Coastguard Worker 
2047*5e7646d2SAndroid Build Coastguard Worker  /*
2048*5e7646d2SAndroid Build Coastguard Worker   * Then add or update the attribute as needed...
2049*5e7646d2SAndroid Build Coastguard Worker   */
2050*5e7646d2SAndroid Build Coastguard Worker 
2051*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(name, "marker-levels") || !strcmp(name, "marker-low-levels") ||
2052*5e7646d2SAndroid Build Coastguard Worker       !strcmp(name, "marker-high-levels"))
2053*5e7646d2SAndroid Build Coastguard Worker   {
2054*5e7646d2SAndroid Build Coastguard Worker    /*
2055*5e7646d2SAndroid Build Coastguard Worker     * Integer values...
2056*5e7646d2SAndroid Build Coastguard Worker     */
2057*5e7646d2SAndroid Build Coastguard Worker 
2058*5e7646d2SAndroid Build Coastguard Worker     if ((attr = ippFindAttribute(p->attrs, name, IPP_TAG_INTEGER)) != NULL &&
2059*5e7646d2SAndroid Build Coastguard Worker         attr->num_values < count)
2060*5e7646d2SAndroid Build Coastguard Worker     {
2061*5e7646d2SAndroid Build Coastguard Worker       ippDeleteAttribute(p->attrs, attr);
2062*5e7646d2SAndroid Build Coastguard Worker       attr = NULL;
2063*5e7646d2SAndroid Build Coastguard Worker     }
2064*5e7646d2SAndroid Build Coastguard Worker 
2065*5e7646d2SAndroid Build Coastguard Worker     if (attr)
2066*5e7646d2SAndroid Build Coastguard Worker       attr->num_values = count;
2067*5e7646d2SAndroid Build Coastguard Worker     else
2068*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, name,
2069*5e7646d2SAndroid Build Coastguard Worker                             count, NULL);
2070*5e7646d2SAndroid Build Coastguard Worker 
2071*5e7646d2SAndroid Build Coastguard Worker     if (!attr)
2072*5e7646d2SAndroid Build Coastguard Worker     {
2073*5e7646d2SAndroid Build Coastguard Worker       free(temp);
2074*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR,
2075*5e7646d2SAndroid Build Coastguard Worker                       "Unable to allocate memory for printer attribute "
2076*5e7646d2SAndroid Build Coastguard Worker 		      "(%d values)", count);
2077*5e7646d2SAndroid Build Coastguard Worker       return;
2078*5e7646d2SAndroid Build Coastguard Worker     }
2079*5e7646d2SAndroid Build Coastguard Worker 
2080*5e7646d2SAndroid Build Coastguard Worker     for (i = 0, start = temp; i < count; i ++)
2081*5e7646d2SAndroid Build Coastguard Worker     {
2082*5e7646d2SAndroid Build Coastguard Worker       if ((ptr = strchr(start, ',')) != NULL)
2083*5e7646d2SAndroid Build Coastguard Worker         *ptr++ = '\0';
2084*5e7646d2SAndroid Build Coastguard Worker 
2085*5e7646d2SAndroid Build Coastguard Worker       attr->values[i].integer = strtol(start, NULL, 10);
2086*5e7646d2SAndroid Build Coastguard Worker 
2087*5e7646d2SAndroid Build Coastguard Worker       if (ptr)
2088*5e7646d2SAndroid Build Coastguard Worker         start = ptr;
2089*5e7646d2SAndroid Build Coastguard Worker     }
2090*5e7646d2SAndroid Build Coastguard Worker   }
2091*5e7646d2SAndroid Build Coastguard Worker   else
2092*5e7646d2SAndroid Build Coastguard Worker   {
2093*5e7646d2SAndroid Build Coastguard Worker    /*
2094*5e7646d2SAndroid Build Coastguard Worker     * Name or keyword values...
2095*5e7646d2SAndroid Build Coastguard Worker     */
2096*5e7646d2SAndroid Build Coastguard Worker 
2097*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(name, "marker-types"))
2098*5e7646d2SAndroid Build Coastguard Worker       value_tag = IPP_TAG_KEYWORD;
2099*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(name, "marker-message"))
2100*5e7646d2SAndroid Build Coastguard Worker       value_tag = IPP_TAG_TEXT;
2101*5e7646d2SAndroid Build Coastguard Worker     else
2102*5e7646d2SAndroid Build Coastguard Worker       value_tag = IPP_TAG_NAME;
2103*5e7646d2SAndroid Build Coastguard Worker 
2104*5e7646d2SAndroid Build Coastguard Worker     if ((attr = ippFindAttribute(p->attrs, name, value_tag)) != NULL &&
2105*5e7646d2SAndroid Build Coastguard Worker         attr->num_values < count)
2106*5e7646d2SAndroid Build Coastguard Worker     {
2107*5e7646d2SAndroid Build Coastguard Worker       ippDeleteAttribute(p->attrs, attr);
2108*5e7646d2SAndroid Build Coastguard Worker       attr = NULL;
2109*5e7646d2SAndroid Build Coastguard Worker     }
2110*5e7646d2SAndroid Build Coastguard Worker 
2111*5e7646d2SAndroid Build Coastguard Worker     if (attr)
2112*5e7646d2SAndroid Build Coastguard Worker     {
2113*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < attr->num_values; i ++)
2114*5e7646d2SAndroid Build Coastguard Worker 	_cupsStrFree(attr->values[i].string.text);
2115*5e7646d2SAndroid Build Coastguard Worker 
2116*5e7646d2SAndroid Build Coastguard Worker       attr->num_values = count;
2117*5e7646d2SAndroid Build Coastguard Worker     }
2118*5e7646d2SAndroid Build Coastguard Worker     else
2119*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, value_tag, name,
2120*5e7646d2SAndroid Build Coastguard Worker                            count, NULL, NULL);
2121*5e7646d2SAndroid Build Coastguard Worker 
2122*5e7646d2SAndroid Build Coastguard Worker     if (!attr)
2123*5e7646d2SAndroid Build Coastguard Worker     {
2124*5e7646d2SAndroid Build Coastguard Worker       free(temp);
2125*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR,
2126*5e7646d2SAndroid Build Coastguard Worker                       "Unable to allocate memory for printer attribute "
2127*5e7646d2SAndroid Build Coastguard Worker 		      "(%d values)", count);
2128*5e7646d2SAndroid Build Coastguard Worker       return;
2129*5e7646d2SAndroid Build Coastguard Worker     }
2130*5e7646d2SAndroid Build Coastguard Worker 
2131*5e7646d2SAndroid Build Coastguard Worker     for (i = 0, quote = '\0', ptr = temp; i < count; i ++)
2132*5e7646d2SAndroid Build Coastguard Worker     {
2133*5e7646d2SAndroid Build Coastguard Worker       for (start = ptr; *ptr; ptr ++)
2134*5e7646d2SAndroid Build Coastguard Worker       {
2135*5e7646d2SAndroid Build Coastguard Worker 	if (*ptr == quote)
2136*5e7646d2SAndroid Build Coastguard Worker 	  *ptr = quote = '\0';
2137*5e7646d2SAndroid Build Coastguard Worker 	else if (quote)
2138*5e7646d2SAndroid Build Coastguard Worker 	  continue;
2139*5e7646d2SAndroid Build Coastguard Worker 	else if (*ptr == '\\' && ptr[1])
2140*5e7646d2SAndroid Build Coastguard Worker 	  _cups_strcpy(ptr, ptr + 1);
2141*5e7646d2SAndroid Build Coastguard Worker 	else if (*ptr == '\'' || *ptr == '\"')
2142*5e7646d2SAndroid Build Coastguard Worker 	{
2143*5e7646d2SAndroid Build Coastguard Worker 	  quote = *ptr;
2144*5e7646d2SAndroid Build Coastguard Worker 
2145*5e7646d2SAndroid Build Coastguard Worker 	  if (ptr == start)
2146*5e7646d2SAndroid Build Coastguard Worker 	    start ++;
2147*5e7646d2SAndroid Build Coastguard Worker 	  else
2148*5e7646d2SAndroid Build Coastguard Worker 	    _cups_strcpy(ptr, ptr + 1);
2149*5e7646d2SAndroid Build Coastguard Worker 	}
2150*5e7646d2SAndroid Build Coastguard Worker 	else if (*ptr == ',')
2151*5e7646d2SAndroid Build Coastguard Worker 	{
2152*5e7646d2SAndroid Build Coastguard Worker 	  *ptr++ = '\0';
2153*5e7646d2SAndroid Build Coastguard Worker 	  break;
2154*5e7646d2SAndroid Build Coastguard Worker 	}
2155*5e7646d2SAndroid Build Coastguard Worker       }
2156*5e7646d2SAndroid Build Coastguard Worker 
2157*5e7646d2SAndroid Build Coastguard Worker       attr->values[i].string.text = _cupsStrAlloc(start);
2158*5e7646d2SAndroid Build Coastguard Worker     }
2159*5e7646d2SAndroid Build Coastguard Worker   }
2160*5e7646d2SAndroid Build Coastguard Worker 
2161*5e7646d2SAndroid Build Coastguard Worker   free(temp);
2162*5e7646d2SAndroid Build Coastguard Worker 
2163*5e7646d2SAndroid Build Coastguard Worker  /*
2164*5e7646d2SAndroid Build Coastguard Worker   * Update the printer-supply and printer-supply-description, as needed...
2165*5e7646d2SAndroid Build Coastguard Worker   */
2166*5e7646d2SAndroid Build Coastguard Worker 
2167*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(name, "marker-names"))
2168*5e7646d2SAndroid Build Coastguard Worker   {
2169*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *supply_desc = ippFindAttribute(p->attrs, "printer-supply-description", IPP_TAG_TEXT);
2170*5e7646d2SAndroid Build Coastguard Worker 					/* printer-supply-description attribute */
2171*5e7646d2SAndroid Build Coastguard Worker 
2172*5e7646d2SAndroid Build Coastguard Worker     if (supply_desc != NULL)
2173*5e7646d2SAndroid Build Coastguard Worker       ippDeleteAttribute(p->attrs, supply_desc);
2174*5e7646d2SAndroid Build Coastguard Worker 
2175*5e7646d2SAndroid Build Coastguard Worker     supply_desc = ippCopyAttribute(p->attrs, attr, 0);
2176*5e7646d2SAndroid Build Coastguard Worker     ippSetName(p->attrs, &supply_desc, "printer-supply-description");
2177*5e7646d2SAndroid Build Coastguard Worker     ippSetValueTag(p->attrs, &supply_desc, IPP_TAG_TEXT);
2178*5e7646d2SAndroid Build Coastguard Worker   }
2179*5e7646d2SAndroid Build Coastguard Worker   else if (!strcmp(name, "marker-colors") || !strcmp(name, "marker-levels") || !strcmp(name, "marker-types"))
2180*5e7646d2SAndroid Build Coastguard Worker   {
2181*5e7646d2SAndroid Build Coastguard Worker     char	buffer[256],		/* printer-supply values */
2182*5e7646d2SAndroid Build Coastguard Worker 		pstype[64],		/* printer-supply type value */
2183*5e7646d2SAndroid Build Coastguard Worker 		*psptr;			/* Pointer into type */
2184*5e7646d2SAndroid Build Coastguard Worker     const char	*color,			/* marker-colors value */
2185*5e7646d2SAndroid Build Coastguard Worker 		*type;			/* marker-types value */
2186*5e7646d2SAndroid Build Coastguard Worker     int		level;			/* marker-levels value */
2187*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *colors = ippFindAttribute(p->attrs, "marker-colors", IPP_TAG_NAME);
2188*5e7646d2SAndroid Build Coastguard Worker 					/* marker-colors attribute */
2189*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *levels = ippFindAttribute(p->attrs, "marker-levels", IPP_TAG_INTEGER);
2190*5e7646d2SAndroid Build Coastguard Worker 					/* marker-levels attribute */
2191*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *types = ippFindAttribute(p->attrs, "marker-types", IPP_TAG_KEYWORD);
2192*5e7646d2SAndroid Build Coastguard Worker 					/* marker-types attribute */
2193*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *supply = ippFindAttribute(p->attrs, "printer-supply", IPP_TAG_STRING);
2194*5e7646d2SAndroid Build Coastguard Worker 					/* printer-supply attribute */
2195*5e7646d2SAndroid Build Coastguard Worker 
2196*5e7646d2SAndroid Build Coastguard Worker     if (supply != NULL)
2197*5e7646d2SAndroid Build Coastguard Worker     {
2198*5e7646d2SAndroid Build Coastguard Worker       ippDeleteAttribute(p->attrs, supply);
2199*5e7646d2SAndroid Build Coastguard Worker       supply = NULL;
2200*5e7646d2SAndroid Build Coastguard Worker     }
2201*5e7646d2SAndroid Build Coastguard Worker 
2202*5e7646d2SAndroid Build Coastguard Worker     if (!colors || !levels || !types)
2203*5e7646d2SAndroid Build Coastguard Worker       return;
2204*5e7646d2SAndroid Build Coastguard Worker 
2205*5e7646d2SAndroid Build Coastguard Worker     count = ippGetCount(colors);
2206*5e7646d2SAndroid Build Coastguard Worker     if (count != ippGetCount(levels) || count != ippGetCount(types))
2207*5e7646d2SAndroid Build Coastguard Worker       return;
2208*5e7646d2SAndroid Build Coastguard Worker 
2209*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; i < count; i ++)
2210*5e7646d2SAndroid Build Coastguard Worker     {
2211*5e7646d2SAndroid Build Coastguard Worker       color = ippGetString(colors, i, NULL);
2212*5e7646d2SAndroid Build Coastguard Worker       level = ippGetInteger(levels, i);
2213*5e7646d2SAndroid Build Coastguard Worker       type  = ippGetString(types, i, NULL);
2214*5e7646d2SAndroid Build Coastguard Worker 
2215*5e7646d2SAndroid Build Coastguard Worker       for (psptr = pstype; *type && psptr < (pstype + sizeof(pstype) - 1); type ++)
2216*5e7646d2SAndroid Build Coastguard Worker         if (*type == '-')
2217*5e7646d2SAndroid Build Coastguard Worker 	{
2218*5e7646d2SAndroid Build Coastguard Worker 	  type ++;
2219*5e7646d2SAndroid Build Coastguard Worker 	  *psptr++ = (char)toupper(*type & 255);
2220*5e7646d2SAndroid Build Coastguard Worker 	}
2221*5e7646d2SAndroid Build Coastguard Worker 	else
2222*5e7646d2SAndroid Build Coastguard Worker 	  *psptr++ = *type;
2223*5e7646d2SAndroid Build Coastguard Worker       *psptr = '\0';
2224*5e7646d2SAndroid Build Coastguard Worker 
2225*5e7646d2SAndroid Build Coastguard Worker       snprintf(buffer, sizeof(buffer), "index=%d;class=%s;type=%s;unit=percent;maxcapacity=100;level=%d;colorantname=%s;", i + 1, strncmp(pstype, "waste", 5) ? "supplyThatIsConsumed" : "receptacleThatIsFilled", pstype, level, color);
2226*5e7646d2SAndroid Build Coastguard Worker 
2227*5e7646d2SAndroid Build Coastguard Worker       if (!i)
2228*5e7646d2SAndroid Build Coastguard Worker         supply = ippAddOctetString(p->attrs, IPP_TAG_PRINTER, "printer-supply", buffer, (int)strlen(buffer));
2229*5e7646d2SAndroid Build Coastguard Worker       else
2230*5e7646d2SAndroid Build Coastguard Worker         ippSetOctetString(p->attrs, &supply, i, buffer, (int)strlen(buffer));
2231*5e7646d2SAndroid Build Coastguard Worker     }
2232*5e7646d2SAndroid Build Coastguard Worker   }
2233*5e7646d2SAndroid Build Coastguard Worker }
2234*5e7646d2SAndroid Build Coastguard Worker 
2235*5e7646d2SAndroid Build Coastguard Worker 
2236*5e7646d2SAndroid Build Coastguard Worker /*
2237*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdSetPrinterAttrs()' - Set printer attributes based upon the PPD file.
2238*5e7646d2SAndroid Build Coastguard Worker  */
2239*5e7646d2SAndroid Build Coastguard Worker 
2240*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetPrinterAttrs(cupsd_printer_t * p)2241*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterAttrs(cupsd_printer_t *p)/* I - Printer to setup */
2242*5e7646d2SAndroid Build Coastguard Worker {
2243*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
2244*5e7646d2SAndroid Build Coastguard Worker   char		resource[HTTP_MAX_URI];	/* Resource portion of URI */
2245*5e7646d2SAndroid Build Coastguard Worker   cupsd_location_t *auth;		/* Pointer to authentication element */
2246*5e7646d2SAndroid Build Coastguard Worker   const char	*auth_supported;	/* Authentication supported */
2247*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*oldattrs;		/* Old printer attributes */
2248*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Attribute data */
2249*5e7646d2SAndroid Build Coastguard Worker   char		*name,			/* Current user/group name */
2250*5e7646d2SAndroid Build Coastguard Worker 		*filter;		/* Current filter */
2251*5e7646d2SAndroid Build Coastguard Worker 
2252*5e7646d2SAndroid Build Coastguard Worker 
2253*5e7646d2SAndroid Build Coastguard Worker  /*
2254*5e7646d2SAndroid Build Coastguard Worker   * Make sure that we have the common attributes defined...
2255*5e7646d2SAndroid Build Coastguard Worker   */
2256*5e7646d2SAndroid Build Coastguard Worker 
2257*5e7646d2SAndroid Build Coastguard Worker   if (!CommonData)
2258*5e7646d2SAndroid Build Coastguard Worker     cupsdCreateCommonData();
2259*5e7646d2SAndroid Build Coastguard Worker 
2260*5e7646d2SAndroid Build Coastguard Worker   _cupsRWLockWrite(&p->lock);
2261*5e7646d2SAndroid Build Coastguard Worker 
2262*5e7646d2SAndroid Build Coastguard Worker  /*
2263*5e7646d2SAndroid Build Coastguard Worker   * Clear out old filters, if any...
2264*5e7646d2SAndroid Build Coastguard Worker   */
2265*5e7646d2SAndroid Build Coastguard Worker 
2266*5e7646d2SAndroid Build Coastguard Worker   delete_printer_filters(p);
2267*5e7646d2SAndroid Build Coastguard Worker 
2268*5e7646d2SAndroid Build Coastguard Worker  /*
2269*5e7646d2SAndroid Build Coastguard Worker   * Figure out the authentication that is required for the printer.
2270*5e7646d2SAndroid Build Coastguard Worker   */
2271*5e7646d2SAndroid Build Coastguard Worker 
2272*5e7646d2SAndroid Build Coastguard Worker   auth_supported = "requesting-user-name";
2273*5e7646d2SAndroid Build Coastguard Worker 
2274*5e7646d2SAndroid Build Coastguard Worker   if (p->type & CUPS_PRINTER_CLASS)
2275*5e7646d2SAndroid Build Coastguard Worker     snprintf(resource, sizeof(resource), "/classes/%s", p->name);
2276*5e7646d2SAndroid Build Coastguard Worker   else
2277*5e7646d2SAndroid Build Coastguard Worker     snprintf(resource, sizeof(resource), "/printers/%s", p->name);
2278*5e7646d2SAndroid Build Coastguard Worker 
2279*5e7646d2SAndroid Build Coastguard Worker   if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL ||
2280*5e7646d2SAndroid Build Coastguard Worker       auth->type == CUPSD_AUTH_NONE)
2281*5e7646d2SAndroid Build Coastguard Worker     auth = cupsdFindPolicyOp(p->op_policy_ptr, IPP_PRINT_JOB);
2282*5e7646d2SAndroid Build Coastguard Worker 
2283*5e7646d2SAndroid Build Coastguard Worker   if (auth)
2284*5e7646d2SAndroid Build Coastguard Worker   {
2285*5e7646d2SAndroid Build Coastguard Worker     int	auth_type;		/* Authentication type */
2286*5e7646d2SAndroid Build Coastguard Worker 
2287*5e7646d2SAndroid Build Coastguard Worker 
2288*5e7646d2SAndroid Build Coastguard Worker     if ((auth_type = auth->type) == CUPSD_AUTH_DEFAULT)
2289*5e7646d2SAndroid Build Coastguard Worker       auth_type = cupsdDefaultAuthType();
2290*5e7646d2SAndroid Build Coastguard Worker 
2291*5e7646d2SAndroid Build Coastguard Worker     if (auth_type == CUPSD_AUTH_BASIC)
2292*5e7646d2SAndroid Build Coastguard Worker       auth_supported = "basic";
2293*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GSSAPI
2294*5e7646d2SAndroid Build Coastguard Worker     else if (auth_type == CUPSD_AUTH_NEGOTIATE)
2295*5e7646d2SAndroid Build Coastguard Worker       auth_supported = "negotiate";
2296*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GSSAPI */
2297*5e7646d2SAndroid Build Coastguard Worker 
2298*5e7646d2SAndroid Build Coastguard Worker     if (auth_type != CUPSD_AUTH_NONE)
2299*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_AUTHENTICATED;
2300*5e7646d2SAndroid Build Coastguard Worker     else
2301*5e7646d2SAndroid Build Coastguard Worker       p->type &= (cups_ptype_t)~CUPS_PRINTER_AUTHENTICATED;
2302*5e7646d2SAndroid Build Coastguard Worker   }
2303*5e7646d2SAndroid Build Coastguard Worker   else
2304*5e7646d2SAndroid Build Coastguard Worker     p->type &= (cups_ptype_t)~CUPS_PRINTER_AUTHENTICATED;
2305*5e7646d2SAndroid Build Coastguard Worker 
2306*5e7646d2SAndroid Build Coastguard Worker  /*
2307*5e7646d2SAndroid Build Coastguard Worker   * Create the required IPP attributes for a printer...
2308*5e7646d2SAndroid Build Coastguard Worker   */
2309*5e7646d2SAndroid Build Coastguard Worker 
2310*5e7646d2SAndroid Build Coastguard Worker   oldattrs = p->attrs;
2311*5e7646d2SAndroid Build Coastguard Worker   p->attrs = ippNew();
2312*5e7646d2SAndroid Build Coastguard Worker 
2313*5e7646d2SAndroid Build Coastguard Worker   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
2314*5e7646d2SAndroid Build Coastguard Worker                "uri-authentication-supported", NULL, auth_supported);
2315*5e7646d2SAndroid Build Coastguard Worker   if (p->printer_id)
2316*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "printer-id", p->printer_id);
2317*5e7646d2SAndroid Build Coastguard Worker   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL,
2318*5e7646d2SAndroid Build Coastguard Worker                p->name);
2319*5e7646d2SAndroid Build Coastguard Worker   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
2320*5e7646d2SAndroid Build Coastguard Worker                NULL, p->location ? p->location : "");
2321*5e7646d2SAndroid Build Coastguard Worker   if (p->geo_location)
2322*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-geo-location", NULL, p->geo_location);
2323*5e7646d2SAndroid Build Coastguard Worker   else
2324*5e7646d2SAndroid Build Coastguard Worker     ippAddOutOfBand(p->attrs, IPP_TAG_PRINTER, IPP_TAG_UNKNOWN, "printer-geo-location");
2325*5e7646d2SAndroid Build Coastguard Worker   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
2326*5e7646d2SAndroid Build Coastguard Worker                NULL, p->info ? p->info : "");
2327*5e7646d2SAndroid Build Coastguard Worker   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-organization", NULL, p->organization ? p->organization : "");
2328*5e7646d2SAndroid Build Coastguard Worker   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-organizational-unit", NULL, p->organizational_unit ? p->organizational_unit : "");
2329*5e7646d2SAndroid Build Coastguard Worker   ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uuid", NULL, p->uuid);
2330*5e7646d2SAndroid Build Coastguard Worker 
2331*5e7646d2SAndroid Build Coastguard Worker   if (cupsArrayCount(p->users) > 0)
2332*5e7646d2SAndroid Build Coastguard Worker   {
2333*5e7646d2SAndroid Build Coastguard Worker     if (p->deny_users)
2334*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
2335*5e7646d2SAndroid Build Coastguard Worker                            "requesting-user-name-denied",
2336*5e7646d2SAndroid Build Coastguard Worker 			   cupsArrayCount(p->users), NULL, NULL);
2337*5e7646d2SAndroid Build Coastguard Worker     else
2338*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
2339*5e7646d2SAndroid Build Coastguard Worker                            "requesting-user-name-allowed",
2340*5e7646d2SAndroid Build Coastguard Worker 			   cupsArrayCount(p->users), NULL, NULL);
2341*5e7646d2SAndroid Build Coastguard Worker 
2342*5e7646d2SAndroid Build Coastguard Worker     for (i = 0, name = (char *)cupsArrayFirst(p->users);
2343*5e7646d2SAndroid Build Coastguard Worker          name;
2344*5e7646d2SAndroid Build Coastguard Worker 	 i ++, name = (char *)cupsArrayNext(p->users))
2345*5e7646d2SAndroid Build Coastguard Worker       attr->values[i].string.text = _cupsStrAlloc(name);
2346*5e7646d2SAndroid Build Coastguard Worker   }
2347*5e7646d2SAndroid Build Coastguard Worker 
2348*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
2349*5e7646d2SAndroid Build Coastguard Worker                 "job-quota-period", p->quota_period);
2350*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
2351*5e7646d2SAndroid Build Coastguard Worker                 "job-k-limit", p->k_limit);
2352*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
2353*5e7646d2SAndroid Build Coastguard Worker                 "job-page-limit", p->page_limit);
2354*5e7646d2SAndroid Build Coastguard Worker   if (p->num_auth_info_required > 0 && strcmp(p->auth_info_required[0], "none"))
2355*5e7646d2SAndroid Build Coastguard Worker     ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
2356*5e7646d2SAndroid Build Coastguard Worker 		  "auth-info-required", p->num_auth_info_required, NULL,
2357*5e7646d2SAndroid Build Coastguard Worker 		  p->auth_info_required);
2358*5e7646d2SAndroid Build Coastguard Worker 
2359*5e7646d2SAndroid Build Coastguard Worker   if (cupsArrayCount(Banners) > 0)
2360*5e7646d2SAndroid Build Coastguard Worker   {
2361*5e7646d2SAndroid Build Coastguard Worker    /*
2362*5e7646d2SAndroid Build Coastguard Worker     * Setup the job-sheets-default attribute...
2363*5e7646d2SAndroid Build Coastguard Worker     */
2364*5e7646d2SAndroid Build Coastguard Worker 
2365*5e7646d2SAndroid Build Coastguard Worker     attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
2366*5e7646d2SAndroid Build Coastguard Worker                 	 "job-sheets-default", 2, NULL, NULL);
2367*5e7646d2SAndroid Build Coastguard Worker 
2368*5e7646d2SAndroid Build Coastguard Worker     if (attr != NULL)
2369*5e7646d2SAndroid Build Coastguard Worker     {
2370*5e7646d2SAndroid Build Coastguard Worker       attr->values[0].string.text = _cupsStrAlloc(Classification ?
2371*5e7646d2SAndroid Build Coastguard Worker 	                                   Classification : p->job_sheets[0]);
2372*5e7646d2SAndroid Build Coastguard Worker       attr->values[1].string.text = _cupsStrAlloc(Classification ?
2373*5e7646d2SAndroid Build Coastguard Worker 	                                   Classification : p->job_sheets[1]);
2374*5e7646d2SAndroid Build Coastguard Worker     }
2375*5e7646d2SAndroid Build Coastguard Worker   }
2376*5e7646d2SAndroid Build Coastguard Worker 
2377*5e7646d2SAndroid Build Coastguard Worker   p->raw    = 0;
2378*5e7646d2SAndroid Build Coastguard Worker   p->remote = 0;
2379*5e7646d2SAndroid Build Coastguard Worker 
2380*5e7646d2SAndroid Build Coastguard Worker  /*
2381*5e7646d2SAndroid Build Coastguard Worker   * Assign additional attributes depending on whether this is a printer
2382*5e7646d2SAndroid Build Coastguard Worker   * or class...
2383*5e7646d2SAndroid Build Coastguard Worker   */
2384*5e7646d2SAndroid Build Coastguard Worker 
2385*5e7646d2SAndroid Build Coastguard Worker   if (p->type & CUPS_PRINTER_CLASS)
2386*5e7646d2SAndroid Build Coastguard Worker   {
2387*5e7646d2SAndroid Build Coastguard Worker     p->raw = 1;
2388*5e7646d2SAndroid Build Coastguard Worker     p->type &= (cups_ptype_t)~CUPS_PRINTER_OPTIONS;
2389*5e7646d2SAndroid Build Coastguard Worker 
2390*5e7646d2SAndroid Build Coastguard Worker    /*
2391*5e7646d2SAndroid Build Coastguard Worker     * Add class-specific attributes...
2392*5e7646d2SAndroid Build Coastguard Worker     */
2393*5e7646d2SAndroid Build Coastguard Worker 
2394*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
2395*5e7646d2SAndroid Build Coastguard Worker 		 "printer-make-and-model", NULL, "Local Printer Class");
2396*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
2397*5e7646d2SAndroid Build Coastguard Worker 		 "file:///dev/null");
2398*5e7646d2SAndroid Build Coastguard Worker 
2399*5e7646d2SAndroid Build Coastguard Worker     if (p->num_printers > 0)
2400*5e7646d2SAndroid Build Coastguard Worker     {
2401*5e7646d2SAndroid Build Coastguard Worker      /*
2402*5e7646d2SAndroid Build Coastguard Worker       * Add a list of member names; URIs are added in copy_printer_attrs...
2403*5e7646d2SAndroid Build Coastguard Worker       */
2404*5e7646d2SAndroid Build Coastguard Worker 
2405*5e7646d2SAndroid Build Coastguard Worker       attr    = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
2406*5e7646d2SAndroid Build Coastguard Worker 			      "member-names", p->num_printers, NULL, NULL);
2407*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_OPTIONS;
2408*5e7646d2SAndroid Build Coastguard Worker 
2409*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < p->num_printers; i ++)
2410*5e7646d2SAndroid Build Coastguard Worker       {
2411*5e7646d2SAndroid Build Coastguard Worker 	if (attr != NULL)
2412*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[i].string.text = _cupsStrAlloc(p->printers[i]->name);
2413*5e7646d2SAndroid Build Coastguard Worker 
2414*5e7646d2SAndroid Build Coastguard Worker 	p->type &= (cups_ptype_t)~CUPS_PRINTER_OPTIONS | p->printers[i]->type;
2415*5e7646d2SAndroid Build Coastguard Worker       }
2416*5e7646d2SAndroid Build Coastguard Worker     }
2417*5e7646d2SAndroid Build Coastguard Worker   }
2418*5e7646d2SAndroid Build Coastguard Worker   else
2419*5e7646d2SAndroid Build Coastguard Worker   {
2420*5e7646d2SAndroid Build Coastguard Worker    /*
2421*5e7646d2SAndroid Build Coastguard Worker     * Add printer-specific attributes...
2422*5e7646d2SAndroid Build Coastguard Worker     */
2423*5e7646d2SAndroid Build Coastguard Worker 
2424*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", NULL,
2425*5e7646d2SAndroid Build Coastguard Worker 		 p->sanitized_device_uri);
2426*5e7646d2SAndroid Build Coastguard Worker 
2427*5e7646d2SAndroid Build Coastguard Worker    /*
2428*5e7646d2SAndroid Build Coastguard Worker     * Assign additional attributes from the PPD file (if any)...
2429*5e7646d2SAndroid Build Coastguard Worker     */
2430*5e7646d2SAndroid Build Coastguard Worker 
2431*5e7646d2SAndroid Build Coastguard Worker     load_ppd(p);
2432*5e7646d2SAndroid Build Coastguard Worker 
2433*5e7646d2SAndroid Build Coastguard Worker    /*
2434*5e7646d2SAndroid Build Coastguard Worker     * Add filters for printer...
2435*5e7646d2SAndroid Build Coastguard Worker     */
2436*5e7646d2SAndroid Build Coastguard Worker 
2437*5e7646d2SAndroid Build Coastguard Worker     cupsdSetPrinterReasons(p, "-cups-missing-filter-warning,"
2438*5e7646d2SAndroid Build Coastguard Worker 			      "cups-insecure-filter-warning");
2439*5e7646d2SAndroid Build Coastguard Worker 
2440*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->filters)
2441*5e7646d2SAndroid Build Coastguard Worker     {
2442*5e7646d2SAndroid Build Coastguard Worker       for (filter = (char *)cupsArrayFirst(p->pc->filters);
2443*5e7646d2SAndroid Build Coastguard Worker 	   filter;
2444*5e7646d2SAndroid Build Coastguard Worker 	   filter = (char *)cupsArrayNext(p->pc->filters))
2445*5e7646d2SAndroid Build Coastguard Worker 	add_printer_filter(p, p->filetype, filter);
2446*5e7646d2SAndroid Build Coastguard Worker     }
2447*5e7646d2SAndroid Build Coastguard Worker     else if (!(p->type & CUPS_PRINTER_REMOTE))
2448*5e7646d2SAndroid Build Coastguard Worker     {
2449*5e7646d2SAndroid Build Coastguard Worker      /*
2450*5e7646d2SAndroid Build Coastguard Worker       * Add a filter from application/vnd.cups-raw to printer/name to
2451*5e7646d2SAndroid Build Coastguard Worker       * handle "raw" printing by users.
2452*5e7646d2SAndroid Build Coastguard Worker       */
2453*5e7646d2SAndroid Build Coastguard Worker 
2454*5e7646d2SAndroid Build Coastguard Worker       add_printer_filter(p, p->filetype, "application/vnd.cups-raw 0 -");
2455*5e7646d2SAndroid Build Coastguard Worker 
2456*5e7646d2SAndroid Build Coastguard Worker      /*
2457*5e7646d2SAndroid Build Coastguard Worker       * Add a PostScript filter, since this is still possibly PS printer.
2458*5e7646d2SAndroid Build Coastguard Worker       */
2459*5e7646d2SAndroid Build Coastguard Worker 
2460*5e7646d2SAndroid Build Coastguard Worker       add_printer_filter(p, p->filetype,
2461*5e7646d2SAndroid Build Coastguard Worker 			 "application/vnd.cups-postscript 0 -");
2462*5e7646d2SAndroid Build Coastguard Worker     }
2463*5e7646d2SAndroid Build Coastguard Worker 
2464*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->prefilters)
2465*5e7646d2SAndroid Build Coastguard Worker     {
2466*5e7646d2SAndroid Build Coastguard Worker       if (!p->prefiltertype)
2467*5e7646d2SAndroid Build Coastguard Worker 	p->prefiltertype = mimeAddType(MimeDatabase, "prefilter", p->name);
2468*5e7646d2SAndroid Build Coastguard Worker 
2469*5e7646d2SAndroid Build Coastguard Worker       for (filter = (char *)cupsArrayFirst(p->pc->prefilters);
2470*5e7646d2SAndroid Build Coastguard Worker 	   filter;
2471*5e7646d2SAndroid Build Coastguard Worker 	   filter = (char *)cupsArrayNext(p->pc->prefilters))
2472*5e7646d2SAndroid Build Coastguard Worker 	add_printer_filter(p, p->prefiltertype, filter);
2473*5e7646d2SAndroid Build Coastguard Worker     }
2474*5e7646d2SAndroid Build Coastguard Worker   }
2475*5e7646d2SAndroid Build Coastguard Worker 
2476*5e7646d2SAndroid Build Coastguard Worker  /*
2477*5e7646d2SAndroid Build Coastguard Worker   * Copy marker attributes as needed...
2478*5e7646d2SAndroid Build Coastguard Worker   */
2479*5e7646d2SAndroid Build Coastguard Worker 
2480*5e7646d2SAndroid Build Coastguard Worker   if (oldattrs)
2481*5e7646d2SAndroid Build Coastguard Worker   {
2482*5e7646d2SAndroid Build Coastguard Worker     ipp_attribute_t *oldattr;		/* Old attribute */
2483*5e7646d2SAndroid Build Coastguard Worker 
2484*5e7646d2SAndroid Build Coastguard Worker 
2485*5e7646d2SAndroid Build Coastguard Worker     if ((oldattr = ippFindAttribute(oldattrs, "marker-colors",
2486*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_NAME)) != NULL)
2487*5e7646d2SAndroid Build Coastguard Worker     {
2488*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
2489*5e7646d2SAndroid Build Coastguard Worker                                 "marker-colors", oldattr->num_values, NULL,
2490*5e7646d2SAndroid Build Coastguard Worker 				NULL)) != NULL)
2491*5e7646d2SAndroid Build Coastguard Worker       {
2492*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < oldattr->num_values; i ++)
2493*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[i].string.text =
2494*5e7646d2SAndroid Build Coastguard Worker 	      _cupsStrAlloc(oldattr->values[i].string.text);
2495*5e7646d2SAndroid Build Coastguard Worker       }
2496*5e7646d2SAndroid Build Coastguard Worker     }
2497*5e7646d2SAndroid Build Coastguard Worker 
2498*5e7646d2SAndroid Build Coastguard Worker     if ((oldattr = ippFindAttribute(oldattrs, "marker-levels",
2499*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_INTEGER)) != NULL)
2500*5e7646d2SAndroid Build Coastguard Worker     {
2501*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
2502*5e7646d2SAndroid Build Coastguard Worker                                  "marker-levels", oldattr->num_values,
2503*5e7646d2SAndroid Build Coastguard Worker 				 NULL)) != NULL)
2504*5e7646d2SAndroid Build Coastguard Worker       {
2505*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < oldattr->num_values; i ++)
2506*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[i].integer = oldattr->values[i].integer;
2507*5e7646d2SAndroid Build Coastguard Worker       }
2508*5e7646d2SAndroid Build Coastguard Worker     }
2509*5e7646d2SAndroid Build Coastguard Worker 
2510*5e7646d2SAndroid Build Coastguard Worker     if ((oldattr = ippFindAttribute(oldattrs, "marker-message",
2511*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_TEXT)) != NULL)
2512*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "marker-message",
2513*5e7646d2SAndroid Build Coastguard Worker                    NULL, oldattr->values[0].string.text);
2514*5e7646d2SAndroid Build Coastguard Worker 
2515*5e7646d2SAndroid Build Coastguard Worker     if ((oldattr = ippFindAttribute(oldattrs, "marker-low-levels",
2516*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_INTEGER)) != NULL)
2517*5e7646d2SAndroid Build Coastguard Worker     {
2518*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
2519*5e7646d2SAndroid Build Coastguard Worker                                  "marker-low-levels", oldattr->num_values,
2520*5e7646d2SAndroid Build Coastguard Worker 				 NULL)) != NULL)
2521*5e7646d2SAndroid Build Coastguard Worker       {
2522*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < oldattr->num_values; i ++)
2523*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[i].integer = oldattr->values[i].integer;
2524*5e7646d2SAndroid Build Coastguard Worker       }
2525*5e7646d2SAndroid Build Coastguard Worker     }
2526*5e7646d2SAndroid Build Coastguard Worker 
2527*5e7646d2SAndroid Build Coastguard Worker     if ((oldattr = ippFindAttribute(oldattrs, "marker-high-levels",
2528*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_INTEGER)) != NULL)
2529*5e7646d2SAndroid Build Coastguard Worker     {
2530*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
2531*5e7646d2SAndroid Build Coastguard Worker                                  "marker-high-levels", oldattr->num_values,
2532*5e7646d2SAndroid Build Coastguard Worker 				 NULL)) != NULL)
2533*5e7646d2SAndroid Build Coastguard Worker       {
2534*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < oldattr->num_values; i ++)
2535*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[i].integer = oldattr->values[i].integer;
2536*5e7646d2SAndroid Build Coastguard Worker       }
2537*5e7646d2SAndroid Build Coastguard Worker     }
2538*5e7646d2SAndroid Build Coastguard Worker 
2539*5e7646d2SAndroid Build Coastguard Worker     if ((oldattr = ippFindAttribute(oldattrs, "marker-names",
2540*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_NAME)) != NULL)
2541*5e7646d2SAndroid Build Coastguard Worker     {
2542*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
2543*5e7646d2SAndroid Build Coastguard Worker                                 "marker-names", oldattr->num_values, NULL,
2544*5e7646d2SAndroid Build Coastguard Worker 				NULL)) != NULL)
2545*5e7646d2SAndroid Build Coastguard Worker       {
2546*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < oldattr->num_values; i ++)
2547*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[i].string.text =
2548*5e7646d2SAndroid Build Coastguard Worker 	      _cupsStrAlloc(oldattr->values[i].string.text);
2549*5e7646d2SAndroid Build Coastguard Worker       }
2550*5e7646d2SAndroid Build Coastguard Worker     }
2551*5e7646d2SAndroid Build Coastguard Worker 
2552*5e7646d2SAndroid Build Coastguard Worker     if ((oldattr = ippFindAttribute(oldattrs, "marker-types",
2553*5e7646d2SAndroid Build Coastguard Worker                                     IPP_TAG_KEYWORD)) != NULL)
2554*5e7646d2SAndroid Build Coastguard Worker     {
2555*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
2556*5e7646d2SAndroid Build Coastguard Worker                                 "marker-types", oldattr->num_values, NULL,
2557*5e7646d2SAndroid Build Coastguard Worker 				NULL)) != NULL)
2558*5e7646d2SAndroid Build Coastguard Worker       {
2559*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < oldattr->num_values; i ++)
2560*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[i].string.text =
2561*5e7646d2SAndroid Build Coastguard Worker 	      _cupsStrAlloc(oldattr->values[i].string.text);
2562*5e7646d2SAndroid Build Coastguard Worker       }
2563*5e7646d2SAndroid Build Coastguard Worker     }
2564*5e7646d2SAndroid Build Coastguard Worker 
2565*5e7646d2SAndroid Build Coastguard Worker     ippDelete(oldattrs);
2566*5e7646d2SAndroid Build Coastguard Worker   }
2567*5e7646d2SAndroid Build Coastguard Worker 
2568*5e7646d2SAndroid Build Coastguard Worker  /*
2569*5e7646d2SAndroid Build Coastguard Worker   * Force sharing off for remote queues...
2570*5e7646d2SAndroid Build Coastguard Worker   */
2571*5e7646d2SAndroid Build Coastguard Worker 
2572*5e7646d2SAndroid Build Coastguard Worker   if (p->type & CUPS_PRINTER_REMOTE)
2573*5e7646d2SAndroid Build Coastguard Worker     p->shared = 0;
2574*5e7646d2SAndroid Build Coastguard Worker 
2575*5e7646d2SAndroid Build Coastguard Worker  /*
2576*5e7646d2SAndroid Build Coastguard Worker   * Populate the document-format-supported attribute...
2577*5e7646d2SAndroid Build Coastguard Worker   */
2578*5e7646d2SAndroid Build Coastguard Worker 
2579*5e7646d2SAndroid Build Coastguard Worker   add_printer_formats(p);
2580*5e7646d2SAndroid Build Coastguard Worker 
2581*5e7646d2SAndroid Build Coastguard Worker  /*
2582*5e7646d2SAndroid Build Coastguard Worker   * Add name-default attributes...
2583*5e7646d2SAndroid Build Coastguard Worker   */
2584*5e7646d2SAndroid Build Coastguard Worker 
2585*5e7646d2SAndroid Build Coastguard Worker   add_printer_defaults(p);
2586*5e7646d2SAndroid Build Coastguard Worker 
2587*5e7646d2SAndroid Build Coastguard Worker   _cupsRWUnlock(&p->lock);
2588*5e7646d2SAndroid Build Coastguard Worker 
2589*5e7646d2SAndroid Build Coastguard Worker  /*
2590*5e7646d2SAndroid Build Coastguard Worker   * Let the browse protocols reflect the change
2591*5e7646d2SAndroid Build Coastguard Worker   */
2592*5e7646d2SAndroid Build Coastguard Worker 
2593*5e7646d2SAndroid Build Coastguard Worker   cupsdRegisterPrinter(p);
2594*5e7646d2SAndroid Build Coastguard Worker }
2595*5e7646d2SAndroid Build Coastguard Worker 
2596*5e7646d2SAndroid Build Coastguard Worker 
2597*5e7646d2SAndroid Build Coastguard Worker /*
2598*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdSetPrinterReasons()' - Set/update the reasons strings.
2599*5e7646d2SAndroid Build Coastguard Worker  */
2600*5e7646d2SAndroid Build Coastguard Worker 
2601*5e7646d2SAndroid Build Coastguard Worker int					/* O - 1 if something changed, 0 otherwise */
cupsdSetPrinterReasons(cupsd_printer_t * p,const char * s)2602*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterReasons(
2603*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
2604*5e7646d2SAndroid Build Coastguard Worker     const char      *s)			/* I - Reasons strings */
2605*5e7646d2SAndroid Build Coastguard Worker {
2606*5e7646d2SAndroid Build Coastguard Worker   int		i,			/* Looping var */
2607*5e7646d2SAndroid Build Coastguard Worker 		changed = 0;		/* Did something change? */
2608*5e7646d2SAndroid Build Coastguard Worker   const char	*sptr;			/* Pointer into reasons */
2609*5e7646d2SAndroid Build Coastguard Worker   char		reason[255],		/* Reason string */
2610*5e7646d2SAndroid Build Coastguard Worker 		*rptr;			/* Pointer into reason */
2611*5e7646d2SAndroid Build Coastguard Worker 
2612*5e7646d2SAndroid Build Coastguard Worker 
2613*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
2614*5e7646d2SAndroid Build Coastguard Worker 		  "cupsdSetPrinterReasons(p=%p(%s),s=\"%s\"", p, p->name, s);
2615*5e7646d2SAndroid Build Coastguard Worker 
2616*5e7646d2SAndroid Build Coastguard Worker   if (s[0] == '-' || s[0] == '+')
2617*5e7646d2SAndroid Build Coastguard Worker   {
2618*5e7646d2SAndroid Build Coastguard Worker    /*
2619*5e7646d2SAndroid Build Coastguard Worker     * Add/remove reasons...
2620*5e7646d2SAndroid Build Coastguard Worker     */
2621*5e7646d2SAndroid Build Coastguard Worker 
2622*5e7646d2SAndroid Build Coastguard Worker     sptr = s + 1;
2623*5e7646d2SAndroid Build Coastguard Worker   }
2624*5e7646d2SAndroid Build Coastguard Worker   else
2625*5e7646d2SAndroid Build Coastguard Worker   {
2626*5e7646d2SAndroid Build Coastguard Worker    /*
2627*5e7646d2SAndroid Build Coastguard Worker     * Replace reasons...
2628*5e7646d2SAndroid Build Coastguard Worker     */
2629*5e7646d2SAndroid Build Coastguard Worker 
2630*5e7646d2SAndroid Build Coastguard Worker     sptr = s;
2631*5e7646d2SAndroid Build Coastguard Worker 
2632*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; i < p->num_reasons; i ++)
2633*5e7646d2SAndroid Build Coastguard Worker       _cupsStrFree(p->reasons[i]);
2634*5e7646d2SAndroid Build Coastguard Worker 
2635*5e7646d2SAndroid Build Coastguard Worker     p->num_reasons = 0;
2636*5e7646d2SAndroid Build Coastguard Worker     changed        = 1;
2637*5e7646d2SAndroid Build Coastguard Worker 
2638*5e7646d2SAndroid Build Coastguard Worker     dirty_printer(p);
2639*5e7646d2SAndroid Build Coastguard Worker   }
2640*5e7646d2SAndroid Build Coastguard Worker 
2641*5e7646d2SAndroid Build Coastguard Worker   if (!strcmp(s, "none"))
2642*5e7646d2SAndroid Build Coastguard Worker     return (changed);
2643*5e7646d2SAndroid Build Coastguard Worker 
2644*5e7646d2SAndroid Build Coastguard Worker  /*
2645*5e7646d2SAndroid Build Coastguard Worker   * Loop through all of the reasons...
2646*5e7646d2SAndroid Build Coastguard Worker   */
2647*5e7646d2SAndroid Build Coastguard Worker 
2648*5e7646d2SAndroid Build Coastguard Worker   while (*sptr)
2649*5e7646d2SAndroid Build Coastguard Worker   {
2650*5e7646d2SAndroid Build Coastguard Worker    /*
2651*5e7646d2SAndroid Build Coastguard Worker     * Skip leading whitespace and commas...
2652*5e7646d2SAndroid Build Coastguard Worker     */
2653*5e7646d2SAndroid Build Coastguard Worker 
2654*5e7646d2SAndroid Build Coastguard Worker     while (isspace(*sptr & 255) || *sptr == ',')
2655*5e7646d2SAndroid Build Coastguard Worker       sptr ++;
2656*5e7646d2SAndroid Build Coastguard Worker 
2657*5e7646d2SAndroid Build Coastguard Worker     for (rptr = reason; *sptr && !isspace(*sptr & 255) && *sptr != ','; sptr ++)
2658*5e7646d2SAndroid Build Coastguard Worker       if (rptr < (reason + sizeof(reason) - 1))
2659*5e7646d2SAndroid Build Coastguard Worker         *rptr++ = *sptr;
2660*5e7646d2SAndroid Build Coastguard Worker 
2661*5e7646d2SAndroid Build Coastguard Worker     if (rptr == reason)
2662*5e7646d2SAndroid Build Coastguard Worker       break;
2663*5e7646d2SAndroid Build Coastguard Worker 
2664*5e7646d2SAndroid Build Coastguard Worker     *rptr = '\0';
2665*5e7646d2SAndroid Build Coastguard Worker 
2666*5e7646d2SAndroid Build Coastguard Worker     if (s[0] == '-')
2667*5e7646d2SAndroid Build Coastguard Worker     {
2668*5e7646d2SAndroid Build Coastguard Worker      /*
2669*5e7646d2SAndroid Build Coastguard Worker       * Remove reason...
2670*5e7646d2SAndroid Build Coastguard Worker       */
2671*5e7646d2SAndroid Build Coastguard Worker 
2672*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < p->num_reasons; i ++)
2673*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(reason, p->reasons[i]))
2674*5e7646d2SAndroid Build Coastguard Worker 	{
2675*5e7646d2SAndroid Build Coastguard Worker 	 /*
2676*5e7646d2SAndroid Build Coastguard Worker 	  * Found a match, so remove it...
2677*5e7646d2SAndroid Build Coastguard Worker 	  */
2678*5e7646d2SAndroid Build Coastguard Worker 
2679*5e7646d2SAndroid Build Coastguard Worker 	  p->num_reasons --;
2680*5e7646d2SAndroid Build Coastguard Worker           changed = 1;
2681*5e7646d2SAndroid Build Coastguard Worker 	  _cupsStrFree(p->reasons[i]);
2682*5e7646d2SAndroid Build Coastguard Worker 
2683*5e7646d2SAndroid Build Coastguard Worker 	  if (i < p->num_reasons)
2684*5e7646d2SAndroid Build Coastguard Worker 	    memmove(p->reasons + i, p->reasons + i + 1, (size_t)(p->num_reasons - i) * sizeof(char *));
2685*5e7646d2SAndroid Build Coastguard Worker 
2686*5e7646d2SAndroid Build Coastguard Worker           if (!strcmp(reason, "paused") && p->state == IPP_PRINTER_STOPPED)
2687*5e7646d2SAndroid Build Coastguard Worker 	    cupsdSetPrinterState(p, IPP_PRINTER_IDLE, 1);
2688*5e7646d2SAndroid Build Coastguard Worker 
2689*5e7646d2SAndroid Build Coastguard Worker           if (!strcmp(reason, "cups-waiting-for-job-completed") && p->job)
2690*5e7646d2SAndroid Build Coastguard Worker             p->job->completed = 0;
2691*5e7646d2SAndroid Build Coastguard Worker 
2692*5e7646d2SAndroid Build Coastguard Worker           if (strcmp(reason, "connecting-to-device"))
2693*5e7646d2SAndroid Build Coastguard Worker 	    dirty_printer(p);
2694*5e7646d2SAndroid Build Coastguard Worker 
2695*5e7646d2SAndroid Build Coastguard Worker 	  break;
2696*5e7646d2SAndroid Build Coastguard Worker 	}
2697*5e7646d2SAndroid Build Coastguard Worker     }
2698*5e7646d2SAndroid Build Coastguard Worker     else if (p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
2699*5e7646d2SAndroid Build Coastguard Worker     {
2700*5e7646d2SAndroid Build Coastguard Worker      /*
2701*5e7646d2SAndroid Build Coastguard Worker       * Add reason...
2702*5e7646d2SAndroid Build Coastguard Worker       */
2703*5e7646d2SAndroid Build Coastguard Worker 
2704*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < p->num_reasons; i ++)
2705*5e7646d2SAndroid Build Coastguard Worker         if (!strcmp(reason, p->reasons[i]))
2706*5e7646d2SAndroid Build Coastguard Worker 	  break;
2707*5e7646d2SAndroid Build Coastguard Worker 
2708*5e7646d2SAndroid Build Coastguard Worker       if (i >= p->num_reasons)
2709*5e7646d2SAndroid Build Coastguard Worker       {
2710*5e7646d2SAndroid Build Coastguard Worker         if (i >= (int)(sizeof(p->reasons) / sizeof(p->reasons[0])))
2711*5e7646d2SAndroid Build Coastguard Worker 	{
2712*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_ALERT,
2713*5e7646d2SAndroid Build Coastguard Worker 	                  "Too many printer-state-reasons values for %s (%d)",
2714*5e7646d2SAndroid Build Coastguard Worker 			  p->name, i + 1);
2715*5e7646d2SAndroid Build Coastguard Worker           return (changed);
2716*5e7646d2SAndroid Build Coastguard Worker         }
2717*5e7646d2SAndroid Build Coastguard Worker 
2718*5e7646d2SAndroid Build Coastguard Worker         p->reasons[i] = _cupsStrAlloc(reason);
2719*5e7646d2SAndroid Build Coastguard Worker 	p->num_reasons ++;
2720*5e7646d2SAndroid Build Coastguard Worker         changed = 1;
2721*5e7646d2SAndroid Build Coastguard Worker 
2722*5e7646d2SAndroid Build Coastguard Worker 	if (!strcmp(reason, "paused") && p->state != IPP_PRINTER_STOPPED)
2723*5e7646d2SAndroid Build Coastguard Worker 	  cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, 1);
2724*5e7646d2SAndroid Build Coastguard Worker 
2725*5e7646d2SAndroid Build Coastguard Worker 	if (!strcmp(reason, "cups-waiting-for-job-completed") && p->job)
2726*5e7646d2SAndroid Build Coastguard Worker 	  p->job->completed = 1;
2727*5e7646d2SAndroid Build Coastguard Worker 
2728*5e7646d2SAndroid Build Coastguard Worker 	if (strcmp(reason, "connecting-to-device"))
2729*5e7646d2SAndroid Build Coastguard Worker 	  dirty_printer(p);
2730*5e7646d2SAndroid Build Coastguard Worker       }
2731*5e7646d2SAndroid Build Coastguard Worker     }
2732*5e7646d2SAndroid Build Coastguard Worker   }
2733*5e7646d2SAndroid Build Coastguard Worker 
2734*5e7646d2SAndroid Build Coastguard Worker   return (changed);
2735*5e7646d2SAndroid Build Coastguard Worker }
2736*5e7646d2SAndroid Build Coastguard Worker 
2737*5e7646d2SAndroid Build Coastguard Worker 
2738*5e7646d2SAndroid Build Coastguard Worker /*
2739*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdSetPrinterState()' - Update the current state of a printer.
2740*5e7646d2SAndroid Build Coastguard Worker  */
2741*5e7646d2SAndroid Build Coastguard Worker 
2742*5e7646d2SAndroid Build Coastguard Worker void
cupsdSetPrinterState(cupsd_printer_t * p,ipp_pstate_t s,int update)2743*5e7646d2SAndroid Build Coastguard Worker cupsdSetPrinterState(
2744*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer to change */
2745*5e7646d2SAndroid Build Coastguard Worker     ipp_pstate_t    s,			/* I - New state */
2746*5e7646d2SAndroid Build Coastguard Worker     int             update)		/* I - Update printers.conf? */
2747*5e7646d2SAndroid Build Coastguard Worker {
2748*5e7646d2SAndroid Build Coastguard Worker   cupsd_job_t	*job;			/* Current job */
2749*5e7646d2SAndroid Build Coastguard Worker   ipp_pstate_t	old_state;		/* Old printer state */
2750*5e7646d2SAndroid Build Coastguard Worker   static const char * const printer_states[] =
2751*5e7646d2SAndroid Build Coastguard Worker   {					/* State strings */
2752*5e7646d2SAndroid Build Coastguard Worker     "idle",
2753*5e7646d2SAndroid Build Coastguard Worker     "processing",
2754*5e7646d2SAndroid Build Coastguard Worker     "stopped"
2755*5e7646d2SAndroid Build Coastguard Worker   };
2756*5e7646d2SAndroid Build Coastguard Worker 
2757*5e7646d2SAndroid Build Coastguard Worker 
2758*5e7646d2SAndroid Build Coastguard Worker  /*
2759*5e7646d2SAndroid Build Coastguard Worker   * Set the new state...
2760*5e7646d2SAndroid Build Coastguard Worker   */
2761*5e7646d2SAndroid Build Coastguard Worker 
2762*5e7646d2SAndroid Build Coastguard Worker   old_state = p->state;
2763*5e7646d2SAndroid Build Coastguard Worker   p->state  = s;
2764*5e7646d2SAndroid Build Coastguard Worker 
2765*5e7646d2SAndroid Build Coastguard Worker   if (old_state != s)
2766*5e7646d2SAndroid Build Coastguard Worker   {
2767*5e7646d2SAndroid Build Coastguard Worker     cupsdAddEvent(s == IPP_PRINTER_STOPPED ? CUPSD_EVENT_PRINTER_STOPPED :
2768*5e7646d2SAndroid Build Coastguard Worker                       CUPSD_EVENT_PRINTER_STATE, p, NULL,
2769*5e7646d2SAndroid Build Coastguard Worker 		  "%s \"%s\" state changed to %s.",
2770*5e7646d2SAndroid Build Coastguard Worker 		  (p->type & CUPS_PRINTER_CLASS) ? "Class" : "Printer",
2771*5e7646d2SAndroid Build Coastguard Worker 		  p->name, printer_states[p->state - IPP_PRINTER_IDLE]);
2772*5e7646d2SAndroid Build Coastguard Worker 
2773*5e7646d2SAndroid Build Coastguard Worker    /*
2774*5e7646d2SAndroid Build Coastguard Worker     * Let the browse code know this needs to be updated...
2775*5e7646d2SAndroid Build Coastguard Worker     */
2776*5e7646d2SAndroid Build Coastguard Worker 
2777*5e7646d2SAndroid Build Coastguard Worker     p->state_time = time(NULL);
2778*5e7646d2SAndroid Build Coastguard Worker   }
2779*5e7646d2SAndroid Build Coastguard Worker 
2780*5e7646d2SAndroid Build Coastguard Worker  /*
2781*5e7646d2SAndroid Build Coastguard Worker   * Set/clear the paused reason as needed...
2782*5e7646d2SAndroid Build Coastguard Worker   */
2783*5e7646d2SAndroid Build Coastguard Worker 
2784*5e7646d2SAndroid Build Coastguard Worker   if (s == IPP_PRINTER_STOPPED)
2785*5e7646d2SAndroid Build Coastguard Worker     cupsdSetPrinterReasons(p, "+paused");
2786*5e7646d2SAndroid Build Coastguard Worker   else
2787*5e7646d2SAndroid Build Coastguard Worker     cupsdSetPrinterReasons(p, "-paused");
2788*5e7646d2SAndroid Build Coastguard Worker 
2789*5e7646d2SAndroid Build Coastguard Worker   if (old_state != s)
2790*5e7646d2SAndroid Build Coastguard Worker   {
2791*5e7646d2SAndroid Build Coastguard Worker     for (job = (cupsd_job_t *)cupsArrayFirst(ActiveJobs);
2792*5e7646d2SAndroid Build Coastguard Worker 	 job;
2793*5e7646d2SAndroid Build Coastguard Worker 	 job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
2794*5e7646d2SAndroid Build Coastguard Worker       if (job->reasons && job->state_value == IPP_JOB_PENDING &&
2795*5e7646d2SAndroid Build Coastguard Worker 	  !_cups_strcasecmp(job->dest, p->name))
2796*5e7646d2SAndroid Build Coastguard Worker 	ippSetString(job->attrs, &job->reasons, 0,
2797*5e7646d2SAndroid Build Coastguard Worker 		     s == IPP_PRINTER_STOPPED ? "printer-stopped" : "none");
2798*5e7646d2SAndroid Build Coastguard Worker   }
2799*5e7646d2SAndroid Build Coastguard Worker 
2800*5e7646d2SAndroid Build Coastguard Worker  /*
2801*5e7646d2SAndroid Build Coastguard Worker   * Clear the message for the queue when going to processing...
2802*5e7646d2SAndroid Build Coastguard Worker   */
2803*5e7646d2SAndroid Build Coastguard Worker 
2804*5e7646d2SAndroid Build Coastguard Worker   if (s == IPP_PRINTER_PROCESSING)
2805*5e7646d2SAndroid Build Coastguard Worker     p->state_message[0] = '\0';
2806*5e7646d2SAndroid Build Coastguard Worker 
2807*5e7646d2SAndroid Build Coastguard Worker  /*
2808*5e7646d2SAndroid Build Coastguard Worker   * Let the browse protocols reflect the change...
2809*5e7646d2SAndroid Build Coastguard Worker   */
2810*5e7646d2SAndroid Build Coastguard Worker 
2811*5e7646d2SAndroid Build Coastguard Worker   if (update)
2812*5e7646d2SAndroid Build Coastguard Worker     cupsdRegisterPrinter(p);
2813*5e7646d2SAndroid Build Coastguard Worker 
2814*5e7646d2SAndroid Build Coastguard Worker  /*
2815*5e7646d2SAndroid Build Coastguard Worker   * Save the printer configuration if a printer goes from idle or processing
2816*5e7646d2SAndroid Build Coastguard Worker   * to stopped (or visa-versa)...
2817*5e7646d2SAndroid Build Coastguard Worker   */
2818*5e7646d2SAndroid Build Coastguard Worker 
2819*5e7646d2SAndroid Build Coastguard Worker   if (update &&
2820*5e7646d2SAndroid Build Coastguard Worker       (old_state == IPP_PRINTER_STOPPED) != (s == IPP_PRINTER_STOPPED))
2821*5e7646d2SAndroid Build Coastguard Worker     dirty_printer(p);
2822*5e7646d2SAndroid Build Coastguard Worker }
2823*5e7646d2SAndroid Build Coastguard Worker 
2824*5e7646d2SAndroid Build Coastguard Worker 
2825*5e7646d2SAndroid Build Coastguard Worker /*
2826*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdStopPrinter()' - Stop a printer from printing any jobs...
2827*5e7646d2SAndroid Build Coastguard Worker  */
2828*5e7646d2SAndroid Build Coastguard Worker 
2829*5e7646d2SAndroid Build Coastguard Worker void
cupsdStopPrinter(cupsd_printer_t * p,int update)2830*5e7646d2SAndroid Build Coastguard Worker cupsdStopPrinter(cupsd_printer_t *p,	/* I - Printer to stop */
2831*5e7646d2SAndroid Build Coastguard Worker                  int             update)/* I - Update printers.conf? */
2832*5e7646d2SAndroid Build Coastguard Worker {
2833*5e7646d2SAndroid Build Coastguard Worker  /*
2834*5e7646d2SAndroid Build Coastguard Worker   * Set the printer state...
2835*5e7646d2SAndroid Build Coastguard Worker   */
2836*5e7646d2SAndroid Build Coastguard Worker 
2837*5e7646d2SAndroid Build Coastguard Worker   cupsdSetPrinterState(p, IPP_PRINTER_STOPPED, update);
2838*5e7646d2SAndroid Build Coastguard Worker 
2839*5e7646d2SAndroid Build Coastguard Worker  /*
2840*5e7646d2SAndroid Build Coastguard Worker   * See if we have a job printing on this printer...
2841*5e7646d2SAndroid Build Coastguard Worker   */
2842*5e7646d2SAndroid Build Coastguard Worker 
2843*5e7646d2SAndroid Build Coastguard Worker   if (p->job && p->job->state_value == IPP_JOB_PROCESSING)
2844*5e7646d2SAndroid Build Coastguard Worker     cupsdSetJobState(p->job, IPP_JOB_PENDING, CUPSD_JOB_DEFAULT,
2845*5e7646d2SAndroid Build Coastguard Worker                      "Job stopped due to printer being paused.");
2846*5e7646d2SAndroid Build Coastguard Worker }
2847*5e7646d2SAndroid Build Coastguard Worker 
2848*5e7646d2SAndroid Build Coastguard Worker 
2849*5e7646d2SAndroid Build Coastguard Worker /*
2850*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdUpdatePrinterPPD()' - Update keywords in a printer's PPD file.
2851*5e7646d2SAndroid Build Coastguard Worker  */
2852*5e7646d2SAndroid Build Coastguard Worker 
2853*5e7646d2SAndroid Build Coastguard Worker int					/* O - 1 if successful, 0 otherwise */
cupsdUpdatePrinterPPD(cupsd_printer_t * p,int num_keywords,cups_option_t * keywords)2854*5e7646d2SAndroid Build Coastguard Worker cupsdUpdatePrinterPPD(
2855*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p,			/* I - Printer */
2856*5e7646d2SAndroid Build Coastguard Worker     int             num_keywords,	/* I - Number of keywords */
2857*5e7646d2SAndroid Build Coastguard Worker     cups_option_t   *keywords)		/* I - Keywords */
2858*5e7646d2SAndroid Build Coastguard Worker {
2859*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
2860*5e7646d2SAndroid Build Coastguard Worker   cups_file_t	*src,			/* Original file */
2861*5e7646d2SAndroid Build Coastguard Worker 		*dst;			/* New file */
2862*5e7646d2SAndroid Build Coastguard Worker   char		srcfile[1024],		/* Original filename */
2863*5e7646d2SAndroid Build Coastguard Worker 		dstfile[1024],		/* New filename */
2864*5e7646d2SAndroid Build Coastguard Worker 		line[1024],		/* Line from file */
2865*5e7646d2SAndroid Build Coastguard Worker 		keystring[41];		/* Keyword from line */
2866*5e7646d2SAndroid Build Coastguard Worker   cups_option_t	*keyword;		/* Current keyword */
2867*5e7646d2SAndroid Build Coastguard Worker 
2868*5e7646d2SAndroid Build Coastguard Worker 
2869*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_INFO, "Updating keywords in PPD file for %s...",
2870*5e7646d2SAndroid Build Coastguard Worker                   p->name);
2871*5e7646d2SAndroid Build Coastguard Worker 
2872*5e7646d2SAndroid Build Coastguard Worker  /*
2873*5e7646d2SAndroid Build Coastguard Worker   * Get the old and new PPD filenames...
2874*5e7646d2SAndroid Build Coastguard Worker   */
2875*5e7646d2SAndroid Build Coastguard Worker 
2876*5e7646d2SAndroid Build Coastguard Worker   snprintf(srcfile, sizeof(srcfile), "%s/ppd/%s.ppd.O", ServerRoot, p->name);
2877*5e7646d2SAndroid Build Coastguard Worker   snprintf(dstfile, sizeof(srcfile), "%s/ppd/%s.ppd", ServerRoot, p->name);
2878*5e7646d2SAndroid Build Coastguard Worker 
2879*5e7646d2SAndroid Build Coastguard Worker  /*
2880*5e7646d2SAndroid Build Coastguard Worker   * Rename the old file and open the old and new...
2881*5e7646d2SAndroid Build Coastguard Worker   */
2882*5e7646d2SAndroid Build Coastguard Worker 
2883*5e7646d2SAndroid Build Coastguard Worker   if (rename(dstfile, srcfile))
2884*5e7646d2SAndroid Build Coastguard Worker   {
2885*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to backup PPD file for %s: %s",
2886*5e7646d2SAndroid Build Coastguard Worker                     p->name, strerror(errno));
2887*5e7646d2SAndroid Build Coastguard Worker     return (0);
2888*5e7646d2SAndroid Build Coastguard Worker   }
2889*5e7646d2SAndroid Build Coastguard Worker 
2890*5e7646d2SAndroid Build Coastguard Worker   if ((src = cupsFileOpen(srcfile, "r")) == NULL)
2891*5e7646d2SAndroid Build Coastguard Worker   {
2892*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open PPD file \"%s\": %s",
2893*5e7646d2SAndroid Build Coastguard Worker                     srcfile, strerror(errno));
2894*5e7646d2SAndroid Build Coastguard Worker     rename(srcfile, dstfile);
2895*5e7646d2SAndroid Build Coastguard Worker     return (0);
2896*5e7646d2SAndroid Build Coastguard Worker   }
2897*5e7646d2SAndroid Build Coastguard Worker 
2898*5e7646d2SAndroid Build Coastguard Worker   if ((dst = cupsFileOpen(dstfile, "w")) == NULL)
2899*5e7646d2SAndroid Build Coastguard Worker   {
2900*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create PPD file \"%s\": %s",
2901*5e7646d2SAndroid Build Coastguard Worker                     dstfile, strerror(errno));
2902*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(src);
2903*5e7646d2SAndroid Build Coastguard Worker     rename(srcfile, dstfile);
2904*5e7646d2SAndroid Build Coastguard Worker     return (0);
2905*5e7646d2SAndroid Build Coastguard Worker   }
2906*5e7646d2SAndroid Build Coastguard Worker 
2907*5e7646d2SAndroid Build Coastguard Worker  /*
2908*5e7646d2SAndroid Build Coastguard Worker   * Copy the first line and then write out all of the keywords...
2909*5e7646d2SAndroid Build Coastguard Worker   */
2910*5e7646d2SAndroid Build Coastguard Worker 
2911*5e7646d2SAndroid Build Coastguard Worker   if (!cupsFileGets(src, line, sizeof(line)))
2912*5e7646d2SAndroid Build Coastguard Worker   {
2913*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to read PPD file \"%s\": %s",
2914*5e7646d2SAndroid Build Coastguard Worker                     srcfile, strerror(errno));
2915*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(src);
2916*5e7646d2SAndroid Build Coastguard Worker     cupsFileClose(dst);
2917*5e7646d2SAndroid Build Coastguard Worker     rename(srcfile, dstfile);
2918*5e7646d2SAndroid Build Coastguard Worker     return (0);
2919*5e7646d2SAndroid Build Coastguard Worker   }
2920*5e7646d2SAndroid Build Coastguard Worker 
2921*5e7646d2SAndroid Build Coastguard Worker   cupsFilePrintf(dst, "%s\n", line);
2922*5e7646d2SAndroid Build Coastguard Worker 
2923*5e7646d2SAndroid Build Coastguard Worker   for (i = num_keywords, keyword = keywords; i > 0; i --, keyword ++)
2924*5e7646d2SAndroid Build Coastguard Worker   {
2925*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG, "*%s: %s", keyword->name, keyword->value);
2926*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(dst, "*%s: %s\n", keyword->name, keyword->value);
2927*5e7646d2SAndroid Build Coastguard Worker   }
2928*5e7646d2SAndroid Build Coastguard Worker 
2929*5e7646d2SAndroid Build Coastguard Worker  /*
2930*5e7646d2SAndroid Build Coastguard Worker   * Then copy the rest of the PPD file, dropping any keywords we changed.
2931*5e7646d2SAndroid Build Coastguard Worker   */
2932*5e7646d2SAndroid Build Coastguard Worker 
2933*5e7646d2SAndroid Build Coastguard Worker   while (cupsFileGets(src, line, sizeof(line)))
2934*5e7646d2SAndroid Build Coastguard Worker   {
2935*5e7646d2SAndroid Build Coastguard Worker    /*
2936*5e7646d2SAndroid Build Coastguard Worker     * Skip keywords we've already set...
2937*5e7646d2SAndroid Build Coastguard Worker     */
2938*5e7646d2SAndroid Build Coastguard Worker 
2939*5e7646d2SAndroid Build Coastguard Worker     if (sscanf(line, "*%40[^:]:", keystring) == 1 &&
2940*5e7646d2SAndroid Build Coastguard Worker         cupsGetOption(keystring, num_keywords, keywords))
2941*5e7646d2SAndroid Build Coastguard Worker       continue;
2942*5e7646d2SAndroid Build Coastguard Worker 
2943*5e7646d2SAndroid Build Coastguard Worker    /*
2944*5e7646d2SAndroid Build Coastguard Worker     * Otherwise write the line...
2945*5e7646d2SAndroid Build Coastguard Worker     */
2946*5e7646d2SAndroid Build Coastguard Worker 
2947*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(dst, "%s\n", line);
2948*5e7646d2SAndroid Build Coastguard Worker   }
2949*5e7646d2SAndroid Build Coastguard Worker 
2950*5e7646d2SAndroid Build Coastguard Worker  /*
2951*5e7646d2SAndroid Build Coastguard Worker   * Close files and return...
2952*5e7646d2SAndroid Build Coastguard Worker   */
2953*5e7646d2SAndroid Build Coastguard Worker 
2954*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(src);
2955*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(dst);
2956*5e7646d2SAndroid Build Coastguard Worker 
2957*5e7646d2SAndroid Build Coastguard Worker   return (1);
2958*5e7646d2SAndroid Build Coastguard Worker }
2959*5e7646d2SAndroid Build Coastguard Worker 
2960*5e7646d2SAndroid Build Coastguard Worker 
2961*5e7646d2SAndroid Build Coastguard Worker /*
2962*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdUpdatePrinters()' - Update printers after a partial reload.
2963*5e7646d2SAndroid Build Coastguard Worker  */
2964*5e7646d2SAndroid Build Coastguard Worker 
2965*5e7646d2SAndroid Build Coastguard Worker void
cupsdUpdatePrinters(void)2966*5e7646d2SAndroid Build Coastguard Worker cupsdUpdatePrinters(void)
2967*5e7646d2SAndroid Build Coastguard Worker {
2968*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Current printer */
2969*5e7646d2SAndroid Build Coastguard Worker 
2970*5e7646d2SAndroid Build Coastguard Worker 
2971*5e7646d2SAndroid Build Coastguard Worker  /*
2972*5e7646d2SAndroid Build Coastguard Worker   * Loop through the printers and recreate the printer attributes
2973*5e7646d2SAndroid Build Coastguard Worker   * for any local printers since the policy and/or access control
2974*5e7646d2SAndroid Build Coastguard Worker   * stuff may have changed.  Also, if browsing is disabled, remove
2975*5e7646d2SAndroid Build Coastguard Worker   * any remote printers...
2976*5e7646d2SAndroid Build Coastguard Worker   */
2977*5e7646d2SAndroid Build Coastguard Worker 
2978*5e7646d2SAndroid Build Coastguard Worker   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
2979*5e7646d2SAndroid Build Coastguard Worker        p;
2980*5e7646d2SAndroid Build Coastguard Worker        p = (cupsd_printer_t *)cupsArrayNext(Printers))
2981*5e7646d2SAndroid Build Coastguard Worker   {
2982*5e7646d2SAndroid Build Coastguard Worker    /*
2983*5e7646d2SAndroid Build Coastguard Worker     * Update the operation policy pointer...
2984*5e7646d2SAndroid Build Coastguard Worker     */
2985*5e7646d2SAndroid Build Coastguard Worker 
2986*5e7646d2SAndroid Build Coastguard Worker     if ((p->op_policy_ptr = cupsdFindPolicy(p->op_policy)) == NULL)
2987*5e7646d2SAndroid Build Coastguard Worker       p->op_policy_ptr = DefaultPolicyPtr;
2988*5e7646d2SAndroid Build Coastguard Worker 
2989*5e7646d2SAndroid Build Coastguard Worker    /*
2990*5e7646d2SAndroid Build Coastguard Worker     * Update printer attributes...
2991*5e7646d2SAndroid Build Coastguard Worker     */
2992*5e7646d2SAndroid Build Coastguard Worker 
2993*5e7646d2SAndroid Build Coastguard Worker     cupsdSetPrinterAttrs(p);
2994*5e7646d2SAndroid Build Coastguard Worker   }
2995*5e7646d2SAndroid Build Coastguard Worker }
2996*5e7646d2SAndroid Build Coastguard Worker 
2997*5e7646d2SAndroid Build Coastguard Worker 
2998*5e7646d2SAndroid Build Coastguard Worker /*
2999*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdValidateDest()' - Validate a printer/class destination.
3000*5e7646d2SAndroid Build Coastguard Worker  */
3001*5e7646d2SAndroid Build Coastguard Worker 
3002*5e7646d2SAndroid Build Coastguard Worker const char *				/* O - Printer or class name */
cupsdValidateDest(const char * uri,cups_ptype_t * dtype,cupsd_printer_t ** printer)3003*5e7646d2SAndroid Build Coastguard Worker cupsdValidateDest(
3004*5e7646d2SAndroid Build Coastguard Worker     const char      *uri,		/* I - Printer URI */
3005*5e7646d2SAndroid Build Coastguard Worker     cups_ptype_t    *dtype,		/* O - Type (printer or class) */
3006*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t **printer)		/* O - Printer pointer */
3007*5e7646d2SAndroid Build Coastguard Worker {
3008*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Current printer */
3009*5e7646d2SAndroid Build Coastguard Worker   char			localname[1024],/* Localized hostname */
3010*5e7646d2SAndroid Build Coastguard Worker 			*lptr,		/* Pointer into localized hostname */
3011*5e7646d2SAndroid Build Coastguard Worker 			*sptr,		/* Pointer into server name */
3012*5e7646d2SAndroid Build Coastguard Worker 			*rptr,		/* Pointer into resource */
3013*5e7646d2SAndroid Build Coastguard Worker 			scheme[32],	/* Scheme portion of URI */
3014*5e7646d2SAndroid Build Coastguard Worker 			username[64],	/* Username portion of URI */
3015*5e7646d2SAndroid Build Coastguard Worker 			hostname[HTTP_MAX_HOST],
3016*5e7646d2SAndroid Build Coastguard Worker 					/* Host portion of URI */
3017*5e7646d2SAndroid Build Coastguard Worker 			resource[HTTP_MAX_URI];
3018*5e7646d2SAndroid Build Coastguard Worker 					/* Resource portion of URI */
3019*5e7646d2SAndroid Build Coastguard Worker   int			port;		/* Port portion of URI */
3020*5e7646d2SAndroid Build Coastguard Worker 
3021*5e7646d2SAndroid Build Coastguard Worker 
3022*5e7646d2SAndroid Build Coastguard Worker  /*
3023*5e7646d2SAndroid Build Coastguard Worker   * Initialize return values...
3024*5e7646d2SAndroid Build Coastguard Worker   */
3025*5e7646d2SAndroid Build Coastguard Worker 
3026*5e7646d2SAndroid Build Coastguard Worker   if (printer)
3027*5e7646d2SAndroid Build Coastguard Worker     *printer = NULL;
3028*5e7646d2SAndroid Build Coastguard Worker 
3029*5e7646d2SAndroid Build Coastguard Worker   if (dtype)
3030*5e7646d2SAndroid Build Coastguard Worker     *dtype = (cups_ptype_t)0;
3031*5e7646d2SAndroid Build Coastguard Worker 
3032*5e7646d2SAndroid Build Coastguard Worker  /*
3033*5e7646d2SAndroid Build Coastguard Worker   * Pull the hostname and resource from the URI...
3034*5e7646d2SAndroid Build Coastguard Worker   */
3035*5e7646d2SAndroid Build Coastguard Worker 
3036*5e7646d2SAndroid Build Coastguard Worker   httpSeparateURI(HTTP_URI_CODING_ALL, uri, scheme, sizeof(scheme),
3037*5e7646d2SAndroid Build Coastguard Worker                   username, sizeof(username), hostname, sizeof(hostname),
3038*5e7646d2SAndroid Build Coastguard Worker 		  &port, resource, sizeof(resource));
3039*5e7646d2SAndroid Build Coastguard Worker 
3040*5e7646d2SAndroid Build Coastguard Worker  /*
3041*5e7646d2SAndroid Build Coastguard Worker   * See if the resource is a class or printer...
3042*5e7646d2SAndroid Build Coastguard Worker   */
3043*5e7646d2SAndroid Build Coastguard Worker 
3044*5e7646d2SAndroid Build Coastguard Worker   if (!strncmp(resource, "/classes/", 9))
3045*5e7646d2SAndroid Build Coastguard Worker   {
3046*5e7646d2SAndroid Build Coastguard Worker    /*
3047*5e7646d2SAndroid Build Coastguard Worker     * Class...
3048*5e7646d2SAndroid Build Coastguard Worker     */
3049*5e7646d2SAndroid Build Coastguard Worker 
3050*5e7646d2SAndroid Build Coastguard Worker     rptr = resource + 9;
3051*5e7646d2SAndroid Build Coastguard Worker   }
3052*5e7646d2SAndroid Build Coastguard Worker   else if (!strncmp(resource, "/printers/", 10))
3053*5e7646d2SAndroid Build Coastguard Worker   {
3054*5e7646d2SAndroid Build Coastguard Worker    /*
3055*5e7646d2SAndroid Build Coastguard Worker     * Printer...
3056*5e7646d2SAndroid Build Coastguard Worker     */
3057*5e7646d2SAndroid Build Coastguard Worker 
3058*5e7646d2SAndroid Build Coastguard Worker     rptr = resource + 10;
3059*5e7646d2SAndroid Build Coastguard Worker   }
3060*5e7646d2SAndroid Build Coastguard Worker   else
3061*5e7646d2SAndroid Build Coastguard Worker   {
3062*5e7646d2SAndroid Build Coastguard Worker    /*
3063*5e7646d2SAndroid Build Coastguard Worker     * Bad resource name...
3064*5e7646d2SAndroid Build Coastguard Worker     */
3065*5e7646d2SAndroid Build Coastguard Worker 
3066*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
3067*5e7646d2SAndroid Build Coastguard Worker   }
3068*5e7646d2SAndroid Build Coastguard Worker 
3069*5e7646d2SAndroid Build Coastguard Worker  /*
3070*5e7646d2SAndroid Build Coastguard Worker   * See if the printer or class name exists...
3071*5e7646d2SAndroid Build Coastguard Worker   */
3072*5e7646d2SAndroid Build Coastguard Worker 
3073*5e7646d2SAndroid Build Coastguard Worker   p = cupsdFindDest(rptr);
3074*5e7646d2SAndroid Build Coastguard Worker 
3075*5e7646d2SAndroid Build Coastguard Worker   if (p == NULL && strchr(rptr, '@') == NULL)
3076*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
3077*5e7646d2SAndroid Build Coastguard Worker   else if (p != NULL)
3078*5e7646d2SAndroid Build Coastguard Worker   {
3079*5e7646d2SAndroid Build Coastguard Worker     if (printer)
3080*5e7646d2SAndroid Build Coastguard Worker       *printer = p;
3081*5e7646d2SAndroid Build Coastguard Worker 
3082*5e7646d2SAndroid Build Coastguard Worker     if (dtype)
3083*5e7646d2SAndroid Build Coastguard Worker       *dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
3084*5e7646d2SAndroid Build Coastguard Worker 
3085*5e7646d2SAndroid Build Coastguard Worker     return (p->name);
3086*5e7646d2SAndroid Build Coastguard Worker   }
3087*5e7646d2SAndroid Build Coastguard Worker 
3088*5e7646d2SAndroid Build Coastguard Worker  /*
3089*5e7646d2SAndroid Build Coastguard Worker   * Change localhost to the server name...
3090*5e7646d2SAndroid Build Coastguard Worker   */
3091*5e7646d2SAndroid Build Coastguard Worker 
3092*5e7646d2SAndroid Build Coastguard Worker   if (!_cups_strcasecmp(hostname, "localhost"))
3093*5e7646d2SAndroid Build Coastguard Worker     strlcpy(hostname, ServerName, sizeof(hostname));
3094*5e7646d2SAndroid Build Coastguard Worker 
3095*5e7646d2SAndroid Build Coastguard Worker   strlcpy(localname, hostname, sizeof(localname));
3096*5e7646d2SAndroid Build Coastguard Worker 
3097*5e7646d2SAndroid Build Coastguard Worker   if (!_cups_strcasecmp(hostname, ServerName))
3098*5e7646d2SAndroid Build Coastguard Worker   {
3099*5e7646d2SAndroid Build Coastguard Worker    /*
3100*5e7646d2SAndroid Build Coastguard Worker     * Localize the hostname...
3101*5e7646d2SAndroid Build Coastguard Worker     */
3102*5e7646d2SAndroid Build Coastguard Worker 
3103*5e7646d2SAndroid Build Coastguard Worker     lptr = strchr(localname, '.');
3104*5e7646d2SAndroid Build Coastguard Worker     sptr = strchr(ServerName, '.');
3105*5e7646d2SAndroid Build Coastguard Worker 
3106*5e7646d2SAndroid Build Coastguard Worker     if (sptr != NULL && lptr != NULL)
3107*5e7646d2SAndroid Build Coastguard Worker     {
3108*5e7646d2SAndroid Build Coastguard Worker      /*
3109*5e7646d2SAndroid Build Coastguard Worker       * Strip the common domain name components...
3110*5e7646d2SAndroid Build Coastguard Worker       */
3111*5e7646d2SAndroid Build Coastguard Worker 
3112*5e7646d2SAndroid Build Coastguard Worker       while (lptr != NULL)
3113*5e7646d2SAndroid Build Coastguard Worker       {
3114*5e7646d2SAndroid Build Coastguard Worker 	if (!_cups_strcasecmp(lptr, sptr))
3115*5e7646d2SAndroid Build Coastguard Worker 	{
3116*5e7646d2SAndroid Build Coastguard Worker           *lptr = '\0';
3117*5e7646d2SAndroid Build Coastguard Worker 	  break;
3118*5e7646d2SAndroid Build Coastguard Worker 	}
3119*5e7646d2SAndroid Build Coastguard Worker 	else
3120*5e7646d2SAndroid Build Coastguard Worker           lptr = strchr(lptr + 1, '.');
3121*5e7646d2SAndroid Build Coastguard Worker       }
3122*5e7646d2SAndroid Build Coastguard Worker     }
3123*5e7646d2SAndroid Build Coastguard Worker   }
3124*5e7646d2SAndroid Build Coastguard Worker 
3125*5e7646d2SAndroid Build Coastguard Worker  /*
3126*5e7646d2SAndroid Build Coastguard Worker   * Find a matching printer or class...
3127*5e7646d2SAndroid Build Coastguard Worker   */
3128*5e7646d2SAndroid Build Coastguard Worker 
3129*5e7646d2SAndroid Build Coastguard Worker   for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
3130*5e7646d2SAndroid Build Coastguard Worker        p;
3131*5e7646d2SAndroid Build Coastguard Worker        p = (cupsd_printer_t *)cupsArrayNext(Printers))
3132*5e7646d2SAndroid Build Coastguard Worker     if (!_cups_strcasecmp(p->hostname, localname) &&
3133*5e7646d2SAndroid Build Coastguard Worker         !_cups_strcasecmp(p->name, rptr))
3134*5e7646d2SAndroid Build Coastguard Worker     {
3135*5e7646d2SAndroid Build Coastguard Worker       if (printer)
3136*5e7646d2SAndroid Build Coastguard Worker         *printer = p;
3137*5e7646d2SAndroid Build Coastguard Worker 
3138*5e7646d2SAndroid Build Coastguard Worker       if (dtype)
3139*5e7646d2SAndroid Build Coastguard Worker 	*dtype = p->type & (CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
3140*5e7646d2SAndroid Build Coastguard Worker 
3141*5e7646d2SAndroid Build Coastguard Worker       return (p->name);
3142*5e7646d2SAndroid Build Coastguard Worker     }
3143*5e7646d2SAndroid Build Coastguard Worker 
3144*5e7646d2SAndroid Build Coastguard Worker   return (NULL);
3145*5e7646d2SAndroid Build Coastguard Worker }
3146*5e7646d2SAndroid Build Coastguard Worker 
3147*5e7646d2SAndroid Build Coastguard Worker 
3148*5e7646d2SAndroid Build Coastguard Worker /*
3149*5e7646d2SAndroid Build Coastguard Worker  * 'cupsdWritePrintcap()' - Write a pseudo-printcap file for older applications
3150*5e7646d2SAndroid Build Coastguard Worker  *                          that need it...
3151*5e7646d2SAndroid Build Coastguard Worker  */
3152*5e7646d2SAndroid Build Coastguard Worker 
3153*5e7646d2SAndroid Build Coastguard Worker void
cupsdWritePrintcap(void)3154*5e7646d2SAndroid Build Coastguard Worker cupsdWritePrintcap(void)
3155*5e7646d2SAndroid Build Coastguard Worker {
3156*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
3157*5e7646d2SAndroid Build Coastguard Worker   cups_file_t		*fp;		/* Printcap file */
3158*5e7646d2SAndroid Build Coastguard Worker   cupsd_printer_t	*p;		/* Current printer */
3159*5e7646d2SAndroid Build Coastguard Worker 
3160*5e7646d2SAndroid Build Coastguard Worker 
3161*5e7646d2SAndroid Build Coastguard Worker  /*
3162*5e7646d2SAndroid Build Coastguard Worker   * See if we have a printcap file; if not, don't bother writing it.
3163*5e7646d2SAndroid Build Coastguard Worker   */
3164*5e7646d2SAndroid Build Coastguard Worker 
3165*5e7646d2SAndroid Build Coastguard Worker   if (!Printcap || !*Printcap)
3166*5e7646d2SAndroid Build Coastguard Worker     return;
3167*5e7646d2SAndroid Build Coastguard Worker 
3168*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_INFO, "Generating printcap %s...", Printcap);
3169*5e7646d2SAndroid Build Coastguard Worker 
3170*5e7646d2SAndroid Build Coastguard Worker  /*
3171*5e7646d2SAndroid Build Coastguard Worker   * Open the printcap file...
3172*5e7646d2SAndroid Build Coastguard Worker   */
3173*5e7646d2SAndroid Build Coastguard Worker 
3174*5e7646d2SAndroid Build Coastguard Worker   if ((fp = cupsFileOpen(Printcap, "w")) == NULL)
3175*5e7646d2SAndroid Build Coastguard Worker     return;
3176*5e7646d2SAndroid Build Coastguard Worker 
3177*5e7646d2SAndroid Build Coastguard Worker  /*
3178*5e7646d2SAndroid Build Coastguard Worker   * Put a comment header at the top so that users will know where the
3179*5e7646d2SAndroid Build Coastguard Worker   * data has come from...
3180*5e7646d2SAndroid Build Coastguard Worker   */
3181*5e7646d2SAndroid Build Coastguard Worker 
3182*5e7646d2SAndroid Build Coastguard Worker   if (PrintcapFormat != PRINTCAP_PLIST)
3183*5e7646d2SAndroid Build Coastguard Worker     cupsFilePrintf(fp, "# This file was automatically generated by cupsd(8) "
3184*5e7646d2SAndroid Build Coastguard Worker                        "from the\n"
3185*5e7646d2SAndroid Build Coastguard Worker                        "# %s/printers.conf file.  All changes to this file\n"
3186*5e7646d2SAndroid Build Coastguard Worker 		       "# will be lost.\n", ServerRoot);
3187*5e7646d2SAndroid Build Coastguard Worker 
3188*5e7646d2SAndroid Build Coastguard Worker  /*
3189*5e7646d2SAndroid Build Coastguard Worker   * Write a new printcap with the current list of printers.
3190*5e7646d2SAndroid Build Coastguard Worker   */
3191*5e7646d2SAndroid Build Coastguard Worker 
3192*5e7646d2SAndroid Build Coastguard Worker   switch (PrintcapFormat)
3193*5e7646d2SAndroid Build Coastguard Worker   {
3194*5e7646d2SAndroid Build Coastguard Worker     case PRINTCAP_BSD :
3195*5e7646d2SAndroid Build Coastguard Worker        /*
3196*5e7646d2SAndroid Build Coastguard Worker 	* Each printer is put in the file as:
3197*5e7646d2SAndroid Build Coastguard Worker 	*
3198*5e7646d2SAndroid Build Coastguard Worker 	*    Printer1:
3199*5e7646d2SAndroid Build Coastguard Worker 	*    Printer2:
3200*5e7646d2SAndroid Build Coastguard Worker 	*    Printer3:
3201*5e7646d2SAndroid Build Coastguard Worker 	*    ...
3202*5e7646d2SAndroid Build Coastguard Worker 	*    PrinterN:
3203*5e7646d2SAndroid Build Coastguard Worker 	*/
3204*5e7646d2SAndroid Build Coastguard Worker 
3205*5e7646d2SAndroid Build Coastguard Worker 	if (DefaultPrinter)
3206*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", DefaultPrinter->name,
3207*5e7646d2SAndroid Build Coastguard Worker 			 DefaultPrinter->info, ServerName,
3208*5e7646d2SAndroid Build Coastguard Worker 			 DefaultPrinter->name);
3209*5e7646d2SAndroid Build Coastguard Worker 
3210*5e7646d2SAndroid Build Coastguard Worker 	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
3211*5e7646d2SAndroid Build Coastguard Worker 	     p;
3212*5e7646d2SAndroid Build Coastguard Worker 	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
3213*5e7646d2SAndroid Build Coastguard Worker 	  if (p != DefaultPrinter)
3214*5e7646d2SAndroid Build Coastguard Worker 	    cupsFilePrintf(fp, "%s|%s:rm=%s:rp=%s:\n", p->name, p->info,
3215*5e7646d2SAndroid Build Coastguard Worker 			   ServerName, p->name);
3216*5e7646d2SAndroid Build Coastguard Worker 	break;
3217*5e7646d2SAndroid Build Coastguard Worker 
3218*5e7646d2SAndroid Build Coastguard Worker     case PRINTCAP_PLIST :
3219*5e7646d2SAndroid Build Coastguard Worker        /*
3220*5e7646d2SAndroid Build Coastguard Worker 	* Each printer is written as a dictionary in a plist file.
3221*5e7646d2SAndroid Build Coastguard Worker 	* Currently the printer-name, printer-info, printer-is-accepting-jobs,
3222*5e7646d2SAndroid Build Coastguard Worker 	* printer-location, printer-make-and-model, printer-state,
3223*5e7646d2SAndroid Build Coastguard Worker 	* printer-state-reasons, printer-type, and (sanitized) device-uri.
3224*5e7646d2SAndroid Build Coastguard Worker 	*/
3225*5e7646d2SAndroid Build Coastguard Worker 
3226*5e7646d2SAndroid Build Coastguard Worker 	cupsFilePuts(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
3227*5e7646d2SAndroid Build Coastguard Worker 			 "<!DOCTYPE plist PUBLIC \"-//Apple Computer//DTD "
3228*5e7646d2SAndroid Build Coastguard Worker 			 "PLIST 1.0//EN\" \"http://www.apple.com/DTDs/"
3229*5e7646d2SAndroid Build Coastguard Worker 			 "PropertyList-1.0.dtd\">\n"
3230*5e7646d2SAndroid Build Coastguard Worker 			 "<plist version=\"1.0\">\n"
3231*5e7646d2SAndroid Build Coastguard Worker 			 "<array>\n");
3232*5e7646d2SAndroid Build Coastguard Worker 
3233*5e7646d2SAndroid Build Coastguard Worker 	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
3234*5e7646d2SAndroid Build Coastguard Worker 	     p;
3235*5e7646d2SAndroid Build Coastguard Worker 	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
3236*5e7646d2SAndroid Build Coastguard Worker 	{
3237*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePuts(fp, "\t<dict>\n"
3238*5e7646d2SAndroid Build Coastguard Worker 			   "\t\t<key>printer-name</key>\n"
3239*5e7646d2SAndroid Build Coastguard Worker 			   "\t\t<string>");
3240*5e7646d2SAndroid Build Coastguard Worker 	  write_xml_string(fp, p->name);
3241*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePuts(fp, "</string>\n"
3242*5e7646d2SAndroid Build Coastguard Worker 			   "\t\t<key>printer-info</key>\n"
3243*5e7646d2SAndroid Build Coastguard Worker 			   "\t\t<string>");
3244*5e7646d2SAndroid Build Coastguard Worker 	  write_xml_string(fp, p->info);
3245*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(fp, "</string>\n"
3246*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<key>printer-is-accepting-jobs</key>\n"
3247*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<%s/>\n"
3248*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<key>printer-location</key>\n"
3249*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<string>", p->accepting ? "true" : "false");
3250*5e7646d2SAndroid Build Coastguard Worker 	  write_xml_string(fp, p->location);
3251*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePuts(fp, "</string>\n"
3252*5e7646d2SAndroid Build Coastguard Worker 			   "\t\t<key>printer-make-and-model</key>\n"
3253*5e7646d2SAndroid Build Coastguard Worker 			   "\t\t<string>");
3254*5e7646d2SAndroid Build Coastguard Worker 	  write_xml_string(fp, p->make_model);
3255*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(fp, "</string>\n"
3256*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<key>printer-state</key>\n"
3257*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<integer>%d</integer>\n"
3258*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<key>printer-state-reasons</key>\n"
3259*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<array>\n", p->state);
3260*5e7646d2SAndroid Build Coastguard Worker 	  for (i = 0; i < p->num_reasons; i ++)
3261*5e7646d2SAndroid Build Coastguard Worker 	  {
3262*5e7646d2SAndroid Build Coastguard Worker 	    cupsFilePuts(fp, "\t\t\t<string>");
3263*5e7646d2SAndroid Build Coastguard Worker 	    write_xml_string(fp, p->reasons[i]);
3264*5e7646d2SAndroid Build Coastguard Worker 	    cupsFilePuts(fp, "</string>\n");
3265*5e7646d2SAndroid Build Coastguard Worker 	  }
3266*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(fp, "\t\t</array>\n"
3267*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<key>printer-type</key>\n"
3268*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<integer>%d</integer>\n"
3269*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<key>device-uri</key>\n"
3270*5e7646d2SAndroid Build Coastguard Worker 			     "\t\t<string>", p->type);
3271*5e7646d2SAndroid Build Coastguard Worker 	  write_xml_string(fp, p->sanitized_device_uri);
3272*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePuts(fp, "</string>\n"
3273*5e7646d2SAndroid Build Coastguard Worker 			   "\t</dict>\n");
3274*5e7646d2SAndroid Build Coastguard Worker 	}
3275*5e7646d2SAndroid Build Coastguard Worker 	cupsFilePuts(fp, "</array>\n"
3276*5e7646d2SAndroid Build Coastguard Worker 			 "</plist>\n");
3277*5e7646d2SAndroid Build Coastguard Worker 	break;
3278*5e7646d2SAndroid Build Coastguard Worker 
3279*5e7646d2SAndroid Build Coastguard Worker     case PRINTCAP_SOLARIS :
3280*5e7646d2SAndroid Build Coastguard Worker        /*
3281*5e7646d2SAndroid Build Coastguard Worker 	* Each printer is put in the file as:
3282*5e7646d2SAndroid Build Coastguard Worker 	*
3283*5e7646d2SAndroid Build Coastguard Worker 	*    _all:all=Printer1,Printer2,Printer3,...,PrinterN
3284*5e7646d2SAndroid Build Coastguard Worker 	*    _default:use=DefaultPrinter
3285*5e7646d2SAndroid Build Coastguard Worker 	*    Printer1:\
3286*5e7646d2SAndroid Build Coastguard Worker 	*            :bsdaddr=ServerName,Printer1:\
3287*5e7646d2SAndroid Build Coastguard Worker 	*            :description=Description:
3288*5e7646d2SAndroid Build Coastguard Worker 	*    Printer2:
3289*5e7646d2SAndroid Build Coastguard Worker 	*            :bsdaddr=ServerName,Printer2:\
3290*5e7646d2SAndroid Build Coastguard Worker 	*            :description=Description:
3291*5e7646d2SAndroid Build Coastguard Worker 	*    Printer3:
3292*5e7646d2SAndroid Build Coastguard Worker 	*            :bsdaddr=ServerName,Printer3:\
3293*5e7646d2SAndroid Build Coastguard Worker 	*            :description=Description:
3294*5e7646d2SAndroid Build Coastguard Worker 	*    ...
3295*5e7646d2SAndroid Build Coastguard Worker 	*    PrinterN:
3296*5e7646d2SAndroid Build Coastguard Worker 	*            :bsdaddr=ServerName,PrinterN:\
3297*5e7646d2SAndroid Build Coastguard Worker 	*            :description=Description:
3298*5e7646d2SAndroid Build Coastguard Worker 	*/
3299*5e7646d2SAndroid Build Coastguard Worker 
3300*5e7646d2SAndroid Build Coastguard Worker 	cupsFilePuts(fp, "_all:all=");
3301*5e7646d2SAndroid Build Coastguard Worker 	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
3302*5e7646d2SAndroid Build Coastguard Worker 	     p;
3303*5e7646d2SAndroid Build Coastguard Worker 	     p = (cupsd_printer_t *)cupsArrayCurrent(Printers))
3304*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(fp, "%s%c", p->name,
3305*5e7646d2SAndroid Build Coastguard Worker 			 cupsArrayNext(Printers) ? ',' : '\n');
3306*5e7646d2SAndroid Build Coastguard Worker 
3307*5e7646d2SAndroid Build Coastguard Worker 	if (DefaultPrinter)
3308*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(fp, "_default:use=%s\n", DefaultPrinter->name);
3309*5e7646d2SAndroid Build Coastguard Worker 
3310*5e7646d2SAndroid Build Coastguard Worker 	for (p = (cupsd_printer_t *)cupsArrayFirst(Printers);
3311*5e7646d2SAndroid Build Coastguard Worker 	     p;
3312*5e7646d2SAndroid Build Coastguard Worker 	     p = (cupsd_printer_t *)cupsArrayNext(Printers))
3313*5e7646d2SAndroid Build Coastguard Worker 	  cupsFilePrintf(fp, "%s:\\\n"
3314*5e7646d2SAndroid Build Coastguard Worker 			     "\t:bsdaddr=%s,%s:\\\n"
3315*5e7646d2SAndroid Build Coastguard Worker 			     "\t:description=%s:\n",
3316*5e7646d2SAndroid Build Coastguard Worker 			 p->name, ServerName, p->name,
3317*5e7646d2SAndroid Build Coastguard Worker 			 p->info ? p->info : "");
3318*5e7646d2SAndroid Build Coastguard Worker 	break;
3319*5e7646d2SAndroid Build Coastguard Worker   }
3320*5e7646d2SAndroid Build Coastguard Worker 
3321*5e7646d2SAndroid Build Coastguard Worker  /*
3322*5e7646d2SAndroid Build Coastguard Worker   * Close the file...
3323*5e7646d2SAndroid Build Coastguard Worker   */
3324*5e7646d2SAndroid Build Coastguard Worker 
3325*5e7646d2SAndroid Build Coastguard Worker   cupsFileClose(fp);
3326*5e7646d2SAndroid Build Coastguard Worker }
3327*5e7646d2SAndroid Build Coastguard Worker 
3328*5e7646d2SAndroid Build Coastguard Worker 
3329*5e7646d2SAndroid Build Coastguard Worker /*
3330*5e7646d2SAndroid Build Coastguard Worker  * 'add_printer_defaults()' - Add name-default attributes to the printer attributes.
3331*5e7646d2SAndroid Build Coastguard Worker  */
3332*5e7646d2SAndroid Build Coastguard Worker 
3333*5e7646d2SAndroid Build Coastguard Worker static void
add_printer_defaults(cupsd_printer_t * p)3334*5e7646d2SAndroid Build Coastguard Worker add_printer_defaults(cupsd_printer_t *p)/* I - Printer */
3335*5e7646d2SAndroid Build Coastguard Worker {
3336*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
3337*5e7646d2SAndroid Build Coastguard Worker   int		num_options;		/* Number of default options */
3338*5e7646d2SAndroid Build Coastguard Worker   cups_option_t	*options,		/* Default options */
3339*5e7646d2SAndroid Build Coastguard Worker 		*option;		/* Current option */
3340*5e7646d2SAndroid Build Coastguard Worker   char		name[256];		/* name-default */
3341*5e7646d2SAndroid Build Coastguard Worker 
3342*5e7646d2SAndroid Build Coastguard Worker 
3343*5e7646d2SAndroid Build Coastguard Worker  /*
3344*5e7646d2SAndroid Build Coastguard Worker   * Maintain a common array of default attribute names...
3345*5e7646d2SAndroid Build Coastguard Worker   */
3346*5e7646d2SAndroid Build Coastguard Worker 
3347*5e7646d2SAndroid Build Coastguard Worker   if (!CommonDefaults)
3348*5e7646d2SAndroid Build Coastguard Worker   {
3349*5e7646d2SAndroid Build Coastguard Worker     CommonDefaults = cupsArrayNew((cups_array_func_t)strcmp, NULL);
3350*5e7646d2SAndroid Build Coastguard Worker 
3351*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("copies-default"));
3352*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("document-format-default"));
3353*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("finishings-default"));
3354*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-account-id-default"));
3355*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-accounting-user-id-default"));
3356*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-cancel-after-default"));
3357*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-hold-until-default"));
3358*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-priority-default"));
3359*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("job-sheets-default"));
3360*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("media-col-default"));
3361*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("notify-lease-duration-default"));
3362*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("notify-events-default"));
3363*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("number-up-default"));
3364*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("orientation-requested-default"));
3365*5e7646d2SAndroid Build Coastguard Worker     cupsArrayAdd(CommonDefaults, _cupsStrAlloc("print-quality-default"));
3366*5e7646d2SAndroid Build Coastguard Worker   }
3367*5e7646d2SAndroid Build Coastguard Worker 
3368*5e7646d2SAndroid Build Coastguard Worker  /*
3369*5e7646d2SAndroid Build Coastguard Worker   * Add all of the default options from the .conf files...
3370*5e7646d2SAndroid Build Coastguard Worker   */
3371*5e7646d2SAndroid Build Coastguard Worker 
3372*5e7646d2SAndroid Build Coastguard Worker   for (num_options = 0, options = NULL, i = p->num_options, option = p->options;
3373*5e7646d2SAndroid Build Coastguard Worker        i > 0;
3374*5e7646d2SAndroid Build Coastguard Worker        i --, option ++)
3375*5e7646d2SAndroid Build Coastguard Worker   {
3376*5e7646d2SAndroid Build Coastguard Worker     if (strcmp(option->name, "ipp-options") &&
3377*5e7646d2SAndroid Build Coastguard Worker 	strcmp(option->name, "job-sheets") &&
3378*5e7646d2SAndroid Build Coastguard Worker         strcmp(option->name, "lease-duration"))
3379*5e7646d2SAndroid Build Coastguard Worker     {
3380*5e7646d2SAndroid Build Coastguard Worker       snprintf(name, sizeof(name), "%s-default", option->name);
3381*5e7646d2SAndroid Build Coastguard Worker       num_options = cupsAddOption(name, option->value, num_options, &options);
3382*5e7646d2SAndroid Build Coastguard Worker 
3383*5e7646d2SAndroid Build Coastguard Worker       if (!cupsArrayFind(CommonDefaults, name))
3384*5e7646d2SAndroid Build Coastguard Worker         cupsArrayAdd(CommonDefaults, _cupsStrAlloc(name));
3385*5e7646d2SAndroid Build Coastguard Worker     }
3386*5e7646d2SAndroid Build Coastguard Worker   }
3387*5e7646d2SAndroid Build Coastguard Worker 
3388*5e7646d2SAndroid Build Coastguard Worker  /*
3389*5e7646d2SAndroid Build Coastguard Worker   * Convert options to IPP attributes...
3390*5e7646d2SAndroid Build Coastguard Worker   */
3391*5e7646d2SAndroid Build Coastguard Worker 
3392*5e7646d2SAndroid Build Coastguard Worker   cupsEncodeOptions2(p->attrs, num_options, options, IPP_TAG_PRINTER);
3393*5e7646d2SAndroid Build Coastguard Worker   cupsFreeOptions(num_options, options);
3394*5e7646d2SAndroid Build Coastguard Worker 
3395*5e7646d2SAndroid Build Coastguard Worker  /*
3396*5e7646d2SAndroid Build Coastguard Worker   * Add standard -default attributes as needed...
3397*5e7646d2SAndroid Build Coastguard Worker   */
3398*5e7646d2SAndroid Build Coastguard Worker 
3399*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("copies", p->num_options, p->options))
3400*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "copies-default",
3401*5e7646d2SAndroid Build Coastguard Worker                   1);
3402*5e7646d2SAndroid Build Coastguard Worker 
3403*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("document-format", p->num_options, p->options))
3404*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
3405*5e7646d2SAndroid Build Coastguard Worker         	 "document-format-default", NULL, "application/octet-stream");
3406*5e7646d2SAndroid Build Coastguard Worker 
3407*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("job-cancel-after", p->num_options, p->options))
3408*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(p->attrs, IPP_TAG_PRINTER, MaxJobTime > 0 ? IPP_TAG_INTEGER : IPP_TAG_NOVALUE,
3409*5e7646d2SAndroid Build Coastguard Worker 		  "job-cancel-after-default", MaxJobTime);
3410*5e7646d2SAndroid Build Coastguard Worker 
3411*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("job-hold-until", p->num_options, p->options))
3412*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
3413*5e7646d2SAndroid Build Coastguard Worker                  "job-hold-until-default", NULL, "no-hold");
3414*5e7646d2SAndroid Build Coastguard Worker 
3415*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("job-priority", p->num_options, p->options))
3416*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
3417*5e7646d2SAndroid Build Coastguard Worker                   "job-priority-default", 50);
3418*5e7646d2SAndroid Build Coastguard Worker 
3419*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("number-up", p->num_options, p->options))
3420*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
3421*5e7646d2SAndroid Build Coastguard Worker                   "number-up-default", 1);
3422*5e7646d2SAndroid Build Coastguard Worker 
3423*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("notify-lease-duration", p->num_options, p->options))
3424*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
3425*5e7646d2SAndroid Build Coastguard Worker         	  "notify-lease-duration-default", DefaultLeaseDuration);
3426*5e7646d2SAndroid Build Coastguard Worker 
3427*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("notify-events", p->num_options, p->options))
3428*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
3429*5e7646d2SAndroid Build Coastguard Worker         	 "notify-events-default", NULL, "job-completed");
3430*5e7646d2SAndroid Build Coastguard Worker 
3431*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("orientation-requested", p->num_options, p->options))
3432*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
3433*5e7646d2SAndroid Build Coastguard Worker                  "orientation-requested-default", NULL, NULL);
3434*5e7646d2SAndroid Build Coastguard Worker 
3435*5e7646d2SAndroid Build Coastguard Worker   if (!cupsGetOption("print-quality", p->num_options, p->options))
3436*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
3437*5e7646d2SAndroid Build Coastguard Worker                   "print-quality-default", IPP_QUALITY_NORMAL);
3438*5e7646d2SAndroid Build Coastguard Worker }
3439*5e7646d2SAndroid Build Coastguard Worker 
3440*5e7646d2SAndroid Build Coastguard Worker 
3441*5e7646d2SAndroid Build Coastguard Worker /*
3442*5e7646d2SAndroid Build Coastguard Worker  * 'add_printer_filter()' - Add a MIME filter for a printer.
3443*5e7646d2SAndroid Build Coastguard Worker  */
3444*5e7646d2SAndroid Build Coastguard Worker 
3445*5e7646d2SAndroid Build Coastguard Worker static void
add_printer_filter(cupsd_printer_t * p,mime_type_t * filtertype,const char * filter)3446*5e7646d2SAndroid Build Coastguard Worker add_printer_filter(
3447*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t  *p,		/* I - Printer to add to */
3448*5e7646d2SAndroid Build Coastguard Worker     mime_type_t	     *filtertype,	/* I - Filter or prefilter MIME type */
3449*5e7646d2SAndroid Build Coastguard Worker     const char       *filter)		/* I - Filter to add */
3450*5e7646d2SAndroid Build Coastguard Worker {
3451*5e7646d2SAndroid Build Coastguard Worker   char		super[MIME_MAX_SUPER],	/* Super-type for filter */
3452*5e7646d2SAndroid Build Coastguard Worker 		type[MIME_MAX_TYPE],	/* Type for filter */
3453*5e7646d2SAndroid Build Coastguard Worker 		dsuper[MIME_MAX_SUPER],	/* Destination super-type for filter */
3454*5e7646d2SAndroid Build Coastguard Worker 		dtype[MIME_MAX_TYPE],	/* Destination type for filter */
3455*5e7646d2SAndroid Build Coastguard Worker 		dest[MIME_MAX_SUPER + MIME_MAX_TYPE + 2],
3456*5e7646d2SAndroid Build Coastguard Worker 					/* Destination super/type */
3457*5e7646d2SAndroid Build Coastguard Worker 		program[1024];		/* Program/filter name */
3458*5e7646d2SAndroid Build Coastguard Worker   int		cost;			/* Cost of filter */
3459*5e7646d2SAndroid Build Coastguard Worker   size_t	maxsize = 0;		/* Maximum supported file size */
3460*5e7646d2SAndroid Build Coastguard Worker   mime_type_t	*temptype,		/* MIME type looping var */
3461*5e7646d2SAndroid Build Coastguard Worker 		*desttype;		/* Destination MIME type */
3462*5e7646d2SAndroid Build Coastguard Worker   mime_filter_t	*filterptr;		/* MIME filter */
3463*5e7646d2SAndroid Build Coastguard Worker   char		filename[1024];		/* Full filter filename */
3464*5e7646d2SAndroid Build Coastguard Worker 
3465*5e7646d2SAndroid Build Coastguard Worker 
3466*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
3467*5e7646d2SAndroid Build Coastguard Worker                   "add_printer_filter(p=%p(%s), filtertype=%p(%s/%s), "
3468*5e7646d2SAndroid Build Coastguard Worker 		  "filter=\"%s\")", p, p->name, filtertype, filtertype->super,
3469*5e7646d2SAndroid Build Coastguard Worker 		  filtertype->type, filter);
3470*5e7646d2SAndroid Build Coastguard Worker 
3471*5e7646d2SAndroid Build Coastguard Worker  /*
3472*5e7646d2SAndroid Build Coastguard Worker   * Parse the filter string; it should be in one of the following formats:
3473*5e7646d2SAndroid Build Coastguard Worker   *
3474*5e7646d2SAndroid Build Coastguard Worker   *     source/type cost program
3475*5e7646d2SAndroid Build Coastguard Worker   *     source/type cost maxsize(nnnn) program
3476*5e7646d2SAndroid Build Coastguard Worker   *     source/type dest/type cost program
3477*5e7646d2SAndroid Build Coastguard Worker   *     source/type dest/type cost maxsize(nnnn) program
3478*5e7646d2SAndroid Build Coastguard Worker   */
3479*5e7646d2SAndroid Build Coastguard Worker 
3480*5e7646d2SAndroid Build Coastguard Worker   if (sscanf(filter, "%15[^/]/%255s%*[ \t]%15[^/]/%255s%d%*[ \t]%1023[^\n]",
3481*5e7646d2SAndroid Build Coastguard Worker              super, type, dsuper, dtype, &cost, program) == 6)
3482*5e7646d2SAndroid Build Coastguard Worker   {
3483*5e7646d2SAndroid Build Coastguard Worker     snprintf(dest, sizeof(dest), "%s/%s/%s", p->name, dsuper, dtype);
3484*5e7646d2SAndroid Build Coastguard Worker 
3485*5e7646d2SAndroid Build Coastguard Worker     if ((desttype = mimeType(MimeDatabase, "printer", dest)) == NULL)
3486*5e7646d2SAndroid Build Coastguard Worker     {
3487*5e7646d2SAndroid Build Coastguard Worker       desttype = mimeAddType(MimeDatabase, "printer", dest);
3488*5e7646d2SAndroid Build Coastguard Worker       if (!p->dest_types)
3489*5e7646d2SAndroid Build Coastguard Worker         p->dest_types = cupsArrayNew(NULL, NULL);
3490*5e7646d2SAndroid Build Coastguard Worker 
3491*5e7646d2SAndroid Build Coastguard Worker       cupsArrayAdd(p->dest_types, desttype);
3492*5e7646d2SAndroid Build Coastguard Worker     }
3493*5e7646d2SAndroid Build Coastguard Worker 
3494*5e7646d2SAndroid Build Coastguard Worker   }
3495*5e7646d2SAndroid Build Coastguard Worker   else
3496*5e7646d2SAndroid Build Coastguard Worker   {
3497*5e7646d2SAndroid Build Coastguard Worker     if (sscanf(filter, "%15[^/]/%255s%d%*[ \t]%1023[^\n]", super, type, &cost,
3498*5e7646d2SAndroid Build Coastguard Worker                program) == 4)
3499*5e7646d2SAndroid Build Coastguard Worker     {
3500*5e7646d2SAndroid Build Coastguard Worker       desttype = filtertype;
3501*5e7646d2SAndroid Build Coastguard Worker     }
3502*5e7646d2SAndroid Build Coastguard Worker     else
3503*5e7646d2SAndroid Build Coastguard Worker     {
3504*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "%s: invalid filter string \"%s\"!",
3505*5e7646d2SAndroid Build Coastguard Worker                       p->name, filter);
3506*5e7646d2SAndroid Build Coastguard Worker       return;
3507*5e7646d2SAndroid Build Coastguard Worker     }
3508*5e7646d2SAndroid Build Coastguard Worker   }
3509*5e7646d2SAndroid Build Coastguard Worker 
3510*5e7646d2SAndroid Build Coastguard Worker   if (!strncmp(program, "maxsize(", 8))
3511*5e7646d2SAndroid Build Coastguard Worker   {
3512*5e7646d2SAndroid Build Coastguard Worker     char	*ptr;			/* Pointer into maxsize(nnnn) program */
3513*5e7646d2SAndroid Build Coastguard Worker 
3514*5e7646d2SAndroid Build Coastguard Worker     maxsize = (size_t)strtoll(program + 8, &ptr, 10);
3515*5e7646d2SAndroid Build Coastguard Worker 
3516*5e7646d2SAndroid Build Coastguard Worker     if (*ptr != ')')
3517*5e7646d2SAndroid Build Coastguard Worker     {
3518*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "%s: invalid filter string \"%s\"!",
3519*5e7646d2SAndroid Build Coastguard Worker                       p->name, filter);
3520*5e7646d2SAndroid Build Coastguard Worker       return;
3521*5e7646d2SAndroid Build Coastguard Worker     }
3522*5e7646d2SAndroid Build Coastguard Worker 
3523*5e7646d2SAndroid Build Coastguard Worker     ptr ++;
3524*5e7646d2SAndroid Build Coastguard Worker     while (_cups_isspace(*ptr))
3525*5e7646d2SAndroid Build Coastguard Worker       ptr ++;
3526*5e7646d2SAndroid Build Coastguard Worker 
3527*5e7646d2SAndroid Build Coastguard Worker     _cups_strcpy(program, ptr);
3528*5e7646d2SAndroid Build Coastguard Worker   }
3529*5e7646d2SAndroid Build Coastguard Worker 
3530*5e7646d2SAndroid Build Coastguard Worker  /*
3531*5e7646d2SAndroid Build Coastguard Worker   * Check permissions on the filter and its containing directory...
3532*5e7646d2SAndroid Build Coastguard Worker   */
3533*5e7646d2SAndroid Build Coastguard Worker 
3534*5e7646d2SAndroid Build Coastguard Worker   if (strcmp(program, "-"))
3535*5e7646d2SAndroid Build Coastguard Worker   {
3536*5e7646d2SAndroid Build Coastguard Worker     if (program[0] == '/')
3537*5e7646d2SAndroid Build Coastguard Worker       strlcpy(filename, program, sizeof(filename));
3538*5e7646d2SAndroid Build Coastguard Worker     else
3539*5e7646d2SAndroid Build Coastguard Worker       snprintf(filename, sizeof(filename), "%s/filter/%s", ServerBin, program);
3540*5e7646d2SAndroid Build Coastguard Worker 
3541*5e7646d2SAndroid Build Coastguard Worker     _cupsFileCheck(filename, _CUPS_FILE_CHECK_PROGRAM, !RunUser,
3542*5e7646d2SAndroid Build Coastguard Worker                    cupsdLogFCMessage, p);
3543*5e7646d2SAndroid Build Coastguard Worker   }
3544*5e7646d2SAndroid Build Coastguard Worker 
3545*5e7646d2SAndroid Build Coastguard Worker  /*
3546*5e7646d2SAndroid Build Coastguard Worker   * Add the filter to the MIME database, supporting wildcards as needed...
3547*5e7646d2SAndroid Build Coastguard Worker   */
3548*5e7646d2SAndroid Build Coastguard Worker 
3549*5e7646d2SAndroid Build Coastguard Worker   for (temptype = mimeFirstType(MimeDatabase);
3550*5e7646d2SAndroid Build Coastguard Worker        temptype;
3551*5e7646d2SAndroid Build Coastguard Worker        temptype = mimeNextType(MimeDatabase))
3552*5e7646d2SAndroid Build Coastguard Worker     if (((super[0] == '*' && _cups_strcasecmp(temptype->super, "printer")) ||
3553*5e7646d2SAndroid Build Coastguard Worker          !_cups_strcasecmp(temptype->super, super)) &&
3554*5e7646d2SAndroid Build Coastguard Worker         (type[0] == '*' || !_cups_strcasecmp(temptype->type, type)))
3555*5e7646d2SAndroid Build Coastguard Worker     {
3556*5e7646d2SAndroid Build Coastguard Worker       if (desttype != filtertype)
3557*5e7646d2SAndroid Build Coastguard Worker       {
3558*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_DEBUG2,
3559*5e7646d2SAndroid Build Coastguard Worker 		        "add_printer_filter: %s: adding filter %s/%s %s/%s %d "
3560*5e7646d2SAndroid Build Coastguard Worker 		        "%s", p->name, temptype->super, temptype->type,
3561*5e7646d2SAndroid Build Coastguard Worker 		        desttype->super, desttype->type,
3562*5e7646d2SAndroid Build Coastguard Worker 		        cost, program);
3563*5e7646d2SAndroid Build Coastguard Worker         filterptr = mimeAddFilter(MimeDatabase, temptype, desttype, cost,
3564*5e7646d2SAndroid Build Coastguard Worker 	                          program);
3565*5e7646d2SAndroid Build Coastguard Worker 
3566*5e7646d2SAndroid Build Coastguard Worker         if (!mimeFilterLookup(MimeDatabase, desttype, filtertype))
3567*5e7646d2SAndroid Build Coastguard Worker         {
3568*5e7646d2SAndroid Build Coastguard Worker           cupsdLogMessage(CUPSD_LOG_DEBUG2,
3569*5e7646d2SAndroid Build Coastguard Worker 	                  "add_printer_filter: %s: adding filter %s/%s %s/%s "
3570*5e7646d2SAndroid Build Coastguard Worker 	                  "0 -", p->name, desttype->super, desttype->type,
3571*5e7646d2SAndroid Build Coastguard Worker 		          filtertype->super, filtertype->type);
3572*5e7646d2SAndroid Build Coastguard Worker           mimeAddFilter(MimeDatabase, desttype, filtertype, 0, "-");
3573*5e7646d2SAndroid Build Coastguard Worker         }
3574*5e7646d2SAndroid Build Coastguard Worker       }
3575*5e7646d2SAndroid Build Coastguard Worker       else
3576*5e7646d2SAndroid Build Coastguard Worker       {
3577*5e7646d2SAndroid Build Coastguard Worker         cupsdLogMessage(CUPSD_LOG_DEBUG2,
3578*5e7646d2SAndroid Build Coastguard Worker 		        "add_printer_filter: %s: adding filter %s/%s %s/%s %d "
3579*5e7646d2SAndroid Build Coastguard Worker 		        "%s", p->name, temptype->super, temptype->type,
3580*5e7646d2SAndroid Build Coastguard Worker 		        filtertype->super, filtertype->type,
3581*5e7646d2SAndroid Build Coastguard Worker 		        cost, program);
3582*5e7646d2SAndroid Build Coastguard Worker         filterptr = mimeAddFilter(MimeDatabase, temptype, filtertype, cost,
3583*5e7646d2SAndroid Build Coastguard Worker 	                          program);
3584*5e7646d2SAndroid Build Coastguard Worker       }
3585*5e7646d2SAndroid Build Coastguard Worker 
3586*5e7646d2SAndroid Build Coastguard Worker       if (filterptr)
3587*5e7646d2SAndroid Build Coastguard Worker 	filterptr->maxsize = maxsize;
3588*5e7646d2SAndroid Build Coastguard Worker     }
3589*5e7646d2SAndroid Build Coastguard Worker }
3590*5e7646d2SAndroid Build Coastguard Worker 
3591*5e7646d2SAndroid Build Coastguard Worker 
3592*5e7646d2SAndroid Build Coastguard Worker /*
3593*5e7646d2SAndroid Build Coastguard Worker  * 'add_printer_formats()' - Add document-format-supported values for a printer.
3594*5e7646d2SAndroid Build Coastguard Worker  */
3595*5e7646d2SAndroid Build Coastguard Worker 
3596*5e7646d2SAndroid Build Coastguard Worker static void
add_printer_formats(cupsd_printer_t * p)3597*5e7646d2SAndroid Build Coastguard Worker add_printer_formats(cupsd_printer_t *p)	/* I - Printer */
3598*5e7646d2SAndroid Build Coastguard Worker {
3599*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
3600*5e7646d2SAndroid Build Coastguard Worker   mime_type_t	*type;			/* Current MIME type */
3601*5e7646d2SAndroid Build Coastguard Worker   cups_array_t	*filters;		/* Filters */
3602*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* document-format-supported attribute */
3603*5e7646d2SAndroid Build Coastguard Worker   char		mimetype[MIME_MAX_SUPER + MIME_MAX_TYPE + 2];
3604*5e7646d2SAndroid Build Coastguard Worker 					/* MIME type name */
3605*5e7646d2SAndroid Build Coastguard Worker 
3606*5e7646d2SAndroid Build Coastguard Worker 
3607*5e7646d2SAndroid Build Coastguard Worker  /*
3608*5e7646d2SAndroid Build Coastguard Worker   * Raw (and remote) queues advertise all of the supported MIME
3609*5e7646d2SAndroid Build Coastguard Worker   * types...
3610*5e7646d2SAndroid Build Coastguard Worker   */
3611*5e7646d2SAndroid Build Coastguard Worker 
3612*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->filetypes);
3613*5e7646d2SAndroid Build Coastguard Worker   p->filetypes = NULL;
3614*5e7646d2SAndroid Build Coastguard Worker 
3615*5e7646d2SAndroid Build Coastguard Worker   if (p->raw)
3616*5e7646d2SAndroid Build Coastguard Worker   {
3617*5e7646d2SAndroid Build Coastguard Worker     ippAddStrings(p->attrs, IPP_TAG_PRINTER,
3618*5e7646d2SAndroid Build Coastguard Worker                   (ipp_tag_t)(IPP_TAG_MIMETYPE | IPP_TAG_COPY),
3619*5e7646d2SAndroid Build Coastguard Worker                   "document-format-supported", NumMimeTypes, NULL, MimeTypes);
3620*5e7646d2SAndroid Build Coastguard Worker     return;
3621*5e7646d2SAndroid Build Coastguard Worker   }
3622*5e7646d2SAndroid Build Coastguard Worker 
3623*5e7646d2SAndroid Build Coastguard Worker  /*
3624*5e7646d2SAndroid Build Coastguard Worker   * Otherwise, loop through the supported MIME types and see if there
3625*5e7646d2SAndroid Build Coastguard Worker   * are filters for them...
3626*5e7646d2SAndroid Build Coastguard Worker   */
3627*5e7646d2SAndroid Build Coastguard Worker 
3628*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_printer_formats: %d types, %d filters",
3629*5e7646d2SAndroid Build Coastguard Worker                   mimeNumTypes(MimeDatabase), mimeNumFilters(MimeDatabase));
3630*5e7646d2SAndroid Build Coastguard Worker 
3631*5e7646d2SAndroid Build Coastguard Worker   p->filetypes = cupsArrayNew(NULL, NULL);
3632*5e7646d2SAndroid Build Coastguard Worker 
3633*5e7646d2SAndroid Build Coastguard Worker   for (type = mimeFirstType(MimeDatabase);
3634*5e7646d2SAndroid Build Coastguard Worker        type;
3635*5e7646d2SAndroid Build Coastguard Worker        type = mimeNextType(MimeDatabase))
3636*5e7646d2SAndroid Build Coastguard Worker   {
3637*5e7646d2SAndroid Build Coastguard Worker     if (!_cups_strcasecmp(type->super, "printer"))
3638*5e7646d2SAndroid Build Coastguard Worker       continue;
3639*5e7646d2SAndroid Build Coastguard Worker 
3640*5e7646d2SAndroid Build Coastguard Worker     snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type);
3641*5e7646d2SAndroid Build Coastguard Worker 
3642*5e7646d2SAndroid Build Coastguard Worker     if ((filters = mimeFilter(MimeDatabase, type, p->filetype, NULL)) != NULL)
3643*5e7646d2SAndroid Build Coastguard Worker     {
3644*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG2,
3645*5e7646d2SAndroid Build Coastguard Worker                       "add_printer_formats: %s: %s needs %d filters",
3646*5e7646d2SAndroid Build Coastguard Worker                       p->name, mimetype, cupsArrayCount(filters));
3647*5e7646d2SAndroid Build Coastguard Worker 
3648*5e7646d2SAndroid Build Coastguard Worker       cupsArrayDelete(filters);
3649*5e7646d2SAndroid Build Coastguard Worker       cupsArrayAdd(p->filetypes, type);
3650*5e7646d2SAndroid Build Coastguard Worker     }
3651*5e7646d2SAndroid Build Coastguard Worker     else
3652*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_DEBUG2,
3653*5e7646d2SAndroid Build Coastguard Worker                       "add_printer_formats: %s: %s not supported",
3654*5e7646d2SAndroid Build Coastguard Worker                       p->name, mimetype);
3655*5e7646d2SAndroid Build Coastguard Worker   }
3656*5e7646d2SAndroid Build Coastguard Worker 
3657*5e7646d2SAndroid Build Coastguard Worker  /*
3658*5e7646d2SAndroid Build Coastguard Worker   * Add the file formats that can be filtered...
3659*5e7646d2SAndroid Build Coastguard Worker   */
3660*5e7646d2SAndroid Build Coastguard Worker 
3661*5e7646d2SAndroid Build Coastguard Worker   if ((type = mimeType(MimeDatabase, "application", "octet-stream")) == NULL ||
3662*5e7646d2SAndroid Build Coastguard Worker       !cupsArrayFind(p->filetypes, type))
3663*5e7646d2SAndroid Build Coastguard Worker     i = 1;
3664*5e7646d2SAndroid Build Coastguard Worker   else
3665*5e7646d2SAndroid Build Coastguard Worker     i = 0;
3666*5e7646d2SAndroid Build Coastguard Worker 
3667*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG2,
3668*5e7646d2SAndroid Build Coastguard Worker                   "add_printer_formats: %s: %d supported types",
3669*5e7646d2SAndroid Build Coastguard Worker                   p->name, cupsArrayCount(p->filetypes) + i);
3670*5e7646d2SAndroid Build Coastguard Worker 
3671*5e7646d2SAndroid Build Coastguard Worker   attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
3672*5e7646d2SAndroid Build Coastguard Worker                        "document-format-supported",
3673*5e7646d2SAndroid Build Coastguard Worker                        cupsArrayCount(p->filetypes) + i, NULL, NULL);
3674*5e7646d2SAndroid Build Coastguard Worker 
3675*5e7646d2SAndroid Build Coastguard Worker   if (i)
3676*5e7646d2SAndroid Build Coastguard Worker     attr->values[0].string.text = _cupsStrAlloc("application/octet-stream");
3677*5e7646d2SAndroid Build Coastguard Worker 
3678*5e7646d2SAndroid Build Coastguard Worker   for (type = (mime_type_t *)cupsArrayFirst(p->filetypes);
3679*5e7646d2SAndroid Build Coastguard Worker        type;
3680*5e7646d2SAndroid Build Coastguard Worker        i ++, type = (mime_type_t *)cupsArrayNext(p->filetypes))
3681*5e7646d2SAndroid Build Coastguard Worker   {
3682*5e7646d2SAndroid Build Coastguard Worker     snprintf(mimetype, sizeof(mimetype), "%s/%s", type->super, type->type);
3683*5e7646d2SAndroid Build Coastguard Worker 
3684*5e7646d2SAndroid Build Coastguard Worker     attr->values[i].string.text = _cupsStrAlloc(mimetype);
3685*5e7646d2SAndroid Build Coastguard Worker   }
3686*5e7646d2SAndroid Build Coastguard Worker 
3687*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_DNSSD) || defined(HAVE_AVAHI)
3688*5e7646d2SAndroid Build Coastguard Worker   {
3689*5e7646d2SAndroid Build Coastguard Worker     char		pdl[1024];	/* Buffer to build pdl list */
3690*5e7646d2SAndroid Build Coastguard Worker     mime_filter_t	*filter;	/* MIME filter looping var */
3691*5e7646d2SAndroid Build Coastguard Worker 
3692*5e7646d2SAndroid Build Coastguard Worker 
3693*5e7646d2SAndroid Build Coastguard Worker    /*
3694*5e7646d2SAndroid Build Coastguard Worker     * We only support raw printing if this is not a Tioga PrintJobMgr based
3695*5e7646d2SAndroid Build Coastguard Worker     * queue and if application/octet-stream is a known type...
3696*5e7646d2SAndroid Build Coastguard Worker     */
3697*5e7646d2SAndroid Build Coastguard Worker 
3698*5e7646d2SAndroid Build Coastguard Worker     for (filter = (mime_filter_t *)cupsArrayFirst(MimeDatabase->filters);
3699*5e7646d2SAndroid Build Coastguard Worker 	 filter;
3700*5e7646d2SAndroid Build Coastguard Worker 	 filter = (mime_filter_t *)cupsArrayNext(MimeDatabase->filters))
3701*5e7646d2SAndroid Build Coastguard Worker     {
3702*5e7646d2SAndroid Build Coastguard Worker       if (filter->dst == p->filetype && strstr(filter->filter, "PrintJobMgr"))
3703*5e7646d2SAndroid Build Coastguard Worker 	break;
3704*5e7646d2SAndroid Build Coastguard Worker     }
3705*5e7646d2SAndroid Build Coastguard Worker 
3706*5e7646d2SAndroid Build Coastguard Worker     pdl[0] = '\0';
3707*5e7646d2SAndroid Build Coastguard Worker 
3708*5e7646d2SAndroid Build Coastguard Worker     if (!filter && mimeType(MimeDatabase, "application", "octet-stream"))
3709*5e7646d2SAndroid Build Coastguard Worker       strlcat(pdl, "application/octet-stream,", sizeof(pdl));
3710*5e7646d2SAndroid Build Coastguard Worker 
3711*5e7646d2SAndroid Build Coastguard Worker    /*
3712*5e7646d2SAndroid Build Coastguard Worker     * Then list a bunch of formats that are supported by the printer...
3713*5e7646d2SAndroid Build Coastguard Worker     */
3714*5e7646d2SAndroid Build Coastguard Worker 
3715*5e7646d2SAndroid Build Coastguard Worker     for (type = (mime_type_t *)cupsArrayFirst(p->filetypes);
3716*5e7646d2SAndroid Build Coastguard Worker 	 type;
3717*5e7646d2SAndroid Build Coastguard Worker 	 type = (mime_type_t *)cupsArrayNext(p->filetypes))
3718*5e7646d2SAndroid Build Coastguard Worker     {
3719*5e7646d2SAndroid Build Coastguard Worker       if (!_cups_strcasecmp(type->super, "application"))
3720*5e7646d2SAndroid Build Coastguard Worker       {
3721*5e7646d2SAndroid Build Coastguard Worker         if (!_cups_strcasecmp(type->type, "pdf"))
3722*5e7646d2SAndroid Build Coastguard Worker 	  strlcat(pdl, "application/pdf,", sizeof(pdl));
3723*5e7646d2SAndroid Build Coastguard Worker         else if (!_cups_strcasecmp(type->type, "postscript"))
3724*5e7646d2SAndroid Build Coastguard Worker 	  strlcat(pdl, "application/postscript,", sizeof(pdl));
3725*5e7646d2SAndroid Build Coastguard Worker       }
3726*5e7646d2SAndroid Build Coastguard Worker       else if (!_cups_strcasecmp(type->super, "image"))
3727*5e7646d2SAndroid Build Coastguard Worker       {
3728*5e7646d2SAndroid Build Coastguard Worker         if (!_cups_strcasecmp(type->type, "jpeg"))
3729*5e7646d2SAndroid Build Coastguard Worker 	  strlcat(pdl, "image/jpeg,", sizeof(pdl));
3730*5e7646d2SAndroid Build Coastguard Worker 	else if (!_cups_strcasecmp(type->type, "png"))
3731*5e7646d2SAndroid Build Coastguard Worker 	  strlcat(pdl, "image/png,", sizeof(pdl));
3732*5e7646d2SAndroid Build Coastguard Worker 	else if (!_cups_strcasecmp(type->type, "pwg-raster"))
3733*5e7646d2SAndroid Build Coastguard Worker 	  strlcat(pdl, "image/pwg-raster,", sizeof(pdl));
3734*5e7646d2SAndroid Build Coastguard Worker       }
3735*5e7646d2SAndroid Build Coastguard Worker     }
3736*5e7646d2SAndroid Build Coastguard Worker 
3737*5e7646d2SAndroid Build Coastguard Worker     if (pdl[0])
3738*5e7646d2SAndroid Build Coastguard Worker       pdl[strlen(pdl) - 1] = '\0';	/* Remove trailing comma */
3739*5e7646d2SAndroid Build Coastguard Worker 
3740*5e7646d2SAndroid Build Coastguard Worker     cupsdSetString(&p->pdl, pdl);
3741*5e7646d2SAndroid Build Coastguard Worker   }
3742*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_DNSSD || HAVE_AVAHI */
3743*5e7646d2SAndroid Build Coastguard Worker }
3744*5e7646d2SAndroid Build Coastguard Worker 
3745*5e7646d2SAndroid Build Coastguard Worker 
3746*5e7646d2SAndroid Build Coastguard Worker /*
3747*5e7646d2SAndroid Build Coastguard Worker  * 'compare_printers()' - Compare two printers.
3748*5e7646d2SAndroid Build Coastguard Worker  */
3749*5e7646d2SAndroid Build Coastguard Worker 
3750*5e7646d2SAndroid Build Coastguard Worker static int				/* O - Result of comparison */
compare_printers(void * first,void * second,void * data)3751*5e7646d2SAndroid Build Coastguard Worker compare_printers(void *first,		/* I - First printer */
3752*5e7646d2SAndroid Build Coastguard Worker                  void *second,		/* I - Second printer */
3753*5e7646d2SAndroid Build Coastguard Worker 		 void *data)		/* I - App data (not used) */
3754*5e7646d2SAndroid Build Coastguard Worker {
3755*5e7646d2SAndroid Build Coastguard Worker   (void)data;
3756*5e7646d2SAndroid Build Coastguard Worker 
3757*5e7646d2SAndroid Build Coastguard Worker   return (_cups_strcasecmp(((cupsd_printer_t *)first)->name,
3758*5e7646d2SAndroid Build Coastguard Worker                      ((cupsd_printer_t *)second)->name));
3759*5e7646d2SAndroid Build Coastguard Worker }
3760*5e7646d2SAndroid Build Coastguard Worker 
3761*5e7646d2SAndroid Build Coastguard Worker 
3762*5e7646d2SAndroid Build Coastguard Worker /*
3763*5e7646d2SAndroid Build Coastguard Worker  * 'delete_printer_filters()' - Delete all MIME filters for a printer.
3764*5e7646d2SAndroid Build Coastguard Worker  */
3765*5e7646d2SAndroid Build Coastguard Worker 
3766*5e7646d2SAndroid Build Coastguard Worker static void
delete_printer_filters(cupsd_printer_t * p)3767*5e7646d2SAndroid Build Coastguard Worker delete_printer_filters(
3768*5e7646d2SAndroid Build Coastguard Worker     cupsd_printer_t *p)			/* I - Printer to remove from */
3769*5e7646d2SAndroid Build Coastguard Worker {
3770*5e7646d2SAndroid Build Coastguard Worker   mime_filter_t	*filter;		/* MIME filter looping var */
3771*5e7646d2SAndroid Build Coastguard Worker   mime_type_t	*type;			/* Destination types for filters */
3772*5e7646d2SAndroid Build Coastguard Worker 
3773*5e7646d2SAndroid Build Coastguard Worker 
3774*5e7646d2SAndroid Build Coastguard Worker  /*
3775*5e7646d2SAndroid Build Coastguard Worker   * Range check input...
3776*5e7646d2SAndroid Build Coastguard Worker   */
3777*5e7646d2SAndroid Build Coastguard Worker 
3778*5e7646d2SAndroid Build Coastguard Worker   if (p == NULL)
3779*5e7646d2SAndroid Build Coastguard Worker     return;
3780*5e7646d2SAndroid Build Coastguard Worker 
3781*5e7646d2SAndroid Build Coastguard Worker  /*
3782*5e7646d2SAndroid Build Coastguard Worker   * Remove all filters from the MIME database that have a destination
3783*5e7646d2SAndroid Build Coastguard Worker   * type == printer...
3784*5e7646d2SAndroid Build Coastguard Worker   */
3785*5e7646d2SAndroid Build Coastguard Worker 
3786*5e7646d2SAndroid Build Coastguard Worker   for (filter = mimeFirstFilter(MimeDatabase);
3787*5e7646d2SAndroid Build Coastguard Worker        filter;
3788*5e7646d2SAndroid Build Coastguard Worker        filter = mimeNextFilter(MimeDatabase))
3789*5e7646d2SAndroid Build Coastguard Worker     if (filter->dst == p->filetype || filter->dst == p->prefiltertype ||
3790*5e7646d2SAndroid Build Coastguard Worker         cupsArrayFind(p->dest_types, filter->dst))
3791*5e7646d2SAndroid Build Coastguard Worker     {
3792*5e7646d2SAndroid Build Coastguard Worker      /*
3793*5e7646d2SAndroid Build Coastguard Worker       * Delete the current filter...
3794*5e7646d2SAndroid Build Coastguard Worker       */
3795*5e7646d2SAndroid Build Coastguard Worker 
3796*5e7646d2SAndroid Build Coastguard Worker       mimeDeleteFilter(MimeDatabase, filter);
3797*5e7646d2SAndroid Build Coastguard Worker     }
3798*5e7646d2SAndroid Build Coastguard Worker 
3799*5e7646d2SAndroid Build Coastguard Worker   for (type = (mime_type_t *)cupsArrayFirst(p->dest_types);
3800*5e7646d2SAndroid Build Coastguard Worker        type;
3801*5e7646d2SAndroid Build Coastguard Worker        type = (mime_type_t *)cupsArrayNext(p->dest_types))
3802*5e7646d2SAndroid Build Coastguard Worker     mimeDeleteType(MimeDatabase, type);
3803*5e7646d2SAndroid Build Coastguard Worker 
3804*5e7646d2SAndroid Build Coastguard Worker   cupsArrayDelete(p->dest_types);
3805*5e7646d2SAndroid Build Coastguard Worker   p->dest_types = NULL;
3806*5e7646d2SAndroid Build Coastguard Worker 
3807*5e7646d2SAndroid Build Coastguard Worker   cupsdSetPrinterReasons(p, "-cups-insecure-filter-warning"
3808*5e7646d2SAndroid Build Coastguard Worker                             ",cups-missing-filter-warning");
3809*5e7646d2SAndroid Build Coastguard Worker }
3810*5e7646d2SAndroid Build Coastguard Worker 
3811*5e7646d2SAndroid Build Coastguard Worker 
3812*5e7646d2SAndroid Build Coastguard Worker /*
3813*5e7646d2SAndroid Build Coastguard Worker  * 'dirty_printer()' - Mark config and state files dirty for the specified
3814*5e7646d2SAndroid Build Coastguard Worker  *                     printer.
3815*5e7646d2SAndroid Build Coastguard Worker  */
3816*5e7646d2SAndroid Build Coastguard Worker 
3817*5e7646d2SAndroid Build Coastguard Worker static void
dirty_printer(cupsd_printer_t * p)3818*5e7646d2SAndroid Build Coastguard Worker dirty_printer(cupsd_printer_t *p)	/* I - Printer */
3819*5e7646d2SAndroid Build Coastguard Worker {
3820*5e7646d2SAndroid Build Coastguard Worker   if (p->type & CUPS_PRINTER_CLASS)
3821*5e7646d2SAndroid Build Coastguard Worker     cupsdMarkDirty(CUPSD_DIRTY_CLASSES);
3822*5e7646d2SAndroid Build Coastguard Worker   else
3823*5e7646d2SAndroid Build Coastguard Worker     cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
3824*5e7646d2SAndroid Build Coastguard Worker 
3825*5e7646d2SAndroid Build Coastguard Worker   if (PrintcapFormat == PRINTCAP_PLIST)
3826*5e7646d2SAndroid Build Coastguard Worker     cupsdMarkDirty(CUPSD_DIRTY_PRINTCAP);
3827*5e7646d2SAndroid Build Coastguard Worker }
3828*5e7646d2SAndroid Build Coastguard Worker 
3829*5e7646d2SAndroid Build Coastguard Worker 
3830*5e7646d2SAndroid Build Coastguard Worker /*
3831*5e7646d2SAndroid Build Coastguard Worker  * 'load_ppd()' - Load a cached PPD file, updating the cache as needed.
3832*5e7646d2SAndroid Build Coastguard Worker  */
3833*5e7646d2SAndroid Build Coastguard Worker 
3834*5e7646d2SAndroid Build Coastguard Worker static void
load_ppd(cupsd_printer_t * p)3835*5e7646d2SAndroid Build Coastguard Worker load_ppd(cupsd_printer_t *p)		/* I - Printer */
3836*5e7646d2SAndroid Build Coastguard Worker {
3837*5e7646d2SAndroid Build Coastguard Worker   int		i, j;			/* Looping vars */
3838*5e7646d2SAndroid Build Coastguard Worker   char		cache_name[1024];	/* Cache filename */
3839*5e7646d2SAndroid Build Coastguard Worker   struct stat	cache_info;		/* Cache file info */
3840*5e7646d2SAndroid Build Coastguard Worker   ppd_file_t	*ppd;			/* PPD file */
3841*5e7646d2SAndroid Build Coastguard Worker   char		ppd_name[1024];		/* PPD filename */
3842*5e7646d2SAndroid Build Coastguard Worker   struct stat	ppd_info;		/* PPD file info */
3843*5e7646d2SAndroid Build Coastguard Worker   char		strings_name[1024];	/* Strings filename */
3844*5e7646d2SAndroid Build Coastguard Worker   int		num_media;		/* Number of media values */
3845*5e7646d2SAndroid Build Coastguard Worker   ppd_size_t	*size;			/* Current PPD size */
3846*5e7646d2SAndroid Build Coastguard Worker   ppd_option_t	*duplex,		/* Duplex option */
3847*5e7646d2SAndroid Build Coastguard Worker 		*output_bin,		/* OutputBin option */
3848*5e7646d2SAndroid Build Coastguard Worker 		*output_mode,		/* OutputMode option */
3849*5e7646d2SAndroid Build Coastguard Worker 		*resolution;		/* (Set|JCL|)Resolution option */
3850*5e7646d2SAndroid Build Coastguard Worker   ppd_choice_t	*choice;		/* Current PPD choice */
3851*5e7646d2SAndroid Build Coastguard Worker   ppd_attr_t	*ppd_attr;		/* PPD attribute */
3852*5e7646d2SAndroid Build Coastguard Worker   int		xdpi,			/* Horizontal resolution */
3853*5e7646d2SAndroid Build Coastguard Worker 		ydpi;			/* Vertical resolution */
3854*5e7646d2SAndroid Build Coastguard Worker   const char	*resptr;		/* Pointer into resolution keyword */
3855*5e7646d2SAndroid Build Coastguard Worker   pwg_size_t	*pwgsize;		/* Current PWG size */
3856*5e7646d2SAndroid Build Coastguard Worker   pwg_map_t	*pwgsource,		/* Current PWG source */
3857*5e7646d2SAndroid Build Coastguard Worker 		*pwgtype;		/* Current PWG type */
3858*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Attribute data */
3859*5e7646d2SAndroid Build Coastguard Worker   _ipp_value_t	*val;			/* Attribute value */
3860*5e7646d2SAndroid Build Coastguard Worker   int		num_finishings,		/* Number of finishings */
3861*5e7646d2SAndroid Build Coastguard Worker 		finishings[100];	/* finishings-supported values */
3862*5e7646d2SAndroid Build Coastguard Worker   int		num_qualities,		/* Number of print-quality values */
3863*5e7646d2SAndroid Build Coastguard Worker 		qualities[3];		/* print-quality values */
3864*5e7646d2SAndroid Build Coastguard Worker   int		num_margins,		/* Number of media-*-margin-supported values */
3865*5e7646d2SAndroid Build Coastguard Worker 		margins[16];		/* media-*-margin-supported values */
3866*5e7646d2SAndroid Build Coastguard Worker   const char	*filter,		/* Current filter */
3867*5e7646d2SAndroid Build Coastguard Worker 		*mandatory;		/* Current mandatory attribute */
3868*5e7646d2SAndroid Build Coastguard Worker   static const char * const pwg_raster_document_types[] =
3869*5e7646d2SAndroid Build Coastguard Worker 		{
3870*5e7646d2SAndroid Build Coastguard Worker 		  "black_1",
3871*5e7646d2SAndroid Build Coastguard Worker 		  "sgray_8",
3872*5e7646d2SAndroid Build Coastguard Worker 		  "srgb_8"
3873*5e7646d2SAndroid Build Coastguard Worker 		};
3874*5e7646d2SAndroid Build Coastguard Worker   static const char * const sides[3] =	/* sides-supported values */
3875*5e7646d2SAndroid Build Coastguard Worker 		{
3876*5e7646d2SAndroid Build Coastguard Worker 		  "one-sided",
3877*5e7646d2SAndroid Build Coastguard Worker 		  "two-sided-long-edge",
3878*5e7646d2SAndroid Build Coastguard Worker 		  "two-sided-short-edge"
3879*5e7646d2SAndroid Build Coastguard Worker 		};
3880*5e7646d2SAndroid Build Coastguard Worker   static const char * const standard_commands[] =
3881*5e7646d2SAndroid Build Coastguard Worker 		{			/* Standard CUPS commands */
3882*5e7646d2SAndroid Build Coastguard Worker 		  "AutoConfigure",
3883*5e7646d2SAndroid Build Coastguard Worker 		  "Clean",
3884*5e7646d2SAndroid Build Coastguard Worker 		  "PrintSelfTestPage"
3885*5e7646d2SAndroid Build Coastguard Worker 		};
3886*5e7646d2SAndroid Build Coastguard Worker 
3887*5e7646d2SAndroid Build Coastguard Worker 
3888*5e7646d2SAndroid Build Coastguard Worker  /*
3889*5e7646d2SAndroid Build Coastguard Worker   * Check to see if the cache is up-to-date...
3890*5e7646d2SAndroid Build Coastguard Worker   */
3891*5e7646d2SAndroid Build Coastguard Worker 
3892*5e7646d2SAndroid Build Coastguard Worker   snprintf(cache_name, sizeof(cache_name), "%s/%s.data", CacheDir, p->name);
3893*5e7646d2SAndroid Build Coastguard Worker   if (stat(cache_name, &cache_info))
3894*5e7646d2SAndroid Build Coastguard Worker     cache_info.st_mtime = 0;
3895*5e7646d2SAndroid Build Coastguard Worker 
3896*5e7646d2SAndroid Build Coastguard Worker   snprintf(ppd_name, sizeof(ppd_name), "%s/ppd/%s.ppd", ServerRoot, p->name);
3897*5e7646d2SAndroid Build Coastguard Worker   if (stat(ppd_name, &ppd_info))
3898*5e7646d2SAndroid Build Coastguard Worker     ppd_info.st_mtime = 1;
3899*5e7646d2SAndroid Build Coastguard Worker 
3900*5e7646d2SAndroid Build Coastguard Worker   snprintf(strings_name, sizeof(strings_name), "%s/%s.strings", CacheDir, p->name);
3901*5e7646d2SAndroid Build Coastguard Worker 
3902*5e7646d2SAndroid Build Coastguard Worker   ippDelete(p->ppd_attrs);
3903*5e7646d2SAndroid Build Coastguard Worker   p->ppd_attrs = NULL;
3904*5e7646d2SAndroid Build Coastguard Worker 
3905*5e7646d2SAndroid Build Coastguard Worker   _ppdCacheDestroy(p->pc);
3906*5e7646d2SAndroid Build Coastguard Worker   p->pc = NULL;
3907*5e7646d2SAndroid Build Coastguard Worker 
3908*5e7646d2SAndroid Build Coastguard Worker   if (cache_info.st_mtime >= ppd_info.st_mtime)
3909*5e7646d2SAndroid Build Coastguard Worker   {
3910*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Loading %s...", cache_name);
3911*5e7646d2SAndroid Build Coastguard Worker 
3912*5e7646d2SAndroid Build Coastguard Worker     if ((p->pc = _ppdCacheCreateWithFile(cache_name, &p->ppd_attrs)) != NULL &&
3913*5e7646d2SAndroid Build Coastguard Worker         p->ppd_attrs)
3914*5e7646d2SAndroid Build Coastguard Worker     {
3915*5e7646d2SAndroid Build Coastguard Worker      /*
3916*5e7646d2SAndroid Build Coastguard Worker       * Loaded successfully!
3917*5e7646d2SAndroid Build Coastguard Worker       */
3918*5e7646d2SAndroid Build Coastguard Worker 
3919*5e7646d2SAndroid Build Coastguard Worker       return;
3920*5e7646d2SAndroid Build Coastguard Worker     }
3921*5e7646d2SAndroid Build Coastguard Worker   }
3922*5e7646d2SAndroid Build Coastguard Worker 
3923*5e7646d2SAndroid Build Coastguard Worker  /*
3924*5e7646d2SAndroid Build Coastguard Worker   * Reload PPD attributes from disk...
3925*5e7646d2SAndroid Build Coastguard Worker   */
3926*5e7646d2SAndroid Build Coastguard Worker 
3927*5e7646d2SAndroid Build Coastguard Worker   cupsdMarkDirty(CUPSD_DIRTY_PRINTERS);
3928*5e7646d2SAndroid Build Coastguard Worker 
3929*5e7646d2SAndroid Build Coastguard Worker   cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Loading %s...", ppd_name);
3930*5e7646d2SAndroid Build Coastguard Worker 
3931*5e7646d2SAndroid Build Coastguard Worker   cupsdClearString(&(p->make_model));
3932*5e7646d2SAndroid Build Coastguard Worker 
3933*5e7646d2SAndroid Build Coastguard Worker   p->type &= (cups_ptype_t)~CUPS_PRINTER_OPTIONS;
3934*5e7646d2SAndroid Build Coastguard Worker   p->type |= CUPS_PRINTER_BW;
3935*5e7646d2SAndroid Build Coastguard Worker 
3936*5e7646d2SAndroid Build Coastguard Worker   finishings[0]  = IPP_FINISHINGS_NONE;
3937*5e7646d2SAndroid Build Coastguard Worker   num_finishings = 1;
3938*5e7646d2SAndroid Build Coastguard Worker 
3939*5e7646d2SAndroid Build Coastguard Worker   p->ppd_attrs = ippNew();
3940*5e7646d2SAndroid Build Coastguard Worker 
3941*5e7646d2SAndroid Build Coastguard Worker   if ((ppd = _ppdOpenFile(ppd_name, _PPD_LOCALIZATION_NONE)) != NULL)
3942*5e7646d2SAndroid Build Coastguard Worker   {
3943*5e7646d2SAndroid Build Coastguard Worker    /*
3944*5e7646d2SAndroid Build Coastguard Worker     * Add make/model and other various attributes...
3945*5e7646d2SAndroid Build Coastguard Worker     */
3946*5e7646d2SAndroid Build Coastguard Worker 
3947*5e7646d2SAndroid Build Coastguard Worker     p->pc = _ppdCacheCreateWithPPD(ppd);
3948*5e7646d2SAndroid Build Coastguard Worker 
3949*5e7646d2SAndroid Build Coastguard Worker     if (!p->pc)
3950*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_WARN, "Unable to create cache of \"%s\": %s",
3951*5e7646d2SAndroid Build Coastguard Worker                       ppd_name, cupsLastErrorString());
3952*5e7646d2SAndroid Build Coastguard Worker 
3953*5e7646d2SAndroid Build Coastguard Worker     ppdMarkDefaults(ppd);
3954*5e7646d2SAndroid Build Coastguard Worker 
3955*5e7646d2SAndroid Build Coastguard Worker     if (ppd->color_device)
3956*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_COLOR;
3957*5e7646d2SAndroid Build Coastguard Worker     if (ppd->variable_sizes)
3958*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_VARIABLE;
3959*5e7646d2SAndroid Build Coastguard Worker     if (!ppd->manual_copies)
3960*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_COPIES;
3961*5e7646d2SAndroid Build Coastguard Worker     if ((ppd_attr = ppdFindAttr(ppd, "cupsFax", NULL)) != NULL)
3962*5e7646d2SAndroid Build Coastguard Worker       if (ppd_attr->value && !_cups_strcasecmp(ppd_attr->value, "true"))
3963*5e7646d2SAndroid Build Coastguard Worker 	p->type |= CUPS_PRINTER_FAX;
3964*5e7646d2SAndroid Build Coastguard Worker 
3965*5e7646d2SAndroid Build Coastguard Worker     ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "color-supported", (char)ppd->color_device);
3966*5e7646d2SAndroid Build Coastguard Worker 
3967*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->charge_info_uri)
3968*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_URI,
3969*5e7646d2SAndroid Build Coastguard Worker                    "printer-charge-info-uri", NULL, p->pc->charge_info_uri);
3970*5e7646d2SAndroid Build Coastguard Worker 
3971*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->account_id)
3972*5e7646d2SAndroid Build Coastguard Worker       ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER, "job-account-id-supported",
3973*5e7646d2SAndroid Build Coastguard Worker                     1);
3974*5e7646d2SAndroid Build Coastguard Worker 
3975*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->accounting_user_id)
3976*5e7646d2SAndroid Build Coastguard Worker       ippAddBoolean(p->ppd_attrs, IPP_TAG_PRINTER,
3977*5e7646d2SAndroid Build Coastguard Worker                     "job-accounting-user-id-supported", 1);
3978*5e7646d2SAndroid Build Coastguard Worker 
3979*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->password)
3980*5e7646d2SAndroid Build Coastguard Worker     {
3981*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
3982*5e7646d2SAndroid Build Coastguard Worker                    "job-password-encryption-supported", NULL, "none");
3983*5e7646d2SAndroid Build Coastguard Worker       ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
3984*5e7646d2SAndroid Build Coastguard Worker                     "job-password-supported", (int)strlen(p->pc->password));
3985*5e7646d2SAndroid Build Coastguard Worker     }
3986*5e7646d2SAndroid Build Coastguard Worker 
3987*5e7646d2SAndroid Build Coastguard Worker     if (ppd->throughput)
3988*5e7646d2SAndroid Build Coastguard Worker     {
3989*5e7646d2SAndroid Build Coastguard Worker       ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
3990*5e7646d2SAndroid Build Coastguard Worker 		    "pages-per-minute", ppd->throughput);
3991*5e7646d2SAndroid Build Coastguard Worker       if (ppd->color_device)
3992*5e7646d2SAndroid Build Coastguard Worker 	ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
3993*5e7646d2SAndroid Build Coastguard Worker 		      "pages-per-minute-color", ppd->throughput);
3994*5e7646d2SAndroid Build Coastguard Worker     }
3995*5e7646d2SAndroid Build Coastguard Worker     else
3996*5e7646d2SAndroid Build Coastguard Worker     {
3997*5e7646d2SAndroid Build Coastguard Worker      /*
3998*5e7646d2SAndroid Build Coastguard Worker       * When there is no speed information, just say "1 page per minute".
3999*5e7646d2SAndroid Build Coastguard Worker       */
4000*5e7646d2SAndroid Build Coastguard Worker 
4001*5e7646d2SAndroid Build Coastguard Worker       ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4002*5e7646d2SAndroid Build Coastguard Worker 		    "pages-per-minute", 1);
4003*5e7646d2SAndroid Build Coastguard Worker       if (ppd->color_device)
4004*5e7646d2SAndroid Build Coastguard Worker 	ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4005*5e7646d2SAndroid Build Coastguard Worker 		      "pages-per-minute-color", 1);
4006*5e7646d2SAndroid Build Coastguard Worker     }
4007*5e7646d2SAndroid Build Coastguard Worker 
4008*5e7646d2SAndroid Build Coastguard Worker     if ((ppd_attr = ppdFindAttr(ppd, "1284DeviceId", NULL)) != NULL)
4009*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-device-id", NULL, ppd_attr->value);
4010*5e7646d2SAndroid Build Coastguard Worker 
4011*5e7646d2SAndroid Build Coastguard Worker     num_qualities = 0;
4012*5e7646d2SAndroid Build Coastguard Worker 
4013*5e7646d2SAndroid Build Coastguard Worker     if ((output_mode = ppdFindOption(ppd, "OutputMode")) ||
4014*5e7646d2SAndroid Build Coastguard Worker         (output_mode = ppdFindOption(ppd, "cupsPrintQuality")))
4015*5e7646d2SAndroid Build Coastguard Worker     {
4016*5e7646d2SAndroid Build Coastguard Worker       if (ppdFindChoice(output_mode, "draft") ||
4017*5e7646d2SAndroid Build Coastguard Worker           ppdFindChoice(output_mode, "fast"))
4018*5e7646d2SAndroid Build Coastguard Worker         qualities[num_qualities ++] = IPP_QUALITY_DRAFT;
4019*5e7646d2SAndroid Build Coastguard Worker 
4020*5e7646d2SAndroid Build Coastguard Worker       qualities[num_qualities ++] = IPP_QUALITY_NORMAL;
4021*5e7646d2SAndroid Build Coastguard Worker 
4022*5e7646d2SAndroid Build Coastguard Worker       if (ppdFindChoice(output_mode, "best") ||
4023*5e7646d2SAndroid Build Coastguard Worker           ppdFindChoice(output_mode, "high"))
4024*5e7646d2SAndroid Build Coastguard Worker         qualities[num_qualities ++] = IPP_QUALITY_HIGH;
4025*5e7646d2SAndroid Build Coastguard Worker     }
4026*5e7646d2SAndroid Build Coastguard Worker     else if ((ppd_attr = ppdFindAttr(ppd, "APPrinterPreset", NULL)) != NULL)
4027*5e7646d2SAndroid Build Coastguard Worker     {
4028*5e7646d2SAndroid Build Coastguard Worker       do
4029*5e7646d2SAndroid Build Coastguard Worker       {
4030*5e7646d2SAndroid Build Coastguard Worker         if (strstr(ppd_attr->spec, "draft") ||
4031*5e7646d2SAndroid Build Coastguard Worker 	    strstr(ppd_attr->spec, "Draft"))
4032*5e7646d2SAndroid Build Coastguard Worker 	{
4033*5e7646d2SAndroid Build Coastguard Worker 	  qualities[num_qualities ++] = IPP_QUALITY_DRAFT;
4034*5e7646d2SAndroid Build Coastguard Worker 	  break;
4035*5e7646d2SAndroid Build Coastguard Worker 	}
4036*5e7646d2SAndroid Build Coastguard Worker       }
4037*5e7646d2SAndroid Build Coastguard Worker       while ((ppd_attr = ppdFindNextAttr(ppd, "APPrinterPreset",
4038*5e7646d2SAndroid Build Coastguard Worker                                          NULL)) != NULL);
4039*5e7646d2SAndroid Build Coastguard Worker 
4040*5e7646d2SAndroid Build Coastguard Worker       qualities[num_qualities ++] = IPP_QUALITY_NORMAL;
4041*5e7646d2SAndroid Build Coastguard Worker       qualities[num_qualities ++] = IPP_QUALITY_HIGH;
4042*5e7646d2SAndroid Build Coastguard Worker     }
4043*5e7646d2SAndroid Build Coastguard Worker     else
4044*5e7646d2SAndroid Build Coastguard Worker       qualities[num_qualities ++] = IPP_QUALITY_NORMAL;
4045*5e7646d2SAndroid Build Coastguard Worker 
4046*5e7646d2SAndroid Build Coastguard Worker     ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
4047*5e7646d2SAndroid Build Coastguard Worker                    "print-quality-supported", num_qualities, qualities);
4048*5e7646d2SAndroid Build Coastguard Worker 
4049*5e7646d2SAndroid Build Coastguard Worker     if (ppd->nickname)
4050*5e7646d2SAndroid Build Coastguard Worker     {
4051*5e7646d2SAndroid Build Coastguard Worker      /*
4052*5e7646d2SAndroid Build Coastguard Worker       * The NickName can be localized in the character set specified
4053*5e7646d2SAndroid Build Coastguard Worker       * by the LanugageEncoding attribute.  However, ppdOpen2() has
4054*5e7646d2SAndroid Build Coastguard Worker       * already converted the ppd->nickname member to UTF-8 for us
4055*5e7646d2SAndroid Build Coastguard Worker       * (the original attribute value is available separately)
4056*5e7646d2SAndroid Build Coastguard Worker       */
4057*5e7646d2SAndroid Build Coastguard Worker 
4058*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->make_model, ppd->nickname);
4059*5e7646d2SAndroid Build Coastguard Worker     }
4060*5e7646d2SAndroid Build Coastguard Worker     else if (ppd->modelname)
4061*5e7646d2SAndroid Build Coastguard Worker     {
4062*5e7646d2SAndroid Build Coastguard Worker      /*
4063*5e7646d2SAndroid Build Coastguard Worker       * Model name can only contain specific characters...
4064*5e7646d2SAndroid Build Coastguard Worker       */
4065*5e7646d2SAndroid Build Coastguard Worker 
4066*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->make_model, ppd->modelname);
4067*5e7646d2SAndroid Build Coastguard Worker     }
4068*5e7646d2SAndroid Build Coastguard Worker     else
4069*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->make_model, "Bad PPD File");
4070*5e7646d2SAndroid Build Coastguard Worker 
4071*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
4072*5e7646d2SAndroid Build Coastguard Worker 		 "printer-make-and-model", NULL, p->make_model);
4073*5e7646d2SAndroid Build Coastguard Worker 
4074*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->strings)
4075*5e7646d2SAndroid Build Coastguard Worker       _cupsMessageSave(strings_name, _CUPS_MESSAGE_STRINGS, p->pc->strings);
4076*5e7646d2SAndroid Build Coastguard Worker 
4077*5e7646d2SAndroid Build Coastguard Worker     if (!access(strings_name, R_OK))
4078*5e7646d2SAndroid Build Coastguard Worker       cupsdSetString(&p->strings, strings_name);
4079*5e7646d2SAndroid Build Coastguard Worker     else
4080*5e7646d2SAndroid Build Coastguard Worker       cupsdClearString(&p->strings);
4081*5e7646d2SAndroid Build Coastguard Worker 
4082*5e7646d2SAndroid Build Coastguard Worker    /*
4083*5e7646d2SAndroid Build Coastguard Worker     * Add media options from the PPD file...
4084*5e7646d2SAndroid Build Coastguard Worker     */
4085*5e7646d2SAndroid Build Coastguard Worker 
4086*5e7646d2SAndroid Build Coastguard Worker     if (ppd->num_sizes == 0 || !p->pc)
4087*5e7646d2SAndroid Build Coastguard Worker     {
4088*5e7646d2SAndroid Build Coastguard Worker       if (!ppdFindAttr(ppd, "APScannerOnly", NULL) && !ppdFindAttr(ppd, "cups3D", NULL))
4089*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_CRIT,
4090*5e7646d2SAndroid Build Coastguard Worker 			"The PPD file for printer %s contains no media "
4091*5e7646d2SAndroid Build Coastguard Worker 			"options and is therefore invalid.", p->name);
4092*5e7646d2SAndroid Build Coastguard Worker 
4093*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4094*5e7646d2SAndroid Build Coastguard Worker 		   "media-default", NULL, "unknown");
4095*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4096*5e7646d2SAndroid Build Coastguard Worker 		   "media-supported", NULL, "unknown");
4097*5e7646d2SAndroid Build Coastguard Worker     }
4098*5e7646d2SAndroid Build Coastguard Worker     else
4099*5e7646d2SAndroid Build Coastguard Worker     {
4100*5e7646d2SAndroid Build Coastguard Worker      /*
4101*5e7646d2SAndroid Build Coastguard Worker       * media-default
4102*5e7646d2SAndroid Build Coastguard Worker       */
4103*5e7646d2SAndroid Build Coastguard Worker 
4104*5e7646d2SAndroid Build Coastguard Worker       if ((size = ppdPageSize(ppd, NULL)) != NULL)
4105*5e7646d2SAndroid Build Coastguard Worker         pwgsize = _ppdCacheGetSize(p->pc, size->name);
4106*5e7646d2SAndroid Build Coastguard Worker       else
4107*5e7646d2SAndroid Build Coastguard Worker         pwgsize = NULL;
4108*5e7646d2SAndroid Build Coastguard Worker 
4109*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4110*5e7646d2SAndroid Build Coastguard Worker 		   "media-default", NULL,
4111*5e7646d2SAndroid Build Coastguard Worker 		   pwgsize ? pwgsize->map.pwg : "unknown");
4112*5e7646d2SAndroid Build Coastguard Worker 
4113*5e7646d2SAndroid Build Coastguard Worker      /*
4114*5e7646d2SAndroid Build Coastguard Worker       * media-col-default
4115*5e7646d2SAndroid Build Coastguard Worker       */
4116*5e7646d2SAndroid Build Coastguard Worker 
4117*5e7646d2SAndroid Build Coastguard Worker       if (pwgsize)
4118*5e7646d2SAndroid Build Coastguard Worker       {
4119*5e7646d2SAndroid Build Coastguard Worker         ipp_t	*col;			/* Collection value */
4120*5e7646d2SAndroid Build Coastguard Worker 
4121*5e7646d2SAndroid Build Coastguard Worker 	col = new_media_col(pwgsize);
4122*5e7646d2SAndroid Build Coastguard Worker 	ippAddCollection(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-default", col);
4123*5e7646d2SAndroid Build Coastguard Worker         ippDelete(col);
4124*5e7646d2SAndroid Build Coastguard Worker       }
4125*5e7646d2SAndroid Build Coastguard Worker 
4126*5e7646d2SAndroid Build Coastguard Worker      /*
4127*5e7646d2SAndroid Build Coastguard Worker       * media-supported
4128*5e7646d2SAndroid Build Coastguard Worker       */
4129*5e7646d2SAndroid Build Coastguard Worker 
4130*5e7646d2SAndroid Build Coastguard Worker       num_media = p->pc->num_sizes;
4131*5e7646d2SAndroid Build Coastguard Worker       if (p->pc->custom_min_keyword)
4132*5e7646d2SAndroid Build Coastguard Worker 	num_media += 2;
4133*5e7646d2SAndroid Build Coastguard Worker 
4134*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4135*5e7646d2SAndroid Build Coastguard Worker 			        "media-supported", num_media, NULL,
4136*5e7646d2SAndroid Build Coastguard Worker 				NULL)) != NULL)
4137*5e7646d2SAndroid Build Coastguard Worker       {
4138*5e7646d2SAndroid Build Coastguard Worker 	val = attr->values;
4139*5e7646d2SAndroid Build Coastguard Worker 
4140*5e7646d2SAndroid Build Coastguard Worker         for (i = p->pc->num_sizes, pwgsize = p->pc->sizes;
4141*5e7646d2SAndroid Build Coastguard Worker 	     i > 0;
4142*5e7646d2SAndroid Build Coastguard Worker 	     i --, pwgsize ++, val ++)
4143*5e7646d2SAndroid Build Coastguard Worker 	  val->string.text = _cupsStrAlloc(pwgsize->map.pwg);
4144*5e7646d2SAndroid Build Coastguard Worker 
4145*5e7646d2SAndroid Build Coastguard Worker         if (p->pc->custom_min_keyword)
4146*5e7646d2SAndroid Build Coastguard Worker 	{
4147*5e7646d2SAndroid Build Coastguard Worker 	  val->string.text = _cupsStrAlloc(p->pc->custom_min_keyword);
4148*5e7646d2SAndroid Build Coastguard Worker 	  val ++;
4149*5e7646d2SAndroid Build Coastguard Worker 	  val->string.text = _cupsStrAlloc(p->pc->custom_max_keyword);
4150*5e7646d2SAndroid Build Coastguard Worker         }
4151*5e7646d2SAndroid Build Coastguard Worker       }
4152*5e7646d2SAndroid Build Coastguard Worker 
4153*5e7646d2SAndroid Build Coastguard Worker      /*
4154*5e7646d2SAndroid Build Coastguard Worker       * media-size-supported
4155*5e7646d2SAndroid Build Coastguard Worker       */
4156*5e7646d2SAndroid Build Coastguard Worker 
4157*5e7646d2SAndroid Build Coastguard Worker       num_media = p->pc->num_sizes;
4158*5e7646d2SAndroid Build Coastguard Worker       if (p->pc->custom_min_keyword)
4159*5e7646d2SAndroid Build Coastguard Worker 	num_media ++;
4160*5e7646d2SAndroid Build Coastguard Worker 
4161*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER,
4162*5e7646d2SAndroid Build Coastguard Worker 				    "media-size-supported", num_media,
4163*5e7646d2SAndroid Build Coastguard Worker 				    NULL)) != NULL)
4164*5e7646d2SAndroid Build Coastguard Worker       {
4165*5e7646d2SAndroid Build Coastguard Worker 	val = attr->values;
4166*5e7646d2SAndroid Build Coastguard Worker 
4167*5e7646d2SAndroid Build Coastguard Worker         for (i = p->pc->num_sizes, pwgsize = p->pc->sizes;
4168*5e7646d2SAndroid Build Coastguard Worker 	     i > 0;
4169*5e7646d2SAndroid Build Coastguard Worker 	     i --, pwgsize ++, val ++)
4170*5e7646d2SAndroid Build Coastguard Worker 	{
4171*5e7646d2SAndroid Build Coastguard Worker 	  val->collection = ippNew();
4172*5e7646d2SAndroid Build Coastguard Worker 	  ippAddInteger(val->collection, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4173*5e7646d2SAndroid Build Coastguard Worker 	                "x-dimension", pwgsize->width);
4174*5e7646d2SAndroid Build Coastguard Worker 	  ippAddInteger(val->collection, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4175*5e7646d2SAndroid Build Coastguard Worker 	                "y-dimension", pwgsize->length);
4176*5e7646d2SAndroid Build Coastguard Worker         }
4177*5e7646d2SAndroid Build Coastguard Worker 
4178*5e7646d2SAndroid Build Coastguard Worker         if (p->pc->custom_min_keyword)
4179*5e7646d2SAndroid Build Coastguard Worker 	{
4180*5e7646d2SAndroid Build Coastguard Worker 	  val->collection = ippNew();
4181*5e7646d2SAndroid Build Coastguard Worker 	  ippAddRange(val->collection, IPP_TAG_PRINTER, "x-dimension",
4182*5e7646d2SAndroid Build Coastguard Worker 	              p->pc->custom_min_width, p->pc->custom_max_width);
4183*5e7646d2SAndroid Build Coastguard Worker 	  ippAddRange(val->collection, IPP_TAG_PRINTER, "y-dimension",
4184*5e7646d2SAndroid Build Coastguard Worker 	              p->pc->custom_min_length, p->pc->custom_max_length);
4185*5e7646d2SAndroid Build Coastguard Worker         }
4186*5e7646d2SAndroid Build Coastguard Worker       }
4187*5e7646d2SAndroid Build Coastguard Worker 
4188*5e7646d2SAndroid Build Coastguard Worker      /*
4189*5e7646d2SAndroid Build Coastguard Worker       * media-source-supported
4190*5e7646d2SAndroid Build Coastguard Worker       */
4191*5e7646d2SAndroid Build Coastguard Worker 
4192*5e7646d2SAndroid Build Coastguard Worker       if (p->pc->num_sources > 0 &&
4193*5e7646d2SAndroid Build Coastguard Worker           (attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4194*5e7646d2SAndroid Build Coastguard Worker 	                        "media-source-supported", p->pc->num_sources,
4195*5e7646d2SAndroid Build Coastguard Worker 			        NULL, NULL)) != NULL)
4196*5e7646d2SAndroid Build Coastguard Worker       {
4197*5e7646d2SAndroid Build Coastguard Worker 	for (i = p->pc->num_sources, pwgsource = p->pc->sources,
4198*5e7646d2SAndroid Build Coastguard Worker 	         val = attr->values;
4199*5e7646d2SAndroid Build Coastguard Worker 	     i > 0;
4200*5e7646d2SAndroid Build Coastguard Worker 	     i --, pwgsource ++, val ++)
4201*5e7646d2SAndroid Build Coastguard Worker 	  val->string.text = _cupsStrAlloc(pwgsource->pwg);
4202*5e7646d2SAndroid Build Coastguard Worker       }
4203*5e7646d2SAndroid Build Coastguard Worker 
4204*5e7646d2SAndroid Build Coastguard Worker      /*
4205*5e7646d2SAndroid Build Coastguard Worker       * media-type-supported
4206*5e7646d2SAndroid Build Coastguard Worker       */
4207*5e7646d2SAndroid Build Coastguard Worker 
4208*5e7646d2SAndroid Build Coastguard Worker       if (p->pc->num_types > 0 &&
4209*5e7646d2SAndroid Build Coastguard Worker           (attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4210*5e7646d2SAndroid Build Coastguard Worker 	                        "media-type-supported", p->pc->num_types,
4211*5e7646d2SAndroid Build Coastguard Worker 			        NULL, NULL)) != NULL)
4212*5e7646d2SAndroid Build Coastguard Worker       {
4213*5e7646d2SAndroid Build Coastguard Worker 	for (i = p->pc->num_types, pwgtype = p->pc->types,
4214*5e7646d2SAndroid Build Coastguard Worker 	         val = attr->values;
4215*5e7646d2SAndroid Build Coastguard Worker 	     i > 0;
4216*5e7646d2SAndroid Build Coastguard Worker 	     i --, pwgtype ++, val ++)
4217*5e7646d2SAndroid Build Coastguard Worker 	  val->string.text = _cupsStrAlloc(pwgtype->pwg);
4218*5e7646d2SAndroid Build Coastguard Worker       }
4219*5e7646d2SAndroid Build Coastguard Worker 
4220*5e7646d2SAndroid Build Coastguard Worker      /*
4221*5e7646d2SAndroid Build Coastguard Worker       * media-*-margin-supported
4222*5e7646d2SAndroid Build Coastguard Worker       */
4223*5e7646d2SAndroid Build Coastguard Worker 
4224*5e7646d2SAndroid Build Coastguard Worker       for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
4225*5e7646d2SAndroid Build Coastguard Worker 	   i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
4226*5e7646d2SAndroid Build Coastguard Worker 	   i --, pwgsize ++)
4227*5e7646d2SAndroid Build Coastguard Worker       {
4228*5e7646d2SAndroid Build Coastguard Worker         for (j = 0; j < num_margins; j ++)
4229*5e7646d2SAndroid Build Coastguard Worker 	  if (pwgsize->bottom == margins[j])
4230*5e7646d2SAndroid Build Coastguard Worker 	    break;
4231*5e7646d2SAndroid Build Coastguard Worker 
4232*5e7646d2SAndroid Build Coastguard Worker 	if (j >= num_margins)
4233*5e7646d2SAndroid Build Coastguard Worker 	{
4234*5e7646d2SAndroid Build Coastguard Worker 	  margins[num_margins] = pwgsize->bottom;
4235*5e7646d2SAndroid Build Coastguard Worker 	  num_margins ++;
4236*5e7646d2SAndroid Build Coastguard Worker 	}
4237*5e7646d2SAndroid Build Coastguard Worker       }
4238*5e7646d2SAndroid Build Coastguard Worker 
4239*5e7646d2SAndroid Build Coastguard Worker       if (num_margins > 0)
4240*5e7646d2SAndroid Build Coastguard Worker         ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4241*5e7646d2SAndroid Build Coastguard Worker 		       "media-bottom-margin-supported", num_margins, margins);
4242*5e7646d2SAndroid Build Coastguard Worker       else
4243*5e7646d2SAndroid Build Coastguard Worker         ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4244*5e7646d2SAndroid Build Coastguard Worker 		      "media-bottom-margin-supported", 0);
4245*5e7646d2SAndroid Build Coastguard Worker 
4246*5e7646d2SAndroid Build Coastguard Worker       for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
4247*5e7646d2SAndroid Build Coastguard Worker 	   i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
4248*5e7646d2SAndroid Build Coastguard Worker 	   i --, pwgsize ++)
4249*5e7646d2SAndroid Build Coastguard Worker       {
4250*5e7646d2SAndroid Build Coastguard Worker         for (j = 0; j < num_margins; j ++)
4251*5e7646d2SAndroid Build Coastguard Worker 	  if (pwgsize->left == margins[j])
4252*5e7646d2SAndroid Build Coastguard Worker 	    break;
4253*5e7646d2SAndroid Build Coastguard Worker 
4254*5e7646d2SAndroid Build Coastguard Worker 	if (j >= num_margins)
4255*5e7646d2SAndroid Build Coastguard Worker 	{
4256*5e7646d2SAndroid Build Coastguard Worker 	  margins[num_margins] = pwgsize->left;
4257*5e7646d2SAndroid Build Coastguard Worker 	  num_margins ++;
4258*5e7646d2SAndroid Build Coastguard Worker 	}
4259*5e7646d2SAndroid Build Coastguard Worker       }
4260*5e7646d2SAndroid Build Coastguard Worker 
4261*5e7646d2SAndroid Build Coastguard Worker       if (num_margins > 0)
4262*5e7646d2SAndroid Build Coastguard Worker         ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4263*5e7646d2SAndroid Build Coastguard Worker 		       "media-left-margin-supported", num_margins, margins);
4264*5e7646d2SAndroid Build Coastguard Worker       else
4265*5e7646d2SAndroid Build Coastguard Worker         ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4266*5e7646d2SAndroid Build Coastguard Worker 		      "media-left-margin-supported", 0);
4267*5e7646d2SAndroid Build Coastguard Worker 
4268*5e7646d2SAndroid Build Coastguard Worker       for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
4269*5e7646d2SAndroid Build Coastguard Worker 	   i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
4270*5e7646d2SAndroid Build Coastguard Worker 	   i --, pwgsize ++)
4271*5e7646d2SAndroid Build Coastguard Worker       {
4272*5e7646d2SAndroid Build Coastguard Worker         for (j = 0; j < num_margins; j ++)
4273*5e7646d2SAndroid Build Coastguard Worker 	  if (pwgsize->right == margins[j])
4274*5e7646d2SAndroid Build Coastguard Worker 	    break;
4275*5e7646d2SAndroid Build Coastguard Worker 
4276*5e7646d2SAndroid Build Coastguard Worker 	if (j >= num_margins)
4277*5e7646d2SAndroid Build Coastguard Worker 	{
4278*5e7646d2SAndroid Build Coastguard Worker 	  margins[num_margins] = pwgsize->right;
4279*5e7646d2SAndroid Build Coastguard Worker 	  num_margins ++;
4280*5e7646d2SAndroid Build Coastguard Worker 	}
4281*5e7646d2SAndroid Build Coastguard Worker       }
4282*5e7646d2SAndroid Build Coastguard Worker 
4283*5e7646d2SAndroid Build Coastguard Worker       if (num_margins > 0)
4284*5e7646d2SAndroid Build Coastguard Worker         ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4285*5e7646d2SAndroid Build Coastguard Worker 		       "media-right-margin-supported", num_margins, margins);
4286*5e7646d2SAndroid Build Coastguard Worker       else
4287*5e7646d2SAndroid Build Coastguard Worker         ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4288*5e7646d2SAndroid Build Coastguard Worker 		      "media-right-margin-supported", 0);
4289*5e7646d2SAndroid Build Coastguard Worker 
4290*5e7646d2SAndroid Build Coastguard Worker       for (i = p->pc->num_sizes, pwgsize = p->pc->sizes, num_margins = 0;
4291*5e7646d2SAndroid Build Coastguard Worker 	   i > 0 && num_margins < (int)(sizeof(margins) / sizeof(margins[0]));
4292*5e7646d2SAndroid Build Coastguard Worker 	   i --, pwgsize ++)
4293*5e7646d2SAndroid Build Coastguard Worker       {
4294*5e7646d2SAndroid Build Coastguard Worker         for (j = 0; j < num_margins; j ++)
4295*5e7646d2SAndroid Build Coastguard Worker 	  if (pwgsize->top == margins[j])
4296*5e7646d2SAndroid Build Coastguard Worker 	    break;
4297*5e7646d2SAndroid Build Coastguard Worker 
4298*5e7646d2SAndroid Build Coastguard Worker 	if (j >= num_margins)
4299*5e7646d2SAndroid Build Coastguard Worker 	{
4300*5e7646d2SAndroid Build Coastguard Worker 	  margins[num_margins] = pwgsize->top;
4301*5e7646d2SAndroid Build Coastguard Worker 	  num_margins ++;
4302*5e7646d2SAndroid Build Coastguard Worker 	}
4303*5e7646d2SAndroid Build Coastguard Worker       }
4304*5e7646d2SAndroid Build Coastguard Worker 
4305*5e7646d2SAndroid Build Coastguard Worker       if (num_margins > 0)
4306*5e7646d2SAndroid Build Coastguard Worker         ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4307*5e7646d2SAndroid Build Coastguard Worker 		       "media-top-margin-supported", num_margins, margins);
4308*5e7646d2SAndroid Build Coastguard Worker       else
4309*5e7646d2SAndroid Build Coastguard Worker         ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
4310*5e7646d2SAndroid Build Coastguard Worker 		      "media-top-margin-supported", 0);
4311*5e7646d2SAndroid Build Coastguard Worker 
4312*5e7646d2SAndroid Build Coastguard Worker      /*
4313*5e7646d2SAndroid Build Coastguard Worker       * media-col-database
4314*5e7646d2SAndroid Build Coastguard Worker       */
4315*5e7646d2SAndroid Build Coastguard Worker 
4316*5e7646d2SAndroid Build Coastguard Worker       if ((attr = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, "media-col-database", p->pc->num_sizes, NULL)) != NULL)
4317*5e7646d2SAndroid Build Coastguard Worker       {
4318*5e7646d2SAndroid Build Coastguard Worker        /*
4319*5e7646d2SAndroid Build Coastguard Worker 	* Add each page size without source or type...
4320*5e7646d2SAndroid Build Coastguard Worker 	*/
4321*5e7646d2SAndroid Build Coastguard Worker 
4322*5e7646d2SAndroid Build Coastguard Worker         for (i = 0, pwgsize = p->pc->sizes; i < p->pc->num_sizes; i ++, pwgsize ++)
4323*5e7646d2SAndroid Build Coastguard Worker 	{
4324*5e7646d2SAndroid Build Coastguard Worker 	  ipp_t *col = new_media_col(pwgsize);
4325*5e7646d2SAndroid Build Coastguard Worker 
4326*5e7646d2SAndroid Build Coastguard Worker 	  ippSetCollection(p->ppd_attrs, &attr, i, col);
4327*5e7646d2SAndroid Build Coastguard Worker 	  ippDelete(col);
4328*5e7646d2SAndroid Build Coastguard Worker 	}
4329*5e7646d2SAndroid Build Coastguard Worker       }
4330*5e7646d2SAndroid Build Coastguard Worker     }
4331*5e7646d2SAndroid Build Coastguard Worker 
4332*5e7646d2SAndroid Build Coastguard Worker    /*
4333*5e7646d2SAndroid Build Coastguard Worker     * Output bin...
4334*5e7646d2SAndroid Build Coastguard Worker     */
4335*5e7646d2SAndroid Build Coastguard Worker 
4336*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->num_bins > 0)
4337*5e7646d2SAndroid Build Coastguard Worker     {
4338*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4339*5e7646d2SAndroid Build Coastguard Worker 			   "output-bin-supported", p->pc->num_bins,
4340*5e7646d2SAndroid Build Coastguard Worker 			   NULL, NULL);
4341*5e7646d2SAndroid Build Coastguard Worker 
4342*5e7646d2SAndroid Build Coastguard Worker       if (attr != NULL)
4343*5e7646d2SAndroid Build Coastguard Worker       {
4344*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0, val = attr->values;
4345*5e7646d2SAndroid Build Coastguard Worker 	     i < p->pc->num_bins;
4346*5e7646d2SAndroid Build Coastguard Worker 	     i ++, val ++)
4347*5e7646d2SAndroid Build Coastguard Worker 	  val->string.text = _cupsStrAlloc(p->pc->bins[i].pwg);
4348*5e7646d2SAndroid Build Coastguard Worker       }
4349*5e7646d2SAndroid Build Coastguard Worker 
4350*5e7646d2SAndroid Build Coastguard Worker       if ((output_bin = ppdFindOption(ppd, "OutputBin")) != NULL)
4351*5e7646d2SAndroid Build Coastguard Worker       {
4352*5e7646d2SAndroid Build Coastguard Worker 	for (i = 0; i < p->pc->num_bins; i ++)
4353*5e7646d2SAndroid Build Coastguard Worker 	  if (!strcmp(p->pc->bins[i].ppd, output_bin->defchoice))
4354*5e7646d2SAndroid Build Coastguard Worker 	    break;
4355*5e7646d2SAndroid Build Coastguard Worker 
4356*5e7646d2SAndroid Build Coastguard Worker         if (i >= p->pc->num_bins)
4357*5e7646d2SAndroid Build Coastguard Worker 	  i = 0;
4358*5e7646d2SAndroid Build Coastguard Worker 
4359*5e7646d2SAndroid Build Coastguard Worker 	ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4360*5e7646d2SAndroid Build Coastguard Worker 		     "output-bin-default", NULL, p->pc->bins[i].pwg);
4361*5e7646d2SAndroid Build Coastguard Worker       }
4362*5e7646d2SAndroid Build Coastguard Worker       else
4363*5e7646d2SAndroid Build Coastguard Worker         ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4364*5e7646d2SAndroid Build Coastguard Worker 	             "output-bin-default", NULL, p->pc->bins[0].pwg);
4365*5e7646d2SAndroid Build Coastguard Worker     }
4366*5e7646d2SAndroid Build Coastguard Worker     else if (((ppd_attr = ppdFindAttr(ppd, "DefaultOutputOrder",
4367*5e7646d2SAndroid Build Coastguard Worker                                      NULL)) != NULL &&
4368*5e7646d2SAndroid Build Coastguard Worker 	      !_cups_strcasecmp(ppd_attr->value, "Reverse")) ||
4369*5e7646d2SAndroid Build Coastguard Worker 	     (!ppd_attr && ppd->manufacturer &&	/* "Compatibility heuristic" */
4370*5e7646d2SAndroid Build Coastguard Worker 	      (!_cups_strcasecmp(ppd->manufacturer, "epson") ||
4371*5e7646d2SAndroid Build Coastguard Worker 	       !_cups_strcasecmp(ppd->manufacturer, "lexmark"))))
4372*5e7646d2SAndroid Build Coastguard Worker     {
4373*5e7646d2SAndroid Build Coastguard Worker      /*
4374*5e7646d2SAndroid Build Coastguard Worker       * Report that this printer has a single output bin that leaves pages face
4375*5e7646d2SAndroid Build Coastguard Worker       * up.
4376*5e7646d2SAndroid Build Coastguard Worker       */
4377*5e7646d2SAndroid Build Coastguard Worker 
4378*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4379*5e7646d2SAndroid Build Coastguard Worker 		   "output-bin-supported", NULL, "face-up");
4380*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4381*5e7646d2SAndroid Build Coastguard Worker 		   "output-bin-default", NULL, "face-up");
4382*5e7646d2SAndroid Build Coastguard Worker     }
4383*5e7646d2SAndroid Build Coastguard Worker     else
4384*5e7646d2SAndroid Build Coastguard Worker     {
4385*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4386*5e7646d2SAndroid Build Coastguard Worker 		   "output-bin-supported", NULL, "face-down");
4387*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4388*5e7646d2SAndroid Build Coastguard Worker 		   "output-bin-default", NULL, "face-down");
4389*5e7646d2SAndroid Build Coastguard Worker     }
4390*5e7646d2SAndroid Build Coastguard Worker 
4391*5e7646d2SAndroid Build Coastguard Worker    /*
4392*5e7646d2SAndroid Build Coastguard Worker     * print-color-mode...
4393*5e7646d2SAndroid Build Coastguard Worker     */
4394*5e7646d2SAndroid Build Coastguard Worker 
4395*5e7646d2SAndroid Build Coastguard Worker     if (ppd->color_device)
4396*5e7646d2SAndroid Build Coastguard Worker     {
4397*5e7646d2SAndroid Build Coastguard Worker       static const char * const color_modes[] =
4398*5e7646d2SAndroid Build Coastguard Worker       {
4399*5e7646d2SAndroid Build Coastguard Worker         "monochrome",
4400*5e7646d2SAndroid Build Coastguard Worker 	"color"
4401*5e7646d2SAndroid Build Coastguard Worker       };
4402*5e7646d2SAndroid Build Coastguard Worker 
4403*5e7646d2SAndroid Build Coastguard Worker       ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4404*5e7646d2SAndroid Build Coastguard Worker                     "print-color-mode-supported", 2, NULL, color_modes);
4405*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4406*5e7646d2SAndroid Build Coastguard Worker                    "print-color-mode-default", NULL, "color");
4407*5e7646d2SAndroid Build Coastguard Worker       ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "pwg-raster-document-type-supported", 3, NULL, pwg_raster_document_types);
4408*5e7646d2SAndroid Build Coastguard Worker     }
4409*5e7646d2SAndroid Build Coastguard Worker     else
4410*5e7646d2SAndroid Build Coastguard Worker     {
4411*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4412*5e7646d2SAndroid Build Coastguard Worker                    "print-color-mode-supported", NULL, "monochrome");
4413*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4414*5e7646d2SAndroid Build Coastguard Worker                    "print-color-mode-default", NULL, "monochrome");
4415*5e7646d2SAndroid Build Coastguard Worker       ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "pwg-raster-document-type-supported", 2, NULL, pwg_raster_document_types);
4416*5e7646d2SAndroid Build Coastguard Worker     }
4417*5e7646d2SAndroid Build Coastguard Worker 
4418*5e7646d2SAndroid Build Coastguard Worker    /*
4419*5e7646d2SAndroid Build Coastguard Worker     * Mandatory job attributes, if any...
4420*5e7646d2SAndroid Build Coastguard Worker     */
4421*5e7646d2SAndroid Build Coastguard Worker 
4422*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && cupsArrayCount(p->pc->mandatory) > 0)
4423*5e7646d2SAndroid Build Coastguard Worker     {
4424*5e7646d2SAndroid Build Coastguard Worker       int	count = cupsArrayCount(p->pc->mandatory);
4425*5e7646d2SAndroid Build Coastguard Worker 					/* Number of mandatory attributes */
4426*5e7646d2SAndroid Build Coastguard Worker 
4427*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4428*5e7646d2SAndroid Build Coastguard Worker                            "printer-mandatory-job-attributes", count, NULL,
4429*5e7646d2SAndroid Build Coastguard Worker                            NULL);
4430*5e7646d2SAndroid Build Coastguard Worker 
4431*5e7646d2SAndroid Build Coastguard Worker       for (val = attr->values,
4432*5e7646d2SAndroid Build Coastguard Worker                mandatory = (char *)cupsArrayFirst(p->pc->mandatory);
4433*5e7646d2SAndroid Build Coastguard Worker            mandatory;
4434*5e7646d2SAndroid Build Coastguard Worker            val ++, mandatory = (char *)cupsArrayNext(p->pc->mandatory))
4435*5e7646d2SAndroid Build Coastguard Worker         val->string.text = _cupsStrAlloc(mandatory);
4436*5e7646d2SAndroid Build Coastguard Worker     }
4437*5e7646d2SAndroid Build Coastguard Worker 
4438*5e7646d2SAndroid Build Coastguard Worker    /*
4439*5e7646d2SAndroid Build Coastguard Worker     * Printer resolutions...
4440*5e7646d2SAndroid Build Coastguard Worker     */
4441*5e7646d2SAndroid Build Coastguard Worker 
4442*5e7646d2SAndroid Build Coastguard Worker     if ((resolution = ppdFindOption(ppd, "Resolution")) == NULL)
4443*5e7646d2SAndroid Build Coastguard Worker       if ((resolution = ppdFindOption(ppd, "JCLResolution")) == NULL)
4444*5e7646d2SAndroid Build Coastguard Worker         if ((resolution = ppdFindOption(ppd, "SetResolution")) == NULL)
4445*5e7646d2SAndroid Build Coastguard Worker 	  resolution = ppdFindOption(ppd, "CNRes_PGP");
4446*5e7646d2SAndroid Build Coastguard Worker 
4447*5e7646d2SAndroid Build Coastguard Worker     if (resolution)
4448*5e7646d2SAndroid Build Coastguard Worker     {
4449*5e7646d2SAndroid Build Coastguard Worker      /*
4450*5e7646d2SAndroid Build Coastguard Worker       * Report all supported resolutions...
4451*5e7646d2SAndroid Build Coastguard Worker       */
4452*5e7646d2SAndroid Build Coastguard Worker 
4453*5e7646d2SAndroid Build Coastguard Worker       attr = ippAddResolutions(p->ppd_attrs, IPP_TAG_PRINTER, "printer-resolution-supported", resolution->num_choices, IPP_RES_PER_INCH, NULL, NULL);
4454*5e7646d2SAndroid Build Coastguard Worker 
4455*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, choice = resolution->choices;
4456*5e7646d2SAndroid Build Coastguard Worker            i < resolution->num_choices;
4457*5e7646d2SAndroid Build Coastguard Worker 	   i ++, choice ++)
4458*5e7646d2SAndroid Build Coastguard Worker       {
4459*5e7646d2SAndroid Build Coastguard Worker         xdpi = ydpi = (int)strtol(choice->choice, (char **)&resptr, 10);
4460*5e7646d2SAndroid Build Coastguard Worker 	if (resptr > choice->choice && xdpi > 0 && *resptr == 'x')
4461*5e7646d2SAndroid Build Coastguard Worker 	  ydpi = (int)strtol(resptr + 1, (char **)&resptr, 10);
4462*5e7646d2SAndroid Build Coastguard Worker 
4463*5e7646d2SAndroid Build Coastguard Worker 	if (xdpi <= 0 || ydpi <= 0)
4464*5e7646d2SAndroid Build Coastguard Worker 	{
4465*5e7646d2SAndroid Build Coastguard Worker 	  cupsdLogMessage(CUPSD_LOG_WARN,
4466*5e7646d2SAndroid Build Coastguard Worker 	                  "Bad resolution \"%s\" for printer %s.",
4467*5e7646d2SAndroid Build Coastguard Worker 			  choice->choice, p->name);
4468*5e7646d2SAndroid Build Coastguard Worker 	  xdpi = ydpi = 300;
4469*5e7646d2SAndroid Build Coastguard Worker 	}
4470*5e7646d2SAndroid Build Coastguard Worker 
4471*5e7646d2SAndroid Build Coastguard Worker         attr->values[i].resolution.xres  = xdpi;
4472*5e7646d2SAndroid Build Coastguard Worker         attr->values[i].resolution.yres  = ydpi;
4473*5e7646d2SAndroid Build Coastguard Worker         attr->values[i].resolution.units = IPP_RES_PER_INCH;
4474*5e7646d2SAndroid Build Coastguard Worker 
4475*5e7646d2SAndroid Build Coastguard Worker         if (choice->marked)
4476*5e7646d2SAndroid Build Coastguard Worker 	  ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, "printer-resolution-default", IPP_RES_PER_INCH, xdpi, ydpi);
4477*5e7646d2SAndroid Build Coastguard Worker 
4478*5e7646d2SAndroid Build Coastguard Worker         if (i == 0)
4479*5e7646d2SAndroid Build Coastguard Worker 	  ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, "pwg-raster-document-resolution-supported", IPP_RES_PER_INCH, xdpi, ydpi);
4480*5e7646d2SAndroid Build Coastguard Worker       }
4481*5e7646d2SAndroid Build Coastguard Worker     }
4482*5e7646d2SAndroid Build Coastguard Worker     else if ((ppd_attr = ppdFindAttr(ppd, "DefaultResolution", NULL)) != NULL &&
4483*5e7646d2SAndroid Build Coastguard Worker              ppd_attr->value)
4484*5e7646d2SAndroid Build Coastguard Worker     {
4485*5e7646d2SAndroid Build Coastguard Worker      /*
4486*5e7646d2SAndroid Build Coastguard Worker       * Just the DefaultResolution to report...
4487*5e7646d2SAndroid Build Coastguard Worker       */
4488*5e7646d2SAndroid Build Coastguard Worker 
4489*5e7646d2SAndroid Build Coastguard Worker       xdpi = ydpi = (int)strtol(ppd_attr->value, (char **)&resptr, 10);
4490*5e7646d2SAndroid Build Coastguard Worker       if (resptr > ppd_attr->value && xdpi > 0)
4491*5e7646d2SAndroid Build Coastguard Worker       {
4492*5e7646d2SAndroid Build Coastguard Worker 	if (*resptr == 'x')
4493*5e7646d2SAndroid Build Coastguard Worker 	  ydpi = (int)strtol(resptr + 1, (char **)&resptr, 10);
4494*5e7646d2SAndroid Build Coastguard Worker 	else
4495*5e7646d2SAndroid Build Coastguard Worker 	  ydpi = xdpi;
4496*5e7646d2SAndroid Build Coastguard Worker       }
4497*5e7646d2SAndroid Build Coastguard Worker 
4498*5e7646d2SAndroid Build Coastguard Worker       if (xdpi <= 0 || ydpi <= 0)
4499*5e7646d2SAndroid Build Coastguard Worker       {
4500*5e7646d2SAndroid Build Coastguard Worker 	cupsdLogMessage(CUPSD_LOG_WARN,
4501*5e7646d2SAndroid Build Coastguard Worker 			"Bad default resolution \"%s\" for printer %s.",
4502*5e7646d2SAndroid Build Coastguard Worker 			ppd_attr->value, p->name);
4503*5e7646d2SAndroid Build Coastguard Worker 	xdpi = ydpi = 300;
4504*5e7646d2SAndroid Build Coastguard Worker       }
4505*5e7646d2SAndroid Build Coastguard Worker 
4506*5e7646d2SAndroid Build Coastguard Worker       ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER,
4507*5e7646d2SAndroid Build Coastguard Worker 		       "printer-resolution-default", IPP_RES_PER_INCH,
4508*5e7646d2SAndroid Build Coastguard Worker 		       xdpi, ydpi);
4509*5e7646d2SAndroid Build Coastguard Worker       ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER,
4510*5e7646d2SAndroid Build Coastguard Worker 		       "printer-resolution-supported", IPP_RES_PER_INCH,
4511*5e7646d2SAndroid Build Coastguard Worker 		       xdpi, ydpi);
4512*5e7646d2SAndroid Build Coastguard Worker       ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, "pwg-raster-document-resolution-supported", IPP_RES_PER_INCH, xdpi, ydpi);
4513*5e7646d2SAndroid Build Coastguard Worker     }
4514*5e7646d2SAndroid Build Coastguard Worker     else
4515*5e7646d2SAndroid Build Coastguard Worker     {
4516*5e7646d2SAndroid Build Coastguard Worker      /*
4517*5e7646d2SAndroid Build Coastguard Worker       * No resolutions in PPD - make one up...
4518*5e7646d2SAndroid Build Coastguard Worker       */
4519*5e7646d2SAndroid Build Coastguard Worker 
4520*5e7646d2SAndroid Build Coastguard Worker       ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER,
4521*5e7646d2SAndroid Build Coastguard Worker 		       "printer-resolution-default", IPP_RES_PER_INCH,
4522*5e7646d2SAndroid Build Coastguard Worker 		       300, 300);
4523*5e7646d2SAndroid Build Coastguard Worker       ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER,
4524*5e7646d2SAndroid Build Coastguard Worker 		       "printer-resolution-supported", IPP_RES_PER_INCH,
4525*5e7646d2SAndroid Build Coastguard Worker 		       300, 300);
4526*5e7646d2SAndroid Build Coastguard Worker       ippAddResolution(p->ppd_attrs, IPP_TAG_PRINTER, "pwg-raster-document-resolution-supported", IPP_RES_PER_INCH, 300, 300);
4527*5e7646d2SAndroid Build Coastguard Worker     }
4528*5e7646d2SAndroid Build Coastguard Worker 
4529*5e7646d2SAndroid Build Coastguard Worker    /*
4530*5e7646d2SAndroid Build Coastguard Worker     * Duplexing, etc...
4531*5e7646d2SAndroid Build Coastguard Worker     */
4532*5e7646d2SAndroid Build Coastguard Worker 
4533*5e7646d2SAndroid Build Coastguard Worker     ppdMarkDefaults(ppd);
4534*5e7646d2SAndroid Build Coastguard Worker 
4535*5e7646d2SAndroid Build Coastguard Worker     if ((duplex = ppdFindOption(ppd, "Duplex")) == NULL)
4536*5e7646d2SAndroid Build Coastguard Worker       if ((duplex = ppdFindOption(ppd, "EFDuplex")) == NULL)
4537*5e7646d2SAndroid Build Coastguard Worker 	if ((duplex = ppdFindOption(ppd, "EFDuplexing")) == NULL)
4538*5e7646d2SAndroid Build Coastguard Worker 	  if ((duplex = ppdFindOption(ppd, "KD03Duplex")) == NULL)
4539*5e7646d2SAndroid Build Coastguard Worker 	    duplex = ppdFindOption(ppd, "JCLDuplex");
4540*5e7646d2SAndroid Build Coastguard Worker 
4541*5e7646d2SAndroid Build Coastguard Worker     if (duplex && duplex->num_choices > 1 &&
4542*5e7646d2SAndroid Build Coastguard Worker 	!ppdInstallableConflict(ppd, duplex->keyword, "DuplexTumble"))
4543*5e7646d2SAndroid Build Coastguard Worker     {
4544*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_DUPLEX;
4545*5e7646d2SAndroid Build Coastguard Worker 
4546*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "pwg-raster-document-sheet-back", NULL, "normal");
4547*5e7646d2SAndroid Build Coastguard Worker 
4548*5e7646d2SAndroid Build Coastguard Worker       ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4549*5e7646d2SAndroid Build Coastguard Worker 		    "sides-supported", 3, NULL, sides);
4550*5e7646d2SAndroid Build Coastguard Worker 
4551*5e7646d2SAndroid Build Coastguard Worker       if (!_cups_strcasecmp(duplex->defchoice, "DuplexTumble"))
4552*5e7646d2SAndroid Build Coastguard Worker 	ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4553*5e7646d2SAndroid Build Coastguard Worker 		     "sides-default", NULL, "two-sided-short-edge");
4554*5e7646d2SAndroid Build Coastguard Worker       else if (!_cups_strcasecmp(duplex->defchoice, "DuplexNoTumble"))
4555*5e7646d2SAndroid Build Coastguard Worker 	ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4556*5e7646d2SAndroid Build Coastguard Worker 		     "sides-default", NULL, "two-sided-long-edge");
4557*5e7646d2SAndroid Build Coastguard Worker       else
4558*5e7646d2SAndroid Build Coastguard Worker 	ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4559*5e7646d2SAndroid Build Coastguard Worker 		     "sides-default", NULL, "one-sided");
4560*5e7646d2SAndroid Build Coastguard Worker     }
4561*5e7646d2SAndroid Build Coastguard Worker     else
4562*5e7646d2SAndroid Build Coastguard Worker     {
4563*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4564*5e7646d2SAndroid Build Coastguard Worker 		   "sides-supported", NULL, "one-sided");
4565*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4566*5e7646d2SAndroid Build Coastguard Worker 		   "sides-default", NULL, "one-sided");
4567*5e7646d2SAndroid Build Coastguard Worker     }
4568*5e7646d2SAndroid Build Coastguard Worker 
4569*5e7646d2SAndroid Build Coastguard Worker     if (ppdFindOption(ppd, "Collate") != NULL)
4570*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_COLLATE;
4571*5e7646d2SAndroid Build Coastguard Worker 
4572*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->finishings)
4573*5e7646d2SAndroid Build Coastguard Worker     {
4574*5e7646d2SAndroid Build Coastguard Worker       _pwg_finishings_t	*fin;		/* Current finishing value */
4575*5e7646d2SAndroid Build Coastguard Worker 
4576*5e7646d2SAndroid Build Coastguard Worker       for (fin = (_pwg_finishings_t *)cupsArrayFirst(p->pc->finishings); fin; fin = (_pwg_finishings_t *)cupsArrayNext(p->pc->finishings))
4577*5e7646d2SAndroid Build Coastguard Worker       {
4578*5e7646d2SAndroid Build Coastguard Worker         if (num_finishings < (int)(sizeof(finishings) / sizeof(finishings[0])))
4579*5e7646d2SAndroid Build Coastguard Worker           finishings[num_finishings++] = (int)fin->value;
4580*5e7646d2SAndroid Build Coastguard Worker 
4581*5e7646d2SAndroid Build Coastguard Worker         switch (fin->value)
4582*5e7646d2SAndroid Build Coastguard Worker         {
4583*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_BIND :
4584*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_BIND_LEFT :
4585*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_BIND_TOP :
4586*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_BIND_RIGHT :
4587*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_BIND_BOTTOM :
4588*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_EDGE_STITCH :
4589*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_EDGE_STITCH_LEFT :
4590*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_EDGE_STITCH_TOP :
4591*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_EDGE_STITCH_RIGHT :
4592*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_EDGE_STITCH_BOTTOM :
4593*5e7646d2SAndroid Build Coastguard Worker               p->type |= CUPS_PRINTER_BIND;
4594*5e7646d2SAndroid Build Coastguard Worker               break;
4595*5e7646d2SAndroid Build Coastguard Worker 
4596*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_COVER :
4597*5e7646d2SAndroid Build Coastguard Worker               p->type |= CUPS_PRINTER_COVER;
4598*5e7646d2SAndroid Build Coastguard Worker               break;
4599*5e7646d2SAndroid Build Coastguard Worker 
4600*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH :
4601*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_TOP_LEFT :
4602*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_BOTTOM_LEFT :
4603*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_TOP_RIGHT :
4604*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_BOTTOM_RIGHT :
4605*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_DUAL_LEFT :
4606*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_DUAL_TOP :
4607*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_DUAL_RIGHT :
4608*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_DUAL_BOTTOM :
4609*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_TRIPLE_LEFT :
4610*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_TRIPLE_TOP :
4611*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_TRIPLE_RIGHT :
4612*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_TRIPLE_BOTTOM :
4613*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_QUAD_LEFT :
4614*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_QUAD_TOP :
4615*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_QUAD_RIGHT :
4616*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_PUNCH_QUAD_BOTTOM :
4617*5e7646d2SAndroid Build Coastguard Worker               p->type |= CUPS_PRINTER_PUNCH;
4618*5e7646d2SAndroid Build Coastguard Worker               break;
4619*5e7646d2SAndroid Build Coastguard Worker 
4620*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE :
4621*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_TOP_LEFT :
4622*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_BOTTOM_LEFT :
4623*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_TOP_RIGHT :
4624*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_BOTTOM_RIGHT :
4625*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_DUAL_LEFT :
4626*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_DUAL_TOP :
4627*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_DUAL_RIGHT :
4628*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_DUAL_BOTTOM :
4629*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_TRIPLE_LEFT :
4630*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_TRIPLE_TOP :
4631*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_TRIPLE_RIGHT :
4632*5e7646d2SAndroid Build Coastguard Worker           case IPP_FINISHINGS_STAPLE_TRIPLE_BOTTOM :
4633*5e7646d2SAndroid Build Coastguard Worker               p->type |= CUPS_PRINTER_STAPLE;
4634*5e7646d2SAndroid Build Coastguard Worker               break;
4635*5e7646d2SAndroid Build Coastguard Worker 
4636*5e7646d2SAndroid Build Coastguard Worker           default :
4637*5e7646d2SAndroid Build Coastguard Worker               break;
4638*5e7646d2SAndroid Build Coastguard Worker         }
4639*5e7646d2SAndroid Build Coastguard Worker       }
4640*5e7646d2SAndroid Build Coastguard Worker     }
4641*5e7646d2SAndroid Build Coastguard Worker 
4642*5e7646d2SAndroid Build Coastguard Worker     if (p->pc && p->pc->templates)
4643*5e7646d2SAndroid Build Coastguard Worker     {
4644*5e7646d2SAndroid Build Coastguard Worker       const char 	*template;	/* Finishing template */
4645*5e7646d2SAndroid Build Coastguard Worker       ipp_attribute_t	*fin_col_db;	/* finishings-col-database attribute */
4646*5e7646d2SAndroid Build Coastguard Worker       ipp_t		*fin_col;	/* finishings-col value */
4647*5e7646d2SAndroid Build Coastguard Worker 
4648*5e7646d2SAndroid Build Coastguard Worker       fin_col_db = ippAddCollections(p->ppd_attrs, IPP_TAG_PRINTER, "finishings-col-database", cupsArrayCount(p->pc->templates), NULL);
4649*5e7646d2SAndroid Build Coastguard Worker       for (i = 0, template = (const char *)cupsArrayFirst(p->pc->templates); template; i ++, template = (const char *)cupsArrayNext(p->pc->templates))
4650*5e7646d2SAndroid Build Coastguard Worker       {
4651*5e7646d2SAndroid Build Coastguard Worker         fin_col = ippNew();
4652*5e7646d2SAndroid Build Coastguard Worker         ippAddString(fin_col, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "finishing-template", NULL, template);
4653*5e7646d2SAndroid Build Coastguard Worker         ippSetCollection(p->ppd_attrs, &fin_col_db, i, fin_col);
4654*5e7646d2SAndroid Build Coastguard Worker         ippDelete(fin_col);
4655*5e7646d2SAndroid Build Coastguard Worker       }
4656*5e7646d2SAndroid Build Coastguard Worker     }
4657*5e7646d2SAndroid Build Coastguard Worker 
4658*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; i < ppd->num_sizes; i ++)
4659*5e7646d2SAndroid Build Coastguard Worker       if (ppd->sizes[i].length > 1728)
4660*5e7646d2SAndroid Build Coastguard Worker 	p->type |= CUPS_PRINTER_LARGE;
4661*5e7646d2SAndroid Build Coastguard Worker       else if (ppd->sizes[i].length > 1008)
4662*5e7646d2SAndroid Build Coastguard Worker 	p->type |= CUPS_PRINTER_MEDIUM;
4663*5e7646d2SAndroid Build Coastguard Worker       else
4664*5e7646d2SAndroid Build Coastguard Worker 	p->type |= CUPS_PRINTER_SMALL;
4665*5e7646d2SAndroid Build Coastguard Worker 
4666*5e7646d2SAndroid Build Coastguard Worker     if ((ppd_attr = ppdFindAttr(ppd, "APICADriver", NULL)) != NULL &&
4667*5e7646d2SAndroid Build Coastguard Worker         ppd_attr->value && !_cups_strcasecmp(ppd_attr->value, "true"))
4668*5e7646d2SAndroid Build Coastguard Worker     {
4669*5e7646d2SAndroid Build Coastguard Worker       if ((ppd_attr = ppdFindAttr(ppd, "APScannerOnly", NULL)) != NULL &&
4670*5e7646d2SAndroid Build Coastguard Worker 	  ppd_attr->value && !_cups_strcasecmp(ppd_attr->value, "true"))
4671*5e7646d2SAndroid Build Coastguard Worker         p->type |= CUPS_PRINTER_SCANNER;
4672*5e7646d2SAndroid Build Coastguard Worker       else
4673*5e7646d2SAndroid Build Coastguard Worker         p->type |= CUPS_PRINTER_MFP;
4674*5e7646d2SAndroid Build Coastguard Worker     }
4675*5e7646d2SAndroid Build Coastguard Worker 
4676*5e7646d2SAndroid Build Coastguard Worker    /*
4677*5e7646d2SAndroid Build Coastguard Worker     * Scan the filters in the PPD file...
4678*5e7646d2SAndroid Build Coastguard Worker     */
4679*5e7646d2SAndroid Build Coastguard Worker 
4680*5e7646d2SAndroid Build Coastguard Worker     if (p->pc)
4681*5e7646d2SAndroid Build Coastguard Worker     {
4682*5e7646d2SAndroid Build Coastguard Worker       for (filter = (const char *)cupsArrayFirst(p->pc->filters);
4683*5e7646d2SAndroid Build Coastguard Worker 	   filter;
4684*5e7646d2SAndroid Build Coastguard Worker 	   filter = (const char *)cupsArrayNext(p->pc->filters))
4685*5e7646d2SAndroid Build Coastguard Worker       {
4686*5e7646d2SAndroid Build Coastguard Worker 	if (!_cups_strncasecmp(filter, "application/vnd.cups-command", 28) &&
4687*5e7646d2SAndroid Build Coastguard Worker 	    _cups_isspace(filter[28]))
4688*5e7646d2SAndroid Build Coastguard Worker 	{
4689*5e7646d2SAndroid Build Coastguard Worker 	  p->type |= CUPS_PRINTER_COMMANDS;
4690*5e7646d2SAndroid Build Coastguard Worker 	  break;
4691*5e7646d2SAndroid Build Coastguard Worker 	}
4692*5e7646d2SAndroid Build Coastguard Worker       }
4693*5e7646d2SAndroid Build Coastguard Worker     }
4694*5e7646d2SAndroid Build Coastguard Worker 
4695*5e7646d2SAndroid Build Coastguard Worker     if (p->type & CUPS_PRINTER_COMMANDS)
4696*5e7646d2SAndroid Build Coastguard Worker     {
4697*5e7646d2SAndroid Build Coastguard Worker       char	*commands,		/* Copy of commands */
4698*5e7646d2SAndroid Build Coastguard Worker 		*start,			/* Start of name */
4699*5e7646d2SAndroid Build Coastguard Worker 		*end;			/* End of name */
4700*5e7646d2SAndroid Build Coastguard Worker       int	count;			/* Number of commands */
4701*5e7646d2SAndroid Build Coastguard Worker 
4702*5e7646d2SAndroid Build Coastguard Worker       if ((ppd_attr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL)
4703*5e7646d2SAndroid Build Coastguard Worker       {
4704*5e7646d2SAndroid Build Coastguard Worker 	for (count = 0, start = ppd_attr->value; *start; count ++)
4705*5e7646d2SAndroid Build Coastguard Worker 	{
4706*5e7646d2SAndroid Build Coastguard Worker 	  while (_cups_isspace(*start))
4707*5e7646d2SAndroid Build Coastguard Worker 	    start ++;
4708*5e7646d2SAndroid Build Coastguard Worker 
4709*5e7646d2SAndroid Build Coastguard Worker 	  if (!*start)
4710*5e7646d2SAndroid Build Coastguard Worker 	    break;
4711*5e7646d2SAndroid Build Coastguard Worker 
4712*5e7646d2SAndroid Build Coastguard Worker 	  while (*start && !isspace(*start & 255))
4713*5e7646d2SAndroid Build Coastguard Worker 	    start ++;
4714*5e7646d2SAndroid Build Coastguard Worker 	}
4715*5e7646d2SAndroid Build Coastguard Worker       }
4716*5e7646d2SAndroid Build Coastguard Worker       else
4717*5e7646d2SAndroid Build Coastguard Worker 	count = 0;
4718*5e7646d2SAndroid Build Coastguard Worker 
4719*5e7646d2SAndroid Build Coastguard Worker       if (count > 0)
4720*5e7646d2SAndroid Build Coastguard Worker       {
4721*5e7646d2SAndroid Build Coastguard Worker        /*
4722*5e7646d2SAndroid Build Coastguard Worker 	* Make a copy of the commands string and count how many commands there
4723*5e7646d2SAndroid Build Coastguard Worker 	* are...
4724*5e7646d2SAndroid Build Coastguard Worker 	*/
4725*5e7646d2SAndroid Build Coastguard Worker 
4726*5e7646d2SAndroid Build Coastguard Worker 	attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4727*5e7646d2SAndroid Build Coastguard Worker 			     "printer-commands", count, NULL, NULL);
4728*5e7646d2SAndroid Build Coastguard Worker 
4729*5e7646d2SAndroid Build Coastguard Worker 	commands = strdup(ppd_attr->value);
4730*5e7646d2SAndroid Build Coastguard Worker 
4731*5e7646d2SAndroid Build Coastguard Worker 	for (count = 0, start = commands; *start; count ++)
4732*5e7646d2SAndroid Build Coastguard Worker 	{
4733*5e7646d2SAndroid Build Coastguard Worker 	  while (isspace(*start & 255))
4734*5e7646d2SAndroid Build Coastguard Worker 	    start ++;
4735*5e7646d2SAndroid Build Coastguard Worker 
4736*5e7646d2SAndroid Build Coastguard Worker 	  if (!*start)
4737*5e7646d2SAndroid Build Coastguard Worker 	    break;
4738*5e7646d2SAndroid Build Coastguard Worker 
4739*5e7646d2SAndroid Build Coastguard Worker 	  end = start;
4740*5e7646d2SAndroid Build Coastguard Worker 	  while (*end && !isspace(*end & 255))
4741*5e7646d2SAndroid Build Coastguard Worker 	    end ++;
4742*5e7646d2SAndroid Build Coastguard Worker 
4743*5e7646d2SAndroid Build Coastguard Worker 	  if (*end)
4744*5e7646d2SAndroid Build Coastguard Worker 	    *end++ = '\0';
4745*5e7646d2SAndroid Build Coastguard Worker 
4746*5e7646d2SAndroid Build Coastguard Worker 	  attr->values[count].string.text = _cupsStrAlloc(start);
4747*5e7646d2SAndroid Build Coastguard Worker 
4748*5e7646d2SAndroid Build Coastguard Worker 	  start = end;
4749*5e7646d2SAndroid Build Coastguard Worker 	}
4750*5e7646d2SAndroid Build Coastguard Worker 
4751*5e7646d2SAndroid Build Coastguard Worker 	free(commands);
4752*5e7646d2SAndroid Build Coastguard Worker       }
4753*5e7646d2SAndroid Build Coastguard Worker       else
4754*5e7646d2SAndroid Build Coastguard Worker       {
4755*5e7646d2SAndroid Build Coastguard Worker        /*
4756*5e7646d2SAndroid Build Coastguard Worker 	* Add the standard list of commands...
4757*5e7646d2SAndroid Build Coastguard Worker 	*/
4758*5e7646d2SAndroid Build Coastguard Worker 
4759*5e7646d2SAndroid Build Coastguard Worker 	ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4760*5e7646d2SAndroid Build Coastguard Worker 		      "printer-commands",
4761*5e7646d2SAndroid Build Coastguard Worker 		      (int)(sizeof(standard_commands) /
4762*5e7646d2SAndroid Build Coastguard Worker 			    sizeof(standard_commands[0])), NULL,
4763*5e7646d2SAndroid Build Coastguard Worker 		      standard_commands);
4764*5e7646d2SAndroid Build Coastguard Worker       }
4765*5e7646d2SAndroid Build Coastguard Worker     }
4766*5e7646d2SAndroid Build Coastguard Worker     else
4767*5e7646d2SAndroid Build Coastguard Worker     {
4768*5e7646d2SAndroid Build Coastguard Worker      /*
4769*5e7646d2SAndroid Build Coastguard Worker       * No commands supported...
4770*5e7646d2SAndroid Build Coastguard Worker       */
4771*5e7646d2SAndroid Build Coastguard Worker 
4772*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
4773*5e7646d2SAndroid Build Coastguard Worker 		   "printer-commands", NULL, "none");
4774*5e7646d2SAndroid Build Coastguard Worker     }
4775*5e7646d2SAndroid Build Coastguard Worker 
4776*5e7646d2SAndroid Build Coastguard Worker    /*
4777*5e7646d2SAndroid Build Coastguard Worker     * Show current and available port monitors for this printer...
4778*5e7646d2SAndroid Build Coastguard Worker     */
4779*5e7646d2SAndroid Build Coastguard Worker 
4780*5e7646d2SAndroid Build Coastguard Worker     ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "port-monitor",
4781*5e7646d2SAndroid Build Coastguard Worker 		 NULL, p->port_monitor ? p->port_monitor : "none");
4782*5e7646d2SAndroid Build Coastguard Worker 
4783*5e7646d2SAndroid Build Coastguard Worker     for (i = 1, ppd_attr = ppdFindAttr(ppd, "cupsPortMonitor", NULL);
4784*5e7646d2SAndroid Build Coastguard Worker 	 ppd_attr;
4785*5e7646d2SAndroid Build Coastguard Worker 	 i ++, ppd_attr = ppdFindNextAttr(ppd, "cupsPortMonitor", NULL));
4786*5e7646d2SAndroid Build Coastguard Worker 
4787*5e7646d2SAndroid Build Coastguard Worker     if (ppd->protocols)
4788*5e7646d2SAndroid Build Coastguard Worker     {
4789*5e7646d2SAndroid Build Coastguard Worker       if (strstr(ppd->protocols, "TBCP"))
4790*5e7646d2SAndroid Build Coastguard Worker 	i ++;
4791*5e7646d2SAndroid Build Coastguard Worker       else if (strstr(ppd->protocols, "BCP"))
4792*5e7646d2SAndroid Build Coastguard Worker 	i ++;
4793*5e7646d2SAndroid Build Coastguard Worker     }
4794*5e7646d2SAndroid Build Coastguard Worker 
4795*5e7646d2SAndroid Build Coastguard Worker     attr = ippAddStrings(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
4796*5e7646d2SAndroid Build Coastguard Worker 			 "port-monitor-supported", i, NULL, NULL);
4797*5e7646d2SAndroid Build Coastguard Worker 
4798*5e7646d2SAndroid Build Coastguard Worker     attr->values[0].string.text = _cupsStrAlloc("none");
4799*5e7646d2SAndroid Build Coastguard Worker 
4800*5e7646d2SAndroid Build Coastguard Worker     for (i = 1, ppd_attr = ppdFindAttr(ppd, "cupsPortMonitor", NULL);
4801*5e7646d2SAndroid Build Coastguard Worker 	 ppd_attr;
4802*5e7646d2SAndroid Build Coastguard Worker 	 i ++, ppd_attr = ppdFindNextAttr(ppd, "cupsPortMonitor", NULL))
4803*5e7646d2SAndroid Build Coastguard Worker       attr->values[i].string.text = _cupsStrAlloc(ppd_attr->value);
4804*5e7646d2SAndroid Build Coastguard Worker 
4805*5e7646d2SAndroid Build Coastguard Worker     if (ppd->protocols)
4806*5e7646d2SAndroid Build Coastguard Worker     {
4807*5e7646d2SAndroid Build Coastguard Worker       if (strstr(ppd->protocols, "TBCP"))
4808*5e7646d2SAndroid Build Coastguard Worker 	attr->values[i].string.text = _cupsStrAlloc("tbcp");
4809*5e7646d2SAndroid Build Coastguard Worker       else if (strstr(ppd->protocols, "BCP"))
4810*5e7646d2SAndroid Build Coastguard Worker 	attr->values[i].string.text = _cupsStrAlloc("bcp");
4811*5e7646d2SAndroid Build Coastguard Worker     }
4812*5e7646d2SAndroid Build Coastguard Worker 
4813*5e7646d2SAndroid Build Coastguard Worker     if (ppdFindAttr(ppd, "APRemoteQueueID", NULL))
4814*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_REMOTE;
4815*5e7646d2SAndroid Build Coastguard Worker 
4816*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_APPLICATIONSERVICES_H
4817*5e7646d2SAndroid Build Coastguard Worker    /*
4818*5e7646d2SAndroid Build Coastguard Worker     * Convert the file referenced in APPrinterIconPath to a 128x128 PNG
4819*5e7646d2SAndroid Build Coastguard Worker     * and save it as cacheDir/printername.png
4820*5e7646d2SAndroid Build Coastguard Worker     */
4821*5e7646d2SAndroid Build Coastguard Worker 
4822*5e7646d2SAndroid Build Coastguard Worker     if ((ppd_attr = ppdFindAttr(ppd, "APPrinterIconPath", NULL)) != NULL &&
4823*5e7646d2SAndroid Build Coastguard Worker         ppd_attr->value &&
4824*5e7646d2SAndroid Build Coastguard Worker 	!_cupsFileCheck(ppd_attr->value, _CUPS_FILE_CHECK_FILE, !RunUser,
4825*5e7646d2SAndroid Build Coastguard Worker 	                cupsdLogFCMessage, p))
4826*5e7646d2SAndroid Build Coastguard Worker     {
4827*5e7646d2SAndroid Build Coastguard Worker       CGImageRef	imageRef = NULL;/* Current icon image */
4828*5e7646d2SAndroid Build Coastguard Worker       CGImageRef	biggestIconRef = NULL;
4829*5e7646d2SAndroid Build Coastguard Worker 					/* Biggest icon image */
4830*5e7646d2SAndroid Build Coastguard Worker       CGImageRef	closestTo128IconRef = NULL;
4831*5e7646d2SAndroid Build Coastguard Worker 					/* Icon image closest to and >= 128 */
4832*5e7646d2SAndroid Build Coastguard Worker       CGImageSourceRef	sourceRef;	/* The file's image source */
4833*5e7646d2SAndroid Build Coastguard Worker       char		outPath[HTTP_MAX_URI];
4834*5e7646d2SAndroid Build Coastguard Worker 					/* The path to the PNG file */
4835*5e7646d2SAndroid Build Coastguard Worker       CFURLRef		outUrl;		/* The URL made from the outPath */
4836*5e7646d2SAndroid Build Coastguard Worker       CFURLRef		icnsFileUrl;	/* The URL of the original ICNS icon file */
4837*5e7646d2SAndroid Build Coastguard Worker       CGImageDestinationRef destRef;	/* The image destination to write */
4838*5e7646d2SAndroid Build Coastguard Worker       size_t		bytesPerRow;	/* The bytes per row used for resizing */
4839*5e7646d2SAndroid Build Coastguard Worker       CGContextRef	context;	/* The CG context used for resizing */
4840*5e7646d2SAndroid Build Coastguard Worker 
4841*5e7646d2SAndroid Build Coastguard Worker       snprintf(outPath, sizeof(outPath), "%s/%s.png", CacheDir, p->name);
4842*5e7646d2SAndroid Build Coastguard Worker       outUrl      = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)outPath, (CFIndex)strlen(outPath), FALSE);
4843*5e7646d2SAndroid Build Coastguard Worker       icnsFileUrl = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)ppd_attr->value, (CFIndex)strlen(ppd_attr->value), FALSE);
4844*5e7646d2SAndroid Build Coastguard Worker       if (outUrl && icnsFileUrl)
4845*5e7646d2SAndroid Build Coastguard Worker       {
4846*5e7646d2SAndroid Build Coastguard Worker         sourceRef = CGImageSourceCreateWithURL(icnsFileUrl, NULL);
4847*5e7646d2SAndroid Build Coastguard Worker         if (sourceRef)
4848*5e7646d2SAndroid Build Coastguard Worker         {
4849*5e7646d2SAndroid Build Coastguard Worker           for (i = 0; i < (int)CGImageSourceGetCount(sourceRef); i ++)
4850*5e7646d2SAndroid Build Coastguard Worker           {
4851*5e7646d2SAndroid Build Coastguard Worker             imageRef = CGImageSourceCreateImageAtIndex(sourceRef, (size_t)i, NULL);
4852*5e7646d2SAndroid Build Coastguard Worker 	    if (!imageRef)
4853*5e7646d2SAndroid Build Coastguard Worker 	      continue;
4854*5e7646d2SAndroid Build Coastguard Worker 
4855*5e7646d2SAndroid Build Coastguard Worker             if (CGImageGetWidth(imageRef) == CGImageGetHeight(imageRef))
4856*5e7646d2SAndroid Build Coastguard Worker             {
4857*5e7646d2SAndroid Build Coastguard Worker              /*
4858*5e7646d2SAndroid Build Coastguard Worker               * Loop through remembering the icon closest to 128 but >= 128
4859*5e7646d2SAndroid Build Coastguard Worker               * and then remember the largest icon.
4860*5e7646d2SAndroid Build Coastguard Worker               */
4861*5e7646d2SAndroid Build Coastguard Worker 
4862*5e7646d2SAndroid Build Coastguard Worker               if (CGImageGetWidth(imageRef) >= 128 &&
4863*5e7646d2SAndroid Build Coastguard Worker 		  (!closestTo128IconRef ||
4864*5e7646d2SAndroid Build Coastguard Worker 		   CGImageGetWidth(imageRef) <
4865*5e7646d2SAndroid Build Coastguard Worker 		       CGImageGetWidth(closestTo128IconRef)))
4866*5e7646d2SAndroid Build Coastguard Worker               {
4867*5e7646d2SAndroid Build Coastguard Worker                 CGImageRelease(closestTo128IconRef);
4868*5e7646d2SAndroid Build Coastguard Worker                 CGImageRetain(imageRef);
4869*5e7646d2SAndroid Build Coastguard Worker                 closestTo128IconRef = imageRef;
4870*5e7646d2SAndroid Build Coastguard Worker               }
4871*5e7646d2SAndroid Build Coastguard Worker 
4872*5e7646d2SAndroid Build Coastguard Worker               if (!biggestIconRef ||
4873*5e7646d2SAndroid Build Coastguard Worker 		  CGImageGetWidth(imageRef) > CGImageGetWidth(biggestIconRef))
4874*5e7646d2SAndroid Build Coastguard Worker               {
4875*5e7646d2SAndroid Build Coastguard Worker                 CGImageRelease(biggestIconRef);
4876*5e7646d2SAndroid Build Coastguard Worker                 CGImageRetain(imageRef);
4877*5e7646d2SAndroid Build Coastguard Worker                 biggestIconRef = imageRef;
4878*5e7646d2SAndroid Build Coastguard Worker               }
4879*5e7646d2SAndroid Build Coastguard Worker 	    }
4880*5e7646d2SAndroid Build Coastguard Worker 
4881*5e7646d2SAndroid Build Coastguard Worker 	    CGImageRelease(imageRef);
4882*5e7646d2SAndroid Build Coastguard Worker           }
4883*5e7646d2SAndroid Build Coastguard Worker 
4884*5e7646d2SAndroid Build Coastguard Worker           if (biggestIconRef)
4885*5e7646d2SAndroid Build Coastguard Worker           {
4886*5e7646d2SAndroid Build Coastguard Worker            /*
4887*5e7646d2SAndroid Build Coastguard Worker             * If biggestIconRef is NULL, we found no icons. Otherwise we first
4888*5e7646d2SAndroid Build Coastguard Worker             * want the closest to 128, but if none are larger than 128, we want
4889*5e7646d2SAndroid Build Coastguard Worker             * the largest icon available.
4890*5e7646d2SAndroid Build Coastguard Worker             */
4891*5e7646d2SAndroid Build Coastguard Worker 
4892*5e7646d2SAndroid Build Coastguard Worker             imageRef = closestTo128IconRef ? closestTo128IconRef :
4893*5e7646d2SAndroid Build Coastguard Worker                                              biggestIconRef;
4894*5e7646d2SAndroid Build Coastguard Worker             CGImageRetain(imageRef);
4895*5e7646d2SAndroid Build Coastguard Worker             CGImageRelease(biggestIconRef);
4896*5e7646d2SAndroid Build Coastguard Worker             if (closestTo128IconRef)
4897*5e7646d2SAndroid Build Coastguard Worker 	      CGImageRelease(closestTo128IconRef);
4898*5e7646d2SAndroid Build Coastguard Worker             destRef = CGImageDestinationCreateWithURL(outUrl, kUTTypePNG, 1,
4899*5e7646d2SAndroid Build Coastguard Worker                                                       NULL);
4900*5e7646d2SAndroid Build Coastguard Worker             if (destRef)
4901*5e7646d2SAndroid Build Coastguard Worker             {
4902*5e7646d2SAndroid Build Coastguard Worker               if (CGImageGetWidth(imageRef) != 128)
4903*5e7646d2SAndroid Build Coastguard Worker               {
4904*5e7646d2SAndroid Build Coastguard Worker                 bytesPerRow = CGImageGetBytesPerRow(imageRef) /
4905*5e7646d2SAndroid Build Coastguard Worker                               CGImageGetWidth(imageRef) * 128;
4906*5e7646d2SAndroid Build Coastguard Worker                 context     = CGBitmapContextCreate(NULL, 128, 128,
4907*5e7646d2SAndroid Build Coastguard Worker 						    CGImageGetBitsPerComponent(imageRef),
4908*5e7646d2SAndroid Build Coastguard Worker 						    bytesPerRow,
4909*5e7646d2SAndroid Build Coastguard Worker 						    CGImageGetColorSpace(imageRef),
4910*5e7646d2SAndroid Build Coastguard Worker 						    kCGImageAlphaPremultipliedFirst);
4911*5e7646d2SAndroid Build Coastguard Worker                 if (context)
4912*5e7646d2SAndroid Build Coastguard Worker                 {
4913*5e7646d2SAndroid Build Coastguard Worker                   CGContextDrawImage(context, CGRectMake(0, 0, 128, 128),
4914*5e7646d2SAndroid Build Coastguard Worker 				     imageRef);
4915*5e7646d2SAndroid Build Coastguard Worker                   CGImageRelease(imageRef);
4916*5e7646d2SAndroid Build Coastguard Worker                   imageRef = CGBitmapContextCreateImage(context);
4917*5e7646d2SAndroid Build Coastguard Worker                   CGContextRelease(context);
4918*5e7646d2SAndroid Build Coastguard Worker                 }
4919*5e7646d2SAndroid Build Coastguard Worker               }
4920*5e7646d2SAndroid Build Coastguard Worker 
4921*5e7646d2SAndroid Build Coastguard Worker               CGImageDestinationAddImage(destRef, imageRef, NULL);
4922*5e7646d2SAndroid Build Coastguard Worker               CGImageDestinationFinalize(destRef);
4923*5e7646d2SAndroid Build Coastguard Worker               CFRelease(destRef);
4924*5e7646d2SAndroid Build Coastguard Worker             }
4925*5e7646d2SAndroid Build Coastguard Worker 
4926*5e7646d2SAndroid Build Coastguard Worker             CGImageRelease(imageRef);
4927*5e7646d2SAndroid Build Coastguard Worker           }
4928*5e7646d2SAndroid Build Coastguard Worker 
4929*5e7646d2SAndroid Build Coastguard Worker           CFRelease(sourceRef);
4930*5e7646d2SAndroid Build Coastguard Worker         }
4931*5e7646d2SAndroid Build Coastguard Worker       }
4932*5e7646d2SAndroid Build Coastguard Worker 
4933*5e7646d2SAndroid Build Coastguard Worker       if (outUrl)
4934*5e7646d2SAndroid Build Coastguard Worker         CFRelease(outUrl);
4935*5e7646d2SAndroid Build Coastguard Worker 
4936*5e7646d2SAndroid Build Coastguard Worker       if (icnsFileUrl)
4937*5e7646d2SAndroid Build Coastguard Worker         CFRelease(icnsFileUrl);
4938*5e7646d2SAndroid Build Coastguard Worker     }
4939*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_APPLICATIONSERVICES_H */
4940*5e7646d2SAndroid Build Coastguard Worker 
4941*5e7646d2SAndroid Build Coastguard Worker    /*
4942*5e7646d2SAndroid Build Coastguard Worker     * Close the PPD and set the type...
4943*5e7646d2SAndroid Build Coastguard Worker     */
4944*5e7646d2SAndroid Build Coastguard Worker 
4945*5e7646d2SAndroid Build Coastguard Worker     ppdClose(ppd);
4946*5e7646d2SAndroid Build Coastguard Worker   }
4947*5e7646d2SAndroid Build Coastguard Worker   else if (!access(ppd_name, 0))
4948*5e7646d2SAndroid Build Coastguard Worker   {
4949*5e7646d2SAndroid Build Coastguard Worker     int			pline;		/* PPD line number */
4950*5e7646d2SAndroid Build Coastguard Worker     ppd_status_t	pstatus;	/* PPD load status */
4951*5e7646d2SAndroid Build Coastguard Worker 
4952*5e7646d2SAndroid Build Coastguard Worker 
4953*5e7646d2SAndroid Build Coastguard Worker     pstatus = ppdLastError(&pline);
4954*5e7646d2SAndroid Build Coastguard Worker 
4955*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_ERROR, "PPD file for %s cannot be loaded.", p->name);
4956*5e7646d2SAndroid Build Coastguard Worker 
4957*5e7646d2SAndroid Build Coastguard Worker     if (pstatus <= PPD_ALLOC_ERROR)
4958*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "%s: %s", ppd_name, strerror(errno));
4959*5e7646d2SAndroid Build Coastguard Worker     else
4960*5e7646d2SAndroid Build Coastguard Worker       cupsdLogMessage(CUPSD_LOG_ERROR, "%s on line %d of %s.", ppdErrorString(pstatus), pline, ppd_name);
4961*5e7646d2SAndroid Build Coastguard Worker 
4962*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_INFO,
4963*5e7646d2SAndroid Build Coastguard Worker 		    "Hint: Run \"cupstestppd %s\" and fix any errors.",
4964*5e7646d2SAndroid Build Coastguard Worker 		    ppd_name);
4965*5e7646d2SAndroid Build Coastguard Worker   }
4966*5e7646d2SAndroid Build Coastguard Worker   else
4967*5e7646d2SAndroid Build Coastguard Worker   {
4968*5e7646d2SAndroid Build Coastguard Worker     if (((!strncmp(p->device_uri, "ipp://", 6) ||
4969*5e7646d2SAndroid Build Coastguard Worker 	  !strncmp(p->device_uri, "ipps://", 7)) &&
4970*5e7646d2SAndroid Build Coastguard Worker 	 (strstr(p->device_uri, "/printers/") != NULL ||
4971*5e7646d2SAndroid Build Coastguard Worker 	  strstr(p->device_uri, "/classes/") != NULL)) ||
4972*5e7646d2SAndroid Build Coastguard Worker 	((strstr(p->device_uri, "._ipp.") != NULL ||
4973*5e7646d2SAndroid Build Coastguard Worker 	  strstr(p->device_uri, "._ipps.") != NULL) &&
4974*5e7646d2SAndroid Build Coastguard Worker 	 !strcmp(p->device_uri + strlen(p->device_uri) - 5, "/cups")))
4975*5e7646d2SAndroid Build Coastguard Worker     {
4976*5e7646d2SAndroid Build Coastguard Worker      /*
4977*5e7646d2SAndroid Build Coastguard Worker       * Tell the client this is really a hard-wired remote printer.
4978*5e7646d2SAndroid Build Coastguard Worker       */
4979*5e7646d2SAndroid Build Coastguard Worker 
4980*5e7646d2SAndroid Build Coastguard Worker       p->type |= CUPS_PRINTER_REMOTE;
4981*5e7646d2SAndroid Build Coastguard Worker 
4982*5e7646d2SAndroid Build Coastguard Worker      /*
4983*5e7646d2SAndroid Build Coastguard Worker       * Then set the make-and-model accordingly...
4984*5e7646d2SAndroid Build Coastguard Worker       */
4985*5e7646d2SAndroid Build Coastguard Worker 
4986*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
4987*5e7646d2SAndroid Build Coastguard Worker 		   "printer-make-and-model", NULL, "Remote Printer");
4988*5e7646d2SAndroid Build Coastguard Worker 
4989*5e7646d2SAndroid Build Coastguard Worker      /*
4990*5e7646d2SAndroid Build Coastguard Worker       * Print all files directly...
4991*5e7646d2SAndroid Build Coastguard Worker       */
4992*5e7646d2SAndroid Build Coastguard Worker 
4993*5e7646d2SAndroid Build Coastguard Worker       p->raw    = 1;
4994*5e7646d2SAndroid Build Coastguard Worker       p->remote = 1;
4995*5e7646d2SAndroid Build Coastguard Worker     }
4996*5e7646d2SAndroid Build Coastguard Worker     else
4997*5e7646d2SAndroid Build Coastguard Worker     {
4998*5e7646d2SAndroid Build Coastguard Worker      /*
4999*5e7646d2SAndroid Build Coastguard Worker       * Otherwise we have neither - treat this as a "dumb" printer
5000*5e7646d2SAndroid Build Coastguard Worker       * with no PPD file...
5001*5e7646d2SAndroid Build Coastguard Worker       */
5002*5e7646d2SAndroid Build Coastguard Worker 
5003*5e7646d2SAndroid Build Coastguard Worker       ippAddString(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
5004*5e7646d2SAndroid Build Coastguard Worker 		   "printer-make-and-model", NULL, "Local Raw Printer");
5005*5e7646d2SAndroid Build Coastguard Worker 
5006*5e7646d2SAndroid Build Coastguard Worker       p->raw = 1;
5007*5e7646d2SAndroid Build Coastguard Worker     }
5008*5e7646d2SAndroid Build Coastguard Worker   }
5009*5e7646d2SAndroid Build Coastguard Worker 
5010*5e7646d2SAndroid Build Coastguard Worker   ippAddIntegers(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
5011*5e7646d2SAndroid Build Coastguard Worker 		 "finishings-supported", num_finishings, finishings);
5012*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(p->ppd_attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
5013*5e7646d2SAndroid Build Coastguard Worker 		"finishings-default", IPP_FINISHINGS_NONE);
5014*5e7646d2SAndroid Build Coastguard Worker 
5015*5e7646d2SAndroid Build Coastguard Worker   if (ppd && p->pc)
5016*5e7646d2SAndroid Build Coastguard Worker   {
5017*5e7646d2SAndroid Build Coastguard Worker    /*
5018*5e7646d2SAndroid Build Coastguard Worker     * Save cached PPD attributes to disk...
5019*5e7646d2SAndroid Build Coastguard Worker     */
5020*5e7646d2SAndroid Build Coastguard Worker 
5021*5e7646d2SAndroid Build Coastguard Worker     cupsdLogMessage(CUPSD_LOG_DEBUG, "load_ppd: Saving %s...", cache_name);
5022*5e7646d2SAndroid Build Coastguard Worker 
5023*5e7646d2SAndroid Build Coastguard Worker     _ppdCacheWriteFile(p->pc, cache_name, p->ppd_attrs);
5024*5e7646d2SAndroid Build Coastguard Worker   }
5025*5e7646d2SAndroid Build Coastguard Worker   else
5026*5e7646d2SAndroid Build Coastguard Worker   {
5027*5e7646d2SAndroid Build Coastguard Worker    /*
5028*5e7646d2SAndroid Build Coastguard Worker     * Remove cache files...
5029*5e7646d2SAndroid Build Coastguard Worker     */
5030*5e7646d2SAndroid Build Coastguard Worker 
5031*5e7646d2SAndroid Build Coastguard Worker     if (cache_info.st_mtime)
5032*5e7646d2SAndroid Build Coastguard Worker       unlink(cache_name);
5033*5e7646d2SAndroid Build Coastguard Worker   }
5034*5e7646d2SAndroid Build Coastguard Worker }
5035*5e7646d2SAndroid Build Coastguard Worker 
5036*5e7646d2SAndroid Build Coastguard Worker 
5037*5e7646d2SAndroid Build Coastguard Worker /*
5038*5e7646d2SAndroid Build Coastguard Worker  * 'new_media_col()' - Create a media-col collection value.
5039*5e7646d2SAndroid Build Coastguard Worker  */
5040*5e7646d2SAndroid Build Coastguard Worker 
5041*5e7646d2SAndroid Build Coastguard Worker static ipp_t *				/* O - Collection value */
new_media_col(pwg_size_t * size)5042*5e7646d2SAndroid Build Coastguard Worker new_media_col(pwg_size_t *size)		/* I - media-size/margin values */
5043*5e7646d2SAndroid Build Coastguard Worker {
5044*5e7646d2SAndroid Build Coastguard Worker   ipp_t	*media_col,			/* Collection value */
5045*5e7646d2SAndroid Build Coastguard Worker 	*media_size;			/* media-size value */
5046*5e7646d2SAndroid Build Coastguard Worker 
5047*5e7646d2SAndroid Build Coastguard Worker 
5048*5e7646d2SAndroid Build Coastguard Worker   media_col = ippNew();
5049*5e7646d2SAndroid Build Coastguard Worker 
5050*5e7646d2SAndroid Build Coastguard Worker   media_size = ippNew();
5051*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "x-dimension", size->width);
5052*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(media_size, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "y-dimension", size->length);
5053*5e7646d2SAndroid Build Coastguard Worker   ippAddCollection(media_col, IPP_TAG_PRINTER, "media-size", media_size);
5054*5e7646d2SAndroid Build Coastguard Worker   ippDelete(media_size);
5055*5e7646d2SAndroid Build Coastguard Worker 
5056*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-bottom-margin", size->bottom);
5057*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-left-margin", size->left);
5058*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-right-margin", size->right);
5059*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(media_col, IPP_TAG_PRINTER, IPP_TAG_INTEGER, "media-top-margin", size->top);
5060*5e7646d2SAndroid Build Coastguard Worker 
5061*5e7646d2SAndroid Build Coastguard Worker   return (media_col);
5062*5e7646d2SAndroid Build Coastguard Worker }
5063*5e7646d2SAndroid Build Coastguard Worker 
5064*5e7646d2SAndroid Build Coastguard Worker 
5065*5e7646d2SAndroid Build Coastguard Worker /*
5066*5e7646d2SAndroid Build Coastguard Worker  * 'write_xml_string()' - Write a string with XML escaping.
5067*5e7646d2SAndroid Build Coastguard Worker  */
5068*5e7646d2SAndroid Build Coastguard Worker 
5069*5e7646d2SAndroid Build Coastguard Worker static void
write_xml_string(cups_file_t * fp,const char * s)5070*5e7646d2SAndroid Build Coastguard Worker write_xml_string(cups_file_t *fp,	/* I - File to write to */
5071*5e7646d2SAndroid Build Coastguard Worker                  const char  *s)	/* I - String to write */
5072*5e7646d2SAndroid Build Coastguard Worker {
5073*5e7646d2SAndroid Build Coastguard Worker   const char	*start;			/* Start of current sequence */
5074*5e7646d2SAndroid Build Coastguard Worker 
5075*5e7646d2SAndroid Build Coastguard Worker 
5076*5e7646d2SAndroid Build Coastguard Worker   if (!s)
5077*5e7646d2SAndroid Build Coastguard Worker     return;
5078*5e7646d2SAndroid Build Coastguard Worker 
5079*5e7646d2SAndroid Build Coastguard Worker   for (start = s; *s; s ++)
5080*5e7646d2SAndroid Build Coastguard Worker   {
5081*5e7646d2SAndroid Build Coastguard Worker     if (*s == '&')
5082*5e7646d2SAndroid Build Coastguard Worker     {
5083*5e7646d2SAndroid Build Coastguard Worker       if (s > start)
5084*5e7646d2SAndroid Build Coastguard Worker         cupsFileWrite(fp, start, (size_t)(s - start));
5085*5e7646d2SAndroid Build Coastguard Worker 
5086*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "&amp;");
5087*5e7646d2SAndroid Build Coastguard Worker       start = s + 1;
5088*5e7646d2SAndroid Build Coastguard Worker     }
5089*5e7646d2SAndroid Build Coastguard Worker     else if (*s == '<')
5090*5e7646d2SAndroid Build Coastguard Worker     {
5091*5e7646d2SAndroid Build Coastguard Worker       if (s > start)
5092*5e7646d2SAndroid Build Coastguard Worker         cupsFileWrite(fp, start, (size_t)(s - start));
5093*5e7646d2SAndroid Build Coastguard Worker 
5094*5e7646d2SAndroid Build Coastguard Worker       cupsFilePuts(fp, "&lt;");
5095*5e7646d2SAndroid Build Coastguard Worker       start = s + 1;
5096*5e7646d2SAndroid Build Coastguard Worker     }
5097*5e7646d2SAndroid Build Coastguard Worker   }
5098*5e7646d2SAndroid Build Coastguard Worker 
5099*5e7646d2SAndroid Build Coastguard Worker   if (s > start)
5100*5e7646d2SAndroid Build Coastguard Worker     cupsFilePuts(fp, start);
5101*5e7646d2SAndroid Build Coastguard Worker }
5102