main.c revision dc6f5b944434891dabd1aed297676349b58cb893
1837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh/*
2e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh * Copyright (C) 2011 The Android Open Source Project
3837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh *
4837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * Licensed under the Apache License, Version 2.0 (the "License");
5837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * you may not use this file except in compliance with the License.
6837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * You may obtain a copy of the License at
7837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh *
8837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh *      http://www.apache.org/licenses/LICENSE-2.0
9837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh *
10837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * Unless required by applicable law or agreed to in writing, software
11837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * distributed under the License is distributed on an "AS IS" BASIS,
12837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * See the License for the specific language governing permissions and
14837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh * limitations under the License.
15837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh */
16837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh
17837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#include <stdio.h>
18837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#include <stdlib.h>
19bd5fa3c99638830d3fa1ae5b4fc4988de5ee0f4dChia-chi Yeh#include <stdarg.h>
20837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#include <signal.h>
21f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#include <poll.h>
22f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
23837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#include "config.h"
24837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#include "gcmalloc.h"
25f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh#include "session.h"
26837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh#include "schedule.h"
27bd5fa3c99638830d3fa1ae5b4fc4988de5ee0f4dChia-chi Yeh#include "plog.h"
28837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh
29458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#ifdef ANDROID_CHANGES
30458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh
311070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <string.h>
321070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <sys/types.h>
331070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <sys/socket.h>
341070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <sys/ioctl.h>
351070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <sys/stat.h>
361070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <fcntl.h>
371070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <errno.h>
381070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <linux/if.h>
391070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <linux/if_tun.h>
401070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh
411070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <android/log.h>
421070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <cutils/sockets.h>
431070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh#include <private/android_filesystem_config.h>
441070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh
454dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yehstatic int android_get_control_and_arguments(int *argc, char ***argv)
46458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh{
47c9ac7d2fae3a233f928fd3f643ffa20b6ea602d3Chia-chi Yeh    static char *args[32];
48458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    int control;
49458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    int i;
50458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh
51458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    if ((i = android_get_control_socket("racoon")) == -1) {
52e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh        return -1;
53458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    }
54458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    do_plog(LLV_DEBUG, "Waiting for control socket");
55458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    if (listen(i, 1) == -1 || (control = accept(i, NULL, 0)) == -1) {
56458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        do_plog(LLV_ERROR, "Cannot get control socket");
57f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh        exit(1);
58458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    }
59458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    close(i);
60458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh
61458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    args[0] = (*argv)[0];
62c9ac7d2fae3a233f928fd3f643ffa20b6ea602d3Chia-chi Yeh    for (i = 1; i < 32; ++i) {
63c9ac7d2fae3a233f928fd3f643ffa20b6ea602d3Chia-chi Yeh        unsigned char bytes[2];
644dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yeh        int length = recv(control, &bytes[0], 1, 0);
654dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yeh
664dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yeh        if (!length) {
674dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yeh            break;
684dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yeh        } else if (length != 1 || recv(control, &bytes[1], 1, 0) != 1) {
69458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            do_plog(LLV_ERROR, "Cannot get argument length");
70f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh            exit(1);
71458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        } else {
72458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            int offset = 0;
734dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yeh            length = bytes[0] << 8 | bytes[1];
74c9ac7d2fae3a233f928fd3f643ffa20b6ea602d3Chia-chi Yeh
75458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            args[i] = malloc(length + 1);
76458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            while (offset < length) {
77458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh                int n = recv(control, &args[i][offset], length - offset, 0);
78458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh                if (n > 0) {
79458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh                    offset += n;
80458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh                } else {
81458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh                    do_plog(LLV_ERROR, "Cannot get argument value");
82f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                    exit(1);
83458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh                }
84458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            }
85458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            args[i][length] = 0;
86458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        }
87458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    }
88458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    do_plog(LLV_DEBUG, "Received %d arguments", i - 1);
89458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh
90458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    *argc = i;
91458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    *argv = args;
92e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh    return control;
93c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh}
94c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
95dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yehvoid android_setenv(char **envp)
961070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh{
971070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh    struct ifreq ifr = {.ifr_flags = IFF_TUN};
98dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh    int tun = open("/dev/tun", 0);
991070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh
100dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh    /* Android does not support INTERNAL_WINS4_LIST, so we just replace it. */
101dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh    while (*envp && strncmp(*envp, "INTERNAL_WINS4_LIST=", 20)) {
102dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh        ++envp;
103dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh    }
104dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh    if (!*envp) {
105dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh        do_plog(LLV_ERROR, "Cannot find environment variable\n");
106dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh        exit(1);
107dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh    }
1081070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh    if (ioctl(tun, TUNSETIFF, &ifr)) {
1091070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh        do_plog(LLV_ERROR, "Cannot allocate TUN: %s\n", strerror(errno));
1101070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh        exit(1);
1111070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh    }
112dc6f5b944434891dabd1aed297676349b58cb893Chia-chi Yeh    sprintf(*envp, "INTERFACE=%s", ifr.ifr_name);
1131070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh}
1141070097bb11002f8b5e289982cee9e324ea2f153Chia-chi Yeh
115458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#endif
116458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh
117c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yehextern void setup(int argc, char **argv);
118f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
1198f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yehchar *pname;
1208f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh
121f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic int monitor_count;
122f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic struct {
123f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    int (*callback)(void *ctx, int fd);
124f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    void *ctx;
125f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh} monitors[10];
126f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehstatic struct pollfd pollfds[10];
127c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
128c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yehstatic void terminate(int signal)
129c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh{
130c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh    exit(1);
131c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh}
132c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
133c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yehstatic void terminated()
134c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh{
135c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh    do_plog(LLV_INFO, "Bye\n");
136c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh}
137c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh
138837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yehint main(int argc, char **argv)
139837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh{
140e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#ifdef ANDROID_CHANGES
1414dd8f6be6496fc7cb7b7351c79f6a90be7be8991Chia-chi Yeh    int control = android_get_control_and_arguments(&argc, &argv);
142e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh    if (control != -1) {
1438f3b38855d8849959825acc45dd11144adc7d862Chia-chi Yeh        pname = "%p";
144e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh    }
145e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh#endif
146e9fc376dc7e9ee22358b872c3eb2808fa42160f0Chia-chi Yeh
147f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    do_plog(LLV_INFO, "ipsec-tools 0.8.0 (http://ipsec-tools.sf.net)\n");
148837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh
1497197eb77ef21feeedc5a47de31ded3a19c2af021Chia-chi Yeh    signal(SIGHUP, terminate);
1507197eb77ef21feeedc5a47de31ded3a19c2af021Chia-chi Yeh    signal(SIGINT, terminate);
1517197eb77ef21feeedc5a47de31ded3a19c2af021Chia-chi Yeh    signal(SIGTERM, terminate);
152837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    signal(SIGPIPE, SIG_IGN);
1539d271b685df5830e92a789119fe9b908da2f6c78Chia-chi Yeh    atexit(terminated);
154837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh
15512f449335c62c731f6eb33db7e27ce331f423f71Chia-chi Yeh    setup(argc, argv);
15612f449335c62c731f6eb33db7e27ce331f423f71Chia-chi Yeh
15712f449335c62c731f6eb33db7e27ce331f423f71Chia-chi Yeh#ifdef ANDROID_CHANGES
15812f449335c62c731f6eb33db7e27ce331f423f71Chia-chi Yeh    close(control);
15912f449335c62c731f6eb33db7e27ce331f423f71Chia-chi Yeh    setuid(AID_VPN);
16012f449335c62c731f6eb33db7e27ce331f423f71Chia-chi Yeh#endif
16112f449335c62c731f6eb33db7e27ce331f423f71Chia-chi Yeh
162837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    while (1) {
163f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh        struct timeval *tv = schedular();
164f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh        int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1;
165f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
166f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh        if (poll(pollfds, monitor_count, timeout) > 0) {
167f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh            int i;
168f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh            for (i = 0; i < monitor_count; ++i) {
169f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                if (pollfds[i].revents & POLLHUP) {
170f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                    do_plog(LLV_ERROR, "fd %d is closed\n", pollfds[i].fd);
171f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                    exit(1);
172f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                }
173f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                if (pollfds[i].revents & POLLIN) {
174f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                    monitors[i].callback(monitors[i].ctx, pollfds[i].fd);
175f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh                }
176837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh            }
177837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh        }
178837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    }
179837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    return 0;
180837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh}
181837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh
182f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh/* session.h */
183f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
184f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehvoid monitor_fd(int fd, int (*callback)(void *, int), void *ctx, int priority)
185f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{
186f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    if (fd < 0 || monitor_count == 10) {
187f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh        do_plog(LLV_ERROR, "Cannot monitor fd");
188f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh        exit(1);
189f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    }
190f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    monitors[monitor_count].callback = callback;
191f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    monitors[monitor_count].ctx = ctx;
192f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    pollfds[monitor_count].fd = fd;
193f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    pollfds[monitor_count].events = POLLIN;
194f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    ++monitor_count;
195f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh}
196f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
197f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yehvoid unmonitor_fd(int fd)
198f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh{
199f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh    exit(1);
200f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh}
201f8a6a7636d53a5730c58ae041e4e09ae12e1657cChia-chi Yeh
202837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh/* plog.h */
203837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh
204837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yehvoid do_plog(int level, char *format, ...)
205837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh{
206458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    if (level >= 0 && level <= 5) {
207458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#ifdef ANDROID_CHANGES
208458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        static int levels[6] = {
209458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            ANDROID_LOG_ERROR, ANDROID_LOG_WARN, ANDROID_LOG_INFO,
210458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh            ANDROID_LOG_INFO, ANDROID_LOG_DEBUG, ANDROID_LOG_VERBOSE
211458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        };
212458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        va_list ap;
213458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        va_start(ap, format);
214458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        __android_log_vprint(levels[level], "racoon", format, ap);
215458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        va_end(ap);
216458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#else
217458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        static char *levels = "EWNIDV";
218458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        fprintf(stderr, "%c: ", levels[level]);
219458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        va_list ap;
220458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        va_start(ap, format);
221458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        vfprintf(stderr, format, ap);
222458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh        va_end(ap);
223458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh#endif
224458fe1ef88671dfe580c488973d5573194839087Chia-chi Yeh    }
225837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh}
226837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh
227837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yehchar *binsanitize(char *data, size_t length)
228837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh{
229837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    char *output = racoon_malloc(length + 1);
230837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    if (output) {
231837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh        size_t i;
232837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh        for (i = 0; i < length; ++i) {
233c454954382b81262dc81ac54e147f4dc7fc0af75Chia-chi Yeh            output[i] = (data[i] < ' ' || data[i] > '~') ? '?' : data[i];
234837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh        }
235837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh        output[length] = '\0';
236837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    }
237837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh    return output;
238837a1c77bab77bd62cccb33a15163a962f8dfb97Chia-chi Yeh}
239