Blame support/httxt2dbm.c

Packit 90a5c9
/* Licensed to the Apache Software Foundation (ASF) under one or more
Packit 90a5c9
 * contributor license agreements.  See the NOTICE file distributed with
Packit 90a5c9
 * this work for additional information regarding copyright ownership.
Packit 90a5c9
 * The ASF licenses this file to You under the Apache License, Version 2.0
Packit 90a5c9
 * (the "License"); you may not use this file except in compliance with
Packit 90a5c9
 * the License.  You may obtain a copy of the License at
Packit 90a5c9
 *
Packit 90a5c9
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 90a5c9
 *
Packit 90a5c9
 * Unless required by applicable law or agreed to in writing, software
Packit 90a5c9
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 90a5c9
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 90a5c9
 * See the License for the specific language governing permissions and
Packit 90a5c9
 * limitations under the License.
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
/*
Packit 90a5c9
 * httxt2dbm.c: simple program for converting RewriteMap text files to DBM
Packit 90a5c9
 * Rewrite databases for the Apache HTTP server
Packit 90a5c9
 *
Packit 90a5c9
 */
Packit 90a5c9
Packit 90a5c9
#include "apr.h"
Packit 90a5c9
#include "apr_lib.h"
Packit 90a5c9
#include "apr_strings.h"
Packit 90a5c9
#include "apr_file_io.h"
Packit 90a5c9
#include "apr_file_info.h"
Packit 90a5c9
#include "apr_pools.h"
Packit 90a5c9
#include "apr_getopt.h"
Packit 90a5c9
#include "apu.h"
Packit 90a5c9
#include "apr_dbm.h"
Packit 90a5c9
Packit 90a5c9
#if APR_HAVE_STDLIB_H
Packit 90a5c9
#include <stdlib.h> /* for atexit() */
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
static const char *input;
Packit 90a5c9
static const char *output;
Packit 90a5c9
static const char *format;
Packit 90a5c9
static const char *shortname;
Packit 90a5c9
static apr_file_t *errfile;
Packit 90a5c9
static int verbose;
Packit 90a5c9
Packit 90a5c9
/* From mod_rewrite.c */
Packit 90a5c9
#ifndef REWRITE_MAX_TXT_MAP_LINE
Packit 90a5c9
#define REWRITE_MAX_TXT_MAP_LINE 1024
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
#define NL APR_EOL_STR
Packit 90a5c9
Packit 90a5c9
#define AVAIL "available"
Packit 90a5c9
#define UNAVAIL "unavailable"
Packit 90a5c9
Packit 90a5c9
static void usage(void)
Packit 90a5c9
{
Packit 90a5c9
    const char *have_sdbm;
Packit 90a5c9
    const char *have_gdbm;
Packit 90a5c9
    const char *have_ndbm;
Packit 90a5c9
    const char *have_db;
Packit 90a5c9
Packit 90a5c9
#if APU_HAVE_SDBM
Packit 90a5c9
    have_sdbm = AVAIL;
Packit 90a5c9
#else
Packit 90a5c9
    have_sdbm = UNAVAIL;
Packit 90a5c9
#endif
Packit 90a5c9
#if APU_HAVE_GDBM
Packit 90a5c9
    have_gdbm = AVAIL;
Packit 90a5c9
#else
Packit 90a5c9
    have_gdbm = UNAVAIL;
Packit 90a5c9
#endif
Packit 90a5c9
#if APU_HAVE_NDBM
Packit 90a5c9
    have_ndbm = AVAIL;
Packit 90a5c9
#else
Packit 90a5c9
    have_ndbm = UNAVAIL;
Packit 90a5c9
#endif
Packit 90a5c9
#if APU_HAVE_DB
Packit 90a5c9
    have_db = AVAIL;
Packit 90a5c9
#else
Packit 90a5c9
    have_db = UNAVAIL;
Packit 90a5c9
#endif
Packit 90a5c9
Packit 90a5c9
    apr_file_printf(errfile,
Packit 90a5c9
    "%s -- Program to Create DBM Files for use by RewriteMap" NL
Packit 90a5c9
    "Usage: %s [-v] [-f format] -i SOURCE_TXT -o OUTPUT_DBM" NL
Packit 90a5c9
    NL
Packit 90a5c9
    "Options: " NL
Packit 90a5c9
    " -v    More verbose output" NL
Packit 90a5c9
    NL
Packit 90a5c9
    " -i    Source Text File. If '-', use stdin." NL
Packit 90a5c9
    NL
Packit 90a5c9
    " -o    Output DBM." NL
Packit 90a5c9
    NL
Packit 90a5c9
    " -f    DBM Format.  If not specified, will use the APR Default." NL
Packit 90a5c9
    "           GDBM for GDBM files (%s)" NL
Packit 90a5c9
    "           SDBM for SDBM files (%s)" NL
Packit 90a5c9
    "           DB   for berkeley DB files (%s)" NL
Packit 90a5c9
    "           NDBM for NDBM files (%s)" NL
Packit 90a5c9
    "           default for the default DBM type" NL
Packit 90a5c9
    NL,
Packit 90a5c9
    shortname,
Packit 90a5c9
    shortname,
Packit 90a5c9
    have_gdbm,
Packit 90a5c9
    have_sdbm,
Packit 90a5c9
    have_db,
Packit 90a5c9
    have_ndbm);
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
Packit 90a5c9
static apr_status_t to_dbm(apr_dbm_t *dbm, apr_file_t *fp, apr_pool_t *pool)
Packit 90a5c9
{
Packit 90a5c9
    apr_status_t rv = APR_SUCCESS;
Packit 90a5c9
    char line[REWRITE_MAX_TXT_MAP_LINE + 1]; /* +1 for \0 */
Packit 90a5c9
    apr_datum_t dbmkey;
Packit 90a5c9
    apr_datum_t dbmval;
Packit 90a5c9
    apr_pool_t* p;
Packit 90a5c9
Packit 90a5c9
    apr_pool_create(&p, pool);
Packit 90a5c9
Packit 90a5c9
    while (apr_file_gets(line, sizeof(line), fp) == APR_SUCCESS) {
Packit 90a5c9
        char *c, *value;
Packit 90a5c9
Packit 90a5c9
        if (*line == '#' || apr_isspace(*line)) {
Packit 90a5c9
            continue;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        c = line;
Packit 90a5c9
Packit 90a5c9
        while (*c && !apr_isspace(*c)) {
Packit 90a5c9
            ++c;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        if (!*c) {
Packit 90a5c9
            /* no value. solid line of data. */
Packit 90a5c9
            continue;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        dbmkey.dptr = apr_pstrmemdup(p, line,  c - line);
Packit 90a5c9
        dbmkey.dsize = (c - line);
Packit 90a5c9
Packit 90a5c9
        while (apr_isspace(*c)) {
Packit 90a5c9
            ++c;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        if (!*c) {
Packit 90a5c9
            apr_pool_clear(p);
Packit 90a5c9
            continue;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        value = c;
Packit 90a5c9
Packit 90a5c9
        while (*c && !apr_isspace(*c)) {
Packit 90a5c9
            ++c;
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        dbmval.dptr = apr_pstrmemdup(p, value,  c - value);
Packit 90a5c9
        dbmval.dsize = (c - value);
Packit 90a5c9
Packit 90a5c9
        if (verbose) {
Packit 90a5c9
            apr_file_printf(errfile, "    '%s' -> '%s'" NL,
Packit 90a5c9
                            dbmkey.dptr, dbmval.dptr);
Packit 90a5c9
        }
Packit 90a5c9
Packit 90a5c9
        rv = apr_dbm_store(dbm, dbmkey, dbmval);
Packit 90a5c9
Packit 90a5c9
        apr_pool_clear(p);
Packit 90a5c9
Packit 90a5c9
        if (rv != APR_SUCCESS) {
Packit 90a5c9
            break;
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return rv;
Packit 90a5c9
}
Packit 90a5c9
Packit 90a5c9
int main(int argc, const char *const argv[])
Packit 90a5c9
{
Packit 90a5c9
    apr_pool_t *pool;
Packit 90a5c9
    apr_status_t rv = APR_SUCCESS;
Packit 90a5c9
    apr_getopt_t *opt;
Packit 90a5c9
    const char *opt_arg;
Packit 90a5c9
    char ch;
Packit 90a5c9
    apr_file_t *infile;
Packit 90a5c9
    apr_dbm_t *outdbm;
Packit 90a5c9
Packit 90a5c9
    apr_app_initialize(&argc, &argv, NULL);
Packit 90a5c9
    atexit(apr_terminate);
Packit 90a5c9
Packit 90a5c9
    verbose = 0;
Packit 90a5c9
    format = NULL;
Packit 90a5c9
    input = NULL;
Packit 90a5c9
    output = NULL;
Packit 90a5c9
Packit 90a5c9
    apr_pool_create(&pool, NULL);
Packit 90a5c9
Packit 90a5c9
    if (argc) {
Packit 90a5c9
        shortname = apr_filepath_name_get(argv[0]);
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        shortname = "httxt2dbm";
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    apr_file_open_stderr(&errfile, pool);
Packit 90a5c9
    rv = apr_getopt_init(&opt, pool, argc, argv);
Packit 90a5c9
Packit 90a5c9
    if (rv != APR_SUCCESS) {
Packit 90a5c9
        apr_file_printf(errfile, "Error: apr_getopt_init failed." NL NL);
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (argc <= 1) {
Packit 90a5c9
        usage();
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    while ((rv = apr_getopt(opt, "vf::i::o::", &ch, &opt_arg)) == APR_SUCCESS) {
Packit 90a5c9
        switch (ch) {
Packit 90a5c9
        case 'v':
Packit 90a5c9
            if (verbose) {
Packit 90a5c9
                apr_file_printf(errfile, "Error: -v can only be passed once" NL NL);
Packit 90a5c9
                usage();
Packit 90a5c9
                return 1;
Packit 90a5c9
            }
Packit 90a5c9
            verbose = 1;
Packit 90a5c9
            break;
Packit 90a5c9
        case 'f':
Packit 90a5c9
            if (format) {
Packit 90a5c9
                apr_file_printf(errfile, "Error: -f can only be passed once" NL NL);
Packit 90a5c9
                usage();
Packit 90a5c9
                return 1;
Packit 90a5c9
            }
Packit 90a5c9
            format = apr_pstrdup(pool, opt_arg);
Packit 90a5c9
            break;
Packit 90a5c9
        case 'i':
Packit 90a5c9
            if (input) {
Packit 90a5c9
                apr_file_printf(errfile, "Error: -i can only be passed once" NL NL);
Packit 90a5c9
                usage();
Packit 90a5c9
                return 1;
Packit 90a5c9
            }
Packit 90a5c9
            input = apr_pstrdup(pool, opt_arg);
Packit 90a5c9
            break;
Packit 90a5c9
        case 'o':
Packit 90a5c9
            if (output) {
Packit 90a5c9
                apr_file_printf(errfile, "Error: -o can only be passed once" NL NL);
Packit 90a5c9
                usage();
Packit 90a5c9
                return 1;
Packit 90a5c9
            }
Packit 90a5c9
            output = apr_pstrdup(pool, opt_arg);
Packit 90a5c9
            break;
Packit 90a5c9
        }
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (rv != APR_EOF) {
Packit 90a5c9
        apr_file_printf(errfile, "Error: Parsing Arguments Failed" NL NL);
Packit 90a5c9
        usage();
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (!input) {
Packit 90a5c9
        apr_file_printf(errfile, "Error: No input file specified." NL NL);
Packit 90a5c9
        usage();
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (!output) {
Packit 90a5c9
        apr_file_printf(errfile, "Error: No output DBM specified." NL NL);
Packit 90a5c9
        usage();
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (!format) {
Packit 90a5c9
        format = "default";
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (verbose) {
Packit 90a5c9
        apr_file_printf(errfile, "DBM Format: %s" NL, format);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (!strcmp(input, "-")) {
Packit 90a5c9
        rv = apr_file_open_stdin(&infile, pool);
Packit 90a5c9
    }
Packit 90a5c9
    else {
Packit 90a5c9
        rv = apr_file_open(&infile, input, APR_READ|APR_BUFFERED,
Packit 90a5c9
                           APR_OS_DEFAULT, pool);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (rv != APR_SUCCESS) {
Packit 90a5c9
        apr_file_printf(errfile,
Packit 90a5c9
                        "Error: Cannot open input file '%s': (%d) %pm" NL NL,
Packit 90a5c9
                         input, rv, &rv;;
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (verbose) {
Packit 90a5c9
        apr_file_printf(errfile, "Input File: %s" NL, input);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    rv = apr_dbm_open_ex(&outdbm, format, output, APR_DBM_RWCREATE,
Packit 90a5c9
                    APR_OS_DEFAULT, pool);
Packit 90a5c9
Packit 90a5c9
    if (APR_STATUS_IS_ENOTIMPL(rv)) {
Packit 90a5c9
        apr_file_printf(errfile,
Packit 90a5c9
                        "Error: The requested DBM Format '%s' is not available." NL NL,
Packit 90a5c9
                         format);
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (rv != APR_SUCCESS) {
Packit 90a5c9
        apr_file_printf(errfile,
Packit 90a5c9
                        "Error: Cannot open output DBM '%s': (%d) %pm" NL NL,
Packit 90a5c9
                         output, rv, &rv;;
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    if (verbose) {
Packit 90a5c9
        apr_file_printf(errfile, "DBM File: %s" NL, output);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    rv = to_dbm(outdbm, infile, pool);
Packit 90a5c9
Packit 90a5c9
    if (rv != APR_SUCCESS) {
Packit 90a5c9
        apr_file_printf(errfile,
Packit 90a5c9
                        "Error: Converting to DBM: (%d) %pm" NL NL,
Packit 90a5c9
                         rv, &rv;;
Packit 90a5c9
        return 1;
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    apr_dbm_close(outdbm);
Packit 90a5c9
Packit 90a5c9
    if (verbose) {
Packit 90a5c9
        apr_file_printf(errfile, "Conversion Complete." NL);
Packit 90a5c9
    }
Packit 90a5c9
Packit 90a5c9
    return 0;
Packit 90a5c9
}
Packit 90a5c9