Rizin
unix-like reverse engineering framework and cli tools
zipcmp.c File Reference
#include "config.h"
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <zlib.h>
#include "getopt.h"
#include "zip.h"
#include "compat.h"
#include "diff_output.h"

Go to the source code of this file.

Classes

struct  archive
 
struct  ef
 
struct  entry
 
struct  enum_map_t
 

Macros

#define PROGRAM   "zipcmp"
 
#define USAGE   "usage: %s [-hipqtVv] archive1 archive2\n"
 
#define OPTIONS   "hVCipqstv"
 
#define BOTH_ARE_ZIPS(a)   (a[0].za && a[1].za)
 
#define INC(k)   (i[k]++, list[k] = ((const char *)list[k]) + element_size)
 
#define PRINT(k)
 

Functions

static int comment_compare (const char *c1, size_t l1, const char *c2, size_t l2)
 
static int compare_list (char *const name[2], const void *list[2], const zip_uint64_t list_length[2], int element_size, int(*cmp)(const void *a, const void *b), int(*ignore)(const void *list, int last, const void *other), int(*check)(char *const name[2], const void *a, const void *b), void(*print)(char side, const void *element), void(*start_file)(const void *element))
 
static int compare_zip (char *const zn[])
 
static int ef_compare (char *const name[2], const struct entry *e1, const struct entry *e2)
 
static int ef_order (const void *a, const void *b)
 
static void ef_print (char side, const void *p)
 
static int ef_read (zip_t *za, zip_uint64_t idx, struct entry *e)
 
static int entry_cmp (const void *p1, const void *p2)
 
static int entry_ignore (const void *p1, int last, const void *o)
 
static int entry_paranoia_checks (char *const name[2], const void *p1, const void *p2)
 
static void entry_print (char side, const void *p)
 
static void entry_start_file (const void *p)
 
static const char * map_enum (const enum_map_t *map, uint32_t value)
 
static int is_directory (const char *name)
 
static int list_zip (const char *name, struct archive *a)
 
static int test_file (zip_t *za, zip_uint64_t idx, const char *zipname, const char *filename, zip_uint64_t size, zip_uint32_t crc)
 
int main (int argc, char *const argv[])
 

Variables

const enum_map_t comp_methods []
 
const enum_map_t extra_fields []
 
const char * progname
 
char help_head [] = PROGRAM " (" PACKAGE ") by Dieter Baron and Thomas Klausner\n\n"
 
char help []
 
char version_string []
 
int ignore_case
 
int test_files
 
int paranoid
 
int verbose
 
int have_directory
 
int check_consistency
 
int summary
 
int plus_count = 0
 
int minus_count = 0
 
diff_output_t output
 

Macro Definition Documentation

◆ BOTH_ARE_ZIPS

#define BOTH_ARE_ZIPS (   a)    (a[0].za && a[1].za)

Definition at line 211 of file zipcmp.c.

◆ INC

#define INC (   k)    (i[k]++, list[k] = ((const char *)list[k]) + element_size)

◆ OPTIONS

#define OPTIONS   "hVCipqstv"

Definition at line 208 of file zipcmp.c.

◆ PRINT

#define PRINT (   k)
Value:
do { \
if (ignore && ignore(list[k], i[k] >= list_length[k] - 1, i[1-k] < list_length[1-k] ? list[1-k] : NULL)) { \
break; \
} \
print((k) ? '+' : '-', list[k]); \
(k) ? plus_count++ : minus_count++; \
diff = 1; \
} while (0)
lzma_index ** i
Definition: index.h:629
#define NULL
Definition: cris-opc.c:27
const char * k
Definition: dsignal.c:11
static void list(RzEgg *egg)
Definition: rz-gg.c:52
int plus_count
Definition: zipcmp.c:235
int minus_count
Definition: zipcmp.c:235

◆ PROGRAM

#define PROGRAM   "zipcmp"

Definition at line 185 of file zipcmp.c.

◆ USAGE

#define USAGE   "usage: %s [-hipqtVv] archive1 archive2\n"

Definition at line 187 of file zipcmp.c.

Function Documentation

◆ comment_compare()

static int comment_compare ( const char *  c1,
size_t  l1,
const char *  c2,
size_t  l2 
)
static

Definition at line 585 of file zipcmp.c.

585  {
586  if (l1 != l2)
587  return 1;
588 
589  if (l1 == 0)
590  return 0;
591 
592  if (c1 == NULL || c2 == NULL)
593  return c1 == c2;
594 
595  return memcmp(c1, c2, (size_t)l2);
596 }
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c1
lsl lsr asr ror lsl lsr asr ror lsl lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror lsl lsr asr ror c2

References c1, c2, and NULL.

Referenced by compare_zip(), and entry_paranoia_checks().

