| /* |
| * "$Id: ipptest.c 5878 2006-08-24 15:55:42Z mike $" |
| * |
| * IPP test command for the Common UNIX Printing System (CUPS). |
| * |
| * Copyright 1997-2006 by Easy Software Products. |
| * |
| * These coded instructions, statements, and computer programs are the |
| * property of Easy Software Products and are protected by Federal |
| * copyright law. Distribution and use rights are outlined in the file |
| * "LICENSE.txt" which should have been included with this file. If this |
| * file is missing or damaged please contact Easy Software Products |
| * at: |
| * |
| * Attn: CUPS Licensing Information |
| * Easy Software Products |
| * 44141 Airport View Drive, Suite 204 |
| * Hollywood, Maryland 20636 USA |
| * |
| * Voice: (301) 373-9600 |
| * EMail: cups-info@cups.org |
| * WWW: http://www.cups.org |
| * |
| * Contents: |
| * |
| * main() - Parse options and do tests. |
| * do_tests() - Do tests as specified in the test file. |
| * get_tag() - Get an IPP value or group tag from a name... |
| * get_token() - Get a token from a file. |
| * print_attr() - Print an attribute on the screen. |
| * usage() - Show program usage. |
| */ |
| |
| /* |
| * Include necessary headers... |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <cups/string.h> |
| #include <errno.h> |
| #include <ctype.h> |
| |
| #include <cups/cups.h> |
| #include <cups/language.h> |
| |
| |
| /* |
| * Globals... |
| */ |
| |
| int Verbosity = 0; /* Show all attributes? */ |
| const char * const TagNames[] = |
| { /* Value/group tag names */ |
| "zero", /* 0x00 */ |
| "operation", /* 0x01 */ |
| "job", /* 0x02 */ |
| "end", /* 0x03 */ |
| "printer", /* 0x04 */ |
| "unsupported-group", /* 0x05 */ |
| "subscription", /* 0x06 */ |
| "event-notification", /* 0x07 */ |
| "", "", "", "", "", "", "", "", |
| "unsupported-value", /* 0x10 */ |
| "default", /* 0x11 */ |
| "unknown", /* 0x12 */ |
| "novalue", /* 0x13 */ |
| "", |
| "notsettable", /* 0x15 */ |
| "deleteattr", /* 0x16 */ |
| "anyvalue", /* 0x17 */ |
| "", "", "", "", "", "", "", "", "", |
| "integer", /* 0x21 */ |
| "boolean", /* 0x22 */ |
| "enum", /* 0x23 */ |
| "", "", "", "", "", "", "", "", "", "", "", "", |
| "string", /* 0x30 */ |
| "date", /* 0x31 */ |
| "resolution", /* 0x32 */ |
| "range", /* 0x33 */ |
| "collection", /* 0x34 */ |
| "textlang", /* 0x35 */ |
| "namelang", /* 0x36 */ |
| "", "", "", "", "", "", "", "", "", "", |
| "text", /* 0x41 */ |
| "name", /* 0x42 */ |
| "", |
| "keyword", /* 0x44 */ |
| "uri", /* 0x45 */ |
| "urischeme", /* 0x46 */ |
| "charset", /* 0x47 */ |
| "language", /* 0x48 */ |
| "mimetype" /* 0x49 */ |
| }; |
| |
| |
| |
| |
| /* |
| * Local functions... |
| */ |
| |
| int do_tests(const char *, const char *); |
| ipp_op_t ippOpValue(const char *); |
| ipp_status_t ippErrorValue(const char *); |
| ipp_tag_t get_tag(const char *); |
| const char *get_tag_string(ipp_tag_t tag); |
| char *get_token(FILE *, char *, int, int *linenum); |
| void print_attr(ipp_attribute_t *); |
| void usage(const char *option); |
| |
| |
| /* |
| * 'main()' - Parse options and do tests. |
| */ |
| |
| int /* O - Exit status */ |
| main(int argc, /* I - Number of command-line arguments */ |
| char *argv[]) /* I - Command-line arguments */ |
| { |
| int i; /* Looping var */ |
| int status; /* Status of tests... */ |
| const char *uri; /* URI to use */ |
| const char *testfile; /* Test file to use */ |
| int interval; /* Test interval */ |
| |
| |
| /* |
| * We need at least: |
| * |
| * testipp URL testfile |
| */ |
| |
| uri = NULL; |
| testfile = NULL; |
| status = 0; |
| interval = 0; |
| |
| for (i = 1; i < argc; i ++) |
| { |
| if (argv[i][0] == '-') |
| { |
| if (!strcmp(argv[i], "-v")) |
| Verbosity ++; |
| else if (!strcmp(argv[i], "-i")) |
| { |
| i++; |
| |
| if (i >= argc) |
| usage(NULL); |
| else |
| interval = atoi(argv[i]); |
| } |
| else |
| usage(argv[i]); |
| } |
| else if (!strncmp(argv[i], "ipp://", 6) || |
| !strncmp(argv[i], "http://", 7) || |
| !strncmp(argv[i], "https://", 8)) |
| { |
| /* |
| * Set URI... |
| */ |
| |
| if (!testfile && uri) |
| usage(NULL); |
| |
| uri = argv[i]; |
| testfile = NULL; |
| } |
| else |
| { |
| /* |
| * Run test... |
| */ |
| |
| testfile = argv[i]; |
| |
| if (!do_tests(uri, testfile)) |
| status ++; |
| } |
| } |
| |
| if (!uri || !testfile) |
| usage(NULL); |
| |
| /* |
| * Loop if the interval is set... |
| */ |
| |
| if (interval) |
| { |
| for (;;) |
| { |
| sleep(interval); |
| do_tests(uri, testfile); |
| } |
| } |
| |
| /* |
| * Exit... |
| */ |
| |
| return (status); |
| } |
| |
| |
| /* |
| * 'do_tests()' - Do tests as specified in the test file. |
| */ |
| |
| int /* 1 = success, 0 = failure */ |
| do_tests(const char *uri, /* I - URI to connect on */ |
| const char *testfile) /* I - Test file to use */ |
| { |
| int i; /* Looping var */ |
| int linenum; /* Current line number */ |
| int version; /* IPP version number to use */ |
| http_t *http; /* HTTP connection to server */ |
| char method[HTTP_MAX_URI], /* URI method */ |
| userpass[HTTP_MAX_URI], /* username:password */ |
| server[HTTP_MAX_URI], /* Server */ |
| resource[HTTP_MAX_URI]; /* Resource path */ |
| int port; /* Port number */ |
| FILE *fp; /* Test file */ |
| char token[1024], /* Token from file */ |
| *tokenptr, /* Pointer into token */ |
| temp[1024], /* Temporary string */ |
| *tempptr; /* Pointer into temp string */ |
| ipp_t *request; /* IPP request */ |
| ipp_t *response; /* IPP response */ |
| ipp_op_t op; /* Operation */ |
| ipp_tag_t group; /* Current group */ |
| ipp_tag_t value; /* Current value type */ |
| ipp_attribute_t *attrptr; /* Attribute pointer */ |
| char attr[128]; /* Attribute name */ |
| int num_statuses; /* Number of valid status codes */ |
| ipp_status_t statuses[100]; /* Valid status codes */ |
| int num_expects; /* Number of expected attributes */ |
| char *expects[100]; /* Expected attributes */ |
| int num_displayed; /* Number of displayed attributes */ |
| char *displayed[100]; /* Displayed attributes */ |
| char name[1024]; /* Name of test */ |
| char filename[1024]; /* Filename */ |
| int pass; /* Did we pass the test? */ |
| int job_id; /* Job ID from last operation */ |
| int subscription_id; /* Subscription ID from last operation */ |
| |
| |
| /* |
| * Open the test file... |
| */ |
| |
| if ((fp = fopen(testfile, "r")) == NULL) |
| { |
| printf("Unable to open test file %s - %s\n", testfile, strerror(errno)); |
| return (0); |
| } |
| |
| /* |
| * Connect to the server... |
| */ |
| |
| httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), userpass, |
| sizeof(userpass), server, sizeof(server), &port, resource, |
| sizeof(resource)); |
| if ((http = httpConnect(server, port)) == NULL) |
| { |
| printf("Unable to connect to %s on port %d - %s\n", server, port, |
| strerror(errno)); |
| return (0); |
| } |
| |
| /* |
| * Loop on tests... |
| */ |
| |
| printf("\"%s\":\n", testfile); |
| pass = 1; |
| job_id = 0; |
| subscription_id = 0; |
| version = 1; |
| linenum = 1; |
| |
| while (get_token(fp, token, sizeof(token), &linenum) != NULL) |
| { |
| /* |
| * Expect an open brace... |
| */ |
| |
| if (strcmp(token, "{")) |
| { |
| printf("Unexpected token %s seen on line %d - aborting test!\n", token, |
| linenum); |
| httpClose(http); |
| return (0); |
| } |
| |
| /* |
| * Initialize things... |
| */ |
| |
| httpSeparateURI(HTTP_URI_CODING_ALL, uri, method, sizeof(method), userpass, |
| sizeof(userpass), server, sizeof(server), &port, resource, |
| sizeof(resource)); |
| |
| request = ippNew(); |
| op = (ipp_op_t)0; |
| group = IPP_TAG_ZERO; |
| value = IPP_TAG_ZERO; |
| num_statuses = 0; |
| num_expects = 0; |
| num_displayed = 0; |
| filename[0] = '\0'; |
| |
| strcpy(name, testfile); |
| if (strrchr(name, '.') != NULL) |
| *strrchr(name, '.') = '\0'; |
| |
| /* |
| * Parse until we see a close brace... |
| */ |
| |
| while (get_token(fp, token, sizeof(token), &linenum) != NULL) |
| { |
| if (!strcmp(token, "}")) |
| break; |
| else if (!strcasecmp(token, "NAME")) |
| { |
| /* |
| * Name of test... |
| */ |
| |
| get_token(fp, name, sizeof(name), &linenum); |
| } |
| else if (!strcasecmp(token, "VERSION")) |
| { |
| /* |
| * IPP version number for test... |
| */ |
| |
| get_token(fp, temp, sizeof(temp), &linenum); |
| sscanf(temp, "%*d.%d", &version); |
| } |
| else if (!strcasecmp(token, "RESOURCE")) |
| { |
| /* |
| * Resource name... |
| */ |
| |
| get_token(fp, resource, sizeof(resource), &linenum); |
| } |
| else if (!strcasecmp(token, "OPERATION")) |
| { |
| /* |
| * Operation... |
| */ |
| |
| get_token(fp, token, sizeof(token), &linenum); |
| op = ippOpValue(token); |
| } |
| else if (!strcasecmp(token, "GROUP")) |
| { |
| /* |
| * Attribute group... |
| */ |
| |
| get_token(fp, token, sizeof(token), &linenum); |
| value = get_tag(token); |
| |
| if (value == group) |
| ippAddSeparator(request); |
| |
| group = value; |
| } |
| else if (!strcasecmp(token, "DELAY")) |
| { |
| /* |
| * Delay before operation... |
| */ |
| |
| int delay; |
| |
| get_token(fp, token, sizeof(token), &linenum); |
| if ((delay = atoi(token)) > 0) |
| sleep(delay); |
| } |
| else if (!strcasecmp(token, "ATTR")) |
| { |
| /* |
| * Attribute... |
| */ |
| |
| get_token(fp, token, sizeof(token), &linenum); |
| value = get_tag(token); |
| get_token(fp, attr, sizeof(attr), &linenum); |
| get_token(fp, temp, sizeof(temp), &linenum); |
| |
| token[sizeof(token) - 1] = '\0'; |
| |
| for (tempptr = temp, tokenptr = token; |
| *tempptr && tokenptr < (token + sizeof(token) - 1);) |
| if (*tempptr == '$') |
| { |
| /* |
| * Substitute a string/number... |
| */ |
| |
| if (!strncasecmp(tempptr + 1, "uri", 3)) |
| { |
| strlcpy(tokenptr, uri, sizeof(token) - (tokenptr - token)); |
| tempptr += 4; |
| } |
| else if (!strncasecmp(tempptr + 1, "method", 6)) |
| { |
| strlcpy(tokenptr, method, sizeof(token) - (tokenptr - token)); |
| tempptr += 7; |
| } |
| else if (!strncasecmp(tempptr + 1, "username", 8)) |
| { |
| strlcpy(tokenptr, userpass, sizeof(token) - (tokenptr - token)); |
| tempptr += 9; |
| } |
| else if (!strncasecmp(tempptr + 1, "hostname", 8)) |
| { |
| strlcpy(tokenptr, server, sizeof(token) - (tokenptr - token)); |
| tempptr += 9; |
| } |
| else if (!strncasecmp(tempptr + 1, "port", 4)) |
| { |
| snprintf(tokenptr, sizeof(token) - (tokenptr - token), |
| "%d", port); |
| tempptr += 5; |
| } |
| else if (!strncasecmp(tempptr + 1, "resource", 8)) |
| { |
| strlcpy(tokenptr, resource, sizeof(token) - (tokenptr - token)); |
| tempptr += 9; |
| } |
| else if (!strncasecmp(tempptr + 1, "job-id", 6)) |
| { |
| snprintf(tokenptr, sizeof(token) - (tokenptr - token), |
| "%d", job_id); |
| tempptr += 7; |
| } |
| else if (!strncasecmp(tempptr + 1, "notify-subscription-id", 22)) |
| { |
| snprintf(tokenptr, sizeof(token) - (tokenptr - token), |
| "%d", subscription_id); |
| tempptr += 23; |
| } |
| else if (!strncasecmp(tempptr + 1, "user", 4)) |
| { |
| strlcpy(tokenptr, cupsUser(), sizeof(token) - (tokenptr - token)); |
| tempptr += 5; |
| } |
| else |
| { |
| *tokenptr++ = *tempptr ++; |
| *tokenptr = '\0'; |
| } |
| |
| tokenptr += strlen(tokenptr); |
| } |
| else |
| { |
| *tokenptr++ = *tempptr++; |
| *tokenptr = '\0'; |
| } |
| |
| switch (value) |
| { |
| case IPP_TAG_BOOLEAN : |
| if (!strcasecmp(token, "true")) |
| ippAddBoolean(request, group, attr, 1); |
| else |
| ippAddBoolean(request, group, attr, atoi(token)); |
| break; |
| |
| case IPP_TAG_INTEGER : |
| case IPP_TAG_ENUM : |
| ippAddInteger(request, group, value, attr, atoi(token)); |
| break; |
| |
| case IPP_TAG_RESOLUTION : |
| puts(" ERROR: resolution tag not yet supported!"); |
| break; |
| |
| case IPP_TAG_RANGE : |
| puts(" ERROR: range tag not yet supported!"); |
| break; |
| |
| default : |
| if (!strchr(token, ',')) |
| ippAddString(request, group, value, attr, NULL, token); |
| else |
| { |
| /* |
| * Multiple string values... |
| */ |
| |
| int num_values; /* Number of values */ |
| char *values[100], /* Values */ |
| *ptr; /* Pointer to next value */ |
| |
| |
| values[0] = token; |
| num_values = 1; |
| |
| for (ptr = strchr(token, ','); ptr; ptr = strchr(ptr, ',')) |
| { |
| *ptr++ = '\0'; |
| values[num_values] = ptr; |
| num_values ++; |
| } |
| |
| ippAddStrings(request, group, value, attr, num_values, |
| NULL, (const char **)values); |
| } |
| break; |
| } |
| } |
| else if (!strcasecmp(token, "FILE")) |
| { |
| /* |
| * File... |
| */ |
| |
| get_token(fp, filename, sizeof(filename), &linenum); |
| } |
| else if (!strcasecmp(token, "STATUS") && |
| num_statuses < (int)(sizeof(statuses) / sizeof(statuses[0]))) |
| { |
| /* |
| * Status... |
| */ |
| |
| get_token(fp, token, sizeof(token), &linenum); |
| statuses[num_statuses] = ippErrorValue(token); |
| num_statuses ++; |
| } |
| else if (!strcasecmp(token, "EXPECT") && |
| num_expects < (int)(sizeof(expects) / sizeof(expects[0]))) |
| { |
| /* |
| * Expected attributes... |
| */ |
| |
| get_token(fp, token, sizeof(token), &linenum); |
| expects[num_expects] = strdup(token); |
| num_expects ++; |
| } |
| else if (!strcasecmp(token, "DISPLAY") && |
| num_displayed < (int)(sizeof(displayed) / sizeof(displayed[0]))) |
| { |
| /* |
| * Display attributes... |
| */ |
| |
| get_token(fp, token, sizeof(token), &linenum); |
| displayed[num_displayed] = strdup(token); |
| num_displayed ++; |
| } |
| else |
| { |
| printf("Unexpected token %s seen on line %d - aborting test!\n", token, |
| linenum); |
| httpClose(http); |
| ippDelete(request); |
| return (0); |
| } |
| } |
| |
| /* |
| * Submit the IPP request... |
| */ |
| |
| request->request.op.version[1] = version; |
| request->request.op.operation_id = op; |
| request->request.op.request_id = 1; |
| |
| if (Verbosity) |
| { |
| printf("%s:\n", ippOpString(op)); |
| |
| for (attrptr = request->attrs; attrptr; attrptr = attrptr->next) |
| print_attr(attrptr); |
| } |
| |
| printf(" %-60.60s [", name); |
| fflush(stdout); |
| |
| if (filename[0]) |
| response = cupsDoFileRequest(http, request, resource, filename); |
| else |
| response = cupsDoRequest(http, request, resource); |
| |
| if (response == NULL) |
| { |
| time_t curtime; |
| |
| curtime = time(NULL); |
| |
| puts("FAIL]"); |
| printf(" ERROR %04x (%s) @ %s\n", cupsLastError(), |
| cupsLastErrorString(), ctime(&curtime)); |
| pass = 0; |
| } |
| else |
| { |
| if ((attrptr = ippFindAttribute(response, "job-id", |
| IPP_TAG_INTEGER)) != NULL) |
| job_id = attrptr->values[0].integer; |
| |
| if ((attrptr = ippFindAttribute(response, "notify-subscription-id", |
| IPP_TAG_INTEGER)) != NULL) |
| subscription_id = attrptr->values[0].integer; |
| |
| for (i = 0; i < num_statuses; i ++) |
| if (response->request.status.status_code == statuses[i]) |
| break; |
| |
| if (i == num_statuses && num_statuses > 0) |
| pass = 0; |
| else |
| { |
| for (i = 0; i < num_expects; i ++) |
| if (ippFindAttribute(response, expects[i], IPP_TAG_ZERO) == NULL) |
| { |
| pass = 0; |
| break; |
| } |
| } |
| |
| if (pass) |
| { |
| puts("PASS]"); |
| printf(" RECEIVED: %lu bytes in response\n", |
| (unsigned long)ippLength(response)); |
| |
| if (Verbosity) |
| { |
| for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next) |
| print_attr(attrptr); |
| } |
| else if (num_displayed > 0) |
| { |
| for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next) |
| if (attrptr->name) |
| { |
| for (i = 0; i < num_displayed; i ++) |
| if (!strcmp(displayed[i], attrptr->name)) |
| { |
| print_attr(attrptr); |
| break; |
| } |
| } |
| } |
| } |
| else |
| { |
| puts("FAIL]"); |
| printf(" RECEIVED: %lu bytes in response\n", |
| (unsigned long)ippLength(response)); |
| |
| for (i = 0; i < num_statuses; i ++) |
| if (response->request.status.status_code == statuses[i]) |
| break; |
| |
| if (i == num_statuses && num_statuses > 0) |
| puts(" BAD STATUS"); |
| |
| printf(" status-code = %04x (%s)\n", |
| cupsLastError(), cupsLastErrorString()); |
| |
| for (i = 0; i < num_expects; i ++) |
| if (ippFindAttribute(response, expects[i], IPP_TAG_ZERO) == NULL) |
| printf(" EXPECTED: %s\n", expects[i]); |
| |
| for (attrptr = response->attrs; attrptr != NULL; attrptr = attrptr->next) |
| print_attr(attrptr); |
| } |
| |
| ippDelete(response); |
| } |
| |
| for (i = 0; i < num_expects; i ++) |
| free(expects[i]); |
| |
| if (!pass) |
| break; |
| } |
| |
| fclose(fp); |
| httpClose(http); |
| |
| return (pass); |
| } |
| |
| |
| /* |
| * 'get_tag()' - Get an IPP value or group tag from a name... |
| */ |
| |
| ipp_tag_t /* O - Value/group tag */ |
| get_tag(const char *name) /* I - Name of value/group tag */ |
| { |
| int i; /* Looping var */ |
| |
| |
| for (i = 0; i < (sizeof(TagNames) / sizeof(TagNames[0])); i ++) |
| if (!strcasecmp(name, TagNames[i])) |
| return ((ipp_tag_t)i); |
| |
| return (IPP_TAG_ZERO); |
| } |
| |
| |
| /* |
| * 'get_tag_string()' - Get the string associated with a tag. |
| */ |
| |
| const char * /* O - Tag name string */ |
| get_tag_string(ipp_tag_t tag) /* I - IPP tag */ |
| { |
| if (tag < (ipp_tag_t)(sizeof(TagNames) / sizeof(TagNames[0]))) |
| return (TagNames[tag]); |
| else |
| return ("UNKNOWN"); |
| } |
| |
| |
| /* |
| * 'get_token()' - Get a token from a file. |
| */ |
| |
| char * /* O - Token from file or NULL on EOF */ |
| get_token(FILE *fp, /* I - File to read from */ |
| char *buf, /* I - Buffer to read into */ |
| int buflen, /* I - Length of buffer */ |
| int *linenum) /* IO - Current line number */ |
| { |
| int ch, /* Character from file */ |
| quote; /* Quoting character */ |
| char *bufptr, /* Pointer into buffer */ |
| *bufend; /* End of buffer */ |
| |
| |
| for (;;) |
| { |
| /* |
| * Skip whitespace... |
| */ |
| |
| while (isspace(ch = getc(fp))) |
| { |
| if (ch == '\n') |
| (*linenum) ++; |
| } |
| |
| /* |
| * Read a token... |
| */ |
| |
| if (ch == EOF) |
| return (NULL); |
| else if (ch == '\'' || ch == '\"') |
| { |
| /* |
| * Quoted text... |
| */ |
| |
| quote = ch; |
| bufptr = buf; |
| bufend = buf + buflen - 1; |
| |
| while ((ch = getc(fp)) != EOF) |
| if (ch == quote) |
| break; |
| else if (bufptr < bufend) |
| *bufptr++ = ch; |
| |
| *bufptr = '\0'; |
| return (buf); |
| } |
| else if (ch == '#') |
| { |
| /* |
| * Comment... |
| */ |
| |
| while ((ch = getc(fp)) != EOF) |
| if (ch == '\n') |
| break; |
| |
| (*linenum) ++; |
| } |
| else |
| { |
| /* |
| * Whitespace delimited text... |
| */ |
| |
| ungetc(ch, fp); |
| |
| bufptr = buf; |
| bufend = buf + buflen - 1; |
| |
| while ((ch = getc(fp)) != EOF) |
| if (isspace(ch) || ch == '#') |
| break; |
| else if (bufptr < bufend) |
| *bufptr++ = ch; |
| |
| if (ch == '#') |
| ungetc(ch, fp); |
| |
| *bufptr = '\0'; |
| return (buf); |
| } |
| } |
| } |
| |
| |
| /* |
| * 'print_attr()' - Print an attribute on the screen. |
| */ |
| |
| void |
| print_attr(ipp_attribute_t *attr) /* I - Attribute to print */ |
| { |
| int i; /* Looping var */ |
| |
| |
| if (attr->name == NULL) |
| { |
| puts(" -- separator --"); |
| return; |
| } |
| |
| printf(" %s (%s%s) = ", attr->name, |
| attr->num_values > 1 ? "1setOf " : "", |
| get_tag_string(attr->value_tag)); |
| |
| switch (attr->value_tag) |
| { |
| case IPP_TAG_INTEGER : |
| case IPP_TAG_ENUM : |
| for (i = 0; i < attr->num_values; i ++) |
| printf("%d ", attr->values[i].integer); |
| break; |
| |
| case IPP_TAG_BOOLEAN : |
| for (i = 0; i < attr->num_values; i ++) |
| if (attr->values[i].boolean) |
| printf("true "); |
| else |
| printf("false "); |
| break; |
| |
| case IPP_TAG_NOVALUE : |
| printf("novalue"); |
| break; |
| |
| case IPP_TAG_RANGE : |
| for (i = 0; i < attr->num_values; i ++) |
| printf("%d-%d ", attr->values[i].range.lower, |
| attr->values[i].range.upper); |
| break; |
| |
| case IPP_TAG_RESOLUTION : |
| for (i = 0; i < attr->num_values; i ++) |
| printf("%dx%d%s ", attr->values[i].resolution.xres, |
| attr->values[i].resolution.yres, |
| attr->values[i].resolution.units == IPP_RES_PER_INCH ? |
| "dpi" : "dpc"); |
| break; |
| |
| case IPP_TAG_STRING : |
| case IPP_TAG_TEXT : |
| case IPP_TAG_NAME : |
| case IPP_TAG_KEYWORD : |
| case IPP_TAG_CHARSET : |
| case IPP_TAG_URI : |
| case IPP_TAG_MIMETYPE : |
| case IPP_TAG_LANGUAGE : |
| for (i = 0; i < attr->num_values; i ++) |
| printf("\"%s\" ", attr->values[i].string.text); |
| break; |
| |
| case IPP_TAG_TEXTLANG : |
| case IPP_TAG_NAMELANG : |
| for (i = 0; i < attr->num_values; i ++) |
| printf("\"%s\",%s ", attr->values[i].string.text, |
| attr->values[i].string.charset); |
| break; |
| |
| default : |
| break; /* anti-compiler-warning-code */ |
| } |
| |
| putchar('\n'); |
| } |
| |
| |
| /* |
| * 'usage()' - Show program usage. |
| */ |
| |
| void |
| usage(const char *option) /* I - Option string or NULL */ |
| { |
| if (option) |
| fprintf(stderr, "ipptest: Unknown option \"%s\"!\n", option); |
| |
| fputs("Usage: ipptest [options] URL testfile [ ... testfileN ]\n", stderr); |
| fputs("Options:\n", stderr); |
| fputs("\n", stderr); |
| fputs("-i N Repeat the last test file once every N seconds.\n", stderr); |
| fputs("-v Show all attributes in response, even on success.\n", stderr); |
| |
| exit(1); |
| } |
| |
| |
| /* |
| * End of "$Id: ipptest.c 5878 2006-08-24 15:55:42Z mike $". |
| */ |