bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / support / httxt2dbm.c
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*
18  * httxt2dbm.c: simple program for converting RewriteMap text files to DBM
19  * Rewrite databases for the Apache HTTP server
20  *
21  */
22
23 #include "apr.h"
24 #include "apr_lib.h"
25 #include "apr_strings.h"
26 #include "apr_file_io.h"
27 #include "apr_file_info.h"
28 #include "apr_pools.h"
29 #include "apr_getopt.h"
30 #include "apu.h"
31 #include "apr_dbm.h"
32
33 #if APR_HAVE_STDLIB_H
34 #include <stdlib.h> /* for atexit() */
35 #endif
36
37 static const char *input;
38 static const char *output;
39 static const char *format;
40 static const char *shortname;
41 static apr_file_t *errfile;
42 static char errbuf[120];
43 static int verbose;
44
45 /* From mod_rewrite.c */
46 #ifndef REWRITE_MAX_TXT_MAP_LINE
47 #define REWRITE_MAX_TXT_MAP_LINE 1024
48 #endif
49
50 #define NL APR_EOL_STR
51
52 #define AVAIL "available"
53 #define UNAVAIL "unavailable"
54
55 static void usage(void)
56 {
57     const char *have_sdbm;
58     const char *have_gdbm;
59     const char *have_ndbm;
60     const char *have_db;
61
62 #if APU_HAVE_SDBM
63     have_sdbm = AVAIL;
64 #else
65     have_sdbm = UNAVAIL;
66 #endif
67 #if APU_HAVE_GDBM
68     have_gdbm = AVAIL;
69 #else
70     have_gdbm = UNAVAIL;
71 #endif
72 #if APU_HAVE_NDBM
73     have_ndbm = AVAIL;
74 #else
75     have_ndbm = UNAVAIL;
76 #endif
77 #if APU_HAVE_DB
78     have_db = AVAIL;
79 #else
80     have_db = UNAVAIL;
81 #endif
82
83     apr_file_printf(errfile,
84     "%s -- Program to Create DBM Files for use by RewriteMap" NL
85     "Usage: %s [-v] [-f format] -i SOURCE_TXT -o OUTPUT_DBM" NL
86     NL
87     "Options: " NL
88     " -v    More verbose output"NL
89     NL
90     " -i    Source Text File. If '-', use stdin."NL
91     NL
92     " -o    Output DBM."NL
93     NL
94     " -f    DBM Format.  If not specified, will use the APR Default." NL
95     "           GDBM for GDBM files (%s)" NL
96     "           SDBM for SDBM files (%s)" NL
97     "           DB   for berkeley DB files (%s)" NL
98     "           NDBM for NDBM files (%s)" NL
99     "           default for the default DBM type" NL
100     NL,
101     shortname,
102     shortname,
103     have_gdbm,
104     have_sdbm,
105     have_db,
106     have_ndbm);
107 }
108
109
110 static apr_status_t to_dbm(apr_dbm_t *dbm, apr_file_t *fp, apr_pool_t *pool)
111 {
112     apr_status_t rv = APR_SUCCESS;
113     char line[REWRITE_MAX_TXT_MAP_LINE + 1]; /* +1 for \0 */
114     apr_datum_t dbmkey;
115     apr_datum_t dbmval;
116     apr_pool_t* p;
117
118     apr_pool_create(&p, pool);
119
120     while (apr_file_gets(line, sizeof(line), fp) == APR_SUCCESS) {
121         char *c, *value;
122
123         if (*line == '#' || apr_isspace(*line)) {
124             continue;
125         }
126
127         c = line;
128
129         while (*c && !apr_isspace(*c)) {
130             ++c;
131         }
132
133         if (!*c) {
134             /* no value. solid line of data. */
135             continue;
136         }
137
138         dbmkey.dptr = apr_pstrmemdup(p, line,  c - line);
139         dbmkey.dsize = (c - line);
140
141         while (*c && apr_isspace(*c)) {
142             ++c;
143         }
144
145         if (!*c) {
146             apr_pool_clear(p);
147             continue;
148         }
149
150         value = c;
151
152         while (*c && !apr_isspace(*c)) {
153             ++c;
154         }
155
156         dbmval.dptr = apr_pstrmemdup(p, value,  c - value);
157         dbmval.dsize = (c - line);
158
159         if (verbose) {
160             apr_file_printf(errfile, "    '%s' -> '%s'"NL,
161                             dbmkey.dptr, dbmval.dptr);
162         }
163
164         rv = apr_dbm_store(dbm, dbmkey, dbmval);
165
166         apr_pool_clear(p);
167
168         if (rv != APR_SUCCESS) {
169             break;
170         }
171     }
172
173     return rv;
174 }
175
176 int main(int argc, const char *const argv[])
177 {
178     apr_pool_t *pool;
179     apr_status_t rv = APR_SUCCESS;
180     apr_getopt_t *opt;
181     const char *optarg;
182     char ch;
183     apr_file_t *infile;
184     apr_dbm_t *outdbm;
185
186     apr_initialize();
187     atexit(apr_terminate);
188
189     verbose = 0;
190     format = NULL;
191     input = NULL;
192     output = NULL;
193
194     apr_pool_create(&pool, NULL);
195
196     if (argc) {
197         shortname = apr_filepath_name_get(argv[0]);
198     }
199     else {
200         shortname = "httxt2dbm";
201     }
202
203     apr_file_open_stderr(&errfile, pool);
204     rv = apr_getopt_init(&opt, pool, argc, argv);
205
206     if (rv != APR_SUCCESS) {
207         apr_file_printf(errfile, "Error: apr_getopt_init failed."NL NL);
208         return 1;
209     }
210
211     if (argc <= 1) {
212         usage();
213         return 1;
214     }
215
216     while ((rv = apr_getopt(opt, "vf::i::o::", &ch, &optarg)) == APR_SUCCESS) {
217         switch (ch) {
218         case 'v':
219             if (verbose) {
220                 apr_file_printf(errfile, "Error: -v can only be passed once" NL NL);
221                 usage();
222                 return 1;
223             }
224             verbose = 1;
225             break;
226         case 'f':
227             if (format) {
228                 apr_file_printf(errfile, "Error: -f can only be passed once" NL NL);
229                 usage();
230                 return 1;
231             }
232             format = apr_pstrdup(pool, optarg);
233             break;
234         case 'i':
235             if (input) {
236                 apr_file_printf(errfile, "Error: -i can only be passed once" NL NL);
237                 usage();
238                 return 1;
239             }
240             input = apr_pstrdup(pool, optarg);
241             break;
242         case 'o':
243             if (output) {
244                 apr_file_printf(errfile, "Error: -o can only be passed once" NL NL);
245                 usage();
246                 return 1;
247             }
248             output = apr_pstrdup(pool, optarg);
249             break;
250         }
251     }
252
253     if (rv != APR_EOF) {
254         apr_file_printf(errfile, "Error: Parsing Arguments Failed" NL NL);
255         usage();
256         return 1;
257     }
258
259     if (!input) {
260         apr_file_printf(errfile, "Error: No input file specified." NL NL);
261         usage();
262         return 1;
263     }
264
265     if (!output) {
266         apr_file_printf(errfile, "Error: No output DBM specified." NL NL);
267         usage();
268         return 1;
269     }
270
271     if (!format) {
272         format = "default";
273     }
274
275     if (verbose) {
276         apr_file_printf(errfile, "DBM Format: %s"NL, format);
277     }
278
279     if (!strcmp(input, "-")) {
280         rv = apr_file_open_stdin(&infile, pool);
281     }
282     else {
283         rv = apr_file_open(&infile, input, APR_READ|APR_BUFFERED,
284                            APR_OS_DEFAULT, pool);
285     }
286
287     if (rv != APR_SUCCESS) {
288         apr_file_printf(errfile,
289                         "Error: Cannot open input file '%s': (%d) %s" NL NL,
290                          input, rv, apr_strerror(rv, errbuf, sizeof(errbuf)));
291         return 1;
292     }
293
294     if (verbose) {
295         apr_file_printf(errfile, "Input File: %s"NL, input);
296     }
297
298     rv = apr_dbm_open_ex(&outdbm, format, output, APR_DBM_RWCREATE,
299                     APR_OS_DEFAULT, pool);
300
301     if (APR_STATUS_IS_ENOTIMPL(rv)) {
302         apr_file_printf(errfile,
303                         "Error: The requested DBM Format '%s' is not available." NL NL,
304                          format);
305         return 1;
306     }
307
308     if (rv != APR_SUCCESS) {
309         apr_file_printf(errfile,
310                         "Error: Cannot open output DBM '%s': (%d) %s" NL NL,
311                          output, rv, apr_strerror(rv, errbuf, sizeof(errbuf)));
312         return 1;
313     }
314
315     if (verbose) {
316         apr_file_printf(errfile, "DBM File: %s"NL, output);
317     }
318
319     rv = to_dbm(outdbm, infile, pool);
320
321     if (rv != APR_SUCCESS) {
322         apr_file_printf(errfile,
323                         "Error: Converting to DBM: (%d) %s" NL NL,
324                          rv, apr_strerror(rv, errbuf, sizeof(errbuf)));
325         return 1;
326     }
327
328     apr_dbm_close(outdbm);
329
330     if (verbose) {
331         apr_file_printf(errfile, "Conversion Complete." NL);
332     }
333
334     return 0;
335 }
336