◆ compare_list()

static int compare_list ( char *const  name[2],
const void *  list[2],
const zip_uint64_t  list_length[2],
int  element_size,
int(*)(const void *a, const void *b cmp,
int(*)(const void *list, int last, const void *other)  ignore,
int(*)(char *const name[2], const void *a, const void *b check,
void(*)(char side, const void *element)  print,
void(*)(const void *element)  start_file 
)
static

Definition at line 599 of file zipcmp.c.

599  {
600  unsigned int i[2];
601  int j;
602  int diff;
603 
604 #define INC(k) (i[k]++, list[k] = ((const char *)list[k]) + element_size)
605 #define PRINT(k) \
606  do { \
607  if (ignore && ignore(list[k], i[k] >= list_length[k] - 1, i[1-k] < list_length[1-k] ? list[1-k] : NULL)) { \
608  break; \
609  } \
610  print((k) ? '+' : '-', list[k]); \
611  (k) ? plus_count++ : minus_count++; \
612  diff = 1; \
613  } while (0)
614 
615  i[0] = i[1] = 0;
616  diff = 0;
617  while (i[0] < list_length[0] && i[1] < list_length[1]) {
618  int c = cmp(list[0], list[1]);
619 
620  if (c == 0) {
621  if (check) {
622  if (start_file) {
623  start_file(list[0]);
624  }
625  diff |= check(name, list[0], list[1]);
626  if (start_file) {
628  }
629  }
630  INC(0);
631  INC(1);
632  }
633  else if (c < 0) {
634  PRINT(0);
635  INC(0);
636  }
637  else {
638  PRINT(1);
639  INC(1);
640  }
641  }
642 
643  for (j = 0; j < 2; j++) {
644  while (i[j] < list_length[j]) {
645  PRINT(j);
646  INC(j);
647  }
648  }
649 
650  return diff;
651 }
static RzILOpEffect * cmp(cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:942
lzma_check check
Definition: container.h:292
void diff_output_end_file(diff_output_t *output)
Definition: diff_output.c:34
#define c(i)
Definition: sha256.c:43
Definition: z80asm.h:102
diff_output_t output
Definition: zipcmp.c:237
#define PRINT(k)
#define INC(k)

References c, check, cmp(), diff_output_end_file(), i, INC, list(), output, and PRINT.

Referenced by compare_zip(), and ef_compare().

◆ compare_zip()

static int compare_zip ( char *const  zn[])
static

Definition at line 303 of file zipcmp.c.

303  {
304  struct archive a[2];
305  struct entry *e[2];
306  zip_uint64_t n[2];
307  int i;
308  int res;
309 
310  for (i = 0; i < 2; i++) {
311  a[i].name = zn[i];
312  a[i].entry = NULL;
313  a[i].nentry = 0;
314  a[i].za = NULL;
315  a[i].comment = NULL;
316  a[i].comment_length = 0;
317 
318  if (is_directory(zn[i])) {
319 #ifndef HAVE_FTS_H
320  fprintf(stderr, "%s: reading directories not supported\n", progname);
321  exit(2);
322 #else
323  if (list_directory(zn[i], a + i) < 0)
324  exit(2);
325  have_directory = 1;
326  paranoid = 0; /* paranoid checks make no sense for directories, since they compare zip metadata */
327 #endif
328  }
329  else {
330  if (list_zip(zn[i], a + i) < 0)
331  exit(2);
332  }
333  if (a[i].nentry > 0)
334  qsort(a[i].entry, a[i].nentry, sizeof(a[i].entry[0]), entry_cmp);
335  }
336 
338 
339  e[0] = a[0].entry;
340  e[1] = a[1].entry;
341  n[0] = a[0].nentry;
342  n[1] = a[1].nentry;
344 
345  if (paranoid) {
346  if (comment_compare(a[0].comment, a[0].comment_length, a[1].comment, a[1].comment_length) != 0) {
347  if (a[0].comment_length > 0) {
348  diff_output_data(&output, '-', (const zip_uint8_t *)a[0].comment, a[0].comment_length, "archive comment");
349  minus_count++;
350  }
351  if (a[1].comment_length > 0) {
352  diff_output_data(&output, '+', (const zip_uint8_t *)a[1].comment, a[1].comment_length, "archive comment");
353  plus_count++;
354  }
355  res = 1;
356  }
357  }
358 
359  for (i = 0; i < 2; i++) {
360  zip_uint64_t j;
361 
362  if (a[i].za) {
363  zip_close(a[i].za);
364  }
365  for (j = 0; j < a[i].nentry; j++) {
366  free(a[i].entry[j].name);
367  }
368  free(a[i].entry);
369  }
370 
371  if (summary) {
372  printf("%d files removed, %d files added\n", minus_count, plus_count);
373  }
374 
375  switch (res) {
376  case 0:
377  exit(0);
378 
379  case 1:
380  exit(1);
381 
382  default:
383  exit(2);
384  }
385 }
#define e(frag)
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
void diff_output_data(diff_output_t *output, int side, const zip_uint8_t *data, zip_uint64_t data_length, const char *fmt,...)
Definition: diff_output.c:75
void diff_output_init(diff_output_t *output, int verbose, char *const archive_names[])
Definition: diff_output.c:19
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
ZIP_EXTERN int zip_close(zip_t *_Nonnull)
Definition: zip_close.c:52
int n
Definition: mipsasm.c:19
void qsort(void *a, size_t n, size_t es, int(*cmp)(const void *, const void *))
Definition: qsort.h:130
#define a(i)
Definition: sha256.c:41
Definition: zipcmp.c:60
Definition: zipcmp.c:77
const char * comment
Definition: zipcmp.c:84
zip_uint32_t comment_length
Definition: zipcmp.c:85
int verbose
Definition: zipcmp.c:234
static void entry_print(char side, const void *p)
Definition: zipcmp.c:808
static int entry_ignore(const void *p1, int last, const void *o)
Definition: zipcmp.c:752
static int is_directory(const char *name)
Definition: zipcmp.c:419
static int entry_cmp(const void *p1, const void *p2)
Definition: zipcmp.c:729
int have_directory
Definition: zipcmp.c:234
static int compare_list(char *const name[2], const void *list[2], const zip_uint64_t list_length[2], int element_size, int(*cmp)(const void *a, const void *b), int(*ignore)(const void *list, int last, const void *other), int(*check)(char *const name[2], const void *a, const void *b), void(*print)(char side, const void *element), void(*start_file)(const void *element))
Definition: zipcmp.c:599
static void entry_start_file(const void *p)
Definition: zipcmp.c:815
static int comment_compare(const char *c1, size_t l1, const char *c2, size_t l2)
Definition: zipcmp.c:585
static int entry_paranoia_checks(char *const name[2], const void *p1, const void *p2)
Definition: zipcmp.c:779
int paranoid
Definition: zipcmp.c:234
static int list_zip(const char *name, struct archive *a)
Definition: zipcmp.c:526
const char * progname
Definition: zipcmp.c:183
int summary
Definition: zipcmp.c:234
uint64_t zip_uint64_t
Definition: zipconf.h:39
uint8_t zip_uint8_t
Definition: zipconf.h:33
zip_t * za
Definition: ziptool.c:79

References a, entry::comment, comment_compare(), entry::comment_length, compare_list(), diff_output_data(), diff_output_init(), e, entry_cmp(), entry_ignore(), entry_paranoia_checks(), entry_print(), entry_start_file(), test-lz4-list::exit, free(), have_directory, i, is_directory(), list_zip(), minus_count, n, NULL, output, paranoid, plus_count, printf(), progname, qsort(), summary, verbose, za, and zip_close().

Referenced by main().

◆ ef_compare()

static int ef_compare ( char *const  name[2],
const struct entry e1,
const struct entry e2 
)
static

Definition at line 690 of file zipcmp.c.

690  {
691  struct ef *ef[2];
692  zip_uint64_t n[2];
693 
694  ef[0] = e1->extra_fields;
695  ef[1] = e2->extra_fields;
696  n[0] = e1->n_extra_fields;
697  n[1] = e2->n_extra_fields;
698 
699  return compare_list(name, (const void **)ef, n, sizeof(struct ef), ef_order, NULL, NULL, ef_print, NULL);
700 }
Definition: zipcmp.c:69
struct ef * extra_fields
Definition: zipcmp.c:82
zip_uint16_t n_extra_fields
Definition: zipcmp.c:83
static void ef_print(char side, const void *p)
Definition: zipcmp.c:721
static int ef_order(const void *a, const void *b)
Definition: zipcmp.c:704

References compare_list(), ef_order(), ef_print(), entry::extra_fields, n, entry::n_extra_fields, and NULL.

Referenced by entry_paranoia_checks().

◆ ef_order()

static int ef_order ( const void *  a,
const void *  b 
)
static

Definition at line 704 of file zipcmp.c.

704  {
705  const struct ef *a, *b;
706 
707  a = (struct ef *)ap;
708  b = (struct ef *)bp;
709 
710  if (a->flags != b->flags)
711  return a->flags - b->flags;
712  if (a->id != b->id)
713  return a->id - b->id;
714  if (a->size != b->size)
715  return a->size - b->size;
716  return memcmp(a->data, b->data, a->size);
717 }
#define b(i)
Definition: sha256.c:42

References a, and b.

Referenced by ef_compare(), and ef_read().

◆ ef_print()

static void ef_print ( char  side,
const void *  p 
)
static

Definition at line 721 of file zipcmp.c.

721  {
722  const struct ef *ef = (struct ef *)p;
723 
724  diff_output_data(&output, side, ef->data, ef->size, " %s extra field %s", ef->flags == ZIP_FL_LOCAL ? "local" : "central", map_enum(extra_fields, ef->id));
725 }
void * p
Definition: libc.cpp:67
#define ZIP_FL_LOCAL
Definition: zip.h:85
zip_uint16_t size
Definition: zipcmp.c:73
zip_uint16_t id
Definition: zipcmp.c:72
const zip_uint8_t * data
Definition: zipcmp.c:74
zip_uint16_t flags
Definition: zipcmp.c:71
static const char * map_enum(const enum_map_t *map, uint32_t value)
Definition: zipcmp.c:864
const enum_map_t extra_fields[]
Definition: zipcmp.c:124

References ef::data, diff_output_data(), extra_fields, ef::flags, ef::id, map_enum(), output, p, ef::size, and ZIP_FL_LOCAL.

Referenced by ef_compare().

◆ ef_read()

static int ef_read ( zip_t za,
zip_uint64_t  idx,
struct entry e 
)
static

Definition at line 655 of file zipcmp.c.

655  {
656  zip_int16_t n_local, n_central;
657  zip_uint16_t i;
658 
659  if ((n_local = zip_file_extra_fields_count(za, idx, ZIP_FL_LOCAL)) < 0 || (n_central = zip_file_extra_fields_count(za, idx, ZIP_FL_CENTRAL)) < 0) {
660  return -1;
661  }
662 
663  e->n_extra_fields = (zip_uint16_t)(n_local + n_central);
664 
665  if ((e->extra_fields = (struct ef *)malloc(sizeof(e->extra_fields[0]) * e->n_extra_fields)) == NULL)
666  return -1;
667 
668  for (i = 0; i < n_local; i++) {
669  e->extra_fields[i].name = e->name;
670  e->extra_fields[i].data = zip_file_extra_field_get(za, idx, i, &e->extra_fields[i].id, &e->extra_fields[i].size, ZIP_FL_LOCAL);
671  if (e->extra_fields[i].data == NULL)
672  return -1;
673  e->extra_fields[i].flags = ZIP_FL_LOCAL;
674  }
675  for (; i < e->n_extra_fields; i++) {
676  e->extra_fields[i].name = e->name;
677  e->extra_fields[i].data = zip_file_extra_field_get(za, idx, (zip_uint16_t)(i - n_local), &e->extra_fields[i].id, &e->extra_fields[i].size, ZIP_FL_CENTRAL);
678  if (e->extra_fields[i].data == NULL)
679  return -1;
680  e->extra_fields[i].flags = ZIP_FL_CENTRAL;
681  }
682 
683  qsort(e->extra_fields, e->n_extra_fields, sizeof(e->extra_fields[0]), ef_order);
684 
685  return 0;
686 }
ZIP_EXTERN const zip_uint8_t *_Nullable zip_file_extra_field_get(zip_t *_Nonnull, zip_uint64_t, zip_uint16_t, zip_uint16_t *_Nullable, zip_uint16_t *_Nullable, zip_flags_t)
ZIP_EXTERN zip_int16_t zip_file_extra_fields_count(zip_t *_Nonnull, zip_uint64_t, zip_flags_t)
#define ZIP_FL_CENTRAL
Definition: zip.h:86
void * malloc(size_t size)
Definition: malloc.c:123
int idx
Definition: setup.py:197
int16_t zip_int16_t
Definition: zipconf.h:34
uint16_t zip_uint16_t
Definition: zipconf.h:35

References e, ef_order(), i, setup::idx, malloc(), NULL, qsort(), za, zip_file_extra_field_get(), zip_file_extra_fields_count(), ZIP_FL_CENTRAL, and ZIP_FL_LOCAL.

Referenced by list_zip().

◆ entry_cmp()

static int entry_cmp ( const void *  p1,
const void *  p2 
)
static

Definition at line 729 of file zipcmp.c.

729  {
730  const struct entry *e1, *e2;
731  int c;
732 
733  e1 = (struct entry *)p1;
734  e2 = (struct entry *)p2;
735 
736  if ((c = (ignore_case ? strcasecmp : strcmp)(e1->name, e2->name)) != 0)
737  return c;
738  if (e1->size != e2->size) {
739  if (e1->size > e2->size)
740  return 1;
741  else
742  return -1;
743  }
744  if (e1->crc != e2->crc)
745  return (int)e1->crc - (int)e2->crc;
746 
747  return 0;
748 }
static int
Definition: sfsocketcall.h:114
zip_uint64_t size
Definition: zipcmp.c:79
zip_uint32_t crc
Definition: zipcmp.c:80
char * name
Definition: zipcmp.c:78
int ignore_case
Definition: zipcmp.c:234

References c, entry::crc, ignore_case, int, entry::name, and entry::size.

Referenced by compare_zip().

◆ entry_ignore()

static int entry_ignore ( const void *  p1,
int  last,
const void *  o 
)
static

Definition at line 752 of file zipcmp.c.

752  {
753  const struct entry *e = (const struct entry *)p;
754  const struct entry *other = (const struct entry *)o;
755 
756  size_t length = strlen(e[0].name);
757 
758  if (length == 0 || e[0].name[length - 1] != '/') {
759  /* not a directory */
760  return 0;
761  }
762 
763  if (other != NULL && strlen(other->name) > length && strncmp(other->name, e[0].name, length) == 0) {
764  /* not empty in other archive */
765  return 1;
766  }
767 
768  if (last || (strlen(e[1].name) < length || strncmp(e[0].name, e[1].name, length) != 0)) {
769  /* empty in this archive */
770  return 0;
771  }
772 
773  /* not empty in this archive */
774  return 1;
775 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133

References e, length, entry::name, NULL, and p.

Referenced by compare_zip().

◆ entry_paranoia_checks()

static int entry_paranoia_checks ( char *const  name[2],
const void *  p1,
const void *  p2 
)
static

Definition at line 779 of file zipcmp.c.

779  {
780  const struct entry *e1, *e2;
781  int ret;
782 
783  e1 = (struct entry *)p1;
784  e2 = (struct entry *)p2;
785 
786  ret = 0;
787 
788  if (e1->comp_method != e2->comp_method) {
789  diff_output(&output, '-', " compression method %s", map_enum(comp_methods, e1->comp_method));
790  diff_output(&output, '+', " compression method %s", map_enum(comp_methods, e2->comp_method));
791  ret = 1;
792  }
793 
794  if (ef_compare(name, e1, e2) != 0) {
795  ret = 1;
796  }
797 
798  if (comment_compare(e1->comment, e1->comment_length, e2->comment, e2->comment_length) != 0) {
799  diff_output_data(&output, '-', (const zip_uint8_t *)e1->comment, e1->comment_length, " comment");
800  diff_output_data(&output, '+', (const zip_uint8_t *)e2->comment, e2->comment_length, " comment");
801  ret = 1;
802  }
803 
804  return ret;
805 }
void diff_output(diff_output_t *output, int side, const char *fmt,...)
Definition: diff_output.c:38
zip_uint32_t comp_method
Definition: zipcmp.c:81
static int ef_compare(char *const name[2], const struct entry *e1, const struct entry *e2)
Definition: zipcmp.c:690
const enum_map_t comp_methods[]
Definition: zipcmp.c:94

References entry::comment, comment_compare(), entry::comment_length, entry::comp_method, comp_methods, diff_output(), diff_output_data(), ef_compare(), map_enum(), and output.

Referenced by compare_zip().

◆ entry_print()

static void entry_print ( char  side,
const void *  p 
)
static

Definition at line 808 of file zipcmp.c.

808  {
809  const struct entry *e = (struct entry *)p;
810 
811  diff_output_file(&output, side, e->name, e->size, e->crc);
812 }
void diff_output_file(diff_output_t *output, char side, const char *name, zip_uint64_t size, zip_uint32_t crc)
Definition: diff_output.c:59

References diff_output_file(), e, output, and p.

Referenced by compare_zip().

◆ entry_start_file()

static void entry_start_file ( const void *  p)
static

Definition at line 815 of file zipcmp.c.

815  {
816  const struct entry *e = (struct entry *)p;
817 
818  diff_output_start_file(&output, e->name, e->size, e->crc);
819 }
void diff_output_start_file(diff_output_t *output, const char *name, zip_uint64_t size, zip_uint32_t crc)
Definition: diff_output.c:28

References diff_output_start_file(), e, output, and p.

Referenced by compare_zip().

◆ is_directory()

static int is_directory ( const char *  name)
static

Definition at line 419 of file zipcmp.c.

419  {
420  struct stat st;
421 
422  if (stat(name, &st) < 0)
423  return 0;
424 
425  return S_ISDIR(st.st_mode);
426 }
#define S_ISDIR(mode)
Definition: compat.h:187
static stat
Definition: sflib.h:131
Definition: sftypes.h:80

References S_ISDIR, and stat.

Referenced by compare_zip().

◆ list_zip()

static int list_zip ( const char *  name,
struct archive a 
)
static

Definition at line 526 of file zipcmp.c.

526  {
527  zip_t *za;
528  int err;
529  struct zip_stat st;
530  unsigned int i;
531 
532  if ((za = zip_open(name, check_consistency ? ZIP_CHECKCONS : 0, &err)) == NULL) {
535  fprintf(stderr, "%s: cannot open zip archive '%s': %s\n", progname, name, zip_error_strerror(&error));
537  return -1;
538  }
539 
540  a->za = za;
541  a->nentry = (zip_uint64_t)zip_get_num_entries(za, 0);
542 
543  if (a->nentry == 0)
544  a->entry = NULL;
545  else {
546  if ((a->nentry > SIZE_MAX / sizeof(a->entry[0])) || (a->entry = (struct entry *)malloc(sizeof(a->entry[0]) * a->nentry)) == NULL) {
547  fprintf(stderr, "%s: malloc failure\n", progname);
548  exit(1);
549  }
550 
551  for (i = 0; i < a->nentry; i++) {
552  zip_stat_index(za, i, 0, &st);
553  a->entry[i].name = strdup(st.name);
554  a->entry[i].size = st.size;
555  a->entry[i].crc = st.crc;
556  if (test_files)
557  test_file(za, i, name, st.name, st.size, st.crc);
558  if (paranoid) {
559  a->entry[i].comp_method = st.comp_method;
560  ef_read(za, i, a->entry + i);
561  a->entry[i].comment = zip_file_get_comment(za, i, &a->entry[i].comment_length, 0);
562  }
563  else {
564  a->entry[i].comp_method = 0;
565  a->entry[i].n_extra_fields = 0;
566  }
567  }
568 
569  if (paranoid) {
570  int length;
571  a->comment = zip_get_archive_comment(za, &length, 0);
572  a->comment_length = (size_t)length;
573  }
574  else {
575  a->comment = NULL;
576  a->comment_length = 0;
577  }
578  }
579 
580  return 0;
581 }
static bool err
Definition: armass.c:435
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int)
Definition: zip_error.c:66
#define ZIP_CHECKCONS
Definition: zip.h:69
ZIP_EXTERN const char *_Nullable zip_get_archive_comment(zip_t *_Nonnull, int *_Nullable, zip_flags_t)
ZIP_EXTERN const char *_Nullable zip_file_get_comment(zip_t *_Nonnull, zip_uint64_t, zip_uint32_t *_Nullable, zip_flags_t)
ZIP_EXTERN void zip_error_fini(zip_error_t *_Nonnull)
Definition: zip_error.c:52
ZIP_EXTERN zip_t *_Nullable zip_open(const char *_Nonnull, int, int *_Nullable)
Definition: zip_open.c:54
ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull)
ZIP_EXTERN const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull)
ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *_Nonnull, zip_flags_t)
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
int size_t
Definition: sftypes.h:40
#define SIZE_MAX
char name[1]
Definition: z80asm.h:104
Definition: zip.h:284
Definition: zip.h:300
Definition: zipint.h:278
void error(const char *msg)
Definition: untgz.c:593
static int test_file(zip_t *za, zip_uint64_t idx, const char *zipname, const char *filename, zip_uint64_t size, zip_uint32_t crc)
Definition: zipcmp.c:823
int test_files
Definition: zipcmp.c:234
static int ef_read(zip_t *za, zip_uint64_t idx, struct entry *e)
Definition: zipcmp.c:655
int check_consistency
Definition: zipcmp.c:234

