"Fossies" - the Fresh Open Source Software Archive

Member "xorriso-1.5.4/libjte/libjte.c" (30 Jan 2021, 15404 Bytes) of package /linux/misc/xorriso-1.5.4.pl02.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 "libjte.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.5.2_vs_1.5.4.

    1 /*
    2  * libjte.c
    3  *
    4  * Copyright (c) 2010-2011 Thomas Schmitt <scdbackup@gmx.net>
    5  *
    6  * API functions of libjte
    7  *
    8  * GNU LGPL v2.1 (including option for GPL v2 or later)
    9  *
   10  */
   11 
   12 #ifdef HAVE_CONFIG_H
   13 #include "../config.h"
   14 #endif
   15 
   16 #include <stdio.h>
   17 #include <ctype.h>
   18 #include <sys/types.h>
   19 #include <unistd.h>
   20 #include <string.h>
   21 #include <stdlib.h>
   22 
   23 #ifdef HAVE_STDINT_H
   24 #include <stdint.h>
   25 #else
   26 #ifdef HAVE_INTTYPES_H
   27 #include <inttypes.h>
   28 #endif
   29 #endif
   30 
   31 #include <errno.h>
   32 
   33 
   34 #include "jte.h"
   35 #include "checksum.h"
   36 
   37 #include "libjte_private.h"
   38 #include "libjte.h"
   39 
   40 
   41 
   42 /* @param flag bit0= do not free *dest before overwriting it
   43 */
   44 static int libjte__set_string(char **dest, char *source, int flag)
   45 {
   46     if (*dest != NULL && !(flag & 1))
   47         free(*dest);
   48     *dest = NULL;
   49     if (source == NULL)
   50         return 1;
   51     *dest = strdup(source);
   52     if (*dest == NULL)
   53         return -1;
   54     return 1;
   55 }
   56 
   57 
   58 /* Version inquiry API */
   59 
   60 void libjte__version(int *major, int *minor, int *micro)
   61 {
   62     *major = LIBJTE_VERSION_MAJOR;
   63     *minor = LIBJTE_VERSION_MINOR;
   64     *micro = LIBJTE_VERSION_MICRO;
   65 }
   66 
   67 
   68 int libjte__is_compatible(int major, int minor, int micro, int flag)
   69 {
   70  int own_major, own_minor, own_micro;
   71 
   72  libjte__version(&own_major, &own_minor, &own_micro);
   73  return(own_major > major ||
   74         (own_major == major && (own_minor > minor ||
   75          (own_minor == minor && own_micro >= micro))));
   76 }
   77 
   78 
   79 /* Life cycle API */
   80 
   81 
   82 int libjte_new(struct libjte_env **jte_handle, int flag)
   83 {
   84     struct libjte_env *o;
   85 
   86     if (sizeof(off_t) < 8) {
   87         fprintf(stderr, "libjte: Fatal compile time misconfiguration. sizeof(off_t) = %d too small.\n\n", (int) sizeof(off_t));
   88         return -1;
   89     }
   90 
   91     *jte_handle = o = calloc(1, sizeof(struct libjte_env));
   92     if (o == NULL)
   93         return -1;
   94     o->jtemplate_out = NULL;
   95     o->jjigdo_out = NULL;
   96     o->jchecksum_list = NULL;
   97     o->checksum_algo = CHECK_MD5;
   98     o->jtjigdo = NULL;
   99     o->jttemplate = NULL;
  100     o->jte_min_size = MIN_JIGDO_FILE_SIZE;
  101     o->checksum_algo_iso =  (CHECK_MD5_USED | \
  102                              CHECK_SHA1_USED | \
  103                              CHECK_SHA256_USED | \
  104                              CHECK_SHA512_USED);
  105     o->checksum_algo_tmpl = (CHECK_MD5_USED | CHECK_SHA256_USED);
  106     o->jte_template_compression = JTE_TEMP_GZIP;
  107     o->exclude_list = NULL;
  108     o->include_list = NULL;
  109     o->map_list = NULL;
  110     o->template_size = 0;
  111     o->image_size = 0;
  112     o->iso_context = NULL;
  113     o->template_context = NULL;
  114     o->entry_list = NULL;
  115     o->entry_last = NULL;
  116     o->t_file = NULL;
  117     o->j_file = NULL;
  118     o->num_matches = 0;
  119     o->num_chunks = 0;
  120     o->checksum_list = NULL;
  121     o->checksum_last = NULL;
  122     o->include_in_jigdo = 0;
  123     memset(o->message_buffer, 0, sizeof(o->message_buffer));
  124     o->error_behavior = 1; /* Print to stderr, do not exit but return -1 */
  125     o->msg_list = NULL;
  126     o->uncomp_buf = NULL;
  127     o->uncomp_size = 0;
  128     o->uncomp_buf_used = 0;
  129     return 1;
  130 }
  131 
  132 int libjte_destroy(struct libjte_env **jte_handle)
  133 {
  134     struct libjte_env *o;
  135 
  136     o = *jte_handle;
  137     if (o == NULL)
  138         return 0;
  139 
  140     free(o->outfile);
  141     free(o->jtemplate_out);
  142     free(o->jjigdo_out);
  143     free(o->jchecksum_list);
  144     if (o->jtjigdo != NULL)
  145         fclose(o->jtjigdo);
  146     if (o->jttemplate != NULL)
  147         fclose(o->jttemplate);
  148 
  149     libjte_destroy_path_match_list(o, 0); /* include_list */
  150     libjte_destroy_path_match_list(o, 1); /* exclude_list */
  151     libjte_destroy_path_mapping(o, 0);
  152 
  153     if (o->iso_context != NULL)
  154         checksum_free_context(o->iso_context);
  155     if (o->template_context != NULL)
  156         checksum_free_context(o->template_context);
  157 
  158     /* >>> TODO : get rid of the following odd situation
  159        o->j_file and o->t_file seem to be only copies of
  160        o->jttemplate and o->jtjigdo */
  161 
  162     libjte_destroy_entry_list(o, 0);
  163     libjte_destroy_checksum_list(o, 0);
  164 
  165     libjte_clear_msg_list(o, 1 | 2); /* dump pending messages to stderr */
  166     free(o->uncomp_buf);
  167     free(o);
  168     *jte_handle = NULL;
  169     return 1;
  170 }
  171 
  172 /* Setup API */
  173 
  174 int libjte_set_outfile(struct libjte_env *o, char *outfile)
  175 {
  176     return libjte__set_string(&(o->outfile), outfile, 0);
  177 }
  178 
  179 int libjte_set_verbose(struct libjte_env *o, int verbose)
  180 {
  181     o->verbose = !!verbose;
  182     return 1;
  183 }
  184 
  185 int libjte_set_checksum_algorithm(struct libjte_env *o,
  186                   char *algorithm,
  187                   int *size)
  188 {
  189     int i = 0;
  190     for (i = 0; ; i++)
  191     {
  192         if (check_algos[i].name == NULL)
  193         {
  194             sprintf(o->message_buffer,
  195                     "libjte: Unknown checksum algorithm %s", algorithm);
  196             libjte_add_msg_entry(o, o->message_buffer, 0);
  197             return -1;
  198         }
  199         if (!strcmp(algorithm, check_algos[i].name))
  200             break;
  201     }
  202     o->checksum_algo = i;
  203     *size = check_algos[i].raw_bytes;
  204     return 1;
  205 }    
  206 
  207 
  208 int libjte_set_template_path(struct libjte_env *o, char *jtemplate_out)
  209 {
  210     return libjte__set_string(&(o->jtemplate_out), jtemplate_out, 0);
  211 }
  212 
  213 int libjte_set_jigdo_path(struct libjte_env *o, char *jjigdo_out)
  214 {
  215     return libjte__set_string(&(o->jjigdo_out), jjigdo_out, 0);
  216 }
  217 
  218 int libjte_set_md5_path(struct libjte_env *o, char *path)
  219 {
  220     return libjte_set_checksum_path(o, path);
  221 }
  222 
  223 int libjte_set_checksum_path(struct libjte_env *o, char *path)
  224 {
  225     return libjte__set_string(&(o->jchecksum_list), path, 0);
  226 }
  227 
  228 int libjte_set_min_size(struct libjte_env *o, int jte_min_size)
  229 {
  230     o->jte_min_size = jte_min_size;
  231     return 1;
  232 }
  233 
  234 static int libjte_decode_checksum_string(struct libjte_env *o,
  235                                          char *checksum_code, int default_algo,
  236                                          int *algo)
  237 {
  238 
  239 #ifdef NIX
  240 
  241     *algo = 0;
  242     if (strcmp(checksum_code, "default") != 0) {
  243         if (strstr(checksum_code, "md5") != NULL)
  244             *algo |= CHECK_MD5_USED;
  245         if (strstr(checksum_code, "sha1") != NULL)
  246             *algo |= CHECK_SHA1_USED;
  247         if (strstr(checksum_code, "sha256") != NULL)
  248             *algo |= CHECK_SHA256_USED;
  249         if (strstr(checksum_code, "sha512") != NULL)
  250             *algo |= CHECK_SHA512_USED;
  251     }
  252     if (*algo == 0)
  253         *algo = default_algo;
  254 
  255 #else /* NIX */
  256 
  257     int ret;
  258 
  259     ret = parse_checksum_algo(checksum_code, algo);
  260     if (ret) {
  261         *algo = default_algo;
  262         sprintf(o->message_buffer, "Invalid checksum algorithm name in '%s'",
  263                 checksum_code);
  264         libjte_add_msg_entry(o, o->message_buffer, 0);
  265         return 0;
  266     }
  267 
  268 #endif /* ! NIX */
  269 
  270     return 1;
  271 }
  272 
  273 int libjte_set_checksum_iso(struct libjte_env *o, char *checksum_code)
  274 {
  275     int ret;
  276     int checksum_algo_iso = (CHECK_MD5_USED | 
  277                              CHECK_SHA1_USED | 
  278                              CHECK_SHA256_USED |
  279                              CHECK_SHA512_USED);
  280 
  281     ret = libjte_decode_checksum_string(o, checksum_code, checksum_algo_iso,
  282                                         &checksum_algo_iso);
  283     if (ret <= 0)
  284         return ret;
  285     o->checksum_algo_iso = checksum_algo_iso;
  286 
  287     /* Maybe have to override - if we're doing a v2 jigdo file based
  288      * around sha256, we always need the sha256 calculated too */
  289     if (o->checksum_algo == CHECK_SHA256)
  290         o->checksum_algo_iso |= CHECK_SHA256_USED;
  291 
  292     return 1;
  293 }
  294 
  295 int libjte_set_checksum_template(struct libjte_env *o, char *checksum_code)
  296 {
  297     int ret;
  298     int checksum_algo_tmpl = CHECK_MD5_USED;
  299 
  300     ret = libjte_decode_checksum_string(o, checksum_code, checksum_algo_tmpl,
  301                                         &checksum_algo_tmpl);
  302     if (ret <= 0)
  303         return ret;
  304     o->checksum_algo_tmpl = checksum_algo_tmpl;
  305 
  306     /* Maybe have to override - if we're doing a v2 jigdo file based
  307      * around sha256, we always need the sha256 calculated too */
  308     if (o->checksum_algo == CHECK_SHA256)
  309         o->checksum_algo_tmpl |= CHECK_SHA256_USED;
  310 
  311     return 1;
  312 }
  313 
  314 int libjte_set_compression(struct libjte_env *o, char *compression_code)
  315 {
  316     jtc_t compr = JTE_TEMP_GZIP;
  317 
  318     if (strcmp(compression_code, "default") != 0) {
  319         if (strcmp(compression_code, "gzip") == 0)
  320             compr = JTE_TEMP_GZIP;
  321         else if (strcmp(compression_code, "bzip2") ==0)
  322             compr = JTE_TEMP_BZIP2;
  323         else {
  324             sprintf(o->message_buffer,
  325                     "libjte: Unknown compression code. Known: gzip bzip2");
  326             libjte_add_msg_entry(o, o->message_buffer, 0);
  327             return 0;
  328         }
  329     }
  330 
  331 #ifndef LIBJTE_WITH_LIBBZ2
  332 
  333     if (compr == JTE_TEMP_BZIP2) {
  334         sprintf(o->message_buffer,
  335                 "libjte: Usage of libbz2 not enabled at compile time\n");
  336         libjte_add_msg_entry(o, o->message_buffer, 0);
  337         return 0;
  338     }
  339 
  340 #endif /* LIBJTE_WITH_LIBBZ2 */
  341  
  342     o->jte_template_compression = compr;
  343     return 1;
  344 }
  345 
  346 int libjte_add_exclude(struct libjte_env *o, char *pattern)
  347 {
  348     int ret;
  349 
  350     ret = jte_add_exclude(o, pattern);
  351     return !ret;
  352 }
  353 
  354 int libjte_add_md5_demand(struct libjte_env *o, char *pattern)
  355 {
  356     int ret;
  357 
  358     ret = jte_add_include(o, pattern);
  359     return !ret;
  360 }
  361 
  362 int libjte_add_checksum_demand(struct libjte_env *o, char *pattern)
  363 {
  364     int ret;
  365 
  366     ret = jte_add_include(o, pattern);
  367     return !ret;
  368 }
  369 
  370 int libjte_add_mapping(struct libjte_env *o, char *arg)
  371 {
  372     int ret;
  373 
  374     ret = jte_add_mapping(o, arg);
  375     return !ret;
  376 }
  377 
  378 int libjte_set_image_size(struct libjte_env *o, off_t image_size)
  379 {
  380     o->image_size = image_size;
  381     return 1;
  382 }
  383 
  384 
  385 /* Operation API */
  386 
  387 int libjte_write_header(struct libjte_env *o)
  388 {
  389     int ret;
  390 
  391     if (o->jtemplate_out == NULL || o->jjigdo_out == NULL ||
  392         o->outfile == NULL || o->jchecksum_list == NULL) {
  393         sprintf(o->message_buffer,
  394                "Undefined: template_path, jigdo_path, checksum_paths, or outfile.");
  395         libjte_add_msg_entry(o, o->message_buffer, 0);
  396         return 0;
  397     }
  398     
  399     o->jttemplate = fopen(o->jtemplate_out, "wb");
  400     if (o->jttemplate == NULL) {
  401         sprintf(o->message_buffer,
  402                 "Cannot open template file '%1.1024s' for writing. errno=%d",
  403                 o->jtemplate_out, errno);
  404         libjte_add_msg_entry(o, o->message_buffer, 0);
  405         return 0;
  406     }
  407     o->jtjigdo = fopen(o->jjigdo_out, "wb");
  408     if (o->jtjigdo == NULL) {
  409         sprintf(o->message_buffer,
  410                 "Cannot open jigdo file '%1.1024s' for writing. errno=%d",
  411                 o->jjigdo_out, errno);
  412         libjte_add_msg_entry(o, o->message_buffer, 0);
  413         return 0;
  414     }
  415 
  416     ret = write_jt_header(o, o->jttemplate, o->jtjigdo);
  417     if (ret <= 0)
  418         return ret;
  419     return 1;
  420 }
  421 
  422 int libjte_write_footer(struct libjte_env *o)
  423 {
  424     int ret;
  425 
  426     ret = write_jt_footer(o);
  427     if (o->jtjigdo != NULL)
  428         fclose(o->jtjigdo);
  429     if (o->jttemplate != NULL)
  430         fclose(o->jttemplate);
  431     o->jtjigdo = NULL;
  432     o->jttemplate = NULL;
  433     if (ret <= 0)
  434         return ret;
  435     return 1;
  436 }
  437 
  438 /* Traditional Data File API */
  439 
  440 int libjte_write_unmatched(struct libjte_env *o, void *buffer, int size,
  441                             int count)
  442 {
  443     int ret;
  444 
  445     ret = jtwrite(o, buffer, size, count);
  446     return ret;
  447 }
  448 
  449 int libjte_write_match_record(struct libjte_env *o,
  450                             char *filename, char *mirror_name, int sector_size,
  451                             off_t size, unsigned char md5[16])
  452 {
  453     int ret;
  454 
  455     if (check_algos[o->checksum_algo].type != CHECK_MD5)
  456     {
  457         sprintf(o->message_buffer, "Attempted to call libjte_write_match_record() after choosing checksum algorithm '%s'",
  458                 check_algos[o->checksum_algo].name);
  459         libjte_add_msg_entry(o, o->message_buffer, 0);
  460         return 0;
  461     }
  462 
  463     ret = write_jt_match_record(o, filename, mirror_name, sector_size, size,
  464                                 md5);
  465     if (ret <= 0)
  466         return ret;
  467     return 1;
  468 }
  469 
  470 int libjte_write_match_record2(struct libjte_env *o,
  471                    char *filename, char *mirror_name, int sector_size,
  472                    off_t size, unsigned char *checksum)
  473 {
  474     int ret;
  475 
  476     ret = write_jt_match_record(o, filename, mirror_name,
  477                 sector_size, size, checksum);
  478     if (ret <= 0)
  479         return ret;
  480     return 1;
  481 }
  482 
  483 int libjte_decide_file_jigdo(struct libjte_env *o,
  484                              char *filename, off_t size, char **mirror_name,
  485                              unsigned char md5[16])
  486 {
  487     if (check_algos[o->checksum_algo].type != CHECK_MD5)
  488     {
  489         sprintf(o->message_buffer, "Attempted to call libjte_decide_file_jigdo() after choosing checksum algorithm '%s'",
  490                 check_algos[o->checksum_algo].name);
  491     libjte_add_msg_entry(o, o->message_buffer, 0);
  492         return 0;
  493     }
  494 
  495     return libjte_decide_file_jigdo2(o, filename, size, mirror_name, md5);
  496 }
  497 
  498 int libjte_decide_file_jigdo2(struct libjte_env *o,
  499                   char *filename, off_t size, char **mirror_name,
  500                   unsigned char *checksum)
  501 {
  502     int ret;
  503     char *checksum_name;
  504 
  505     *mirror_name = NULL;
  506     ret = list_file_in_jigdo(o, filename, size, &checksum_name, checksum);
  507     if (ret <= 0)
  508         return ret;
  509     *mirror_name = strdup(checksum_name);
  510     if (*mirror_name == NULL) {
  511         libjte_report_no_mem(o, strlen(checksum_name) + 1, 0);
  512         return -1;
  513     }
  514     return 1;
  515 }
  516 
  517 /* Simplified Data File API */
  518 
  519 int libjte_begin_data_file(struct libjte_env *o, char *filename,
  520                            int sector_size, off_t size)
  521 {
  522     int ret;
  523     char *mirror_name;
  524     unsigned char *checksum;
  525 
  526     checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
  527     if (!checksum)
  528         return -1;
  529 
  530     o->include_in_jigdo = 0;
  531     ret = list_file_in_jigdo(o, filename, size, &mirror_name, checksum);
  532     if (ret < 0)
  533     {
  534         free(checksum);
  535         return ret;
  536     }
  537     if (ret == 0)
  538     {
  539         free(checksum);
  540         return 2;
  541     }
  542     write_jt_match_record(o, filename, mirror_name, sector_size,
  543                           size, checksum);
  544     o->include_in_jigdo = 1;
  545     return 1;
  546 }
  547 
  548 int libjte_show_data_chunk(struct libjte_env *o,
  549                            void *buffer, int sector_size,
  550                            int count)
  551 {
  552     o->image_size += count * sector_size;
  553     if (o->include_in_jigdo)
  554         return 2;
  555     jtwrite(o, buffer, sector_size, count);
  556     return 1;
  557 }
  558 
  559 int libjte_end_data_file(struct libjte_env *o)
  560 {
  561     o->include_in_jigdo = 0;
  562     return 1;
  563 }
  564 
  565 
  566 /* Error reporting API */
  567 
  568 int libjte_set_error_behavior(struct libjte_env *o,
  569                               int to_stderr, int with_exit)
  570 {
  571     o->error_behavior = 0;
  572     if (to_stderr > 0)
  573         o->error_behavior |= 1;
  574     if (with_exit> 0)
  575         o->error_behavior |= 2;
  576     return 1;
  577 }
  578 
  579 char *libjte_get_next_message(struct libjte_env *o)
  580 {
  581     jigdo_msg_entry_t *old_entry;
  582     char *msg;
  583 
  584     if (o->msg_list == NULL)
  585         return NULL;
  586     old_entry = o->msg_list;
  587     o->msg_list = old_entry->next;
  588     msg = old_entry->message;
  589     free(old_entry);
  590     return msg;
  591 }
  592 
  593 /* @param flag bit0= print pending messages to stderr
  594 */
  595 int libjte_clear_msg_list(struct libjte_env *o, int flag)
  596 {
  597     char *msg;
  598 
  599     if ((flag & 2) && o->msg_list != NULL)
  600         fprintf(stderr,
  601                     "libjte: -- have to dump error messages to stderr --\n");
  602     while (1) {
  603         msg = libjte_get_next_message(o);
  604         if (msg == NULL)
  605     break;
  606         if (flag & 1)
  607             fprintf(stderr, "libjte: %s\n", msg);
  608         free(msg);
  609     }
  610     return 1;
  611 }
  612