25 #define _RPMIOB_INTERNAL
26 #define _RPMZ_INTERNAL
27 #define _RPMZ_INTERNAL_XZ
37 static int opt_preserve_name;
42 static lzma_stream strm = LZMA_STREAM_INIT;
49 static bool auto_adjust =
true;
53 static bool preset_default =
true;
65 #define F_ISSET(_f, _FLAG) (((_f) & ((RPMZ_FLAGS_##_FLAG) & ~0x40000000)) != RPMZ_FLAGS_NONE)
66 #define RZ_ISSET(_FLAG) F_ISSET(z->flags, _FLAG)
70 .stdin_fn =
"(stdin)",
71 .stdout_fn =
"(stdout)",
89 ._checksum = LZMA_CHECK_CRC64,
105 if (fstat(fdno, &sb) == -1 &&
errno == EBADF)
106 ret = (open(devnull, flags) == fdno) ? 1 : 2;
115 static int _oneshot = 0;
119 static const char _devnull[] =
"/dev/null";
120 #if defined(STDIN_FILENO)
121 (void)
checkfd(_devnull, STDIN_FILENO, O_RDONLY);
123 #if defined(STDOUT_FILENO)
124 (void)
checkfd(_devnull, STDOUT_FILENO, O_WRONLY);
126 #if defined(STDERR_FILENO)
127 (void)
checkfd(_devnull, STDERR_FILENO, O_WRONLY);
147 if (
Lstat(fn, &nsb) != 0
148 || nsb.st_dev != ost->st_dev || nsb.st_ino != ost->st_ino)
153 if (S_ISREG(nsb.st_mode) &&
Unlink(fn))
181 if (
Fchown(z->ofd, z->isb.st_uid, -1) && (geteuid() == 0))
183 zq->ofn, strerror(
errno));
187 if (
Fchown(z->ofd, -1, z->isb.st_gid)) {
189 zq->ofn, strerror(
errno));
198 mode = ((z->isb.st_mode & 0070) >> 3)
199 & (z->isb.st_mode & 0007);
200 mode = (z->isb.st_mode & 0700) | (mode << 3) |
mode;
203 mode = z->isb.st_mode & 0777;
208 zq->ofn, strerror(
errno));
222 # if defined(HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
224 atime_nsec = z->isb.st_atim.tv_nsec;
225 mtime_nsec = z->isb.st_mtim.tv_nsec;
227 # elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)
229 atime_nsec = z->isb.st_atimespec.tv_nsec;
230 mtime_nsec = z->isb.st_mtimespec.tv_nsec;
232 # elif defined(HAVE_STRUCT_STAT_ST_ATIMENSEC)
234 atime_nsec = z->isb.st_atimensec;
235 mtime_nsec = z->isb.st_mtimensec;
237 # elif defined(HAVE_STRUCT_STAT_ST_UATIME)
239 atime_nsec = z->isb.st_uatime * 1000;
240 mtime_nsec = z->isb.st_umtime * 1000;
242 # elif defined(HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC)
244 atime_nsec = z->isb.st_atim.st__tim.tv_nsec;
245 mtime_nsec = z->isb.st_mtim.st__tim.tv_nsec;
255 #if defined(HAVE_FUTIMENS)
257 {
struct timespec tv[2];
258 tv[0].tv_sec = z->isb.st_atime;
259 tv[0].tv_nsec = atime_nsec;
260 tv[1].tv_sec = z->isb.st_mtime;
261 tv[1].tv_nsec = mtime_nsec;
264 (void)futimens(
Fileno(z->ofd), tv);
267 #elif defined(HAVE_FUTIMES) || defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMES)
269 {
struct timeval tv[2];
270 tv[0].tv_sec = z->isb.st_atime;
271 tv[0].tv_usec = atime_nsec / 1000;
272 tv[1].tv_sec = z->isb.st_mtime;
273 tv[1].tv_usec = mtime_nsec / 1000;
275 # if defined(HAVE_FUTIMES)
277 (void)futimes(
Fileno(z->ofd), tv);
278 # elif defined(HAVE_FUTIMESAT)
280 (void)futimesat(
Fileno(z->ofd), NULL, tv);
283 (void)
Utimes(zq->ofn, tv);
287 #elif defined(HAVE_UTIME)
291 {
struct utimbuf buf = {
292 .actime = z->isb.st_atime,
293 .modtime = z->isb.st_mtime,
300 (void)
Utime(zq->ofn, &buf);
310 #if defined(HAVE_PHYSMEM_SYSCTL)
311 #include <sys/sysctl.h>
319 #if defined(HAVE_PHYSMEM_SYSCONF)
320 {
const long pagesize = sysconf(_SC_PAGESIZE);
321 const long pages = sysconf(_SC_PHYS_PAGES);
322 if (pagesize != -1 || pages != -1)
325 #elif defined(HAVE_PHYSMEM_SYSCTL)
326 {
int name[2] = { CTL_HW, HW_PHYSMEM };
328 size_t mem_ptr_size =
sizeof(mem);
329 if (!sysctl(name, 2, &mem, &mem_ptr_size, NULL, 0)) {
330 if (mem_ptr_size !=
sizeof(mem)) {
331 if (mem_ptr_size ==
sizeof(
unsigned int))
332 ret = *(
unsigned int *)(&mem);
342 #if defined(HAVE_NCPU_SYSCTL)
343 #include <sys/sysctl.h>
352 #if defined(HAVE_NCPU_SYSCONF)
353 {
const long cpus = sysconf(_SC_NPROCESSORS_ONLN);
355 zq->threads = (size_t)(cpus);
358 #elif defined(HAVE_NCPU_SYSCTL)
359 {
int name[2] = { CTL_HW, HW_NCPU };
361 size_t cpus_size =
sizeof(cpus);
362 if (!sysctl(name, 2, &cpus, &cpus_size, NULL, 0)
363 && cpus_size ==
sizeof(cpus) && cpus > 0)
364 z->threads = (size_t)(cpus);
368 #if defined(_SC_THREAD_THREADS_MAX)
369 {
const long threads_max = sysconf(_SC_THREAD_THREADS_MAX);
370 if (threads_max > 0 && (
unsigned)(threads_max) < zq->threads)
371 zq->threads = (unsigned)(threads_max);
373 #elif defined(PTHREAD_THREADS_MAX)
374 if (zq->threads > PTHREAD_THREADS_MAX)
375 zq->threads = PTHREAD_THREADS_MAX;
390 z->mem = 16 * 1024 * 1024;
393 z->memlimit_encoder = z->mem - z->mem / 10;
394 z->memlimit_decoder = z->mem / 3;
442 size_t flen = strlen(fn);
443 size_t slen = strlen(suffix);
444 int rc = (flen > slen && !strcmp(fn + flen - slen, suffix));
446 fprintf(stderr,
"\tchk(%s,%s) ret %d\n", fn, suffix, rc);
462 size_t nfn = strlen(fn);
463 size_t nos = (old ? strlen(old) : 0);
464 size_t nns = (
new ? strlen(
new) : 0);
465 char * t =
xmalloc(nfn - nos + nns + 1);
469 strncpy(te, fn, (nfn - nos));
488 const char * fn = z->ifn;
489 const char * t = NULL;
492 if (z->format != sp->
format)
504 fprintf(stderr,
"==> uncompressedFN: %s\n", t);
517 const char * fn = z->ifn;
518 const char * t = NULL;
530 t =
rpmGetPath(fn, (z->suffix ? z->suffix : z->osuffix), NULL);
533 fprintf(stderr,
"==> compressedFN: %s (suffix %s osuffix %s)\n", t, z->suffix, z->osuffix);
547 if (z->ofd != NULL) {
551 if (zq->ofn != NULL && strcmp(zq->ofn, z->stdout_fn))
553 if ((xx =
Fclose(z->ofd)) != 0) {
555 zq->ofn, strerror(
errno));
560 if (z->ifd != NULL) {
561 if ((xx =
Fclose(z->ifd)) != 0) {
563 z->ifn, strerror(
errno));
574 if (zq->ofn != NULL && strcmp(zq->ofn, z->stdout_fn)) {
577 fprintf(stderr,
"==> Unlink(%s) FAIL\n", zq->ofn);
581 if (!
F_ISSET(z->flags, KEEP) && z->ifn != z->stdin_fn) {
584 fprintf(stderr,
"==> Unlink(%s)\n", z->ifn);
589 zq->ofn =
_free(zq->ofn);
601 fprintf(stderr,
"==> rpmzInit(%p) ifn %s ofmode %s\n", z, z->ifn, z->ofmode);
606 z->ifn = z->stdin_fn;
611 z->ifd =
fdDup(STDIN_FILENO);
614 z->ifd = z->idio->_fdopen(
fdDup(STDIN_FILENO), z->ifmode);
618 struct stat * st = &z->isb;
621 if (ifn != z->_ifn) {
623 strncpy(z->_ifn, ifn,
sizeof(z->_ifn));
625 assert(z->_ifn[
sizeof(z->_ifn) - 1] ==
'\0');
628 if (
Lstat(z->ifn, &z->isb) < 0) {
630 assert(
errno != EOVERFLOW);
631 assert(
errno != EFBIG);
633 fprintf(stderr,
"%s: input %s does not exist, skipping\n",
637 if (!S_ISREG(st->st_mode) && !
S_ISLNK(st->st_mode) && !S_ISDIR(st->st_mode))
639 fprintf(stderr,
"%s: input %s is a special file or device -- skipping\n",
644 fprintf(stderr,
"%s: input %s is a symbolic link -- skipping\n",
650 if (S_ISDIR(st->st_mode)) {
651 struct stat sb = *st;
660 if (!
F_ISSET(z->flags, RECURSE)) {
661 fprintf(stderr,
"%s: input %s is a directory -- skipping\n",
665 len = strlen(z->_ifn);
667 if ((dir =
Opendir(z->_ifn)) == NULL)
669 while ((dp =
Readdir(dir)) != NULL) {
670 if (dp->d_name[0] ==
'\0' ||
671 (dp->d_name[0] ==
'.' && (dp->d_name[1] ==
'\0' ||
672 (dp->d_name[1] ==
'.' && dp->d_name[2] ==
'\0'))))
678 for (i = 0; av[
i] != NULL; i++) {
680 strncpy(te+1, av[i],
sizeof(z->_ifn) - len - 1);
681 assert(z->_ifn[
sizeof(z->_ifn) - 1] ==
'\0');
696 z->ifd =
Fopen(z->ifn, z->ifmode);
699 z->ifd = z->idio->_fopen(z->ifn, z->ifmode);
704 if (z->ifd == NULL ||
Ferror(z->ifd)) {
705 fprintf(stderr,
"%s: can't open %s\n",
__progname, z->ifn);
709 if (
F_ISSET(z->flags, STDOUT)) {
710 zq->ofn =
xstrdup(z->stdout_fn);
715 z->ofd = z->odio->_fdopen(
fdDup(STDOUT_FILENO), z->ofmode);
718 z->ofd =
fdDup(STDOUT_FILENO);
722 if (z->ifn == z->stdin_fn)
731 if (!
F_ISSET(z->flags, OVERWRITE) &&
Stat(zq->ofn, &z->osb) == 0) {
732 fprintf(stderr,
"%s: output file %s already exists\n",
737 z->ofd = z->odio->_fopen(zq->ofn, z->ofmode);
742 if (!
F_ISSET(z->flags, OVERWRITE) &&
Stat(zq->ofn, &z->osb) == 0) {
743 fprintf(stderr,
"%s: output file %s already exists\n",
748 z->ofd =
Fopen(zq->ofn, z->ofmode);
752 if (z->ofd == NULL ||
Ferror(z->ofd)) {
753 fprintf(stderr,
"%s: can't open %s\n",
__progname, zq->ofn);
770 iob->blen =
Fread(iob->b, 1, iob->allocated, z->ifd);
775 if (iob->blen == 0)
break;
777 if (
Fwrite(iob->b, 1, iob->blen, z->ofd) != iob->blen)
791 if (rc ==
RPMRC_OK && z->ifd != NULL && z->ofd != NULL)
806 if (signals_init_count++ == 0) {
822 if (--signals_init_count == 0) {
836 static int terminating = 0;
838 if (terminating)
return 1;
854 static int signals_block_count;
861 if (signals_block_count++ == 0) {
862 const int saved_errno =
errno;
863 mythread_sigmask(SIG_BLOCK, &hooked_signals, NULL);
870 signals_unblock(
void)
874 assert(signals_block_count > 0);
876 if (--signals_block_count == 0) {
877 const int saved_errno =
errno;
878 mythread_sigmask(SIG_UNBLOCK, &hooked_signals, NULL);
889 const int sig = exit_signal;
893 sa.sa_handler = SIG_DFL;
894 sigfillset(&sa.sa_mask);
896 sigaction(sig, &sa, NULL);
942 void (*
set)(
void *filter_options,
944 void *filter_options)
950 if (str == NULL || str[0] ==
'\0')
957 char *split = strchr(name,
',');
965 value = strchr(name,
'=');
969 if (value == NULL || value[0] ==
'\0') {
970 fprintf(stderr,
_(
"%s: %s: Options must be `name=value' pairs separated with commas\n"),
977 for (i = 0; opts[
i].
name != NULL; ++
i) {
978 if (strcmp(name, opts[i].name) != 0)
981 if (opts[i].map == NULL) {
985 v = str_to_uint64(name, value, opts[i].min, opts[i].
max);
987 v = strtoull(value, NULL, 0);
989 set(filter_options, i, v);
994 for (j = 0; opts[
i].
map[
j].
name != NULL; ++
j) {
995 if (strcmp(opts[i].map[j].name, value) == 0)
999 if (opts[i].map[j].name == NULL) {
1000 fprintf(stderr,
_(
"%s: %s: Invalid option value\n"),
1005 set(filter_options, i, opts[i].map[j].
id);
1013 fprintf(stderr,
_(
"%s: %s: Invalid option name\n"),
__progname, name);
1038 lzma_options_subblock *opt =
options;
1041 case OPT_SIZE: opt->subblock_data_size = value;
break;
1042 case OPT_RLE: opt->rle = value;
break;
1043 case OPT_ALIGN: opt->alignment = value;
break;
1047 static lzma_options_subblock *
1052 {
"size", NULL, LZMA_SUBBLOCK_DATA_SIZE_MIN,
1053 LZMA_SUBBLOCK_DATA_SIZE_MAX },
1054 {
"rle", NULL, LZMA_SUBBLOCK_RLE_OFF,
1055 LZMA_SUBBLOCK_RLE_MAX },
1056 {
"align",NULL, LZMA_SUBBLOCK_ALIGNMENT_MIN,
1057 LZMA_SUBBLOCK_ALIGNMENT_MAX },
1058 { NULL, NULL, 0, 0 }
1061 lzma_options_subblock *
options =
xmalloc(
sizeof(lzma_options_subblock));
1062 options->allow_subfilters = 0;
1063 options->alignment = LZMA_SUBBLOCK_ALIGNMENT_DEFAULT;
1064 options->subblock_data_size = LZMA_SUBBLOCK_DATA_SIZE_DEFAULT;
1065 options->rle = LZMA_SUBBLOCK_RLE_OFF;
1082 lzma_options_delta *opt =
options;
1084 case OPT_DIST: opt->dist = value;
break;
1088 static lzma_options_delta *
1092 {
"dist", NULL, LZMA_DELTA_DIST_MIN,
1093 LZMA_DELTA_DIST_MAX },
1094 { NULL, NULL, 0, 0 }
1097 lzma_options_delta *
options =
xmalloc(
sizeof(lzma_options_delta));
1099 options->type = LZMA_DELTA_TYPE_BYTE;
1100 options->dist = LZMA_DELTA_DIST_MIN;
1124 lzma_options_lzma *opt =
options;
1128 if (lzma_lzma_preset(options, (uint32_t)(value))) {
1129 fprintf(stderr,
_(
"LZMA1/LZMA2 preset %u is not supported\n"),
1130 (
unsigned int)(value));
1134 case OPT_DICT: opt->dict_size = value;
break;
1135 case OPT_LC: opt->lc = value;
break;
1136 case OPT_LP: opt->lp = value;
break;
1137 case OPT_PB: opt->pb = value;
break;
1138 case OPT_MODE: opt->mode = value;
break;
1139 case OPT_NICE: opt->nice_len = value;
break;
1140 case OPT_MF: opt->mf = value;
break;
1141 case OPT_DEPTH: opt->depth = value;
break;
1145 static lzma_options_lzma *
1150 {
"fast", LZMA_MODE_FAST },
1151 {
"normal", LZMA_MODE_NORMAL },
1157 {
"hc3", LZMA_MF_HC3 },
1158 {
"hc4", LZMA_MF_HC4 },
1159 {
"bt2", LZMA_MF_BT2 },
1160 {
"bt3", LZMA_MF_BT3 },
1161 {
"bt4", LZMA_MF_BT4 },
1167 {
"preset", NULL, 1, 9 },
1168 {
"dict", NULL, LZMA_DICT_SIZE_MIN,
1169 (UINT32_C(1) << 30) + (UINT32_C(1) << 29) },
1170 {
"lc", NULL, LZMA_LCLP_MIN, LZMA_LCLP_MAX },
1171 {
"lp", NULL, LZMA_LCLP_MIN, LZMA_LCLP_MAX },
1172 {
"pb", NULL, LZMA_PB_MIN, LZMA_PB_MAX },
1173 {
"mode",
modes, 0, 0 },
1174 {
"nice", NULL, 2, 273 },
1175 {
"mf", mfs, 0, 0 },
1176 {
"depth", NULL, 0, UINT32_MAX },
1177 { NULL, NULL, 0, 0 }
1182 options->dict_size = LZMA_DICT_SIZE_DEFAULT;
1183 options->preset_dict = NULL;
1184 options->preset_dict_size = 0,
1185 options->lc = LZMA_LC_DEFAULT;
1186 options->lp = LZMA_LP_DEFAULT;
1187 options->pb = LZMA_PB_DEFAULT;
1188 options->persistent = 0;
1189 options->mode = LZMA_MODE_NORMAL;
1190 options->nice_len = 64;
1191 options->mf = LZMA_MF_BT4;
1203 if (z->_filters_count == LZMA_FILTERS_MAX) {
1204 fprintf(stderr,
_(
"%s: Maximum number of filters is %d\n"),
1209 z->_filters[z->_filters_count].id = id;
1210 z->_filters[z->_filters_count].options =
options;
1211 z->_filters_count++;
1220 return z->memlimit_custom != 0 ? z->memlimit_custom : z->memlimit_encoder;
1227 return z->memlimit_custom != 0 ? z->memlimit_custom : z->memlimit_decoder;
1245 for (i = 0; filters[
i].id != LZMA_VLI_UNKNOWN; ++
i) {
1248 switch (filters[i].
id) {
1249 case LZMA_FILTER_LZMA1:
1250 case LZMA_FILTER_LZMA2: {
1251 const lzma_options_lzma *opt = filters[
i].options;
1252 const char *lzmaver;
1256 switch (opt->mode) {
1257 case LZMA_MODE_FAST: mode =
"fast";
break;
1258 case LZMA_MODE_NORMAL: mode =
"normal";
break;
1259 default: mode =
"UNKNOWN";
break;
1263 case LZMA_MF_HC3: mf =
"hc3";
break;
1264 case LZMA_MF_HC4: mf =
"hc4";
break;
1265 case LZMA_MF_BT2: mf =
"bt2";
break;
1266 case LZMA_MF_BT3: mf =
"bt3";
break;
1267 case LZMA_MF_BT4: mf =
"bt4";
break;
1268 default: mf =
"UNKNOWN";
break;
1271 lzmaver = (filters[
i].id == LZMA_FILTER_LZMA2 ?
"2" :
"1");
1273 te =
stpcpy(te,
"=dict=");
1274 sprintf(te,
"%u", (
unsigned)opt->dict_size);
1277 sprintf(te,
"%u", (
unsigned)opt->lc);
1280 sprintf(te,
"%u", (
unsigned)opt->lp);
1283 sprintf(te,
"%u", (
unsigned)opt->pb);
1286 te =
stpcpy(te,
",nice=");
1287 sprintf(te,
"%u", (
unsigned)opt->nice_len);
1290 te =
stpcpy(te,
",depth=");
1291 sprintf(te,
"%u", (
unsigned)opt->depth);
1296 case LZMA_FILTER_X86: te =
stpcpy(te,
"x86");
break;
1297 case LZMA_FILTER_POWERPC: te =
stpcpy(te,
"powerpc");
break;
1298 case LZMA_FILTER_IA64: te =
stpcpy(te,
"ia64");
break;
1299 case LZMA_FILTER_ARM: te =
stpcpy(te,
"arm");
break;
1300 case LZMA_FILTER_ARMTHUMB: te =
stpcpy(te,
"armthumb");
break;
1301 case LZMA_FILTER_SPARC: te =
stpcpy(te,
"sparc");
break;
1302 case LZMA_FILTER_DELTA: {
1303 const lzma_options_delta *opt = filters[
i].options;
1304 te =
stpcpy(te,
"delta=dist=");
1305 sprintf(te,
"%u", (
unsigned)opt->dist);
1310 default: te =
stpcpy(te,
"UNKNOWN");
break;
1322 rpmlog(
RPMLOG_CRIT,
_(
"Memory usage limit (%llu MiB) is too small for the given filter setup (%llu MiB)\n"),
1323 (
unsigned long long)(memory_limit >> 20),
1324 (
unsigned long long)(memory_usage >> 20));
1339 size_t thread_limit;
1344 if (
F_ISSET(z->flags, POWERPC))
1350 if (
F_ISSET(z->flags, ARMTHUMB))
1355 if (z->_filters_count == 0) {
1364 rpmlog(
RPMLOG_WARNING,
_(
"The exact options of the presets may vary between software versions.\n"));
1367 {
size_t preset_number = z->level;
1370 if (
F_ISSET(z->flags, EXTREME))
1371 preset_number |= LZMA_PRESET_EXTREME;
1373 if (lzma_lzma_preset(&z->_options, preset_number))
1379 ? LZMA_FILTER_LZMA1 : LZMA_FILTER_LZMA2;
1380 z->_filters[0].options = &z->_options;
1381 z->_filters_count = 1;
1385 preset_default =
false;
1389 z->_filters[z->_filters_count].id = LZMA_VLI_UNKNOWN;
1394 || z->_filters[0].id != LZMA_FILTER_LZMA1))
1404 memory_usage = lzma_raw_encoder_memusage(z->_filters);
1407 memory_usage = lzma_raw_decoder_memusage(z->_filters);
1411 if (memory_usage == UINT64_MAX)
1415 rpmlog(
RPMLOG_DEBUG,
_(
"%'llu MiB (%'llu B) of memory is required per thread, limit is %'llu MiB (%'llu B)\n"),
1416 (
unsigned long long)(memory_usage >> 20),
1417 (
unsigned long long)memory_usage,
1418 (
unsigned long long)(memory_limit >> 20),
1419 (
unsigned long long)memory_limit);
1421 if (memory_usage > memory_limit) {
1423 lzma_options_lzma *opt;
1439 while (z->_filters[i].id != LZMA_FILTER_LZMA2
1440 && z->_filters[i].id != LZMA_FILTER_LZMA1) {
1441 if (z->_filters[i].id == LZMA_VLI_UNKNOWN)
1449 opt = z->_filters[
i].options;
1450 orig_dict_size = opt->dict_size;
1451 opt->dict_size &= ~((UINT32_C(1) << 20) - 1);
1460 if (opt->dict_size < (UINT32_C(1) << 20))
1463 memory_usage = lzma_raw_encoder_memusage(z->_filters);
1464 assert(memory_usage != UINT64_MAX);
1467 if (memory_usage <= memory_limit)
1473 opt->dict_size -= UINT32_C(1) << 20;
1480 if (!preset_default)
1482 rpmlog(
RPMLOG_WARNING,
"Adjusted LZMA%c dictionary size from %'u MiB to %'u MiB to not exceed the memory usage limit of %'llu MiB\n",
1483 z->_filters[i].id == LZMA_FILTER_LZMA2
1485 (
unsigned)(orig_dict_size >> 20),
1486 (
unsigned)(opt->dict_size >> 20),
1487 (
unsigned long long)(memory_limit >> 20));
1492 assert(memory_usage > 0);
1493 thread_limit = memory_limit / memory_usage;
1494 if (thread_limit == 0)
1497 if (zq->threads > thread_limit)
1498 zq->threads = thread_limit;
1508 static int rpmzLoadManifests(
rpmz z)
1515 if ((manifests = z->manifests) != NULL)
1516 while ((fn = *manifests++) != NULL) {
1524 if (!(xx == 0 && iob != NULL)) {
1525 fprintf(stderr,
_(
"%s: Failed to open %s\n"),
__progname, fn);
1530 be = (
char *)(iob->b + iob->blen);
1531 while (be > (
char *)iob->b && (be[-1] ==
'\n' || be[-1] ==
'\r')) {
1538 for (f = (
char *)iob->b; *f; f = fe) {
1544 while (*fe && !(*fe ==
'\n' || *fe ==
'\r'))
1548 while (*fe && (*fe ==
'\n' || *fe ==
'\r'))
1565 path =
rpmExpand(z->base_prefix, g, NULL);
1568 (void)
argvAdd(&z->argv, path);
1588 enum poptCallbackReason reason,
1589 const struct poptOption * opt,
const char *
arg,
1596 if (opt->arg == NULL)
1599 {
char * end = NULL;
1600 z->memlimit_custom = (
rpmuint64_t) strtoll(arg, &end, 0);
1601 if (end == NULL || *end ==
'\0')
1603 if (!strcmp(end,
"k") || !strcmp(end,
"kB"))
1604 z->memlimit_custom *= 1000;
1605 else if (!strcmp(end,
"M") || !strcmp(end,
"MB"))
1606 z->memlimit_custom *= 1000 * 1000;
1607 else if (!strcmp(end,
"G") || !strcmp(end,
"GB"))
1608 z->memlimit_custom *= 1000 * 1000 * 1000;
1609 else if (!strcmp(end,
"Ki") || !strcmp(end,
"KiB"))
1610 z->memlimit_custom *= 1024;
1611 else if (!strcmp(end,
"Mi") || !strcmp(end,
"MiB"))
1612 z->memlimit_custom *= 1024 * 1024;
1613 else if (!strcmp(end,
"Gi") || !strcmp(end,
"GiB"))
1614 z->memlimit_custom *= 1024 * 1024 * 1024;
1616 fprintf(stderr,
_(
"%s: Invalid memory scaling suffix \"%s\"\n"),
1623 if (!strcmp(arg,
"none"))
1624 z->_checksum = LZMA_CHECK_NONE;
1625 else if (!strcmp(arg,
"crc32"))
1626 z->_checksum = LZMA_CHECK_CRC32;
1627 else if (!strcmp(arg,
"crc64"))
1628 z->_checksum = LZMA_CHECK_CRC64;
1629 else if (!strcmp(arg,
"sha256"))
1630 z->_checksum = LZMA_CHECK_SHA256;
1632 fprintf(stderr,
_(
"%s: Unknown integrity check method \"%s\"\n"),
1639 if (!strcmp(arg,
"auto"))
1641 else if (!strcmp(arg,
"xz"))
1643 else if (!strcmp(arg,
"lzma") || !strcmp(arg,
"alone"))
1645 else if (!strcmp(arg,
"raw"))
1647 else if (!strcmp(arg,
"gzip") || !strcmp(arg,
"gz"))
1649 else if (!strcmp(arg,
"zlib"))
1651 else if (!strcmp(arg,
"zip"))
1653 else if (!strcmp(arg,
"bzip2") || !strcmp(arg,
"bz2"))
1656 fprintf(stderr,
_(
"%s: Unknown file format type \"%s\"\n"),
1677 fprintf(stderr,
"%s\n",
VERSION);
1681 case 'V': fprintf(stderr,
"%s\n",
VERSION); exit(EXIT_SUCCESS);
1684 fprintf(stderr,
_(
"%s: Unknown option -%c\n"),
__progname, opt->val);
1685 poptPrintUsage(con, stderr, 0);
1695 { NULL,
'\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
1701 " --lzma=[OPTS] LZMA filter; OPTS is a comma-separated list of zero or\n"
1702 " more of the following options (valid values; default):\n"
1703 " dict=NUM dictionary size in bytes (1 - 1Gi; 8Mi)\n"
1704 " lc=NUM number of literal context bits (0-8; 3)\n"
1705 " lp=NUM number of literal position bits (0-4; 0)\n"
1706 " pb=NUM number of position bits (0-4; 2)\n"
1707 " mode=MODE compression mode (`fast' or `best'; `best')\n"
1708 " nice_len=NUM number of fast bytes (5-273; 128)\n"
1709 " mf=NAME match finder (hc3, hc4, bt2, bt3, bt4; bt4)\n"
1710 " depth=NUM match finder cycles; 0=automatic (default)\n"
1712 {
"lzma1",
'\0', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, NULL,
OPT_LZMA1,
1713 N_(
"LZMA1 filter"),
N_(
"OPTS") },
1714 {
"lzma2",
'\0', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, NULL,
OPT_LZMA2,
1715 N_(
"LZMA2 filter"),
N_(
"OPTS") },
1718 N_(
"ix86 filter (sometimes called BCJ filter)"), NULL },
1720 N_(
"x86 filter (also called BCJ filter)"), NULL },
1722 N_(
"PowerPC (big endian) filter"), NULL },
1724 N_(
"PowerPC (big endian) filter"), NULL },
1726 N_(
"IA64 (Itanium) filter"), NULL },
1728 N_(
"IA64 (Itanium) filter"), NULL },
1730 N_(
"ARM filter"), NULL },
1732 N_(
"ARM-Thumb filter"), NULL },
1734 N_(
"SPARC filter"), NULL },
1737 " --delta=[OPTS] Delta filter; valid OPTS (valid values; default):\n"
1738 " dist=NUM Distance between bytes being\n"
1739 " subtracted from each other (1-256; 1)\n"
1741 {
"delta",
'\0', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, NULL,
OPT_DELTA,
1742 N_(
"Delta filter"),
N_(
"OPTS") },
1745 " --subblock=[OPTS] Subblock filter; valid OPTS (valid values; default):\n"
1746 " size=NUM number of bytes of data per subblock\n"
1747 " (1 - 256Mi; 4Ki)\n"
1748 " rle=NUM run-length encoder chunk size (0-256; 0)\n"
1750 {
"subblock",
'\0', POPT_ARG_STRING|POPT_ARGFLAG_OPTIONAL, NULL,
OPT_SUBBLOCK,
1751 N_(
"Subblock filter"),
N_(
"OPTS") },
1761 { NULL,
'\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
1765 {
"debug",
'D', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, &
_debug, -1,
1766 N_(
"debug spewage"), NULL },
1768 {
"format",
'F', POPT_ARG_STRING, NULL,
'F',
1769 N_(
"file FORMAT {auto|xz|lzma|alone|raw|gz|bz2}"),
N_(
"FORMAT") },
1770 {
"check",
'C', POPT_ARG_STRING, NULL,
'C',
1771 N_(
"integrity check METHOD {none|crc32|crc64|sha256}"),
N_(
"METHOD") },
1772 {
"memory",
'M', POPT_ARG_STRING, NULL,
'M',
1773 N_(
"use roughly NUM Mbytes of memory at maximum"),
N_(
"NUM") },
1776 {
"files",
'\0', POPT_ARG_ARGV, &
__rpmz.manifests, 0,
1777 N_(
"Read file names from MANIFEST"),
N_(
"MANIFEST") },
1779 {
"quiet",
'q', POPT_ARG_VAL, NULL,
'q',
1780 N_(
"suppress warnings; specify twice to suppress errors too"), NULL },
1781 {
"verbose",
'v', POPT_ARG_VAL, NULL,
'v',
1782 N_(
"be verbose; specify twice for even more verbose"), NULL },
1783 {
"help",
'h', POPT_ARG_VAL, NULL,
'h',
1784 N_(
"display this help and exit"), NULL },
1785 {
"long-help",
'h', POPT_ARG_VAL, NULL,
'H',
1786 N_(
"display this help and exit"), NULL },
1788 {
"version",
'V', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, NULL,
'V',
1789 N_(
"Display software version"), NULL },
1790 {
"license",
'L', POPT_ARG_VAL|POPT_ARGFLAG_DOC_HIDDEN, NULL,
'L',
1791 N_(
"Display softwre license"), NULL },
1798 { NULL,
'\0', POPT_ARG_CALLBACK | POPT_CBFLAG_INC_DATA | POPT_CBFLAG_CONTINUE,
1804 Compress or decompress FILEs.\n\
1810 { NULL,
'\0', POPT_ARG_INCLUDE_TABLE, rpmzOptionsPoptTable, 0,
1811 N_(
"Compression options: "), NULL },
1817 N_(
"extreme compression"), NULL },
1822 N_(
"Filters:"), NULL },
1826 {
"sign",
'S', POPT_ARG_STRING, NULL, 0,
1827 N_(
"sign the data with GnuPG when compressing, or verify the signature when decompressing"),
N_(
"PUBKEY") },
1833 N_(
"Common options for all rpmio executables:"),
1839 { NULL, (char)-1, POPT_ARG_INCLUDE_TABLE, NULL, 0,
1841 Usage: rpmz [OPTION]... [FILE]...\n\
1842 Compress or decompress FILEs.\
1870 zq->blocksize = 128;
1874 xx = rpmzParseArgv0(z, argv[0]);
1889 xx = rpmzParseEnv(z, NULL, optionsTable);
1895 optCon =
rpmioInit(argc, argv, optionsTable);
1909 z->format = z->_format_compress_auto;
1912 switch (z->format) {
1915 z->idio = z->odio =
xzdio;
1921 z->idio = z->odio =
lzdio;
1922 z->osuffix =
".lzma";
1927 z->idio = z->odio =
xzdio;
1932 fprintf(stderr,
"==> warning: assuming auto format is gzip\n");
1936 z->idio = z->odio =
gzdio;
1940 z->idio = z->odio =
gzdio;
1944 z->idio = z->odio =
gzdio;
1945 z->osuffix =
".zip";
1948 z->idio = z->odio =
bzdio;
1949 z->osuffix =
".bz2";
1955 xx =
snprintf(z->ofmode,
sizeof(z->ofmode)-1,
"wb%u",
1956 (
unsigned)(
__rpmz.level % 10));
1960 {
ARGV_t av = poptGetArgs(optCon);
1966 if (z->manifests != NULL)
1967 xx = rpmzLoadManifests(z);
1974 if (z->argv == NULL || z->argv[0] == NULL)
1980 for (i = 0; i < ac; i++) {
1985 ifn = (z->argv && strcmp(z->argv[i],
"-") ? z->argv[
i] : NULL);
2003 z->manifests =
argvFree(z->manifests);
static const char * suffix[]
static void signals_exit(void)
poptContext rpmioInit(int argc, char *const argv[], struct poptOption *optionsTable)
Initialize most everything needed by an rpmio executable context.
static struct suffixPairs_s suffixPairs[]
static void parse_options(const char *str, const option_map *opts, void(*set)(void *filter_options, rpmuint32_t key, rpmuint64_t value), void *filter_options)
const char const char size_t len
size_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd)
fwrite(3) clone.
static char * changeSuffix(const char *fn, const char *old, const char *new)
Return (malloc'd) string with new suffix substituted for old.
char * xstrdup(const char *str)
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
void rpmzArgCallback(poptContext con, enum poptCallbackReason reason, const struct poptOption *opt, const char *arg, void *data)
static void set_delta(void *options, rpmuint32_t key, rpmuint64_t value)
char * rpmGetPath(const char *path,...)
Return (malloc'ed) expanded, canonicalized, file path.
int Utimes(const char *path, const struct timeval *times)
utimes(2) clone.
static rpmuint64_t physmem(void)
static void signals_fini(void)
struct rpmzQueue_s * rpmzQueue
int argvAppend(ARGV_t *argvp, ARGV_t av)
Append one argv array to another.
int Stat(const char *path, struct stat *st)
stat(2) clone.
int Fflush(FD_t fd)
fflush(3) clone.
static struct poptOption rpmzFiltersPoptTable[]
rpmiob rpmiobFree(rpmiob iob)
Destroy a I/O buffer instance.
static void rpmlog(int code, const char *fmt,...)
static void io_unlink(const char *fn, const struct stat *ost)
int Utime(const char *path, const struct utimbuf *buf)
int rpmiobSlurp(const char *fn, rpmiob *iobp)
RPM parallel compressor internals.
static int checkfd(const char *devnull, int fdno, int flags)
static void coder_set_compression_settings(rpmz z)
int Fchown(FD_t fd, uid_t owner, gid_t group)
fchown(2) clone.
const char const bson_bool_t v
static lzma_options_delta * options_delta(const char *str)
static rpmuint64_t hw_memlimit_encoder(rpmz z)
static lzma_options_subblock * options_subblock(const char *str)
static void coder_add_filter(rpmz z, lzma_vli id, void *options)
FD_t fdFree(FD_t fd, const char *msg)
static rpmRC rpmzCopy(rpmz z, rpmiob iob)
int argvCount(const ARGV_t argv)
Return no.
const char const bson * data
int Lstat(const char *path, struct stat *st)
lstat(2) clone.
#define POPT_ARGFLAG_TOGGLE
static int xisspace(int c)
unsigned long long rpmuint64_t
ARGV_t argvFree(ARGV_t argv)
Destroy an argv array.
static int signals_init_count
static void memlimit_too_small(rpmuint64_t memory_usage, rpmuint64_t memory_limit)
static void signals_init(void)
static lzma_options_lzma * options_lzma(const char *str)
static void set_subblock(void *options, rpmuint32_t key, rpmuint64_t value)
int argvAdd(ARGV_t *argvp, ARGstr_t val)
Add a string to an argv array.
static rpmuint64_t hw_memlimit_decoder(rpmz z)
char * rpmExpand(const char *arg,...)
Return (malloc'ed) concatenated macro expansion(s).
static rpmRC rpmzInit(rpmz z, const char *ifn)
static void hw_memlimit_init(rpmz z)
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
const char const char int arg
int Fchmod(FD_t fd, mode_t mode)
fchmod(2) clone.
int Fclose(FD_t fd)
fclose(3) clone.
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
static void io_init(void)
const char const bson int mongo_write_concern int flags
void argvPrint(const char *msg, ARGV_t argv, FILE *fp)
Print argv array elements.
static void hw_init(rpmz z)
enum rpmRC_e rpmRC
RPM return codes.
int Ferror(FD_t fd)
ferror(3) clone.
const char const char const char * opts
static int snprintf(char *buf, int nb, const char *fmt,...)
const char const bson * key
static void set(char *t, NODE *ip)
const char const char int int max
struct dirent * Readdir(DIR *dir)
readdir(3) clone.
static struct poptOption rpmzPrivatePoptTable[]
char * stpcpy(char *dest, const char *src)
static const char * uncompressedFN(rpmz z)
Return (malloc'd) uncompressed file name.
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
static rpmRC rpmzFini(rpmz z, rpmRC rc)
#define F_ISSET(_f, _FLAG)
int main(int argc, char *argv[])
int Fileno(FD_t fd)
fileno(3) clone.
int Closedir(DIR *dir)
closedir(3) clone.
const char const char * code
DIR * Opendir(const char *path)
opendir(3) clone.
static int chkSuffix(const char *fn, const char *suffix)
Check string for a suffix.
int rpmlogSetMask(int mask)
Set the log mask level.
struct poptOption rpmioAllPoptTable[]
Popt option table for options shared by all modes and executables.
static void hw_cores(rpmz z)
poptContext rpmioFini(poptContext optCon)
Destroy most everything needed by an rpm CLI executable context.
const char const bson const bson int int int options
static void message_filters(int code, const lzma_filter *filters)
static rpmRC rpmzProcess(rpmz z, const char *ifn)
static const char * compressedFN(rpmz z)
Return (malloc'd) compressed file name.
int rpmsqEnable(int signum, rpmsqAction_t handler)
Enable or disable a signal handler.
static int signals_terminating(int terminate)
static void io_copy_attrs(rpmz z)
static struct poptOption optionsTable[]
static void set_lzma(void *options, rpmuint32_t key, rpmuint64_t value)
int Unlink(const char *path)
unlink(2) clone.