References a, check_consistency, zip_stat::comp_method, zip_stat::crc, ef_read(), err, error(), test-lz4-list::exit, i, length, malloc(), zip_stat::name, NULL, paranoid, progname, zip_stat::size, SIZE_MAX, strdup(), test_file(), test_files, za, ZIP_CHECKCONS, zip_error_fini(), zip_error_init_with_code(), zip_error_strerror(), zip_file_get_comment(), zip_get_archive_comment(), zip_get_num_entries(), zip_open(), and zip_stat_index().

Referenced by compare_zip().

◆ main()

int main ( int  argc,
char *const  argv[] 
)

Definition at line 241 of file zipcmp.c.

241  {
242  int c;
243 
244  progname = argv[0];
245 
246  ignore_case = 0;
247  test_files = 0;
248  check_consistency = 0;
249  paranoid = 0;
250  have_directory = 0;
251  verbose = 1;
252  summary = 0;
253 
254  while ((c = getopt(argc, argv, OPTIONS)) != -1) {
255  switch (c) {
256  case 'C':
257  check_consistency = 1;
258  break;
259  case 'i':
260  ignore_case = 1;
261  break;
262  case 'p':
263  paranoid = 1;
264  break;
265  case 'q':
266  verbose = 0;
267  break;
268  case 's':
269  summary = 1;
270  break;
271  case 't':
272  test_files = 1;
273  break;
274  case 'v':
275  verbose = 1;
276  break;
277 
278  case 'h':
279  fputs(help_head, stdout);
281  fputs(help, stdout);
282  exit(0);
283  case 'V':
284  fputs(version_string, stdout);
285  exit(0);
286 
287  default:
288  fprintf(stderr, USAGE, progname);
289  exit(2);
290  }
291  }
292 
293  if (argc != optind + 2) {
294  fprintf(stderr, USAGE, progname);
295  exit(2);
296  }
297 
298  exit((compare_zip(argv + optind) == 0) ? 0 : 1);
299 }
int getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.h:20
int optind
Definition: getopt.h:6
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
char help[]
Definition: zipcmp.c:191
static int compare_zip(char *const zn[])
Definition: zipcmp.c:303
#define USAGE
Definition: zipcmp.c:187
char version_string[]
Definition: zipcmp.c:204
char help_head[]
Definition: zipcmp.c:189
#define OPTIONS
Definition: zipcmp.c:208

