23 #include "../config.h"
29 #ifdef HAVE_INTTYPES_H
37 #ifdef LIBJTE_WITH_ZLIB
41 #ifdef LIBJTE_WITH_LIBBZ2
45 #include <sys/types.h>
56 #define JTET_FILE_MATCH 1
57 #define JTET_NOMATCH 2
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/"
64 #define JIGDO_TEMPLATE_VERSION_MD5 "1.1"
65 #define JIGDO_TEMPLATE_VERSION_SHA256 "2.0"
67 #define JTE_MAX_ERROR_LIST_LENGTH 20
130 new = malloc(
sizeof *
new);
134 regcomp(&new->match_pattern, pattern, REG_NEWLINE);
135 new->match_rule = strdup(pattern);
136 if (new->match_rule == NULL)
160 for (s = *old; s != NULL; s = s_next) {
182 char *filename,
char **matched)
185 regmatch_t pmatch[1];
214 for (s = o->
entry_list ; s != NULL; s = s_next) {
233 regmatch_t pmatch[1];
240 "File %1.1024s should have matched a checksum entry, but didn't! (Rule '%1.1024s')",
267 char *filename, off_t size,
268 char **realname,
unsigned char *checksum)
272 int checksum_done = 0, ret;
280 if (size < o->jte_min_size)
284 "Jigdo-ignoring file %1.1024s; it's too small", filename);
295 "Jigdo-ignoring file %1.1024s; it's covered in the exclude list by \"%1.1024s\"",
296 filename, matched_rule);
314 if (size == (off_t)entry->
size)
324 "Error with file '%1.1024s' : errno=%d",
371 if (
from == NULL || !strlen(
from) || eqpt == arg)
376 to = calloc(1, (eqpt - arg) + 1);
381 strncpy(
to, arg, eqpt - arg);
384 new = malloc(
sizeof(*
new));
396 "Adding mapping from %1.1024s to %1.1024s for the jigdo file",
406 while (NULL != entry->
next)
418 for (s = o->
map_list; s != NULL; s = s_next) {
433 char *new_name = filename;
438 if (!strncmp(filename, entry->
from, strlen(entry->
from)))
440 new_name = calloc(1, 2 + strlen(filename) + strlen(entry->
to) - strlen(entry->
from));
444 "Failed to malloc new filename; abort!");
449 sprintf(new_name,
"%s:%s", entry->
to, &filename[strlen(entry->
from)]);
456 return strdup(filename);
461 const void *ptr,
size_t size,
size_t nmemb, FILE *stream)
466 written = fwrite(ptr, size, nmemb, stream);
468 if (written != nmemb)
480 #ifndef LIBJTE_WITH_LIBBZ2
484 "libjte: Compression algorithm BZIP2 not enabled at compile time");
492 memset(buf, 0,
sizeof(buf));
501 "cannot allocate template checksum contexts");
508 i += sprintf(p,
"JigsawDownload template %s libjte-%d.%d.%d \r\n",
512 i += sprintf(p,
"JigsawDownload template %s libjte-%d.%d.%d \r\n",
520 i += sprintf(p,
"\r\n");
528 unsigned char *checksum, uint64_t size,
544 new->filename = strdup(filename);
586 for (i = 0; i < 12; i++)
590 size += (in[i] -
'0');
608 FILE *checksum_file = NULL;
609 unsigned char buf[1024];
610 unsigned char *checksum;
611 char *filename = NULL;
612 unsigned char *numbuf = NULL;
624 sprintf(o->
message_buffer,
"Ignoring call with checksum list file '%1.1024s'",
634 sprintf(o->
message_buffer,
"cannot allocate memory to read from checksum list file '%1.1024s'",
645 sprintf(o->
message_buffer,
"cannot open checksum list file '%1.1024s'",
654 memset(buf, 0,
sizeof(buf));
655 if(!fgets((
char *)buf,
sizeof(buf), checksum_file))
658 fclose(checksum_file);
659 sprintf(o->
message_buffer,
"cannot read from checksum list file '%1.1024s'",
668 for (i = 0; valid && i < csum_hex_size; i++)
669 if (!isxdigit(buf[i]))
672 if (
' ' != buf[csum_hex_size])
673 valid = -csum_hex_size;
674 if (
' ' != buf[csum_hex_size+1])
675 valid = -csum_hex_size - 1;
680 fclose(checksum_file);
681 sprintf(o->
message_buffer,
"invalid checksum list file '%1.1024s' - wrong checksum type?",
688 fseek(checksum_file, 0, SEEK_SET);
689 memset(buf, 0,
sizeof(buf));
690 while (fgets((
char *)buf,
sizeof(buf), checksum_file))
692 numbuf = &buf[csum_hex_size + 2];
693 filename = (
char *)&buf[csum_hex_size + 16];
695 if (buf[strlen((
char *)buf)-1] ==
'\n')
696 buf[strlen((
char *)buf)-1] = 0;
701 fclose(checksum_file);
702 sprintf(o->
message_buffer,
"cannot parse checksum file '%1.1024s'",
714 fclose(checksum_file);
715 sprintf(o->
message_buffer,
"cannot add checksum entry to list from file '%1.1024s', error %d",
722 memset(buf, 0,
sizeof(buf));
727 "parse_checksum_list: added checksums for %d files", num_files);
731 fclose(checksum_file);
737 FILE *template_file, FILE *jigdo_file)
741 o->
t_file = template_file;
750 sprintf(o->
message_buffer,
"cannot allocate iso checksum contexts");
775 #ifdef LIBJTE_WITH_ZLIB
778 unsigned char comp_size_out[6];
779 unsigned char uncomp_size_out[6];
780 off_t compressed_size_out = 0;
782 unsigned char *comp_buf = NULL;
784 c_stream.zalloc = NULL;
785 c_stream.zfree = NULL;
786 c_stream.opaque = NULL;
788 err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
792 if (NULL == (comp_buf = malloc(2 * size)))
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;
800 err = deflate(&c_stream, Z_NO_FLUSH);
807 err = deflate(&c_stream, Z_FINISH);
814 compressed_size_out = c_stream.total_out + 16;
815 err = deflateEnd(&c_stream);
828 write_le48(compressed_size_out, &comp_size_out[0]);
851 static int complaints = 0;
857 "\nlibjte: Configuration error. Use without enabled zlib\n\n");
865 #ifdef LIBJTE_WITH_LIBBZ2
872 unsigned char comp_size_out[6];
873 unsigned char uncomp_size_out[6];
874 off_t compressed_size_out = 0;
876 char *comp_buf = NULL;
878 c_stream.bzalloc = NULL;
879 c_stream.bzfree = NULL;
880 c_stream.opaque = NULL;
882 err = BZ2_bzCompressInit(&c_stream, 9, 0, 0);
886 if (NULL == (comp_buf = (
char*) malloc(2 * size)))
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;
893 err = BZ2_bzCompress(&c_stream, BZ_FINISH);
900 compressed_size_out = c_stream.total_out_lo32 + 16;
901 err = BZ2_bzCompressEnd(&c_stream);
914 write_le48(compressed_size_out, &comp_size_out[0]);
966 unsigned char *
buffer,
size_t size)
980 "failed to allocate %lu bytes for template compression buffer",
1026 unsigned char out_len[6];
1094 entry = entry->
next;
1125 unsigned char *buf,
size_t buf_size)
1127 const char *b64_enc =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
1131 char *output_buffer = NULL;
1132 int output_buffer_size;
1135 output_buffer_size = buf_size * 8 / 6 + 1 + 1;
1136 p = output_buffer = calloc(1, output_buffer_size);
1137 if (output_buffer == NULL)
1140 "base64_dump: Out of memory for buffer size %d",
1141 output_buffer_size);
1146 memset(output_buffer, 0, output_buffer_size);
1148 for (i = 0; i < buf_size ; i++)
1150 value = (value << 8) | buf[i];
1152 p += sprintf(p,
"%c", b64_enc[(value >> bits) & 63U]);
1155 p += sprintf(p,
"%c", b64_enc[(value >> bits) & 63U]);
1161 p += sprintf(p,
"%c", b64_enc[value & 63U]);
1163 return output_buffer;
1172 while (num > 0 && l < 39) {
1173 dec[l++] =
'0' + num % 10;
1179 for (i = 0;i < l / 2; i++) {
1181 dec[i] = dec[l - i - 1];
1182 dec[l - i - 1] = tr;
1191 unsigned char *template_checksum;
1195 FILE *j_file = o->
j_file;
1199 if (!template_checksum)
1202 "write_jigdo_file: Out of memory for buffer size %d",
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");
1216 fprintf(j_file,
"[Jigdo]\n");
1221 fprintf(j_file,
"Generator=libjte-%d.%d.%d\n\n",
1224 fprintf(j_file,
"[Image]\n");
1226 fprintf(j_file,
"Template=http://localhost/%s\n", o->
jtemplate_out);
1233 fprintf(j_file,
"Template-MD5Sum=%s \n", b64);
1235 fprintf(j_file,
"Template-SHA256Sum=%s \n", b64);
1243 fprintf(j_file,
"# Template Hex %sSum %s\n", info->
name,
1247 fprintf(j_file,
"# Template size %s bytes\n",
1255 fprintf(j_file,
"# Image Hex %sSum %s\n",
1260 fprintf(j_file,
"# Image size %s bytes\n\n",
1263 fprintf(j_file,
"[Parts]\n");
1270 if (new_name == NULL)
1275 fprintf(j_file,
"%s=%s\n", b64, new_name);
1279 entry = entry->
next;
1282 fprintf(j_file,
"\n[Servers]\n");
1319 new_entry = calloc(1,
sizeof(
entry_t));
1321 new_entry->
next = NULL;
1340 char *filename, off_t size,
unsigned char *checksum,
1345 new_entry = calloc(1,
sizeof(
entry_t));
1347 new_entry->
next = NULL;
1398 char *filename,
char *mirror_name,
int sector_size,
1399 off_t size,
unsigned char *checksum)
1402 off_t remain = size;
1403 FILE *infile = NULL;
1405 uint64_t rsync64_sum = 0;
1406 int first_block = 1;
1408 memset(buf, 0,
sizeof(buf));
1410 if ((infile = fopen(filename,
"rb")) == NULL) {
1411 #ifndef HAVE_STRERROR
1416 filename, strerror(errno));
1426 if (remain > (off_t)
sizeof(buf))
1428 if (fread(buf, 1, use, infile) == 0)
1431 "cannot read from '%s'", filename);
1446 if (size % sector_size)
1448 int pad_size = sector_size - (size % sector_size);
1449 memset(buf, 0, pad_size);
1454 if (size % sector_size)
1456 int pad_size = sector_size - (size % sector_size);
1466 int list_length = 0;
1469 fprintf(stderr,
"libjte: %s\n", message);
1483 if (new_entry == NULL) {
1485 fprintf(stderr,
"libjte: %s\n", message);
1486 fprintf(stderr,
"libjte: OUT OF MEMORY\n");
1489 new_entry->
next = NULL;
1490 new_entry->
message = strdup(message);
1491 if (new_entry->
message == NULL) {
1498 s->
next = new_entry;
int checksum_calculate(char *filename, int64_t size, unsigned char *out, enum checksum_types which)
checksum_context_t * checksum_init_context(int checksums, const char *owner)
const char * checksum_hex(checksum_context_t *context, enum checksum_types which)
void checksum_update(checksum_context_t *context, unsigned char const *buf, unsigned int len)
void checksum_copy(checksum_context_t *context, enum checksum_types which, unsigned char *digest)
void checksum_final(checksum_context_t *context)
int checksum_parse_hex(char *in, unsigned char *out, int size)
void checksum_free_context(checksum_context_t *context)
struct checksum_info * checksum_information(enum checksum_types which)
void write_le32(unsigned long in, unsigned char *out)
void write_le48(uint64_t in, unsigned char *out)
void write_le64(uint64_t in, unsigned char *out)
int libjte_add_msg_entry(struct libjte_env *o, char *message, int flag)
int write_jt_match_record(struct libjte_env *o, char *filename, char *mirror_name, int sector_size, off_t size, unsigned char *checksum)
static int write_jigdo_file(struct libjte_env *o)
int libjte_destroy_checksum_list(struct libjte_env *o, int flag)
static char * uint64_to_dec(uint64_t num, char dec[40])
int libjte_destroy_path_match_list(struct libjte_env *o, int flag)
int list_file_in_jigdo(struct libjte_env *o, char *filename, off_t size, char **realname, unsigned char *checksum)
int jte_add_include(struct libjte_env *o, char *pattern)
static int jte_add_path_match(struct libjte_env *o, char *pattern, int flag)
static int parse_checksum_list(struct libjte_env *o)
static int write_template_desc_entries(struct libjte_env *o, off_t image_len)
int write_jt_header(struct libjte_env *o, FILE *template_file, FILE *jigdo_file)
#define JIGDO_TEMPLATE_VERSION_MD5
int jte_add_mapping(struct libjte_env *o, char *arg)
static char * remap_filename(struct libjte_env *o, char *filename)
static int flush_compressed_chunk(struct libjte_env *o, void *buffer, off_t size)
int jtwrite(struct libjte_env *o, void *buffer, int size, int count)
int jte_add_exclude(struct libjte_env *o, char *pattern)
static int write_template_header(struct libjte_env *o)
static int write_compressed_chunk(struct libjte_env *o, unsigned char *buffer, size_t size)
static void add_file_entry(struct libjte_env *o, char *filename, off_t size, unsigned char *checksum, uint64_t rsyncsum)
static void add_unmatched_entry(struct libjte_env *o, int uncompressed_length)
#define JTE_MAX_ERROR_LIST_LENGTH
int libjte_destroy_path_mapping(struct libjte_env *o, int flag)
static int check_checksum_file_match(struct libjte_env *o, char *filename)
static int check_exclude_by_name(struct libjte_env *o, char *filename, char **matched)
int libjte_destroy_entry_list(struct libjte_env *o, int flag)
static char * file_base_name(char *path)
static char * base64_dump(struct libjte_env *o, unsigned char *buf, size_t buf_size)
static void exit_if_enabled(struct libjte_env *o, int value)
static int template_fwrite(struct libjte_env *o, const void *ptr, size_t size, size_t nmemb, FILE *stream)
#define JIGDO_TEMPLATE_VERSION_SHA256
int write_jt_footer(struct libjte_env *o)
static int flush_bz2_chunk(struct libjte_env *o, void *buffer, off_t size)
int libjte_report_no_mem(struct libjte_env *o, size_t size, int flag)
@ JDT_OBSOLETE_WRITTEN_FILE
@ JDT_OBSOLETE_IMAGE_INFO
@ JDT_OBSOLETE_MATCHED_FILE
@ JDT_WRITTEN_FILE_SHA256
@ JDT_MATCHED_FILE_SHA256
static int add_checksum_entry(struct libjte_env *o, unsigned char *checksum, uint64_t size, char *filename)
static int flush_gzip_chunk(struct libjte_env *o, void *buffer, off_t size)
static uint64_t parse_number(unsigned char in[12])
struct _jigdo_image_entry_sha256 jigdo_image_entry_sha256_t
#define MIN_JIGDO_FILE_SIZE
struct _jigdo_chunk_entry jigdo_chunk_entry_t
static const struct _checksum_data check_algos[]
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)
#define LIBJTE_VERSION_MICRO
#define LIBJTE_VERSION_MAJOR
#define LIBJTE_VERSION_MINOR
uint64_t rsync64(unsigned char *mem, size_t size)
struct _checksum_list_entry * next
unsigned char fileMD5[(128/8)]
unsigned char fileRsync[8]
unsigned char fileSHA256[(256/8)]
unsigned char fileRsync[8]
unsigned char blockLen[4]
unsigned char imageMD5[(128/8)]
unsigned char imageLen[6]
unsigned char imageLen[6]
unsigned char imageSHA256[(256/8)]
unsigned char blockLen[4]
struct _jigdo_msg_entry * next
off_t uncompressed_length
checksum_context_t * iso_context
checksum_context_t * template_context
struct path_match * exclude_list
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]
struct path_mapping * map_list
unsigned char * uncomp_buf
struct path_mapping * next