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