Rizin
unix-like reverse engineering framework and cli tools
zipmerge.c File Reference
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "config.h"
#include "getopt.h"
#include "zip.h"

Go to the source code of this file.

Macros

#define PROGRAM   "zipmerge"
 
#define USAGE   "usage: %s [-DhIiSsV] target-zip zip...\n"
 
#define OPTIONS   "hVDiIsS"
 
#define CONFIRM_ALL_YES   0x001
 
#define CONFIRM_ALL_NO   0x002
 
#define CONFIRM_SAME_YES   0x010
 
#define CONFIRM_SAME_NO   0x020
 

Functions

static int confirm_replace (zip_t *, const char *, zip_uint64_t, zip_t *, const char *, zip_uint64_t)
 
static zip_tmerge_zip (zip_t *, const char *, const char *)
 
int main (int argc, char *argv[])
 

Variables

char * progname
 
char help_head [] = PROGRAM " (" PACKAGE ") by Dieter Baron and Thomas Klausner\n\n"
 
char help []
 
char version_string []
 
int confirm
 
zip_flags_t name_flags
 

Macro Definition Documentation

◆ CONFIRM_ALL_NO

#define CONFIRM_ALL_NO   0x002

Definition at line 75 of file zipmerge.c.

◆ CONFIRM_ALL_YES

#define CONFIRM_ALL_YES   0x001

Definition at line 74 of file zipmerge.c.

◆ CONFIRM_SAME_NO

#define CONFIRM_SAME_NO   0x020

Definition at line 77 of file zipmerge.c.

◆ CONFIRM_SAME_YES

#define CONFIRM_SAME_YES   0x010

Definition at line 76 of file zipmerge.c.

◆ OPTIONS

#define OPTIONS   "hVDiIsS"

Definition at line 72 of file zipmerge.c.

◆ PROGRAM

#define PROGRAM   "zipmerge"

Definition at line 51 of file zipmerge.c.

◆ USAGE

#define USAGE   "usage: %s [-DhIiSsV] target-zip zip...\n"

Definition at line 53 of file zipmerge.c.

Function Documentation

◆ confirm_replace()

static int confirm_replace ( zip_t za,
const char *  tname,
zip_uint64_t  it,
zip_t zs,
const char *  sname,
zip_uint64_t  is 
)
static

Definition at line 174 of file zipmerge.c.

174  {
175  char line[1024];
176  struct zip_stat st, ss;
177 
178  if (confirm & CONFIRM_ALL_YES)
179  return 1;
180  else if (confirm & CONFIRM_ALL_NO)
181  return 0;
182 
183  if (zip_stat_index(za, it, ZIP_FL_UNCHANGED, &st) < 0) {
184  fprintf(stderr, "%s: cannot stat file %" PRIu64 " in '%s': %s\n", progname, it, tname, zip_strerror(za));
185  return -1;
186  }
187  if (zip_stat_index(zs, is, 0, &ss) < 0) {
188  fprintf(stderr, "%s: cannot stat file %" PRIu64 " in '%s': %s\n", progname, is, sname, zip_strerror(zs));
189  return -1;
190  }
191 
192  if (st.size == ss.size && st.crc == ss.crc) {
194  return 1;
195  else if (confirm & CONFIRM_SAME_NO)
196  return 0;
197  }
198 
199  printf("replace '%s' (%" PRIu64 " / %08x) in `%s'\n"
200  " with '%s' (%" PRIu64 " / %08x) from `%s'? ",
201  st.name, st.size, st.crc, tname, ss.name, ss.size, ss.crc, sname);
202  fflush(stdout);
203 
204  if (fgets(line, sizeof(line), stdin) == NULL) {
205  fprintf(stderr, "%s: read error from stdin: %s\n", progname, strerror(errno));
206  return -1;
207  }
208 
209  if (tolower((unsigned char)line[0]) == 'y')
210  return 1;
211 
212  return 0;
213 }
#define NULL
Definition: cris-opc.c:27
_Use_decl_annotations_ int __cdecl printf(const char *const _Format,...)
Definition: cs_driver.c:93
#define PRIu64
Definition: macros.h:18
ZIP_EXTERN int zip_stat_index(zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_stat_t *_Nonnull)
#define ZIP_FL_UNCHANGED
Definition: zip.h:79
ZIP_EXTERN const char *_Nonnull zip_strerror(zip_t *_Nonnull)
Definition: zip_strerror.c:39
line
Definition: setup.py:34
#define tolower(c)
Definition: safe-ctype.h:149
Definition: zip.h:300
int confirm
Definition: zipmerge.c:79
#define CONFIRM_ALL_NO
Definition: zipmerge.c:75
#define CONFIRM_SAME_NO
Definition: zipmerge.c:77
#define CONFIRM_SAME_YES
Definition: zipmerge.c:76
#define CONFIRM_ALL_YES
Definition: zipmerge.c:74
char * progname
Definition: zipmerge.c:49
zip_t * za
Definition: ziptool.c:79

