]>
Commit | Line | Data |
---|---|---|
75e1a17c MS |
1 | /* |
2 | * Simulated client test program for CUPS. | |
3 | * | |
4 | * Copyright 2017 by Apple Inc. | |
5 | * | |
6 | * These coded instructions, statements, and computer programs are the | |
7 | * property of Apple Inc. and are protected by Federal copyright | |
8 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
9 | * which should have been included with this file. If this file is | |
10 | * missing or damaged, see the license at "http://www.cups.org/". | |
11 | * | |
12 | * This file is subject to the Apple OS-Developed Software exception. | |
13 | */ | |
14 | ||
15 | /* | |
16 | * Include necessary headers... | |
17 | */ | |
18 | ||
19 | #include "cups.h" | |
20 | #include "thread-private.h" | |
21 | #include <stdlib.h> | |
22 | ||
23 | ||
24 | /* | |
25 | * Local types... | |
26 | */ | |
27 | ||
28 | typedef struct _client_monitor_s | |
29 | { | |
30 | const char *uri, /* Printer URI */ | |
31 | *hostname, /* Hostname */ | |
32 | *user, /* Username */ | |
33 | *resource; /* Resource path */ | |
34 | int port; /* Port number */ | |
35 | http_encryption_t encryption; /* Use encryption? */ | |
36 | ipp_pstate_t printer_state; /* Current printer state */ | |
37 | char printer_state_reasons[1024]; | |
38 | /* Current printer-state-reasons */ | |
39 | int job_id; /* Job ID for submitted job */ | |
40 | ipp_jstate_t job_state; /* Current job state */ | |
41 | char job_state_reasons[1024]; | |
42 | /* Current job-state-reasons */ | |
43 | } _client_monitor_t; | |
44 | ||
45 | ||
46 | /* | |
47 | * Local functions... | |
48 | */ | |
49 | ||
50 | static void *monitor_printer(_client_monitor_t *monitor); | |
51 | ||
52 | ||
53 | /* | |
54 | * 'main()' - Main entry. | |
55 | */ | |
56 | ||
57 | int /* O - Exit status */ | |
58 | main(int argc, /* I - Number of command-line arguments */ | |
59 | char *argv[]) /* I - Command-line arguments */ | |
60 | { | |
61 | return (0); | |
62 | } | |
63 | ||
64 | ||
65 | /* | |
66 | * 'monitor_printer()' - Monitor the job and printer states. | |
67 | */ | |
68 | ||
69 | static void * /* O - Thread exit code */ | |
70 | monitor_printer( | |
71 | _client_monitor_t *monitor) /* I - Monitoring data */ | |
72 | { | |
73 | http_t *http; /* Connection to printer */ | |
74 | ipp_t *request, /* IPP request */ | |
75 | *response; /* IPP response */ | |
76 | ipp_attribute_t *attr; /* Attribute in response */ | |
77 | ipp_pstate_t printer_state; /* Printer state */ | |
78 | char printer_state_reasons[1024]; | |
79 | /* Printer state reasons */ | |
80 | int job_id; /* Job ID */ | |
81 | ipp_jstate_t job_state; /* Job state */ | |
82 | char job_state_reasons[1024];/* Printer state reasons */ | |
83 | static const char * const jattrs[] = /* Job attributes we want */ | |
84 | { | |
85 | "job-state", | |
86 | "job-state-reasons" | |
87 | }; | |
88 | static const char * const pattrs[] = /* Printer attributes we want */ | |
89 | { | |
90 | "printer-state", | |
91 | "printer-state-reasons" | |
92 | }; | |
93 | ||
94 | ||
95 | /* | |
96 | * Open a connection to the printer... | |
97 | */ | |
98 | ||
99 | http = httpConnect2(monitor->hostname, monitor->port, NULL, AF_UNSPEC, | |
100 | monitor->encryption, 1, 0, NULL); | |
101 | httpSetTimeout(http, 30.0, timeout_cb, NULL); | |
102 | ||
103 | /* | |
104 | * Loop until the job is canceled, aborted, or completed. | |
105 | */ | |
106 | ||
107 | printer_state = (ipp_pstate_t)0; | |
108 | printer_state_reasons[0] = '\0'; | |
109 | ||
110 | job_state = (ipp_jstate_t)0; | |
111 | job_state_reasons[0] = '\0'; | |
112 | ||
113 | while (monitor->job_state < IPP_JOB_CANCELED) | |
114 | { | |
115 | /* | |
116 | * Reconnect to the printer as needed... | |
117 | */ | |
118 | ||
119 | if (httpGetFd(http) < 0) | |
120 | httpReconnect(http); | |
121 | ||
122 | if (httpGetFd(http) >= 0) | |
123 | { | |
124 | /* | |
125 | * Connected, so check on the printer state... | |
126 | */ | |
127 | ||
128 | request = ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES); | |
129 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, monitor->uri); | |
130 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); | |
131 | ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); | |
132 | ||
133 | response = cupsDoRequest(http, request, monitor->resource); | |
134 | ||
135 | if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) | |
136 | printer_state = (ipp_pstate_t)ippGetInteger(attr, 0); | |
137 | ||
138 | if ((attr = ippFindAttribute(response, "printer-state-reasons", IPP_TAG_KEYWORD)) != NULL) | |
139 | ippAttributeString(attr, printer_state_reasons, sizeof(printer_state_reasons)); | |
140 | ||
141 | if (printer_state != monitor->printer_state || strcmp(printer_state_reasons, monitor->printer_state_reasons)) | |
142 | { | |
143 | printf("PRINTER: %s (%s)\n", ippEnumString("printer-state", printer_state), printer_state_reasons); | |
144 | ||
145 | monitor->printer_state = printer_state; | |
146 | strlcpy(monitor->printer_state_reasons, printer_state_reasons, sizeof(monitor->printer_state_reasons)); | |
147 | } | |
148 | ||
149 | ippDelete(response); | |
150 | ||
151 | if (monitor->job_id > 0) | |
152 | { | |
153 | /* | |
154 | * Check the status of the job itself... | |
155 | */ | |
156 | ||
157 | request = ippNewRequest(IPP_OP_GET_JOB_ATTRIBUTES); | |
158 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, monitor->uri); | |
159 | ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", monitor->job_id); | |
160 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); | |
161 | ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs); | |
162 | ||
163 | response = cupsDoRequest(http, request, monitor->resource); | |
164 | ||
165 | if ((attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM)) != NULL) | |
166 | job_state = (ipp_jstate_t)ippGetInteger(attr, 0); | |
167 | ||
168 | if ((attr = ippFindAttribute(response, "job-state-reasons", IPP_TAG_KEYWORD)) != NULL) | |
169 | ippAttributeString(attr, job_state_reasons, sizeof(job_state_reasons)); | |
170 | ||
171 | if (job_state != monitor->job_state || strcmp(job_state_reasons, monitor->job_state_reasons)) | |
172 | { | |
173 | printf("JOB %d: %s (%s)\n", monitor->job_id, ippEnumString("job-state", job_state), job_state_reasons); | |
174 | ||
175 | monitor->job_state = job_state; | |
176 | strlcpy(monitor->job_state_reasons, job_state_reasons, sizeof(monitor->job_state_reasons)); | |
177 | } | |
178 | ||
179 | ippDelete(response); | |
180 | } | |
181 | } | |
182 | ||
183 | /* | |
184 | * Sleep for 5 seconds... | |
185 | */ | |
186 | ||
187 | sleep(5); | |
188 | } | |
189 | ||
190 | /* | |
191 | * Cleanup and return... | |
192 | */ | |
193 | ||
194 | httpClose(http); | |
195 | ||
196 | return (NULL); | |
197 | } |