/* * Copyright (C) 2005 Network Applied Communication Laboratory Co., Ltd. * * This file is part of Rast. * See the file COPYING for redistribution information. * */ #include #include #include #include #include #include #include #include #include "rast/db.h" #include "rast/filter.h" #define OPTION_MIME_TYPE 'm' static int memory_error(int retcode); static void print_error(rast_error_t *error); static void print_apr_error(apr_status_t status); static char * format_option(const apr_getopt_option_t *option, apr_pool_t *pool) { char *s; if (option == NULL) { return "?"; } if (option->optch <= 0xff) { s = apr_psprintf(pool, "-%c [--%s]", option->optch, option->name); } else { s = apr_psprintf(pool, "--%s", option->name); } if (option->has_arg) { s = apr_pstrcat(pool, s, " arg", NULL); } if (option->description != NULL) { s = apr_psprintf(pool, "%-24s : %s", s, option->description); } return s; } static char * create_usage(apr_getopt_option_t *opts, apr_pool_t *pool) { char *usage = ""; int i; for (i = 0; opts[i].optch != 0; i++) { char *line = format_option(&opts[i], pool); usage = apr_pstrcat(pool, usage, " ", line, "\n", NULL); } return usage; } static void print_usage(const char *program_name, apr_getopt_option_t *opts, apr_pool_t *pool) { fprintf(stderr, "usage: %s [options] \n", program_name); fprintf(stderr, "%s\n", create_usage(opts, pool)); } static int parse_options(int argc, const char **argv, const char **mime_type, apr_pool_t *pool) { int count; const char *program_name; apr_getopt_t *os; apr_getopt_option_t opts[] = { { .name = "mime-type", .optch = OPTION_MIME_TYPE, .has_arg = 1, .description = "use this mime-type", }, {0}, }; program_name = argv[0]; apr_getopt_init(&os, pool, argc, argv); for (count = 0; ; count++) { int option_char; const char *option_arg; apr_status_t status; status = apr_getopt_long(os, opts, &option_char, &option_arg); if (status == APR_EOF) { break; } if (status != APR_SUCCESS) { char message[RAST_BUFSIZ]; apr_strerror(status, message, sizeof(message)); fprintf(stderr, "apr_error: %s\n", message); apr_pool_destroy(pool); exit(2); } if (option_arg != NULL) { count++; } switch (option_char) { case OPTION_MIME_TYPE: *mime_type = option_arg; break; default: print_usage(program_name, opts, pool); apr_pool_destroy(pool); exit(2); } } if (argc - count < 3) { print_usage(program_name, opts, pool); apr_pool_destroy(pool); exit(2); } return count; } int main(int argc, const char **argv) { apr_pool_t *pool; const char *dbpath, *filename; rast_db_t *db; rast_error_t *error, *get_doc_id_error; apr_finfo_t finfo; apr_file_t *file; apr_status_t status; apr_size_t len; apr_time_exp_t last_modified; rast_value_t property; rast_document_t *doc; rast_doc_id_t doc_id; rast_filter_chain_t *chain; apr_bucket_brigade *brigade; apr_bucket *bucket; apr_bucket_alloc_t *bucket_alloc; const char *mime_type = NULL; int num_parsed_options; apr_initialize(); atexit(apr_terminate); error = rast_initialize(); if (error != RAST_OK) { print_error(error); return 1; } atexit(rast_finalize); apr_pool_create_ex(&pool, NULL, memory_error, NULL); num_parsed_options = parse_options(argc, argv, &mime_type, pool); dbpath = argv[num_parsed_options + 1]; filename = argv[num_parsed_options + 2]; status = apr_stat(&finfo, filename, APR_FINFO_SIZE | APR_FINFO_MTIME, pool); if (status != APR_SUCCESS) { print_apr_error(status); return 1; } status = apr_file_open(&file, filename, APR_READ, APR_OS_DEFAULT, pool); if (status != APR_SUCCESS) { print_apr_error(status); return 1; } len = finfo.size; error = rast_db_open(&db, dbpath, RAST_DB_RDWR, NULL, pool); if (error != RAST_OK) { print_error(error); return 1; } error = rast_db_create_document(db, &doc); if (error != RAST_OK) { print_error(error); return 1; } rast_value_set_string(&property, (char *) filename); rast_value_set_type(&property, RAST_TYPE_STRING); error = rast_document_set_property(doc, "filename", &property); if (error != RAST_OK) { print_error(error); return 1; } error = rast_document_set_property(doc, "title", &property); if (error != RAST_OK) { print_error(error); return 1; } apr_time_exp_lt(&last_modified, finfo.mtime); rast_value_set_date(&property, apr_psprintf(pool, "%04d-%02d-%02dT%02d:%02d:%02d", last_modified.tm_year + 1900, last_modified.tm_mon + 1, last_modified.tm_mday, last_modified.tm_hour, last_modified.tm_min, last_modified.tm_sec)); rast_value_set_type(&property, RAST_TYPE_DATE); error = rast_document_set_property(doc, "last_modified", &property); if (error != RAST_OK) { print_error(error); return 1; } rast_value_set_uint(&property, len); rast_value_set_type(&property, RAST_TYPE_UINT); error = rast_document_set_property(doc, "filesize", &property); if (error != RAST_OK) { print_error(error); return 1; } bucket_alloc = apr_bucket_alloc_create(pool); error = rast_filter_chain_create(&chain, doc, NULL, 0, pool); if (error != RAST_OK) { print_error(error); return 1; } brigade = apr_brigade_create(pool, bucket_alloc); bucket = apr_bucket_file_create(file, 0, finfo.size, pool, bucket_alloc); APR_BRIGADE_INSERT_TAIL(brigade, bucket); bucket = apr_bucket_eos_create(bucket_alloc); APR_BRIGADE_INSERT_TAIL(brigade, bucket); error = rast_filter_chain_invoke(chain, brigade, mime_type, filename); if (error != RAST_OK) { print_error(error); return 1; } get_doc_id_error = rast_document_get_doc_id(doc, &doc_id); error = rast_document_commit(doc); if (error != RAST_OK) { print_error(error); return 1; } if (get_doc_id_error == RAST_OK) { printf("doc_id: %d\n", doc_id); } else { printf("unknown doc_id: %s\n", get_doc_id_error->message); rast_error_destroy(get_doc_id_error); } rast_db_close(db); return 0; } static int memory_error(int retcode) { abort(); return -1; /* prevent compiler warnings */ } static void print_error(rast_error_t *error) { #ifdef RAST_DEBUG fprintf(stderr, "failure: %s:%d: %s\n", error->file, error->line, error->message); #else fprintf(stderr, "failure: %s\n", error->message); #endif rast_error_destroy(error); } static void print_apr_error(apr_status_t status) { char buf[1024]; apr_strerror(status, buf, sizeof(buf)); fprintf(stderr, "error: %s\n", apr_strerror(status, buf, sizeof(buf))); } /* vim: set filetype=c sw=4 expandtab : */