References confirm, CONFIRM_ALL_NO, CONFIRM_ALL_YES, CONFIRM_SAME_NO, CONFIRM_SAME_YES, zip_stat::crc, setup::line, zip_stat::name, NULL, printf(), PRIu64, progname, zip_stat::size, tolower, za, ZIP_FL_UNCHANGED, zip_stat_index(), and zip_strerror().

Referenced by merge_zip().

◆ main()

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

Definition at line 87 of file zipmerge.c.

87  {
88  zip_t *za;
89  zip_t **zs;
90  int c, err;
91  unsigned int i, n;
92  char *tname;
93 
94  progname = argv[0];
95 
97  name_flags = 0;
98 
99  while ((c = getopt(argc, argv, OPTIONS)) != -1) {
100  switch (c) {
101  case 'D':
103  break;
104  case 'i':
106  break;
107  case 'I':
109  break;
110  case 's':
113  break;
114  case 'S':
117  break;
118 
119  case 'h':
120  fputs(help_head, stdout);
122  fputs(help, stdout);
123  exit(0);
124  case 'V':
125  fputs(version_string, stdout);
126  exit(0);
127 
128  default:
129  fprintf(stderr, USAGE, progname);
130  exit(2);
131  }
132  }
133 
134  if (argc < optind + 2) {
135  fprintf(stderr, USAGE, progname);
136  exit(2);
137  }
138 
139  tname = argv[optind++];
140  argv += optind;
141 
142  n = (unsigned int)(argc - optind);
143  if ((zs = (zip_t **)malloc(sizeof(zs[0]) * n)) == NULL) {
144  fprintf(stderr, "%s: out of memory\n", progname);
145  exit(1);
146  }
147 
148  if ((za = zip_open(tname, ZIP_CREATE, &err)) == NULL) {
151  fprintf(stderr, "%s: can't open zip archive '%s': %s\n", progname, tname, zip_error_strerror(&error));
153  exit(1);
154  }
155 
156  for (i = 0; i < n; i++) {
157  if ((zs[i] = merge_zip(za, tname, argv[i])) == NULL)
158  exit(1);
159  }
160 
161  if (zip_close(za) < 0) {
162  fprintf(stderr, "%s: cannot write zip archive '%s': %s\n", progname, tname, zip_strerror(za));
163  exit(1);
164  }
165 
166  for (i = 0; i < n; i++)
167  zip_close(zs[i]);
168 
169  exit(0);
170 }
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
int getopt(int nargc, char *const nargv[], const char *ostr)
Definition: getopt.h:20
int optind
Definition: getopt.h:6
ZIP_EXTERN void zip_error_init_with_code(zip_error_t *_Nonnull, int)
Definition: zip_error.c:66
#define ZIP_FL_NODIR
Definition: zip.h:77
#define ZIP_CREATE
Definition: zip.h:67
ZIP_EXTERN int zip_close(zip_t *_Nonnull)
Definition: zip_close.c:52
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 const char *_Nonnull zip_error_strerror(zip_error_t *_Nonnull)
#define ZIP_FL_NOCASE
Definition: zip.h:76
void * malloc(size_t size)
Definition: malloc.c:123
static static fork const void static count static fd const char const char static newpath char char argv
Definition: sflib.h:40
int n
Definition: mipsasm.c:19
static int
Definition: sfsocketcall.h:114
#define c(i)
Definition: sha256.c:43
Definition: zip.h:284
Definition: zipint.h:278
void error(const char *msg)
Definition: untgz.c:593
char help[]
Definition: zipmerge.c:57
static zip_t * merge_zip(zip_t *, const char *, const char *)
Definition: zipmerge.c:217
zip_flags_t name_flags
Definition: zipmerge.c:80
#define USAGE
Definition: zipmerge.c:53
char version_string[]
Definition: zipmerge.c:68
char help_head[]
Definition: zipmerge.c:55
#define OPTIONS
Definition: zipmerge.c:72

References argv, c, confirm, CONFIRM_ALL_YES, CONFIRM_SAME_NO, CONFIRM_SAME_YES, err, error(), test-lz4-list::exit, getopt(), help, help_head, i, int, malloc(), merge_zip(), n, name_flags, NULL, optind, OPTIONS, printf(), progname, USAGE, version_string, za, zip_close(), ZIP_CREATE, zip_error_fini(), zip_error_init_with_code(), zip_error_strerror(), ZIP_FL_NOCASE, ZIP_FL_NODIR, zip_open(), and zip_strerror().

◆ merge_zip()

static zip_t * merge_zip ( zip_t za,
const char *  tname,
const char *  sname 
)
static

Definition at line 217 of file zipmerge.c.

