xorriso  1.5.4.pl02
About: GNU xorriso creates, loads, manipulates and writes ISO 9660 filesystem images with Rock Ridge extensions. It is suitable for incremental data backup and for production of bootable ISO 9660 images. GNU xorriso is a statical compilation of the libraries libburn, libisofs, libisoburn, and libjte.
  Fossies Dox: xorriso-1.5.4.pl02.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

jte.c
Go to the documentation of this file.
1 /*
2  * jte.c
3  *
4  *
5  * Copyright (c) 2004-2019 Steve McIntyre <steve@einval.com>
6  * Copyright (c) 2010-2011 Thomas Schmitt <scdbackup@gmx.net>
7  * Copyright (c) 2010-2011 George Danchev <danchev@spnet.net>
8  *
9  * These routines were originally implemented by
10  * Steve McIntyre <steve@einval.com>.
11  * More recently few tweaks and additions were applied by
12  * Thomas Schmitt <scdbackup@gmx.net> and
13  * George Danchev <danchev@spnet.net>
14  * Updated by Steve to add more generic checksum support, first for sha256
15  *
16  * Implementation of the Jigdo Template Engine - make jigdo files
17  * directly when making ISO images
18  *
19  * GNU GPL v2+
20  */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "../config.h"
24 #endif
25 
26 #ifdef HAVE_STDINT_H
27 #include <stdint.h>
28 #else
29 #ifdef HAVE_INTTYPES_H
30 #include <inttypes.h>
31 #endif
32 #endif
33 
34 #include <string.h>
35 #include <stdlib.h>
36 
37 #ifdef LIBJTE_WITH_ZLIB
38 #include <zlib.h>
39 #endif
40 
41 #ifdef LIBJTE_WITH_LIBBZ2
42 #include <bzlib.h>
43 #endif
44 
45 #include <sys/types.h>
46 #include <ctype.h>
47 #include <errno.h>
48 #include "jte.h"
49 #include "checksum.h"
50 #include "endianconv.h"
51 #include "rsync.h"
52 #include "libjte_private.h"
53 #include "libjte.h"
54 
55 /* Different types used in building our state list below */
56 #define JTET_FILE_MATCH 1
57 #define JTET_NOMATCH 2
58 
59 #define JTE_VER_MAJOR 0x0002
60 #define JTE_VER_MINOR 0x0000
61 #define JTE_NAME "JTE"
62 #define JTE_COMMENT "JTE at https://www.einval.com/~steve/software/JTE/ ; Jigdo at https://www.einval.com/~steve/software/jigdo/"
63 
64 #define JIGDO_TEMPLATE_VERSION_MD5 "1.1"
65 #define JIGDO_TEMPLATE_VERSION_SHA256 "2.0"
66 
67 #define JTE_MAX_ERROR_LIST_LENGTH 20
68 
69 /* The various type of jigdo descriptor */
81 };
82 
83 /* Grab the file component from a full path */
84 static char *file_base_name(char *path)
85 {
86  char *endptr = path;
87  char *ptr = path;
88 
89  while (*ptr != '\0')
90  {
91  if ('/' == *ptr)
92  endptr = ++ptr;
93  else
94  ++ptr;
95  }
96  return endptr;
97 }
98 
99 static void exit_if_enabled(struct libjte_env *o, int value)
100 {
101  if (!(o->error_behavior & 2))
102  return;
103  libjte_clear_msg_list(o, 1);
104  exit(value);
105 }
106 
107 int libjte_report_no_mem(struct libjte_env *o, size_t size, int flag)
108 {
109  sprintf(o->message_buffer, "Out of memory for %.f new bytes",
110  (double) size);
112  return -1;
113 }
114 
115 /* @param flag bit0-7 = mode
116  0= include_list
117  1= exclude_list
118 */
119 static int jte_add_path_match(struct libjte_env *o, char *pattern, int flag)
120 {
121  struct path_match *new = NULL, **old;
122  int mode;
123 
124  mode = flag & 255;
125  if (mode == 0)
126  old = &(o->include_list);
127  else
128  old = &(o->exclude_list);
129 
130  new = malloc(sizeof *new);
131  if (new == NULL)
132  return libjte_report_no_mem(o, sizeof *new, 0);
133 
134  regcomp(&new->match_pattern, pattern, REG_NEWLINE);
135  new->match_rule = strdup(pattern);
136  if (new->match_rule == NULL)
137  return libjte_report_no_mem(o, sizeof *new, 0);
138 
139  /* Order on the list doesn't matter! */
140  new->next = *old;
141 
142  *old = new;
143  return 0;
144 }
145 
146 /* @param flag bit0-7 = mode
147  0= include_list
148  1= exclude_list
149 */
151 {
152  struct path_match **old, *s, *s_next;
153  int mode;
154 
155  mode = flag & 255;
156  if (mode == 0)
157  old = &(o->include_list);
158  else
159  old = &(o->exclude_list);
160  for (s = *old; s != NULL; s = s_next) {
161  s_next = s->next;
162  regfree(&(s->match_pattern));
163  free(s->match_rule);
164  free(s);
165  }
166  *old = NULL;
167  return 1;
168 }
169 
170 /* Build the list of exclusion regexps */
171 int jte_add_exclude(struct libjte_env *o, char *pattern)
172 {
173  int ret;
174 
175  ret = jte_add_path_match(o, pattern, 1);
176  return ret;
177 }
178 
179 /* Check if the file should be excluded because of a filename match. 1
180  means exclude, 0 means not */
181 static int check_exclude_by_name(struct libjte_env *o,
182  char *filename, char **matched)
183 {
184  struct path_match *ptr = o->exclude_list;
185  regmatch_t pmatch[1];
186 
187  while (ptr)
188  {
189  if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0))
190  {
191  *matched = ptr->match_rule;
192  return 1;
193  }
194  ptr = ptr->next;
195  }
196 
197  /* Not matched, so return 0 */
198  return 0;
199 }
200 
201 /* Build the list of required inclusion regexps */
202 int jte_add_include(struct libjte_env *o, char *pattern)
203 {
204  int ret;
205 
206  ret = jte_add_path_match(o, pattern, 0);
207  return ret;
208 }
209 
210 int libjte_destroy_entry_list(struct libjte_env *o, int flag)
211 {
212  entry_t *s, *s_next;
213 
214  for (s = o->entry_list ; s != NULL; s = s_next) {
215  s_next = s->next;
216  if (s->entry_type == JTET_FILE_MATCH) {
217  if (s->data.file.filename != NULL)
218  free(s->data.file.filename);
219  }
220  free(s);
221  }
222  o->entry_list = o->entry_last = NULL;
223  return 1;
224 }
225 
226 /* Check if a file has to be checksum-matched to be valid. If we get called
227  here, we've failed to match any of the checksum entries we were
228  given. If the path to the filename matches one of the paths in our
229  list, clearly it must have been corrupted. Abort with an error. */
230 static int check_checksum_file_match(struct libjte_env *o, char *filename)
231 {
232  struct path_match *ptr = o->include_list;
233  regmatch_t pmatch[1];
234 
235  while (ptr)
236  {
237  if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0))
238  {
239  sprintf(o->message_buffer,
240  "File %1.1024s should have matched a checksum entry, but didn't! (Rule '%1.1024s')",
241  filename, ptr->match_rule);
243  exit_if_enabled(o, 1);
244  return -1;
245  }
246  ptr = ptr->next;
247  }
248  return 0;
249 }
250 
251 /* Should we list a file separately in the jigdo output, or should we
252  just dump it into the template file as binary data? Three things
253  cases to look for here:
254 
255  1. Small files are better simply folded in, as they take less space that way.
256 
257  2. Files in /doc (for example) may change in the archive all the
258  time and it's better to not have to fetch snapshot copies if we
259  can avoid it.
260 
261  3. Files living in specified paths *must* match an entry in the
262  checksum-list, or they must have been corrupted. If we find a
263  corrupt file, bail out with an error.
264 
265 */
267  char *filename, off_t size,
268  char **realname, unsigned char *checksum)
269 {
270  char *matched_rule;
272  int checksum_done = 0, ret;
273 
274  if (o->jtemplate_out == NULL)
275  return 0;
276 
277  memset(checksum, 0, check_algos[o->checksum_algo].raw_bytes);
278 
279  /* Cheaper to check file size first */
280  if (size < o->jte_min_size)
281  {
282  if (o->verbose > 1) {
283  sprintf(o->message_buffer,
284  "Jigdo-ignoring file %1.1024s; it's too small", filename);
286  }
287  return 0;
288  }
289 
290  /* Now check the excluded list by name */
291  if (check_exclude_by_name(o, filename, &matched_rule))
292  {
293  if (o->verbose > 1) {
294  sprintf(o->message_buffer,
295  "Jigdo-ignoring file %1.1024s; it's covered in the exclude list by \"%1.1024s\"",
296  filename, matched_rule);
298  }
299  return 0;
300  }
301 
302  /* Check to see if the file is in our checksum list. Check three things:
303 
304  1. the size
305  2. the filename
306  3. (only if the first 2 match) the checksum
307 
308  If we get a match for all three, include the file and return
309  the full path to the file that we have gleaned from the mirror.
310  */
311 
312  while (entry)
313  {
314  if (size == (off_t)entry->size)
315  {
316  if (!strcmp(file_base_name(filename), file_base_name(entry->filename)))
317  {
318  if (!checksum_done)
319  {
320  ret = checksum_calculate(filename, size,
321  checksum, check_algos[o->checksum_algo].type);
322  if (ret < 0) { /* (0 is success) */
323  sprintf(o->message_buffer,
324  "Error with file '%1.1024s' : errno=%d",
325  filename, errno);
327  return -1;
328  }
329  checksum_done = 1;
330  }
331  if (!memcmp(checksum, entry->checksum, check_algos[o->checksum_algo].raw_bytes))
332  {
333  *realname = entry->filename;
334  return 1;
335  }
336  }
337  }
338  entry = entry->next;
339  }
340 
341  /* We haven't found an entry in our checksum list to match this
342  * file. If we should have done, complain and bail out. */
343  ret = check_checksum_file_match(o, filename);
344  return ret;
345 }
346 
347 /* Add a mapping of pathnames (e.g. Debian=/mirror/debian). We should
348  be passed TO=FROM here */
349 int jte_add_mapping(struct libjte_env *o, char *arg)
350 {
351  struct path_mapping *new = NULL;
352  struct path_mapping *entry = NULL;
353  char *p = arg;
354  char *from = NULL;
355  char *to = NULL;
356  char *eqpt = NULL;
357 
358  /* Find the "=" in the string passed. */
359  while (*p)
360  {
361  if ('=' == *p)
362  {
363  if (eqpt == NULL)
364  eqpt = p;
365  p++;
366  from = p;
367  break;
368  }
369  p++;
370  }
371  if (from == NULL || !strlen(from) || eqpt == arg)
372  return EINVAL;
373  from = strdup(from);
374  if (from == NULL)
375  return ENOMEM;
376  to = calloc(1, (eqpt - arg) + 1);
377  if (to == NULL) {
378  free(from);
379  return ENOMEM;
380  }
381  strncpy(to, arg, eqpt - arg);
382  to[eqpt - arg] = 0;
383 
384  new = malloc(sizeof(*new));
385  if (!new) {
386  free(to);
387  free(from);
388  return ENOMEM;
389  }
390  new->from = from;
391  new->to = to;
392  new->next = NULL;
393 
394  if (o->verbose > 0) {
395  sprintf(o->message_buffer,
396  "Adding mapping from %1.1024s to %1.1024s for the jigdo file",
397  from, to);
399  }
400  if (o->map_list == NULL)
401  o->map_list = new;
402  else
403  {
404  /* Order is important; add to the end of the list */
405  entry = o->map_list;
406  while (NULL != entry->next)
407  entry = entry->next;
408  entry->next = new;
409  }
410  return 0;
411 }
412 
413 
414 int libjte_destroy_path_mapping(struct libjte_env *o, int flag)
415 {
416  struct path_mapping *s, *s_next;
417 
418  for (s = o->map_list; s != NULL; s = s_next) {
419  s_next = s->next;
420  free(s->from);
421  free(s->to);
422  free(s);
423  }
424  o->map_list = NULL;
425  return 1;
426 }
427 
428 
429 /* Check if the filename should be remapped; if so map it, otherwise
430  return the original name. */
431 static char *remap_filename(struct libjte_env *o, char *filename)
432 {
433  char *new_name = filename;
434  struct path_mapping *entry = o->map_list;
435 
436  while (entry)
437  {
438  if (!strncmp(filename, entry->from, strlen(entry->from)))
439  {
440  new_name = calloc(1, 2 + strlen(filename) + strlen(entry->to) - strlen(entry->from));
441  if (!new_name)
442  {
443  sprintf(o->message_buffer,
444  "Failed to malloc new filename; abort!");
446  exit_if_enabled(o, 1);
447  return NULL;
448  }
449  sprintf(new_name, "%s:%s", entry->to, &filename[strlen(entry->from)]);
450  return new_name;
451  }
452  entry = entry->next;
453  }
454 
455  /* No mapping in effect */
456  return strdup(filename);
457 }
458 
459 /* Write data to the template file and update the checksum */
460 static int template_fwrite(struct libjte_env *o,
461  const void *ptr, size_t size, size_t nmemb, FILE *stream)
462 {
463  size_t written;
464 
465  checksum_update(o->template_context, ptr, size * nmemb);
466  written = fwrite(ptr, size, nmemb, stream);
467  o->template_size += written * size;
468  if (written != nmemb)
469  return 0;
470  return 1;
471 }
472 
473 /* Create a new template file and initialise it */
474 static int write_template_header(struct libjte_env *o)
475 {
476  char buf[2048];
477  int i = 0;
478  char *p = buf;
479 
480 #ifndef LIBJTE_WITH_LIBBZ2
481 
483  sprintf(o->message_buffer,
484  "libjte: Compression algorithm BZIP2 not enabled at compile time");
486  exit_if_enabled(o, 1);
487  return -1;
488  }
489 
490 #endif /* LIBJTE_WITH_LIBBZ2 */
491 
492  memset(buf, 0, sizeof(buf));
493 
494  if (o->template_context != NULL)
497  "template");
498  if (o->template_context == NULL)
499  {
500  sprintf(o->message_buffer,
501  "cannot allocate template checksum contexts");
503  exit_if_enabled(o, 1);
504  return -1;
505  }
506 
508  i += sprintf(p, "JigsawDownload template %s libjte-%d.%d.%d \r\n",
511  else /* CHECK_SHA256 */
512  i += sprintf(p, "JigsawDownload template %s libjte-%d.%d.%d \r\n",
515  p = &buf[i];
516 
517  i += sprintf(p, "%s \r\n", JTE_COMMENT);
518  p = &buf[i];
519 
520  i += sprintf(p, "\r\n");
521  if (template_fwrite(o, buf, i, 1, o->t_file) <= 0)
522  return 0;
523  return 1;
524 }
525 
526 /* Read the checksum list and build a list in memory for us to use later */
527 static int add_checksum_entry(struct libjte_env *o,
528  unsigned char *checksum, uint64_t size,
529  char *filename)
530 {
531  checksum_list_entry_t *new = NULL;
532 
533  new = calloc(1, sizeof(checksum_list_entry_t));
534  if (!new)
535  return ENOMEM;
536  new->checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
537  if (!new->checksum)
538  {
539  free(new);
540  return ENOMEM;
541  }
542  memcpy(new->checksum, checksum, check_algos[o->checksum_algo].raw_bytes);
543  new->size = size;
544  new->filename = strdup(filename);
545  if (!new->filename)
546  {
547  free(new->checksum);
548  free(new);
549  return ENOMEM;
550  }
551 
552  /* Add to the end of the list */
553  if (NULL == o->checksum_last)
554  {
555  o->checksum_last = new;
556  o->checksum_list = new;
557  }
558  else
559  {
560  o->checksum_last->next = new;
561  o->checksum_last = new;
562  }
563  return 0;
564 }
565 
566 int libjte_destroy_checksum_list(struct libjte_env *o, int flag)
567 {
568  checksum_list_entry_t *s, *s_next;
569 
570  for (s = o->checksum_list; s != NULL; s = s_next) {
571  s_next = s->next;
572  free(s->checksum);
573  free(s->filename);
574  free(s);
575  }
576  o->checksum_list = o->checksum_last = NULL;
577  return 1;
578 }
579 
580 /* Parse a 12-digit decimal number */
581 static uint64_t parse_number(unsigned char in[12])
582 {
583  uint64_t size = 0;
584  int i = 0;
585 
586  for (i = 0; i < 12; i++)
587  {
588  size *= 10;
589  if (isdigit(in[i]))
590  size += (in[i] - '0');
591  }
592 
593  return size;
594 }
595 
596 /* Read the checksum list and build a list in memory for us to use later
597  list format:
598 
599  <---checksum---> <--Size--> <--Filename-->
600  XX 12 remaining
601 
602  We know XX (length of the checksum in hex) from the specified
603  checksum type in our env. We explicitly check here that the
604  entries are well-formed
605 */
606 static int parse_checksum_list(struct libjte_env *o)
607 {
608  FILE *checksum_file = NULL;
609  unsigned char buf[1024];
610  unsigned char *checksum;
611  char *filename = NULL;
612  unsigned char *numbuf = NULL;
613  int num_files = 0;
614  uint64_t size = 0;
615  int i = 0;
616  int valid = 1;
617  int error = 0;
618  int csum_hex_size = check_algos[o->checksum_algo].hex_bytes;
619 
620  if (!strcmp (o->jchecksum_list, "/dev/null"))
621  {
622  if (o->verbose)
623  {
624  sprintf(o->message_buffer, "Ignoring call with checksum list file '%1.1024s'",
625  o->jchecksum_list);
627  }
628  return 1;
629  }
630 
631  checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
632  if (!checksum)
633  {
634  sprintf(o->message_buffer, "cannot allocate memory to read from checksum list file '%1.1024s'",
635  o->jchecksum_list);
637  exit_if_enabled(o, 1);
638  errno = ENOMEM;
639  return -1;
640  }
641 
642  checksum_file = fopen(o->jchecksum_list, "rb");
643  if (!checksum_file)
644  {
645  sprintf(o->message_buffer, "cannot open checksum list file '%1.1024s'",
646  o->jchecksum_list);
648  exit_if_enabled(o, 1);
649  return -1;
650  }
651 
652  /* Validate the first line - is it using the right checksum
653  * type? */
654  memset(buf, 0, sizeof(buf));
655  if(!fgets((char *)buf, sizeof(buf), checksum_file))
656  {
657  free(checksum);
658  fclose(checksum_file);
659  sprintf(o->message_buffer, "cannot read from checksum list file '%1.1024s'",
660  o->jchecksum_list);
662  exit_if_enabled(o, 1);
663  return -1;
664  }
665 
666  /* Check that we have hex digits for just the right number of
667  * characters, followed by two spaces */
668  for (i = 0; valid && i < csum_hex_size; i++)
669  if (!isxdigit(buf[i]))
670  valid = -i;
671  if (valid > 0) {
672  if (' ' != buf[csum_hex_size])
673  valid = -csum_hex_size;
674  if (' ' != buf[csum_hex_size+1])
675  valid = -csum_hex_size - 1;
676  }
677  if(valid <= 0)
678  {
679  free(checksum);
680  fclose(checksum_file);
681  sprintf(o->message_buffer, "invalid checksum list file '%1.1024s' - wrong checksum type?",
682  o->jchecksum_list);
684  exit_if_enabled(o, 1);
685  return -1;
686  }
687 
688  fseek(checksum_file, 0, SEEK_SET);
689  memset(buf, 0, sizeof(buf));
690  while (fgets((char *)buf, sizeof(buf), checksum_file))
691  {
692  numbuf = &buf[csum_hex_size + 2];
693  filename = (char *)&buf[csum_hex_size + 16];
694  /* Lose the trailing \n from the fgets() call */
695  if (buf[strlen((char *)buf)-1] == '\n')
696  buf[strlen((char *)buf)-1] = 0;
697 
698  if (checksum_parse_hex((char *)buf, checksum, csum_hex_size))
699  {
700  free(checksum);
701  fclose(checksum_file);
702  sprintf(o->message_buffer, "cannot parse checksum file '%1.1024s'",
703  o->jchecksum_list);
705  exit_if_enabled(o, 1);
706  return -1;
707  }
708  size = parse_number(numbuf);
709 
710  error = add_checksum_entry(o, checksum, size, filename);
711  if (error)
712  {
713  free(checksum);
714  fclose(checksum_file);
715  sprintf(o->message_buffer, "cannot add checksum entry to list from file '%1.1024s', error %d",
716  o->jchecksum_list, error);
718  exit_if_enabled(o, 1);
719  return -1;
720  }
721 
722  memset(buf, 0, sizeof(buf));
723  num_files++;
724  }
725  if (o->verbose > 0) {
726  sprintf(o->message_buffer,
727  "parse_checksum_list: added checksums for %d files", num_files);
729  }
730  free(checksum);
731  fclose(checksum_file);
732  return 1;
733 }
734 
735 /* Initialise state and start the jigdo template file */
737  FILE *template_file, FILE *jigdo_file)
738 {
739  int ret;
740 
741  o->t_file = template_file;
742  o->j_file = jigdo_file;
743 
744  /* Start checksum work for the image */
745  if (o->iso_context != NULL)
748  if (o->iso_context == NULL)
749  {
750  sprintf(o->message_buffer, "cannot allocate iso checksum contexts");
752  exit_if_enabled(o, 1);
753  return -1;
754  }
755 
756  /* Start the template file */
757  ret = write_template_header(o);
758  if (ret <= 0)
759  return ret;
760 
761  /* Load up the checksum list if we've been given one */
762  if (o->jchecksum_list) {
763  ret = parse_checksum_list(o);
764  if (ret <= 0)
765  return ret;
766  }
767  return 1;
768 }
769 
770 /* Compress and flush out a buffer full of template data */
771 /* Return 0 on failure, non-zero on success */
772 static int flush_gzip_chunk(struct libjte_env *o, void *buffer, off_t size)
773 {
774 
775 #ifdef LIBJTE_WITH_ZLIB
776 
777  z_stream c_stream; /* compression stream */
778  unsigned char comp_size_out[6];
779  unsigned char uncomp_size_out[6];
780  off_t compressed_size_out = 0;
781  int err = 0;
782  unsigned char *comp_buf = NULL;
783 
784  c_stream.zalloc = NULL;
785  c_stream.zfree = NULL;
786  c_stream.opaque = NULL;
787 
788  err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
789  if (err < 0)
790  return 0;
791 
792  if (NULL == (comp_buf = malloc(2 * size))) /* Worst case */
793  return 0;
794 
795  c_stream.next_out = comp_buf;
796  c_stream.avail_out = 2 * size;
797  c_stream.next_in = buffer;
798  c_stream.avail_in = size;
799 
800  err = deflate(&c_stream, Z_NO_FLUSH);
801  if (err < 0)
802  {
803  free(comp_buf);
804  return 0;
805  }
806 
807  err = deflate(&c_stream, Z_FINISH);
808  if (err < 0)
809  {
810  free(comp_buf);
811  return 0;
812  }
813 
814  compressed_size_out = c_stream.total_out + 16;
815  err = deflateEnd(&c_stream);
816  if (err < 0)
817  {
818  free(comp_buf);
819  return 0;
820  }
821 
822  if (template_fwrite(o, "DATA", 4, 1, o->t_file) <= 0)
823  {
824  free(comp_buf);
825  return 0;
826  }
827 
828  write_le48(compressed_size_out, &comp_size_out[0]);
829  if (template_fwrite(o, comp_size_out, sizeof(comp_size_out), 1, o->t_file)
830  <= 0)
831  {
832  free(comp_buf);
833  return 0;
834  }
835 
836  write_le48(size, &uncomp_size_out[0]);
837  if (template_fwrite(o, uncomp_size_out, sizeof(uncomp_size_out), 1,
838  o->t_file) <= 0)
839  {
840  free(comp_buf);
841  return 0;
842  }
843 
844  if (template_fwrite(o, comp_buf, c_stream.total_out, 1, o->t_file) <= 0)
845  return 0;
846  free(comp_buf);
847  return 1;
848 
849 #else /* LIBJTE_WITH_ZLIB */
850 
851  static int complaints = 0;
852 
853  if (complaints >= 3)
854  return 0;
855  complaints++;
856  fprintf(stderr,
857  "\nlibjte: Configuration error. Use without enabled zlib\n\n");
858  return 0;
859 
860 #endif /* ! LIBJTE_WITH_ZLIB */
861 
862 }
863 
864 
865 #ifdef LIBJTE_WITH_LIBBZ2
866 
867 /* Compress and flush out a buffer full of template data */
868 /* Return 0 on failure, non-zero on success */
869 static int flush_bz2_chunk(struct libjte_env *o, void *buffer, off_t size)
870 {
871  bz_stream c_stream; /* compression stream */
872  unsigned char comp_size_out[6];
873  unsigned char uncomp_size_out[6];
874  off_t compressed_size_out = 0;
875  int err = 0;
876  char *comp_buf = NULL;
877 
878  c_stream.bzalloc = NULL;
879  c_stream.bzfree = NULL;
880  c_stream.opaque = NULL;
881 
882  err = BZ2_bzCompressInit(&c_stream, 9, 0, 0);
883  if (err < 0)
884  return 0;
885 
886  if (NULL == (comp_buf = (char*) malloc(2 * size))) /* Worst case */
887  return 0;
888  c_stream.next_out = comp_buf;
889  c_stream.avail_out = 2 * size;
890  c_stream.next_in = buffer;
891  c_stream.avail_in = size;
892 
893  err = BZ2_bzCompress(&c_stream, BZ_FINISH);
894  if (err < 0)
895  {
896  free(comp_buf);
897  return 0;
898  }
899 
900  compressed_size_out = c_stream.total_out_lo32 + 16;
901  err = BZ2_bzCompressEnd(&c_stream);
902  if (err < 0)
903  {
904  free(comp_buf);
905  return 0;
906  }
907 
908  if (template_fwrite(o, "BZIP", 4, 1, o->t_file) <= 0)
909  {
910  free(comp_buf);
911  return 0;
912  }
913 
914  write_le48(compressed_size_out, &comp_size_out[0]);
915  if (template_fwrite(o, comp_size_out, sizeof(comp_size_out), 1,
916  o->t_file) <= 0)
917  {
918  free(comp_buf);
919  return 0;
920  }
921 
922  write_le48(size, &uncomp_size_out[0]);
923  if (template_fwrite(o, uncomp_size_out, sizeof(uncomp_size_out), 1,
924  o->t_file) <= 0)
925  {
926  free(comp_buf);
927  return 0;
928  }
929 
930  if (template_fwrite(o, comp_buf, c_stream.total_out_lo32, 1,
931  o->t_file) <= 0)
932  return 0;
933  free(comp_buf);
934  return 1;
935 }
936 
937 #else /* LIBJTE_WITH_LIBBZ2 */
938 
939 /* Compress and flush out a buffer full of template data */
940 static int flush_bz2_chunk(struct libjte_env *o, void *buffer, off_t size)
941 {
942  return 0;
943 }
944 
945 #endif /* ! LIBJTE_WITH_LIBBZ2 */
946 
947 
948 static int flush_compressed_chunk(struct libjte_env *o,
949  void *buffer, off_t size)
950 {
951  int ret;
952 
953  if (size <= 0)
954  return 1;
955 
957  ret = flush_bz2_chunk(o, buffer, size);
958  else
959  ret = flush_gzip_chunk(o, buffer, size);
960  return ret;
961 }
962 
963 /* Append to an existing data buffer, and compress/flush it if
964  necessary */
965 static int write_compressed_chunk(struct libjte_env *o,
966  unsigned char *buffer, size_t size)
967 {
968  int ret;
969 
970  if (o->uncomp_buf == NULL)
971  {
973  o->uncomp_size = 900 * 1024;
974  else
975  o->uncomp_size = 1024 * 1024;
976  o->uncomp_buf = malloc(o->uncomp_size);
977  if (o->uncomp_buf == NULL)
978  {
979  sprintf(o->message_buffer,
980  "failed to allocate %lu bytes for template compression buffer",
981  (unsigned long) o->uncomp_size);
983  exit_if_enabled(o, 1);
984  return -1;
985  }
986  }
987 
988  if ((o->uncomp_buf_used + size) > o->uncomp_size)
989  {
991  if (ret <= 0)
992  return ret;
993  o->uncomp_buf_used = 0;
994  }
995 
996  if (!size) /* Signal a flush before we start writing the DESC entry */
997  {
999  if (ret <= 0)
1000  return ret;
1001  return 1;
1002  }
1003 
1004  if (!o->uncomp_buf_used)
1005  memset(o->uncomp_buf, 0, o->uncomp_size);
1006 
1007  while (size > o->uncomp_size)
1008  {
1010  if (ret <= 0)
1011  return ret;
1012  buffer += o->uncomp_size;
1013  size -= o->uncomp_size;
1014  }
1015  memcpy(&(o->uncomp_buf[o->uncomp_buf_used]), buffer, size);
1016  o->uncomp_buf_used += size;
1017  return 1;
1018 }
1019 
1020 /* Loop through the list of DESC entries that we've built up and
1021  append them to the template file */
1022 static int write_template_desc_entries(struct libjte_env *o, off_t image_len)
1023 {
1024  entry_t *entry = o->entry_list;
1025  off_t desc_len = 0;
1026  unsigned char out_len[6];
1027  int ret;
1028 
1030  {
1031  desc_len = 16 /* DESC + length twice */
1032  + (sizeof(jigdo_file_entry_md5_t) * o->num_matches)
1033  + (sizeof(jigdo_chunk_entry_t) * o->num_chunks)
1034  + sizeof(jigdo_image_entry_md5_t);
1035  }
1036  else /* CHECK_SHA256 */
1037  {
1038  desc_len = 16 /* DESC + length twice */
1039  + (sizeof(jigdo_file_entry_sha256_t) * o->num_matches)
1040  + (sizeof(jigdo_chunk_entry_t) * o->num_chunks)
1041  + sizeof(jigdo_image_entry_sha256_t);
1042  }
1043 
1044  write_le48(desc_len, &out_len[0]);
1045  ret = write_compressed_chunk(o, NULL, 0);
1046  if (ret <= 0)
1047  return ret;
1048  if (template_fwrite(o, "DESC", 4, 1, o->t_file) <= 0)
1049  return 0;
1050  if (template_fwrite(o, out_len, sizeof(out_len), 1, o->t_file) <= 0)
1051  return 0;
1052 
1053  while (entry)
1054  {
1055  switch (entry->entry_type)
1056  {
1057  case JTET_FILE_MATCH:
1058  {
1060  {
1061  jigdo_file_entry_md5_t jfile;
1062  jfile.type = JDT_MATCHED_FILE_MD5;
1063  write_le48(entry->data.file.file_length, &jfile.fileLen[0]);
1064  write_le64(entry->data.file.rsyncsum, &jfile.fileRsync[0]);
1065  memcpy(jfile.fileMD5, entry->data.file.checksum, sizeof(jfile.fileMD5));
1066  if (template_fwrite(o, &jfile, sizeof(jfile), 1,
1067  o->t_file) <= 0)
1068  return 0;
1069  }
1070  else /* CHECK_SHA256 */
1071  {
1073  jfile.type = JDT_MATCHED_FILE_SHA256;
1074  write_le48(entry->data.file.file_length, &jfile.fileLen[0]);
1075  write_le64(entry->data.file.rsyncsum, &jfile.fileRsync[0]);
1076  memcpy(jfile.fileSHA256, entry->data.file.checksum, sizeof(jfile.fileSHA256));
1077  if (template_fwrite(o, &jfile, sizeof(jfile), 1,
1078  o->t_file) <= 0)
1079  return 0;
1080  }
1081  break;
1082  }
1083  case JTET_NOMATCH:
1084  {
1085  jigdo_chunk_entry_t jchunk;
1086  jchunk.type = JDT_UNMATCHED_DATA;
1087  write_le48(entry->data.chunk.uncompressed_length, &jchunk.skipLen[0]);
1088  if (template_fwrite(o, &jchunk, sizeof(jchunk), 1,
1089  o->t_file) <= 0)
1090  return 0;
1091  break;
1092  }
1093  }
1094  entry = entry->next;
1095  }
1096 
1098  {
1099  jigdo_image_entry_md5_t jimage;
1100  jimage.type = JDT_IMAGE_INFO_MD5;
1101  write_le48(image_len, &jimage.imageLen[0]);
1102  checksum_copy(o->iso_context, CHECK_MD5, &jimage.imageMD5[0]);
1104  if (template_fwrite(o, &jimage, sizeof(jimage), 1, o->t_file) <= 0)
1105  return 0;
1106  }
1107  else /* CHECK_SHA256 */
1108  {
1110  jimage.type = JDT_IMAGE_INFO_SHA256;
1111  write_le48(image_len, &jimage.imageLen[0]);
1114  if (template_fwrite(o, &jimage, sizeof(jimage), 1, o->t_file) <= 0)
1115  return 0;
1116  }
1117 
1118  if(template_fwrite(o, out_len, sizeof(out_len), 1, o->t_file) <= 0)
1119  return 0;
1120  return 1;
1121 }
1122 
1123 /* Dump a buffer in jigdo-style "base64" */
1124 static char *base64_dump(struct libjte_env *o,
1125  unsigned char *buf, size_t buf_size)
1126 {
1127  const char *b64_enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
1128  int value = 0;
1129  unsigned int i;
1130  int bits = 0;
1131  char *output_buffer = NULL;
1132  int output_buffer_size;
1133  char *p = NULL;
1134 
1135  output_buffer_size = buf_size * 8 / 6 + 1 + 1; /* round up , care for 0 */
1136  p = output_buffer = calloc(1, output_buffer_size);
1137  if (output_buffer == NULL)
1138  {
1139  sprintf(o->message_buffer,
1140  "base64_dump: Out of memory for buffer size %d",
1141  output_buffer_size);
1143  exit_if_enabled(o, 1);
1144  return NULL;
1145  }
1146  memset(output_buffer, 0, output_buffer_size);
1147 
1148  for (i = 0; i < buf_size ; i++)
1149  {
1150  value = (value << 8) | buf[i];
1151  bits += 2;
1152  p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]);
1153  if (bits >= 6) {
1154  bits -= 6;
1155  p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]);
1156  }
1157  }
1158  if (bits > 0)
1159  {
1160  value <<= 6 - bits;
1161  p += sprintf(p, "%c", b64_enc[value & 63U]);
1162  }
1163  return output_buffer;
1164 }
1165 
1166 
1167 static char *uint64_to_dec(uint64_t num, char dec[40])
1168 {
1169  int i, l = 0, tr;
1170 
1171  dec[0] = 0;
1172  while (num > 0 && l < 39) {
1173  dec[l++] = '0' + num % 10;
1174  num /= 10;
1175  }
1176  dec[l] = 0;
1177 
1178  /* Revert sequence of digits to Big Endian Decimal */
1179  for (i = 0;i < l / 2; i++) {
1180  tr = dec[i];
1181  dec[i] = dec[l - i - 1];
1182  dec[l - i - 1] = tr;
1183  }
1184  return dec;
1185 }
1186 
1187 
1188 /* Write the .jigdo file to match the .template we've just finished. */
1189 static int write_jigdo_file(struct libjte_env *o)
1190 {
1191  unsigned char *template_checksum;
1192  entry_t *entry = o->entry_list;
1193  int i = 0;
1194  struct checksum_info *info = NULL;
1195  FILE *j_file = o->j_file;
1196  char *b64, dec[40];
1197 
1198  template_checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
1199  if (!template_checksum)
1200  {
1201  sprintf(o->message_buffer,
1202  "write_jigdo_file: Out of memory for buffer size %d",
1205  exit_if_enabled(o, 1);
1206  return -1;
1207  }
1208 
1210  checksum_copy(o->template_context, check_algos[o->checksum_algo].type, &template_checksum[0]);
1211 
1212  fprintf(j_file, "# JigsawDownload\n");
1213  fprintf(j_file, "# See <https://www.einval.com/~steve/software/jigdo/> for details about jigdo\n");
1214  fprintf(j_file, "# See <https://www.einval.com/~steve/software/JTE/> for details about JTE\n\n");
1215 
1216  fprintf(j_file, "[Jigdo]\n");
1218  fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION_MD5);
1219  else /* CHECK_SHA256 */
1220  fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION_SHA256);
1221  fprintf(j_file, "Generator=libjte-%d.%d.%d\n\n",
1223 
1224  fprintf(j_file, "[Image]\n");
1225  fprintf(j_file, "Filename=%s\n", file_base_name(o->outfile));
1226  fprintf(j_file, "Template=http://localhost/%s\n", o->jtemplate_out);
1227 
1228  b64 = base64_dump(o, &template_checksum[0], check_algos[o->checksum_algo].raw_bytes);
1229  if (b64 == NULL)
1230  return -1;
1231 
1233  fprintf(j_file, "Template-MD5Sum=%s \n", b64);
1234  else /* CHECK_SHA256 */
1235  fprintf(j_file, "Template-SHA256Sum=%s \n", b64);
1236  free(b64);
1237 
1238  for (i = 0; i < NUM_CHECKSUMS; i++)
1239  {
1240  if (o->checksum_algo_tmpl & (1 << i))
1241  {
1242  info = checksum_information(i);
1243  fprintf(j_file, "# Template Hex %sSum %s\n", info->name,
1245  }
1246  }
1247  fprintf(j_file, "# Template size %s bytes\n",
1248  uint64_to_dec(o->template_size, dec));
1249 
1250  for (i = 0; i < NUM_CHECKSUMS; i++)
1251  {
1252  if (o->checksum_algo_iso & (1 << i))
1253  {
1254  info = checksum_information(i);
1255  fprintf(j_file, "# Image Hex %sSum %s\n",
1256  info->name, checksum_hex(o->iso_context, i));
1257  }
1258  }
1259 
1260  fprintf(j_file, "# Image size %s bytes\n\n",
1261  uint64_to_dec(o->image_size, dec));
1262 
1263  fprintf(j_file, "[Parts]\n");
1264  while (entry)
1265  {
1266  if (JTET_FILE_MATCH == entry->entry_type)
1267  {
1268  char *new_name = remap_filename(o, entry->data.file.filename);
1269 
1270  if (new_name == NULL)
1271  return -1;
1273  if (b64 == NULL)
1274  return -1;
1275  fprintf(j_file, "%s=%s\n", b64, new_name);
1276  free(b64);
1277  free(new_name);
1278  }
1279  entry = entry->next;
1280  }
1281 
1282  fprintf(j_file, "\n[Servers]\n");
1283  fflush(j_file);
1284  return 1;
1285 }
1286 
1287 /* Finish and flush state; for now:
1288 
1289  1. Dump the DESC blocks and the footer information in the jigdo template file
1290  2. Write the jigdo .jigdo file containing file pointers
1291 */
1293 {
1294  int ret;
1295 
1296  /* Finish calculating the image's checksum */
1298 
1300  if (ret <= 0)
1301  return ret;
1302 
1303  ret = write_jigdo_file(o);
1304  return ret;
1305 }
1306 
1307 /* Add a raw data entry to the list of extents; no file to match */
1308 static void add_unmatched_entry(struct libjte_env *o, int uncompressed_length)
1309 {
1310  entry_t *new_entry = NULL;
1311 
1312  /* Can we extend a previous non-match entry? */
1313  if (o->entry_last && (JTET_NOMATCH == o->entry_last->entry_type))
1314  {
1315  o->entry_last->data.chunk.uncompressed_length += uncompressed_length;
1316  return;
1317  }
1318 
1319  new_entry = calloc(1, sizeof(entry_t));
1320  new_entry->entry_type = JTET_NOMATCH;
1321  new_entry->next = NULL;
1322  new_entry->data.chunk.uncompressed_length = uncompressed_length;
1323 
1324  /* Add to the end of the list */
1325  if (NULL == o->entry_last)
1326  {
1327  o->entry_last = new_entry;
1328  o->entry_list = new_entry;
1329  }
1330  else
1331  {
1332  o->entry_last->next = new_entry;
1333  o->entry_last = new_entry;
1334  }
1335  o->num_chunks++;
1336 }
1337 
1338 /* Add a file match entry to the list of extents */
1339 static void add_file_entry(struct libjte_env *o,
1340  char *filename, off_t size, unsigned char *checksum,
1341  uint64_t rsyncsum)
1342 {
1343  entry_t *new_entry = NULL;
1344 
1345  new_entry = calloc(1, sizeof(entry_t));
1346  new_entry->entry_type = JTET_FILE_MATCH;
1347  new_entry->next = NULL;
1348  new_entry->data.file.checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
1349  memcpy(new_entry->data.file.checksum, checksum, check_algos[o->checksum_algo].raw_bytes);
1350  new_entry->data.file.file_length = size;
1351  new_entry->data.file.rsyncsum = rsyncsum;
1352  new_entry->data.file.filename = strdup(filename);
1353 
1354  /* Add to the end of the list */
1355  if (NULL == o->entry_last)
1356  {
1357  o->entry_last = new_entry;
1358  o->entry_list = new_entry;
1359  }
1360  else
1361  {
1362  o->entry_last->next = new_entry;
1363  o->entry_last = new_entry;
1364  }
1365  o->num_matches++;
1366 }
1367 
1368 /* Cope with an unmatched block in the .iso file:
1369 
1370  1. Write a compressed data chunk in the jigdo template file
1371  2. Add an entry in our list of unmatched chunks for later */
1372 int jtwrite(struct libjte_env *o, void *buffer, int size, int count)
1373 {
1374  int ret;
1375 
1376  if (o->jtemplate_out == NULL)
1377  return 0;
1378 
1379  /* Update the global image checksum */
1380  checksum_update(o->iso_context, buffer, size * count);
1381 
1382  /* Write a compressed version of the data to the template file,
1383  and add a reference on the state list so we can write that
1384  later. */
1385  ret = write_compressed_chunk(o, buffer, size*count);
1386  if (ret <= 0)
1387  return ret;
1388  add_unmatched_entry(o, size*count);
1389  return 1;
1390 }
1391 
1392 /* Cope with a file entry in the .iso file:
1393 
1394  1. Read the file for the image's checksum
1395  2. Add an entry in our list of files to be written into the .jigdo later
1396 */
1398  char *filename, char *mirror_name, int sector_size,
1399  off_t size, unsigned char *checksum)
1400 {
1401  char buf[32768];
1402  off_t remain = size;
1403  FILE *infile = NULL;
1404  int use = 0;
1405  uint64_t rsync64_sum = 0;
1406  int first_block = 1;
1407 
1408  memset(buf, 0, sizeof(buf));
1409 
1410  if ((infile = fopen(filename, "rb")) == NULL) {
1411 #ifndef HAVE_STRERROR
1412  sprintf(o->message_buffer, "cannot open '%s': (%d)",
1413  filename, errno);
1414 #else
1415  sprintf(o->message_buffer, "cannot open '%s': %s",
1416  filename, strerror(errno));
1417 #endif
1419  exit_if_enabled(o, 1);
1420  return -1;
1421  }
1422 
1423  while (remain > 0)
1424  {
1425  use = remain;
1426  if (remain > (off_t)sizeof(buf))
1427  use = sizeof(buf);
1428  if (fread(buf, 1, use, infile) == 0)
1429  {
1430  sprintf(o->message_buffer,
1431  "cannot read from '%s'", filename);
1433  exit_if_enabled(o, 1);
1434  return -1;
1435  }
1436  if (first_block)
1437  rsync64_sum = rsync64((unsigned char *) buf, MIN_JIGDO_FILE_SIZE);
1438  checksum_update(o->iso_context, (unsigned char *) buf, use);
1439  remain -= use;
1440  first_block = 0;
1441  }
1442 
1443  fclose(infile);
1444 
1445  /* Update the image checksum with any necessary padding data */
1446  if (size % sector_size)
1447  {
1448  int pad_size = sector_size - (size % sector_size);
1449  memset(buf, 0, pad_size);
1450  checksum_update(o->iso_context, (unsigned char *) buf, pad_size);
1451  }
1452 
1453  add_file_entry(o, mirror_name, size, &checksum[0], rsync64_sum);
1454  if (size % sector_size)
1455  {
1456  int pad_size = sector_size - (size % sector_size);
1457  write_compressed_chunk(o, (unsigned char *) buf, pad_size);
1458  add_unmatched_entry(o, pad_size);
1459  }
1460  return 1;
1461 }
1462 
1463 int libjte_add_msg_entry(struct libjte_env *o, char *message, int flag)
1464 {
1465  jigdo_msg_entry_t *new_entry = NULL, *s = NULL;
1466  int list_length = 0;
1467 
1468  if (o->error_behavior & 1) {
1469  fprintf(stderr, "libjte: %s\n", message);
1470  return 1;
1471  }
1472  if (o->msg_list != NULL) {
1473  /* Find end of list and eventually do an emergency message dump */
1474  for (s = o->msg_list; s->next != NULL; s = s->next)
1475  list_length++;
1476  if (list_length >= JTE_MAX_ERROR_LIST_LENGTH) {
1477  libjte_clear_msg_list(o, 1 | 2); /* dump to stderr */
1478  o->msg_list = s = NULL;
1479  }
1480  }
1481 
1482  new_entry = calloc(1, sizeof(jigdo_msg_entry_t));
1483  if (new_entry == NULL) {
1484 no_mem:;
1485  fprintf(stderr, "libjte: %s\n", message);
1486  fprintf(stderr, "libjte: OUT OF MEMORY\n");
1487  return -1;
1488  }
1489  new_entry->next = NULL;
1490  new_entry->message = strdup(message);
1491  if (new_entry->message == NULL) {
1492  free(new_entry);
1493  goto no_mem;
1494  }
1495  if (o->msg_list == NULL)
1496  o->msg_list = new_entry;
1497  else
1498  s->next = new_entry;
1499  return 1;
1500 }
1501 
int checksum_calculate(char *filename, int64_t size, unsigned char *out, enum checksum_types which)
Definition: checksum.c:528
checksum_context_t * checksum_init_context(int checksums, const char *owner)
Definition: checksum.c:236
const char * checksum_hex(checksum_context_t *context, enum checksum_types which)
Definition: checksum.c:460
void checksum_update(checksum_context_t *context, unsigned char const *buf, unsigned int len)
Definition: checksum.c:383
void checksum_copy(checksum_context_t *context, enum checksum_types which, unsigned char *digest)
Definition: checksum.c:440
void checksum_final(checksum_context_t *context)
Definition: checksum.c:401
int checksum_parse_hex(char *in, unsigned char *out, int size)
Definition: checksum.c:576
void checksum_free_context(checksum_context_t *context)
Definition: checksum.c:318
struct checksum_info * checksum_information(enum checksum_types which)
Definition: checksum.c:180
@ NUM_CHECKSUMS
Definition: checksum.h:22
@ CHECK_MD5
Definition: checksum.h:18
@ CHECK_SHA256
Definition: checksum.h:20
void write_le32(unsigned long in, unsigned char *out)
Definition: endian.c:134
void write_le48(uint64_t in, unsigned char *out)
Definition: endian.c:86
void write_le64(uint64_t in, unsigned char *out)
Definition: endian.c:56
int libjte_add_msg_entry(struct libjte_env *o, char *message, int flag)
Definition: jte.c:1463
int write_jt_match_record(struct libjte_env *o, char *filename, char *mirror_name, int sector_size, off_t size, unsigned char *checksum)
Definition: jte.c:1397
static int write_jigdo_file(struct libjte_env *o)
Definition: jte.c:1189
int libjte_destroy_checksum_list(struct libjte_env *o, int flag)
Definition: jte.c:566
static char * uint64_to_dec(uint64_t num, char dec[40])
Definition: jte.c:1167
int libjte_destroy_path_match_list(struct libjte_env *o, int flag)
Definition: jte.c:150
int list_file_in_jigdo(struct libjte_env *o, char *filename, off_t size, char **realname, unsigned char *checksum)
Definition: jte.c:266
int jte_add_include(struct libjte_env *o, char *pattern)
Definition: jte.c:202
static int jte_add_path_match(struct libjte_env *o, char *pattern, int flag)
Definition: jte.c:119
#define JTE_COMMENT
Definition: jte.c:62
static int parse_checksum_list(struct libjte_env *o)
Definition: jte.c:606
static int write_template_desc_entries(struct libjte_env *o, off_t image_len)
Definition: jte.c:1022
int write_jt_header(struct libjte_env *o, FILE *template_file, FILE *jigdo_file)
Definition: jte.c:736
#define JIGDO_TEMPLATE_VERSION_MD5
Definition: jte.c:64
#define JTET_FILE_MATCH
Definition: jte.c:56
#define JTET_NOMATCH
Definition: jte.c:57
int jte_add_mapping(struct libjte_env *o, char *arg)
Definition: jte.c:349
static char * remap_filename(struct libjte_env *o, char *filename)
Definition: jte.c:431
static int flush_compressed_chunk(struct libjte_env *o, void *buffer, off_t size)
Definition: jte.c:948
int jtwrite(struct libjte_env *o, void *buffer, int size, int count)
Definition: jte.c:1372
int jte_add_exclude(struct libjte_env *o, char *pattern)
Definition: jte.c:171
static int write_template_header(struct libjte_env *o)
Definition: jte.c:474
static int write_compressed_chunk(struct libjte_env *o, unsigned char *buffer, size_t size)
Definition: jte.c:965
static void add_file_entry(struct libjte_env *o, char *filename, off_t size, unsigned char *checksum, uint64_t rsyncsum)
Definition: jte.c:1339
static void add_unmatched_entry(struct libjte_env *o, int uncompressed_length)
Definition: jte.c:1308
#define JTE_MAX_ERROR_LIST_LENGTH
Definition: jte.c:67
int libjte_destroy_path_mapping(struct libjte_env *o, int flag)
Definition: jte.c:414
static int check_checksum_file_match(struct libjte_env *o, char *filename)
Definition: jte.c:230
static int check_exclude_by_name(struct libjte_env *o, char *filename, char **matched)
Definition: jte.c:181
int libjte_destroy_entry_list(struct libjte_env *o, int flag)
Definition: jte.c:210
static char * file_base_name(char *path)
Definition: jte.c:84
static char * base64_dump(struct libjte_env *o, unsigned char *buf, size_t buf_size)
Definition: jte.c:1124
static void exit_if_enabled(struct libjte_env *o, int value)
Definition: jte.c:99
static int template_fwrite(struct libjte_env *o, const void *ptr, size_t size, size_t nmemb, FILE *stream)
Definition: jte.c:460
#define JIGDO_TEMPLATE_VERSION_SHA256
Definition: jte.c:65
int write_jt_footer(struct libjte_env *o)
Definition: jte.c:1292
static int flush_bz2_chunk(struct libjte_env *o, void *buffer, off_t size)
Definition: jte.c:940
int libjte_report_no_mem(struct libjte_env *o, size_t size, int flag)
Definition: jte.c:107
_jigdo_desc_type
Definition: jte.c:70
@ JDT_OBSOLETE_WRITTEN_FILE
Definition: jte.c:74
@ JDT_OBSOLETE_IMAGE_INFO
Definition: jte.c:71
@ JDT_OBSOLETE_MATCHED_FILE
Definition: jte.c:73
@ JDT_WRITTEN_FILE_SHA256
Definition: jte.c:80
@ JDT_MATCHED_FILE_MD5
Definition: jte.c:76
@ JDT_WRITTEN_FILE_MD5
Definition: jte.c:77
@ JDT_UNMATCHED_DATA
Definition: jte.c:72
@ JDT_MATCHED_FILE_SHA256
Definition: jte.c:79
@ JDT_IMAGE_INFO_MD5
Definition: jte.c:75
@ JDT_IMAGE_INFO_SHA256
Definition: jte.c:78
static int add_checksum_entry(struct libjte_env *o, unsigned char *checksum, uint64_t size, char *filename)
Definition: jte.c:527
static int flush_gzip_chunk(struct libjte_env *o, void *buffer, off_t size)
Definition: jte.c:772
static uint64_t parse_number(unsigned char in[12])
Definition: jte.c:581
struct _jigdo_image_entry_sha256 jigdo_image_entry_sha256_t
#define MIN_JIGDO_FILE_SIZE
Definition: jte.h:105
struct _jigdo_chunk_entry jigdo_chunk_entry_t
static const struct _checksum_data check_algos[]
Definition: jte.h:80
@ JTE_TEMP_BZIP2
Definition: jte.h:53
struct _jigdo_file_entry_sha256 jigdo_file_entry_sha256_t
struct _jigdo_image_entry_md5 jigdo_image_entry_md5_t
struct _jigdo_file_entry_md5 jigdo_file_entry_md5_t
int libjte_clear_msg_list(struct libjte_env *o, int flag)
Definition: libjte.c:595
#define LIBJTE_VERSION_MICRO
Definition: libjte.h:31
#define LIBJTE_VERSION_MAJOR
Definition: libjte.h:29
#define LIBJTE_VERSION_MINOR
Definition: libjte.h:30
uint64_t rsync64(unsigned char *mem, size_t size)
Definition: rsync.c:105
int hex_bytes
Definition: jte.h:62
enum checksum_types type
Definition: jte.h:58
int raw_bytes
Definition: jte.h:60
Definition: jte.h:192
uint64_t size
Definition: jte.h:195
char * filename
Definition: jte.h:196
unsigned char * checksum
Definition: jte.h:194
struct _checksum_list_entry * next
Definition: jte.h:193
Definition: jte.h:143
int entry_type
Definition: jte.h:144
file_entry_t file
Definition: jte.h:148
struct _entry * next
Definition: jte.h:145
union _entry::@7 data
unmatched_entry_t chunk
Definition: jte.h:149
unsigned char * checksum
Definition: jte.h:131
off_t file_length
Definition: jte.h:132
char * filename
Definition: jte.h:134
uint64_t rsyncsum
Definition: jte.h:133
Definition: jte.h:170
unsigned char type
Definition: jte.h:171
unsigned char skipLen[6]
Definition: jte.h:172
Definition: jte.h:154
unsigned char fileMD5[(128/8)]
Definition: jte.h:158
unsigned char fileLen[6]
Definition: jte.h:156
unsigned char fileRsync[8]
Definition: jte.h:157
unsigned char type
Definition: jte.h:155
Definition: jte.h:162
unsigned char fileSHA256[(256/8)]
Definition: jte.h:166
unsigned char fileLen[6]
Definition: jte.h:164
unsigned char fileRsync[8]
Definition: jte.h:165
unsigned char type
Definition: jte.h:163
Definition: jte.h:176
unsigned char blockLen[4]
Definition: jte.h:180
unsigned char imageMD5[(128/8)]
Definition: jte.h:179
unsigned char imageLen[6]
Definition: jte.h:178
unsigned char type
Definition: jte.h:177
Definition: jte.h:184
unsigned char imageLen[6]
Definition: jte.h:186
unsigned char imageSHA256[(256/8)]
Definition: jte.h:187
unsigned char type
Definition: jte.h:185
unsigned char blockLen[4]
Definition: jte.h:188
Definition: jte.h:201
struct _jigdo_msg_entry * next
Definition: jte.h:202
char * message
Definition: jte.h:203
off_t uncompressed_length
Definition: jte.h:139
char * name
Definition: checksum.h:35
int error_behavior
size_t uncomp_size
char * outfile
size_t uncomp_buf_used
checksum_context_t * iso_context
uint64_t template_size
checksum_context_t * template_context
struct path_match * exclude_list
int checksum_algo_iso
jtc_t jte_template_compression
jigdo_msg_entry_t * msg_list
struct path_match * include_list
checksum_list_entry_t * checksum_last
checksum_list_entry_t * checksum_list
char message_buffer[4096]
char * jtemplate_out
struct path_mapping * map_list
int checksum_algo_tmpl
entry_t * entry_last
char * jchecksum_list
entry_t * entry_list
FILE * t_file
unsigned char * uncomp_buf
uint64_t image_size
FILE * j_file
char * to
Definition: jte.h:123
char * from
Definition: jte.h:122
struct path_mapping * next
Definition: jte.h:124
char * match_rule
Definition: jte.h:115
struct path_match * next
Definition: jte.h:116
regex_t match_pattern
Definition: jte.h:114