Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
srohatgi01
GitHub Repository: srohatgi01/cups
Path: blob/master/berkeley/lpc.c
1090 views
1
/*
2
* "lpc" command for CUPS.
3
*
4
* Copyright 2007-2014 by Apple Inc.
5
* Copyright 1997-2006 by Easy Software Products.
6
*
7
* Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8
*/
9
10
/*
11
* Include necessary headers...
12
*/
13
14
#include <cups/cups-private.h>
15
16
17
/*
18
* Local functions...
19
*/
20
21
static int compare_strings(const char *, const char *, size_t);
22
static void do_command(http_t *, const char *, const char *);
23
static void show_help(const char *);
24
static void show_prompt(const char *message);
25
static void show_status(http_t *, const char *);
26
27
28
/*
29
* 'main()' - Parse options and commands.
30
*/
31
32
int
33
main(int argc, /* I - Number of command-line arguments */
34
char *argv[]) /* I - Command-line arguments */
35
{
36
http_t *http; /* Connection to server */
37
char line[1024], /* Input line from user */
38
*params; /* Pointer to parameters */
39
40
41
_cupsSetLocale(argv);
42
43
/*
44
* Connect to the scheduler...
45
*/
46
47
http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
48
49
if (argc > 1)
50
{
51
/*
52
* Process a single command on the command-line...
53
*/
54
55
do_command(http, argv[1], argv[2]);
56
}
57
else
58
{
59
/*
60
* Do the command prompt thing...
61
*/
62
63
show_prompt(_("lpc> "));
64
while (fgets(line, sizeof(line), stdin) != NULL)
65
{
66
/*
67
* Strip trailing whitespace...
68
*/
69
70
for (params = line + strlen(line) - 1; params >= line;)
71
if (!isspace(*params & 255))
72
break;
73
else
74
*params-- = '\0';
75
76
/*
77
* Strip leading whitespace...
78
*/
79
80
for (params = line; isspace(*params & 255); params ++);
81
82
if (params > line)
83
_cups_strcpy(line, params);
84
85
if (!line[0])
86
{
87
/*
88
* Nothing left, just show a prompt...
89
*/
90
91
show_prompt(_("lpc> "));
92
continue;
93
}
94
95
/*
96
* Find any options in the string...
97
*/
98
99
for (params = line; *params != '\0'; params ++)
100
if (isspace(*params & 255))
101
break;
102
103
/*
104
* Remove whitespace between the command and parameters...
105
*/
106
107
while (isspace(*params & 255))
108
*params++ = '\0';
109
110
/*
111
* The "quit" and "exit" commands exit; otherwise, process as needed...
112
*/
113
114
if (!compare_strings(line, "quit", 1) ||
115
!compare_strings(line, "exit", 2))
116
break;
117
118
if (*params == '\0')
119
do_command(http, line, NULL);
120
else
121
do_command(http, line, params);
122
123
/*
124
* Put another prompt out to the user...
125
*/
126
127
show_prompt(_("lpc> "));
128
}
129
}
130
131
/*
132
* Close the connection to the server and return...
133
*/
134
135
httpClose(http);
136
137
return (0);
138
}
139
140
141
/*
142
* 'compare_strings()' - Compare two command-line strings.
143
*/
144
145
static int /* O - -1 or 1 = no match, 0 = match */
146
compare_strings(const char *s, /* I - Command-line string */
147
const char *t, /* I - Option string */
148
size_t tmin) /* I - Minimum number of unique chars in option */
149
{
150
size_t slen; /* Length of command-line string */
151
152
153
slen = strlen(s);
154
if (slen < tmin)
155
return (-1);
156
else
157
return (strncmp(s, t, slen));
158
}
159
160
161
/*
162
* 'do_command()' - Do an lpc command...
163
*/
164
165
static void
166
do_command(http_t *http, /* I - HTTP connection to server */
167
const char *command, /* I - Command string */
168
const char *params) /* I - Parameters for command */
169
{
170
if (!compare_strings(command, "status", 4))
171
show_status(http, params);
172
else if (!compare_strings(command, "help", 1) || !strcmp(command, "?"))
173
show_help(params);
174
else
175
_cupsLangPrintf(stdout,
176
_("%s is not implemented by the CUPS version of lpc."),
177
command);
178
}
179
180
181
/*
182
* 'show_help()' - Show help messages.
183
*/
184
185
static void
186
show_help(const char *command) /* I - Command to describe or NULL */
187
{
188
if (!command)
189
{
190
_cupsLangPrintf(stdout,
191
_("Commands may be abbreviated. Commands are:\n"
192
"\n"
193
"exit help quit status ?"));
194
}
195
else if (!compare_strings(command, "help", 1) || !strcmp(command, "?"))
196
_cupsLangPrintf(stdout, _("help\t\tGet help on commands."));
197
else if (!compare_strings(command, "status", 4))
198
_cupsLangPrintf(stdout, _("status\t\tShow status of daemon and queue."));
199
else
200
_cupsLangPrintf(stdout, _("?Invalid help command unknown."));
201
}
202
203
204
/*
205
* 'show_prompt()' - Show a localized prompt message.
206
*/
207
208
static void
209
show_prompt(const char *message) /* I - Message string to use */
210
{
211
ssize_t bytes; /* Number of bytes formatted */
212
char output[8192]; /* Message buffer */
213
cups_lang_t *lang = cupsLangDefault();
214
/* Default language */
215
216
/*
217
* Transcode to the destination charset and write the prompt...
218
*/
219
220
if ((bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)_cupsLangString(lang, message), sizeof(output), lang->encoding)) > 0)
221
{
222
fwrite(output, 1, (size_t)bytes, stdout);
223
fflush(stdout);
224
}
225
}
226
227
228
/*
229
* 'show_status()' - Show printers.
230
*/
231
232
static void
233
show_status(http_t *http, /* I - HTTP connection to server */
234
const char *dests) /* I - Destinations */
235
{
236
ipp_t *request, /* IPP Request */
237
*response; /* IPP Response */
238
ipp_attribute_t *attr; /* Current attribute */
239
char *printer, /* Printer name */
240
*device, /* Device URI */
241
*delimiter; /* Char search result */
242
ipp_pstate_t pstate; /* Printer state */
243
int accepting; /* Is printer accepting jobs? */
244
int jobcount; /* Count of current jobs */
245
const char *dptr, /* Pointer into destination list */
246
*ptr; /* Pointer into printer name */
247
int match; /* Non-zero if this job matches */
248
static const char *requested[] = /* Requested attributes */
249
{
250
"device-uri",
251
"printer-is-accepting-jobs",
252
"printer-name",
253
"printer-state",
254
"queued-job-count"
255
};
256
257
258
if (http == NULL)
259
return;
260
261
/*
262
* Build a CUPS_GET_PRINTERS request, which requires the following
263
* attributes:
264
*
265
* attributes-charset
266
* attributes-natural-language
267
*/
268
269
request = ippNewRequest(CUPS_GET_PRINTERS);
270
271
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
272
"requested-attributes", sizeof(requested) / sizeof(requested[0]),
273
NULL, requested);
274
275
/*
276
* Do the request and get back a response...
277
*/
278
279
if ((response = cupsDoRequest(http, request, "/")) != NULL)
280
{
281
/*
282
* Loop through the printers returned in the list and display
283
* their status...
284
*/
285
286
for (attr = response->attrs; attr != NULL; attr = attr->next)
287
{
288
/*
289
* Skip leading attributes until we hit a job...
290
*/
291
292
while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
293
attr = attr->next;
294
295
if (attr == NULL)
296
break;
297
298
/*
299
* Pull the needed attributes from this job...
300
*/
301
302
printer = NULL;
303
device = "file:/dev/null";
304
pstate = IPP_PRINTER_IDLE;
305
jobcount = 0;
306
accepting = 1;
307
308
while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
309
{
310
if (!strcmp(attr->name, "device-uri") &&
311
attr->value_tag == IPP_TAG_URI)
312
device = attr->values[0].string.text;
313
else if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
314
attr->value_tag == IPP_TAG_BOOLEAN)
315
accepting = attr->values[0].boolean;
316
else if (!strcmp(attr->name, "printer-name") &&
317
attr->value_tag == IPP_TAG_NAME)
318
printer = attr->values[0].string.text;
319
else if (!strcmp(attr->name, "printer-state") &&
320
attr->value_tag == IPP_TAG_ENUM)
321
pstate = (ipp_pstate_t)attr->values[0].integer;
322
else if (!strcmp(attr->name, "queued-job-count") &&
323
attr->value_tag == IPP_TAG_INTEGER)
324
jobcount = attr->values[0].integer;
325
326
attr = attr->next;
327
}
328
329
/*
330
* See if we have everything needed...
331
*/
332
333
if (printer == NULL)
334
{
335
if (attr == NULL)
336
break;
337
else
338
continue;
339
}
340
341
/*
342
* A single 'all' printer name is special, meaning all printers.
343
*/
344
345
if (dests != NULL && !strcmp(dests, "all"))
346
dests = NULL;
347
348
/*
349
* See if this is a printer we're interested in...
350
*/
351
352
match = dests == NULL;
353
354
if (dests != NULL)
355
{
356
for (dptr = dests; *dptr != '\0';)
357
{
358
/*
359
* Skip leading whitespace and commas...
360
*/
361
362
while (isspace(*dptr & 255) || *dptr == ',')
363
dptr ++;
364
365
if (*dptr == '\0')
366
break;
367
368
/*
369
* Compare names...
370
*/
371
372
for (ptr = printer;
373
*ptr != '\0' && *dptr != '\0' && *ptr == *dptr;
374
ptr ++, dptr ++)
375
/* do nothing */;
376
377
if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' ||
378
isspace(*dptr & 255)))
379
{
380
match = 1;
381
break;
382
}
383
384
/*
385
* Skip trailing junk...
386
*/
387
388
while (!isspace(*dptr & 255) && *dptr != '\0')
389
dptr ++;
390
while (isspace(*dptr & 255) || *dptr == ',')
391
dptr ++;
392
393
if (*dptr == '\0')
394
break;
395
}
396
}
397
398
/*
399
* Display the printer entry if needed...
400
*/
401
402
if (match)
403
{
404
/*
405
* Display it...
406
*/
407
408
printf("%s:\n", printer);
409
if (!strncmp(device, "file:", 5))
410
_cupsLangPrintf(stdout,
411
_("\tprinter is on device \'%s\' speed -1"),
412
device + 5);
413
else
414
{
415
/*
416
* Just show the scheme...
417
*/
418
419
if ((delimiter = strchr(device, ':')) != NULL )
420
{
421
*delimiter = '\0';
422
_cupsLangPrintf(stdout,
423
_("\tprinter is on device \'%s\' speed -1"),
424
device);
425
}
426
}
427
428
if (accepting)
429
_cupsLangPuts(stdout, _("\tqueuing is enabled"));
430
else
431
_cupsLangPuts(stdout, _("\tqueuing is disabled"));
432
433
if (pstate != IPP_PRINTER_STOPPED)
434
_cupsLangPuts(stdout, _("\tprinting is enabled"));
435
else
436
_cupsLangPuts(stdout, _("\tprinting is disabled"));
437
438
if (jobcount == 0)
439
_cupsLangPuts(stdout, _("\tno entries"));
440
else
441
_cupsLangPrintf(stdout, _("\t%d entries"), jobcount);
442
443
_cupsLangPuts(stdout, _("\tdaemon present"));
444
}
445
446
if (attr == NULL)
447
break;
448
}
449
450
ippDelete(response);
451
}
452
}
453
454