217  {
218  zip_t *zs;
220  zip_int64_t ret, idx;
221  zip_uint64_t i;
222  int err;
223  const char *fname;
224 
225  if ((zs = zip_open(sname, 0, &err)) == NULL) {
228  fprintf(stderr, "%s: can't open zip archive '%s': %s\n", progname, sname, zip_error_strerror(&error));
230  return NULL;
231  }
232 
233  ret = zip_get_num_entries(zs, 0);
234  if (ret < 0) {
235  fprintf(stderr, "%s: cannot get number of entries for '%s': %s\n", progname, sname, zip_strerror(za));
236  return NULL;
237  }
238  for (i = 0; i < (zip_uint64_t)ret; i++) {
239  fname = zip_get_name(zs, i, 0);
240 
241  if ((idx = zip_name_locate(za, fname, name_flags)) >= 0) {
242  switch (confirm_replace(za, tname, (zip_uint64_t)idx, zs, sname, i)) {
243  case 0:
244  break;
245 
246  case 1:
247  if ((source = zip_source_zip(za, zs, i, 0, 0, 0)) == NULL || zip_replace(za, (zip_uint64_t)idx, source) < 0) {
249  fprintf(stderr, "%s: cannot replace '%s' in `%s': %s\n", progname, fname, tname, zip_strerror(za));
250  zip_close(zs);
251  return NULL;
252  }
253  break;
254 
255  case -1:
256  zip_close(zs);
257  return NULL;
258 
259  default:
260  fprintf(stderr,
261  "%s: internal error: "
262  "unexpected return code from confirm (%d)\n",
263  progname, err);
264  zip_close(zs);
265  return NULL;
266  }
267  }
268  else {
269  if ((source = zip_source_zip(za, zs, i, 0, 0, 0)) == NULL || zip_add(za, fname, source) < 0) {
271  fprintf(stderr, "%s: cannot add '%s' to `%s': %s\n", progname, fname, tname, zip_strerror(za));
272  zip_close(zs);
273  return NULL;
274  }
275  }
276  }
277 
278  return zs;
279 }
ZIP_EXTERN zip_int64_t zip_name_locate(zip_t *_Nonnull, const char *_Nonnull, zip_flags_t)
ZIP_EXTERN zip_int64_t zip_add(zip_t *_Nonnull, const char *_Nonnull, zip_source_t *_Nonnull)
Definition: zip_add.c:47
ZIP_EXTERN const char *_Nullable zip_get_name(zip_t *_Nonnull, zip_uint64_t, zip_flags_t)
Definition: zip_get_name.c:41
ZIP_EXTERN zip_source_t *_Nullable zip_source_zip(zip_t *_Nonnull, zip_t *_Nonnull, zip_uint64_t, zip_flags_t, zip_uint64_t, zip_int64_t)
ZIP_EXTERN void zip_source_free(zip_source_t *_Nullable)
ZIP_EXTERN int zip_replace(zip_t *_Nonnull, zip_uint64_t, zip_source_t *_Nonnull)
Definition: zip_replace.c:40
ZIP_EXTERN zip_int64_t zip_get_num_entries(zip_t *_Nonnull, zip_flags_t)
const char * source
Definition: lz4.h:699
int idx
Definition: setup.py:197
uint64_t zip_uint64_t
Definition: zipconf.h:39
int64_t zip_int64_t
Definition: zipconf.h:38
static int confirm_replace(zip_t *, const char *, zip_uint64_t, zip_t *, const char *, zip_uint64_t)
Definition: zipmerge.c:174

References confirm_replace(), err, error(), create_tags_rz::fname, i, setup::idx, name_flags, NULL, progname, source, za, zip_add(), zip_close(), zip_error_fini(), zip_error_init_with_code(), zip_error_strerror(), zip_get_name(), zip_get_num_entries(), zip_name_locate(), zip_open(), zip_replace(), zip_source_free(), zip_source_zip(), and zip_strerror().

Referenced by main().

Variable Documentation

◆ confirm

int confirm

Definition at line 79 of file zipmerge.c.

Referenced by confirm_replace(), and main().

◆ help

char help[] ( void  )
Initial value:
= "\n\
-h display this help message\n\
-V display version number\n\
-D ignore directory component in file names\n\
-I ignore case in file names\n\
-i ask before overwriting files\n\
-S don't overwrite identical files\n\
-s overwrite identical files without asking\n\
\n\
Report bugs to <libzip@nih.at>.\n"

Definition at line 57 of file zipmerge.c.

Referenced by main().

◆ help_head

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

Definition at line 55 of file zipmerge.c.

Referenced by main().

◆ name_flags

zip_flags_t name_flags

Definition at line 80 of file zipmerge.c.

Referenced by main(), and merge_zip().

◆ progname

char* progname

Definition at line 49 of file zipmerge.c.

Referenced by confirm_replace(), main(), and merge_zip().

◆ version_string

char version_string[]
Initial value:
= PROGRAM " (" PACKAGE " " VERSION ")\n\
Copyright (C) 2004-2021 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: zipmerge.c:51

Definition at line 68 of file zipmerge.c.

Referenced by main().