📄 ipp.c
字号:
} else if (attr->value_tag != tag && tag != IPP_TAG_END_COLLECTION) return (IPP_ERROR); /* * Finally, reallocate the attribute array as needed... */ if ((attr->num_values % IPP_MAX_VALUES) == 0 && attr->num_values > 0) { ipp_attribute_t *temp, /* Pointer to new buffer */ *ptr; /* Pointer in attribute list */ /* * Reallocate memory... */ if ((temp = realloc(attr, sizeof(ipp_attribute_t) + (attr->num_values + IPP_MAX_VALUES - 1) * sizeof(ipp_value_t))) == NULL) return (IPP_ERROR); /* * Reset pointers in the list... */ for (ptr = ipp->attrs; ptr && ptr->next != attr; ptr = ptr->next); if (ptr) ptr->next = temp; else ipp->attrs = temp; attr = ipp->current = ipp->last = temp; } } else if (tag == IPP_TAG_MEMBERNAME) { /* * Name must be length 0! */ if (n) { DEBUG_puts("ippReadIO: member name not empty!"); return (IPP_ERROR); } attr = ipp->current = _ipp_add_attr(ipp, IPP_MAX_VALUES); attr->group_tag = ipp->curtag; attr->value_tag = IPP_TAG_ZERO; attr->num_values = 0; } else { /* * New attribute; read the name and add it... */ if ((*cb)(src, buffer, n) < n) { DEBUG_puts("ippReadIO: unable to read name!"); return (IPP_ERROR); } buffer[n] = '\0'; DEBUG_printf(("ippReadIO: name = \'%s\'\n", buffer)); attr = ipp->current = _ipp_add_attr(ipp, IPP_MAX_VALUES); attr->group_tag = ipp->curtag; attr->value_tag = tag; attr->name = strdup((char *)buffer); attr->num_values = 0; } value = attr->values + attr->num_values; if ((*cb)(src, buffer, 2) < 2) { DEBUG_puts("ippReadIO: unable to read value length!"); return (IPP_ERROR); } n = (buffer[0] << 8) | buffer[1]; DEBUG_printf(("ippReadIO: value length = %d\n", n)); switch (tag) { case IPP_TAG_INTEGER : case IPP_TAG_ENUM : if ((*cb)(src, buffer, 4) < 4) { DEBUG_puts("ippReadIO: Unable to read integer value!"); return (IPP_ERROR); } n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3]; value->integer = n; break; case IPP_TAG_BOOLEAN : if ((*cb)(src, buffer, 1) < 1) { DEBUG_puts("ippReadIO: Unable to read boolean value!"); return (IPP_ERROR); } value->boolean = buffer[0]; break; case IPP_TAG_TEXT : case IPP_TAG_NAME : case IPP_TAG_KEYWORD : case IPP_TAG_STRING : case IPP_TAG_URI : case IPP_TAG_URISCHEME : case IPP_TAG_CHARSET : case IPP_TAG_LANGUAGE : case IPP_TAG_MIMETYPE : value->string.text = calloc(n + 1, 1); if ((*cb)(src, (ipp_uchar_t *)value->string.text, n) < n) { DEBUG_puts("ippReadIO: Unable to read string value!"); return (IPP_ERROR); } DEBUG_printf(("ippReadIO: value = \'%s\'\n", value->string.text)); break; case IPP_TAG_DATE : if ((*cb)(src, value->date, 11) < 11) { DEBUG_puts("ippReadIO: Unable to date integer value!"); return (IPP_ERROR); } break; case IPP_TAG_RESOLUTION : if ((*cb)(src, buffer, 9) < 9) { DEBUG_puts("ippReadIO: Unable to read resolution value!"); return (IPP_ERROR); } value->resolution.xres = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3]; value->resolution.yres = (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | buffer[7]; value->resolution.units = (ipp_res_t)buffer[8]; break; case IPP_TAG_RANGE : if ((*cb)(src, buffer, 8) < 8) { DEBUG_puts("ippReadIO: Unable to read range value!"); return (IPP_ERROR); } value->range.lower = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | buffer[3]; value->range.upper = (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | buffer[7]; break; case IPP_TAG_TEXTLANG : case IPP_TAG_NAMELANG : if (n > sizeof(buffer) || n < 4) { DEBUG_printf(("ippReadIO: bad value length %d!\n", n)); return (IPP_ERROR); } if ((*cb)(src, buffer, n) < n) { DEBUG_puts("ippReadIO: Unable to read string w/language value!"); return (IPP_ERROR); } bufptr = buffer; /* * text-with-language and name-with-language are composite * values: * * charset-length * charset * text-length * text */ n = (bufptr[0] << 8) | bufptr[1]; value->string.charset = calloc(n + 1, 1); memcpy(value->string.charset, bufptr + 2, n); bufptr += 2 + n; n = (bufptr[0] << 8) | bufptr[1]; value->string.text = calloc(n + 1, 1); memcpy(value->string.text, bufptr + 2, n); break; case IPP_TAG_BEGIN_COLLECTION : /* * Oh, boy, here comes a collection value, so read it... */ value->collection = ippNew(); if (n > 0) { DEBUG_puts("ippReadIO: begCollection tag with value length > 0!"); return (IPP_ERROR); } if (ippReadIO(src, cb, 1, ipp, value->collection) == IPP_ERROR) { DEBUG_puts("ippReadIO: Unable to read collection value!"); return (IPP_ERROR); } break; case IPP_TAG_END_COLLECTION : if (n > 0) { DEBUG_puts("ippReadIO: endCollection tag with value length > 0!"); return (IPP_ERROR); } DEBUG_puts("ippReadIO: endCollection tag..."); return (ipp->state = IPP_DATA); case IPP_TAG_MEMBERNAME : /* * The value the name of the member in the collection, which * we need to carry over... */ attr->name = calloc(n + 1, 1); if ((*cb)(src, (ipp_uchar_t *)attr->name, n) < n) { DEBUG_puts("ippReadIO: Unable to read member name value!"); return (IPP_ERROR); } DEBUG_printf(("ippReadIO: member name = \"%s\"\n", attr->name)); break; default : /* Other unsupported values */ value->unknown.length = n; if (n > 0) { value->unknown.data = malloc(n); if ((*cb)(src, value->unknown.data, n) < n) { DEBUG_puts("ippReadIO: Unable to read unsupported value!"); return (IPP_ERROR); } } else value->unknown.data = NULL; break; } attr->num_values ++; /* * If blocking is disabled, stop here... */ if (!blocking) break; } break; case IPP_DATA : break; default : break; /* anti-compiler-warning-code */ } return (ipp->state);}/* * 'ippTimeToDate()' - Convert from UNIX time to RFC 1903 format. */const ipp_uchar_t * /* O - RFC-1903 date/time data */ippTimeToDate(time_t t) /* I - UNIX time value */{ struct tm *unixdate; /* UNIX unixdate/time info */ static ipp_uchar_t date[11]; /* RFC-1903 date/time data */ /* * RFC-1903 date/time format is: * * Byte(s) Description * ------- ----------- * 0-1 Year (0 to 65535) * 2 Month (1 to 12) * 3 Day (1 to 31) * 4 Hours (0 to 23) * 5 Minutes (0 to 59) * 6 Seconds (0 to 60, 60 = "leap second") * 7 Deciseconds (0 to 9) * 8 +/- UTC * 9 UTC hours (0 to 11) * 10 UTC minutes (0 to 59) */ unixdate = gmtime(&t); unixdate->tm_year += 1900; date[0] = unixdate->tm_year >> 8; date[1] = unixdate->tm_year; date[2] = unixdate->tm_mon + 1; date[3] = unixdate->tm_mday; date[4] = unixdate->tm_hour; date[5] = unixdate->tm_min; date[6] = unixdate->tm_sec; date[7] = 0; date[8] = '+'; date[9] = 0; date[10] = 0; return (date);}/* * 'ippWrite()' - Write data for an IPP request to a HTTP connection. */ipp_state_t /* O - Current state */ippWrite(http_t *http, /* I - HTTP connection */ ipp_t *ipp) /* I - IPP data */{ DEBUG_printf(("ippWrite(%p, %p)\n", http, ipp)); if (http == NULL) return (IPP_ERROR); return (ippWriteIO(http, (ipp_iocb_t)httpWrite, http->blocking, NULL, ipp));}/* * 'ippWriteFile()' - Write data for an IPP request to a file. */ipp_state_t /* O - Current state */ippWriteFile(int fd, /* I - HTTP data */ ipp_t *ipp) /* I - IPP data */{ DEBUG_printf(("ippWriteFile(%d, %p)\n", fd, ipp)); ipp->state = IPP_IDLE; return (ippWriteIO(&fd, (ipp_iocb_t)ipp_write_file, 1, NULL, ipp));}/* * 'ippWriteIO()' - Write data for an IPP request. */ipp_state_t /* O - Current state */ippWriteIO(void *dst, /* I - Destination */ ipp_iocb_t cb, /* I - Write callback function */ int blocking, /* I - Use blocking IO? */ ipp_t *parent, /* I - Parent IPP request */ ipp_t *ipp) /* I - IPP data */{ int i; /* Looping var */ int n; /* Length of data */ unsigned char buffer[32768], /* Data buffer */ *bufptr; /* Pointer into buffer */ ipp_attribute_t *attr; /* Current attribute */ ipp_value_t *value; /* Current value */ DEBUG_printf(("ippWriteIO(%p, %p, %d, %p, %p)\n", dst, cb, blocking, parent, ipp)); if (dst == NULL || ipp == NULL) return (IPP_ERROR); switch (ipp->state) { case IPP_IDLE : ipp->state ++; /* Avoid common problem... */ case IPP_HEADER : if (parent == NULL) { /* * Send the request header: * * Version = 2 bytes * Operation/Status Code = 2 bytes * Request ID = 4 bytes * Total = 8 bytes */ bufptr = buffer; *bufptr++ = ipp->request.any.version[0]; *bufptr++ = ipp->request.any.version[1]; *bufptr++ = ipp->request.any.op_status >> 8; *bufptr++ = ipp->request.any.op_status; *bufptr++ = ipp->request.any.request_id >> 24; *bufptr++ = ipp->request.any.request_id >> 16; *bufptr++ = ipp->request.any.request_id >> 8; *bufptr++ = ipp->request.any.request_id; if ((*cb)(dst, buffer, bufptr - buffer) < 0) { DEBUG_puts("ippWrite: Could not write IPP header..."); return (IPP_ERROR); } } /* * Reset the state engine to point to the first attribute * in the request/response, with no current group. */ ipp->state = IPP_ATTRIBUTE; ipp->current = ipp->attrs; ipp->curtag = IPP_TAG_ZERO; DEBUG_printf(("ippWrite: version=%d.%d\n", buffer[0], buffer[1])); DEBUG_printf(("ippWrite: op_status=%04x\n", ipp->request.any.op_status)); DEBUG_printf(("ippWrite: request_id=%d\n", ipp->request.any.request_id)); /* * If blocking is disabled, stop here... */ if (!blocking) break; case IPP_ATTRIBUTE : while (ipp->current != NULL) { /* * Write this attribute... */ bufptr = buffer; attr = ipp->current; ipp->current = ipp->current->next; if (ipp->curtag != attr->group_tag && parent == NULL) { /* * Send a group tag byte... */ ipp->curtag = attr->group_tag; if (attr->group_tag == IPP_TAG_ZERO) continue; DEBUG_printf(("ippWrite: wrote group tag = %x\n", attr->group_tag)); *bufptr++ = attr->group_tag; } /* * Write the attribute tag and name. The current implementation * does not support the extension value tags above 0x7f, so all * value tags are 1 byte. * * The attribute name length does not include the trailing nul * character in the source string. * * Collection values (parent != NULL) are written differently... */ if (parent == NULL) { /* * Get the length of the attribute name, and make sure it won't * overflow the buffer... */ if ((n = strlen(attr->name)) > (sizeof(buffer) - 4)) return (IPP_ERROR); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -