1 /* $NetBSD: percent_x.c,v 1.5 2012/03/21 10:10:37 matt Exp $ */
4 * percent_x() takes a string and performs %<char> expansions. It aborts the
5 * program when the expansion would overflow the output buffer. The result
6 * of %<char> expansion may be passed on to a shell process. For this
7 * reason, characters with a special meaning to shells are replaced by
10 * Diagnostics are reported through syslog(3).
12 * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
15 #include <sys/cdefs.h>
18 static char sccsid
[] = "@(#) percent_x.c 1.4 94/12/28 17:42:37";
20 __RCSID("$NetBSD: percent_x.c,v 1.5 2012/03/21 10:10:37 matt Exp $");
24 /* System libraries. */
36 /* percent_x - do %<char> expansion, abort if result buffer is too small */
39 percent_x(char *result
, int result_len
, char *string
,
40 struct request_info
*request
)
43 char *end
= result
+ result_len
- 1; /* end of result buffer */
46 static const char ok_chars
[] = "1234567890!@%-_=+:,./"
47 "abcdefghijklmnopqrstuvwxyz"
48 "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
54 * Warning: we may be called from a child process or after pattern
55 * matching, so we cannot use clean_exit() or tcpd_jump().
59 if (*str
== '%' && (ch
= str
[1]) != 0) {
62 ch
== 'a' ? eval_hostaddr(request
->client
) :
63 ch
== 'A' ? eval_hostaddr(request
->server
) :
64 ch
== 'c' ? eval_client(request
) :
65 ch
== 'd' ? eval_daemon(request
) :
66 ch
== 'h' ? eval_hostinfo(request
->client
) :
67 ch
== 'H' ? eval_hostinfo(request
->server
) :
68 ch
== 'n' ? eval_hostname(request
->client
) :
69 ch
== 'N' ? eval_hostname(request
->server
) :
70 ch
== 'p' ? eval_pid(request
) :
71 ch
== 's' ? eval_server(request
) :
72 ch
== 'u' ? eval_user(request
) :
73 ch
== '%' ? __UNCONST("%")
74 : (tcpd_warn("unrecognized %%%c", ch
), __UNCONST(""));
75 for (cp
= expansion
; *(cp
+= strspn(cp
, ok_chars
)); /* */ )
77 expansion_len
= cp
- expansion
;
82 if (bp
+ expansion_len
>= end
) {
83 tcpd_warn("percent_x: expansion too long: %.30s...", result
);
87 memcpy(bp
, expansion
, expansion_len
);