octstr.c.debug
上传用户:gzpyjq
上传日期:2013-01-31
资源大小:1852k
文件大小:47k
源码类别:

手机WAP编程

开发平台:

WINDOWS

  1. /*
  2.  * octstr.c - implementation of Octet strings
  3.  *
  4.  * See octstr.h for explanations of what public functions should do.
  5.  *
  6.  * Lars Wirzenius
  7.  */
  8. #include <ctype.h>
  9. #include <limits.h>
  10. #include <errno.h>
  11. #include <stdlib.h>
  12. #include <string.h>
  13. #include <unistd.h>
  14. #include <sys/types.h>
  15. #include <sys/socket.h>
  16. #include <netinet/in.h>
  17. #include "gwlib.h"
  18. /***********************************************************************
  19.  * Definitions of data structures. These are not visible to the external
  20.  * world -- they may be accessed only via the functions declared in
  21.  * octstr.h. This ensures they really are abstract.
  22.  */
  23. /*
  24.  * The octet string.
  25.  *
  26.  * `data' is a pointer to dynamically allocated memory are where the 
  27.  * octets in the string. It may be bigger than the actual length of the
  28.  * string.
  29.  *
  30.  * `len' is the length of the string.
  31.  *
  32.  * `size' is the size of the memory area `data' points at.
  33.  *
  34.  * When `size' is greater than zero, it is at least `len+1', and the
  35.  * character at `len' is ''. This is so that octstr_get_cstr will
  36.  * always work.
  37.  *
  38.  * `immutable' defines whether the octet string is immutable or not.
  39.  */
  40. struct Octstr
  41. {
  42.     unsigned char *data;
  43.     long len;
  44.     long size;
  45.     int immutable;
  46. };
  47. /**********************************************************************
  48.  * Hash table of immutable octet strings.
  49.  */
  50. #define MAX_IMMUTABLES 1024
  51. static Octstr *immutables[MAX_IMMUTABLES];
  52. static Mutex immutables_mutex;
  53. static int immutables_init = 0;
  54. static char is_safe[UCHAR_MAX + 1];
  55. /*
  56.  * Convert a pointer to a C string literal to a long that can be used
  57.  * for hashing. This is done by converting the pointer into an integer
  58.  * and discarding the lowest to bits to get rid of typical alignment
  59.  * bits.
  60.  */
  61. #define CSTR_TO_LONG(ptr) (((long) ptr) >> 2)
  62. /***********************************************************************
  63.  * Declarations of internal functions. These are defined at the end of
  64.  * the file.
  65.  */
  66. static void seems_valid_real(Octstr *ostr, const char *filename, long lineno,
  67.                              const char *function);
  68. #ifdef NO_GWASSERT
  69. #define seems_valid(ostr)
  70. #else
  71. #define seems_valid(ostr) 
  72.     (seems_valid_real(ostr, __FILE__, __LINE__, __func__))
  73. #endif
  74. /***********************************************************************
  75.  * Implementations of the functions declared in octstr.h. See the
  76.  * header for explanations of what they should do.
  77.  */
  78. /* Reserve space for at least 'size' octets */
  79. static void octstr_grow(Octstr *ostr, long size)
  80. {
  81.     gw_assert(!ostr->immutable);
  82.     seems_valid(ostr);
  83.     gw_assert(size >= 0);
  84.     size++;   /* make room for the invisible terminating NUL */
  85.     if (size > ostr->size) {
  86.         ostr->data = gw_realloc(ostr->data, size);
  87.         ostr->size = size;
  88.     }
  89. }
  90. /*
  91.  * Fill is_safe table. is_safe[c] means that c can be left as such when
  92.  * url-encoded.
  93.  * RFC 2396 defines the list of characters that need to be encoded.
  94.  * Space is treated as an exception by the encoding routine;
  95.  * it's listed as safe here, but is actually changed to '+'.
  96.  */
  97. static void urlcode_init(void)
  98. {
  99.     int i;
  100.     unsigned char *safe = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  101. "abcdefghijklmnopqrstuvwxyz-_.!~*'()";
  102.     for (i = 0; safe[i] != ''; ++i)
  103. is_safe[safe[i]] = 1;
  104. }
  105. void octstr_init(void)
  106. {
  107.     urlcode_init();
  108.     mutex_init_static(&immutables_mutex);
  109.     immutables_init = 1;
  110. }
  111. void octstr_shutdown(void)
  112. {
  113.     long i, n;
  114.     n = 0;
  115.     for (i = 0; i < MAX_IMMUTABLES; ++i) {
  116.         if (immutables[i] != NULL) {
  117.     gw_free(immutables[i]);
  118.             ++n;
  119.         }
  120.     }
  121.     debug("gwlib.octstr", 0, "Immutable octet strings: %ld.", n);
  122.     mutex_destroy(&immutables_mutex);
  123. }
  124. Octstr *octstr_create_real(const char *cstr)
  125. {
  126.     gw_assert(cstr != NULL);
  127.     return octstr_create_from_data(cstr, strlen(cstr));
  128. }
  129. Octstr *octstr_create_from_data_real(const char *data, long len)
  130. {
  131.     Octstr *ostr;
  132.     gw_assert(len >= 0);
  133.     if (data == NULL)
  134.         gw_assert(len == 0);
  135.     ostr = gw_malloc(sizeof(*ostr));
  136.     if (len == 0) {
  137.         ostr->len = 0;
  138.         ostr->size = 0;
  139.         ostr->data = NULL;
  140.     } else {
  141.         ostr->len = len;
  142.         ostr->size = len + 1;
  143.         ostr->data = gw_malloc(ostr->size);
  144.         memcpy(ostr->data, data, len);
  145.         ostr->data[len] = '';
  146.     }
  147.     ostr->immutable = 0;
  148.     seems_valid(ostr);
  149.     return ostr;
  150. }
  151. Octstr *octstr_imm(const char *cstr)
  152. {
  153.     Octstr *os;
  154.     long i, index;
  155.     unsigned char *data;
  156.     gw_assert(immutables_init);
  157.     gw_assert(cstr != NULL);
  158.     index = CSTR_TO_LONG(cstr) % MAX_IMMUTABLES;
  159.     data = (unsigned char *) cstr;
  160.     mutex_lock(&immutables_mutex);
  161.     i = index;
  162.     for (; ; ) {
  163. if (immutables[i] == NULL || immutables[i]->data == data)
  164.             break;
  165.         i = (i + 1) % MAX_IMMUTABLES;
  166.         if (i == index)
  167.             panic(0, "Too many immutable strings.");
  168.     }
  169.     os = immutables[i];
  170.     if (os == NULL) {
  171. /*
  172.  * Can't use octstr_create() because it copies the string,
  173.  * which would break our hashing.
  174.  */
  175. os = gw_malloc(sizeof(*os));
  176.         os->data = data;
  177.         os->len = strlen(data);
  178.         os->size = os->len + 1;
  179.         os->immutable = 1;
  180. immutables[i] = os;
  181. seems_valid(os);
  182.     }
  183.     mutex_unlock(&immutables_mutex);
  184.     return os;
  185. }
  186. void octstr_destroy_impl(Octstr *ostr, const char *file,
  187.  long line, const char *func)
  188. {
  189.     if (ostr != NULL) {
  190. seems_valid_real(ostr, file, line, func);
  191. if (!ostr->immutable) {
  192.             gw_free(ostr->data);
  193.             gw_free(ostr);
  194.         }
  195.     }
  196. }
  197. void octstr_destroy_item(void *os)
  198. {
  199.     octstr_destroy(os);
  200. }
  201. long octstr_len(Octstr *ostr)
  202. {
  203.     if (ostr == NULL)
  204.         return 0;
  205.     seems_valid(ostr);
  206.     return ostr->len;
  207. }
  208. Octstr *octstr_copy_real(Octstr *ostr, long from, long len)
  209. {
  210.     seems_valid(ostr);
  211.     gw_assert(from >= 0);
  212.     gw_assert(len >= 0);
  213.     if (from >= ostr->len)
  214.         return octstr_create("");
  215.     if (len > ostr->len - from)
  216.         len = ostr->len - from;
  217.     return octstr_create_from_data(ostr->data + from, len);
  218. }
  219. Octstr *octstr_duplicate_real(Octstr *ostr)
  220. {
  221.     if (ostr == NULL)
  222.         return NULL;
  223.     seems_valid(ostr);
  224.     return octstr_create_from_data(ostr->data, ostr->len);
  225. }
  226. Octstr *octstr_cat(Octstr *ostr1, Octstr *ostr2)
  227. {
  228.     Octstr *ostr;
  229.     seems_valid(ostr1);
  230.     seems_valid(ostr2);
  231.     gw_assert(!ostr1->immutable);
  232.     ostr = octstr_create("");
  233.     ostr->len = ostr1->len + ostr2->len;
  234.     ostr->size = ostr->len + 1;
  235.     ostr->data = gw_malloc(ostr->size);
  236.     if (ostr1->len > 0)
  237.         memcpy(ostr->data, ostr1->data, ostr1->len);
  238.     if (ostr2->len > 0)
  239.         memcpy(ostr->data + ostr1->len, ostr2->data, ostr2->len);
  240.     ostr->data[ostr->len] = '';
  241.     seems_valid(ostr);
  242.     return ostr;
  243. }
  244. int octstr_get_char(Octstr *ostr, long pos)
  245. {
  246.     seems_valid(ostr);
  247.     if (pos >= ostr->len || pos < 0)
  248.         return -1;
  249.     return ostr->data[pos];
  250. }
  251. void octstr_set_char(Octstr *ostr, long pos, int ch)
  252. {
  253.     seems_valid(ostr);
  254.     gw_assert(!ostr->immutable);
  255.     if (pos < ostr->len)
  256.         ostr->data[pos] = ch;
  257.     seems_valid(ostr);
  258. }
  259. void octstr_get_many_chars(char *buf, Octstr *ostr, long pos, long len)
  260. {
  261.     gw_assert(buf != NULL);
  262.     seems_valid(ostr);
  263.     if (pos >= ostr->len)
  264.         return;
  265.     if (pos + len > ostr->len)
  266.         len = ostr->len - pos;
  267.     if (len > 0)
  268.         memcpy(buf, ostr->data + pos, len);
  269. }
  270. char *octstr_get_cstr_real(Octstr *ostr, const char *file, long line, 
  271.                   const char *func)
  272. {
  273.     seems_valid_real(ostr, file, line, func);
  274.     if (ostr->len == 0)
  275.         return "";
  276.     return ostr->data;
  277. }
  278. void octstr_append_from_hex(Octstr *ostr, char *hex)
  279. {
  280.     Octstr *output;
  281.     seems_valid(ostr);
  282.     gw_assert(!ostr->immutable);
  283.     output = octstr_create(hex);
  284.     octstr_hex_to_binary(output);
  285.     octstr_append(ostr, output);
  286.     octstr_destroy(output);
  287. }
  288. void octstr_binary_to_hex(Octstr *ostr, int uppercase)
  289. {
  290.     unsigned char *hexits;
  291.     long i;
  292.     seems_valid(ostr);
  293.     gw_assert(!ostr->immutable);
  294.     if (ostr->len == 0)
  295.         return;
  296.     hexits = uppercase ? "0123456789ABCDEF" : "0123456789abcdef";
  297.     octstr_grow(ostr, ostr->len * 2);
  298.     /* In-place modification must be done back-to-front to avoid
  299.      * overwriting the data while we read it.  Even the order of
  300.      * the two assignments is important, to get i == 0 right. */
  301.     for (i = ostr->len - 1; i >= 0; i--) {
  302.         ostr->data[i * 2 + 1] = hexits[ostr->data[i] % 16];
  303.         ostr->data[i * 2] = hexits[(ostr->data[i] / 16) & 0xf];
  304.     }
  305.     ostr->len = ostr->len * 2;
  306.     ostr->data[ostr->len] = '';
  307.     seems_valid(ostr);
  308. }
  309. int octstr_hex_to_binary(Octstr *ostr)
  310. {
  311.     long len, i;
  312.     unsigned char *p;
  313.     seems_valid(ostr);
  314.     gw_assert(!ostr->immutable);
  315.     if (ostr->len == 0)
  316.         return 0;
  317.     /* Check if it's in the right format */
  318.     if (!octstr_check_range(ostr, 0, ostr->len, gw_isxdigit))
  319.         return -1;
  320.     len = ostr->len;
  321.     /* Convert ascii data to binary values */
  322.     for (i = 0, p = ostr->data; i < len; i++, p++) {
  323.         if (*p >= '0' && *p <= '9')
  324.             *p -= '0';
  325.         else if (*p >= 'a' && *p <= 'f')
  326.             *p = *p - 'a' + 10;
  327.         else if (*p >= 'A' && *p <= 'F')
  328.             *p = *p - 'A' + 10;
  329.         else {
  330.             /* isxdigit checked the whole string, so we should
  331.              * not be able to get here. */
  332.             gw_assert(0);
  333.             *p = 0;
  334.         }
  335.     }
  336.     /* De-hexing will compress data by factor of 2 */
  337.     len = ostr->len / 2;
  338.     for (i = 0; i < len; i++) {
  339.         ostr->data[i] = ostr->data[i * 2] * 16 | ostr->data[i * 2 + 1];
  340.     }
  341.     ostr->len = len;
  342.     ostr->data[len] = '';
  343.     seems_valid(ostr);
  344.     return 0;
  345. }
  346. void octstr_binary_to_base64(Octstr *ostr)
  347. {
  348.     static const unsigned char base64[64] =
  349.         "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  350.     long triplets;
  351.     long lines;
  352.     long orig_len;
  353.     unsigned char *data;
  354.     long from, to;
  355.     int left_on_line;
  356.     seems_valid(ostr);
  357.     gw_assert(!ostr->immutable);
  358.     if (ostr->len == 0) {
  359.         /* Always terminate with CR LF */
  360.         octstr_insert(ostr, octstr_imm("1512"), 0);
  361.         return;
  362.     }
  363.     /* The lines must be 76 characters each (or less), and each
  364.      * triplet will expand to 4 characters, so we can fit 19
  365.      * triplets on one line.  We need a CR LF after each line,
  366.      * which will add 2 octets per 19 triplets (rounded up). */
  367.     triplets = (ostr->len + 2) / 3;   /* round up */
  368.     lines = (triplets + 18) / 19;
  369.     octstr_grow(ostr, triplets * 4 + lines * 2);
  370.     orig_len = ostr->len;
  371.     data = ostr->data;
  372.     ostr->len = triplets * 4 + lines * 2;
  373.     data[ostr->len] = '';
  374.     /* This function works back-to-front, so that encoded data will
  375.      * not overwrite source data.
  376.      * from points to the start of the last triplet (which may be
  377.      * an odd-sized one), and to points to the start of where the
  378.      * last quad should go.  */
  379.     from = (triplets - 1) * 3;
  380.     to = (triplets - 1) * 4 + (lines - 1) * 2;
  381.     /* First write the CR LF after the last quad */
  382.     data[to + 5] = 10;   /* LF */
  383.     data[to + 4] = 13;   /* CR */
  384.     left_on_line = triplets - ((lines - 1) * 19);
  385.     /* base64 encoding is in 3-octet units.  To handle leftover
  386.      * octets, conceptually we have to zero-pad up to the next
  387.      * 6-bit unit, and pad with '=' characters for missing 6-bit
  388.      * units.
  389.      * We do it by first completing the first triplet with 
  390.      * zero-octets, and after the loop replacing some of the
  391.      * result characters with '=' characters.
  392.      * There is enough room for this, because even with a 1 or 2
  393.      * octet source string, space for four octets of output
  394.      * will be reserved.
  395.      */
  396.     switch (orig_len % 3) {
  397.     case 0:
  398.         break;
  399.     case 1:
  400.         data[orig_len] = 0;
  401.         data[orig_len + 1] = 0;
  402.         break;
  403.     case 2:
  404.         data[orig_len + 1] = 0;
  405.         break;
  406.     }
  407.     /* Now we only have perfect triplets. */
  408.     while (from >= 0) {
  409.         long whole_triplet;
  410.         /* Add a newline, if necessary */
  411.         if (left_on_line == 0) {
  412.             to -= 2;
  413.             data[to + 5] = 10;  /* LF */
  414.             data[to + 4] = 13;  /* CR */
  415.             left_on_line = 19;
  416.         }
  417.         whole_triplet = (data[from] << 16) |
  418.                         (data[from + 1] << 8) |
  419.                         data[from + 2];
  420.         data[to + 3] = base64[whole_triplet % 64];
  421.         data[to + 2] = base64[(whole_triplet >> 6) % 64];
  422.         data[to + 1] = base64[(whole_triplet >> 12) % 64];
  423.         data[to] = base64[(whole_triplet >> 18) % 64];
  424.         to -= 4;
  425.         from -= 3;
  426.         left_on_line--;
  427.     }
  428.     gw_assert(left_on_line == 0);
  429.     gw_assert(from == -3);
  430.     gw_assert(to == -4);
  431.     /* Insert padding characters in the last quad.  Remember that
  432.      * there is a CR LF between the last quad and the end of the
  433.      * string. */
  434.     switch (orig_len % 3) {
  435.     case 0:
  436.         break;
  437.     case 1:
  438.         gw_assert(data[ostr->len - 3] == 'A');
  439.         gw_assert(data[ostr->len - 4] == 'A');
  440.         data[ostr->len - 3] = '=';
  441.         data[ostr->len - 4] = '=';
  442.         break;
  443.     case 2:
  444.         gw_assert(data[ostr->len - 3] == 'A');
  445.         data[ostr->len - 3] = '=';
  446.         break;
  447.     }
  448.     seems_valid(ostr);
  449. }
  450. void octstr_base64_to_binary(Octstr *ostr)
  451. {
  452.     long triplet;
  453.     long pos, len;
  454.     long to;
  455.     int quadpos = 0;
  456.     int warned = 0;
  457.     unsigned char *data;
  458.     seems_valid(ostr);
  459.     gw_assert(!ostr->immutable);
  460.     len = ostr->len;
  461.     data = ostr->data;
  462.     if (len == 0)
  463.         return;
  464.     to = 0;
  465.     triplet = 0;
  466.     quadpos = 0;
  467.     for (pos = 0; pos < len; pos++) {
  468.         int c = data[pos];
  469.         int sixbits;
  470.         if (c >= 'A' && c <= 'Z') {
  471.             sixbits = c - 'A';
  472.         } else if (c >= 'a' && c <= 'z') {
  473.             sixbits = 26 + c - 'a';
  474.         } else if (c >= '0' && c <= '9') {
  475.             sixbits = 52 + c - '0';
  476.         } else if (c == '+') {
  477.             sixbits = 62;
  478.         } else if (c == '/') {
  479.             sixbits = 63;
  480.         } else if (c == '=') {
  481.             /* These can only occur at the end of encoded
  482.              * text.  RFC 2045 says we can assume it really
  483.              * is the end. */
  484.             break;
  485.         } else if (isspace(c)) {
  486.             /* skip whitespace */
  487.             continue;
  488.         } else {
  489.             if (!warned) {
  490.                 warning(0, "Unusual characters in base64 "
  491.                         "encoded text.");
  492.                 warned = 1;
  493.             }
  494.             continue;
  495.         }
  496.         triplet = (triplet << 6) | sixbits;
  497.         quadpos++;
  498.         if (quadpos == 4) {
  499.             data[to++] = (triplet >> 16) & 0xff;
  500.             data[to++] = (triplet >> 8) & 0xff;
  501.             data[to++] = triplet & 0xff;
  502.             quadpos = 0;
  503.         }
  504.     }
  505.     /* Deal with leftover octets */
  506.     switch (quadpos) {
  507.     case 0:
  508.         break;
  509.     case 3:  /* triplet has 18 bits, we want the first 16 */
  510.         data[to++] = (triplet >> 10) & 0xff;
  511.         data[to++] = (triplet >> 2) & 0xff;
  512.         break;
  513.     case 2:  /* triplet has 12 bits, we want the first 8 */
  514.         data[to++] = (triplet >> 4) & 0xff;
  515.         break;
  516.     case 1:
  517.         warning(0, "Bad padding in base64 encoded text.");
  518.         break;
  519.     }
  520.     ostr->len = to;
  521.     data[to] = '';
  522.     seems_valid(ostr);
  523. }
  524. long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
  525. {
  526.     /* strtol wants a char *, and we have to compare the result to
  527.      * an unsigned char *.  The easiest way to avoid warnings without
  528.      * introducing typecasts is to use two variables. */
  529.     char *endptr;
  530.     unsigned char *endpos;
  531.     long number;
  532.     seems_valid(ostr);
  533.     gw_assert(nump != NULL);
  534.     gw_assert(base == 0 || (base >= 2 && base <= 36));
  535.     if (pos >= ostr->len) {
  536.         errno = EINVAL;
  537.         return -1;
  538.     }
  539.     errno = 0;
  540.     number = strtol(ostr->data + pos, &endptr, base);
  541.     endpos = endptr;
  542.     if (errno == ERANGE)
  543.         return -1;
  544.     if (endpos == ostr->data + pos) {
  545.         errno = EINVAL;
  546.         return -1;
  547.     }
  548.     *nump = number;
  549.     return endpos - ostr->data;
  550. }
  551. int octstr_check_range(Octstr *ostr, long pos, long len,
  552.                        octstr_func_t filter)
  553. {
  554.     long end = pos + len;
  555.     seems_valid(ostr);
  556.     gw_assert(len >= 0);
  557.     if (pos >= ostr->len)
  558.         return 1;
  559.     if (end > ostr->len)
  560.         end = ostr->len;
  561.     for ( ; pos < end; pos++) {
  562.         if (!filter(ostr->data[pos]))
  563.             return 0;
  564.     }
  565.     return 1;
  566. }
  567. void octstr_convert_range(Octstr *ostr, long pos, long len,
  568.                           octstr_func_t map)
  569. {
  570.     long end = pos + len;
  571.     seems_valid(ostr);
  572.     gw_assert(!ostr->immutable);
  573.     gw_assert(len >= 0);
  574.     if (pos >= ostr->len)
  575.         return;
  576.     if (end > ostr->len)
  577.         end = ostr->len;
  578.     for ( ; pos < end; pos++) {
  579.         ostr->data[pos] = map(ostr->data[pos]);
  580.     }
  581.     seems_valid(ostr);
  582. }
  583. int octstr_compare(Octstr *ostr1, Octstr *ostr2)
  584. {
  585.     int ret;
  586.     long len;
  587.     seems_valid(ostr1);
  588.     seems_valid(ostr2);
  589.     if (ostr1->len < ostr2->len)
  590.         len = ostr1->len;
  591.     else
  592.         len = ostr2->len;
  593.     if (len == 0) {
  594. if (ostr1->len == 0 && ostr2->len > 0)
  595.     return -1;
  596. if (ostr1->len > 0 && ostr2->len == 0)
  597.     return 1;
  598.         return 0;
  599.     }
  600.     ret = memcmp(ostr1->data, ostr2->data, len);
  601.     if (ret == 0) {
  602.         if (ostr1->len < ostr2->len)
  603.             ret = -1;
  604.         else if (ostr1->len > ostr2->len)
  605.             ret = 1;
  606.     }
  607.     return ret;
  608. }
  609. int octstr_case_compare(Octstr *os1, Octstr *os2)
  610. {
  611.     int c1, c2;
  612.     long i, len;
  613.     seems_valid(os1);
  614.     seems_valid(os2);
  615.     if (os1->len < os2->len)
  616.         len = os1->len;
  617.     else
  618.         len = os2->len;
  619.     if (len == 0) {
  620. if (os1->len == 0 && os2->len > 0)
  621.     return -1;
  622. if (os1->len > 0 && os2->len == 0)
  623.     return 1;
  624.         return 0;
  625.     }
  626.     for (i = 0; i < len; ++i) {
  627. c1 = toupper(os1->data[i]);
  628. c2 = toupper(os2->data[i]);
  629. if (c1 != c2)
  630.     break;
  631.     }
  632.     if (i == len) {
  633. if (i == os1->len && i == os2->len)
  634.     return 0;
  635. if (i == os1->len)
  636.     return -1;
  637. return 1;
  638.     } else {
  639. c1 = toupper(os1->data[i]);
  640. c2 = toupper(os2->data[i]);
  641. if (c1 < c2)
  642.     return -1;
  643. if (c1 == c2)
  644.     return 0;
  645. return 1;
  646.     }
  647. }
  648. int octstr_ncompare(Octstr *ostr1, Octstr *ostr2, long n)
  649. {
  650.     long len;
  651.     seems_valid(ostr1);
  652.     seems_valid(ostr2);
  653.     if ((ostr1->len < ostr2->len) && (ostr1->len < n))
  654.         len = ostr1->len;
  655.     else if ((ostr2->len < ostr1->len) && (ostr2->len < n))
  656.         len = ostr2->len;
  657.     else
  658.         len = n;
  659.     if (len == 0)
  660.         return 0;
  661.     return memcmp(ostr1->data, ostr2->data, len);
  662. }
  663. int octstr_str_compare(Octstr *ostr, const char *str)
  664. {
  665.     seems_valid(ostr);
  666.     if (str == NULL)
  667.         return -1;
  668.     if (ostr->data == NULL)
  669. return strcmp("", str);
  670.     return strcmp(ostr->data, str);
  671. }
  672. int octstr_search_char(Octstr *ostr, int ch, long pos)
  673. {
  674.     unsigned char *p;
  675.     seems_valid(ostr);
  676.     gw_assert(ch >= 0);
  677.     gw_assert(ch <= UCHAR_MAX);
  678.     gw_assert(pos >= 0);
  679.     if (pos >= ostr->len)
  680.         return -1;
  681.     p = memchr(ostr->data + pos, ch, ostr->len - pos);
  682.     if (!p)
  683.         return -1;
  684.     return p - ostr->data;
  685. }
  686. int octstr_search(Octstr *haystack, Octstr *needle, long pos)
  687. {
  688.     int first;
  689.     seems_valid(haystack);
  690.     seems_valid(needle);
  691.     gw_assert(pos >= 0);
  692.     /* Always "find" an empty string */
  693.     if (needle->len == 0)
  694.         return 0;
  695.     if (needle->len == 1)
  696.         return octstr_search_char(haystack, needle->data[0], pos);
  697.     /* For each occurrence of needle's first character in ostr,
  698.      * check if the rest of needle follows.  Stop if there are no
  699.      * more occurrences, or if the rest of needle can't possibly
  700.      * fit in the haystack. */
  701.     first = needle->data[0];
  702.     pos = octstr_search_char(haystack, first, pos);
  703.     while (pos >= 0 && haystack->len - pos >= needle->len) {
  704.         if (memcmp(haystack->data + pos,
  705.                    needle->data, needle->len) == 0)
  706.             return pos;
  707.         pos = octstr_search_char(haystack, first, pos + 1);
  708.     }
  709.     return -1;
  710. }
  711. int octstr_case_search(Octstr *haystack, Octstr *needle, long pos)
  712. {
  713.     long i, j;
  714.     int c1, c2;
  715.     seems_valid(haystack);
  716.     seems_valid(needle);
  717.     gw_assert(pos >= 0);
  718.     /* Always "find" an empty string */
  719.     if (needle->len == 0)
  720.         return 0;
  721.     for (i = pos; i <= haystack->len - needle->len; ++i) {
  722. for (j = 0; j < needle->len; ++j) {
  723.     c1 = toupper(haystack->data[i + j]);
  724.     c2 = toupper(needle->data[j]);
  725.     if (c1 != c2)
  726.      break;
  727. }
  728. if (j == needle->len)
  729.     return i;
  730.     }
  731.     return -1;    
  732. }
  733. int octstr_print(FILE *f, Octstr *ostr)
  734. {
  735.     gw_assert(f != NULL);
  736.     seems_valid(ostr);
  737.     if (ostr->len == 0)
  738.         return 0;
  739.     if (fwrite(ostr->data, ostr->len, 1, f) != 1) {
  740.         error(errno, "Couldn't write all of octet string to file.");
  741.         return -1;
  742.     }
  743.     return 0;
  744. }
  745. int octstr_pretty_print(FILE *f, Octstr *ostr)
  746. {
  747.     unsigned char *p;
  748.     long i;
  749.     gw_assert(f != NULL);
  750.     seems_valid(ostr);
  751.     p = ostr->data;
  752.     for (i = 0; i < ostr->len; ++i, ++p) {
  753.         if (isprint(*p))
  754.             fprintf(f, "%c", *p);
  755.         else
  756.             fprintf(f, "\x%02x", *p);
  757.     }
  758.     if (ferror(f))
  759.         return -1;
  760.     return 0;
  761. }
  762. int octstr_write_to_socket(int socket, Octstr *ostr)
  763. {
  764.     long len;
  765.     unsigned char *data;
  766.     int ret;
  767.     gw_assert(socket >= 0);
  768.     seems_valid(ostr);
  769.     data = ostr->data;
  770.     len = ostr->len;
  771.     while (len > 0) {
  772.         ret = write(socket, data, len);
  773.         if (ret == -1) {
  774.             if (errno != EINTR) {
  775.                 error(errno, "Writing to socket failed");
  776.                 return -1;
  777.             }
  778.         } else {
  779.             /* ret may be less than len */
  780.             len -= ret;
  781.             data += ret;
  782.         }
  783.     }
  784.     return 0;
  785. }
  786. long octstr_write_data(Octstr *ostr, int fd, long from)
  787. {
  788.     long ret;
  789.     gw_assert(fd >= 0);
  790.     gw_assert(from >= 0);
  791.     seems_valid(ostr);
  792.     if (from >= ostr->len)
  793.         return 0;
  794.     ret = write(fd, ostr->data + from, ostr->len - from);
  795.     if (ret < 0) {
  796.         if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
  797.             return 0;
  798.         error(errno, "Error writing %ld octets to fd %d:",
  799.               ostr->len - from, fd);
  800.         return -1;
  801.     }
  802.     return ret;
  803. }
  804. int octstr_append_from_socket(Octstr *ostr, int socket)
  805. {
  806.     unsigned char buf[4096];
  807.     int len;
  808.     seems_valid(ostr);
  809.     gw_assert(!ostr->immutable);
  810. again:
  811.     len = recv(socket, buf, sizeof(buf), 0);
  812.     if (len < 0 && errno == EINTR)
  813.         goto again;
  814.     if (len < 0) {
  815.         error(errno, "Could not read from socket %d", socket);
  816.         return -1;
  817.     }
  818.     octstr_append_data(ostr, buf, len);
  819.     return len;
  820. }
  821. void octstr_insert_impl (Octstr *ostr1, Octstr *ostr2, long pos,
  822.  const char *file, long line, const char *func)
  823. {
  824.     seems_valid_real(ostr1, file, line, func);
  825.     seems_valid_real(ostr2, file, line, func);
  826.     gw_assert(pos <= ostr1->len);
  827.     gw_assert(!ostr1->immutable);
  828.     if (ostr2->len == 0)
  829.         return;
  830.     octstr_grow(ostr1, ostr1->len + ostr2->len);
  831.     memmove(ostr1->data + pos + ostr2->len, ostr1->data + pos,
  832.             ostr1->len - pos);
  833.     memcpy(ostr1->data + pos, ostr2->data, ostr2->len);
  834.     ostr1->len += ostr2->len;
  835.     ostr1->data[ostr1->len] = '';
  836.     seems_valid(ostr1);
  837. }
  838. void octstr_truncate(Octstr *ostr, int new_len)
  839. {
  840.     seems_valid(ostr);
  841.     gw_assert(!ostr->immutable);
  842.     gw_assert(new_len >= 0);
  843.     if (new_len >= ostr->len)
  844.         return;
  845.     ostr->len = new_len;
  846.     ostr->data[new_len] = '';
  847.     seems_valid(ostr);
  848. }
  849. void octstr_strip_blanks(Octstr *text)
  850. {
  851.     int start = 0, end, len = 0;
  852.     seems_valid(text);
  853.     gw_assert(!text->immutable);
  854.     /* Remove white space from the beginning of the text */
  855.     while (isspace(octstr_get_char(text, start)) && 
  856.    start <= octstr_len(text))
  857.         start ++;
  858.     if (start > 0)
  859.         octstr_delete(text, 0, start);
  860.     /* and from the end. */
  861.     if ((len = octstr_len(text)) > 0) {
  862.         end = len = len - 1;
  863.         while (isspace(octstr_get_char(text, end)) && end >= 0)
  864.             end--;
  865.         octstr_delete(text, end + 1, len - end);
  866.     }
  867.     seems_valid(text);
  868. }
  869. void octstr_strip_nonalphanums(Octstr *text)
  870. {
  871.     int start = 0, end, len = 0;
  872.     seems_valid(text);
  873.     gw_assert(!text->immutable);
  874.     /* Remove white space from the beginning of the text */
  875.     while (!isalnum(octstr_get_char(text, start)) && 
  876.    start <= octstr_len(text))
  877.         start ++;
  878.     if (start > 0)
  879.         octstr_delete(text, 0, start);
  880.     /* and from the end. */
  881.     if ((len = octstr_len(text)) > 0) {
  882.         end = len = len - 1;
  883.         while (!isalnum(octstr_get_char(text, end)) && end >= 0)
  884.             end--;
  885.         octstr_delete(text, end + 1, len - end);
  886.     }
  887.     seems_valid(text);
  888. }
  889. void octstr_shrink_blanks(Octstr *text)
  890. {
  891.     int i, j, end;
  892.     seems_valid(text);
  893.     gw_assert(!text->immutable);
  894.     end = octstr_len(text);
  895.     /* Shrink white spaces to one  */
  896.     for (i = 0; i < end; i++) {
  897.         if (isspace(octstr_get_char(text, i))) {
  898.             /* Change the remaining space into single space. */
  899.             if (octstr_get_char(text, i) != ' ')
  900.                 octstr_set_char(text, i, ' ');
  901.             j = i = i + 1;
  902.             while (isspace(octstr_get_char(text, j)))
  903.                 j ++;
  904.             if (j - i > 1)
  905.                 octstr_delete(text, i, j - i);
  906.         }
  907.     }
  908.     seems_valid(text);
  909. }
  910. void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
  911. {
  912.     seems_valid(ostr);
  913.     gw_assert(!ostr->immutable);
  914.     gw_assert(pos <= ostr->len);
  915.     if (len == 0)
  916.         return;
  917.     octstr_grow(ostr, ostr->len + len);
  918.     if (ostr->len > pos) { /* only if neccessary */
  919.         memmove(ostr->data + pos + len, ostr->data + pos, ostr->len - pos);
  920.     }
  921.     memcpy(ostr->data + pos, data, len);
  922.     ostr->len += len;
  923.     ostr->data[ostr->len] = '';
  924.     seems_valid(ostr);
  925. }
  926. void octstr_append_data(Octstr *ostr, const char *data, long len)
  927. {
  928.     gw_assert(ostr != NULL);
  929.     octstr_insert_data(ostr, ostr->len, data, len);
  930. }
  931. void octstr_append_impl(Octstr *ostr1, Octstr *ostr2,
  932. const char *file, long line, const char *func)
  933. {
  934.     gw_assert(ostr1 != NULL);
  935.     octstr_insert_impl(ostr1, ostr2, ostr1->len, file, line, func);
  936. }
  937. void octstr_append_cstr(Octstr *ostr, const char *cstr)
  938. {
  939.     octstr_insert_data(ostr, ostr->len, cstr, strlen(cstr));
  940. }
  941. void octstr_append_char(Octstr *ostr, int ch)
  942. {
  943.     unsigned char c = ch;
  944.     gw_assert(ch >= 0);
  945.     gw_assert(ch <= UCHAR_MAX);
  946.     octstr_insert_data(ostr, ostr->len, &c, 1);
  947. }
  948. void octstr_delete(Octstr *ostr1, long pos, long len)
  949. {
  950.     seems_valid(ostr1);
  951.     gw_assert(!ostr1->immutable);
  952.     if (pos > ostr1->len)
  953.         pos = ostr1->len;
  954.     if (pos + len > ostr1->len)
  955.         len = ostr1->len - pos;
  956.     if (len > 0) {
  957.         memmove(ostr1->data + pos, ostr1->data + pos + len,
  958.                 ostr1->len - pos - len);
  959.         ostr1->len -= len;
  960.         ostr1->data[ostr1->len] = '';
  961.     }
  962.     seems_valid(ostr1);
  963. }
  964. Octstr *octstr_read_file(const char *filename)
  965. {
  966.     FILE *f;
  967.     Octstr *os;
  968.     char buf[4096];
  969.     long n;
  970.     gw_assert(filename != NULL);
  971.     f = fopen(filename, "r");
  972.     if (f == NULL) {
  973.         error(errno, "fopen failed: couldn't open `%s'", filename);
  974.         return NULL;
  975.     }
  976.     os = octstr_create("");
  977.     if (os == NULL)
  978.         goto error;
  979.     while ((n = fread(buf, 1, sizeof(buf), f)) > 0)
  980.         octstr_insert_data(os, octstr_len(os), buf, n);
  981.     (void) fclose(f);
  982.     return os;
  983. error:
  984.     (void) fclose(f);
  985.     octstr_destroy(os);
  986.     return NULL;
  987. }
  988. Octstr *octstr_read_pipe(FILE *f)
  989. {
  990.     Octstr *os;
  991.     char buf[4096];
  992.     gw_assert(f != NULL);
  993.     os = octstr_create("");
  994.     if (os == NULL)
  995.         goto error;
  996.     while (fgets(buf, sizeof(buf), f) != NULL)
  997.         octstr_append_data(os, buf, strlen(buf));
  998.     return os;
  999. error:
  1000.     octstr_destroy(os);
  1001.     return NULL;
  1002. }
  1003. List *octstr_split_words(Octstr *ostr)
  1004. {
  1005.     unsigned char *p;
  1006.     List *list;
  1007.     Octstr *word;
  1008.     long i, start, end;
  1009.     seems_valid(ostr);
  1010.     list = list_create();
  1011.     p = ostr->data;
  1012.     i = 0;
  1013.     for (; ; ) {
  1014.         while (i < ostr->len && isspace(*p)) {
  1015.             ++p;
  1016.             ++i;
  1017.         }
  1018.         start = i;
  1019.         while (i < ostr->len && !isspace(*p)) {
  1020.             ++p;
  1021.             ++i;
  1022.         }
  1023.         end = i;
  1024.         if (start == end)
  1025.             break;
  1026.         word = octstr_create_from_data(ostr->data + start,
  1027.                                        end - start);
  1028.         list_append(list, word);
  1029.     }
  1030.     return list;
  1031. }
  1032. List *octstr_split(Octstr *os, Octstr *sep)
  1033. {
  1034.     List *list;
  1035.     long next, pos, seplen;
  1036.     
  1037.     list = list_create();
  1038.     pos = 0;
  1039.     seplen = octstr_len(sep);
  1040.     while ((next = octstr_search(os, sep, pos)) != -1) {
  1041. list_append(list, octstr_copy(os, pos, next - pos));
  1042. pos = next + seplen;
  1043.     }
  1044.     
  1045.     if (pos < octstr_len(os))
  1046.      list_append(list, octstr_copy(os, pos, octstr_len(os)));
  1047.     
  1048.     return list;
  1049. }
  1050. int octstr_item_match(void *item, void *pattern)
  1051. {
  1052.     return octstr_compare(item, pattern) == 0;
  1053. }
  1054. void octstr_dump(Octstr *ostr, int level)
  1055. {
  1056.     unsigned char *p, *d, buf[1024], charbuf[256];
  1057.     long pos;
  1058.     const int octets_per_line = 8;
  1059.     int c, this_line_begins_at;
  1060.     if (ostr == NULL)
  1061.         return;
  1062.     seems_valid(ostr);
  1063.     debug("gwlib.octstr", 0, "%*sOctet string at %p:", level, "",
  1064.           (void *) ostr);
  1065.     debug("gwlib.octstr", 0, "%*s  len:  %lu", level, "",
  1066.           (unsigned long) ostr->len);
  1067.     debug("gwlib.octstr", 0, "%*s  size: %lu", level, "",
  1068.           (unsigned long) ostr->size);
  1069.     debug("gwlib.octstr", 0, "%*s  immutable: %d", level, "",
  1070.           ostr->immutable);
  1071.     buf[0] = '';
  1072.     p = buf;
  1073.     d = charbuf;
  1074.     this_line_begins_at = 0;
  1075.     for (pos = 0; pos < octstr_len(ostr); ) {
  1076.         c = octstr_get_char(ostr, pos);
  1077.         sprintf(p, "%02x ", c);
  1078.         p = strchr(p, '');
  1079.         if (isprint(c))
  1080.             *d++ = c;
  1081.         else
  1082.             *d++ = '.';
  1083.         ++pos;
  1084.         if (pos - this_line_begins_at == octets_per_line) {
  1085.             *d = '';
  1086.             debug("gwlib.octstr", 0, "%*s  data: %s  %s", level, "",
  1087.                   buf, charbuf);
  1088.             buf[0] = '';
  1089.             charbuf[0] = '';
  1090.             p = buf;
  1091.             d = charbuf;
  1092.             this_line_begins_at = pos;
  1093.         }
  1094.     }
  1095.     if (pos - this_line_begins_at > 0) {
  1096.         *d = '';
  1097.         debug("gwlib.octstr", 0, "%*s  data: %-*.*s  %s", level, "",
  1098.               octets_per_line*3,
  1099.               octets_per_line*3, buf, charbuf);
  1100.     }
  1101.     debug("gwlib.octstr", 0, "%*sOctet string dump ends.", level, "");
  1102. }
  1103. void octstr_dump_short(Octstr *ostr, int level, const char *name)
  1104. {
  1105.     char buf[100];
  1106.     char *p;
  1107.     long i;
  1108.     int c;
  1109.     if (ostr == NULL) {
  1110.         debug("gwlib.octstr", 0, "%*s%s: NULL", level, "", name);
  1111.         return;
  1112.     }
  1113.     seems_valid(ostr);
  1114.     if (ostr->len < 20) {
  1115.         p = buf;
  1116.         for (i = 0; i < ostr->len; i++) {
  1117.             c = ostr->data[i];
  1118.             if (c == 'n') {
  1119.                 *p++ = '\';
  1120.                 *p++ = 'n';
  1121.             } else if (!isprint(c)) {
  1122.                 break;
  1123.             } else if (c == '"') {
  1124.                 *p++ = '\';
  1125.                 *p++ = '"';
  1126.             } else if (c == '\') {
  1127.                 *p++ = '\';
  1128.                 *p++ = '\';
  1129.             } else {
  1130.                 *p++ = c;
  1131.             }
  1132.         }
  1133.         if (i == ostr->len) {
  1134.             *p++ = 0;
  1135.             /* We got through the loop without hitting nonprintable
  1136.              * characters. */
  1137.             debug("gwlib.octstr", 0, "%*s%s: "%s"", level, "", name, buf);
  1138.             return;
  1139.         }
  1140.     }
  1141.     debug("gwlib.octstr", 0, "%*s%s:", level, "", name);
  1142.     octstr_dump(ostr, level + 1);
  1143. }
  1144. void octstr_url_encode(Octstr *ostr)
  1145. {
  1146.     int i, n, newlen;
  1147.     unsigned char *str, *str2, *hexits;
  1148.     unsigned char c;
  1149.     Octstr *res;
  1150.     seems_valid(ostr);
  1151.     res = octstr_create("");
  1152.     if (ostr->len == 0)
  1153. return;
  1154.     str = ostr->data;
  1155.     n = 0;
  1156.     for (i = 0; i < ostr->len; i++)
  1157. if (!is_safe[*str++])
  1158.     n++;
  1159.     newlen = ostr->len + 2 * n;
  1160.     res->len = newlen;
  1161.     res->size = res->len + 1;
  1162.     res->data = gw_malloc(res->size);
  1163.     hexits = "0123456789ABCDEF";
  1164.     str = ostr->data;
  1165.     str2 = res->data;
  1166.     for (i = 0; i < ostr->len; i++) {
  1167. c = *str++;
  1168. if (!is_safe[c]) {
  1169.     *str2++ = '%';
  1170.     *str2++ = hexits[c >> 4 & 0xf];
  1171.     *str2++ = hexits[c & 0xf];
  1172. }
  1173. else if (c == ' ')
  1174.     *str2++ = '+';
  1175. else
  1176.     *str2++ = c;
  1177.     }
  1178.     *str2 = 0;
  1179.     seems_valid(res);
  1180.     
  1181.     octstr_truncate(ostr, 0);
  1182.     octstr_insert(ostr, res, 0);
  1183.     octstr_destroy(res);
  1184. }
  1185. int octstr_url_decode(Octstr *ostr)
  1186. {
  1187.     long value;
  1188.     unsigned char *string = ostr->data;
  1189.     unsigned char *dptr = ostr->data;
  1190.     unsigned char buf[3];     /* buffer for strtol conversion */
  1191.     buf[2] = '';
  1192.     seems_valid(ostr);
  1193.     gw_assert(!ostr->immutable);
  1194.     if (ostr->len == 0)
  1195.         return 0;
  1196.     do {
  1197.         if (*string == '%') {
  1198.             if (*(string + 1) == '' || *(string + 2) == '')
  1199.                 goto error;
  1200.             buf[0] = *(string + 1);
  1201.             buf[1] = *(string + 2);
  1202.             value = strtol(buf, NULL, 16);
  1203.             if (value >= 0 && value < 256) {
  1204.                 *dptr = (unsigned char)value;
  1205.                 string += 3;
  1206.                 dptr++;
  1207.                 continue;
  1208.             }
  1209.             warning(0, "Garbage encoded (value = %ld)", value);
  1210.         }
  1211.         if (*string == '+') {
  1212.             *dptr++ = ' ';
  1213.             string++;
  1214.         } else
  1215.             *dptr++ = *string++;
  1216.     } while (*string);  /* we stop here because it terimates encoded string */
  1217.     *dptr = '';
  1218.     ostr->len = (dptr - ostr->data);
  1219.     seems_valid(ostr);
  1220.     return 0;
  1221. error:
  1222.     *dptr = '';
  1223.     ostr->len = (dptr - ostr->data);
  1224.     warning(0, "octstr_url_decode: corrupted end-of-string <%s>", string);
  1225.     seems_valid(ostr);
  1226.     return -1;
  1227. }
  1228. long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
  1229. {
  1230.     long pos;
  1231.     long result;
  1232.     int mask;
  1233.     int shiftwidth;
  1234.     seems_valid(ostr);
  1235.     gw_assert(bitpos >= 0);
  1236.     gw_assert(numbits <= 32);
  1237.     gw_assert(numbits >= 0);
  1238.     pos = bitpos / 8;
  1239.     bitpos = bitpos % 8;
  1240.     /* This also takes care of the len == 0 case */
  1241.     if (pos >= ostr->len)
  1242.         return 0;
  1243.     mask = (1 << numbits) - 1;
  1244.     /* It's easy if the range fits in one octet */
  1245.     if (bitpos + numbits <= 8) {
  1246.         /* shiftwidth is the number of bits to ignore on the right.
  1247.          * bitpos 0 is the leftmost bit. */
  1248.         shiftwidth = 8 - (bitpos + numbits);
  1249.         return (ostr->data[pos] >> shiftwidth) & mask;
  1250.     }
  1251.     /* Otherwise... */
  1252.     result = 0;
  1253.     while (bitpos + numbits > 8) {
  1254.         result = (result << 8) | ostr->data[pos];
  1255.         numbits -= (8 - bitpos);
  1256.         bitpos = 0;
  1257.         pos++;
  1258.         if (pos >= ostr->len)
  1259.             return (result << numbits) & mask;
  1260.     }
  1261.     gw_assert(bitpos == 0);
  1262.     result <<= numbits;
  1263.     result |= ostr->data[pos] >> (8 - numbits);
  1264.     return result & mask;
  1265. }
  1266. void octstr_set_bits(Octstr *ostr, long bitpos, int numbits,
  1267.                      unsigned long value)
  1268. {
  1269.     long pos;
  1270.     unsigned long mask;
  1271.     int shiftwidth;
  1272.     int bits;
  1273.     int maxlen;
  1274.     int c;
  1275.     seems_valid(ostr);
  1276.     gw_assert(!ostr->immutable);
  1277.     gw_assert(bitpos >= 0);
  1278.     gw_assert(numbits <= 32);
  1279.     gw_assert(numbits >= 0);
  1280.     maxlen = (bitpos + numbits + 7) / 8;
  1281.     if (maxlen > ostr->len) {
  1282.         octstr_grow(ostr, maxlen);
  1283.         /* Make sure the new octets start out with value 0 */
  1284.         for (pos = ostr->len; pos < maxlen; pos++) {
  1285.             ostr->data[pos] = 0;
  1286.         }
  1287.         ostr->len = maxlen;
  1288.         ostr->data[maxlen] = 0;
  1289.     }
  1290.     mask = (1 << numbits) - 1;
  1291.     /* mask is also the largest value that fits */
  1292.     gw_assert(value <= mask);
  1293.     pos = bitpos / 8;
  1294.     bitpos = bitpos % 8;
  1295.     /* Does the range fit in one octet? */
  1296.     if (bitpos + numbits <= 8) {
  1297.         /* shiftwidth is the number of bits to ignore on the right.
  1298.          * bitpos 0 is the leftmost bit. */
  1299.         shiftwidth = 8 - (bitpos + numbits);
  1300.         /* Extract the bits we don't want to affect */
  1301.         c = ostr->data[pos] & ~(mask << shiftwidth);
  1302.         c |= value << shiftwidth;
  1303.         gw_assert(pos < ostr->len);
  1304.         ostr->data[pos] = c;
  1305.         return;
  1306.     }
  1307.     /* Otherwise... */
  1308.     /* If speed is a problem here, we could have separate cases for
  1309.      * the first octet (which may have bitpos > 0), and the rest,
  1310.      * which don't. */
  1311.     while (bitpos + numbits > 8) {
  1312.         /* We want this many bits from the value */
  1313.         bits = 8 - bitpos;
  1314.         /* There are this many bits to their right in the value */
  1315.         shiftwidth = numbits - bits;
  1316.         /* Construct a mask for "bits" bits on the far right */
  1317.         mask = (1 << bits) - 1;
  1318.         /* Get the bits we want */
  1319.         c = (value >> shiftwidth) & mask;
  1320.         /* Merge them with the bits that are already there */
  1321.         gw_assert(pos < ostr->len);
  1322.         ostr->data[pos] = (ostr->data[pos] & ~mask) | c;
  1323.         numbits -= (8 - bitpos);
  1324.         bitpos = 0;
  1325.         pos++;
  1326.     }
  1327.     gw_assert(bitpos == 0);
  1328.     gw_assert(pos < ostr->len);
  1329.     /* Set remaining bits.  This is just like the single-octet case
  1330.      * before the loop, except that we know bitpos is 0. */
  1331.     mask = (1 << numbits) - 1;
  1332.     shiftwidth = 8 - numbits;
  1333.     c = ostr->data[pos] & ~(mask << shiftwidth);
  1334.     c |= value << shiftwidth;
  1335.     ostr->data[pos] = c;
  1336.     seems_valid(ostr);
  1337. }
  1338. void octstr_append_uintvar(Octstr *ostr, unsigned long value)
  1339. {
  1340.     /* A uintvar is defined to be up to 32 bits large, so it will
  1341.      * fit in 5 octets. */
  1342.     unsigned char octets[5];
  1343.     int i;
  1344.     int start;
  1345.     /* Handle last byte separately; it has no continuation bit,
  1346.      * and must be encoded even if value is 0. */
  1347.     octets[4] = value & 0x7f;
  1348.     value >>= 7;
  1349.     for (i = 3; value > 0 && i >= 0; i--) {
  1350.         octets[i] = 0x80 | (value & 0x7f);
  1351.         value >>= 7;
  1352.     }
  1353.     start = i + 1;
  1354.     octstr_append_data(ostr, octets + start, 5 - start);
  1355. }
  1356. long octstr_extract_uintvar(Octstr *ostr, unsigned long *value, long pos)
  1357. {
  1358.     int c;
  1359.     int count;
  1360.     unsigned long ui;
  1361.     ui = 0;
  1362.     for (count = 0; count < 5; count++) {
  1363.         c = octstr_get_char(ostr, pos + count);
  1364.         if (c < 0)
  1365.             return -1;
  1366.         ui = (ui << 7) | (c & 0x7f);
  1367.         if (!(c & 0x80)) {
  1368.             *value = ui;
  1369.             return pos + count + 1;
  1370.         }
  1371.     }
  1372.     return -1;
  1373. }
  1374. void octstr_append_decimal(Octstr *ostr, long value)
  1375. {
  1376.     char tmp[128];
  1377.     Octstr *ostmp;
  1378.     sprintf(tmp, "%ld", value);
  1379.     ostmp = octstr_create(tmp);
  1380.     octstr_append(ostr, ostmp);
  1381.     octstr_destroy(ostmp);
  1382. }
  1383. /**********************************************************************
  1384.  * octstr_format and related private functions
  1385.  */
  1386. /*
  1387.  * A parsed form of the format string. This struct has been carefully
  1388.  * defined so that it can be initialized with {0} and it will have 
  1389.  * the correct defaults.
  1390.  */
  1391. struct format
  1392. {
  1393.     int minus;
  1394.     int zero;
  1395.     long min_width;
  1396.     int has_prec;
  1397.     long prec;
  1398.     long type;
  1399. };
  1400. static void format_flags(struct format *format, const char **fmt)
  1401. {
  1402.     int done;
  1403.     done = 0;
  1404.     do
  1405.     {
  1406.         switch (**fmt) {
  1407.         case '-':
  1408.             format->minus = 1;
  1409.             break;
  1410.         case '0':
  1411.             format->zero = 1;
  1412.             break;
  1413.         default:
  1414.             done = 1;
  1415.         }
  1416.         if (!done)
  1417.             ++(*fmt);
  1418.     } while (!done);
  1419. }
  1420. static void format_width(struct format *format, const char **fmt,
  1421.                          va_list *args)
  1422. {
  1423.     char *end;
  1424.     if (**fmt == '*')
  1425.     {
  1426.         format->min_width = va_arg(*args, int);
  1427.         ++(*fmt);
  1428.     } else if (isdigit(**(const unsigned char **) fmt))
  1429.     {
  1430.         format->min_width = strtol(*fmt, &end, 10);
  1431.         *fmt = end;
  1432.         /* XXX error checking is missing from here */
  1433.     }
  1434. }
  1435. static void format_prec(struct format *format, const char **fmt,
  1436.                         va_list *args)
  1437. {
  1438.     char *end;
  1439.     if (**fmt != '.')
  1440.         return;
  1441.     ++(*fmt);
  1442.     if (**fmt == '*')
  1443.     {
  1444.         format->has_prec = 1;
  1445.         format->prec = va_arg(*args, int);
  1446.         ++(*fmt);
  1447.     } else if (isdigit(**(const unsigned char **) fmt))
  1448.     {
  1449.         format->has_prec = 1;
  1450.         format->prec = strtol(*fmt, &end, 10);
  1451.         *fmt = end;
  1452.         /* XXX error checking is missing from here */
  1453.     }
  1454. }
  1455. static void format_type(struct format *format, const char **fmt)
  1456. {
  1457.     switch (**fmt)
  1458.     {
  1459.     case 'h':
  1460.     case 'l':
  1461.         format->type = **fmt;
  1462.         ++(*fmt);
  1463.         break;
  1464.     }
  1465. }
  1466. static void convert(Octstr *os, struct format *format, const char **fmt,
  1467.                     va_list *args)
  1468. {
  1469.     Octstr *new;
  1470.     char *s, *pad;
  1471.     long n;
  1472.     unsigned long u;
  1473.     char tmpfmt[1024];
  1474.     char tmpbuf[1024];
  1475.     char c;
  1476.     void *p;
  1477.     new = NULL;
  1478.     switch (**fmt)
  1479.     {
  1480.     case 'c':
  1481.         c = va_arg(*args, int);
  1482.         new = octstr_create_from_data(&c, 1);
  1483.         break;
  1484.     case 'd':
  1485.     case 'i':
  1486.         switch (format->type) {
  1487.         case 'l':
  1488.             n = va_arg(*args, long);
  1489.             break;
  1490.         case 'h':
  1491.             n = (short) va_arg(*args, int);
  1492.             break;
  1493.         default:
  1494.             n = va_arg(*args, int);
  1495.             break;
  1496.         }
  1497.         new = octstr_create("");
  1498.         octstr_append_decimal(new, n);
  1499.         break;
  1500.     case 'o':
  1501.     case 'u':
  1502.     case 'x':
  1503.     case 'X':
  1504. switch (format->type) {
  1505. case 'l':
  1506.     u = va_arg(*args, unsigned long);
  1507.     break;
  1508.         case 'h':
  1509.             u = (unsigned short) va_arg(*args, unsigned int);
  1510.             break;
  1511.         default:
  1512.             u = va_arg(*args, unsigned int);
  1513.             break;
  1514.         }
  1515.         tmpfmt[0] = '%';
  1516. tmpfmt[1] = 'l';
  1517. tmpfmt[2] = **fmt;
  1518. tmpfmt[3] = '';
  1519. sprintf(tmpbuf, tmpfmt, u);
  1520.         new = octstr_create(tmpbuf);
  1521.         break;
  1522.     case 'e':
  1523.     case 'f':
  1524.     case 'g':
  1525.         sprintf(tmpfmt, "%%");
  1526.         if (format->minus)
  1527.             strcat(tmpfmt, "-");
  1528.         if (format->zero)
  1529.             strcat(tmpfmt, "0");
  1530.         if (format->min_width > 0)
  1531.             sprintf(strchr(tmpfmt, ''),
  1532.                     "%ld", format->min_width);
  1533.         if (format->has_prec)
  1534.             sprintf(strchr(tmpfmt, ''),
  1535.                     ".%ld", format->prec);
  1536.         if (format->type != '')
  1537.             sprintf(strchr(tmpfmt, ''),
  1538.                     "%c", (int) format->type);
  1539.         sprintf(strchr(tmpfmt, ''), "%c", **fmt);
  1540.         snprintf(tmpbuf, sizeof(tmpbuf),
  1541.                  tmpfmt, va_arg(*args, double));
  1542.         new = octstr_create(tmpbuf);
  1543.         break;
  1544.     case 's':
  1545.         s = va_arg(*args, char *);
  1546.         if (format->has_prec && format->prec < (long) strlen(s))
  1547.             n = format->prec;
  1548.         else
  1549.             n = (long) strlen(s);
  1550.         new = octstr_create_from_data(s, n);
  1551.         break;
  1552.     case 'p':
  1553.      p = va_arg(*args, void *);
  1554. sprintf(tmpfmt, "%p", p);
  1555. new = octstr_create(tmpfmt);
  1556. break;
  1557.     case 'S':
  1558.         new = octstr_duplicate(va_arg(*args, Octstr *));
  1559.         if (format->has_prec)
  1560.             octstr_truncate(new, format->prec);
  1561.         break;
  1562.     case 'E':
  1563.         new = octstr_duplicate(va_arg(*args, Octstr *));
  1564. octstr_url_encode(new);
  1565. /*
  1566.  * note: we use blind truncate - encoded character can get cut half-way.
  1567.          */
  1568.         if (format->has_prec)
  1569.             octstr_truncate(new, format->prec);
  1570.         break;
  1571.     case '%':
  1572.      new = octstr_imm("%");
  1573.      break;
  1574.     default:
  1575.         panic(0, "octstr_format format string syntax error.");
  1576.     }
  1577.     if (format->zero)
  1578.         pad = "0";
  1579.     else
  1580.         pad = " ";
  1581.     if (format->minus) {
  1582.         while (format->min_width > octstr_len(new))
  1583.             octstr_append_data(new, pad, 1);
  1584.     } else {
  1585.         while (format->min_width > octstr_len(new))
  1586.             octstr_insert_data(new, 0, pad, 1);
  1587.     }
  1588.     octstr_append(os, new);
  1589.     octstr_destroy(new);
  1590.     if (**fmt != '')
  1591.         ++(*fmt);
  1592. }
  1593. Octstr *octstr_format(const char *fmt, ...)
  1594. {
  1595.     va_list args;
  1596.     Octstr *os;
  1597.     va_start(args, fmt);
  1598.     os = octstr_format_valist(fmt, args);
  1599.     va_end(args);
  1600.     return os;
  1601. }
  1602. Octstr *octstr_format_valist(const char *fmt, va_list args)
  1603. {
  1604.     Octstr *os;
  1605.     size_t n;
  1606.     os = octstr_create("");
  1607.     while (*fmt != '') {
  1608.         struct format format = { 0, };
  1609.         n = strcspn(fmt, "%");
  1610.         octstr_append_data(os, fmt, n);
  1611.         fmt += n;
  1612.         gw_assert(*fmt == '%' || *fmt == '');
  1613.         if (*fmt == '')
  1614.             continue;
  1615.         ++fmt;
  1616.         format_flags(&format, &fmt);
  1617.         format_width(&format, &fmt, &args);
  1618.         format_prec(&format, &fmt, &args);
  1619.         format_type(&format, &fmt);
  1620.         convert(os, &format, &fmt, &args);
  1621.     }
  1622.     seems_valid(os);
  1623.     return os;
  1624. }
  1625. void octstr_format_append(Octstr *os, const char *fmt, ...)
  1626. {
  1627.     Octstr *temp;
  1628.     va_list args;
  1629.     va_start(args, fmt);
  1630.     temp = octstr_format_valist(fmt, args);
  1631.     va_end(args);
  1632.     octstr_append(os, temp);
  1633.     octstr_destroy(temp);
  1634. }
  1635. unsigned long octstr_hash_key(Octstr *ostr)
  1636. {
  1637.     unsigned long key = 0;
  1638.     long i;
  1639.     if (ostr == NULL)
  1640. return 0;
  1641.     for (i = 0; i < octstr_len(ostr); i++)
  1642. key = key + octstr_get_char(ostr, i);
  1643.     return key;
  1644. }
  1645. /**********************************************************************
  1646.  * Local functions.
  1647.  */
  1648. static void seems_valid_real(Octstr *ostr, const char *filename, long lineno,
  1649.                              const char *function)
  1650. {
  1651.     gw_assert(immutables_init);
  1652.     gw_assert_place(ostr != NULL,
  1653.                     filename, lineno, function);
  1654.     gw_assert_allocated(ostr,
  1655.                         filename, lineno, function);
  1656.     gw_assert_place(ostr->len >= 0,
  1657.                     filename, lineno, function);
  1658.     gw_assert_place(ostr->size >= 0,
  1659.                     filename, lineno, function);
  1660.     if (ostr->size == 0) {
  1661.         gw_assert_place(ostr->len == 0,
  1662.                         filename, lineno, function);
  1663.         gw_assert_place(ostr->data == NULL,
  1664.                         filename, lineno, function);
  1665.     } else {
  1666.         gw_assert_place(ostr->len + 1 <= ostr->size,
  1667.                         filename, lineno, function);
  1668.         gw_assert_place(ostr->data != NULL,
  1669.                         filename, lineno, function);
  1670. if (!ostr->immutable)
  1671.             gw_assert_allocated(ostr->data,
  1672.                                 filename, lineno, function);
  1673.         gw_assert_place(ostr->data[ostr->len] == '',
  1674.                         filename, lineno, function);
  1675.     }
  1676. }
  1677. int
  1678. octstr_recode (Octstr *tocode, Octstr *fromcode, Octstr *orig)
  1679. {
  1680.     Octstr *octstr_utf8 = NULL;
  1681.     Octstr *octstr_final = NULL;
  1682.     int resultcode = 0;
  1683.     
  1684.     if (octstr_case_compare(tocode, fromcode) == 0) {
  1685. goto cleanup_and_exit;
  1686.     }
  1687.     if ((octstr_case_compare(fromcode, octstr_imm ("utf-8")) != 0) &&
  1688. (octstr_case_compare(fromcode, octstr_imm ("utf8")) != 0)) {
  1689. if (charset_to_utf8(orig, &octstr_utf8, fromcode) < 0) {
  1690.     resultcode = -1;
  1691.     goto cleanup_and_exit;
  1692. }
  1693.     } else {
  1694. octstr_utf8 = octstr_duplicate(orig);
  1695.     }
  1696.     if ((octstr_case_compare(tocode, octstr_imm ("utf-8")) != 0) &&
  1697. (octstr_case_compare(tocode, octstr_imm ("utf8")) != 0)) {
  1698. if (charset_from_utf8(octstr_utf8, &octstr_final, tocode) < 0) {
  1699.     resultcode = -1;
  1700.     goto cleanup_and_exit;
  1701. }
  1702.     } else {
  1703. octstr_final = octstr_duplicate(octstr_utf8);
  1704.     }
  1705.     octstr_truncate(orig, 0);
  1706.     octstr_append(orig, octstr_final);
  1707.  cleanup_and_exit:
  1708.     octstr_destroy (octstr_utf8);
  1709.     octstr_destroy (octstr_final);
  1710.     return resultcode;
  1711. }