4 * Copyright (c) 2004-2006 Steve McIntyre <steve@einval.com>
6 * Implementation of the Jigdo Template Engine - make jigdo files
7 * directly when making ISO images
13 #include "genisoimage.h"
25 #include "dvd_reader.h"
28 #include "endianconv.h"
39 /* Different types used in building our state list below */
40 #define JTET_FILE_MATCH 1
41 #define JTET_NOMATCH 2
43 #define JTE_VER_MAJOR 0x0001
44 #define JTE_VER_MINOR 0x0013
45 #define JTE_NAME "JTE"
46 #define JTE_COMMENT "JTE at http://www.einval.com/~steve/software/JTE/ ; jigdo at http://atterer.org/jigdo/"
48 #define JIGDO_TEMPLATE_VERSION "1.1"
51 Simple list to hold the results of -jigdo-exclude and
52 -jigdo-force-match command line options. Seems easiest to do this
57 regex_t match_pattern;
59 struct path_match *next;
62 /* List of mappings e.g. Debian=/mirror/debian */
67 struct path_mapping *next;
70 FILE *jtjigdo = NULL; /* File handle used throughout for the jigdo file */
71 FILE *jttemplate = NULL; /* File handle used throughout for the template file */
72 char *jjigdo_out = NULL; /* Output name for jigdo .jigdo file; NULL means don't do it */
73 char *jtemplate_out = NULL; /* Output name for jigdo template file; NULL means don't do it */
74 char *jmd5_list = NULL; /* Name of file to use for MD5 checking */
75 int jte_min_size = MIN_JIGDO_FILE_SIZE;
76 jtc_t jte_template_compression = JTE_TEMP_GZIP;
77 struct path_match *exclude_list = NULL;
78 struct path_match *include_list = NULL;
79 struct path_mapping *map_list = NULL;
80 unsigned long long template_size = 0;
81 unsigned long long image_size = 0;
82 int checksum_algo_iso = (CHECK_MD5_USED | \
86 int checksum_algo_tmpl = CHECK_MD5_USED;
88 static checksum_context_t *iso_context = NULL;
89 static checksum_context_t *template_context = NULL;
91 /* List of files that we've seen, ready to write into the template and
93 typedef struct _file_entry
95 unsigned char md5[16];
97 unsigned long long rsyncsum;
101 typedef struct _unmatched_entry
103 off_t uncompressed_length;
106 typedef struct _entry
108 int entry_type; /* JTET_TYPE as above */
113 unmatched_entry_t chunk;
117 typedef struct _jigdo_file_entry
120 unsigned char fileLen[6];
121 unsigned char fileRsync[8];
122 unsigned char fileMD5[16];
123 } jigdo_file_entry_t;
125 typedef struct _jigdo_chunk_entry
128 unsigned char skipLen[6];
129 } jigdo_chunk_entry_t;
131 typedef struct _jigdo_image_entry
134 unsigned char imageLen[6];
135 unsigned char imageMD5[16];
136 unsigned char blockLen[4];
137 } jigdo_image_entry_t;
139 typedef struct _md5_list_entry
141 struct _md5_list_entry *next;
142 unsigned char MD5[16];
143 unsigned long long size;
147 entry_t *entry_list = NULL;
148 entry_t *entry_last = NULL;
153 md5_list_entry_t *md5_list = NULL;
154 md5_list_entry_t *md5_last = NULL;
156 /* Grab the file component from a full path */
157 static char *file_base_name(char *path)
172 /* Build the list of exclusion regexps */
173 extern int jte_add_exclude(char *pattern)
175 struct path_match *new = NULL;
177 new = malloc(sizeof *new);
181 regcomp(&new->match_pattern, pattern, REG_NEWLINE);
182 new->match_rule = pattern;
184 /* Order on the exclude list doesn't matter! */
185 new->next = exclude_list;
191 /* Check if the file should be excluded because of a filename match. 1
192 means exclude, 0 means not */
193 static int check_exclude_by_name(char *filename, char **matched)
195 struct path_match *ptr = exclude_list;
196 regmatch_t pmatch[1];
201 if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0))
203 *matched = ptr->match_rule;
209 /* Not matched, so return 0 */
213 /* Build the list of required inclusion regexps */
214 extern int jte_add_include(char *pattern)
216 struct path_match *new = NULL;
218 new = malloc(sizeof *new);
222 regcomp(&new->match_pattern, pattern, REG_NEWLINE);
223 new->match_rule = pattern;
225 /* Order on the include list doesn't matter! */
226 new->next = include_list;
232 /* Check if a file has to be MD5-matched to be valid. If we get called
233 here, we've failed to match any of the MD5 entries we were
234 given. If the path to the filename matches one of the paths in our
235 list, clearly it must have been corrupted. Abort with an error. */
236 static void check_md5_file_match(char *filename)
238 struct path_match *ptr = include_list;
239 regmatch_t pmatch[1];
244 if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0))
247 comerr("File %s should have matched an MD5 entry, but didn't! (Rule '%s')\n", filename, ptr->match_rule);
249 fprintf(stderr, "File %s should have matched an MD5 entry, but didn't! (Rule '%s')\n", filename, ptr->match_rule);
257 /* Should we list a file separately in the jigdo output, or should we
258 just dump it into the template file as binary data? Three things
259 cases to look for here:
261 1. Small files are better simply folded in, as they take less space that way.
263 2. Files in /doc (for example) may change in the archive all the
264 time and it's better to not have to fetch snapshot copies if we
267 3. Files living in specified paths *must* match an entry in the
268 md5-list, or they must have been corrupted. If we find a corrupt
269 file, bail out with an error.
272 extern int list_file_in_jigdo(char *filename, off_t size, char **realname, unsigned char md5[16])
275 md5_list_entry_t *entry = md5_list;
281 memset(md5, 0, sizeof(md5));
283 /* Cheaper to check file size first */
284 if (size < jte_min_size)
287 fprintf(stderr, "Jigdo-ignoring file %s; it's too small\n", filename);
291 /* Now check the excluded list by name */
292 if (check_exclude_by_name(filename, &matched_rule))
295 fprintf(stderr, "Jigdo-ignoring file %s; it's covered in the exclude list by \"%s\"\n", filename, matched_rule);
299 /* Check to see if the file is in our md5 list. Check three things:
303 3. (only if the first 2 match) the md5sum
305 If we get a match for all three, include the file and return
306 the full path to the file that we have gleaned from the mirror.
311 if (size == entry->size)
313 if (!strcmp(file_base_name(filename), file_base_name(entry->filename)))
317 calculate_md5sum(filename, size, md5);
320 if (!memcmp(md5, entry->MD5, sizeof(entry->MD5)))
322 *realname = entry->filename;
330 /* We haven't found an entry in our MD5 list to match this
331 * file. If we should have done, complain and bail out. */
332 check_md5_file_match(filename);
336 /* Add a mapping of pathnames (e.g. Debian=/mirror/debian). We should
337 be passed TO=FROM here */
338 extern int jte_add_mapping(char *arg)
341 struct path_mapping *new = NULL;
342 struct path_mapping *entry = NULL;
347 /* Find the "=" in the string passed. Set it to NULL and we can
348 use the string in-place */
360 if (!from || !strlen(from) || !to || !strlen(to))
363 new = malloc(sizeof(*new));
372 fprintf(stderr, "Adding mapping from %s to %s for the jigdo file\n", from, to);
377 /* Order is important; add to the end of the list */
379 while (NULL != entry->next)
386 /* Check if the filename should be remapped; if so map it, otherwise
387 return the original name. */
388 static char *remap_filename(char *filename)
390 char *new_name = filename;
391 struct path_mapping *entry = map_list;
395 if (!strncmp(filename, entry->from, strlen(entry->from)))
397 new_name = calloc(1, 2 + strlen(filename) + strlen(entry->to) - strlen(entry->from));
400 fprintf(stderr, "Failed to malloc new filename; abort!\n");
403 sprintf(new_name, "%s:%s", entry->to, &filename[strlen(entry->from)]);
409 /* No mapping in effect */
410 return strdup(filename);
413 /* Write data to the template file and update the MD5 sum */
414 static size_t template_fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
416 checksum_update(template_context, ptr, size * nmemb);
417 template_size += (unsigned long long)size * nmemb;
418 return fwrite(ptr, size, nmemb, stream);
421 /* Create a new template file and initialise it */
422 static void write_template_header()
428 memset(buf, 0, sizeof(buf));
430 template_context = checksum_init_context(checksum_algo_tmpl, "template");
431 if (!template_context)
434 comerr("cannot allocate template checksum contexts\n");
436 fprintf(stderr, "cannot allocate template checksum contexts\n");
441 i += sprintf(p, "JigsawDownload template %s %s/%d.%d \r\n",
442 JIGDO_TEMPLATE_VERSION, JTE_NAME, JTE_VER_MAJOR, JTE_VER_MINOR);
445 i += sprintf(p, "%s \r\n", JTE_COMMENT);
448 i += sprintf(p, "\r\n");
449 template_fwrite(buf, i, 1, t_file);
452 /* Read the MD5 list and build a list in memory for us to use later */
453 static void add_md5_entry(unsigned char *md5, unsigned long long size, char *filename)
456 md5_list_entry_t *new = NULL;
458 new = calloc(1, sizeof(md5_list_entry_t));
459 memcpy(new->MD5, md5, sizeof(new->MD5));
461 new->filename = strdup(filename);
463 /* Add to the end of the list */
464 if (NULL == md5_last)
471 md5_last->next = new;
476 /* Parse a 12-digit decimal number */
477 static unsigned long long parse_number(unsigned char in[12])
479 unsigned long long size = 0;
482 for (i = 0; i < 12; i++)
486 size += (in[i] - '0');
492 /* Read the MD5 list and build a list in memory for us to use later
495 <---MD5---> <--Size--> <--Filename-->
498 static void parse_md5_list(void)
500 FILE *md5_file = NULL;
501 unsigned char buf[1024];
502 unsigned char md5[16];
503 char *filename = NULL;
504 unsigned char *numbuf = NULL;
506 unsigned long long size = 0;
508 md5_file = fopen(jmd5_list, "rb");
512 comerr("cannot read from MD5 list file '%s'\n", jmd5_list);
514 fprintf(stderr, "cannot read from MD5 list file '%s'\n", jmd5_list);
519 memset(buf, 0, sizeof(buf));
520 while (fgets((char *)buf, sizeof(buf), md5_file))
523 filename = (char *)&buf[48];
524 /* Lose the trailing \n from the fgets() call */
525 if (buf[strlen((char *)buf)-1] == '\n')
526 buf[strlen((char *)buf)-1] = 0;
528 if (mk_MD5Parse(buf, md5))
531 comerr("cannot parse MD5 file '%s'\n", jmd5_list);
533 fprintf(stderr, "cannot parse MD5 file '%s'\n", jmd5_list);
537 size = parse_number(numbuf);
538 add_md5_entry(md5, size, filename);
539 memset(buf, 0, sizeof(buf));
543 fprintf(stderr, "parse_md5_list: added MD5 checksums for %d files\n", num_files);
547 /* Initialise state and start the jigdo template file */
548 void write_jt_header(FILE *template_file, FILE *jigdo_file)
550 t_file = template_file;
553 /* Start checksum work for the image */
554 iso_context = checksum_init_context(checksum_algo_iso, "iso");
558 comerr("cannot allocate iso checksum contexts\n");
560 fprintf(stderr, "cannot allocate iso checksum contexts\n");
565 /* Start the template file */
566 write_template_header();
568 /* Load up the MD5 list if we've been given one */
573 /* Compress and flush out a buffer full of template data */
574 static void flush_gzip_chunk(void *buffer, off_t size)
576 z_stream c_stream; /* compression stream */
577 unsigned char comp_size_out[6];
578 unsigned char uncomp_size_out[6];
579 off_t compressed_size_out = 0;
581 unsigned char *comp_buf = NULL;
583 c_stream.zalloc = NULL;
584 c_stream.zfree = NULL;
585 c_stream.opaque = NULL;
587 err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
588 comp_buf = malloc(2 * size); /* Worst case */
589 c_stream.next_out = comp_buf;
590 c_stream.avail_out = 2 * size;
591 c_stream.next_in = buffer;
592 c_stream.avail_in = size;
594 err = deflate(&c_stream, Z_NO_FLUSH);
595 err = deflate(&c_stream, Z_FINISH);
597 compressed_size_out = c_stream.total_out + 16;
598 err = deflateEnd(&c_stream);
600 template_fwrite("DATA", 4, 1, t_file);
602 write_le48(compressed_size_out, &comp_size_out[0]);
603 template_fwrite(comp_size_out, sizeof(comp_size_out), 1, t_file);
605 write_le48(size, &uncomp_size_out[0]);
606 template_fwrite(uncomp_size_out, sizeof(uncomp_size_out), 1, t_file);
608 template_fwrite(comp_buf, c_stream.total_out, 1, t_file);
612 /* Compress and flush out a buffer full of template data */
613 static void flush_bz2_chunk(void *buffer, off_t size)
615 bz_stream c_stream; /* compression stream */
616 unsigned char comp_size_out[6];
617 unsigned char uncomp_size_out[6];
618 off_t compressed_size_out = 0;
620 unsigned char *comp_buf = NULL;
622 c_stream.bzalloc = NULL;
623 c_stream.bzfree = NULL;
624 c_stream.opaque = NULL;
626 err = BZ2_bzCompressInit(&c_stream, 9, 0, 0);
627 comp_buf = malloc(2 * size); /* Worst case */
628 c_stream.next_out = comp_buf;
629 c_stream.avail_out = 2 * size;
630 c_stream.next_in = buffer;
631 c_stream.avail_in = size;
633 err = BZ2_bzCompress(&c_stream, BZ_FINISH);
635 compressed_size_out = c_stream.total_out_lo32 + 16;
636 err = BZ2_bzCompressEnd(&c_stream);
638 template_fwrite("BZIP", 4, 1, t_file);
640 write_le48(compressed_size_out, &comp_size_out[0]);
641 template_fwrite(comp_size_out, sizeof(comp_size_out), 1, t_file);
643 write_le48(size, &uncomp_size_out[0]);
644 template_fwrite(uncomp_size_out, sizeof(uncomp_size_out), 1, t_file);
646 template_fwrite(comp_buf, c_stream.total_out_lo32, 1, t_file);
650 static void flush_compressed_chunk(void *buffer, off_t size)
652 if (jte_template_compression == JTE_TEMP_BZIP2)
653 flush_bz2_chunk(buffer, size);
655 flush_gzip_chunk(buffer, size);
658 /* Append to an existing data buffer, and compress/flush it if
660 static void write_compressed_chunk(unsigned char *buffer, size_t size)
662 static unsigned char *uncomp_buf = NULL;
663 static size_t uncomp_size = 0;
664 static size_t uncomp_buf_used = 0;
668 if (jte_template_compression == JTE_TEMP_BZIP2)
669 uncomp_size = 900 * 1024;
671 uncomp_size = 1024 * 1024;
672 uncomp_buf = malloc(uncomp_size);
676 comerr("failed to allocate %d bytes for template compression buffer\n", uncomp_size);
678 fprintf(stderr, "failed to allocate %d bytes for template compression buffer\n", uncomp_size);
684 if ((uncomp_buf_used + size) > uncomp_size)
686 flush_compressed_chunk(uncomp_buf, uncomp_buf_used);
690 if (!size) /* Signal a flush before we start writing the DESC entry */
692 flush_compressed_chunk(uncomp_buf, uncomp_buf_used);
696 if (!uncomp_buf_used)
697 memset(uncomp_buf, 0, uncomp_size);
699 while (size > uncomp_size)
701 flush_compressed_chunk(buffer, uncomp_size);
702 buffer += uncomp_size;
705 memcpy(&uncomp_buf[uncomp_buf_used], buffer, size);
706 uncomp_buf_used += size;
709 /* Loop through the list of DESC entries that we've built up and
710 append them to the template file */
711 static void write_template_desc_entries(off_t image_len)
713 entry_t *entry = entry_list;
715 unsigned char out_len[6];
716 jigdo_image_entry_t jimage;
718 desc_len = 16 /* DESC + length twice */
719 + (sizeof(jigdo_file_entry_t) * num_matches)
720 + (sizeof(jigdo_chunk_entry_t) * num_chunks)
721 + sizeof(jigdo_image_entry_t);
723 write_le48(desc_len, &out_len[0]);
724 write_compressed_chunk(NULL, 0);
725 template_fwrite("DESC", 4, 1, t_file);
726 template_fwrite(out_len, sizeof(out_len), 1, t_file);
730 switch (entry->entry_type)
732 case JTET_FILE_MATCH:
734 jigdo_file_entry_t jfile;
735 jfile.type = 6; /* Matched file */
736 write_le48(entry->data.file.file_length, &jfile.fileLen[0]);
737 write_le64(entry->data.file.rsyncsum, &jfile.fileRsync[0]);
738 memcpy(jfile.fileMD5, entry->data.file.md5, sizeof(jfile.fileMD5));
739 template_fwrite(&jfile, sizeof(jfile), 1, t_file);
744 jigdo_chunk_entry_t jchunk;
745 jchunk.type = 2; /* Raw data, compressed */
746 write_le48(entry->data.chunk.uncompressed_length, &jchunk.skipLen[0]);
747 template_fwrite(&jchunk, sizeof(jchunk), 1, t_file);
755 write_le48(image_len, &jimage.imageLen[0]);
756 checksum_copy(iso_context, CHECK_MD5, &jimage.imageMD5[0]);
757 write_le32(MIN_JIGDO_FILE_SIZE, &jimage.blockLen[0]);
758 template_fwrite(&jimage, sizeof(jimage), 1, t_file);
759 template_fwrite(out_len, sizeof(out_len), 1, t_file);
762 /* Dump a buffer in jigdo-style "base64" */
763 static char *base64_dump(unsigned char *buf, size_t buf_size)
765 const char *b64_enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
769 static char output_buffer[2048];
770 char *p = output_buffer;
772 memset(output_buffer, 0, sizeof(output_buffer));
773 if (buf_size >= (sizeof(output_buffer) * 6/8))
775 fprintf(stderr, "base64_dump: Buffer too small!\n");
779 for (i = 0; i < buf_size ; i++)
781 value = (value << 8) | buf[i];
783 p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]);
786 p += sprintf(p, "%c", b64_enc[(value >> bits) & 63U]);
792 p += sprintf(p, "%c", b64_enc[value & 63U]);
794 return output_buffer;
797 /* Write the .jigdo file to match the .template we've just finished. */
798 static void write_jigdo_file(void)
800 unsigned char template_md5sum[16];
801 entry_t *entry = entry_list;
802 struct path_mapping *map = map_list;
804 struct checksum_info *info = NULL;
806 checksum_final(template_context);
807 checksum_copy(template_context, CHECK_MD5, &template_md5sum[0]);
809 fprintf(j_file, "# JigsawDownload\n");
810 fprintf(j_file, "# See <http://atterer.org/jigdo/> for details about jigdo\n");
811 fprintf(j_file, "# See <http://www.einval.com/~steve/software/CD/JTE/> for details about JTE\n\n");
813 fprintf(j_file, "[Jigdo]\n");
814 fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION);
815 fprintf(j_file, "Generator=%s/%d.%d\n\n", JTE_NAME, JTE_VER_MAJOR, JTE_VER_MINOR);
817 fprintf(j_file, "[Image]\n");
818 fprintf(j_file, "Filename=%s\n", file_base_name(outfile));
819 fprintf(j_file, "Template=http://localhost/%s\n", jtemplate_out);
821 fprintf(j_file, "Template-MD5Sum=%s \n",
822 base64_dump(&template_md5sum[0], sizeof(template_md5sum)));
824 for (i = 0; i < NUM_CHECKSUMS; i++)
826 if (checksum_algo_tmpl & (1 << i))
828 info = checksum_information(i);
829 fprintf(j_file, "# Template Hex %sSum %s\n", info->name, checksum_hex(template_context, i));
832 fprintf(j_file, "# Template size %lld bytes\n", template_size);
834 for (i = 0; i < NUM_CHECKSUMS; i++)
836 if (checksum_algo_iso & (1 << i))
838 info = checksum_information(i);
839 fprintf(j_file, "# Image Hex %sSum %s\n", info->name, checksum_hex(iso_context, i));
843 fprintf(j_file, "# Image size %lld bytes\n\n", image_size);
845 fprintf(j_file, "[Parts]\n");
848 if (JTET_FILE_MATCH == entry->entry_type)
850 char *new_name = remap_filename(entry->data.file.filename);
851 fprintf(j_file, "%s=%s\n",
852 base64_dump(&entry->data.file.md5[0], sizeof(entry->data.file.md5)),
859 fprintf(j_file, "\n[Servers]\n");
863 /* Finish and flush state; for now:
865 1. Dump the DESC blocks and the footer information in the jigdo template file
866 2. Write the jigdo .jigdo file containing file pointers
868 void write_jt_footer(void)
870 /* Finish calculating the image's checksum */
871 checksum_final(iso_context);
873 /* And calculate the image size */
874 image_size = (unsigned long long)SECTOR_SIZE * last_extent_written;
876 write_template_desc_entries(image_size);
881 /* Add a raw data entry to the list of extents; no file to match */
882 static void add_unmatched_entry(int uncompressed_length)
884 entry_t *new_entry = NULL;
886 /* Can we extend a previous non-match entry? */
887 if (entry_last && (JTET_NOMATCH == entry_last->entry_type))
889 entry_last->data.chunk.uncompressed_length += uncompressed_length;
893 new_entry = calloc(1, sizeof(entry_t));
894 new_entry->entry_type = JTET_NOMATCH;
895 new_entry->next = NULL;
896 new_entry->data.chunk.uncompressed_length = uncompressed_length;
898 /* Add to the end of the list */
899 if (NULL == entry_last)
901 entry_last = new_entry;
902 entry_list = new_entry;
906 entry_last->next = new_entry;
907 entry_last = new_entry;
912 /* Add a file match entry to the list of extents */
913 static void add_file_entry(char *filename, off_t size, unsigned char *md5,
914 unsigned long long rsyncsum)
916 entry_t *new_entry = NULL;
918 new_entry = calloc(1, sizeof(entry_t));
919 new_entry->entry_type = JTET_FILE_MATCH;
920 new_entry->next = NULL;
921 memcpy(new_entry->data.file.md5, md5, sizeof(new_entry->data.file.md5));
922 new_entry->data.file.file_length = size;
923 new_entry->data.file.rsyncsum = rsyncsum;
924 new_entry->data.file.filename = strdup(filename);
926 /* Add to the end of the list */
927 if (NULL == entry_last)
929 entry_last = new_entry;
930 entry_list = new_entry;
934 entry_last->next = new_entry;
935 entry_last = new_entry;
940 /* Cope with an unmatched block in the .iso file:
942 1. Write a compressed data chunk in the jigdo template file
943 2. Add an entry in our list of unmatched chunks for later */
944 void jtwrite(buffer, size, count, submode, islast)
952 if (count != 1 || (size % 2048) != 0)
953 error("Count: %d, size: %d\n", count, size);
959 /* Update the global image checksum */
960 checksum_update(iso_context, buffer, size * count);
961 // mk_MD5Update(&iso_context, buffer, size*count);
963 /* Write a compressed version of the data to the template file,
964 and add a reference on the state list so we can write that
966 write_compressed_chunk(buffer, size*count);
967 add_unmatched_entry(size*count);
970 /* Cope with a file entry in the .iso file:
972 1. Read the file for the image's md5 checksum
973 2. Add an entry in our list of files to be written into the .jigdo later
975 void write_jt_match_record(char *filename, char *mirror_name, int sector_size, off_t size, unsigned char md5[16])
977 unsigned long long tmp_size = 0;
982 unsigned long long rsync64_sum = 0;
985 memset(buf, 0, sizeof(buf));
987 if ((infile = fopen(filename, "rb")) == NULL) {
989 comerr("cannot open '%s'\n", filename);
991 #ifndef HAVE_STRERROR
992 fprintf(stderr, "cannot open '%s': (%d)\n",
995 fprintf(stderr, "cannot open '%s': %s\n",
996 filename, strerror(errno));
1005 if (remain > sizeof(buf))
1007 if (fread(buf, 1, use, infile) == 0)
1009 #ifdef USE_LIBSCHILY
1010 comerr("cannot read from '%s'\n", filename);
1012 fprintf(stderr, "cannot read from '%s'\n", filename);
1017 rsync64_sum = rsync64(buf, MIN_JIGDO_FILE_SIZE);
1018 checksum_update(iso_context, buf, use);
1019 // mk_MD5Update(&iso_context, buf, use);
1026 /* Update the image checksum with any necessary padding data */
1027 if (size % sector_size)
1029 int pad_size = sector_size - (size % sector_size);
1030 memset(buf, 0, pad_size);
1031 checksum_update(iso_context, buf, pad_size);
1032 // mk_MD5Update(&iso_context, buf, pad_size);
1035 add_file_entry(mirror_name, size, &md5[0], rsync64_sum);
1036 if (size % sector_size)
1038 int pad_size = sector_size - (size % sector_size);
1039 write_compressed_chunk(buf, pad_size);
1040 add_unmatched_entry(pad_size);