]> git.ipfire.org Git - thirdparty/cups.git/blame - test/ipptest.c
Load cups into easysw/current.
[thirdparty/cups.git] / test / ipptest.c
CommitLineData
ef416fc2 1/*
b94498cf 2 * "$Id: ipptest.c 6503 2007-05-01 23:06:44Z mike $"
ef416fc2 3 *
4 * IPP test command for the Common UNIX Printing System (CUPS).
5 *
b94498cf 6 * Copyright 1997-2007 by Easy Software Products.
ef416fc2 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 USA
19 *
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
e00b005a 26 * main() - Parse options and do tests.
27 * do_tests() - Do tests as specified in the test file.
28 * get_tag() - Get an IPP value or group tag from a name...
29 * get_token() - Get a token from a file.
30 * print_attr() - Print an attribute on the screen.
31 * usage() - Show program usage.
ef416fc2 32 */
33
34/*
35 * Include necessary headers...
36 */
37
38#include <stdio.h>
39#include <stdlib.h>
40#include <cups/string.h>
41#include <errno.h>
42#include <ctype.h>
43
44#include <cups/cups.h>
45#include <cups/language.h>
46
47
e00b005a 48/*
49 * Globals...
50 */
51
89d46774 52int Verbosity = 0; /* Show all attributes? */
53const char * const TagNames[] =
54 { /* Value/group tag names */
55 "zero", /* 0x00 */
56 "operation", /* 0x01 */
57 "job", /* 0x02 */
58 "end", /* 0x03 */
59 "printer", /* 0x04 */
60 "unsupported-group", /* 0x05 */
61 "subscription", /* 0x06 */
62 "event-notification", /* 0x07 */
63 "", "", "", "", "", "", "", "",
64 "unsupported-value", /* 0x10 */
65 "default", /* 0x11 */
66 "unknown", /* 0x12 */
67 "novalue", /* 0x13 */
68 "",
69 "notsettable", /* 0x15 */
70 "deleteattr", /* 0x16 */
71 "anyvalue", /* 0x17 */
72 "", "", "", "", "", "", "", "", "",
73 "integer", /* 0x21 */
74 "boolean", /* 0x22 */
75 "enum", /* 0x23 */
76 "", "", "", "", "", "", "", "", "", "", "", "",
77 "string", /* 0x30 */
78 "date", /* 0x31 */
79 "resolution", /* 0x32 */
80 "range", /* 0x33 */
81 "collection", /* 0x34 */
82 "textlang", /* 0x35 */
83 "namelang", /* 0x36 */
84 "", "", "", "", "", "", "", "", "", "",
85 "text", /* 0x41 */
86 "name", /* 0x42 */
87 "",
88 "keyword", /* 0x44 */
89 "uri", /* 0x45 */
90 "urischeme", /* 0x46 */
91 "charset", /* 0x47 */
92 "language", /* 0x48 */
93 "mimetype" /* 0x49 */
94 };
95
96
e00b005a 97
98
ef416fc2 99/*
100 * Local functions...
101 */
102
103int do_tests(const char *, const char *);
104ipp_op_t ippOpValue(const char *);
105ipp_status_t ippErrorValue(const char *);
106ipp_tag_t get_tag(const char *);
89d46774 107const char *get_tag_string(ipp_tag_t tag);
ef416fc2 108char *get_token(FILE *, char *, int, int *linenum);
109void print_attr(ipp_attribute_t *);
e00b005a 110void usage(const char *option);
ef416fc2 111
112
113/*
114 * 'main()' - Parse options and do tests.
115 */
116
117int /* O - Exit status */
118main(int argc, /* I - Number of command-line arguments */
119 char *argv[]) /* I - Command-line arguments */
120{
121 int i; /* Looping var */
122 int status; /* Status of tests... */
e00b005a 123 const char *uri; /* URI to use */
124 const char *testfile; /* Test file to use */
8ca02f3c 125 int interval; /* Test interval */
ef416fc2 126
127
128 /*
129 * We need at least:
130 *
131 * testipp URL testfile
132 */
133
e00b005a 134 uri = NULL;
135 testfile = NULL;
136 status = 0;
8ca02f3c 137 interval = 0;
e00b005a 138
139 for (i = 1; i < argc; i ++)
ef416fc2 140 {
e00b005a 141 if (argv[i][0] == '-')
142 {
143 if (!strcmp(argv[i], "-v"))
144 Verbosity ++;
b94498cf 145 else if (!strcmp(argv[i], "-d"))
146 {
147 i ++;
148
149 if (i >= argc)
150 usage(NULL);
151 else
152 putenv(argv[i]);
153 }
8ca02f3c 154 else if (!strcmp(argv[i], "-i"))
155 {
156 i++;
157
158 if (i >= argc)
159 usage(NULL);
160 else
161 interval = atoi(argv[i]);
162 }
e00b005a 163 else
164 usage(argv[i]);
165 }
166 else if (!strncmp(argv[i], "ipp://", 6) ||
167 !strncmp(argv[i], "http://", 7) ||
168 !strncmp(argv[i], "https://", 8))
169 {
170 /*
171 * Set URI...
172 */
ef416fc2 173
e00b005a 174 if (!testfile && uri)
175 usage(NULL);
176
177 uri = argv[i];
178 testfile = NULL;
179 }
180 else
181 {
182 /*
183 * Run test...
184 */
185
186 testfile = argv[i];
187
188 if (!do_tests(uri, testfile))
189 status ++;
190 }
191 }
ef416fc2 192
e00b005a 193 if (!uri || !testfile)
194 usage(NULL);
ef416fc2 195
8ca02f3c 196 /*
197 * Loop if the interval is set...
198 */
199
200 if (interval)
201 {
202 for (;;)
203 {
204 sleep(interval);
205 do_tests(uri, testfile);
206 }
207 }
208
ef416fc2 209 /*
210 * Exit...
211 */
212
e00b005a 213 return (status);
ef416fc2 214}
215
216
217/*
218 * 'do_tests()' - Do tests as specified in the test file.
219 */
220
221int /* 1 = success, 0 = failure */
222do_tests(const char *uri, /* I - URI to connect on */
223 const char *testfile) /* I - Test file to use */
224{
225 int i; /* Looping var */
226 int linenum; /* Current line number */
227 int version; /* IPP version number to use */
228 http_t *http; /* HTTP connection to server */
229 char method[HTTP_MAX_URI], /* URI method */
230 userpass[HTTP_MAX_URI], /* username:password */
231 server[HTTP_MAX_URI], /* Server */
232 resource[HTTP_MAX_URI]; /* Resource path */
233 int port; /* Port number */
234 FILE *fp; /* Test file */
235 char token[1024], /* Token from file */
236 *tokenptr, /* Pointer into token */
237 temp[1024], /* Temporary string */
238 *tempptr; /* Pointer into temp string */
239 ipp_t *request; /* IPP request */
240 ipp_t *response; /* IPP response */
241 ipp_op_t op; /* Operation */
242 ipp_tag_t group; /* Current group */
243 ipp_tag_t value; /* Current value type */
244 ipp_attribute_t *attrptr; /* Attribute pointer */
245 char attr[128]; /* Attribute name */
246 int num_statuses; /* Number of valid status codes */
247 ipp_status_t statuses[100]; /* Valid status codes */
248 int num_expects; /* Number of expected attributes */
249 char *expects[100]; /* Expected attributes */
250 int num_displayed; /* Number of displayed attributes */
251 char *displayed[100]; /* Displayed attributes */
252 char name[1024]; /* Name of test */
253 char filename[1024]; /* Filename */
254 int pass; /* Did we pass the test? */
255 int job_id; /* Job ID from last operation */
256 int subscription_id; /* Subscription ID from last operation */
257
258
259 /*
260 * Open the test file...
261 */
262
263 if ((fp = fopen(testfile, "r")) == NULL)
264 {
265 printf("Unable to open test file %s - %s\n", testfile, strerror(errno));
266 return (0);
267 }
268
269 /*
270 * Connect to the server...
271 */
272
a4d04587 273 httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), userpass,
274 sizeof(userpass), server, sizeof(server), &port, resource,
275 sizeof(resource));
ef416fc2 276 if ((http = httpConnect(server, port)) == NULL)
277 {
278 printf("Unable to connect to %s on port %d - %s\n", server, port,
279 strerror(errno));
280 return (0);
281 }
282
283 /*
284 * Loop on tests...
285 */
286
287 printf("\"%s\":\n", testfile);
288 pass = 1;
289 job_id = 0;
290 subscription_id = 0;
291 version = 1;
292 linenum = 1;
293
294 while (get_token(fp, token, sizeof(token), &linenum) != NULL)
295 {
296 /*
297 * Expect an open brace...
298 */
299
300 if (strcmp(token, "{"))
301 {
302 printf("Unexpected token %s seen on line %d - aborting test!\n", token,
303 linenum);
304 httpClose(http);
305 return (0);
306 }
307
308 /*
309 * Initialize things...
310 */
311
a4d04587 312 httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), userpass,
313 sizeof(userpass), server, sizeof(server), &port, resource,
314 sizeof(resource));
ef416fc2 315
316 request = ippNew();
317 op = (ipp_op_t)0;
318 group = IPP_TAG_ZERO;
319 value = IPP_TAG_ZERO;
320 num_statuses = 0;
321 num_expects = 0;
322 num_displayed = 0;
323 filename[0] = '\0';
324
325 strcpy(name, testfile);
326 if (strrchr(name, '.') != NULL)
327 *strrchr(name, '.') = '\0';
328
329 /*
330 * Parse until we see a close brace...
331 */
332
333 while (get_token(fp, token, sizeof(token), &linenum) != NULL)
334 {
335 if (!strcmp(token, "}"))
336 break;
337 else if (!strcasecmp(token, "NAME"))
338 {
339 /*
340 * Name of test...
341 */
342
343 get_token(fp, name, sizeof(name), &linenum);
344 }
345 else if (!strcasecmp(token, "VERSION"))
346 {
347 /*
348 * IPP version number for test...
349 */
350
351 get_token(fp, temp, sizeof(temp), &linenum);
352 sscanf(temp, "%*d.%d", &version);
353 }
354 else if (!strcasecmp(token, "RESOURCE"))
355 {
356 /*
357 * Resource name...
358 */
359
360 get_token(fp, resource, sizeof(resource), &linenum);
361 }
362 else if (!strcasecmp(token, "OPERATION"))
363 {
364 /*
365 * Operation...
366 */
367
368 get_token(fp, token, sizeof(token), &linenum);
369 op = ippOpValue(token);
370 }
371 else if (!strcasecmp(token, "GROUP"))
372 {
373 /*
374 * Attribute group...
375 */
376
377 get_token(fp, token, sizeof(token), &linenum);
378 value = get_tag(token);
379
380 if (value == group)
381 ippAddSeparator(request);
382
383 group = value;
384 }
385 else if (!strcasecmp(token, "DELAY"))
386 {
387 /*
388 * Delay before operation...
389 */
390
391 int delay;
392
393 get_token(fp, token, sizeof(token), &linenum);
394 if ((delay = atoi(token)) > 0)
395 sleep(delay);
396 }
397 else if (!strcasecmp(token, "ATTR"))
398 {
399 /*
400 * Attribute...
401 */
402
403 get_token(fp, token, sizeof(token), &linenum);
404 value = get_tag(token);
405 get_token(fp, attr, sizeof(attr), &linenum);
406 get_token(fp, temp, sizeof(temp), &linenum);
407
408 token[sizeof(token) - 1] = '\0';
409
410 for (tempptr = temp, tokenptr = token;
411 *tempptr && tokenptr < (token + sizeof(token) - 1);)
412 if (*tempptr == '$')
413 {
414 /*
415 * Substitute a string/number...
416 */
417
418 if (!strncasecmp(tempptr + 1, "uri", 3))
419 {
420 strlcpy(tokenptr, uri, sizeof(token) - (tokenptr - token));
421 tempptr += 4;
422 }
423 else if (!strncasecmp(tempptr + 1, "method", 6))
424 {
425 strlcpy(tokenptr, method, sizeof(token) - (tokenptr - token));
426 tempptr += 7;
427 }
428 else if (!strncasecmp(tempptr + 1, "username", 8))
429 {
430 strlcpy(tokenptr, userpass, sizeof(token) - (tokenptr - token));
431 tempptr += 9;
432 }
433 else if (!strncasecmp(tempptr + 1, "hostname", 8))
434 {
435 strlcpy(tokenptr, server, sizeof(token) - (tokenptr - token));
436 tempptr += 9;
437 }
438 else if (!strncasecmp(tempptr + 1, "port", 4))
439 {
440 snprintf(tokenptr, sizeof(token) - (tokenptr - token),
441 "%d", port);
442 tempptr += 5;
443 }
444 else if (!strncasecmp(tempptr + 1, "resource", 8))
445 {
446 strlcpy(tokenptr, resource, sizeof(token) - (tokenptr - token));
447 tempptr += 9;
448 }
449 else if (!strncasecmp(tempptr + 1, "job-id", 6))
450 {
451 snprintf(tokenptr, sizeof(token) - (tokenptr - token),
452 "%d", job_id);
453 tempptr += 7;
454 }
455 else if (!strncasecmp(tempptr + 1, "notify-subscription-id", 22))
456 {
457 snprintf(tokenptr, sizeof(token) - (tokenptr - token),
458 "%d", subscription_id);
459 tempptr += 23;
460 }
461 else if (!strncasecmp(tempptr + 1, "user", 4))
462 {
463 strlcpy(tokenptr, cupsUser(), sizeof(token) - (tokenptr - token));
464 tempptr += 5;
465 }
b94498cf 466 else if (!strncasecmp(tempptr + 1, "ENV[", 4))
467 {
468 char *end; /* End of $ENV[name] */
469
470
471 if ((end = strchr(tempptr + 5, ']')) != NULL)
472 {
473 *end++ = '\0';
474 strlcpy(tokenptr,
475 getenv(tempptr + 5) ? getenv(tempptr + 5) : tempptr + 5,
476 sizeof(token) - (tokenptr - token));
477 tempptr = end;
478 }
479 else
480 {
481 *tokenptr++ = *tempptr++;
482 *tokenptr = '\0';
483 }
484 }
ef416fc2 485 else
486 {
b94498cf 487 *tokenptr++ = *tempptr++;
ef416fc2 488 *tokenptr = '\0';
489 }
490
491 tokenptr += strlen(tokenptr);
492 }
493 else
494 {
495 *tokenptr++ = *tempptr++;
496 *tokenptr = '\0';
497 }
498
499 switch (value)
500 {
501 case IPP_TAG_BOOLEAN :
502 if (!strcasecmp(token, "true"))
503 ippAddBoolean(request, group, attr, 1);
504 else
505 ippAddBoolean(request, group, attr, atoi(token));
506 break;
507
508 case IPP_TAG_INTEGER :
509 case IPP_TAG_ENUM :
510 ippAddInteger(request, group, value, attr, atoi(token));
511 break;
512
513 case IPP_TAG_RESOLUTION :
514 puts(" ERROR: resolution tag not yet supported!");
515 break;
516
517 case IPP_TAG_RANGE :
518 puts(" ERROR: range tag not yet supported!");
519 break;
520
521 default :
522 if (!strchr(token, ','))
523 ippAddString(request, group, value, attr, NULL, token);
524 else
525 {
526 /*
527 * Multiple string values...
528 */
529
530 int num_values; /* Number of values */
531 char *values[100], /* Values */
532 *ptr; /* Pointer to next value */
533
534
535 values[0] = token;
536 num_values = 1;
537
538 for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ','))
539 {
540 *ptr++ = '\0';
541 values[num_values] = ptr;
542 num_values ++;
543 }
544
545 ippAddStrings(request, group, value, attr, num_values,
546 NULL, (const char **)values);
547 }
548 break;
549 }
550 }
551 else if (!strcasecmp(token, "FILE"))
552 {
553 /*
554 * File...
555 */
556
557 get_token(fp, filename, sizeof(filename), &linenum);
558 }
559 else if (!strcasecmp(token, "STATUS") &&
560 num_statuses < (int)(sizeof(statuses) / sizeof(statuses[0])))
561 {
562 /*
563 * Status...
564 */
565
566 get_token(fp, token, sizeof(token), &linenum);
567 statuses[num_statuses] = ippErrorValue(token);
568 num_statuses ++;
569 }
570 else if (!strcasecmp(token, "EXPECT") &&
571 num_expects < (int)(sizeof(expects) / sizeof(expects[0])))
572 {
573 /*
574 * Expected attributes...
575 */
576
577 get_token(fp, token, sizeof(token), &linenum);
578 expects[num_expects] = strdup(token);
579 num_expects ++;
580 }
581 else if (!strcasecmp(token, "DISPLAY") &&
582 num_displayed < (int)(sizeof(displayed) / sizeof(displayed[0])))
583 {
584 /*
585 * Display attributes...
586 */
587
588 get_token(fp, token, sizeof(token), &linenum);
589 displayed[num_displayed] = strdup(token);
590 num_displayed ++;
591 }
592 else
593 {
594 printf("Unexpected token %s seen on line %d - aborting test!\n", token,
595 linenum);
596 httpClose(http);
597 ippDelete(request);
598 return (0);
599 }
600 }
601
602 /*
603 * Submit the IPP request...
604 */
605
606 request->request.op.version[1] = version;
607 request->request.op.operation_id = op;
608 request->request.op.request_id = 1;
609
bd7854cb 610 if (Verbosity)
611 {
612 printf("%s:\n", ippOpString(op));
613
614 for (attrptr = request->attrs; attrptr; attrptr = attrptr->next)
615 print_attr(attrptr);
616 }
ef416fc2 617
618 printf(" %-60.60s [", name);
619 fflush(stdout);
620
621 if (filename[0])
622 response = cupsDoFileRequest(http, request, resource, filename);
623 else
b94498cf 624 response = cupsDoIORequest(http, request, resource, -1,
625 Verbosity ? 1 : -1);
ef416fc2 626
627 if (response == NULL)
628 {
629 time_t curtime;
630
631 curtime = time(NULL);
632
633 puts("FAIL]");
634 printf(" ERROR %04x (%s) @ %s\n", cupsLastError(),
bd7854cb 635 cupsLastErrorString(), ctime(&curtime));
ef416fc2 636 pass = 0;
637 }
638 else
639 {
640 if ((attrptr = ippFindAttribute(response, "job-id",
641 IPP_TAG_INTEGER)) != NULL)
642 job_id = attrptr->values[0].integer;
643
644 if ((attrptr = ippFindAttribute(response, "notify-subscription-id",
645 IPP_TAG_INTEGER)) != NULL)
646 subscription_id = attrptr->values[0].integer;
647
648 for (i = 0; i < num_statuses; i ++)
649 if (response->request.status.status_code == statuses[i])
650 break;
651
652 if (i == num_statuses && num_statuses > 0)
653 pass = 0;
654 else
655 {
656 for (i = 0; i < num_expects; i ++)
657 if (ippFindAttribute(response, expects[i], IPP_TAG_ZERO) == NULL)
658 {
659 pass = 0;
660 break;
661 }
662 }
663
664 if (pass)
665 {
666 puts("PASS]");
667 printf(" RECEIVED: %lu bytes in response\n",
668 (unsigned long)ippLength(response));
669
e00b005a 670 if (Verbosity)
671 {
672 for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next)
673 print_attr(attrptr);
674 }
675 else if (num_displayed > 0)
ef416fc2 676 {
677 for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next)
678 if (attrptr->name)
679 {
680 for (i = 0; i < num_displayed; i ++)
681 if (!strcmp(displayed[i], attrptr->name))
682 {
683 print_attr(attrptr);
684 break;
685 }
686 }
687 }
688 }
689 else
690 {
691 puts("FAIL]");
692 printf(" RECEIVED: %lu bytes in response\n",
693 (unsigned long)ippLength(response));
694
695 for (i = 0; i < num_statuses; i ++)
696 if (response->request.status.status_code == statuses[i])
697 break;
698
699 if (i == num_statuses && num_statuses > 0)
700 puts(" BAD STATUS");
701
702 printf(" status-code = %04x (%s)\n",
b94498cf 703 cupsLastError(), ippErrorString(cupsLastError()));
ef416fc2 704
705 for (i = 0; i < num_expects; i ++)
706 if (ippFindAttribute(response, expects[i], IPP_TAG_ZERO) == NULL)
707 printf(" EXPECTED: %s\n", expects[i]);
708
709 for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next)
710 print_attr(attrptr);
711 }
712
713 ippDelete(response);
714 }
715
716 for (i = 0; i < num_expects; i ++)
717 free(expects[i]);
718
719 if (!pass)
720 break;
721 }
722
723 fclose(fp);
724 httpClose(http);
725
726 return (pass);
727}
728
729
730/*
731 * 'get_tag()' - Get an IPP value or group tag from a name...
732 */
733
734ipp_tag_t /* O - Value/group tag */
735get_tag(const char *name) /* I - Name of value/group tag */
736{
737 int i; /* Looping var */
ef416fc2 738
739
89d46774 740 for (i = 0; i < (sizeof(TagNames) / sizeof(TagNames[0])); i ++)
741 if (!strcasecmp(name, TagNames[i]))
ef416fc2 742 return ((ipp_tag_t)i);
743
744 return (IPP_TAG_ZERO);
745}
746
747
89d46774 748/*
749 * 'get_tag_string()' - Get the string associated with a tag.
750 */
751
752const char * /* O - Tag name string */
753get_tag_string(ipp_tag_t tag) /* I - IPP tag */
754{
755 if (tag < (ipp_tag_t)(sizeof(TagNames) / sizeof(TagNames[0])))
756 return (TagNames[tag]);
757 else
758 return ("UNKNOWN");
759}
760
761
ef416fc2 762/*
763 * 'get_token()' - Get a token from a file.
764 */
765
766char * /* O - Token from file or NULL on EOF */
767get_token(FILE *fp, /* I - File to read from */
768 char *buf, /* I - Buffer to read into */
769 int buflen, /* I - Length of buffer */
770 int *linenum) /* IO - Current line number */
771{
772 int ch, /* Character from file */
773 quote; /* Quoting character */
774 char *bufptr, /* Pointer into buffer */
775 *bufend; /* End of buffer */
776
777
778 for (;;)
779 {
780 /*
781 * Skip whitespace...
782 */
783
784 while (isspace(ch = getc(fp)))
785 {
786 if (ch == '\n')
787 (*linenum) ++;
788 }
789
790 /*
791 * Read a token...
792 */
793
794 if (ch == EOF)
795 return (NULL);
796 else if (ch == '\'' || ch == '\"')
797 {
798 /*
799 * Quoted text...
800 */
801
802 quote = ch;
803 bufptr = buf;
804 bufend = buf + buflen - 1;
805
806 while ((ch = getc(fp)) != EOF)
807 if (ch == quote)
808 break;
809 else if (bufptr < bufend)
810 *bufptr++ = ch;
811
812 *bufptr = '\0';
813 return (buf);
814 }
815 else if (ch == '#')
816 {
817 /*
818 * Comment...
819 */
820
821 while ((ch = getc(fp)) != EOF)
822 if (ch == '\n')
823 break;
824
825 (*linenum) ++;
826 }
827 else
828 {
829 /*
830 * Whitespace delimited text...
831 */
832
833 ungetc(ch, fp);
834
835 bufptr = buf;
836 bufend = buf + buflen - 1;
837
838 while ((ch = getc(fp)) != EOF)
839 if (isspace(ch) || ch == '#')
840 break;
841 else if (bufptr < bufend)
842 *bufptr++ = ch;
843
844 if (ch == '#')
845 ungetc(ch, fp);
846
847 *bufptr = '\0';
848 return (buf);
849 }
850 }
851}
852
853
854/*
855 * 'print_attr()' - Print an attribute on the screen.
856 */
857
858void
859print_attr(ipp_attribute_t *attr) /* I - Attribute to print */
860{
861 int i; /* Looping var */
862
863
864 if (attr->name == NULL)
865 {
866 puts(" -- separator --");
867 return;
868 }
869
d09495fa 870 printf(" %s (%s%s) = ", attr->name,
871 attr->num_values > 1 ? "1setOf " : "",
872 get_tag_string(attr->value_tag));
ef416fc2 873
874 switch (attr->value_tag)
875 {
876 case IPP_TAG_INTEGER :
877 case IPP_TAG_ENUM :
878 for (i = 0; i < attr->num_values; i ++)
879 printf("%d ", attr->values[i].integer);
880 break;
881
882 case IPP_TAG_BOOLEAN :
883 for (i = 0; i < attr->num_values; i ++)
884 if (attr->values[i].boolean)
885 printf("true ");
886 else
887 printf("false ");
888 break;
889
890 case IPP_TAG_NOVALUE :
891 printf("novalue");
892 break;
893
894 case IPP_TAG_RANGE :
895 for (i = 0; i < attr->num_values; i ++)
896 printf("%d-%d ", attr->values[i].range.lower,
897 attr->values[i].range.upper);
898 break;
899
900 case IPP_TAG_RESOLUTION :
901 for (i = 0; i < attr->num_values; i ++)
902 printf("%dx%d%s ", attr->values[i].resolution.xres,
903 attr->values[i].resolution.yres,
904 attr->values[i].resolution.units == IPP_RES_PER_INCH ?
905 "dpi" : "dpc");
906 break;
907
908 case IPP_TAG_STRING :
909 case IPP_TAG_TEXT :
910 case IPP_TAG_NAME :
911 case IPP_TAG_KEYWORD :
912 case IPP_TAG_CHARSET :
913 case IPP_TAG_URI :
914 case IPP_TAG_MIMETYPE :
915 case IPP_TAG_LANGUAGE :
916 for (i = 0; i < attr->num_values; i ++)
917 printf("\"%s\" ", attr->values[i].string.text);
918 break;
919
920 case IPP_TAG_TEXTLANG :
921 case IPP_TAG_NAMELANG :
922 for (i = 0; i < attr->num_values; i ++)
923 printf("\"%s\",%s ", attr->values[i].string.text,
924 attr->values[i].string.charset);
925 break;
926
927 default :
928 break; /* anti-compiler-warning-code */
929 }
930
931 putchar('\n');
932}
933
934
935/*
e00b005a 936 * 'usage()' - Show program usage.
937 */
938
939void
940usage(const char *option) /* I - Option string or NULL */
941{
942 if (option)
943 fprintf(stderr, "ipptest: Unknown option \"%s\"!\n", option);
944
945 fputs("Usage: ipptest [options] URL testfile [ ... testfileN ]\n", stderr);
946 fputs("Options:\n", stderr);
947 fputs("\n", stderr);
8ca02f3c 948 fputs("-i N Repeat the last test file once every N seconds.\n", stderr);
949 fputs("-v Show all attributes in response, even on success.\n", stderr);
e00b005a 950
951 exit(1);
952}
953
954
955/*
b94498cf 956 * End of "$Id: ipptest.c 6503 2007-05-01 23:06:44Z mike $".
ef416fc2 957 */