PageRenderTime 26ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

/src/netbsd/src/external/ibm-public/postfix/dist/src/util/attr_print64.c

https://bitbucket.org/killerpenguinassassins/open_distrib_devel
C | 285 lines | 157 code | 28 blank | 100 comment | 20 complexity | df0ee3628ae9f6e577eaabd5096575fc MD5 | raw file
Possible License(s): CC0-1.0, MIT, LGPL-2.0, LGPL-3.0, WTFPL, GPL-2.0, BSD-2-Clause, AGPL-3.0, CC-BY-SA-3.0, MPL-2.0, JSON, BSD-3-Clause-No-Nuclear-License-2014, LGPL-2.1, CPL-1.0, AGPL-1.0, 0BSD, ISC, Apache-2.0, GPL-3.0, IPL-1.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause
  1. /* $NetBSD: attr_print64.c,v 1.1.1.1 2009/06/23 10:08:58 tron Exp $ */
  2. /*++
  3. /* NAME
  4. /* attr_print64 3
  5. /* SUMMARY
  6. /* send attributes over byte stream
  7. /* SYNOPSIS
  8. /* #include <attr.h>
  9. /*
  10. /* int attr_print64(fp, flags, type, name, ..., ATTR_TYPE_END)
  11. /* VSTREAM fp;
  12. /* int flags;
  13. /* int type;
  14. /* char *name;
  15. /*
  16. /* int attr_vprint64(fp, flags, ap)
  17. /* VSTREAM fp;
  18. /* int flags;
  19. /* va_list ap;
  20. /* DESCRIPTION
  21. /* attr_print64() takes zero or more (name, value) simple attributes
  22. /* and converts its input to a byte stream that can be recovered with
  23. /* attr_scan64(). The stream is not flushed.
  24. /*
  25. /* attr_vprint64() provides an alternate interface that is convenient
  26. /* for calling from within variadic functions.
  27. /*
  28. /* Attributes are sent in the requested order as specified with the
  29. /* attr_print64() argument list. This routine satisfies the formatting
  30. /* rules as outlined in attr_scan64(3).
  31. /*
  32. /* Arguments:
  33. /* .IP fp
  34. /* Stream to write the result to.
  35. /* .IP flags
  36. /* The bit-wise OR of zero or more of the following.
  37. /* .RS
  38. /* .IP ATTR_FLAG_MORE
  39. /* After sending the requested attributes, leave the output stream in
  40. /* a state that is usable for more attribute sending operations on
  41. /* the same output attribute list.
  42. /* By default, attr_print64() automatically appends an attribute list
  43. /* terminator when it has sent the last requested attribute.
  44. /* .RE
  45. /* .IP type
  46. /* The type determines the arguments that follow.
  47. /* .RS
  48. /* .IP "ATTR_TYPE_INT (char *, int)"
  49. /* This argument is followed by an attribute name and an integer.
  50. /* .IP "ATTR_TYPE_LONG (char *, long)"
  51. /* This argument is followed by an attribute name and a long integer.
  52. /* .IP "ATTR_TYPE_STR (char *, char *)"
  53. /* This argument is followed by an attribute name and a null-terminated
  54. /* string.
  55. /* .IP "ATTR_TYPE_DATA (char *, ssize_t, char *)"
  56. /* This argument is followed by an attribute name, an attribute value
  57. /* length, and an attribute value pointer.
  58. /* .IP "ATTR_TYPE_FUNC (ATTR_PRINT_SLAVE_FN, void *)"
  59. /* This argument is followed by a function pointer and generic data
  60. /* pointer. The caller-specified function returns whatever the
  61. /* specified attribute printing function returns.
  62. /* .IP "ATTR_TYPE_HASH (HTABLE *)"
  63. /* .IP "ATTR_TYPE_NAMEVAL (NVTABLE *)"
  64. /* The content of the table is sent as a sequence of string-valued
  65. /* attributes with names equal to the table lookup keys.
  66. /* .IP ATTR_TYPE_END
  67. /* This terminates the attribute list.
  68. /* .RE
  69. /* DIAGNOSTICS
  70. /* The result value is 0 in case of success, VSTREAM_EOF in case
  71. /* of trouble.
  72. /*
  73. /* Panic: interface violation. All system call errors are fatal.
  74. /* SEE ALSO
  75. /* attr_scan64(3) recover attributes from byte stream
  76. /* LICENSE
  77. /* .ad
  78. /* .fi
  79. /* The Secure Mailer license must be distributed with this software.
  80. /* AUTHOR(S)
  81. /* Wietse Venema
  82. /* IBM T.J. Watson Research
  83. /* P.O. Box 704
  84. /* Yorktown Heights, NY 10598, USA
  85. /*--*/
  86. /* System library. */
  87. #include <sys_defs.h>
  88. #include <stdarg.h>
  89. #include <string.h>
  90. /* Utility library. */
  91. #include <msg.h>
  92. #include <mymalloc.h>
  93. #include <vstream.h>
  94. #include <htable.h>
  95. #include <base64_code.h>
  96. #include <attr.h>
  97. #define STR(x) vstring_str(x)
  98. #define LEN(x) VSTRING_LEN(x)
  99. /* attr_print64_str - encode and send attribute information */
  100. static void attr_print64_str(VSTREAM *fp, const char *str, ssize_t len)
  101. {
  102. static VSTRING *base64_buf;
  103. if (base64_buf == 0)
  104. base64_buf = vstring_alloc(10);
  105. base64_encode(base64_buf, str, len);
  106. vstream_fputs(STR(base64_buf), fp);
  107. }
  108. static void attr_print64_num(VSTREAM *fp, unsigned num)
  109. {
  110. static VSTRING *plain;
  111. if (plain == 0)
  112. plain = vstring_alloc(10);
  113. vstring_sprintf(plain, "%u", num);
  114. attr_print64_str(fp, STR(plain), LEN(plain));
  115. }
  116. static void attr_print64_long_num(VSTREAM *fp, unsigned long long_num)
  117. {
  118. static VSTRING *plain;
  119. if (plain == 0)
  120. plain = vstring_alloc(10);
  121. vstring_sprintf(plain, "%lu", long_num);
  122. attr_print64_str(fp, STR(plain), LEN(plain));
  123. }
  124. /* attr_vprint64 - send attribute list to stream */
  125. int attr_vprint64(VSTREAM *fp, int flags, va_list ap)
  126. {
  127. const char *myname = "attr_print64";
  128. int attr_type;
  129. char *attr_name;
  130. unsigned int_val;
  131. unsigned long long_val;
  132. char *str_val;
  133. HTABLE_INFO **ht_info_list;
  134. HTABLE_INFO **ht;
  135. ssize_t len_val;
  136. ATTR_PRINT_SLAVE_FN print_fn;
  137. void *print_arg;
  138. /*
  139. * Sanity check.
  140. */
  141. if (flags & ~ATTR_FLAG_ALL)
  142. msg_panic("%s: bad flags: 0x%x", myname, flags);
  143. /*
  144. * Iterate over all (type, name, value) triples, and produce output on
  145. * the fly.
  146. */
  147. while ((attr_type = va_arg(ap, int)) != ATTR_TYPE_END) {
  148. switch (attr_type) {
  149. case ATTR_TYPE_INT:
  150. attr_name = va_arg(ap, char *);
  151. attr_print64_str(fp, attr_name, strlen(attr_name));
  152. int_val = va_arg(ap, int);
  153. VSTREAM_PUTC(':', fp);
  154. attr_print64_num(fp, (unsigned) int_val);
  155. VSTREAM_PUTC('\n', fp);
  156. if (msg_verbose)
  157. msg_info("send attr %s = %u", attr_name, int_val);
  158. break;
  159. case ATTR_TYPE_LONG:
  160. attr_name = va_arg(ap, char *);
  161. attr_print64_str(fp, attr_name, strlen(attr_name));
  162. long_val = va_arg(ap, long);
  163. VSTREAM_PUTC(':', fp);
  164. attr_print64_long_num(fp, (unsigned long) long_val);
  165. VSTREAM_PUTC('\n', fp);
  166. if (msg_verbose)
  167. msg_info("send attr %s = %lu", attr_name, long_val);
  168. break;
  169. case ATTR_TYPE_STR:
  170. attr_name = va_arg(ap, char *);
  171. attr_print64_str(fp, attr_name, strlen(attr_name));
  172. str_val = va_arg(ap, char *);
  173. VSTREAM_PUTC(':', fp);
  174. attr_print64_str(fp, str_val, strlen(str_val));
  175. VSTREAM_PUTC('\n', fp);
  176. if (msg_verbose)
  177. msg_info("send attr %s = %s", attr_name, str_val);
  178. break;
  179. case ATTR_TYPE_DATA:
  180. attr_name = va_arg(ap, char *);
  181. attr_print64_str(fp, attr_name, strlen(attr_name));
  182. len_val = va_arg(ap, ssize_t);
  183. str_val = va_arg(ap, char *);
  184. VSTREAM_PUTC(':', fp);
  185. attr_print64_str(fp, str_val, len_val);
  186. VSTREAM_PUTC('\n', fp);
  187. if (msg_verbose)
  188. msg_info("send attr %s = [data %ld bytes]",
  189. attr_name, (long) len_val);
  190. break;
  191. case ATTR_TYPE_FUNC:
  192. print_fn = va_arg(ap, ATTR_PRINT_SLAVE_FN);
  193. print_arg = va_arg(ap, void *);
  194. print_fn(attr_print64, fp, flags | ATTR_FLAG_MORE, print_arg);
  195. break;
  196. case ATTR_TYPE_HASH:
  197. ht_info_list = htable_list(va_arg(ap, HTABLE *));
  198. for (ht = ht_info_list; *ht; ht++) {
  199. attr_print64_str(fp, ht[0]->key, strlen(ht[0]->key));
  200. VSTREAM_PUTC(':', fp);
  201. attr_print64_str(fp, ht[0]->value, strlen(ht[0]->value));
  202. VSTREAM_PUTC('\n', fp);
  203. if (msg_verbose)
  204. msg_info("send attr name %s value %s",
  205. ht[0]->key, ht[0]->value);
  206. }
  207. myfree((char *) ht_info_list);
  208. break;
  209. default:
  210. msg_panic("%s: unknown type code: %d", myname, attr_type);
  211. }
  212. }
  213. if ((flags & ATTR_FLAG_MORE) == 0)
  214. VSTREAM_PUTC('\n', fp);
  215. return (vstream_ferror(fp));
  216. }
  217. int attr_print64(VSTREAM *fp, int flags,...)
  218. {
  219. va_list ap;
  220. int ret;
  221. va_start(ap, flags);
  222. ret = attr_vprint64(fp, flags, ap);
  223. va_end(ap);
  224. return (ret);
  225. }
  226. #ifdef TEST
  227. /*
  228. * Proof of concept test program. Mirror image of the attr_scan64 test
  229. * program.
  230. */
  231. #include <msg_vstream.h>
  232. int main(int unused_argc, char **argv)
  233. {
  234. HTABLE *table = htable_create(1);
  235. msg_vstream_init(argv[0], VSTREAM_ERR);
  236. msg_verbose = 1;
  237. htable_enter(table, "foo-name", mystrdup("foo-value"));
  238. htable_enter(table, "bar-name", mystrdup("bar-value"));
  239. attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
  240. ATTR_TYPE_INT, ATTR_NAME_INT, 4711,
  241. ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
  242. ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
  243. ATTR_TYPE_DATA, ATTR_NAME_DATA, strlen("whoopee"), "whoopee",
  244. ATTR_TYPE_HASH, table,
  245. ATTR_TYPE_END);
  246. attr_print64(VSTREAM_OUT, ATTR_FLAG_NONE,
  247. ATTR_TYPE_INT, ATTR_NAME_INT, 4711,
  248. ATTR_TYPE_LONG, ATTR_NAME_LONG, 1234,
  249. ATTR_TYPE_STR, ATTR_NAME_STR, "whoopee",
  250. ATTR_TYPE_DATA, ATTR_NAME_DATA, strlen("whoopee"), "whoopee",
  251. ATTR_TYPE_END);
  252. if (vstream_fflush(VSTREAM_OUT) != 0)
  253. msg_fatal("write error: %m");
  254. htable_free(table, myfree);
  255. return (0);
  256. }
  257. #endif