"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "libjte/jte.c" between
xorriso-1.5.2.tar.gz and xorriso-1.5.4.tar.gz

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.

jte.c  (xorriso-1.5.2):jte.c  (xorriso-1.5.4)
/* /*
* jte.c * jte.c
* *
* *
* Copyright (c) 2004-2006 Steve McIntyre <steve@einval.com> * Copyright (c) 2004-2019 Steve McIntyre <steve@einval.com>
* Copyright (c) 2010-2011 Thomas Schmitt <scdbackup@gmx.net> * Copyright (c) 2010-2011 Thomas Schmitt <scdbackup@gmx.net>
* Copyright (c) 2010-2011 George Danchev <danchev@spnet.net> * Copyright (c) 2010-2011 George Danchev <danchev@spnet.net>
* *
* These routines were originally implemented by * These routines were originally implemented by
* Steve McIntyre <steve@einval.com>. * Steve McIntyre <steve@einval.com>.
* More recently few tweaks and additions were applied by * More recently few tweaks and additions were applied by
* Thomas Schmitt <scdbackup@gmx.net> and * Thomas Schmitt <scdbackup@gmx.net> and
* George Danchev <danchev@spnet.net> * George Danchev <danchev@spnet.net>
* Updated by Steve to add more generic checksum support, first for sha256
* *
* Implementation of the Jigdo Template Engine - make jigdo files * Implementation of the Jigdo Template Engine - make jigdo files
* directly when making ISO images * directly when making ISO images
* *
* GNU GPL v2+ * GNU GPL v2+
*/ */
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "../config.h" #include "../config.h"
#endif #endif
skipping to change at line 51 skipping to change at line 52
#include <bzlib.h> #include <bzlib.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
#include "jte.h" #include "jte.h"
#include "checksum.h" #include "checksum.h"
#include "endianconv.h" #include "endianconv.h"
#include "rsync.h" #include "rsync.h"
#include "md5.h"
#include "libjte_private.h" #include "libjte_private.h"
#include "libjte.h" #include "libjte.h"
/* #include "version.h" */ /* generated by autotools */
/* Different types used in building our state list below */ /* Different types used in building our state list below */
#define JTET_FILE_MATCH 1 #define JTET_FILE_MATCH 1
#define JTET_NOMATCH 2 #define JTET_NOMATCH 2
#define JTE_VER_MAJOR 0x0001 #define JTE_VER_MAJOR 0x0002
#define JTE_VER_MINOR 0x0013 #define JTE_VER_MINOR 0x0000
#define JTE_NAME "JTE" #define JTE_NAME "JTE"
#define JTE_COMMENT "JTE at http://www.einval.com/~steve/software/JTE/ ; j igdo at http://atterer.org/jigdo/" #define JTE_COMMENT "JTE at https://www.einval.com/~steve/software/JTE/ ; Jigdo at https://www.einval.com/~steve/software/jigdo/"
#define JIGDO_TEMPLATE_VERSION "1.1" #define JIGDO_TEMPLATE_VERSION_MD5 "1.1"
#define JIGDO_TEMPLATE_VERSION_SHA256 "2.0"
#define JTE_MAX_ERROR_LIST_LENGTH 20 #define JTE_MAX_ERROR_LIST_LENGTH 20
/* The various type of jigdo descriptor */
enum _jigdo_desc_type {
JDT_OBSOLETE_IMAGE_INFO = 1,
JDT_UNMATCHED_DATA = 2,
JDT_OBSOLETE_MATCHED_FILE = 3,
JDT_OBSOLETE_WRITTEN_FILE = 4,
JDT_IMAGE_INFO_MD5 = 5,
JDT_MATCHED_FILE_MD5 = 6,
JDT_WRITTEN_FILE_MD5 = 7,
JDT_IMAGE_INFO_SHA256 = 8,
JDT_MATCHED_FILE_SHA256 = 9,
JDT_WRITTEN_FILE_SHA256 = 10
};
/* Grab the file component from a full path */ /* Grab the file component from a full path */
static char *file_base_name(char *path) static char *file_base_name(char *path)
{ {
char *endptr = path; char *endptr = path;
char *ptr = path; char *ptr = path;
while (*ptr != '\0') while (*ptr != '\0')
{ {
if ('/' == *ptr) if ('/' == *ptr)
endptr = ++ptr; endptr = ++ptr;
else else
++ptr; ++ptr;
} }
return endptr; return endptr;
} }
static void exit_if_enabled(struct libjte_env *o, int value) static void exit_if_enabled(struct libjte_env *o, int value)
{ {
if (!(o->error_behavior & 2)) if (!(o->error_behavior & 2))
return; return;
libjte_clear_msg_list(0, 1); libjte_clear_msg_list(o, 1);
exit(value); exit(value);
} }
int libjte_report_no_mem(struct libjte_env *o, size_t size, int flag) int libjte_report_no_mem(struct libjte_env *o, size_t size, int flag)
{ {
sprintf(o->message_buffer, "Out of memory for %.f new bytes", sprintf(o->message_buffer, "Out of memory for %.f new bytes",
(double) size); (double) size);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
return -1; return -1;
} }
skipping to change at line 158 skipping to change at line 171
s_next = s->next; s_next = s->next;
regfree(&(s->match_pattern)); regfree(&(s->match_pattern));
free(s->match_rule); free(s->match_rule);
free(s); free(s);
} }
*old = NULL; *old = NULL;
return 1; return 1;
} }
/* Build the list of exclusion regexps */ /* Build the list of exclusion regexps */
extern int jte_add_exclude(struct libjte_env *o, char *pattern) int jte_add_exclude(struct libjte_env *o, char *pattern)
{ {
int ret; int ret;
ret = jte_add_path_match(o, pattern, 1); ret = jte_add_path_match(o, pattern, 1);
return ret; return ret;
} }
/* Check if the file should be excluded because of a filename match. 1 /* Check if the file should be excluded because of a filename match. 1
means exclude, 0 means not */ means exclude, 0 means not */
static int check_exclude_by_name(struct libjte_env *o, static int check_exclude_by_name(struct libjte_env *o,
skipping to change at line 189 skipping to change at line 202
return 1; return 1;
} }
ptr = ptr->next; ptr = ptr->next;
} }
/* Not matched, so return 0 */ /* Not matched, so return 0 */
return 0; return 0;
} }
/* Build the list of required inclusion regexps */ /* Build the list of required inclusion regexps */
extern int jte_add_include(struct libjte_env *o, char *pattern) int jte_add_include(struct libjte_env *o, char *pattern)
{ {
int ret; int ret;
ret = jte_add_path_match(o, pattern, 0); ret = jte_add_path_match(o, pattern, 0);
return ret; return ret;
} }
int libjte_destroy_entry_list(struct libjte_env *o, int flag) int libjte_destroy_entry_list(struct libjte_env *o, int flag)
{ {
entry_t *s, *s_next; entry_t *s, *s_next;
skipping to change at line 213 skipping to change at line 226
if (s->entry_type == JTET_FILE_MATCH) { if (s->entry_type == JTET_FILE_MATCH) {
if (s->data.file.filename != NULL) if (s->data.file.filename != NULL)
free(s->data.file.filename); free(s->data.file.filename);
} }
free(s); free(s);
} }
o->entry_list = o->entry_last = NULL; o->entry_list = o->entry_last = NULL;
return 1; return 1;
} }
/* Check if a file has to be MD5-matched to be valid. If we get called /* Check if a file has to be checksum-matched to be valid. If we get called
here, we've failed to match any of the MD5 entries we were here, we've failed to match any of the checksum entries we were
given. If the path to the filename matches one of the paths in our given. If the path to the filename matches one of the paths in our
list, clearly it must have been corrupted. Abort with an error. */ list, clearly it must have been corrupted. Abort with an error. */
static int check_md5_file_match(struct libjte_env *o, char *filename) static int check_checksum_file_match(struct libjte_env *o, char *filename)
{ {
struct path_match *ptr = o->include_list; struct path_match *ptr = o->include_list;
regmatch_t pmatch[1]; regmatch_t pmatch[1];
while (ptr) while (ptr)
{ {
if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0)) if (!regexec(&ptr->match_pattern, filename, 1, pmatch, 0))
{ {
sprintf(o->message_buffer, sprintf(o->message_buffer,
"File %1.1024s should have matched an MD5 entry, "File %1.1024s should have matched a checksum entry, but didn't!
but didn't! (Rule '%1.1024s')", (Rule '%1.1024s')",
filename, ptr->match_rule); filename, ptr->match_rule);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
ptr = ptr->next; ptr = ptr->next;
} }
return 0; return 0;
} }
/* Should we list a file separately in the jigdo output, or should we /* Should we list a file separately in the jigdo output, or should we
just dump it into the template file as binary data? Three things just dump it into the template file as binary data? Three things
cases to look for here: cases to look for here:
1. Small files are better simply folded in, as they take less space that way. 1. Small files are better simply folded in, as they take less space that way.
2. Files in /doc (for example) may change in the archive all the 2. Files in /doc (for example) may change in the archive all the
time and it's better to not have to fetch snapshot copies if we time and it's better to not have to fetch snapshot copies if we
can avoid it. can avoid it.
3. Files living in specified paths *must* match an entry in the 3. Files living in specified paths *must* match an entry in the
md5-list, or they must have been corrupted. If we find a corrupt checksum-list, or they must have been corrupted. If we find a
file, bail out with an error. corrupt file, bail out with an error.
*/ */
extern int list_file_in_jigdo(struct libjte_env *o, int list_file_in_jigdo(struct libjte_env *o,
char *filename, off_t size, char **realname, unsigned char md5[16]) char *filename, off_t size,
char **realname, unsigned char *checksum)
{ {
char *matched_rule; char *matched_rule;
md5_list_entry_t *entry = o->md5_list; checksum_list_entry_t *entry = o->checksum_list;
int md5sum_done = 0, ret; int checksum_done = 0, ret;
if (o->jtemplate_out == NULL) if (o->jtemplate_out == NULL)
return 0; return 0;
memset(md5, 0, 16); memset(checksum, 0, check_algos[o->checksum_algo].raw_bytes);
/* Cheaper to check file size first */ /* Cheaper to check file size first */
if (size < o->jte_min_size) if (size < o->jte_min_size)
{ {
if (o->verbose > 1) { if (o->verbose > 1) {
sprintf(o->message_buffer, sprintf(o->message_buffer,
"Jigdo-ignoring file %1.1024s; it's too small", filename); "Jigdo-ignoring file %1.1024s; it's too small", filename);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
} }
return 0; return 0;
skipping to change at line 288 skipping to change at line 302
{ {
if (o->verbose > 1) { if (o->verbose > 1) {
sprintf(o->message_buffer, sprintf(o->message_buffer,
"Jigdo-ignoring file %1.1024s; it's covered in the exclude l ist by \"%1.1024s\"", "Jigdo-ignoring file %1.1024s; it's covered in the exclude l ist by \"%1.1024s\"",
filename, matched_rule); filename, matched_rule);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
} }
return 0; return 0;
} }
/* Check to see if the file is in our md5 list. Check three things: /* Check to see if the file is in our checksum list. Check three things:
1. the size 1. the size
2. the filename 2. the filename
3. (only if the first 2 match) the md5sum 3. (only if the first 2 match) the checksum
If we get a match for all three, include the file and return If we get a match for all three, include the file and return
the full path to the file that we have gleaned from the mirror. the full path to the file that we have gleaned from the mirror.
*/ */
while (entry) while (entry)
{ {
if (size == (off_t) entry->size) if (size == (off_t)entry->size)
{ {
if (!strcmp(file_base_name(filename), file_base_name(entry->filename ))) if (!strcmp(file_base_name(filename), file_base_name(entry->filename )))
{ {
if (!md5sum_done) if (!checksum_done)
{ {
ret = calculate_md5sum(filename, size, md5); ret = checksum_calculate(filename, size,
checksum, check_algos[o->checksum_a
lgo].type);
if (ret < 0) { /* (0 is success) */ if (ret < 0) { /* (0 is success) */
sprintf(o->message_buffer, sprintf(o->message_buffer,
"Error with file '%1.1024s' : errno=%d", "Error with file '%1.1024s' : errno=%d",
filename, errno); filename, errno);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
return -1; return -1;
} }
md5sum_done = 1; checksum_done = 1;
} }
if (!memcmp(md5, entry->MD5, sizeof(entry->MD5))) if (!memcmp(checksum, entry->checksum, check_algos[o->checksum_a lgo].raw_bytes))
{ {
*realname = entry->filename; *realname = entry->filename;
return 1; return 1;
} }
} }
} }
entry = entry->next; entry = entry->next;
} }
/* We haven't found an entry in our MD5 list to match this /* We haven't found an entry in our checksum list to match this
* file. If we should have done, complain and bail out. */ * file. If we should have done, complain and bail out. */
ret = check_md5_file_match(o, filename); ret = check_checksum_file_match(o, filename);
return ret; return ret;
} }
/* Add a mapping of pathnames (e.g. Debian=/mirror/debian). We should /* Add a mapping of pathnames (e.g. Debian=/mirror/debian). We should
be passed TO=FROM here */ be passed TO=FROM here */
extern int jte_add_mapping(struct libjte_env *o, char *arg) int jte_add_mapping(struct libjte_env *o, char *arg)
{ {
struct path_mapping *new = NULL; struct path_mapping *new = NULL;
struct path_mapping *entry = NULL; struct path_mapping *entry = NULL;
char *p = arg; char *p = arg;
char *from = NULL; char *from = NULL;
char *to = NULL; char *to = NULL;
char *eqpt = NULL; char *eqpt = NULL;
/* Find the "=" in the string passed. */ /* Find the "=" in the string passed. */
while (*p) while (*p)
skipping to change at line 442 skipping to change at line 457
sprintf(new_name, "%s:%s", entry->to, &filename[strlen(entry->from)] ); sprintf(new_name, "%s:%s", entry->to, &filename[strlen(entry->from)] );
return new_name; return new_name;
} }
entry = entry->next; entry = entry->next;
} }
/* No mapping in effect */ /* No mapping in effect */
return strdup(filename); return strdup(filename);
} }
/* Write data to the template file and update the MD5 sum */ /* Write data to the template file and update the checksum */
static int template_fwrite(struct libjte_env *o, static int template_fwrite(struct libjte_env *o,
const void *ptr, size_t size, size_t nmemb, FILE *stream) const void *ptr, size_t size, size_t nmemb, FILE *stream)
{ {
size_t written; size_t written;
checksum_update(o->template_context, ptr, size * nmemb); checksum_update(o->template_context, ptr, size * nmemb);
written = fwrite(ptr, size, nmemb, stream); written = fwrite(ptr, size, nmemb, stream);
o->template_size += written * size; o->template_size += written * size;
if (written != nmemb) if (written != nmemb)
return 0; return 0;
skipping to change at line 490 skipping to change at line 505
"template"); "template");
if (o->template_context == NULL) if (o->template_context == NULL)
{ {
sprintf(o->message_buffer, sprintf(o->message_buffer,
"cannot allocate template checksum contexts"); "cannot allocate template checksum contexts");
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
i += sprintf(p, "JigsawDownload template %s libjte-%d.%d.%d \r\n", if (CHECK_MD5 == check_algos[o->checksum_algo].type)
JIGDO_TEMPLATE_VERSION, i += sprintf(p, "JigsawDownload template %s libjte-%d.%d.%d \r\n",
LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR, LIBJTE_VERSION_MICRO); JIGDO_TEMPLATE_VERSION_MD5,
LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR, LIBJTE_VERSION_
MICRO);
else /* CHECK_SHA256 */
i += sprintf(p, "JigsawDownload template %s libjte-%d.%d.%d \r\n",
JIGDO_TEMPLATE_VERSION_SHA256,
LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR, LIBJTE_VERSION_
MICRO);
p = &buf[i]; p = &buf[i];
i += sprintf(p, "%s \r\n", JTE_COMMENT); i += sprintf(p, "%s \r\n", JTE_COMMENT);
p = &buf[i]; p = &buf[i];
i += sprintf(p, "\r\n"); i += sprintf(p, "\r\n");
if (template_fwrite(o, buf, i, 1, o->t_file) <= 0) if (template_fwrite(o, buf, i, 1, o->t_file) <= 0)
return 0; return 0;
return 1; return 1;
} }
/* Read the MD5 list and build a list in memory for us to use later */ /* Read the checksum list and build a list in memory for us to use later */
static void add_md5_entry(struct libjte_env *o, static int add_checksum_entry(struct libjte_env *o,
unsigned char *md5, uint64_t size, char *filename) unsigned char *checksum, uint64_t size,
char *filename)
{ {
md5_list_entry_t *new = NULL; checksum_list_entry_t *new = NULL;
new = calloc(1, sizeof(md5_list_entry_t)); new = calloc(1, sizeof(checksum_list_entry_t));
memcpy(new->MD5, md5, sizeof(new->MD5)); if (!new)
return ENOMEM;
new->checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
if (!new->checksum)
{
free(new);
return ENOMEM;
}
memcpy(new->checksum, checksum, check_algos[o->checksum_algo].raw_bytes);
new->size = size; new->size = size;
new->filename = strdup(filename); new->filename = strdup(filename);
if (!new->filename)
{
free(new->checksum);
free(new);
return ENOMEM;
}
/* Add to the end of the list */ /* Add to the end of the list */
if (NULL == o->md5_last) if (NULL == o->checksum_last)
{ {
o->md5_last = new; o->checksum_last = new;
o->md5_list = new; o->checksum_list = new;
} }
else else
{ {
o->md5_last->next = new; o->checksum_last->next = new;
o->md5_last = new; o->checksum_last = new;
} }
return 0;
} }
int libjte_destroy_md5_list(struct libjte_env *o, int flag) int libjte_destroy_checksum_list(struct libjte_env *o, int flag)
{ {
md5_list_entry_t *s, *s_next; checksum_list_entry_t *s, *s_next;
for (s = o->md5_list; s != NULL; s = s_next) { for (s = o->checksum_list; s != NULL; s = s_next) {
s_next = s->next; s_next = s->next;
free(s->checksum);
free(s->filename); free(s->filename);
free(s); free(s);
} }
o->md5_list = o->md5_last = NULL; o->checksum_list = o->checksum_last = NULL;
return 1; return 1;
} }
/* Parse a 12-digit decimal number */ /* Parse a 12-digit decimal number */
static uint64_t parse_number(unsigned char in[12]) static uint64_t parse_number(unsigned char in[12])
{ {
uint64_t size = 0; uint64_t size = 0;
int i = 0; int i = 0;
for (i = 0; i < 12; i++) for (i = 0; i < 12; i++)
{ {
size *= 10; size *= 10;
if (isdigit(in[i])) if (isdigit(in[i]))
size += (in[i] - '0'); size += (in[i] - '0');
} }
return size; return size;
} }
/* Read the MD5 list and build a list in memory for us to use later /* Read the checksum list and build a list in memory for us to use later
MD5 list format: list format:
<---checksum---> <--Size--> <--Filename-->
XX 12 remaining
<---MD5---> <--Size--> <--Filename--> We know XX (length of the checksum in hex) from the specified
32 12 remaining checksum type in our env. We explicitly check here that the
entries are well-formed
*/ */
static int parse_md5_list(struct libjte_env *o) static int parse_checksum_list(struct libjte_env *o)
{ {
FILE *md5_file = NULL; FILE *checksum_file = NULL;
unsigned char buf[1024]; unsigned char buf[1024];
unsigned char md5[16]; unsigned char *checksum;
char *filename = NULL; char *filename = NULL;
unsigned char *numbuf = NULL; unsigned char *numbuf = NULL;
int num_files = 0; int num_files = 0;
uint64_t size = 0; uint64_t size = 0;
int i = 0;
int valid = 1;
int error = 0;
int csum_hex_size = check_algos[o->checksum_algo].hex_bytes;
md5_file = fopen(o->jmd5_list, "rb"); if (!strcmp (o->jchecksum_list, "/dev/null"))
if (!md5_file)
{ {
sprintf(o->message_buffer, "cannot read from MD5 list file '%1.1024s'", if (o->verbose)
o->jmd5_list); {
sprintf(o->message_buffer, "Ignoring call with checksum list file '%
1.1024s'",
o->jchecksum_list);
libjte_add_msg_entry(o, o->message_buffer, 0);
}
return 1;
}
checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
if (!checksum)
{
sprintf(o->message_buffer, "cannot allocate memory to read from checksum
list file '%1.1024s'",
o->jchecksum_list);
libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1);
errno = ENOMEM;
return -1;
}
checksum_file = fopen(o->jchecksum_list, "rb");
if (!checksum_file)
{
sprintf(o->message_buffer, "cannot open checksum list file '%1.1024s'",
o->jchecksum_list);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
/* Validate the first line - is it using the right checksum
* type? */
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
while (fgets((char *)buf, sizeof(buf), md5_file)) if(!fgets((char *)buf, sizeof(buf), checksum_file))
{ {
numbuf = &buf[34]; free(checksum);
filename = (char *)&buf[48]; fclose(checksum_file);
sprintf(o->message_buffer, "cannot read from checksum list file '%1.1024
s'",
o->jchecksum_list);
libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1);
return -1;
}
/* Check that we have hex digits for just the right number of
* characters, followed by two spaces */
for (i = 0; valid && i < csum_hex_size; i++)
if (!isxdigit(buf[i]))
valid = -i;
if (valid > 0) {
if (' ' != buf[csum_hex_size])
valid = -csum_hex_size;
if (' ' != buf[csum_hex_size+1])
valid = -csum_hex_size - 1;
}
if(valid <= 0)
{
free(checksum);
fclose(checksum_file);
sprintf(o->message_buffer, "invalid checksum list file '%1.1024s' - wron
g checksum type?",
o->jchecksum_list);
libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1);
return -1;
}
fseek(checksum_file, 0, SEEK_SET);
memset(buf, 0, sizeof(buf));
while (fgets((char *)buf, sizeof(buf), checksum_file))
{
numbuf = &buf[csum_hex_size + 2];
filename = (char *)&buf[csum_hex_size + 16];
/* Lose the trailing \n from the fgets() call */ /* Lose the trailing \n from the fgets() call */
if (buf[strlen((char *)buf)-1] == '\n') if (buf[strlen((char *)buf)-1] == '\n')
buf[strlen((char *)buf)-1] = 0; buf[strlen((char *)buf)-1] = 0;
if (mk_MD5Parse(buf, md5)) if (checksum_parse_hex((char *)buf, checksum, csum_hex_size))
{ {
sprintf(o->message_buffer, "cannot parse MD5 file '%1.1024s'", free(checksum);
o->jmd5_list); fclose(checksum_file);
sprintf(o->message_buffer, "cannot parse checksum file '%1.1024s'",
o->jchecksum_list);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
size = parse_number(numbuf); size = parse_number(numbuf);
add_md5_entry(o, md5, size, filename);
error = add_checksum_entry(o, checksum, size, filename);
if (error)
{
free(checksum);
fclose(checksum_file);
sprintf(o->message_buffer, "cannot add checksum entry to list from f
ile '%1.1024s', error %d",
o->jchecksum_list, error);
libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1);
return -1;
}
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
num_files++; num_files++;
} }
if (o->verbose > 0) { if (o->verbose > 0) {
sprintf(o->message_buffer, sprintf(o->message_buffer,
"parse_md5_list: added MD5 checksums for %d files", num_files); "parse_checksum_list: added checksums for %d files", num_files);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
} }
fclose(md5_file); free(checksum);
fclose(checksum_file);
return 1; return 1;
} }
/* Initialise state and start the jigdo template file */ /* Initialise state and start the jigdo template file */
int write_jt_header(struct libjte_env *o, int write_jt_header(struct libjte_env *o,
FILE *template_file, FILE *jigdo_file) FILE *template_file, FILE *jigdo_file)
{ {
int ret; int ret;
o->t_file = template_file; o->t_file = template_file;
skipping to change at line 640 skipping to change at line 759
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
/* Start the template file */ /* Start the template file */
ret = write_template_header(o); ret = write_template_header(o);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
/* Load up the MD5 list if we've been given one */ /* Load up the checksum list if we've been given one */
if (o->jmd5_list) { if (o->jchecksum_list) {
ret = parse_md5_list(o); ret = parse_checksum_list(o);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
} }
return 1; return 1;
} }
/* Compress and flush out a buffer full of template data */ /* Compress and flush out a buffer full of template data */
/* Return 0 on failure, non-zero on success */ /* Return 0 on failure, non-zero on success */
static int flush_gzip_chunk(struct libjte_env *o, void *buffer, off_t size) static int flush_gzip_chunk(struct libjte_env *o, void *buffer, off_t size)
{ {
skipping to change at line 847 skipping to change at line 966
return ret; return ret;
} }
/* Append to an existing data buffer, and compress/flush it if /* Append to an existing data buffer, and compress/flush it if
necessary */ necessary */
static int write_compressed_chunk(struct libjte_env *o, static int write_compressed_chunk(struct libjte_env *o,
unsigned char *buffer, size_t size) unsigned char *buffer, size_t size)
{ {
int ret; int ret;
if (o->uncomp_buf == NULL) if (o->uncomp_buf == NULL)
{ {
if (o->jte_template_compression == JTE_TEMP_BZIP2) if (o->jte_template_compression == JTE_TEMP_BZIP2)
o->uncomp_size = 900 * 1024; o->uncomp_size = 900 * 1024;
else else
o->uncomp_size = 1024 * 1024; o->uncomp_size = 1024 * 1024;
o->uncomp_buf = malloc(o->uncomp_size); o->uncomp_buf = malloc(o->uncomp_size);
if (o->uncomp_buf == NULL) if (o->uncomp_buf == NULL)
{ {
sprintf(o->message_buffer, sprintf(o->message_buffer,
"failed to allocate %lu bytes for template compression buffer", "failed to allocate %lu bytes for template compression buffer",
(unsigned long) o->uncomp_size); (unsigned long) o->uncomp_size);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
} }
if ((o->uncomp_buf_used + size) > o->uncomp_size) if ((o->uncomp_buf_used + size) > o->uncomp_size)
{ {
ret = flush_compressed_chunk(o, o->uncomp_buf, o->uncomp_buf_used); ret = flush_compressed_chunk(o, o->uncomp_buf, o->uncomp_buf_used);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
o->uncomp_buf_used = 0; o->uncomp_buf_used = 0;
} }
if (!size) /* Signal a flush before we start writing the DESC entry */ if (!size) /* Signal a flush before we start writing the DESC entry */
skipping to change at line 904 skipping to change at line 1023
return 1; return 1;
} }
/* Loop through the list of DESC entries that we've built up and /* Loop through the list of DESC entries that we've built up and
append them to the template file */ append them to the template file */
static int write_template_desc_entries(struct libjte_env *o, off_t image_len) static int write_template_desc_entries(struct libjte_env *o, off_t image_len)
{ {
entry_t *entry = o->entry_list; entry_t *entry = o->entry_list;
off_t desc_len = 0; off_t desc_len = 0;
unsigned char out_len[6]; unsigned char out_len[6];
jigdo_image_entry_t jimage;
int ret; int ret;
desc_len = 16 /* DESC + length twice */ if (CHECK_MD5 == check_algos[o->checksum_algo].type)
+ (sizeof(jigdo_file_entry_t) * o->num_matches) {
+ (sizeof(jigdo_chunk_entry_t) * o->num_chunks) desc_len = 16 /* DESC + length twice */
+ sizeof(jigdo_image_entry_t); + (sizeof(jigdo_file_entry_md5_t) * o->num_matches)
+ (sizeof(jigdo_chunk_entry_t) * o->num_chunks)
+ sizeof(jigdo_image_entry_md5_t);
}
else /* CHECK_SHA256 */
{
desc_len = 16 /* DESC + length twice */
+ (sizeof(jigdo_file_entry_sha256_t) * o->num_matches)
+ (sizeof(jigdo_chunk_entry_t) * o->num_chunks)
+ sizeof(jigdo_image_entry_sha256_t);
}
write_le48(desc_len, &out_len[0]); write_le48(desc_len, &out_len[0]);
ret = write_compressed_chunk(o, NULL, 0); ret = write_compressed_chunk(o, NULL, 0);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
if (template_fwrite(o, "DESC", 4, 1, o->t_file) <= 0) if (template_fwrite(o, "DESC", 4, 1, o->t_file) <= 0)
return 0; return 0;
if (template_fwrite(o, out_len, sizeof(out_len), 1, o->t_file) <= 0) if (template_fwrite(o, out_len, sizeof(out_len), 1, o->t_file) <= 0)
return 0; return 0;
while (entry) while (entry)
{ {
switch (entry->entry_type) switch (entry->entry_type)
{ {
case JTET_FILE_MATCH: case JTET_FILE_MATCH:
{ {
jigdo_file_entry_t jfile; if (CHECK_MD5 == check_algos[o->checksum_algo].type)
jfile.type = 6; /* Matched file */ {
write_le48(entry->data.file.file_length, &jfile.fileLen[0]); jigdo_file_entry_md5_t jfile;
write_le64(entry->data.file.rsyncsum, &jfile.fileRsync[0]); jfile.type = JDT_MATCHED_FILE_MD5;
memcpy(jfile.fileMD5, entry->data.file.md5, sizeof(jfile.fileMD5 write_le48(entry->data.file.file_length, &jfile.fileLen[0]);
)); write_le64(entry->data.file.rsyncsum, &jfile.fileRsync[0]);
if (template_fwrite(o, &jfile, sizeof(jfile), 1, memcpy(jfile.fileMD5, entry->data.file.checksum, sizeof(jfil
o->t_file) <= 0) e.fileMD5));
return 0; if (template_fwrite(o, &jfile, sizeof(jfile), 1,
o->t_file) <= 0)
return 0;
}
else /* CHECK_SHA256 */
{
jigdo_file_entry_sha256_t jfile;
jfile.type = JDT_MATCHED_FILE_SHA256;
write_le48(entry->data.file.file_length, &jfile.fileLen[0]);
write_le64(entry->data.file.rsyncsum, &jfile.fileRsync[0]);
memcpy(jfile.fileSHA256, entry->data.file.checksum, sizeof(j
file.fileSHA256));
if (template_fwrite(o, &jfile, sizeof(jfile), 1,
o->t_file) <= 0)
return 0;
}
break; break;
} }
case JTET_NOMATCH: case JTET_NOMATCH:
{ {
jigdo_chunk_entry_t jchunk; jigdo_chunk_entry_t jchunk;
jchunk.type = 2; /* Raw data, compressed */ jchunk.type = JDT_UNMATCHED_DATA;
write_le48(entry->data.chunk.uncompressed_length, &jchunk.skipLe n[0]); write_le48(entry->data.chunk.uncompressed_length, &jchunk.skipLe n[0]);
if (template_fwrite(o, &jchunk, sizeof(jchunk), 1, if (template_fwrite(o, &jchunk, sizeof(jchunk), 1,
o->t_file) <= 0) o->t_file) <= 0)
return 0; return 0;
break; break;
} }
} }
entry = entry->next; entry = entry->next;
} }
jimage.type = 5; if (CHECK_MD5 == check_algos[o->checksum_algo].type)
write_le48(image_len, &jimage.imageLen[0]); {
checksum_copy(o->iso_context, CHECK_MD5, &jimage.imageMD5[0]); jigdo_image_entry_md5_t jimage;
write_le32(MIN_JIGDO_FILE_SIZE, &jimage.blockLen[0]); jimage.type = JDT_IMAGE_INFO_MD5;
if (template_fwrite(o, &jimage, sizeof(jimage), 1, o->t_file) <= 0) write_le48(image_len, &jimage.imageLen[0]);
return 0; checksum_copy(o->iso_context, CHECK_MD5, &jimage.imageMD5[0]);
write_le32(MIN_JIGDO_FILE_SIZE, &jimage.blockLen[0]);
if (template_fwrite(o, &jimage, sizeof(jimage), 1, o->t_file) <= 0)
return 0;
}
else /* CHECK_SHA256 */
{
jigdo_image_entry_sha256_t jimage;
jimage.type = JDT_IMAGE_INFO_SHA256;
write_le48(image_len, &jimage.imageLen[0]);
checksum_copy(o->iso_context, CHECK_SHA256, &jimage.imageSHA256[0]);
write_le32(MIN_JIGDO_FILE_SIZE, &jimage.blockLen[0]);
if (template_fwrite(o, &jimage, sizeof(jimage), 1, o->t_file) <= 0)
return 0;
}
if(template_fwrite(o, out_len, sizeof(out_len), 1, o->t_file) <= 0) if(template_fwrite(o, out_len, sizeof(out_len), 1, o->t_file) <= 0)
return 0; return 0;
return 1; return 1;
} }
/* Dump a buffer in jigdo-style "base64" */ /* Dump a buffer in jigdo-style "base64" */
static char *base64_dump(struct libjte_env *o, static char *base64_dump(struct libjte_env *o,
unsigned char *buf, size_t buf_size) unsigned char *buf, size_t buf_size)
{ {
const char *b64_enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0 123456789-_"; const char *b64_enc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0 123456789-_";
skipping to change at line 1028 skipping to change at line 1185
tr = dec[i]; tr = dec[i];
dec[i] = dec[l - i - 1]; dec[i] = dec[l - i - 1];
dec[l - i - 1] = tr; dec[l - i - 1] = tr;
} }
return dec; return dec;
} }
/* Write the .jigdo file to match the .template we've just finished. */ /* Write the .jigdo file to match the .template we've just finished. */
static int write_jigdo_file(struct libjte_env *o) static int write_jigdo_file(struct libjte_env *o)
{ {
unsigned char template_md5sum[16]; unsigned char *template_checksum;
entry_t *entry = o->entry_list; entry_t *entry = o->entry_list;
int i = 0; int i = 0;
struct checksum_info *info = NULL; struct checksum_info *info = NULL;
FILE *j_file = o->j_file; FILE *j_file = o->j_file;
char *b64, dec[40]; char *b64, dec[40];
template_checksum = calloc(1, check_algos[o->checksum_algo].raw_bytes);
if (!template_checksum)
{
sprintf(o->message_buffer,
"write_jigdo_file: Out of memory for buffer size %d",
check_algos[o->checksum_algo].raw_bytes);
libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1);
return -1;
}
checksum_final(o->template_context); checksum_final(o->template_context);
checksum_copy(o->template_context, CHECK_MD5, &template_md5sum[0]); checksum_copy(o->template_context, check_algos[o->checksum_algo].type, &temp late_checksum[0]);
fprintf(j_file, "# JigsawDownload\n"); fprintf(j_file, "# JigsawDownload\n");
fprintf(j_file, "# See <http://atterer.org/jigdo/> for details about jigdo\n fprintf(j_file, "# See <https://www.einval.com/~steve/software/jigdo/> for d
"); etails about jigdo\n");
fprintf(j_file, "# See <http://www.einval.com/~steve/software/CD/JTE/> for d fprintf(j_file, "# See <https://www.einval.com/~steve/software/JTE/> for det
etails about JTE\n\n"); ails about JTE\n\n");
fprintf(j_file, "[Jigdo]\n"); fprintf(j_file, "[Jigdo]\n");
fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION); if (CHECK_MD5 == check_algos[o->checksum_algo].type)
fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION_MD5);
else /* CHECK_SHA256 */
fprintf(j_file, "Version=%s\n", JIGDO_TEMPLATE_VERSION_SHA256);
fprintf(j_file, "Generator=libjte-%d.%d.%d\n\n", fprintf(j_file, "Generator=libjte-%d.%d.%d\n\n",
LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR, LIBJTE_VERSION_MICRO); LIBJTE_VERSION_MAJOR, LIBJTE_VERSION_MINOR, LIBJTE_VERSION_MICRO);
fprintf(j_file, "[Image]\n"); fprintf(j_file, "[Image]\n");
fprintf(j_file, "Filename=%s\n", file_base_name(o->outfile)); fprintf(j_file, "Filename=%s\n", file_base_name(o->outfile));
fprintf(j_file, "Template=http://localhost/%s\n", o->jtemplate_out); fprintf(j_file, "Template=http://localhost/%s\n", o->jtemplate_out);
b64 = base64_dump(o, &template_md5sum[0], sizeof(template_md5sum)); b64 = base64_dump(o, &template_checksum[0], check_algos[o->checksum_algo].ra w_bytes);
if (b64 == NULL) if (b64 == NULL)
return -1; return -1;
fprintf(j_file, "Template-MD5Sum=%s \n", b64);
if (CHECK_MD5 == check_algos[o->checksum_algo].type)
fprintf(j_file, "Template-MD5Sum=%s \n", b64);
else /* CHECK_SHA256 */
fprintf(j_file, "Template-SHA256Sum=%s \n", b64);
free(b64); free(b64);
for (i = 0; i < NUM_CHECKSUMS; i++) for (i = 0; i < NUM_CHECKSUMS; i++)
{ {
if (o->checksum_algo_tmpl & (1 << i)) if (o->checksum_algo_tmpl & (1 << i))
{ {
info = checksum_information(i); info = checksum_information(i);
fprintf(j_file, "# Template Hex %sSum %s\n", info->name, fprintf(j_file, "# Template Hex %sSum %s\n", info->name,
checksum_hex(o->template_context, i)); checksum_hex(o->template_context, i));
} }
skipping to change at line 1091 skipping to change at line 1266
fprintf(j_file, "[Parts]\n"); fprintf(j_file, "[Parts]\n");
while (entry) while (entry)
{ {
if (JTET_FILE_MATCH == entry->entry_type) if (JTET_FILE_MATCH == entry->entry_type)
{ {
char *new_name = remap_filename(o, entry->data.file.filename); char *new_name = remap_filename(o, entry->data.file.filename);
if (new_name == NULL) if (new_name == NULL)
return -1; return -1;
b64 = base64_dump(o, &entry->data.file.md5[0], b64 = base64_dump(o, entry->data.file.checksum, check_algos[o->check
sizeof(entry->data.file.md5)); sum_algo].raw_bytes);
if (b64 == NULL) if (b64 == NULL)
return -1; return -1;
fprintf(j_file, "%s=%s\n", b64, new_name); fprintf(j_file, "%s=%s\n", b64, new_name);
free(b64); free(b64);
free(new_name); free(new_name);
} }
entry = entry->next; entry = entry->next;
} }
fprintf(j_file, "\n[Servers]\n"); fprintf(j_file, "\n[Servers]\n");
skipping to change at line 1160 skipping to change at line 1334
else else
{ {
o->entry_last->next = new_entry; o->entry_last->next = new_entry;
o->entry_last = new_entry; o->entry_last = new_entry;
} }
o->num_chunks++; o->num_chunks++;
} }
/* Add a file match entry to the list of extents */ /* Add a file match entry to the list of extents */
static void add_file_entry(struct libjte_env *o, static void add_file_entry(struct libjte_env *o,
char *filename, off_t size, unsigned char *md5, char *filename, off_t size, unsigned char *checksum,
uint64_t rsyncsum) uint64_t rsyncsum)
{ {
entry_t *new_entry = NULL; entry_t *new_entry = NULL;
new_entry = calloc(1, sizeof(entry_t)); new_entry = calloc(1, sizeof(entry_t));
new_entry->entry_type = JTET_FILE_MATCH; new_entry->entry_type = JTET_FILE_MATCH;
new_entry->next = NULL; new_entry->next = NULL;
memcpy(new_entry->data.file.md5, md5, sizeof(new_entry->data.file.md5)); new_entry->data.file.checksum = calloc(1, check_algos[o->checksum_algo].raw_
bytes);
memcpy(new_entry->data.file.checksum, checksum, check_algos[o->checksum_algo
].raw_bytes);
new_entry->data.file.file_length = size; new_entry->data.file.file_length = size;
new_entry->data.file.rsyncsum = rsyncsum; new_entry->data.file.rsyncsum = rsyncsum;
new_entry->data.file.filename = strdup(filename); new_entry->data.file.filename = strdup(filename);
/* Add to the end of the list */ /* Add to the end of the list */
if (NULL == o->entry_last) if (NULL == o->entry_last)
{ {
o->entry_last = new_entry; o->entry_last = new_entry;
o->entry_list = new_entry; o->entry_list = new_entry;
} }
skipping to change at line 1213 skipping to change at line 1388
later. */ later. */
ret = write_compressed_chunk(o, buffer, size*count); ret = write_compressed_chunk(o, buffer, size*count);
if (ret <= 0) if (ret <= 0)
return ret; return ret;
add_unmatched_entry(o, size*count); add_unmatched_entry(o, size*count);
return 1; return 1;
} }
/* Cope with a file entry in the .iso file: /* Cope with a file entry in the .iso file:
1. Read the file for the image's md5 checksum 1. Read the file for the image's checksum
2. Add an entry in our list of files to be written into the .jigdo later 2. Add an entry in our list of files to be written into the .jigdo later
*/ */
int write_jt_match_record(struct libjte_env *o, int write_jt_match_record(struct libjte_env *o,
char *filename, char *mirror_name, int sector_size, char *filename, char *mirror_name, int sector_size,
off_t size, unsigned char md5[16]) off_t size, unsigned char *checksum)
{ {
char buf[32768]; char buf[32768];
off_t remain = size; off_t remain = size;
FILE *infile = NULL; FILE *infile = NULL;
int use = 0; int use = 0;
uint64_t rsync64_sum = 0; uint64_t rsync64_sum = 0;
int first_block = 1; int first_block = 1;
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
if ((infile = fopen(filename, "rb")) == NULL) { if ((infile = fopen(filename, "rb")) == NULL) {
#ifndef HAVE_STRERROR #ifndef HAVE_STRERROR
sprintf(o->message_buffer, "cannot open '%s': (%d)", sprintf(o->message_buffer, "cannot open '%s': (%d)",
filename, errno); filename, errno);
#else #else
sprintf(o->message_buffer, "cannot open '%s': %s", sprintf(o->message_buffer, "cannot open '%s': %s",
filename, strerror(errno)); filename, strerror(errno));
#endif #endif
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
while (remain > 0) while (remain > 0)
{ {
use = remain; use = remain;
if (remain > (off_t) sizeof(buf)) if (remain > (off_t)sizeof(buf))
use = sizeof(buf); use = sizeof(buf);
if (fread(buf, 1, use, infile) == 0) if (fread(buf, 1, use, infile) == 0)
{ {
sprintf(o->message_buffer, sprintf(o->message_buffer,
"cannot read from '%s'", filename); "cannot read from '%s'", filename);
libjte_add_msg_entry(o, o->message_buffer, 0); libjte_add_msg_entry(o, o->message_buffer, 0);
exit_if_enabled(o, 1); exit_if_enabled(o, 1);
return -1; return -1;
} }
if (first_block) if (first_block)
rsync64_sum = rsync64((unsigned char *) buf, MIN_JIGDO_FILE_SIZE); rsync64_sum = rsync64((unsigned char *) buf, MIN_JIGDO_FILE_SIZE);
checksum_update(o->iso_context, (unsigned char *) buf, use); checksum_update(o->iso_context, (unsigned char *) buf, use);
remain -= use; remain -= use;
first_block = 0; first_block = 0;
} }
fclose(infile); fclose(infile);
/* Update the image checksum with any necessary padding data */ /* Update the image checksum with any necessary padding data */
if (size % sector_size) if (size % sector_size)
{ {
int pad_size = sector_size - (size % sector_size); int pad_size = sector_size - (size % sector_size);
memset(buf, 0, pad_size); memset(buf, 0, pad_size);
checksum_update(o->iso_context, (unsigned char *) buf, pad_size); checksum_update(o->iso_context, (unsigned char *) buf, pad_size);
} }
add_file_entry(o, mirror_name, size, &md5[0], rsync64_sum); add_file_entry(o, mirror_name, size, &checksum[0], rsync64_sum);
if (size % sector_size) if (size % sector_size)
{ {
int pad_size = sector_size - (size % sector_size); int pad_size = sector_size - (size % sector_size);
write_compressed_chunk(o, (unsigned char *) buf, pad_size); write_compressed_chunk(o, (unsigned char *) buf, pad_size);
add_unmatched_entry(o, pad_size); add_unmatched_entry(o, pad_size);
} }
return 1; return 1;
} }
int libjte_add_msg_entry(struct libjte_env *o, char *message, int flag) int libjte_add_msg_entry(struct libjte_env *o, char *message, int flag)
 End of changes. 89 change blocks. 
148 lines changed or deleted 335 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)