2 * percent_x() takes a string and performs %<char> expansions. It aborts the
3 * program when the expansion would overflow the output buffer. The result
4 * of %<char> expansion may be passed on to a shell process. For this
5 * reason, characters with a special meaning to shells are replaced by
8 * Diagnostics are reported through syslog(3).
10 * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
13 /* System libraries. */
26 /* percent_x - do %<char> expansion, abort if result buffer is too small */
28 char *percent_x(result
, result_len
, string
, request
)
32 struct request_info
*request
;
35 char *end
= result
+ result_len
- 1; /* end of result buffer */
38 static char ok_chars
[] = "1234567890!@%-_=+:,./\
39 abcdefghijklmnopqrstuvwxyz\
40 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
46 * Warning: we may be called from a child process or after pattern
47 * matching, so we cannot use clean_exit() or tcpd_jump().
51 if (*str
== '%' && (ch
= str
[1]) != 0) {
54 ch
== 'a' ? eval_hostaddr(request
->client
) :
55 ch
== 'A' ? eval_hostaddr(request
->server
) :
56 ch
== 'c' ? eval_client(request
) :
57 ch
== 'd' ? eval_daemon(request
) :
58 ch
== 'h' ? eval_hostinfo(request
->client
) :
59 ch
== 'H' ? eval_hostinfo(request
->server
) :
60 ch
== 'n' ? eval_hostname(request
->client
) :
61 ch
== 'N' ? eval_hostname(request
->server
) :
62 ch
== 'p' ? eval_pid(request
) :
63 ch
== 's' ? eval_server(request
) :
64 ch
== 'u' ? eval_user(request
) :
65 ch
== '%' ? "%" : (tcpd_warn("unrecognized %%%c", ch
), "");
66 for (cp
= expansion
; *(cp
+= strspn(cp
, ok_chars
)); /* */ )
68 expansion_len
= cp
- expansion
;
73 if (bp
+ expansion_len
>= end
) {
74 tcpd_warn("percent_x: expansion too long: %.30s...", result
);
78 memcpy(bp
, expansion
, expansion_len
);