xref: /aosp_15_r20/external/libcups/cups/testthreads.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Threaded test program for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright © 2012-2019 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  *
6*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more
7*5e7646d2SAndroid Build Coastguard Worker  * information.
8*5e7646d2SAndroid Build Coastguard Worker  */
9*5e7646d2SAndroid Build Coastguard Worker 
10*5e7646d2SAndroid Build Coastguard Worker /*
11*5e7646d2SAndroid Build Coastguard Worker  * Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker  */
13*5e7646d2SAndroid Build Coastguard Worker 
14*5e7646d2SAndroid Build Coastguard Worker #include <stdio.h>
15*5e7646d2SAndroid Build Coastguard Worker #include <errno.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/cups.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <cups/thread-private.h>
18*5e7646d2SAndroid Build Coastguard Worker 
19*5e7646d2SAndroid Build Coastguard Worker 
20*5e7646d2SAndroid Build Coastguard Worker /*
21*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
22*5e7646d2SAndroid Build Coastguard Worker  */
23*5e7646d2SAndroid Build Coastguard Worker 
24*5e7646d2SAndroid Build Coastguard Worker static int	enum_dests_cb(void *_name, unsigned flags, cups_dest_t *dest);
25*5e7646d2SAndroid Build Coastguard Worker static void	*run_query(cups_dest_t *dest);
26*5e7646d2SAndroid Build Coastguard Worker static void	show_supported(http_t *http, cups_dest_t *dest, cups_dinfo_t *dinfo, const char *option, const char *value);
27*5e7646d2SAndroid Build Coastguard Worker 
28*5e7646d2SAndroid Build Coastguard Worker 
29*5e7646d2SAndroid Build Coastguard Worker /*
30*5e7646d2SAndroid Build Coastguard Worker  * 'main()' - Main entry.
31*5e7646d2SAndroid Build Coastguard Worker  */
32*5e7646d2SAndroid Build Coastguard Worker 
33*5e7646d2SAndroid Build Coastguard Worker int					/* O - Exit status */
main(int argc,char * argv[])34*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				/* I - Number of command-line arguments */
35*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			/* I - Command-line arguments */
36*5e7646d2SAndroid Build Coastguard Worker {
37*5e7646d2SAndroid Build Coastguard Worker  /*
38*5e7646d2SAndroid Build Coastguard Worker   * Go through all the available destinations to find the requested one...
39*5e7646d2SAndroid Build Coastguard Worker   */
40*5e7646d2SAndroid Build Coastguard Worker 
41*5e7646d2SAndroid Build Coastguard Worker   (void)argc;
42*5e7646d2SAndroid Build Coastguard Worker 
43*5e7646d2SAndroid Build Coastguard Worker   cupsEnumDests(CUPS_DEST_FLAGS_NONE, -1, NULL, 0, 0, enum_dests_cb, argv[1]);
44*5e7646d2SAndroid Build Coastguard Worker 
45*5e7646d2SAndroid Build Coastguard Worker   return (0);
46*5e7646d2SAndroid Build Coastguard Worker }
47*5e7646d2SAndroid Build Coastguard Worker 
48*5e7646d2SAndroid Build Coastguard Worker 
49*5e7646d2SAndroid Build Coastguard Worker /*
50*5e7646d2SAndroid Build Coastguard Worker  * 'enum_dests_cb()' - Destination enumeration function...
51*5e7646d2SAndroid Build Coastguard Worker  */
52*5e7646d2SAndroid Build Coastguard Worker 
53*5e7646d2SAndroid Build Coastguard Worker static int				/* O - 1 to continue, 0 to stop */
enum_dests_cb(void * _name,unsigned flags,cups_dest_t * dest)54*5e7646d2SAndroid Build Coastguard Worker enum_dests_cb(void        *_name,	/* I - Printer name, if any */
55*5e7646d2SAndroid Build Coastguard Worker               unsigned    flags,	/* I - Enumeration flags */
56*5e7646d2SAndroid Build Coastguard Worker               cups_dest_t *dest)	/* I - Found destination */
57*5e7646d2SAndroid Build Coastguard Worker {
58*5e7646d2SAndroid Build Coastguard Worker   const char		*name = (const char *)_name;
59*5e7646d2SAndroid Build Coastguard Worker 					/* Printer name */
60*5e7646d2SAndroid Build Coastguard Worker   cups_dest_t		*cdest;		/* Copied destination */
61*5e7646d2SAndroid Build Coastguard Worker 
62*5e7646d2SAndroid Build Coastguard Worker 
63*5e7646d2SAndroid Build Coastguard Worker   (void)flags;
64*5e7646d2SAndroid Build Coastguard Worker 
65*5e7646d2SAndroid Build Coastguard Worker  /*
66*5e7646d2SAndroid Build Coastguard Worker   * If a name was specified, compare it...
67*5e7646d2SAndroid Build Coastguard Worker   */
68*5e7646d2SAndroid Build Coastguard Worker 
69*5e7646d2SAndroid Build Coastguard Worker   if (name && strcasecmp(name, dest->name))
70*5e7646d2SAndroid Build Coastguard Worker     return (1);				/* Continue */
71*5e7646d2SAndroid Build Coastguard Worker 
72*5e7646d2SAndroid Build Coastguard Worker  /*
73*5e7646d2SAndroid Build Coastguard Worker   * Copy the destination and run the query on a separate thread...
74*5e7646d2SAndroid Build Coastguard Worker   */
75*5e7646d2SAndroid Build Coastguard Worker 
76*5e7646d2SAndroid Build Coastguard Worker   cupsCopyDest(dest, 0, &cdest);
77*5e7646d2SAndroid Build Coastguard Worker   _cupsThreadWait(_cupsThreadCreate((_cups_thread_func_t)run_query, cdest));
78*5e7646d2SAndroid Build Coastguard Worker 
79*5e7646d2SAndroid Build Coastguard Worker   cupsFreeDests(1, cdest);
80*5e7646d2SAndroid Build Coastguard Worker 
81*5e7646d2SAndroid Build Coastguard Worker  /*
82*5e7646d2SAndroid Build Coastguard Worker   * Continue if no name was specified or the name matches...
83*5e7646d2SAndroid Build Coastguard Worker   */
84*5e7646d2SAndroid Build Coastguard Worker 
85*5e7646d2SAndroid Build Coastguard Worker   return (!name || !strcasecmp(name, dest->name));
86*5e7646d2SAndroid Build Coastguard Worker }
87*5e7646d2SAndroid Build Coastguard Worker 
88*5e7646d2SAndroid Build Coastguard Worker 
89*5e7646d2SAndroid Build Coastguard Worker /*
90*5e7646d2SAndroid Build Coastguard Worker  * 'run_query()' - Query printer capabilities on a separate thread.
91*5e7646d2SAndroid Build Coastguard Worker  */
92*5e7646d2SAndroid Build Coastguard Worker 
93*5e7646d2SAndroid Build Coastguard Worker static void *				/* O - Return value (not used) */
run_query(cups_dest_t * dest)94*5e7646d2SAndroid Build Coastguard Worker run_query(cups_dest_t *dest)		/* I - Destination to query */
95*5e7646d2SAndroid Build Coastguard Worker {
96*5e7646d2SAndroid Build Coastguard Worker   http_t	*http;			/* Connection to destination */
97*5e7646d2SAndroid Build Coastguard Worker   cups_dinfo_t	*dinfo;			/* Destination info */
98*5e7646d2SAndroid Build Coastguard Worker   unsigned	dflags = CUPS_DEST_FLAGS_NONE;
99*5e7646d2SAndroid Build Coastguard Worker 					/* Destination flags */
100*5e7646d2SAndroid Build Coastguard Worker 
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker   if ((http = cupsConnectDest(dest, dflags, 300, NULL, NULL, 0, NULL, NULL)) == NULL)
103*5e7646d2SAndroid Build Coastguard Worker   {
104*5e7646d2SAndroid Build Coastguard Worker     printf("testthreads: Unable to connect to destination \"%s\": %s\n", dest->name, cupsLastErrorString());
105*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
106*5e7646d2SAndroid Build Coastguard Worker   }
107*5e7646d2SAndroid Build Coastguard Worker 
108*5e7646d2SAndroid Build Coastguard Worker   if ((dinfo = cupsCopyDestInfo(http, dest)) == NULL)
109*5e7646d2SAndroid Build Coastguard Worker   {
110*5e7646d2SAndroid Build Coastguard Worker     printf("testdest: Unable to get information for destination \"%s\": %s\n", dest->name, cupsLastErrorString());
111*5e7646d2SAndroid Build Coastguard Worker     return (NULL);
112*5e7646d2SAndroid Build Coastguard Worker   }
113*5e7646d2SAndroid Build Coastguard Worker 
114*5e7646d2SAndroid Build Coastguard Worker   printf("\n%s:\n", dest->name);
115*5e7646d2SAndroid Build Coastguard Worker 
116*5e7646d2SAndroid Build Coastguard Worker   show_supported(http, dest, dinfo, NULL, NULL);
117*5e7646d2SAndroid Build Coastguard Worker 
118*5e7646d2SAndroid Build Coastguard Worker   return (NULL);
119*5e7646d2SAndroid Build Coastguard Worker }
120*5e7646d2SAndroid Build Coastguard Worker 
121*5e7646d2SAndroid Build Coastguard Worker 
122*5e7646d2SAndroid Build Coastguard Worker 
123*5e7646d2SAndroid Build Coastguard Worker /*
124*5e7646d2SAndroid Build Coastguard Worker  * 'show_supported()' - Show supported options, values, etc.
125*5e7646d2SAndroid Build Coastguard Worker  */
126*5e7646d2SAndroid Build Coastguard Worker 
127*5e7646d2SAndroid Build Coastguard Worker static void
show_supported(http_t * http,cups_dest_t * dest,cups_dinfo_t * dinfo,const char * option,const char * value)128*5e7646d2SAndroid Build Coastguard Worker show_supported(http_t       *http,	/* I - Connection to destination */
129*5e7646d2SAndroid Build Coastguard Worker 	       cups_dest_t  *dest,	/* I - Destination */
130*5e7646d2SAndroid Build Coastguard Worker 	       cups_dinfo_t *dinfo,	/* I - Destination information */
131*5e7646d2SAndroid Build Coastguard Worker 	       const char   *option,	/* I - Option, if any */
132*5e7646d2SAndroid Build Coastguard Worker 	       const char   *value)	/* I - Value, if any */
133*5e7646d2SAndroid Build Coastguard Worker {
134*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*attr;		/* Attribute */
135*5e7646d2SAndroid Build Coastguard Worker   int			i,		/* Looping var */
136*5e7646d2SAndroid Build Coastguard Worker 			count;		/* Number of values */
137*5e7646d2SAndroid Build Coastguard Worker 
138*5e7646d2SAndroid Build Coastguard Worker 
139*5e7646d2SAndroid Build Coastguard Worker   if (!option)
140*5e7646d2SAndroid Build Coastguard Worker   {
141*5e7646d2SAndroid Build Coastguard Worker     attr = cupsFindDestSupported(http, dest, dinfo, "job-creation-attributes");
142*5e7646d2SAndroid Build Coastguard Worker     if (attr)
143*5e7646d2SAndroid Build Coastguard Worker     {
144*5e7646d2SAndroid Build Coastguard Worker       count = ippGetCount(attr);
145*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < count; i ++)
146*5e7646d2SAndroid Build Coastguard Worker         show_supported(http, dest, dinfo, ippGetString(attr, i, NULL), NULL);
147*5e7646d2SAndroid Build Coastguard Worker     }
148*5e7646d2SAndroid Build Coastguard Worker     else
149*5e7646d2SAndroid Build Coastguard Worker     {
150*5e7646d2SAndroid Build Coastguard Worker       static const char * const options[] =
151*5e7646d2SAndroid Build Coastguard Worker       {					/* List of standard options */
152*5e7646d2SAndroid Build Coastguard Worker         CUPS_COPIES,
153*5e7646d2SAndroid Build Coastguard Worker 	CUPS_FINISHINGS,
154*5e7646d2SAndroid Build Coastguard Worker 	CUPS_MEDIA,
155*5e7646d2SAndroid Build Coastguard Worker 	CUPS_NUMBER_UP,
156*5e7646d2SAndroid Build Coastguard Worker 	CUPS_ORIENTATION,
157*5e7646d2SAndroid Build Coastguard Worker 	CUPS_PRINT_COLOR_MODE,
158*5e7646d2SAndroid Build Coastguard Worker 	CUPS_PRINT_QUALITY,
159*5e7646d2SAndroid Build Coastguard Worker 	CUPS_SIDES
160*5e7646d2SAndroid Build Coastguard Worker       };
161*5e7646d2SAndroid Build Coastguard Worker 
162*5e7646d2SAndroid Build Coastguard Worker       puts("    No job-creation-attributes-supported attribute, probing instead.");
163*5e7646d2SAndroid Build Coastguard Worker 
164*5e7646d2SAndroid Build Coastguard Worker       for (i = 0; i < (int)(sizeof(options) / sizeof(options[0])); i ++)
165*5e7646d2SAndroid Build Coastguard Worker         if (cupsCheckDestSupported(http, dest, dinfo, options[i], NULL))
166*5e7646d2SAndroid Build Coastguard Worker 	  show_supported(http, dest, dinfo, options[i], NULL);
167*5e7646d2SAndroid Build Coastguard Worker     }
168*5e7646d2SAndroid Build Coastguard Worker   }
169*5e7646d2SAndroid Build Coastguard Worker   else if (!value)
170*5e7646d2SAndroid Build Coastguard Worker   {
171*5e7646d2SAndroid Build Coastguard Worker     printf("    %s (%s - %s)\n", option, cupsLocalizeDestOption(http, dest, dinfo, option), cupsCheckDestSupported(http, dest, dinfo, option, NULL) ? "supported" : "not-supported");
172*5e7646d2SAndroid Build Coastguard Worker 
173*5e7646d2SAndroid Build Coastguard Worker     if ((attr = cupsFindDestSupported(http, dest, dinfo, option)) != NULL)
174*5e7646d2SAndroid Build Coastguard Worker     {
175*5e7646d2SAndroid Build Coastguard Worker       count = ippGetCount(attr);
176*5e7646d2SAndroid Build Coastguard Worker 
177*5e7646d2SAndroid Build Coastguard Worker       switch (ippGetValueTag(attr))
178*5e7646d2SAndroid Build Coastguard Worker       {
179*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_INTEGER :
180*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0; i < count; i ++)
181*5e7646d2SAndroid Build Coastguard Worker               printf("        %d\n", ippGetInteger(attr, i));
182*5e7646d2SAndroid Build Coastguard Worker 	    break;
183*5e7646d2SAndroid Build Coastguard Worker 
184*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_ENUM :
185*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0; i < count; i ++)
186*5e7646d2SAndroid Build Coastguard Worker 	    {
187*5e7646d2SAndroid Build Coastguard Worker 	      int val = ippGetInteger(attr, i);
188*5e7646d2SAndroid Build Coastguard Worker 	      char valstr[256];
189*5e7646d2SAndroid Build Coastguard Worker 
190*5e7646d2SAndroid Build Coastguard Worker               snprintf(valstr, sizeof(valstr), "%d", val);
191*5e7646d2SAndroid Build Coastguard Worker               printf("        %s (%s)\n", ippEnumString(option, ippGetInteger(attr, i)), cupsLocalizeDestValue(http, dest, dinfo, option, valstr));
192*5e7646d2SAndroid Build Coastguard Worker             }
193*5e7646d2SAndroid Build Coastguard Worker 	    break;
194*5e7646d2SAndroid Build Coastguard Worker 
195*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_RANGE :
196*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0; i < count; i ++)
197*5e7646d2SAndroid Build Coastguard Worker 	    {
198*5e7646d2SAndroid Build Coastguard Worker 	      int upper, lower = ippGetRange(attr, i, &upper);
199*5e7646d2SAndroid Build Coastguard Worker 
200*5e7646d2SAndroid Build Coastguard Worker               printf("        %d-%d\n", lower, upper);
201*5e7646d2SAndroid Build Coastguard Worker 	    }
202*5e7646d2SAndroid Build Coastguard Worker 	    break;
203*5e7646d2SAndroid Build Coastguard Worker 
204*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_RESOLUTION :
205*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0; i < count; i ++)
206*5e7646d2SAndroid Build Coastguard Worker 	    {
207*5e7646d2SAndroid Build Coastguard Worker 	      int xres, yres;
208*5e7646d2SAndroid Build Coastguard Worker 	      ipp_res_t units;
209*5e7646d2SAndroid Build Coastguard Worker 	      xres = ippGetResolution(attr, i, &yres, &units);
210*5e7646d2SAndroid Build Coastguard Worker 
211*5e7646d2SAndroid Build Coastguard Worker               if (xres == yres)
212*5e7646d2SAndroid Build Coastguard Worker                 printf("        %d%s\n", xres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
213*5e7646d2SAndroid Build Coastguard Worker 	      else
214*5e7646d2SAndroid Build Coastguard Worker                 printf("        %dx%d%s\n", xres, yres, units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
215*5e7646d2SAndroid Build Coastguard Worker 	    }
216*5e7646d2SAndroid Build Coastguard Worker 	    break;
217*5e7646d2SAndroid Build Coastguard Worker 
218*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_KEYWORD :
219*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0; i < count; i ++)
220*5e7646d2SAndroid Build Coastguard Worker               printf("        %s (%s)\n", ippGetString(attr, i, NULL), cupsLocalizeDestValue(http, dest, dinfo, option, ippGetString(attr, i, NULL)));
221*5e7646d2SAndroid Build Coastguard Worker 	    break;
222*5e7646d2SAndroid Build Coastguard Worker 
223*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_TEXTLANG :
224*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_NAMELANG :
225*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_TEXT :
226*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_NAME :
227*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_URI :
228*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_URISCHEME :
229*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_CHARSET :
230*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_LANGUAGE :
231*5e7646d2SAndroid Build Coastguard Worker 	case IPP_TAG_MIMETYPE :
232*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0; i < count; i ++)
233*5e7646d2SAndroid Build Coastguard Worker               printf("        %s\n", ippGetString(attr, i, NULL));
234*5e7646d2SAndroid Build Coastguard Worker 	    break;
235*5e7646d2SAndroid Build Coastguard Worker 
236*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_STRING :
237*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0; i < count; i ++)
238*5e7646d2SAndroid Build Coastguard Worker 	    {
239*5e7646d2SAndroid Build Coastguard Worker 	      int j, len;
240*5e7646d2SAndroid Build Coastguard Worker 	      unsigned char *data = ippGetOctetString(attr, i, &len);
241*5e7646d2SAndroid Build Coastguard Worker 
242*5e7646d2SAndroid Build Coastguard Worker               fputs("        ", stdout);
243*5e7646d2SAndroid Build Coastguard Worker 	      for (j = 0; j < len; j ++)
244*5e7646d2SAndroid Build Coastguard Worker 	      {
245*5e7646d2SAndroid Build Coastguard Worker 	        if (data[j] < ' ' || data[j] >= 0x7f)
246*5e7646d2SAndroid Build Coastguard Worker 		  printf("<%02X>", data[j]);
247*5e7646d2SAndroid Build Coastguard Worker 		else
248*5e7646d2SAndroid Build Coastguard Worker 		  putchar(data[j]);
249*5e7646d2SAndroid Build Coastguard Worker               }
250*5e7646d2SAndroid Build Coastguard Worker               putchar('\n');
251*5e7646d2SAndroid Build Coastguard Worker 	    }
252*5e7646d2SAndroid Build Coastguard Worker 	    break;
253*5e7646d2SAndroid Build Coastguard Worker 
254*5e7646d2SAndroid Build Coastguard Worker         case IPP_TAG_BOOLEAN :
255*5e7646d2SAndroid Build Coastguard Worker 	    break;
256*5e7646d2SAndroid Build Coastguard Worker 
257*5e7646d2SAndroid Build Coastguard Worker         default :
258*5e7646d2SAndroid Build Coastguard Worker 	    printf("        %s\n", ippTagString(ippGetValueTag(attr)));
259*5e7646d2SAndroid Build Coastguard Worker 	    break;
260*5e7646d2SAndroid Build Coastguard Worker       }
261*5e7646d2SAndroid Build Coastguard Worker     }
262*5e7646d2SAndroid Build Coastguard Worker 
263*5e7646d2SAndroid Build Coastguard Worker   }
264*5e7646d2SAndroid Build Coastguard Worker   else if (cupsCheckDestSupported(http, dest, dinfo, option, value))
265*5e7646d2SAndroid Build Coastguard Worker     puts("YES");
266*5e7646d2SAndroid Build Coastguard Worker   else
267*5e7646d2SAndroid Build Coastguard Worker     puts("NO");
268*5e7646d2SAndroid Build Coastguard Worker }
269