"Fossies" - the Fresh Open Source Software Archive

Member "detox-1.4.5/src/detox.c" (15 Aug 2021, 8249 Bytes) of package /linux/privat/detox-1.4.5.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "detox.c" see the Fossies "Dox" file reference documentation.

    1 /**
    2  * This file is part of the Detox package.
    3  *
    4  * Copyright (c) Doug Harple <detox.dharple@gmail.com>
    5  *
    6  * For the full copyright and license information, please view the LICENSE
    7  * file that was distributed with this source code.
    8  */
    9 
   10 #include "config.h"
   11 
   12 #include <sys/types.h>
   13 #include <sys/stat.h>
   14 #include <stdio.h>
   15 #include <stdlib.h>
   16 #include <string.h>
   17 #include <errno.h>
   18 #include <unistd.h>
   19 
   20 #include "detox.h"
   21 #include "clean_string.h"
   22 
   23 #include "file.h"
   24 
   25 #include "config_file.h"
   26 #include "config_file_spoof.h"
   27 #include "config_file_dump.h"
   28 #include "parse_table.h"
   29 #include "parse_options.h"
   30 
   31 #define MAX_PATH_LEN 256
   32 
   33 int main(int argc, char **argv)
   34 {
   35     struct stat stat_info;
   36     int err;
   37 
   38     struct detox_parse_results *parse_results = NULL;
   39     struct detox_sequence_list *list_work = NULL;
   40     struct detox_sequence_entry *which_sequence = NULL;
   41     struct detox_sequence_entry *work = NULL;
   42     struct detox_options *main_options;
   43 
   44     char *check_config_file = NULL;
   45     char *file_work = NULL;
   46     char **file_walk;
   47 
   48     main_options = parse_options_getopt(argc, argv);
   49 
   50     if (main_options == NULL) {
   51         fprintf(stderr, "detox: an error occurred while parsing command line arguments\n");
   52         exit(EXIT_FAILURE);
   53     }
   54 
   55     if (main_options->check_config_file) {
   56         check_config_file = strdup(main_options->check_config_file);
   57     }
   58 
   59     if (check_config_file != NULL) {
   60         parse_results = parse_config_file(check_config_file, NULL, main_options);
   61         if (parse_results == NULL) {
   62             fprintf(stderr, "detox: unable to open: %s\n", check_config_file);
   63             exit(EXIT_FAILURE);
   64         }
   65     }
   66     else {
   67         check_config_file = malloc(MAX_PATH_LEN);
   68         if (check_config_file == NULL) {
   69             fprintf(stderr, "out of memory: %s\n", strerror(errno));
   70             exit(EXIT_FAILURE);
   71         }
   72 
   73 #ifdef SYSCONFDIR
   74         err = snprintf(check_config_file, MAX_PATH_LEN, "%s/detoxrc", SYSCONFDIR);
   75         if (err < MAX_PATH_LEN)
   76             parse_results = parse_config_file(check_config_file, NULL, main_options);
   77 #endif
   78 
   79         if (parse_results == NULL) {
   80             parse_results = parse_config_file("/etc/detoxrc", NULL, main_options);
   81         }
   82 
   83         if (parse_results == NULL) {
   84             parse_results = parse_config_file("/usr/local/etc/detoxrc", NULL, main_options);
   85         }
   86 
   87         file_work = getenv("HOME");
   88         if (file_work != NULL) {
   89             err = snprintf(check_config_file, MAX_PATH_LEN, "%s/.detoxrc", file_work);
   90             if (err < MAX_PATH_LEN)
   91                 parse_results = parse_config_file(check_config_file, parse_results, main_options);
   92 
   93             file_work = NULL;
   94         }
   95 
   96         if (parse_results == NULL) {
   97             parse_results = spoof_config_file(main_options);
   98         }
   99 
  100         free(check_config_file);
  101     }
  102 
  103     if (parse_results == NULL) {
  104         fprintf(stderr, "detox: no config file to work with\n");
  105         exit(EXIT_FAILURE);
  106     }
  107 
  108     /*
  109      * Store the files_to_ignore array in the main_options struct for use in
  110      * parse_dir/file/special
  111      */
  112 
  113     main_options->files_to_ignore = parse_results->files_to_ignore;
  114 
  115     /*
  116      * Determine which sequence to use
  117      */
  118 
  119     which_sequence = NULL;
  120 
  121     list_work = parse_results->sequences;
  122 
  123     while (list_work != NULL) {
  124         if (strcmp(list_work->name, (main_options->sequence_name == NULL) ? "default" : main_options->sequence_name) == 0) {
  125             which_sequence = list_work->head;
  126             break;
  127         }
  128 
  129         list_work = list_work->next;
  130     }
  131 
  132     /*
  133      * If no sequence was found, and the user didn't specify a sequence
  134      * to use, just use the first sequence.
  135      */
  136 
  137     if (which_sequence == NULL && main_options->sequence_name == NULL) {
  138         if (parse_results->sequences != NULL) {
  139             which_sequence = parse_results->sequences->head;
  140         }
  141     }
  142 
  143     main_options->sequence_to_use = which_sequence;
  144 
  145     /*
  146      * List sequences
  147      */
  148     if (main_options->list_sequences) {
  149         dump_config_file(parse_results, main_options);
  150         exit(EXIT_SUCCESS);
  151     }
  152 
  153     /*
  154      * Fail if no sequence is available
  155      */
  156     if (main_options->sequence_to_use == NULL) {
  157         /*
  158          * XXX - Explain this better
  159          */
  160         fprintf(stderr, "detox: no sequence to work with\n");
  161         exit(EXIT_FAILURE);
  162     }
  163 
  164     /*
  165      * Check translation tables
  166      */
  167 
  168     work = main_options->sequence_to_use;
  169     while (work != NULL) {
  170         char *check_filename = NULL;
  171         int do_search = 0;
  172 
  173         struct translation_table *table = NULL;
  174         struct clean_string_options *opts;
  175 
  176         if (work->cleaner == &clean_iso8859_1) {
  177             if (work->options != NULL) {
  178                 opts = work->options;
  179                 if (opts->filename != NULL) {
  180                     check_filename = opts->filename;
  181                 }
  182             }
  183 
  184             if (!check_filename) {
  185                 check_filename = "iso8859_1.tbl";
  186                 do_search = 1;
  187             }
  188         }
  189         else if (work->cleaner == &clean_utf_8) {
  190             if (work->options != NULL) {
  191                 opts = work->options;
  192                 if (opts->filename != NULL) {
  193                     check_filename = opts->filename;
  194                 }
  195             }
  196 
  197             if (!check_filename) {
  198                 check_filename = "unicode.tbl";
  199                 do_search = 1;
  200             }
  201         }
  202         else if (work->cleaner == &clean_safe) {
  203             if (work->options != NULL) {
  204                 opts = work->options;
  205                 if (opts->filename != NULL) {
  206                     check_filename = opts->filename;
  207                 }
  208             }
  209 
  210             if (!check_filename) {
  211                 check_filename = "safe.tbl";
  212                 do_search = 1;
  213             }
  214         }
  215 
  216         if (check_filename || do_search) {
  217 
  218             table = NULL;
  219 
  220             if (do_search) {
  221                 check_config_file = malloc(MAX_PATH_LEN);
  222                 if (check_config_file == NULL) {
  223                     fprintf(stderr, "out of memory: %s\n", strerror(errno));
  224                     exit(EXIT_FAILURE);
  225                 }
  226 
  227 #ifdef DATADIR
  228                 err = snprintf(check_config_file, MAX_PATH_LEN, "%s/detox/%s", DATADIR, check_filename);
  229                 if (err < MAX_PATH_LEN)
  230                     table = parse_table(check_config_file);
  231 #endif
  232 
  233                 if (table == NULL) {
  234                     err = snprintf(check_config_file, MAX_PATH_LEN, "/usr/share/detox/%s", check_filename);
  235                     if (err < MAX_PATH_LEN)
  236                         table = parse_table(check_config_file);
  237                 }
  238 
  239                 if (table == NULL) {
  240                     err = snprintf(check_config_file, MAX_PATH_LEN, "/usr/local/share/detox/%s", check_filename);
  241                     if (err < MAX_PATH_LEN)
  242                         table = parse_table(check_config_file);
  243                 }
  244 
  245                 if (table == NULL) {
  246 
  247                     /*
  248                      * Fall back to the non-file based
  249                      * cleaner
  250                      */
  251                     if (work->cleaner == &clean_iso8859_1) {
  252                         work->cleaner = &clean_iso8859_1_basic;
  253                     }
  254                     else if (work->cleaner == &clean_utf_8) {
  255                         work->cleaner = &clean_utf_8_basic;
  256                     }
  257                     else if (work->cleaner == &clean_safe) {
  258                         work->cleaner = &clean_safe_basic;
  259                     }
  260                     else {
  261                         fprintf(stderr, "detox: unable to locate translation table or fall back\n");
  262                         exit(EXIT_FAILURE);
  263                     }
  264                 }
  265                 else {
  266 
  267                     /*
  268                      * Allocate an options
  269                      */
  270                     opts = malloc(sizeof(struct clean_string_options));
  271                     if (opts == NULL) {
  272                         fprintf(stderr, "out of memory: %s\n", strerror(errno));
  273                         exit(EXIT_FAILURE);
  274                     }
  275                     memset(opts, 0, sizeof(struct clean_string_options));
  276 
  277                     opts->translation_table = table;
  278                     work->options = opts;
  279                 }
  280 
  281                 free(check_config_file);
  282             }
  283             else {
  284                 table = parse_table(check_filename);
  285                 if (table == NULL) {
  286                     fprintf(stderr, "detox: unable to parse file: %s\n", check_filename);
  287                     exit(EXIT_FAILURE);
  288                 }
  289 
  290                 opts = work->options;
  291                 opts->translation_table = table;
  292             }
  293         }
  294 
  295 
  296         work = work->next;
  297     }
  298 
  299     /*
  300      * Do some actual work
  301      */
  302 
  303     if (!main_options->is_inline_mode) {
  304         file_walk = main_options->files;
  305         while (*file_walk) {
  306             if (main_options->verbose) {
  307                 printf("Scanning: %s\n", *file_walk);
  308             }
  309 
  310             err = lstat(*file_walk, &stat_info);
  311             if (err == -1) {
  312                 fprintf(stderr, "%s: %s\n", *file_walk, strerror(errno));
  313             }
  314             else {
  315                 if (S_ISDIR(stat_info.st_mode)) {
  316                     file_work = parse_file(*file_walk, main_options);
  317                     parse_dir(file_work, main_options);
  318                     free(file_work);
  319                 }
  320                 else if (S_ISREG(stat_info.st_mode)) {
  321                     parse_file(*file_walk, main_options);
  322                 }
  323                 else if (main_options->special) {
  324                     parse_special(*file_walk, main_options);
  325                 }
  326             }
  327 
  328             file_walk++;
  329         }
  330     } else {
  331         if (main_options->files[0] != NULL) {
  332             file_walk = main_options->files;
  333             while (*file_walk) {
  334                 err = lstat(*file_walk, &stat_info);
  335                 if (err == -1) {
  336                     fprintf(stderr, "%s: %s\n", *file_walk, strerror(errno));
  337                 }
  338                 else {
  339                     if (S_ISDIR(stat_info.st_mode)) {
  340                         fprintf(stderr, "%s: is a directory\n", *file_walk);
  341                     }
  342                     else {
  343                         parse_inline(*file_walk, main_options);
  344                     }
  345                 }
  346 
  347                 file_walk++;
  348             }
  349         }
  350         else {
  351             parse_inline(NULL, main_options);
  352         }
  353     }
  354 
  355     return 0;
  356 }