1 /*	$Id$ */
2 /*
3  * Copyright (c) 2012, 2014--2018 Kristaps Dzonsons <kristaps@bsd.lv>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #ifndef KCGI_H
18 #define KCGI_H
19 
20 #if !defined(__BEGIN_DECLS)
21 #  ifdef __cplusplus
22 #  define       __BEGIN_DECLS           extern "C" {
23 #  else
24 #  define       __BEGIN_DECLS
25 #  endif
26 #endif
27 #if !defined(__END_DECLS)
28 #  ifdef __cplusplus
29 #  define       __END_DECLS             }
30 #  else
31 #  define       __END_DECLS
32 #  endif
33 #endif
34 
35 /*
36  * Stringification of version major, minor, and build.
37  */
38 #define NAME(s) NAME0(s)
39 #define NAME0(s) #s
40 #define NAME2(x,y,z) x ## . ## y ## . ## z
41 #define NAME1(x,y,z) NAME2(x,y,z)
42 
43 /*
44  * Major version.
45  */
46 #define	KCGI_VMAJOR	0
47 
48 /*
49  * Minor version.
50  */
51 #define	KCGI_VMINOR	13
52 
53 /*
54  * Build version.
55  */
56 #define	KCGI_VBUILD	0
57 
58 /*
59  * Version string of major.minor.build (as a literal string).
60  */
61 #define	KCGI_VERSION	NAME(NAME1(KCGI_VMAJOR,KCGI_VMINOR,KCGI_VBUILD))
62 
63 /*
64  * Integral stamp of version.
65  * Guaranteed to be increasing with build, minor, and major.
66  * (Assumes build and minor never go over 100.)
67  */
68 #define	KCGI_VSTAMP \
69 	((KCGI_VBUILD+1) + \
70 	 (KCGI_VMINOR+1)*100 + \
71 	 (KCGI_VMAJOR+1)*10000)
72 
73 /*
74  * All of the public functions, variables, and structures in this header
75  * file are described in kcgi(3).
76  * If you don't see something in kcgi(3) and see it here instead, it
77  * shouldn't be used.
78  */
79 
80 enum	khttp {
81 	KHTTP_100,
82 	KHTTP_101,
83 	KHTTP_103,
84 	KHTTP_200,
85 	KHTTP_201,
86 	KHTTP_202,
87 	KHTTP_203,
88 	KHTTP_204,
89 	KHTTP_205,
90 	KHTTP_206,
91 	KHTTP_207,
92 	KHTTP_300,
93 	KHTTP_301,
94 	KHTTP_302,
95 	KHTTP_303,
96 	KHTTP_304,
97 	KHTTP_306,
98 	KHTTP_307,
99 	KHTTP_308,
100 	KHTTP_400,
101 	KHTTP_401,
102 	KHTTP_402,
103 	KHTTP_403,
104 	KHTTP_404,
105 	KHTTP_405,
106 	KHTTP_406,
107 	KHTTP_407,
108 	KHTTP_408,
109 	KHTTP_409,
110 	KHTTP_410,
111 	KHTTP_411,
112 	KHTTP_412,
113 	KHTTP_413,
114 	KHTTP_414,
115 	KHTTP_415,
116 	KHTTP_416,
117 	KHTTP_417,
118 	KHTTP_424,
119 	KHTTP_428,
120 	KHTTP_429,
121 	KHTTP_431,
122 	KHTTP_500,
123 	KHTTP_501,
124 	KHTTP_502,
125 	KHTTP_503,
126 	KHTTP_504,
127 	KHTTP_505,
128 	KHTTP_507,
129 	KHTTP_511,
130 	KHTTP__MAX
131 };
132 
133 enum	krequ {
134 	KREQU_ACCEPT,
135 	KREQU_ACCEPT_CHARSET,
136 	KREQU_ACCEPT_ENCODING,
137 	KREQU_ACCEPT_LANGUAGE,
138 	KREQU_AUTHORIZATION,
139 	KREQU_DEPTH,
140 	KREQU_FROM,
141 	KREQU_HOST,
142 	KREQU_IF,
143 	KREQU_IF_MODIFIED_SINCE,
144 	KREQU_IF_MATCH,
145 	KREQU_IF_NONE_MATCH,
146 	KREQU_IF_RANGE,
147 	KREQU_IF_UNMODIFIED_SINCE,
148 	KREQU_MAX_FORWARDS,
149 	KREQU_PROXY_AUTHORIZATION,
150 	KREQU_RANGE,
151 	KREQU_REFERER,
152 	KREQU_USER_AGENT,
153 	KREQU__MAX
154 };
155 
156 enum	kresp {
157 	KRESP_ACCESS_CONTROL_ALLOW_ORIGIN,
158 	KRESP_ACCEPT_RANGES,
159 	KRESP_AGE,
160 	KRESP_ALLOW,
161 	KRESP_CACHE_CONTROL,
162 	KRESP_CONNECTION,
163 	KRESP_CONTENT_ENCODING,
164 	KRESP_CONTENT_LANGUAGE,
165 	KRESP_CONTENT_LENGTH,
166 	KRESP_CONTENT_LOCATION,
167 	KRESP_CONTENT_MD5,
168 	KRESP_CONTENT_DISPOSITION,
169 	KRESP_CONTENT_RANGE,
170 	KRESP_CONTENT_TYPE,
171 	KRESP_DATE,
172 	KRESP_ETAG,
173 	KRESP_EXPIRES,
174 	KRESP_LAST_MODIFIED,
175 	KRESP_LINK,
176 	KRESP_LOCATION,
177 	KRESP_P3P,
178 	KRESP_PRAGMA,
179 	KRESP_PROXY_AUTHENTICATE,
180 	KRESP_REFRESH,
181 	KRESP_RETRY_AFTER,
182 	KRESP_SERVER,
183 	KRESP_SET_COOKIE,
184 	KRESP_STATUS,
185 	KRESP_STRICT_TRANSPORT_SECURITY,
186 	KRESP_TRAILER,
187 	KRESP_TRANSFER_ENCODING,
188 	KRESP_UPGRADE,
189 	KRESP_VARY,
190 	KRESP_VIA,
191 	KRESP_WARNING,
192 	KRESP_WWW_AUTHENTICATE,
193 	KRESP_X_FRAME_OPTIONS,
194 	KRESP__MAX
195 };
196 
197 enum	kattrx {
198 	KATTRX_STRING,
199 	KATTRX_INT,
200 	KATTRX_DOUBLE
201 };
202 
203 enum	kmethod {
204 	KMETHOD_ACL,
205 	KMETHOD_CONNECT,
206 	KMETHOD_COPY,
207 	KMETHOD_DELETE,
208 	KMETHOD_GET,
209 	KMETHOD_HEAD,
210 	KMETHOD_LOCK,
211 	KMETHOD_MKCALENDAR,
212 	KMETHOD_MKCOL,
213 	KMETHOD_MOVE,
214 	KMETHOD_OPTIONS,
215 	KMETHOD_POST,
216 	KMETHOD_PROPFIND,
217 	KMETHOD_PROPPATCH,
218 	KMETHOD_PUT,
219 	KMETHOD_REPORT,
220 	KMETHOD_TRACE,
221 	KMETHOD_UNLOCK,
222 	KMETHOD__MAX
223 };
224 
225 enum	kpairtype {
226 	KPAIR_INTEGER,
227 	KPAIR_STRING,
228 	KPAIR_DOUBLE,
229 	KPAIR__MAX
230 };
231 
232 enum	kscheme {
233 	KSCHEME_AAA,
234 	KSCHEME_AAAS,
235 	KSCHEME_ABOUT,
236 	KSCHEME_ACAP,
237 	KSCHEME_ACCT,
238 	KSCHEME_CAP,
239 	KSCHEME_CID,
240 	KSCHEME_COAP,
241 	KSCHEME_COAPS,
242 	KSCHEME_CRID,
243 	KSCHEME_DATA,
244 	KSCHEME_DAV,
245 	KSCHEME_DICT,
246 	KSCHEME_DNS,
247 	KSCHEME_FILE,
248 	KSCHEME_FTP,
249 	KSCHEME_GEO,
250 	KSCHEME_GO,
251 	KSCHEME_GOPHER,
252 	KSCHEME_H323,
253 	KSCHEME_HTTP,
254 	KSCHEME_HTTPS,
255 	KSCHEME_IAX,
256 	KSCHEME_ICAP,
257 	KSCHEME_IM,
258 	KSCHEME_IMAP,
259 	KSCHEME_INFO,
260 	KSCHEME_IPP,
261 	KSCHEME_IRIS,
262 	KSCHEME_IRIS_BEEP,
263 	KSCHEME_IRIS_XPC,
264 	KSCHEME_IRIS_XPCS,
265 	KSCHEME_IRIS_LWZ,
266 	KSCHEME_JABBER,
267 	KSCHEME_LDAP,
268 	KSCHEME_MAILTO,
269 	KSCHEME_MID,
270 	KSCHEME_MSRP,
271 	KSCHEME_MSRPS,
272 	KSCHEME_MTQP,
273 	KSCHEME_MUPDATE,
274 	KSCHEME_NEWS,
275 	KSCHEME_NFS,
276 	KSCHEME_NI,
277 	KSCHEME_NIH,
278 	KSCHEME_NNTP,
279 	KSCHEME_OPAQUELOCKTOKEN,
280 	KSCHEME_POP,
281 	KSCHEME_PRES,
282 	KSCHEME_RELOAD,
283 	KSCHEME_RTSP,
284 	KSCHEME_RTSPS,
285 	KSCHEME_RTSPU,
286 	KSCHEME_SERVICE,
287 	KSCHEME_SESSION,
288 	KSCHEME_SHTTP,
289 	KSCHEME_SIEVE,
290 	KSCHEME_SIP,
291 	KSCHEME_SIPS,
292 	KSCHEME_SMS,
293 	KSCHEME_SNMP,
294 	KSCHEME_SOAP_BEEP,
295 	KSCHEME_SOAP_BEEPS,
296 	KSCHEME_STUN,
297 	KSCHEME_STUNS,
298 	KSCHEME_TAG,
299 	KSCHEME_TEL,
300 	KSCHEME_TELNET,
301 	KSCHEME_TFTP,
302 	KSCHEME_THISMESSAGE,
303 	KSCHEME_TN3270,
304 	KSCHEME_TIP,
305 	KSCHEME_TURN,
306 	KSCHEME_TURNS,
307 	KSCHEME_TV,
308 	KSCHEME_URN,
309 	KSCHEME_VEMMI,
310 	KSCHEME_WS,
311 	KSCHEME_WSS,
312 	KSCHEME_XCON,
313 	KSCHEME_XCON_USERID,
314 	KSCHEME_XMLRPC_BEEP,
315 	KSCHEME_XMLRPC_BEEPS,
316 	KSCHEME_XMPP,
317 	KSCHEME_Z39_50R,
318 	KSCHEME_Z39_50S,
319 	KSCHEME__MAX
320 };
321 
322 enum	kmime {
323 	KMIME_APP_JAVASCRIPT,
324 	KMIME_APP_JSON,
325 	KMIME_APP_OCTET_STREAM,
326 	KMIME_APP_PDF,
327 	KMIME_APP_XML,
328 	KMIME_APP_ZIP,
329 	KMIME_IMAGE_GIF,
330 	KMIME_IMAGE_JPEG,
331 	KMIME_IMAGE_PNG,
332 	KMIME_IMAGE_SVG_XML,
333 	KMIME_TEXT_CALENDAR,
334 	KMIME_TEXT_CSS,
335 	KMIME_TEXT_CSV,
336 	KMIME_TEXT_HTML,
337 	KMIME_TEXT_PLAIN,
338 	KMIME_TEXT_XML,
339 	KMIME__MAX
340 };
341 
342 struct	kmimemap {
343 	const char	*name;
344 	size_t		 mime;
345 };
346 
347 enum	kpairstate {
348 	KPAIR_UNCHECKED = 0,
349 	KPAIR_VALID,
350 	KPAIR_INVALID
351 };
352 
353 #define KREQ_DEBUG_WRITE	  0x01
354 #define KREQ_DEBUG_READ_BODY	  0x02
355 
356 struct	kpair {
357 	char		*key; /* key name */
358 	size_t		 keypos; /* bucket (if assigned) */
359 	char		*val; /*  key value */
360 	size_t		 valsz; /* length of "val" */
361 	char		*file; /* content filename (or NULL) */
362 	char		*ctype; /* content type (or NULL) */
363 	size_t		 ctypepos; /* content type index */
364 	char		*xcode; /* content xfer encoding (or NULL) */
365 	struct kpair	*next; /* next in map entry */
366 	enum kpairstate	 state; /* parse state */
367 	enum kpairtype	 type; /* if parsed, the parse type */
368 	union parsed {
369 		int64_t i; /* validated integer */
370 		const char *s; /* validated string */
371 		double d; /* validated decimal */
372 	} parsed;
373 };
374 
375 struct	kreq; /* forward declaration */
376 struct	kfcgi;
377 
378 struct	kvalid {
379 	int		(*valid)(struct kpair *kp);
380 	const char	 *name;
381 };
382 
383 enum	kauth {
384 	KAUTH_NONE = 0,
385 	KAUTH_BASIC,
386 	KAUTH_DIGEST,
387 	KAUTH_BEARER,
388 	KAUTH_UNKNOWN
389 };
390 
391 enum	khttpalg {
392 	KHTTPALG_MD5 = 0,
393 	KHTTPALG_MD5_SESS,
394 	KHTTPALG__MAX
395 };
396 
397 enum	khttpqop {
398 	KHTTPQOP_NONE = 0,
399 	KHTTPQOP_AUTH,
400 	KHTTPQOP_AUTH_INT,
401 	KHTTPQOP__MAX
402 };
403 
404 struct	khttpdigest {
405 	enum khttpalg	 alg;
406 	enum khttpqop	 qop;
407 	char		*user;
408 	char		*uri;
409 	char		*realm;
410 	char		*nonce;
411 	char		*cnonce;
412 	char		*response;
413 	uint32_t	 count;
414 	char		*opaque;
415 };
416 
417 struct	khttpbasic {
418 	char		*response;
419 };
420 
421 struct	khttpauth {
422 	enum kauth	 type;
423 	int		 authorised;
424 	char		*digest;
425 	union {
426 		struct khttpdigest digest;
427 		struct khttpbasic basic;
428 	} d;
429 };
430 
431 struct	kdata;
432 
433 struct	khead {
434 	char		*key;
435 	char		*val;
436 };
437 
438 struct	kreq {
439 	struct khead		 *reqmap[KREQU__MAX];
440 	struct khead		 *reqs;
441 	size_t		 	  reqsz;
442 	enum kmethod		  method;
443 	enum kauth		  auth;
444 	struct khttpauth	  rawauth;
445 	struct kpair		 *cookies;
446 	size_t			  cookiesz;
447 	struct kpair		**cookiemap;
448 	struct kpair		**cookienmap;
449 	struct kpair		 *fields;
450 	struct kpair		**fieldmap;
451 	struct kpair		**fieldnmap;
452 	size_t			  fieldsz;
453 	size_t			  mime;
454 	size_t			  page;
455 	enum kscheme		  scheme;
456 	char			 *path;
457 	char			 *suffix;
458 	char			 *fullpath;
459 	char			 *pagename;
460 	char			 *remote;
461 	char			 *host;
462 	uint16_t		  port;
463 	struct kdata		 *kdata;
464 	const struct kvalid	 *keys;
465 	size_t			  keysz;
466 	char			 *pname;
467 	void			 *arg;
468 };
469 
470 struct	kopts {
471 	ssize_t		  	  sndbufsz;
472 };
473 
474 struct	kcgi_buf {
475 	char		*buf; /* buffer contents */
476 	size_t		 maxsz; /* buffer size (allocated) */
477 	size_t		 sz; /* buffer current length */
478 	size_t		 growsz; /* amount to grow (0 == default) */
479 };
480 
481 struct	ktemplate {
482 	const char *const	 *key;
483 	size_t		 	  keysz;
484 	void		 	 *arg;
485 	int		 	(*cb)(size_t, void *);
486 };
487 
488 enum	kcgi_err {
489 	KCGI_OK = 0,
490 	/* ENOMEM (fork, malloc, etc.). */
491 	KCGI_ENOMEM,
492 	/* FastCGI request to exit. */
493 	KCGI_EXIT,
494 	/* FastCGI connection has closed. */
495 	KCGI_HUP,
496 	/* ENFILE or EMFILE (fd ops). */
497 	KCGI_ENFILE,
498 	/* EAGAIN (fork). */
499 	KCGI_EAGAIN,
500 	/* Internal system error (malformed data). */
501 	KCGI_FORM,
502 	/* Opaque operating-system error. */
503 	KCGI_SYSTEM,
504 	/* Writer error. */
505 	KCGI_WRITER
506 };
507 
508 typedef enum kcgi_err (*ktemplate_writef)(const char *, size_t, void *);
509 
510 struct	ktemplatex {
511 	ktemplate_writef	 writer;
512 	int			(*fbk)(const char *, size_t, void *);
513 };
514 
515 __BEGIN_DECLS
516 
517 const char	*kcgi_strerror(enum kcgi_err);
518 
519 enum kcgi_err	 khttp_body(struct kreq *);
520 enum kcgi_err	 khttp_body_compress(struct kreq *, int);
521 void		 khttp_free(struct kreq *);
522 void		 khttp_child_free(struct kreq *);
523 enum kcgi_err	 khttp_head(struct kreq *, const char *,
524 			const char *, ...)
525 			__attribute__((format(printf, 3, 4)));
526 enum kcgi_err	 khttp_parse(struct kreq *,
527 			const struct kvalid *, size_t,
528 			const char *const *, size_t, size_t);
529 enum kcgi_err	 khttp_parsex(struct kreq *, const struct kmimemap *,
530 			const char *const *, size_t,
531 			const struct kvalid *, size_t,
532 			const char *const *, size_t,
533 			size_t, size_t, void *, void (*)(void *),
534 			unsigned int, const struct kopts *);
535 enum kcgi_err	 khttp_printf(struct kreq *, const char *, ...)
536 			__attribute__((format(printf, 2, 3)));
537 enum kcgi_err	 khttp_putc(struct kreq *, int);
538 enum kcgi_err	 khttp_puts(struct kreq *, const char *);
539 enum kcgi_err	 khttp_template(struct kreq *,
540 			const struct ktemplate *, const char *);
541 enum kcgi_err	 khttp_template_fd(struct kreq *,
542 			const struct ktemplate *, int, const char *);
543 enum kcgi_err	 khttp_template_buf(struct kreq *,
544 			const struct ktemplate *, const char *,
545 			size_t);
546 enum kcgi_err	 khttp_templatex(const struct ktemplate *,
547 			const char *, const struct ktemplatex *,
548 			void *);
549 enum kcgi_err	 khttp_templatex_buf(const struct ktemplate *,
550 			const char *, size_t,
551 			const struct ktemplatex *, void *);
552 enum kcgi_err	 khttp_templatex_fd(const struct ktemplate *,
553 			int, const char *,
554 			const struct ktemplatex *, void *);
555 enum kcgi_err	 khttp_write(struct kreq *, const char *, size_t);
556 
557 enum kcgi_err	 kcgi_buf_printf(struct kcgi_buf *, const char *, ...)
558 			__attribute__((format(printf, 2, 3)));
559 enum kcgi_err	 kcgi_buf_putc(struct kcgi_buf *, char);
560 enum kcgi_err	 kcgi_buf_puts(struct kcgi_buf *, const char *);
561 enum kcgi_err	 kcgi_buf_write(const char *, size_t, void *);
562 
563 int		 khttpdigest_validate(const struct kreq *,
564 			const char *);
565 int		 khttpdigest_validatehash(const struct kreq *,
566 			const char *);
567 int		 khttpbasic_validate(const struct kreq *,
568 			const char *, const char *);
569 
570 int		 kvalid_bit(struct kpair *);
571 int		 kvalid_date(struct kpair *);
572 int		 kvalid_double(struct kpair *);
573 int		 kvalid_email(struct kpair *);
574 int		 kvalid_int(struct kpair *);
575 int		 kvalid_string(struct kpair *);
576 int		 kvalid_stringne(struct kpair *);
577 int		 kvalid_udouble(struct kpair *);
578 int		 kvalid_uint(struct kpair *);
579 
580 void		 kcgi_writer_disable(struct kreq *);
581 
582 enum kcgi_err	 khttp_fcgi_parse(struct kfcgi *, struct kreq *);
583 enum kcgi_err	 khttp_fcgi_init(struct kfcgi **,
584 			const struct kvalid *, size_t,
585 			const char *const *, size_t, size_t);
586 enum kcgi_err	 khttp_fcgi_initx(struct kfcgi **,
587 			const char *const *, size_t,
588 			const struct kvalid *, size_t,
589 			const struct kmimemap *, size_t,
590 			const char *const *, size_t, size_t,
591 			void *, void (*)(void *), unsigned int,
592 			const struct kopts *);
593 enum kcgi_err	 khttp_fcgi_free(struct kfcgi *);
594 void		 khttp_fcgi_child_free(struct kfcgi *);
595 int		 khttp_fcgi_test(void);
596 
597 void		 khttp_epoch2datetime(int64_t, int64_t *, int64_t *,
598 			int64_t *, int64_t *, int64_t *, int64_t *,
599 			int64_t *, int64_t *);
600 char		*khttp_epoch2str(int64_t, char *, size_t);
601 char		*khttp_epoch2ustr(int64_t, char *, size_t);
602 int		 khttp_epoch2tms(int64_t, int *, int *, int *,
603 			int *, int *, int *, int *, int *);
604 #define		 KHTTP_EPOCH2TM(_tt, _tm) \
605 		 khttp_epoch2tms((_tt), \
606 			&(_tm)->tm_sec, \
607 			&(_tm)->tm_min, \
608 			&(_tm)->tm_hour, \
609 			&(_tm)->tm_mday, \
610 			&(_tm)->tm_mon, \
611 			&(_tm)->tm_year, \
612 			&(_tm)->tm_wday, \
613 			&(_tm)->tm_yday)
614 int	 	 khttp_datetime2epoch(int64_t *, int64_t, int64_t,
615 			int64_t, int64_t, int64_t, int64_t);
616 int	 	 khttp_date2epoch(int64_t *, int64_t, int64_t,
617 			int64_t);
618 
619 char 		*khttp_urlabs(enum kscheme, const char *,
620 			uint16_t, const char *, ...);
621 enum kcgi_err	 khttp_urldecode(const char *, char **);
622 enum kcgi_err	 khttp_urldecode_inplace(char *);
623 char		*khttp_urlencode(const char *);
624 char		*khttp_urlpart(const char *,
625 			const char *, const char *, ...);
626 char		*khttp_urlpartx(const char *,
627 			const char *, const char *, ...);
628 char 		*khttp_vurlabs(enum kscheme, const char *,
629 			uint16_t, const char *, va_list);
630 char		*khttp_vurlpart(const char *,
631 			const char *, const char *, va_list);
632 char		*khttp_vurlpartx(const char *,
633 			const char *, const char *, va_list);
634 
635 void		 kutil_invalidate(struct kreq *, struct kpair *);
636 
637 int		 kutil_openlog(const char *);
638 void	 	 kutil_verr(const struct kreq *,
639 			const char *, const char *, va_list)
640 			__attribute__((format(printf, 3, 0)))
641 			__attribute__((__noreturn__));
642 void	 	 kutil_verrx(const struct kreq *,
643 			const char *, const char *, va_list)
644 			__attribute__((format(printf, 3, 0)))
645 			__attribute__((__noreturn__));
646 void		 kutil_vinfo(const struct kreq *,
647 			const char *, const char *, va_list)
648 			__attribute__((format(printf, 3, 0)));
649 void		 kutil_vlog(const struct kreq *, const char *,
650 			const char *, const char *, va_list)
651 			__attribute__((format(printf, 4, 0)));
652 void		 kutil_vlogx(const struct kreq *, const char *,
653 			const char *, const char *, va_list)
654 			__attribute__((format(printf, 4, 0)));
655 void		 kutil_vwarn(const struct kreq *,
656 			const char *, const char *, va_list)
657 			__attribute__((format(printf, 3, 0)));
658 void		 kutil_vwarnx(const struct kreq *,
659 			const char *, const char *, va_list)
660 			__attribute__((format(printf, 3, 0)));
661 void		 kutil_log(const struct kreq *, const char *,
662 			const char *, const char *, ...)
663 			__attribute__((format(printf, 4, 5)));
664 void		 kutil_logx(const struct kreq *, const char *,
665 			const char *, const char *, ...)
666 			__attribute__((format(printf, 4, 5)));
667 void		 kutil_info(const struct kreq *,
668 			const char *, const char *, ...)
669 			__attribute__((format(printf, 3, 4)));
670 void		 kutil_warn(const struct kreq *,
671 			const char *, const char *, ...)
672 			__attribute__((format(printf, 3, 4)));
673 void		 kutil_warnx(const struct kreq *,
674 			const char *, const char *, ...)
675 			__attribute__((format(printf, 3, 4)));
676 void		 kutil_err(const struct kreq *,
677 			const char *, const char *, ...)
678 			__attribute__((format(printf, 3, 4)))
679 			__attribute__((__noreturn__));
680 void		 kutil_errx(const struct kreq *,
681 			const char *, const char *, ...)
682 			__attribute__((format(printf, 3, 4)))
683 			__attribute__((__noreturn__));
684 
685 int		 kasprintf(char **, const char *, ...)
686 			__attribute__((format(printf, 2, 3)));
687 int		 kvasprintf(char **, const char *, va_list)
688 			__attribute__((format(printf, 2, 0)));
689 void		*kcalloc(size_t, size_t);
690 void		*kmalloc(size_t);
691 void		*krealloc(void *, size_t);
692 void		*kreallocarray(void *, size_t, size_t);
693 char		*kstrdup(const char *);
694 
695 extern const char *const	 kmimetypes[KMIME__MAX];
696 extern const char *const	 khttps[KHTTP__MAX];
697 extern const char *const	 kschemes[KSCHEME__MAX];
698 extern const char *const	 kresps[KRESP__MAX];
699 extern const char *const	 kmethods[KMETHOD__MAX];
700 extern const struct kmimemap	 ksuffixmap[];
701 extern const char *const	 ksuffixes[KMIME__MAX];
702 
703 /* DEPRECATED FUNCTIONS AND MACROS. */
704 
705 #define		 KUTIL_EPOCH2TM(_tt, _tm) \
706 		 kutil_epoch2tmvals((_tt), \
707 			&(_tm)->tm_sec, \
708 			&(_tm)->tm_min, \
709 			&(_tm)->tm_hour, \
710 			&(_tm)->tm_mday, \
711 			&(_tm)->tm_mon, \
712 			&(_tm)->tm_year, \
713 			&(_tm)->tm_wday, \
714 			&(_tm)->tm_yday)
715 void		 kutil_epoch2tmvals(int64_t, int *, int *, int *,
716 			int *, int *, int *, int *, int *)
717 			__attribute__((deprecated));
718 char		*kutil_epoch2str(int64_t, char *, size_t)
719 			__attribute__((deprecated));
720 char		*kutil_epoch2utcstr(int64_t, char *, size_t)
721 			__attribute__((deprecated));
722 int64_t	 	 kutil_date2epoch(int64_t, int64_t, int64_t)
723 			__attribute__((deprecated));
724 int	 	 kutil_date_check(int64_t, int64_t, int64_t)
725 			__attribute__((deprecated));
726 int64_t	 	 kutil_datetime2epoch(int64_t, int64_t, int64_t,
727 			int64_t, int64_t, int64_t)
728 			__attribute__((deprecated));
729 int	 	 kutil_datetime_check(int64_t, int64_t, int64_t,
730 			int64_t, int64_t, int64_t)
731 			__attribute__((deprecated));
732 char		*kutil_urlabs(enum kscheme, const char *,
733 			uint16_t, const char *)
734 			__attribute__((deprecated));
735 enum kcgi_err	 kutil_urldecode(const char *, char **)
736 			__attribute__((deprecated));
737 enum kcgi_err	 kutil_urldecode_inplace(char *)
738 			__attribute__((deprecated));
739 char		*kutil_urlencode(const char *)
740 			__attribute__((deprecated));
741 char		*kutil_urlpart(struct kreq *, const char *,
742 			const char *, const char *, ...)
743 			__attribute__((deprecated));
744 char		*kutil_urlpartx(struct kreq *, const char *,
745 			const char *, const char *, ...)
746 			__attribute__((deprecated));
747 __END_DECLS
748 
749 #endif /*!KCGI_H*/
750