References argv, c, check_consistency, compare_zip(), test-lz4-list::exit, getopt(), have_directory, help, help_head, ignore_case, optind, OPTIONS, paranoid, printf(), progname, summary, test_files, USAGE, verbose, and version_string.

◆ map_enum()

static const char * map_enum ( const enum_map_t map,
uint32_t  value 
)
static

Definition at line 864 of file zipcmp.c.

864  {
865  static char unknown[16];
866  size_t i = 0;
867 
868  while (map[i].value < UINT32_MAX) {
869  if (map[i].value == value) {
870  return map[i].name;
871  }
872  i++;
873  }
874 
875  snprintf(unknown, sizeof(unknown), "unknown (%u)", value);
876  unknown[sizeof(unknown) - 1] = '\0';
877 
878  return unknown;
879 }
static int value
Definition: cmd_api.c:93
size_t map(int syms, int left, int len)
Definition: enough.c:237
snprintf
Definition: kernel.h:364
#define UINT32_MAX

References i, map(), snprintf, UINT32_MAX, and value.

Referenced by ef_print(), and entry_paranoia_checks().

◆ test_file()

static int test_file ( zip_t za,
zip_uint64_t  idx,
const char *  zipname,
const char *  filename,
zip_uint64_t  size,
zip_uint32_t  crc 
)
static

