xref: /aosp_15_r20/external/libcups/scheduler/testsub.c (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker  * Scheduler notification tester for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker  *
4*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2007-2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker  * Copyright 2006-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker  *
7*5e7646d2SAndroid Build Coastguard Worker  * Licensed under Apache License v2.0.  See the file "LICENSE" for more 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 <cups/cups.h>
15*5e7646d2SAndroid Build Coastguard Worker #include <cups/debug-private.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/string-private.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <signal.h>
18*5e7646d2SAndroid Build Coastguard Worker #include <cups/ipp-private.h>	/* TODO: Update so we don't need this */
19*5e7646d2SAndroid Build Coastguard Worker 
20*5e7646d2SAndroid Build Coastguard Worker 
21*5e7646d2SAndroid Build Coastguard Worker /*
22*5e7646d2SAndroid Build Coastguard Worker  * Local globals...
23*5e7646d2SAndroid Build Coastguard Worker  */
24*5e7646d2SAndroid Build Coastguard Worker 
25*5e7646d2SAndroid Build Coastguard Worker static int	terminate = 0;
26*5e7646d2SAndroid Build Coastguard Worker 
27*5e7646d2SAndroid Build Coastguard Worker 
28*5e7646d2SAndroid Build Coastguard Worker /*
29*5e7646d2SAndroid Build Coastguard Worker  * Local functions...
30*5e7646d2SAndroid Build Coastguard Worker  */
31*5e7646d2SAndroid Build Coastguard Worker 
32*5e7646d2SAndroid Build Coastguard Worker static void	print_attributes(ipp_t *ipp, int indent);
33*5e7646d2SAndroid Build Coastguard Worker static void	sigterm_handler(int sig);
34*5e7646d2SAndroid Build Coastguard Worker static void	usage(void) _CUPS_NORETURN;
35*5e7646d2SAndroid Build Coastguard Worker 
36*5e7646d2SAndroid Build Coastguard Worker 
37*5e7646d2SAndroid Build Coastguard Worker /*
38*5e7646d2SAndroid Build Coastguard Worker  * 'main()' - Subscribe to the .
39*5e7646d2SAndroid Build Coastguard Worker  */
40*5e7646d2SAndroid Build Coastguard Worker 
41*5e7646d2SAndroid Build Coastguard Worker int
main(int argc,char * argv[])42*5e7646d2SAndroid Build Coastguard Worker main(int  argc,				/* I - Number of command-line arguments */
43*5e7646d2SAndroid Build Coastguard Worker      char *argv[])			/* I - Command-line arguments */
44*5e7646d2SAndroid Build Coastguard Worker {
45*5e7646d2SAndroid Build Coastguard Worker   int		i;			/* Looping var */
46*5e7646d2SAndroid Build Coastguard Worker   const char	*uri;			/* URI to use */
47*5e7646d2SAndroid Build Coastguard Worker   int		num_events;		/* Number of events */
48*5e7646d2SAndroid Build Coastguard Worker   const char	*events[100];		/* Events */
49*5e7646d2SAndroid Build Coastguard Worker   int		subscription_id,	/* notify-subscription-id */
50*5e7646d2SAndroid Build Coastguard Worker 		sequence_number,	/* notify-sequence-number */
51*5e7646d2SAndroid Build Coastguard Worker 		interval;		/* Interval between polls */
52*5e7646d2SAndroid Build Coastguard Worker   http_t	*http;			/* HTTP connection */
53*5e7646d2SAndroid Build Coastguard Worker   ipp_t		*request,		/* IPP request */
54*5e7646d2SAndroid Build Coastguard Worker 		*response;		/* IPP response */
55*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t *attr;		/* Current attribute */
56*5e7646d2SAndroid Build Coastguard Worker #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
57*5e7646d2SAndroid Build Coastguard Worker   struct sigaction action;		/* Actions for POSIX signals */
58*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
59*5e7646d2SAndroid Build Coastguard Worker 
60*5e7646d2SAndroid Build Coastguard Worker 
61*5e7646d2SAndroid Build Coastguard Worker  /*
62*5e7646d2SAndroid Build Coastguard Worker   * Parse command-line...
63*5e7646d2SAndroid Build Coastguard Worker   */
64*5e7646d2SAndroid Build Coastguard Worker 
65*5e7646d2SAndroid Build Coastguard Worker   num_events = 0;
66*5e7646d2SAndroid Build Coastguard Worker   uri        = NULL;
67*5e7646d2SAndroid Build Coastguard Worker 
68*5e7646d2SAndroid Build Coastguard Worker   for (i = 1; i < argc; i ++)
69*5e7646d2SAndroid Build Coastguard Worker     if (!strcmp(argv[i], "-E"))
70*5e7646d2SAndroid Build Coastguard Worker       cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
71*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "-e"))
72*5e7646d2SAndroid Build Coastguard Worker     {
73*5e7646d2SAndroid Build Coastguard Worker       i ++;
74*5e7646d2SAndroid Build Coastguard Worker       if (i >= argc || num_events >= 100)
75*5e7646d2SAndroid Build Coastguard Worker         usage();
76*5e7646d2SAndroid Build Coastguard Worker 
77*5e7646d2SAndroid Build Coastguard Worker       events[num_events] = argv[i];
78*5e7646d2SAndroid Build Coastguard Worker       num_events ++;
79*5e7646d2SAndroid Build Coastguard Worker     }
80*5e7646d2SAndroid Build Coastguard Worker     else if (!strcmp(argv[i], "-h"))
81*5e7646d2SAndroid Build Coastguard Worker     {
82*5e7646d2SAndroid Build Coastguard Worker       i ++;
83*5e7646d2SAndroid Build Coastguard Worker       if (i >= argc)
84*5e7646d2SAndroid Build Coastguard Worker         usage();
85*5e7646d2SAndroid Build Coastguard Worker 
86*5e7646d2SAndroid Build Coastguard Worker       cupsSetServer(argv[i]);
87*5e7646d2SAndroid Build Coastguard Worker     }
88*5e7646d2SAndroid Build Coastguard Worker     else if (uri || strncmp(argv[i], "ipp://", 6))
89*5e7646d2SAndroid Build Coastguard Worker       usage();
90*5e7646d2SAndroid Build Coastguard Worker     else
91*5e7646d2SAndroid Build Coastguard Worker       uri = argv[i];
92*5e7646d2SAndroid Build Coastguard Worker 
93*5e7646d2SAndroid Build Coastguard Worker   if (!uri)
94*5e7646d2SAndroid Build Coastguard Worker     usage();
95*5e7646d2SAndroid Build Coastguard Worker 
96*5e7646d2SAndroid Build Coastguard Worker   if (num_events == 0)
97*5e7646d2SAndroid Build Coastguard Worker   {
98*5e7646d2SAndroid Build Coastguard Worker     events[0]  = "all";
99*5e7646d2SAndroid Build Coastguard Worker     num_events = 1;
100*5e7646d2SAndroid Build Coastguard Worker   }
101*5e7646d2SAndroid Build Coastguard Worker 
102*5e7646d2SAndroid Build Coastguard Worker  /*
103*5e7646d2SAndroid Build Coastguard Worker   * Connect to the server...
104*5e7646d2SAndroid Build Coastguard Worker   */
105*5e7646d2SAndroid Build Coastguard Worker 
106*5e7646d2SAndroid Build Coastguard Worker   if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
107*5e7646d2SAndroid Build Coastguard Worker                                  cupsEncryption())) == NULL)
108*5e7646d2SAndroid Build Coastguard Worker   {
109*5e7646d2SAndroid Build Coastguard Worker     perror(cupsServer());
110*5e7646d2SAndroid Build Coastguard Worker     return (1);
111*5e7646d2SAndroid Build Coastguard Worker   }
112*5e7646d2SAndroid Build Coastguard Worker 
113*5e7646d2SAndroid Build Coastguard Worker  /*
114*5e7646d2SAndroid Build Coastguard Worker   * Catch CTRL-C and SIGTERM...
115*5e7646d2SAndroid Build Coastguard Worker   */
116*5e7646d2SAndroid Build Coastguard Worker 
117*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */
118*5e7646d2SAndroid Build Coastguard Worker   sigset(SIGINT, sigterm_handler);
119*5e7646d2SAndroid Build Coastguard Worker   sigset(SIGTERM, sigterm_handler);
120*5e7646d2SAndroid Build Coastguard Worker #elif defined(HAVE_SIGACTION)
121*5e7646d2SAndroid Build Coastguard Worker   memset(&action, 0, sizeof(action));
122*5e7646d2SAndroid Build Coastguard Worker 
123*5e7646d2SAndroid Build Coastguard Worker   sigemptyset(&action.sa_mask);
124*5e7646d2SAndroid Build Coastguard Worker   action.sa_handler = sigterm_handler;
125*5e7646d2SAndroid Build Coastguard Worker   sigaction(SIGINT, &action, NULL);
126*5e7646d2SAndroid Build Coastguard Worker   sigaction(SIGTERM, &action, NULL);
127*5e7646d2SAndroid Build Coastguard Worker #else
128*5e7646d2SAndroid Build Coastguard Worker   signal(SIGINT, sigterm_handler);
129*5e7646d2SAndroid Build Coastguard Worker   signal(SIGTERM, sigterm_handler);
130*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_SIGSET */
131*5e7646d2SAndroid Build Coastguard Worker 
132*5e7646d2SAndroid Build Coastguard Worker  /*
133*5e7646d2SAndroid Build Coastguard Worker   * Create the subscription...
134*5e7646d2SAndroid Build Coastguard Worker   */
135*5e7646d2SAndroid Build Coastguard Worker 
136*5e7646d2SAndroid Build Coastguard Worker   if (strstr(uri, "/jobs/"))
137*5e7646d2SAndroid Build Coastguard Worker   {
138*5e7646d2SAndroid Build Coastguard Worker     request = ippNewRequest(IPP_CREATE_JOB_SUBSCRIPTION);
139*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
140*5e7646d2SAndroid Build Coastguard Worker   }
141*5e7646d2SAndroid Build Coastguard Worker   else
142*5e7646d2SAndroid Build Coastguard Worker   {
143*5e7646d2SAndroid Build Coastguard Worker     request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION);
144*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
145*5e7646d2SAndroid Build Coastguard Worker                  uri);
146*5e7646d2SAndroid Build Coastguard Worker   }
147*5e7646d2SAndroid Build Coastguard Worker 
148*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
149*5e7646d2SAndroid Build Coastguard Worker                NULL, cupsUser());
150*5e7646d2SAndroid Build Coastguard Worker 
151*5e7646d2SAndroid Build Coastguard Worker   ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events",
152*5e7646d2SAndroid Build Coastguard Worker                 num_events, NULL, events);
153*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD,
154*5e7646d2SAndroid Build Coastguard Worker                "notify-pull-method", NULL, "ippget");
155*5e7646d2SAndroid Build Coastguard Worker 
156*5e7646d2SAndroid Build Coastguard Worker   response = cupsDoRequest(http, request, uri);
157*5e7646d2SAndroid Build Coastguard Worker   if (cupsLastError() >= IPP_BAD_REQUEST)
158*5e7646d2SAndroid Build Coastguard Worker   {
159*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "Create-%s-Subscription: %s\n",
160*5e7646d2SAndroid Build Coastguard Worker             strstr(uri, "/jobs") ? "Job" : "Printer", cupsLastErrorString());
161*5e7646d2SAndroid Build Coastguard Worker     ippDelete(response);
162*5e7646d2SAndroid Build Coastguard Worker     httpClose(http);
163*5e7646d2SAndroid Build Coastguard Worker     return (1);
164*5e7646d2SAndroid Build Coastguard Worker   }
165*5e7646d2SAndroid Build Coastguard Worker 
166*5e7646d2SAndroid Build Coastguard Worker   if ((attr = ippFindAttribute(response, "notify-subscription-id",
167*5e7646d2SAndroid Build Coastguard Worker                                IPP_TAG_INTEGER)) == NULL)
168*5e7646d2SAndroid Build Coastguard Worker   {
169*5e7646d2SAndroid Build Coastguard Worker     fputs("ERROR: No notify-subscription-id in response!\n", stderr);
170*5e7646d2SAndroid Build Coastguard Worker     ippDelete(response);
171*5e7646d2SAndroid Build Coastguard Worker     httpClose(http);
172*5e7646d2SAndroid Build Coastguard Worker     return (1);
173*5e7646d2SAndroid Build Coastguard Worker   }
174*5e7646d2SAndroid Build Coastguard Worker 
175*5e7646d2SAndroid Build Coastguard Worker   subscription_id = attr->values[0].integer;
176*5e7646d2SAndroid Build Coastguard Worker 
177*5e7646d2SAndroid Build Coastguard Worker   printf("Create-%s-Subscription: notify-subscription-id=%d\n",
178*5e7646d2SAndroid Build Coastguard Worker          strstr(uri, "/jobs/") ? "Job" : "Printer", subscription_id);
179*5e7646d2SAndroid Build Coastguard Worker 
180*5e7646d2SAndroid Build Coastguard Worker   ippDelete(response);
181*5e7646d2SAndroid Build Coastguard Worker 
182*5e7646d2SAndroid Build Coastguard Worker  /*
183*5e7646d2SAndroid Build Coastguard Worker   * Monitor for events...
184*5e7646d2SAndroid Build Coastguard Worker   */
185*5e7646d2SAndroid Build Coastguard Worker 
186*5e7646d2SAndroid Build Coastguard Worker   sequence_number = 0;
187*5e7646d2SAndroid Build Coastguard Worker 
188*5e7646d2SAndroid Build Coastguard Worker   while (!terminate)
189*5e7646d2SAndroid Build Coastguard Worker   {
190*5e7646d2SAndroid Build Coastguard Worker    /*
191*5e7646d2SAndroid Build Coastguard Worker     * Get the current events...
192*5e7646d2SAndroid Build Coastguard Worker     */
193*5e7646d2SAndroid Build Coastguard Worker 
194*5e7646d2SAndroid Build Coastguard Worker     printf("\nGet-Notifications(%d,%d):", subscription_id, sequence_number);
195*5e7646d2SAndroid Build Coastguard Worker     fflush(stdout);
196*5e7646d2SAndroid Build Coastguard Worker 
197*5e7646d2SAndroid Build Coastguard Worker     request = ippNewRequest(IPP_GET_NOTIFICATIONS);
198*5e7646d2SAndroid Build Coastguard Worker 
199*5e7646d2SAndroid Build Coastguard Worker     if (strstr(uri, "/jobs/"))
200*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
201*5e7646d2SAndroid Build Coastguard Worker     else
202*5e7646d2SAndroid Build Coastguard Worker       ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
203*5e7646d2SAndroid Build Coastguard Worker                    uri);
204*5e7646d2SAndroid Build Coastguard Worker 
205*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
206*5e7646d2SAndroid Build Coastguard Worker                  "requesting-user-name", NULL, cupsUser());
207*5e7646d2SAndroid Build Coastguard Worker 
208*5e7646d2SAndroid Build Coastguard Worker     ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
209*5e7646d2SAndroid Build Coastguard Worker                   "notify-subscription-ids", subscription_id);
210*5e7646d2SAndroid Build Coastguard Worker     if (sequence_number)
211*5e7646d2SAndroid Build Coastguard Worker       ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
212*5e7646d2SAndroid Build Coastguard Worker                     "notify-sequence-numbers", sequence_number + 1);
213*5e7646d2SAndroid Build Coastguard Worker 
214*5e7646d2SAndroid Build Coastguard Worker     response = cupsDoRequest(http, request, uri);
215*5e7646d2SAndroid Build Coastguard Worker 
216*5e7646d2SAndroid Build Coastguard Worker     printf(" %s\n", ippErrorString(cupsLastError()));
217*5e7646d2SAndroid Build Coastguard Worker 
218*5e7646d2SAndroid Build Coastguard Worker     if (cupsLastError() >= IPP_BAD_REQUEST)
219*5e7646d2SAndroid Build Coastguard Worker       fprintf(stderr, "Get-Notifications: %s\n", cupsLastErrorString());
220*5e7646d2SAndroid Build Coastguard Worker     else if (response)
221*5e7646d2SAndroid Build Coastguard Worker     {
222*5e7646d2SAndroid Build Coastguard Worker       print_attributes(response, 0);
223*5e7646d2SAndroid Build Coastguard Worker 
224*5e7646d2SAndroid Build Coastguard Worker       for (attr = ippFindAttribute(response, "notify-sequence-number",
225*5e7646d2SAndroid Build Coastguard Worker                                    IPP_TAG_INTEGER);
226*5e7646d2SAndroid Build Coastguard Worker            attr;
227*5e7646d2SAndroid Build Coastguard Worker 	   attr = ippFindNextAttribute(response, "notify-sequence-number",
228*5e7646d2SAndroid Build Coastguard Worker 	                               IPP_TAG_INTEGER))
229*5e7646d2SAndroid Build Coastguard Worker         if (attr->values[0].integer > sequence_number)
230*5e7646d2SAndroid Build Coastguard Worker 	  sequence_number = attr->values[0].integer;
231*5e7646d2SAndroid Build Coastguard Worker     }
232*5e7646d2SAndroid Build Coastguard Worker 
233*5e7646d2SAndroid Build Coastguard Worker     if ((attr = ippFindAttribute(response, "notify-get-interval",
234*5e7646d2SAndroid Build Coastguard Worker                                  IPP_TAG_INTEGER)) != NULL &&
235*5e7646d2SAndroid Build Coastguard Worker         attr->values[0].integer > 0)
236*5e7646d2SAndroid Build Coastguard Worker       interval = attr->values[0].integer;
237*5e7646d2SAndroid Build Coastguard Worker     else
238*5e7646d2SAndroid Build Coastguard Worker       interval = 5;
239*5e7646d2SAndroid Build Coastguard Worker 
240*5e7646d2SAndroid Build Coastguard Worker     ippDelete(response);
241*5e7646d2SAndroid Build Coastguard Worker     sleep((unsigned)interval);
242*5e7646d2SAndroid Build Coastguard Worker   }
243*5e7646d2SAndroid Build Coastguard Worker 
244*5e7646d2SAndroid Build Coastguard Worker  /*
245*5e7646d2SAndroid Build Coastguard Worker   * Cancel the subscription...
246*5e7646d2SAndroid Build Coastguard Worker   */
247*5e7646d2SAndroid Build Coastguard Worker 
248*5e7646d2SAndroid Build Coastguard Worker   printf("\nCancel-Subscription:");
249*5e7646d2SAndroid Build Coastguard Worker   fflush(stdout);
250*5e7646d2SAndroid Build Coastguard Worker 
251*5e7646d2SAndroid Build Coastguard Worker   request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION);
252*5e7646d2SAndroid Build Coastguard Worker 
253*5e7646d2SAndroid Build Coastguard Worker   if (strstr(uri, "/jobs/"))
254*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
255*5e7646d2SAndroid Build Coastguard Worker   else
256*5e7646d2SAndroid Build Coastguard Worker     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
257*5e7646d2SAndroid Build Coastguard Worker                  uri);
258*5e7646d2SAndroid Build Coastguard Worker 
259*5e7646d2SAndroid Build Coastguard Worker   ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
260*5e7646d2SAndroid Build Coastguard Worker                NULL, cupsUser());
261*5e7646d2SAndroid Build Coastguard Worker 
262*5e7646d2SAndroid Build Coastguard Worker   ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
263*5e7646d2SAndroid Build Coastguard Worker                 "notify-subscription-id", subscription_id);
264*5e7646d2SAndroid Build Coastguard Worker 
265*5e7646d2SAndroid Build Coastguard Worker   ippDelete(cupsDoRequest(http, request, uri));
266*5e7646d2SAndroid Build Coastguard Worker 
267*5e7646d2SAndroid Build Coastguard Worker   printf(" %s\n", ippErrorString(cupsLastError()));
268*5e7646d2SAndroid Build Coastguard Worker 
269*5e7646d2SAndroid Build Coastguard Worker   if (cupsLastError() >= IPP_BAD_REQUEST)
270*5e7646d2SAndroid Build Coastguard Worker     fprintf(stderr, "Cancel-Subscription: %s\n", cupsLastErrorString());
271*5e7646d2SAndroid Build Coastguard Worker 
272*5e7646d2SAndroid Build Coastguard Worker  /*
273*5e7646d2SAndroid Build Coastguard Worker   * Close the connection and return...
274*5e7646d2SAndroid Build Coastguard Worker   */
275*5e7646d2SAndroid Build Coastguard Worker 
276*5e7646d2SAndroid Build Coastguard Worker   httpClose(http);
277*5e7646d2SAndroid Build Coastguard Worker 
278*5e7646d2SAndroid Build Coastguard Worker   return (0);
279*5e7646d2SAndroid Build Coastguard Worker }
280*5e7646d2SAndroid Build Coastguard Worker 
281*5e7646d2SAndroid Build Coastguard Worker 
282*5e7646d2SAndroid Build Coastguard Worker /*
283*5e7646d2SAndroid Build Coastguard Worker  * 'print_attributes()' - Print the attributes in a request...
284*5e7646d2SAndroid Build Coastguard Worker  */
285*5e7646d2SAndroid Build Coastguard Worker 
286*5e7646d2SAndroid Build Coastguard Worker static void
print_attributes(ipp_t * ipp,int indent)287*5e7646d2SAndroid Build Coastguard Worker print_attributes(ipp_t *ipp,		/* I - IPP request */
288*5e7646d2SAndroid Build Coastguard Worker                  int   indent)		/* I - Indentation */
289*5e7646d2SAndroid Build Coastguard Worker {
290*5e7646d2SAndroid Build Coastguard Worker   int			i;		/* Looping var */
291*5e7646d2SAndroid Build Coastguard Worker   ipp_tag_t		group;		/* Current group */
292*5e7646d2SAndroid Build Coastguard Worker   ipp_attribute_t	*attr;		/* Current attribute */
293*5e7646d2SAndroid Build Coastguard Worker   _ipp_value_t		*val;		/* Current value */
294*5e7646d2SAndroid Build Coastguard Worker   static const char * const tags[] =	/* Value/group tag strings */
295*5e7646d2SAndroid Build Coastguard Worker 			{
296*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-00",
297*5e7646d2SAndroid Build Coastguard Worker 			  "operation-attributes-tag",
298*5e7646d2SAndroid Build Coastguard Worker 			  "job-attributes-tag",
299*5e7646d2SAndroid Build Coastguard Worker 			  "end-of-attributes-tag",
300*5e7646d2SAndroid Build Coastguard Worker 			  "printer-attributes-tag",
301*5e7646d2SAndroid Build Coastguard Worker 			  "unsupported-attributes-tag",
302*5e7646d2SAndroid Build Coastguard Worker 			  "subscription-attributes-tag",
303*5e7646d2SAndroid Build Coastguard Worker 			  "event-attributes-tag",
304*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-08",
305*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-09",
306*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-0A",
307*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-0B",
308*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-0C",
309*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-0D",
310*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-0E",
311*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-0F",
312*5e7646d2SAndroid Build Coastguard Worker 			  "unsupported",
313*5e7646d2SAndroid Build Coastguard Worker 			  "default",
314*5e7646d2SAndroid Build Coastguard Worker 			  "unknown",
315*5e7646d2SAndroid Build Coastguard Worker 			  "no-value",
316*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-14",
317*5e7646d2SAndroid Build Coastguard Worker 			  "not-settable",
318*5e7646d2SAndroid Build Coastguard Worker 			  "delete-attr",
319*5e7646d2SAndroid Build Coastguard Worker 			  "admin-define",
320*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-18",
321*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-19",
322*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-1A",
323*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-1B",
324*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-1C",
325*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-1D",
326*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-1E",
327*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-1F",
328*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-20",
329*5e7646d2SAndroid Build Coastguard Worker 			  "integer",
330*5e7646d2SAndroid Build Coastguard Worker 			  "boolean",
331*5e7646d2SAndroid Build Coastguard Worker 			  "enum",
332*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-24",
333*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-25",
334*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-26",
335*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-27",
336*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-28",
337*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-29",
338*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-2a",
339*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-2b",
340*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-2c",
341*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-2d",
342*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-2e",
343*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-2f",
344*5e7646d2SAndroid Build Coastguard Worker 			  "octetString",
345*5e7646d2SAndroid Build Coastguard Worker 			  "dateTime",
346*5e7646d2SAndroid Build Coastguard Worker 			  "resolution",
347*5e7646d2SAndroid Build Coastguard Worker 			  "rangeOfInteger",
348*5e7646d2SAndroid Build Coastguard Worker 			  "begCollection",
349*5e7646d2SAndroid Build Coastguard Worker 			  "textWithLanguage",
350*5e7646d2SAndroid Build Coastguard Worker 			  "nameWithLanguage",
351*5e7646d2SAndroid Build Coastguard Worker 			  "endCollection",
352*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-38",
353*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-39",
354*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-3a",
355*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-3b",
356*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-3c",
357*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-3d",
358*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-3e",
359*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-3f",
360*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-40",
361*5e7646d2SAndroid Build Coastguard Worker 			  "textWithoutLanguage",
362*5e7646d2SAndroid Build Coastguard Worker 			  "nameWithoutLanguage",
363*5e7646d2SAndroid Build Coastguard Worker 			  "reserved-43",
364*5e7646d2SAndroid Build Coastguard Worker 			  "keyword",
365*5e7646d2SAndroid Build Coastguard Worker 			  "uri",
366*5e7646d2SAndroid Build Coastguard Worker 			  "uriScheme",
367*5e7646d2SAndroid Build Coastguard Worker 			  "charset",
368*5e7646d2SAndroid Build Coastguard Worker 			  "naturalLanguage",
369*5e7646d2SAndroid Build Coastguard Worker 			  "mimeMediaType",
370*5e7646d2SAndroid Build Coastguard Worker 			  "memberName"
371*5e7646d2SAndroid Build Coastguard Worker 			};
372*5e7646d2SAndroid Build Coastguard Worker 
373*5e7646d2SAndroid Build Coastguard Worker 
374*5e7646d2SAndroid Build Coastguard Worker   for (group = IPP_TAG_ZERO, attr = ipp->attrs; attr; attr = attr->next)
375*5e7646d2SAndroid Build Coastguard Worker   {
376*5e7646d2SAndroid Build Coastguard Worker     if ((attr->group_tag == IPP_TAG_ZERO && indent <= 8) || !attr->name)
377*5e7646d2SAndroid Build Coastguard Worker     {
378*5e7646d2SAndroid Build Coastguard Worker       group = IPP_TAG_ZERO;
379*5e7646d2SAndroid Build Coastguard Worker       putchar('\n');
380*5e7646d2SAndroid Build Coastguard Worker       continue;
381*5e7646d2SAndroid Build Coastguard Worker     }
382*5e7646d2SAndroid Build Coastguard Worker 
383*5e7646d2SAndroid Build Coastguard Worker     if (group != attr->group_tag)
384*5e7646d2SAndroid Build Coastguard Worker     {
385*5e7646d2SAndroid Build Coastguard Worker       group = attr->group_tag;
386*5e7646d2SAndroid Build Coastguard Worker 
387*5e7646d2SAndroid Build Coastguard Worker       putchar('\n');
388*5e7646d2SAndroid Build Coastguard Worker       for (i = 4; i < indent; i ++)
389*5e7646d2SAndroid Build Coastguard Worker         putchar(' ');
390*5e7646d2SAndroid Build Coastguard Worker 
391*5e7646d2SAndroid Build Coastguard Worker       printf("%s:\n\n", tags[group]);
392*5e7646d2SAndroid Build Coastguard Worker     }
393*5e7646d2SAndroid Build Coastguard Worker 
394*5e7646d2SAndroid Build Coastguard Worker     for (i = 0; i < indent; i ++)
395*5e7646d2SAndroid Build Coastguard Worker       putchar(' ');
396*5e7646d2SAndroid Build Coastguard Worker 
397*5e7646d2SAndroid Build Coastguard Worker     printf("%s (", attr->name);
398*5e7646d2SAndroid Build Coastguard Worker     if (attr->num_values > 1)
399*5e7646d2SAndroid Build Coastguard Worker       printf("1setOf ");
400*5e7646d2SAndroid Build Coastguard Worker     printf("%s):", tags[attr->value_tag]);
401*5e7646d2SAndroid Build Coastguard Worker 
402*5e7646d2SAndroid Build Coastguard Worker     switch (attr->value_tag)
403*5e7646d2SAndroid Build Coastguard Worker     {
404*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_ENUM :
405*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_INTEGER :
406*5e7646d2SAndroid Build Coastguard Worker           for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
407*5e7646d2SAndroid Build Coastguard Worker 	    printf(" %d", val->integer);
408*5e7646d2SAndroid Build Coastguard Worker           putchar('\n');
409*5e7646d2SAndroid Build Coastguard Worker           break;
410*5e7646d2SAndroid Build Coastguard Worker 
411*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_BOOLEAN :
412*5e7646d2SAndroid Build Coastguard Worker           for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
413*5e7646d2SAndroid Build Coastguard Worker 	    printf(" %s", val->boolean ? "true" : "false");
414*5e7646d2SAndroid Build Coastguard Worker           putchar('\n');
415*5e7646d2SAndroid Build Coastguard Worker           break;
416*5e7646d2SAndroid Build Coastguard Worker 
417*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_RANGE :
418*5e7646d2SAndroid Build Coastguard Worker           for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
419*5e7646d2SAndroid Build Coastguard Worker 	    printf(" %d-%d", val->range.lower, val->range.upper);
420*5e7646d2SAndroid Build Coastguard Worker           putchar('\n');
421*5e7646d2SAndroid Build Coastguard Worker           break;
422*5e7646d2SAndroid Build Coastguard Worker 
423*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_DATE :
424*5e7646d2SAndroid Build Coastguard Worker           {
425*5e7646d2SAndroid Build Coastguard Worker 	    char	vstring[256];	/* Formatted time */
426*5e7646d2SAndroid Build Coastguard Worker 
427*5e7646d2SAndroid Build Coastguard Worker 	    for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
428*5e7646d2SAndroid Build Coastguard Worker 	      printf(" (%s)", _cupsStrDate(vstring, sizeof(vstring), ippDateToTime(val->date)));
429*5e7646d2SAndroid Build Coastguard Worker           }
430*5e7646d2SAndroid Build Coastguard Worker           putchar('\n');
431*5e7646d2SAndroid Build Coastguard Worker           break;
432*5e7646d2SAndroid Build Coastguard Worker 
433*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_RESOLUTION :
434*5e7646d2SAndroid Build Coastguard Worker           for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
435*5e7646d2SAndroid Build Coastguard Worker 	    printf(" %dx%d%s", val->resolution.xres, val->resolution.yres,
436*5e7646d2SAndroid Build Coastguard Worker 	           val->resolution.units == IPP_RES_PER_INCH ? "dpi" : "dpcm");
437*5e7646d2SAndroid Build Coastguard Worker           putchar('\n');
438*5e7646d2SAndroid Build Coastguard Worker           break;
439*5e7646d2SAndroid Build Coastguard Worker 
440*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_STRING :
441*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_TEXTLANG :
442*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_NAMELANG :
443*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_TEXT :
444*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_NAME :
445*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_KEYWORD :
446*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_URI :
447*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_URISCHEME :
448*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_CHARSET :
449*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_LANGUAGE :
450*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_MIMETYPE :
451*5e7646d2SAndroid Build Coastguard Worker           for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
452*5e7646d2SAndroid Build Coastguard Worker 	    printf(" \"%s\"", val->string.text);
453*5e7646d2SAndroid Build Coastguard Worker           putchar('\n');
454*5e7646d2SAndroid Build Coastguard Worker           break;
455*5e7646d2SAndroid Build Coastguard Worker 
456*5e7646d2SAndroid Build Coastguard Worker       case IPP_TAG_BEGIN_COLLECTION :
457*5e7646d2SAndroid Build Coastguard Worker           putchar('\n');
458*5e7646d2SAndroid Build Coastguard Worker 
459*5e7646d2SAndroid Build Coastguard Worker           for (i = 0, val = attr->values; i < attr->num_values; i ++, val ++)
460*5e7646d2SAndroid Build Coastguard Worker 	  {
461*5e7646d2SAndroid Build Coastguard Worker 	    if (i)
462*5e7646d2SAndroid Build Coastguard Worker 	      putchar('\n');
463*5e7646d2SAndroid Build Coastguard Worker 	    print_attributes(val->collection, indent + 4);
464*5e7646d2SAndroid Build Coastguard Worker 	  }
465*5e7646d2SAndroid Build Coastguard Worker           break;
466*5e7646d2SAndroid Build Coastguard Worker 
467*5e7646d2SAndroid Build Coastguard Worker       default :
468*5e7646d2SAndroid Build Coastguard Worker           printf("UNKNOWN (%d values)\n", attr->num_values);
469*5e7646d2SAndroid Build Coastguard Worker           break;
470*5e7646d2SAndroid Build Coastguard Worker     }
471*5e7646d2SAndroid Build Coastguard Worker   }
472*5e7646d2SAndroid Build Coastguard Worker }
473*5e7646d2SAndroid Build Coastguard Worker 
474*5e7646d2SAndroid Build Coastguard Worker 
475*5e7646d2SAndroid Build Coastguard Worker /*
476*5e7646d2SAndroid Build Coastguard Worker  * 'sigterm_handler()' - Flag when the user hits CTRL-C...
477*5e7646d2SAndroid Build Coastguard Worker  */
478*5e7646d2SAndroid Build Coastguard Worker 
479*5e7646d2SAndroid Build Coastguard Worker static void
sigterm_handler(int sig)480*5e7646d2SAndroid Build Coastguard Worker sigterm_handler(int sig)		/* I - Signal number (unused) */
481*5e7646d2SAndroid Build Coastguard Worker {
482*5e7646d2SAndroid Build Coastguard Worker   (void)sig;
483*5e7646d2SAndroid Build Coastguard Worker 
484*5e7646d2SAndroid Build Coastguard Worker   terminate = 1;
485*5e7646d2SAndroid Build Coastguard Worker }
486*5e7646d2SAndroid Build Coastguard Worker 
487*5e7646d2SAndroid Build Coastguard Worker 
488*5e7646d2SAndroid Build Coastguard Worker /*
489*5e7646d2SAndroid Build Coastguard Worker  * 'usage()' - Show program usage...
490*5e7646d2SAndroid Build Coastguard Worker  */
491*5e7646d2SAndroid Build Coastguard Worker 
492*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)493*5e7646d2SAndroid Build Coastguard Worker usage(void)
494*5e7646d2SAndroid Build Coastguard Worker {
495*5e7646d2SAndroid Build Coastguard Worker   puts("Usage: testsub [-E] [-e event ... -e eventN] [-h hostname] URI");
496*5e7646d2SAndroid Build Coastguard Worker   exit(0);
497*5e7646d2SAndroid Build Coastguard Worker }
498