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.
14 static char sccsid
[] = "@(#) percent_x.c 1.4 94/12/28 17:42:37";
17 /* System libraries. */
29 /* percent_x - do %<char> expansion, abort if result buffer is too small */
31 char *percent_x(result
, result_len
, string
, request
)
35 struct request_info
*request
;
38 char *end
= result
+ result_len
- 1; /* end of result buffer */
41 static char ok_chars
[] = "1234567890!@%-_=+:,./\
42 abcdefghijklmnopqrstuvwxyz\
43 ABCDEFGHIJKLMNOPQRSTUVWXYZ";
49 * Warning: we may be called from a child process or after pattern
50 * matching, so we cannot use clean_exit() or tcpd_jump().
54 if (*str
== '%' && (ch
= str
[1]) != 0) {
57 ch
== 'a' ? eval_hostaddr(request
->client
) :
58 ch
== 'A' ? eval_hostaddr(request
->server
) :
59 ch
== 'c' ? eval_client(request
) :
60 ch
== 'd' ? eval_daemon(request
) :
61 ch
== 'h' ? eval_hostinfo(request
->client
) :
62 ch
== 'H' ? eval_hostinfo(request
->server
) :
63 ch
== 'n' ? eval_hostname(request
->client
) :
64 ch
== 'N' ? eval_hostname(request
->server
) :
65 ch
== 'p' ? eval_pid(request
) :
66 ch
== 's' ? eval_server(request
) :
67 ch
== 'u' ? eval_user(request
) :
68 ch
== '%' ? "%" : (tcpd_warn("unrecognized %%%c", ch
), "");
69 for (cp
= expansion
; *(cp
+= strspn(cp
, ok_chars
)); /* */ )
71 expansion_len
= cp
- expansion
;
76 if (bp
+ expansion_len
>= end
) {
77 tcpd_warn("percent_x: expansion too long: %.30s...", result
);
81 memcpy(bp
, expansion
, expansion_len
);