Definition at line 823 of file zipcmp.c.

823  {
824  zip_file_t *zf;
825  char buf[8192];
826  zip_uint64_t nsize;
827  zip_int64_t n;
828  zip_uint32_t ncrc;
829 
830  if ((zf = zip_fopen_index(za, idx, 0)) == NULL) {
831  fprintf(stderr, "%s: %s: cannot open file %s (index %" PRIu64 "): %s\n", progname, zipname, filename, idx, zip_strerror(za));
832  return -1;
833  }
834 
835  ncrc = (zip_uint32_t)crc32(0, NULL, 0);
836  nsize = 0;
837 
838  while ((n = zip_fread(zf, buf, sizeof(buf))) > 0) {
839  nsize += (zip_uint64_t)n;
840  ncrc = (zip_uint32_t)crc32(ncrc, (const Bytef *)buf, (unsigned int)n);
841  }
842 
843  if (n < 0) {
844  fprintf(stderr, "%s: %s: error reading file %s (index %" PRIu64 "): %s\n", progname, zipname, filename, idx, zip_file_strerror(zf));
845  zip_fclose(zf);
846  return -1;
847  }
848 
849  zip_fclose(zf);
850 
851  if (nsize != size) {
852  fprintf(stderr, "%s: %s: file %s (index %" PRIu64 "): unexpected length %" PRId64 " (should be %" PRId64 ")\n", progname, zipname, filename, idx, nsize, size);
853  return -2;
854  }
855  if (ncrc != crc) {
856  fprintf(stderr, "%s: %s: file %s (index %" PRIu64 "): unexpected length %x (should be %x)\n", progname, zipname, filename, idx, ncrc, crc);
857  return -2;
858  }
859 
860  return 0;
861 }
voidpf void uLong size
Definition: ioapi.h:138
const char * filename
Definition: ioapi.h:137
voidpf void * buf
Definition: ioapi.h:138
#define PRIu64
Definition: macros.h:18
#define PRId64
Definition: macros.h:17
ZIP_EXTERN int zip_fclose(zip_file_t *_Nonnull)
Definition: zip_fclose.c:41
ZIP_EXTERN const char *_Nonnull zip_file_strerror(zip_file_t *_Nonnull)
ZIP_EXTERN zip_int64_t zip_fread(zip_file_t *_Nonnull, void *_Nonnull, zip_uint64_t)
Definition: zip_fread.c:39
ZIP_EXTERN zip_file_t *_Nullable zip_fopen_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t)
ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull)
Definition: zip_strerror.c:39
Byte FAR Bytef
Definition: zconf.h:400
uint32_t zip_uint32_t
Definition: zipconf.h:37
int64_t zip_int64_t
Definition: zipconf.h:38
unsigned long ZEXPORT crc32(unsigned long crc, const unsigned char FAR *buf, uInt len)
Definition: crc32.c:1063

