]> git.ipfire.org Git - thirdparty/cups.git/blame - scheduler/cups-polld.c
Merge changes from 1.1.x into 1.2 devel.
[thirdparty/cups.git] / scheduler / cups-polld.c
CommitLineData
e173a49f 1/*
753453e4 2 * "$Id: cups-polld.c,v 1.5.2.2 2001/12/26 16:52:52 mike Exp $"
e173a49f 3 *
93419f78 4 * Polling daemon for the Common UNIX Printing System (CUPS).
e173a49f 5 *
d2935a0f 6 * Copyright 1997-2001 by Easy Software Products, all rights reserved.
e173a49f 7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
753453e4 26 * main() - Open socks and poll until we are killed...
27 * poll_server() - Poll the server for the given set of printers or classes.
e173a49f 28 */
29
30/*
31 * Include necessary headers...
32 */
33
93419f78 34#include <cups/cups.h>
35#include <stdlib.h>
36#include <cups/language.h>
37#include <cups/string.h>
e173a49f 38
39
40/*
93419f78 41 * Local functions...
e173a49f 42 */
43
93419f78 44int poll_server(http_t *http, cups_lang_t *language, ipp_op_t op,
45 int sock, int port);
46
47
48/*
49 * 'main()' - Open socks and poll until we are killed...
50 */
e173a49f 51
93419f78 52int /* O - Exit status */
53main(int argc, /* I - Number of command-line arguments */
54 char *argv[]) /* I - Command-line arguments */
55{
56 http_t *http; /* HTTP connection */
57 cups_lang_t *language; /* Language info */
58 int interval; /* Polling interval */
59 int sock; /* Browser sock */
60 int port; /* Browser port */
61 int val; /* Socket option value */
e173a49f 62
e173a49f 63
64 /*
93419f78 65 * The command-line must contain the following:
66 *
67 * cups-polld server server-port interval port
e173a49f 68 */
69
93419f78 70 if (argc != 5)
e173a49f 71 {
93419f78 72 fputs("Usage: cups-polld server server-port interval port\n", stderr);
73 return (1);
e173a49f 74 }
75
93419f78 76 interval = atoi(argv[3]);
77 port = atoi(argv[4]);
78
e173a49f 79 /*
93419f78 80 * Open a connection to the server...
e173a49f 81 */
82
b5cb0608 83 if ((http = httpConnectEncrypt(argv[1], atoi(argv[2]),
84 cupsEncryption())) == NULL)
e173a49f 85 {
93419f78 86 perror("cups-polld");
87 return (1);
e173a49f 88 }
89
90 /*
93419f78 91 * Open a broadcast sock...
e173a49f 92 */
93
93419f78 94 if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
e173a49f 95 {
93419f78 96 perror("cups-polld");
97 httpClose(http);
98 return (1);
e173a49f 99 }
100
101 /*
93419f78 102 * Set the "broadcast" flag...
e173a49f 103 */
104
93419f78 105 val = 1;
106 if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val)))
107 {
108 perror("cups-polld");
e173a49f 109
93419f78 110 close(sock);
111 httpClose(http);
112 return (1);
113 }
e173a49f 114
115 /*
93419f78 116 * Loop forever, asking for available printers and classes...
e173a49f 117 */
118
93419f78 119 language = cupsLangDefault();
120
121 for (;;)
e173a49f 122 {
753453e4 123 if (!poll_server(http, language, CUPS_GET_PRINTERS, sock, port))
124 poll_server(http, language, CUPS_GET_CLASSES, sock, port);
93419f78 125
126 sleep(interval);
e173a49f 127 }
128}
129
130
131/*
93419f78 132 * 'poll_server()' - Poll the server for the given set of printers or classes.
e173a49f 133 */
134
93419f78 135int /* O - 0 for success, -1 on error */
136poll_server(http_t *http, /* I - HTTP connection */
137 cups_lang_t *language, /* I - Language */
138 ipp_op_t op, /* I - Operation code */
139 int sock, /* I - Broadcast sock */
140 int port) /* I - Broadcast port */
e173a49f 141{
93419f78 142 ipp_t *request, /* Request data */
143 *response; /* Response data */
144 ipp_attribute_t *attr; /* Current attribute */
145 const char *uri, /* printer-uri */
146 *info, /* printer-info */
147 *location, /* printer-location */
148 *make_model; /* printer-make-and-model */
149 cups_ptype_t type; /* printer-type */
150 ipp_pstate_t state; /* printer-state */
151 struct sockaddr_in addr; /* Broadcast address */
152 char packet[1540]; /* Data packet */
753453e4 153 static const char *attrs[] = /* Requested attributes */
154 {
155 "printer-info",
156 "printer-location",
157 "printer-make-and-model",
158 "printer-state",
159 "printer-type",
160 "printer-uri-supported"
161 };
e173a49f 162
163
164 /*
93419f78 165 * Broadcast to 127.0.0.1 (localhost)
e173a49f 166 */
167
93419f78 168 memset(&addr, 0, sizeof(addr));
169 addr.sin_addr.s_addr = htonl(0x7f000001);
170 addr.sin_family = AF_INET;
171 addr.sin_port = htons(port);
e173a49f 172
173 /*
93419f78 174 * Build a CUPS_GET_PRINTERS or CUPS_GET_CLASSES request, which requires
175 * only the attributes-charset and attributes-natural-language attributes.
e173a49f 176 */
177
93419f78 178 request = ippNew();
e173a49f 179
93419f78 180 request->request.op.operation_id = op;
181 request->request.op.request_id = 1;
e173a49f 182
93419f78 183 language = cupsLangDefault();
e173a49f 184
93419f78 185 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
186 "attributes-charset", NULL, cupsLangEncoding(language));
e173a49f 187
93419f78 188 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
189 "attributes-natural-language", NULL, language->language);
e173a49f 190
753453e4 191 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
192 "requested-attributes", sizeof(attrs) / sizeof(attrs[0]),
193 NULL, attrs);
194
93419f78 195 /*
196 * Do the request and get back a response...
197 */
e173a49f 198
93419f78 199 if ((response = cupsDoRequest(http, request, "/")) != NULL)
e173a49f 200 {
93419f78 201 if (response->request.status.status_code > IPP_OK_CONFLICT)
e173a49f 202 {
93419f78 203 fprintf(stderr, "cups-polld: get-%s failed: %s\n",
204 op == CUPS_GET_PRINTERS ? "printers" : "classes",
205 ippErrorString(response->request.status.status_code));
206 ippDelete(response);
207 return (-1);
e173a49f 208 }
93419f78 209
e173a49f 210 /*
93419f78 211 * Loop through the printers or classes returned in the list...
e173a49f 212 */
213
93419f78 214 for (attr = response->attrs; attr != NULL; attr = attr->next)
e173a49f 215 {
216 /*
93419f78 217 * Skip leading attributes until we hit a printer...
e173a49f 218 */
219
93419f78 220 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
221 attr = attr->next;
222
223 if (attr == NULL)
224 break;
e173a49f 225
226 /*
93419f78 227 * Pull the needed attributes from this printer...
e173a49f 228 */
229
93419f78 230 uri = NULL;
231 info = "";
232 location = "";
233 make_model = "";
234 type = CUPS_PRINTER_REMOTE;
235 state = IPP_PRINTER_IDLE;
e173a49f 236
93419f78 237 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
238 {
239 if (strcmp(attr->name, "printer-uri-supported") == 0 &&
240 attr->value_tag == IPP_TAG_URI)
241 uri = attr->values[0].string.text;
e173a49f 242
93419f78 243 if (strcmp(attr->name, "printer-info") == 0 &&
244 attr->value_tag == IPP_TAG_TEXT)
245 info = attr->values[0].string.text;
e173a49f 246
93419f78 247 if (strcmp(attr->name, "printer-location") == 0 &&
248 attr->value_tag == IPP_TAG_TEXT)
249 location = attr->values[0].string.text;
e173a49f 250
93419f78 251 if (strcmp(attr->name, "printer-make-and-model") == 0 &&
252 attr->value_tag == IPP_TAG_TEXT)
253 make_model = attr->values[0].string.text;
e173a49f 254
93419f78 255 if (strcmp(attr->name, "printer-state") == 0 &&
256 attr->value_tag == IPP_TAG_ENUM)
257 state = (ipp_pstate_t)attr->values[0].integer;
e173a49f 258
93419f78 259 if (strcmp(attr->name, "printer-type") == 0 &&
260 attr->value_tag == IPP_TAG_ENUM)
261 type = (cups_ptype_t)attr->values[0].integer;
e173a49f 262
93419f78 263 attr = attr->next;
264 }
e173a49f 265
e173a49f 266 /*
93419f78 267 * See if we have everything needed...
e173a49f 268 */
269
93419f78 270 if (uri == NULL)
e173a49f 271 {
93419f78 272 if (attr == NULL)
273 break;
274 else
275 continue;
e173a49f 276 }
277
278 /*
93419f78 279 * See if this is a local printer or class...
e173a49f 280 */
281
93419f78 282 if (!(type & CUPS_PRINTER_REMOTE))
e173a49f 283 {
284 /*
93419f78 285 * Send the printer information...
e173a49f 286 */
287
04de52f8 288 snprintf(packet, sizeof(packet), "%x %x %s \"%s\" \"%s\" \"%s\"\n",
93419f78 289 type | CUPS_PRINTER_REMOTE, state, uri,
290 location, info, make_model);
291 puts(packet);
e173a49f 292
93419f78 293 if (sendto(sock, packet, strlen(packet), 0,
294 (struct sockaddr *)&addr, sizeof(addr)) <= 0)
e173a49f 295 {
93419f78 296 perror("cups-polld");
297 return (-1);
e173a49f 298 }
e173a49f 299 }
e173a49f 300
93419f78 301 if (attr == NULL)
302 break;
e173a49f 303 }
e173a49f 304
93419f78 305 ippDelete(response);
306 }
307 else
e173a49f 308 {
93419f78 309 fprintf(stderr, "cups-polld: get-%s failed: %s\n",
310 op == CUPS_GET_PRINTERS ? "printers" : "classes",
311 ippErrorString(cupsLastError()));
312 return (-1);
e173a49f 313 }
e173a49f 314
93419f78 315 return (0);
e173a49f 316}
317
318
319/*
753453e4 320 * End of "$Id: cups-polld.c,v 1.5.2.2 2001/12/26 16:52:52 mike Exp $".
e173a49f 321 */