]>
git.ipfire.org Git - thirdparty/cups.git/blob - test/ipptest.c
2 * "$Id: ipptest.c,v 1.9 2002/01/02 17:59:20 mike Exp $"
4 * IPP test command for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2002 by Easy Software Products.
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
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * main() - Parse options and do tests.
27 * do_tests() - Do tests as specified in the test file.
28 * get_operation() - Get an IPP opcode from an operation name...
29 * get_status() - Get an IPP status from a status name...
30 * get_tag() - Get an IPP value or group tag from a name...
31 * get_token() - Get a token from a file.
32 * print_attr() - Print an attribute on the screen.
36 * Include necessary headers...
41 #include <cups/string.h>
45 #include <cups/cups.h>
46 #include <cups/language.h>
58 int do_tests(const char *, const char *);
59 ipp_op_t
get_operation(const char *);
60 ipp_status_t
get_status(const char *);
61 ipp_tag_t
get_tag(const char *);
62 char *get_token(FILE *, char *, int);
63 void print_attr(ipp_attribute_t
*);
67 * 'main()' - Parse options and do tests.
70 int /* O - Exit status */
71 main(int argc
, /* I - Number of command-line arguments */
72 char *argv
[]) /* I - Command-line arguments */
74 int i
; /* Looping var */
75 int status
; /* Status of tests... */
81 * testipp URL testfile
86 fputs("Usage: testipp URL testfile [ ... testfileN ]\n", stderr
);
94 for (i
= 2, status
= 1; status
&& i
< argc
; i
++)
95 status
= status
&& do_tests(argv
[1], argv
[i
]);
106 * 'do_tests()' - Do tests as specified in the test file.
109 int /* 1 = success, 0 = failure */
110 do_tests(const char *uri
, /* I - URI to connect on */
111 const char *testfile
) /* I - Test file to use */
113 int i
; /* Looping var */
114 http_t
*http
; /* HTTP connection to server */
115 char method
[HTTP_MAX_URI
], /* URI method */
116 userpass
[HTTP_MAX_URI
], /* username:password */
117 server
[HTTP_MAX_URI
], /* Server */
118 resource
[HTTP_MAX_URI
]; /* Resource path */
119 int port
; /* Port number */
120 FILE *fp
; /* Test file */
121 char token
[1024], /* Token from file */
122 *tokenptr
, /* Pointer into token */
123 temp
[1024], /* Temporary string */
124 *tempptr
; /* Pointer into temp string */
125 ipp_t
*request
; /* IPP request */
126 ipp_t
*response
; /* IPP response */
127 ipp_op_t op
; /* Operation */
128 ipp_tag_t group
; /* Current group */
129 ipp_tag_t value
; /* Current value type */
130 ipp_attribute_t
*attrptr
; /* Attribute pointer */
131 char attr
[128]; /* Attribute name */
132 int num_statuses
; /* Number of valid status codes */
133 ipp_status_t statuses
[100]; /* Valid status codes */
134 int num_expects
; /* Number of expected attributes */
135 char *expects
[100]; /* Expected attributes */
136 char name
[1024]; /* Name of test */
137 char filename
[1024]; /* Filename */
138 int pass
; /* Did we pass the test? */
139 int job_id
; /* Job ID from last operation */
143 * Open the test file...
146 if ((fp
= fopen(testfile
, "r")) == NULL
)
148 printf("Unable to open test file %s - %s\n", testfile
, strerror(errno
));
153 * Connect to the server...
156 httpSeparate(uri
, method
, userpass
, server
, &port
, resource
);
157 if ((http
= httpConnect(server
, port
)) == NULL
)
159 printf("Unable to connect to %s on port %d - %s\n", server
, port
,
168 printf("\"%s\":\n", testfile
);
172 while (get_token(fp
, token
, sizeof(token
)) != NULL
)
175 * Expect an open brace...
178 if (strcmp(token
, "{") != 0)
180 printf("Unexpected token %s seen - aborting test!\n", token
);
186 * Initialize things...
189 httpSeparate(uri
, method
, userpass
, server
, &port
, resource
);
193 group
= IPP_TAG_OPERATION
;
194 value
= IPP_TAG_ZERO
;
199 strcpy(name
, testfile
);
200 if (strrchr(name
, '.') != NULL
)
201 *strrchr(name
, '.') = '\0';
204 * Parse until we see a close brace...
207 while (get_token(fp
, token
, sizeof(token
)) != NULL
)
209 if (strcmp(token
, "}") == 0)
211 else if (strcasecmp(token
, "NAME") == 0)
217 get_token(fp
, name
, sizeof(name
));
219 else if (strcasecmp(token
, "RESOURCE") == 0)
225 get_token(fp
, resource
, sizeof(resource
));
227 else if (strcasecmp(token
, "OPERATION") == 0)
233 get_token(fp
, token
, sizeof(token
));
234 op
= get_operation(token
);
236 else if (strcasecmp(token
, "GROUP") == 0)
242 get_token(fp
, token
, sizeof(token
));
243 group
= get_tag(token
);
245 else if (strcasecmp(token
, "ATTR") == 0)
251 get_token(fp
, token
, sizeof(token
));
252 value
= get_tag(token
);
253 get_token(fp
, attr
, sizeof(attr
));
254 get_token(fp
, temp
, sizeof(temp
));
256 token
[sizeof(token
) - 1] = '\0';
258 for (tempptr
= temp
, tokenptr
= token
;
259 *tempptr
&& tokenptr
< (token
+ sizeof(token
) - 1);)
263 * Substitute a string/number...
266 if (strncasecmp(tempptr
+ 1, "uri", 3) == 0)
268 strncpy(tokenptr
, uri
, sizeof(token
) - 1 - (tokenptr
- token
));
271 else if (strncasecmp(tempptr
+ 1, "method", 6) == 0)
273 strncpy(tokenptr
, method
, sizeof(token
) - 1 - (tokenptr
- token
));
276 else if (strncasecmp(tempptr
+ 1, "username", 8) == 0)
278 strncpy(tokenptr
, userpass
, sizeof(token
) - 1 - (tokenptr
- token
));
281 else if (strncasecmp(tempptr
+ 1, "hostname", 8) == 0)
283 strncpy(tokenptr
, server
, sizeof(token
) - 1 - (tokenptr
- token
));
286 else if (strncasecmp(tempptr
+ 1, "port", 4) == 0)
288 snprintf(tokenptr
, sizeof(token
) - 1 - (tokenptr
- token
),
292 else if (strncasecmp(tempptr
+ 1, "resource", 8) == 0)
294 strncpy(tokenptr
, resource
, sizeof(token
) - 1 - (tokenptr
- token
));
297 else if (strncasecmp(tempptr
+ 1, "job-id", 6) == 0)
299 snprintf(tokenptr
, sizeof(token
) - 1 - (tokenptr
- token
),
303 else if (strncasecmp(tempptr
+ 1, "user", 4) == 0)
305 strncpy(tokenptr
, cupsUser(), sizeof(token
) - 1 - (tokenptr
- token
));
310 *tokenptr
++ = *tempptr
++;
314 tokenptr
+= strlen(tokenptr
);
318 *tokenptr
++ = *tempptr
++;
324 case IPP_TAG_BOOLEAN
:
325 if (strcasecmp(token
, "true") == 0)
326 ippAddBoolean(request
, group
, attr
, 1);
328 ippAddBoolean(request
, group
, attr
, atoi(token
));
331 case IPP_TAG_INTEGER
:
333 ippAddInteger(request
, group
, value
, attr
, atoi(token
));
336 case IPP_TAG_RESOLUTION
:
337 puts(" ERROR: resolution tag not yet supported!");
341 puts(" ERROR: range tag not yet supported!");
345 ippAddString(request
, group
, value
, attr
, NULL
, token
);
349 else if (strcasecmp(token
, "FILE") == 0)
355 get_token(fp
, filename
, sizeof(filename
));
357 else if (strcasecmp(token
, "STATUS") == 0)
363 get_token(fp
, token
, sizeof(token
));
364 statuses
[num_statuses
] = get_status(token
);
367 else if (strcasecmp(token
, "EXPECT") == 0)
373 get_token(fp
, token
, sizeof(token
));
374 expects
[num_expects
] = strdup(token
);
379 printf("Unexpected token %s seen - aborting test!\n", token
);
387 * Submit the IPP request...
390 request
->request
.op
.operation_id
= op
;
391 request
->request
.op
.request_id
= 1;
393 printf(" %-60.60s [ ]", name
);
397 response
= cupsDoFileRequest(http
, request
, resource
, filename
);
399 response
= cupsDoRequest(http
, request
, resource
);
401 if (response
== NULL
)
403 printf("\b\b\b\b\bFAIL]\n");
404 printf(" ERROR %x\n", cupsLastError());
406 ippErrorString(cupsLastError()));
411 if ((attrptr
= ippFindAttribute(response
, "job-id", IPP_TAG_INTEGER
)) != NULL
)
412 job_id
= attrptr
->values
[0].integer
;
414 for (i
= 0; i
< num_statuses
; i
++)
415 if (response
->request
.status
.status_code
== statuses
[i
])
418 if (i
== num_statuses
&& num_statuses
> 0)
420 printf("\b\b\b\b\bFAIL]\n");
421 printf(" STATUS %x\n", response
->request
.status
.status_code
);
423 ippErrorString(response
->request
.status
.status_code
));
424 printf(" (%d bytes in response)\n", ippLength(response
));
430 for (i
= 0; i
< num_expects
; i
++)
431 if (ippFindAttribute(response
, expects
[i
], IPP_TAG_ZERO
) == NULL
)
435 printf("\b\b\b\b\bFAIL]\n");
436 printf(" (%d bytes in response)\n", ippLength(response
));
440 printf(" EXPECTED %s\n", expects
[i
]);
445 printf("\b\b\b\b\bPASS]\n");
446 printf(" (%d bytes in response)\n", ippLength(response
));
451 for (attrptr
= response
->attrs
; attrptr
!= NULL
; attrptr
= attrptr
->next
)
459 for (i
= 0; i
< num_expects
; i
++)
474 * 'get_operation()' - Get an IPP opcode from an operation name...
478 get_operation(const char *name
)
481 static char *ipp_ops
[] =
492 "get-job-attributes",
494 "get-printer-attributes",
502 "set-printer-attributes",
503 "set-job-attributes",
504 "get-printer-supported-values"
511 "cups-delete-printer",
524 for (i
= 0; i
< (sizeof(ipp_ops
) / sizeof(ipp_ops
[0])); i
++)
525 if (strcasecmp(name
, ipp_ops
[i
]) == 0)
526 return ((ipp_op_t
)i
);
528 for (i
= 0; i
< (sizeof(cups_ops
) / sizeof(cups_ops
[0])); i
++)
529 if (strcasecmp(name
, cups_ops
[i
]) == 0)
530 return ((ipp_op_t
)(i
+ 0x4001));
532 return ((ipp_op_t
)0);
537 * 'get_status()' - Get an IPP status from a status name...
541 get_status(const char *name
)
544 static const char *status_oks
[] = /* "OK" status codes */
547 "successful-ok-ignored-or-substituted-attributes",
548 "successful-ok-conflicting-attributes"
550 *status_400s
[] = /* Client errors */
552 "client-error-bad-request",
553 "client-error-forbidden",
554 "client-error-not-authenticated",
555 "client-error-not-authorized",
556 "client-error-not-possible",
557 "client-error-timeout",
558 "client-error-not-found",
560 "client-error-request-entity-too-large",
561 "client-error-request-value-too-long",
562 "client-error-document-format-not-supported",
563 "client-error-attributes-or-values-not-supported",
564 "client-error-uri-scheme-not-supported",
565 "client-error-charset-not-supported",
566 "client-error-conflicting-attributes",
567 "client-error-compression-not-supported",
568 "client-error-compression-error",
569 "client-error-document-format-error",
570 "client-error-document-access-error"
572 *status_500s
[] = /* Server errors */
574 "server-error-internal-error",
575 "server-error-operation-not-supported",
576 "server-error-service-unavailable",
577 "server-error-version-not-supported",
578 "server-error-device-error",
579 "server-error-temporary-error",
580 "server-error-not-accepting-jobs",
582 "server-error-job-canceled",
583 "server-error-multiple-document-jobs-not-supported"
587 for (i
= 0; i
< (sizeof(status_oks
) / sizeof(status_oks
[0])); i
++)
588 if (strcasecmp(name
, status_oks
[i
]) == 0)
589 return ((ipp_status_t
)i
);
591 for (i
= 0; i
< (sizeof(status_400s
) / sizeof(status_400s
[0])); i
++)
592 if (strcasecmp(name
, status_400s
[i
]) == 0)
593 return ((ipp_status_t
)(i
+ 0x400));
595 for (i
= 0; i
< (sizeof(status_500s
) / sizeof(status_500s
[0])); i
++)
596 if (strcasecmp(name
, status_500s
[i
]) == 0)
597 return ((ipp_status_t
)(i
+ 0x500));
599 return ((ipp_status_t
)-1);
604 * 'get_tag()' - Get an IPP value or group tag from a name...
608 get_tag(const char *name
)
611 static char *names
[] =
613 "zero", "operation", "job", "end", "printer",
614 "unsupported-group", "", "", "", "", "", "", "",
615 "", "", "", "unsupported-value", "default",
616 "unknown", "novalue", "", "notsettable",
617 "deleteattr", "anyvalue", "", "", "", "", "", "",
618 "", "", "", "integer", "boolean", "enum", "", "",
619 "", "", "", "", "", "", "", "", "", "", "string",
620 "date", "resolution", "range", "collection",
621 "textlang", "namelang", "", "", "", "", "", "", "",
622 "", "", "", "text", "name", "", "keyword", "uri",
623 "urischeme", "charset", "language", "mimetype"
627 for (i
= 0; i
< (sizeof(names
) / sizeof(names
[0])); i
++)
628 if (strcasecmp(name
, names
[i
]) == 0)
629 return ((ipp_tag_t
)i
);
631 return (IPP_TAG_ZERO
);
636 * 'get_token()' - Get a token from a file.
639 char * /* O - Token from file or NULL on EOF */
640 get_token(FILE *fp
, /* I - File to read from */
641 char *buf
, /* I - Buffer to read into */
642 int buflen
) /* I - Length of buffer */
644 int ch
, /* Character from file */
645 quote
; /* Quoting character */
646 char *bufptr
, /* Pointer into buffer */
647 *bufend
; /* End of buffer */
656 while (isspace(ch
= getc(fp
)));
664 else if (ch
== '\'' || ch
== '\"')
672 bufend
= buf
+ buflen
- 1;
674 while ((ch
= getc(fp
)) != EOF
)
677 else if (bufptr
< bufend
)
689 while ((ch
= getc(fp
)) != EOF
)
696 * Whitespace delimited text...
702 bufend
= buf
+ buflen
- 1;
704 while ((ch
= getc(fp
)) != EOF
)
705 if (isspace(ch
) || ch
== '#')
707 else if (bufptr
< bufend
)
721 * 'print_attr()' - Print an attribute on the screen.
725 print_attr(ipp_attribute_t
*attr
) /* I - Attribute to print */
727 int i
; /* Looping var */
730 if (attr
->name
== NULL
)
732 puts(" -- separator --");
736 printf(" %s = ", attr
->name
);
738 switch (attr
->value_tag
)
740 case IPP_TAG_INTEGER
:
742 for (i
= 0; i
< attr
->num_values
; i
++)
743 printf("%d ", attr
->values
[i
].integer
);
746 case IPP_TAG_BOOLEAN
:
747 for (i
= 0; i
< attr
->num_values
; i
++)
748 if (attr
->values
[i
].boolean
)
754 case IPP_TAG_NOVALUE
:
759 for (i
= 0; i
< attr
->num_values
; i
++)
760 printf("%d-%d ", attr
->values
[i
].range
.lower
,
761 attr
->values
[i
].range
.upper
);
764 case IPP_TAG_RESOLUTION
:
765 for (i
= 0; i
< attr
->num_values
; i
++)
766 printf("%dx%d%s ", attr
->values
[i
].resolution
.xres
,
767 attr
->values
[i
].resolution
.yres
,
768 attr
->values
[i
].resolution
.units
== IPP_RES_PER_INCH
?
772 case IPP_TAG_STRING
:
775 case IPP_TAG_KEYWORD
:
776 case IPP_TAG_CHARSET
:
778 case IPP_TAG_MIMETYPE
:
779 case IPP_TAG_LANGUAGE
:
780 for (i
= 0; i
< attr
->num_values
; i
++)
781 printf("\"%s\" ", attr
->values
[i
].string
.text
);
784 case IPP_TAG_TEXTLANG
:
785 case IPP_TAG_NAMELANG
:
786 for (i
= 0; i
< attr
->num_values
; i
++)
787 printf("\"%s\",%s ", attr
->values
[i
].string
.text
,
788 attr
->values
[i
].string
.charset
);
792 break; /* anti-compiler-warning-code */
800 * End of "$Id: ipptest.c,v 1.9 2002/01/02 17:59:20 mike Exp $".