References entry::crc, crc32(), setup::idx, int, n, NULL, PRId64, PRIu64, progname, za, zip_fclose(), zip_file_strerror(), zip_fopen_index(), zip_fread(), and zip_strerror().

Referenced by list_zip().

Variable Documentation

◆ check_consistency

int check_consistency

Definition at line 234 of file zipcmp.c.

Referenced by list_zip(), and main().

◆ comp_methods

const enum_map_t comp_methods[]
Initial value:
= {
{ 0, "Stored (no compression)" },
{ 1, "Shrunk" },
{ 2, "Reduced with compression factor 1" },
{ 3, "Reduced with compression factor 2" },
{ 4, "Reduced with compression factor 3" },
{ 5, "Reduced with compression factor 4" },
{ 6, "Imploded" },
{ 7, "Reserved for Tokenizing compression algorithm" },
{ 8, "Deflated" },
{ 9, "Enhanced Deflating using Deflate64(tm)" },
{ 10, "PKWARE Data Compression Library Imploding (old IBM TERSE)" },
{ 11, "11 (Reserved by PKWARE)" },
{ 12, "BZIP2" },
{ 13, "13 (Reserved by PKWARE)" },
{ 14, "LZMA (EFS)" },
{ 15, "15 (Reserved by PKWARE)" },
{ 16, "16 (Reserved by PKWARE)" },
{ 17, "17 (Reserved by PKWARE)" },
{ 18, "IBM TERSE (new)" },
{ 19, "IBM LZ77 z Architecture (PFS)" },
{ 20, "Zstandard compressed data (obsolete)" },
{ 93, "Zstandard compressed data" },
{ 95, "XZ compressed data" },
{ 97, "WavPack compressed data" },
{ 98, "PPMd version I, Rev 1" },
{ 99, "WinZIP AES Encryption" },
}

