72 #include <sys/types.h> 73 #include <sys/socket.h> 74 #include <netinet/in.h> 82 #if (defined(__linux__) && (defined(__powerpc__) || defined(__s390__) || defined(__x86_64))) || \ 83 (defined(__FreeBSD__) && defined(__amd64__)) || \ 84 (defined(DARWIN) && defined(__x86_64__)) 86 #define VALPARM(y) va_list y 90 #define VALPARM(y) va_list *y 131 #define MAX_IMMUTABLES 1024 145 #define CSTR_TO_LONG(ptr) (((unsigned long) ptr) >> 2) 151 #define H2B(a) (a >= '0' && a <= '9' ? \ 152 a - '0' : (a >= 'a' && a <= 'f' ? \ 153 a - 'a' + 10 : (a >= 'A' && a <= 'F' ? a - 'A' + 10 : -1) \ 165 const char *
function);
167 #define seems_valid(ostr) 169 #define seems_valid(ostr) \ 170 (seems_valid_real(ostr, __FILE__, __LINE__, __func__)) 210 unsigned char *safe =
" ABCDEFGHIJKLMNOPQRSTUVWXYZ" 211 "abcdefghijklmnopqrstuvwxyz" 213 for (i = 0; safe[i] !=
'\0'; ++i)
238 debug(
"gwlib.octstr", 0,
"Immutable octet strings: %ld.", n);
251 long line,
const char *func)
262 if (len < 0 || (data == NULL && len != 0))
265 ostr = gw_malloc_trace(
sizeof(*ostr),
file, line, func);
272 ostr->
size = len + 1;
273 ostr->
data = gw_malloc_trace(ostr->
size,
file, line, func);
274 memcpy(ostr->
data, data, len);
275 ostr->
data[len] =
'\0';
293 data = (
unsigned char *) cstr;
302 panic(0,
"Too many immutable strings.");
310 os = gw_malloc(
sizeof(*os));
312 os->
len = strlen(data);
409 if (pos >= ostr->
len || pos < 0)
411 return ostr->
data[pos];
420 ostr->
data[pos] = ch;
430 if (pos >= ostr->
len)
432 if (pos + len > ostr->
len)
433 len = ostr->
len - pos;
435 memcpy(buf, ostr->
data + pos, len);
467 unsigned char *hexits;
475 hexits = uppercase ?
"0123456789ABCDEF" :
"0123456789abcdef";
481 for (i = ostr->
len - 1; i >= 0; i--) {
483 ostr->
data[tmp + 1] = hexits[ostr->
data[i] & 0xf];
484 ostr->
data[tmp] = hexits[ostr->
data[i] >> 4];
487 ostr->
len = ostr->
len * 2;
512 for (i = 0, p = ostr->
data; i < len; i++, p++) {
513 if (*p >=
'0' && *p <=
'9')
515 else if (*p >=
'a' && *p <=
'f')
517 else if (*p >=
'A' && *p <=
'F')
530 for (i = 0; i < len; i++) {
531 ostr->
data[i] = ostr->
data[i * 2] * 16 | ostr->
data[i * 2 + 1];
535 ostr->
data[len] =
'\0';
544 static const unsigned char base64[64] =
545 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
556 if (ostr->
len == 0) {
566 triplets = (ostr->
len + 2) / 3;
567 lines = (triplets + 18) / 19;
570 orig_len = ostr->
len;
573 ostr->
len = triplets * 4 +
lines * 2;
574 data[ostr->
len] =
'\0';
581 from = (triplets - 1) * 3;
582 to = (triplets - 1) * 4 + (
lines - 1) * 2;
587 left_on_line = triplets - ((
lines - 1) * 19);
600 switch (orig_len % 3) {
605 data[orig_len + 1] = 0;
608 data[orig_len + 1] = 0;
617 if (left_on_line == 0) {
624 whole_triplet = (data[
from] << 16) |
625 (data[
from + 1] << 8) |
627 data[to + 3] = base64[whole_triplet % 64];
628 data[to + 2] = base64[(whole_triplet >> 6) % 64];
629 data[to + 1] = base64[(whole_triplet >> 12) % 64];
630 data[to] = base64[(whole_triplet >> 18) % 64];
644 switch (orig_len % 3) {
650 data[ostr->
len - 3] =
'=';
651 data[ostr->
len - 4] =
'=';
655 data[ostr->
len - 3] =
'=';
684 for (pos = 0; pos < len; pos++) {
688 if (c >=
'A' && c <=
'Z') {
690 }
else if (c >=
'a' && c <=
'z') {
691 sixbits = 26 + c -
'a';
692 }
else if (c >=
'0' && c <=
'9') {
693 sixbits = 52 + c -
'0';
694 }
else if (c ==
'+') {
696 }
else if (c ==
'/') {
698 }
else if (c ==
'=') {
703 }
else if (isspace(c)) {
708 warning(0,
"Unusual characters in base64 " 715 triplet = (triplet << 6) | sixbits;
719 data[to++] = (triplet >> 16) & 0xff;
720 data[to++] = (triplet >> 8) & 0xff;
721 data[to++] = triplet & 0xff;
731 data[to++] = (triplet >> 10) & 0xff;
732 data[to++] = (triplet >> 2) & 0xff;
735 data[to++] = (triplet >> 4) & 0xff;
738 warning(0,
"Bad padding in base64 encoded text.");
755 unsigned char *endpos;
760 gw_assert(base == 0 || (base >= 2 && base <= 36));
762 if (pos >= ostr->
len) {
768 number = strtol(ostr->
data + pos, &endptr, base);
772 if (endpos == ostr->
data + pos) {
778 return endpos - ostr->
data;
788 unsigned char *endpos;
794 if (pos >= ostr->
len) {
804 if (endpos == ostr->
data + pos) {
810 return endpos - ostr->
data;
817 long end = pos + len;
822 if (pos >= ostr->
len)
827 for ( ; pos < end; pos++) {
828 if (!filter(ostr->
data[pos]))
839 long end = pos + len;
845 if (pos >= ostr->
len)
850 for ( ; pos < end; pos++) {
851 ostr->
data[pos] = map(ostr->
data[pos]);
860 return isprint(c) ? c :
'.';
879 if (ostr1->
len < ostr2->
len)
885 if (ostr1->
len == 0 && ostr2->
len > 0)
887 if (ostr1->
len > 0 && ostr2->
len == 0)
892 ret = memcmp(ostr1->
data, ostr2->
data, len);
894 if (ostr1->
len < ostr2->
len)
896 else if (ostr1->
len > ostr2->
len)
917 if (os1->
len == 0 && os2->
len > 0)
919 if (os1->
len > 0 && os2->
len == 0)
925 for (i = 0; i < len; ++i) {
926 c1 = toupper(os1->
data[i]);
927 c2 = toupper(os2->
data[i]);
933 if (i == os1->
len && i == os2->
len)
959 if ((ostr1->
len < ostr2->
len) && (ostr1->
len < n))
961 else if ((ostr2->
len < ostr1->
len) && (ostr2->
len < n))
969 return memcmp(ostr1->
data, ostr2->
data, len);
979 if (ostr->
data == NULL)
980 return strcmp(
"", str);
982 return strcmp(ostr->
data, str);
992 if (ostr->
data == NULL)
993 return strcasecmp(
"", str);
995 return strcasecmp(ostr->
data, str);
1005 if (ostr->
data == NULL)
1008 return strncmp(ostr->
data, str, n);
1021 if (pos >= ostr->
len)
1024 p = memchr(ostr->
data + pos, ch, ostr->
len - pos);
1027 return p - ostr->
data;
1040 if (pos >= ostr->
len)
1043 for (i = pos; i >= 0; i--) {
1044 if (ostr->
data[i] == ch)
1079 if (needle->
len == 0)
1082 if (needle->
len == 1)
1089 first = needle->
data[0];
1091 while (pos >= 0 && haystack->
len - pos >= needle->
len) {
1092 if (memcmp(haystack->
data + pos,
1093 needle->
data, needle->
len) == 0)
1112 if (needle->
len == 0)
1115 for (i = pos; i <= haystack->
len - needle->
len; ++i) {
1116 for (j = 0; j < needle->
len; ++j) {
1117 c1 = toupper(haystack->
data[i + j]);
1118 c2 = toupper(needle->
data[j]);
1122 if (j == needle->
len)
1139 if (needle->
len == 0)
1142 for (i = pos; i <= haystack->
len - needle->
len && i < n; ++i) {
1143 for (j = 0; j < needle->
len && j < n; ++j) {
1144 c1 = toupper(haystack->
data[i + j]);
1145 c2 = toupper(needle->
data[j]);
1149 if (j == needle->
len)
1166 if (needle == NULL || needle[0] ==
'\0')
1169 needle_len = strlen(needle);
1171 if (needle_len == 1)
1180 while (pos >= 0 && haystack->
len - pos >= needle_len) {
1181 if (memcmp(haystack->
data + pos,
1182 needle, needle_len) == 0)
1198 if (fwrite(ostr->
data, ostr->
len, 1, f) != 1) {
1199 error(errno,
"Couldn't write all of octet string to file.");
1215 for (i = 0; i < ostr->
len; ++i, ++p) {
1217 fprintf(f,
"%c", *p);
1219 fprintf(f,
"\\x%02x", *p);
1230 unsigned char *data;
1239 ret = write(socket, data, len);
1241 if (errno != EINTR) {
1242 error(errno,
"Writing to socket failed");
1269 if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
1271 error(errno,
"Error writing %ld octets to fd %d:",
1282 unsigned char buf[4096];
1289 len = recv(socket, buf,
sizeof(buf), 0);
1290 if (len < 0 && errno == EINTR)
1294 error(errno,
"Could not read from socket %d", socket);
1313 if (ostr2->
len == 0)
1317 memmove(ostr1->
data + pos + ostr2->
len, ostr1->
data + pos,
1319 memcpy(ostr1->
data + pos, ostr2->
data, ostr2->
len);
1320 ostr1->
len += ostr2->
len;
1321 ostr1->
data[ostr1->
len] =
'\0';
1336 if (new_len >= ostr->
len)
1339 ostr->
len = new_len;
1340 ostr->
data[new_len] =
'\0';
1348 int start = 0, end, len = 0;
1364 end = len = len - 1;
1375 return c ==
'\n' || c ==
'\r';
1380 int start = 0, end, len = 0;
1396 end = len = len - 1;
1407 int start = 0, end, len = 0;
1423 end = len = len - 1;
1443 for (i = 0; i < end; i++) {
1471 if (ostr->
len > pos) {
1472 memmove(ostr->
data + pos + len, ostr->
data + pos, ostr->
len - pos);
1474 memcpy(ostr->
data + pos, data, len);
1488 if (ostr->
len > pos)
1489 memmove(ostr->
data + pos + 1, ostr->
data + pos, ostr->
len - pos);
1490 memcpy(ostr->
data + pos, &c, 1);
1519 unsigned char c = ch;
1532 if (pos > ostr1->
len)
1534 if (pos + len > ostr1->
len)
1535 len = ostr1->
len - pos;
1537 memmove(ostr1->
data + pos, ostr1->
data + pos + len,
1538 ostr1->
len - pos - len);
1540 ostr1->
data[ostr1->
len] =
'\0';
1567 while ((n = fread(buf, 1,
sizeof(buf), f)) > 0)
1591 while (fgets(buf,
sizeof(buf), f) != NULL)
1616 while (i < ostr->len && isspace(*p)) {
1622 while (i < ostr->len && !isspace(*p)) {
1643 long next, pos, seplen;
1651 pos = next + seplen;
1677 unsigned char c, *str, *str2, *res, *hexits;
1689 for (i = n = 0, str = ostr->
data, all_safe = 1; i < ostr->len; i++) {
1706 hexits =
"0123456789ABCDEF";
1713 res = str2 = (n ? gw_malloc((len = ostr->
len + 2 * n + 1)) : ostr->
data);
1715 for (i = 0, str = ostr->
data; i < ostr->len; i++) {
1725 *str2++ = hexits[c >> 4 & 0xf];
1726 *str2++ = hexits[c & 0xf];
1736 gw_free(ostr->
data);
1739 ostr->
len = len - 1;
1748 unsigned char *string;
1749 unsigned char *dptr;
1750 int code, code2, ret = 0;
1761 string = ostr->
data;
1765 if (*
string ==
'%') {
1766 if (*(
string + 1) ==
'\0' || *(
string + 2) ==
'\0') {
1767 warning(0,
"octstr_url_decode: corrupted end-of-string <%s>",
string);
1773 code2 =
H2B(*(
string + 2));
1775 if (
code == -1 || code2 == -1) {
1776 warning(0,
"octstr_url_decode: garbage detected (%c%c%c) skipping.",
1777 *
string, *(
string + 1), *(
string + 2));
1778 *dptr++ = *
string++;
1779 *dptr++ = *
string++;
1780 *dptr++ = *
string++;
1785 *dptr++ =
code << 4 | code2;
1788 else if (*
string ==
'+') {
1792 *dptr++ = *
string++;
1796 ostr->
len = (dptr - ostr->
data);
1816 bitpos = bitpos % 8;
1819 if (pos >= ostr->
len)
1822 mask = (1 << numbits) - 1;
1825 if (bitpos + numbits <= 8) {
1828 shiftwidth = 8 - (bitpos + numbits);
1829 return (ostr->
data[pos] >> shiftwidth) & mask;
1834 while (bitpos + numbits > 8) {
1835 result = (result << 8) | ostr->
data[pos];
1836 numbits -= (8 - bitpos);
1839 if (pos >= ostr->
len)
1840 return (result << numbits) & mask;
1845 result |= ostr->
data[pos] >> (8 - numbits);
1846 return result & mask;
1850 unsigned long value)
1865 maxlen = (bitpos + numbits + 7) / 8;
1869 for (pos = ostr->
len; pos <
maxlen; pos++) {
1870 ostr->
data[pos] = 0;
1876 mask = (1 << numbits) - 1;
1881 bitpos = bitpos % 8;
1884 if (bitpos + numbits <= 8) {
1887 shiftwidth = 8 - (bitpos + numbits);
1889 c = ostr->
data[pos] & ~(mask << shiftwidth);
1890 c |= value << shiftwidth;
1892 ostr->
data[pos] = c;
1900 while (bitpos + numbits > 8) {
1904 shiftwidth = numbits - bits;
1906 mask = (1 << bits) - 1;
1908 c = (value >> shiftwidth) & mask;
1911 ostr->
data[pos] = (ostr->
data[pos] & ~mask) | c;
1912 numbits -= (8 - bitpos);
1921 mask = (1 << numbits) - 1;
1922 shiftwidth = 8 - numbits;
1923 c = ostr->
data[pos] & ~(mask << shiftwidth);
1924 c |= value << shiftwidth;
1925 ostr->
data[pos] = c;
1935 unsigned char octets[5];
1941 octets[4] = value & 0x7f;
1944 for (i = 3; value > 0 && i >= 0; i--) {
1945 octets[i] = 0x80 | (value & 0x7f);
1961 for (count = 0; count < 5; count++) {
1965 ui = (ui << 7) | (c & 0x7f);
1968 return pos + count + 1;
1980 sprintf(tmp,
"%ld", value);
1992 unsigned char *p, *d, buf[1024], charbuf[256];
1994 const int octets_per_line = 16;
1995 int c, this_line_begins_at;
2002 debug(
"gwlib.octstr", 0,
"%*sOctet string at %p:", level,
"",
2004 debug(
"gwlib.octstr", 0,
"%*s len: %lu", level,
"",
2005 (
unsigned long) ostr->len);
2006 debug(
"gwlib.octstr", 0,
"%*s size: %lu", level,
"",
2007 (
unsigned long) ostr->size);
2008 debug(
"gwlib.octstr", 0,
"%*s immutable: %d", level,
"",
2014 this_line_begins_at = 0;
2017 sprintf(p,
"%02x ", c);
2018 p = strchr(p,
'\0');
2024 if (pos - this_line_begins_at == octets_per_line) {
2026 debug(
"gwlib.octstr", 0,
"%*s data: %s %s", level,
"",
2032 this_line_begins_at = pos;
2035 if (pos - this_line_begins_at > 0) {
2037 debug(
"gwlib.octstr", 0,
"%*s data: %-*.*s %s", level,
"",
2039 octets_per_line*3, buf, charbuf);
2042 debug(
"gwlib.octstr", 0,
"%*sOctet string dump ends.", level,
"");
2056 #define LLwarning warning 2057 #define LLerror error 2059 #define octstr_dump_LOGLEVEL(loglevel, ostr, level) \ 2061 unsigned char *p, *d, buf[1024], charbuf[256]; \ 2063 const int octets_per_line = 16; \ 2064 int c, this_line_begins_at; \ 2069 seems_valid(ostr); \ 2071 LL##loglevel(0, "%*sOctet string at %p:", level, "", \ 2073 LL##loglevel(0, "%*s len: %lu", level, "", \ 2074 (unsigned long) ostr->len); \ 2075 LL##loglevel(0, "%*s size: %lu", level, "", \ 2076 (unsigned long) ostr->size); \ 2077 LL##loglevel(0, "%*s immutable: %d", level, "", \ 2083 this_line_begins_at = 0; \ 2084 for (pos = 0; pos < octstr_len(ostr); ) { \ 2085 c = octstr_get_char(ostr, pos); \ 2086 sprintf(p, "%02x ", c); \ 2087 p = strchr(p, '\0'); \ 2093 if (pos - this_line_begins_at == octets_per_line) { \ 2095 LL##loglevel(0, "%*s data: %s %s", level, "", \ 2098 charbuf[0] = '\0'; \ 2101 this_line_begins_at = pos; \ 2104 if (pos - this_line_begins_at > 0) { \ 2106 LL##loglevel(0, "%*s data: %-*.*s %s", level, "", \ 2107 octets_per_line*3, \ 2108 octets_per_line*3, buf, charbuf); \ 2111 LL##loglevel(0, "%*sOctet string dump ends.", level, ""); \ 2118 unsigned int loglevel;
2121 loglevel = va_arg(p,
unsigned int);
2152 debug(
"gwlib.octstr", 0,
"%*s%s: NULL", level,
"",
name);
2158 if (ostr->
len < 20) {
2160 for (i = 0; i < ostr->
len; i++) {
2165 }
else if (!isprint(c)) {
2167 }
else if (c ==
'"') {
2170 }
else if (c ==
'\\') {
2177 if (i == ostr->
len) {
2181 debug(
"gwlib.octstr", 0,
"%*s%s: \"%s\"", level,
"",
name, buf);
2186 debug(
"gwlib.octstr", 0,
"%*s%s:", level,
"",
name);
2250 }
else if (isdigit(**(
const unsigned char **) fmt))
2272 }
else if (isdigit(**(
const unsigned char **) fmt))
2290 if (*(*fmt + 1) ==
'l'){
2306 unsigned long long u;
2317 c = va_arg(
VALST(args),
int);
2325 n = va_arg(
VALST(args),
long long);
2328 n = va_arg(
VALST(args),
long);
2331 n = (short) va_arg(
VALST(args), int);
2334 n = va_arg(
VALST(args),
int);
2347 u = va_arg(
VALST(args),
unsigned long);
2350 u = va_arg(
VALST(args),
unsigned long long);
2353 u = (
unsigned short) va_arg(
VALST(args),
unsigned int);
2356 u = va_arg(
VALST(args),
unsigned int);
2363 sprintf(tmpbuf, tmpfmt, u);
2370 sprintf(tmpfmt,
"%%");
2372 strcat(tmpfmt,
"-");
2374 strcat(tmpfmt,
"0");
2376 sprintf(strchr(tmpfmt,
'\0'),
2379 sprintf(strchr(tmpfmt,
'\0'),
2382 sprintf(strchr(tmpfmt,
'\0'),
2384 sprintf(strchr(tmpfmt,
'\0'),
"%c", **fmt);
2385 snprintf(tmpbuf,
sizeof(tmpbuf),
2386 tmpfmt, va_arg(
VALST(args),
double));
2391 s = va_arg(
VALST(args),
char *);
2395 n = (long) strlen(s);
2400 p = va_arg(
VALST(args),
void *);
2401 sprintf(tmpfmt,
"%p", p);
2440 panic(0,
"octstr_format format string syntax error.");
2469 va_start(args, fmt);
2483 while (*fmt !=
'\0') {
2486 n = strcspn(fmt,
"%");
2512 va_start(args, fmt);
2525 unsigned long b = 378551;
2526 unsigned long a = 63689;
2527 unsigned long hash = 0;
2528 unsigned long i = 0;
2532 for(i = 0; i < len; str++, i++) {
2533 hash = hash*a+(*str);
2537 return (hash & 0x7FFFFFFF);
2546 const char *
function)
2551 gw_assert_allocated(ostr,
2557 if (ostr->
size == 0) {
2568 gw_assert_allocated(ostr->
data,
2578 Octstr *octstr_utf8 = NULL;
2579 Octstr *octstr_final = NULL;
2583 goto cleanup_and_exit;
2590 goto cleanup_and_exit;
2600 goto cleanup_and_exit;
2642 if (!isdigit(c) && (c!=
'+'))
2693 len = ostr->
len + (ostr->
len/2);
2696 for (i = 0; i < len; i += 3)
2724 for (i = 0; i < len; ++i) {
2744 #define ENTITY(a,b) \ 2746 octstr_delete(input, i, 1); \ 2747 octstr_insert(input, octstr_imm("&" b ";"), i); \ 2748 i += sizeof(b); break; 2762 #define ENTITY(a,b) { a, b }, 2763 struct entity_struct {
2767 const struct entity_struct entities[] = {
2778 endfind = (
sizeof(entities) /
sizeof(
struct entity_struct)) - 1;
2780 center = startfind + ((endfind - startfind) / 2);
2782 if (matchresult == 0) {
2783 return entities[center].entity;
2785 if (endfind - startfind <= 1) {
2789 if (matchresult < 0) {
2806 int startpos = 0, endpos;
2813 match =
octstr_copy(input, startpos + 1, endpos - startpos - 1);
void error(int err, const char *fmt,...)
static void seems_valid_real(const Octstr *ostr, const char *filename, long lineno, const char *function)
void info(int err, const char *fmt,...)
void octstr_strip_char(Octstr *text, char ch)
int octstr_write_to_socket(int socket, Octstr *ostr)
int octstr_str_case_compare(const Octstr *ostr, const char *str)
void octstr_replace(Octstr *haystack, Octstr *needle, Octstr *repl)
long octstr_search_chars(const Octstr *ostr, const Octstr *chars, long pos)
void octstr_append_data(Octstr *ostr, const char *data, long len)
static int iscrlf(unsigned char c)
void octstr_convert_range(Octstr *ostr, long pos, long len, octstr_func_t map)
int(* octstr_func_t)(int)
void octstr_append_from_hex(Octstr *ostr, char *hex)
gw_assert(wtls_machine->packet_to_send !=NULL)
static int make_printable(int c)
void gwlist_append(List *list, void *item)
int octstr_check_range(Octstr *ostr, long pos, long len, octstr_func_t filter)
void octstr_append(Octstr *ostr1, const Octstr *ostr2)
static char is_safe[UCHAR_MAX+1]
int octstr_append_from_socket(Octstr *ostr, int socket)
static void format_type(struct format *format, const char **fmt)
int octstr_recode(Octstr *tocode, Octstr *fromcode, Octstr *orig)
Octstr * octstr_copy_real(const Octstr *ostr, long from, long len, const char *file, long line, const char *func)
Octstr * octstr_read_pipe(FILE *f)
void octstr_set_bits(Octstr *ostr, long bitpos, int numbits, unsigned long value)
int charset_to_utf8(Octstr *from, Octstr **to, Octstr *charset_from)
int octstr_url_decode(Octstr *ostr)
void octstr_append_char(Octstr *ostr, int ch)
void octstr_replace_first(Octstr *haystack, Octstr *needle, Octstr *repl)
long octstr_search(const Octstr *haystack, const Octstr *needle, long pos)
void octstr_binary_to_base64(Octstr *ostr)
long octstr_case_nsearch(const Octstr *haystack, const Octstr *needle, long pos, long n)
static void format_flags(struct format *format, const char **fmt)
int octstr_print(FILE *f, Octstr *ostr)
void octstr_dump_short(Octstr *ostr, int level, const char *name)
void octstr_shutdown(void)
void octstr_append_cstr(Octstr *ostr, const char *cstr)
void octstr_convert_to_html_entities(Octstr *input)
void octstr_insert_data(Octstr *ostr, long pos, const char *data, long len)
void octstr_strip_blanks(Octstr *text)
long octstr_rsearch_char(const Octstr *ostr, int ch, long pos)
#define octstr_get_cstr(ostr)
#define octstr_copy(ostr, from, len)
void octstr_binary_to_hex(Octstr *ostr, int uppercase)
long octstr_search_char(const Octstr *ostr, int ch, long pos)
Octstr * octstr_duplicate_real(const Octstr *ostr, const char *file, long line, const char *func)
#define octstr_format_valist(fmt, args)
long octstr_str_search(const Octstr *haystack, const char *needle, long pos)
long octstr_parse_double(double *nump, Octstr *ostr, long pos)
static Mutex immutables_mutex
static void format_width(struct format *format, const char **fmt, VALPARM(args))
static Octstr * immutables[MAX_IMMUTABLES]
void octstr_convert_printable(Octstr *ostr)
void octstr_strip_nonalphanums(Octstr *text)
Octstr * octstr_imm(const char *cstr)
void octstr_insert(Octstr *ostr1, const Octstr *ostr2, long pos)
long octstr_get_bits(Octstr *ostr, long bitpos, int numbits)
char * octstr_get_cstr_real(const Octstr *ostr, const char *file, long line, const char *func)
void octstr_delete(Octstr *ostr1, long pos, long len)
void octstr_insert_char(Octstr *ostr, long pos, const char c)
int octstr_ncompare(const Octstr *ostr1, const Octstr *ostr2, long n)
#define octstr_duplicate(ostr)
#define octstr_dump(ostr, level,...)
long octstr_case_search(const Octstr *haystack, const Octstr *needle, long pos)
int octstr_item_match(void *item, void *pattern)
static void convert(Octstr *os, struct format *format, const char **fmt, VALPARM(args))
#define octstr_create_from_data_trace(data, len, file, line, func)
void octstr_dump_real(const Octstr *ostr, int level,...)
#define mutex_init_static(mutex)
int octstr_case_compare(const Octstr *os1, const Octstr *os2)
void warning(int err, const char *fmt,...)
List * octstr_split_words(const Octstr *ostr)
static void octstr_dump_debug(const Octstr *ostr, int level)
unsigned long octstr_hash_key(Octstr *ostr)
static int immutables_init
#define CSTR_TO_LONG(ptr)
#define octstr_dump_LOGLEVEL(loglevel, ostr, level)
Octstr * octstr_format(const char *fmt,...)
void octstr_destroy(Octstr *ostr)
char filename[FILENAME_MAX+1]
#define octstr_create(cstr)
void octstr_destroy_item(void *os)
static void urlcode_init(void)
int octstr_item_case_match(void *item, void *pattern)
static void format_prec(struct format *format, const char **fmt, VALPARM(args))
void mutex_destroy(Mutex *mutex)
static void octstr_grow(Octstr *ostr, long size)
void octstr_base64_to_binary(Octstr *ostr)
long octstr_write_data(Octstr *ostr, int fd, long from)
int octstr_is_all_hex(Octstr *os)
Octstr * octstr_read_file(const char *filename)
void octstr_strip_crlfs(Octstr *text)
Octstr * octstr_create_from_data_real(const char *data, long len, const char *file, long line, const char *func)
long octstr_len(const Octstr *ostr)
void octstr_append_uintvar(Octstr *ostr, unsigned long value)
void octstr_append_decimal(Octstr *ostr, long value)
static int octstr_find_entity(Octstr *input, int startfind, int endfind)
#define seems_valid(ostr)
int charset_from_utf8(Octstr *utf8, Octstr **to, Octstr *charset_to)
void debug(const char *place, int err, const char *fmt,...)
int octstr_hex_to_binary(Octstr *ostr)
int octstr_str_compare(const Octstr *ostr, const char *str)
int octstr_symbolize(Octstr *ostr)
int octstr_str_ncompare(const Octstr *ostr, const char *str, long n)
Octstr * octstr_cat(Octstr *ostr1, Octstr *ostr2)
long octstr_parse_long(long *nump, Octstr *ostr, long pos, int base)
void octstr_format_append(Octstr *os, const char *fmt,...)
void octstr_truncate(Octstr *ostr, int new_len)
long octstr_extract_uintvar(Octstr *ostr, unsigned long *value, long pos)
int octstr_pretty_print(FILE *f, Octstr *ostr)
int octstr_isnum(Octstr *ostr1)
void octstr_get_many_chars(char *buf, Octstr *ostr, long pos, long len)
int octstr_get_char(const Octstr *ostr, long pos)
Octstr * octstr_create_real(const char *cstr, const char *file, long line, const char *func)
void octstr_set_char(Octstr *ostr, long pos, int ch)
void octstr_shrink_blanks(Octstr *text)
#define octstr_create_from_data(data, len)
Octstr * octstr_format_valist_real(const char *fmt, va_list args)
List * octstr_split(const Octstr *os, const Octstr *sep)
void octstr_convert_from_html_entities(Octstr *input)
void octstr_url_encode(Octstr *ostr)
int octstr_compare(const Octstr *ostr1, const Octstr *ostr2)
#define gw_assert_place(expr, file, lineno, func)
void octstr_delete_matching(Octstr *haystack, Octstr *needle)