source: trunk/third/tcp_wrappers/percent_x.c @ 11717

Revision 11717, 2.3 KB checked in by danw, 26 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r11716, which included commits to RCS files with non-trunk default branches.
Line 
1 /*
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
6  * underscores.
7  *
8  * Diagnostics are reported through syslog(3).
9  *
10  * Author: Wietse Venema, Eindhoven University of Technology, The Netherlands.
11  */
12
13#ifndef lint
14static char sccsid[] = "@(#) percent_x.c 1.4 94/12/28 17:42:37";
15#endif
16
17/* System libraries. */
18
19#include <stdio.h>
20#include <syslog.h>
21#include <string.h>
22
23extern void exit();
24
25/* Local stuff. */
26
27#include "tcpd.h"
28
29/* percent_x - do %<char> expansion, abort if result buffer is too small */
30
31char   *percent_x(result, result_len, string, request)
32char   *result;
33int     result_len;
34char   *string;
35struct request_info *request;
36{
37    char   *bp = result;
38    char   *end = result + result_len - 1;      /* end of result buffer */
39    char   *expansion;
40    int     expansion_len;
41    static char ok_chars[] = "1234567890!@%-_=+:,./\
42abcdefghijklmnopqrstuvwxyz\
43ABCDEFGHIJKLMNOPQRSTUVWXYZ";
44    char   *str = string;
45    char   *cp;
46    int     ch;
47
48    /*
49     * Warning: we may be called from a child process or after pattern
50     * matching, so we cannot use clean_exit() or tcpd_jump().
51     */
52
53    while (*str) {
54        if (*str == '%' && (ch = str[1]) != 0) {
55            str += 2;
56            expansion =
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)); /* */ )
70                *cp = '_';
71            expansion_len = cp - expansion;
72        } else {
73            expansion = str++;
74            expansion_len = 1;
75        }
76        if (bp + expansion_len >= end) {
77            tcpd_warn("percent_x: expansion too long: %.30s...", result);
78            sleep(5);
79            exit(0);
80        }
81        memcpy(bp, expansion, expansion_len);
82        bp += expansion_len;
83    }
84    *bp = 0;
85    return (result);
86}
Note: See TracBrowser for help on using the repository browser.