Definition at line 94 of file zipcmp.c.

Referenced by entry_paranoia_checks().

◆ extra_fields

const enum_map_t extra_fields[]

Definition at line 124 of file zipcmp.c.

Referenced by ef_print().

◆ have_directory

int have_directory

Definition at line 234 of file zipcmp.c.

Referenced by compare_zip(), and main().

◆ help

char help[] ( void  )
Initial value:
= "\n\
-h display this help message\n\
-C check archive consistencies\n\
-i compare names ignoring case distinctions\n\
-p compare as many details as possible\n\
-q be quiet\n\
-s print a summary\n\
-t test zip files (compare file contents to checksum)\n\
-V display version number\n\
-v be verbose (print differences, default)\n\
\n\
Report bugs to <libzip@nih.at>.\n"

Definition at line 191 of file zipcmp.c.

Referenced by main().

◆ help_head

char help_head[] = PROGRAM " (" PACKAGE ") by Dieter Baron and Thomas Klausner\n\n"

Definition at line 189 of file zipcmp.c.

Referenced by main().

◆ ignore_case

int ignore_case

Definition at line 234 of file zipcmp.c.

Referenced by entry_cmp(), main(), rz_search_keyword_new_str(), and rz_search_keyword_new_wide().

◆ minus_count

int minus_count = 0

Definition at line 235 of file zipcmp.c.

Referenced by compare_zip().

◆ output

◆ paranoid

int paranoid

Definition at line 234 of file zipcmp.c.

Referenced by compare_zip(), list_zip(), and main().

◆ plus_count

int plus_count = 0

Definition at line 235 of file zipcmp.c.

Referenced by compare_zip().

◆ progname

const char* progname

Definition at line 183 of file zipcmp.c.

Referenced by compare_zip(), list_zip(), main(), and test_file().

◆ summary

◆ test_files

int test_files

Definition at line 234 of file zipcmp.c.

Referenced by list_zip(), and main().

◆ verbose

int verbose

Definition at line 234 of file zipcmp.c.

Referenced by compare_zip(), and main().

◆ version_string

char version_string[]
Initial value:
= PROGRAM " (" PACKAGE " " VERSION ")\n\
Copyright (C) 2003-2022 Dieter Baron and Thomas Klausner\n\
" PACKAGE " comes with ABSOLUTELY NO WARRANTY, to the extent permitted by law.\n"
#define VERSION
Definition: config.h:54
#define PACKAGE
Definition: config.h:59
#define PROGRAM
Definition: zipcmp.c:185

Definition at line 204 of file zipcmp.c.

Referenced by main().