static void g_zlib_compressor_set_gzheader (GZlibCompressor *compressor) { /* On win32, these functions were not exported before 1.2.4 */ #if !defined (G_OS_WIN32) || ZLIB_VERNUM >= 0x1240 const gchar *filename; if (compressor->format != G_ZLIB_COMPRESSOR_FORMAT_GZIP || compressor->file_info == NULL) return; memset (&compressor->gzheader, 0, sizeof (gz_header)); compressor->gzheader.os = 0x03; /* Unix */ filename = g_file_info_get_name (compressor->file_info); compressor->gzheader.name = (Bytef *) filename; compressor->gzheader.name_max = filename ? strlen (filename) + 1 : 0; compressor->gzheader.time = (uLong) g_file_info_get_attribute_uint64 (compressor->file_info, G_FILE_ATTRIBUTE_TIME_MODIFIED); if (deflateSetHeader (&compressor->zstream, &compressor->gzheader) != Z_OK) g_warning ("unexpected zlib error: %s\n", compressor->zstream.msg); #endif /* !G_OS_WIN32 || ZLIB >= 1.2.4 */ }
bool InitGzipCompressor (z_stream *strm_p, int level, gz_header *gzip_header_p, const char *filename_s, const time_t last_modified) { int i; #define WINDOW_BITS 15 #define GZIP_ENCODING 16 strm_p -> zalloc = Z_NULL; strm_p -> zfree = Z_NULL; strm_p -> opaque = Z_NULL; i = deflateInit2 (strm_p, level, Z_DEFLATED, WINDOW_BITS | GZIP_ENCODING, Z_DEFLATED, Z_DEFAULT_STRATEGY); if (i == Z_OK) { memset (gzip_header_p, 0, sizeof (gz_header)); gzip_header_p -> os = OS; if (filename_s) { gzip_header_p -> name = (Bytef *) filename_s; gzip_header_p -> name_max = strlen (filename_s) + 1; } gzip_header_p -> time = last_modified; i = deflateSetHeader (strm_p, gzip_header_p); } return (i == Z_OK); }
/* compress or decompress from stdin to stdout */ int main(int argc, char **argv) { int rc = Z_OK; bool compress = true; int list_contents = 0; bool force = false; bool quiet __attribute__((unused)) = false; int window_bits = 31; /* GZIP */ int level = Z_DEFAULT_COMPRESSION; char *prog = basename(argv[0]); const char *in_f = NULL; char out_f[PATH_MAX]; FILE *i_fp = stdin; FILE *o_fp = NULL; const char *suffix = "gz"; int force_software = 0; int cpu = -1; unsigned char *in = NULL; unsigned char *out = NULL; z_stream strm; const char *name = NULL; char *comment = NULL; const char *extra_fname = NULL; uint8_t *extra = NULL; int extra_len = 0; struct stat s; const char *accel = "GENWQE"; const char *accel_env = getenv("ZLIB_ACCELERATOR"); int card_no = 0; const char *card_no_env = getenv("ZLIB_CARD"); /* Use environment variables as defaults. Command line options can than overrule this. */ if (accel_env != NULL) accel = accel_env; if (card_no_env != NULL) card_no = atoi(card_no_env); /* avoid end-of-line conversions */ SET_BINARY_MODE(stdin); SET_BINARY_MODE(stdout); if (strstr(prog, "gunzip") != 0) compress = false; while (1) { int ch; int option_index = 0; static struct option long_options[] = { { "stdout", no_argument, NULL, 'c' }, { "decompress", no_argument, NULL, 'd' }, { "force", no_argument, NULL, 'f' }, { "help", no_argument, NULL, 'h' }, /* list */ { "list", no_argument, NULL, 'l' }, { "license", no_argument, NULL, 'L' }, { "suffix", required_argument, NULL, 'S' }, { "verbose", no_argument, NULL, 'v' }, { "version", no_argument, NULL, 'V' }, { "fast", no_argument, NULL, '1' }, { "best", no_argument, NULL, '9' }, /* our own options */ { "cpu", required_argument, NULL, 'X' }, { "accelerator-type", required_argument, NULL, 'A' }, { "card_no", required_argument, NULL, 'B' }, { "software", no_argument, NULL, 's' }, { "extra", required_argument, NULL, 'E' }, { "name", required_argument, NULL, 'N' }, { "comment", required_argument, NULL, 'C' }, { "i_bufsize", required_argument, NULL, 'i' }, { "o_bufsize", required_argument, NULL, 'o' }, { 0, no_argument, NULL, 0 }, }; ch = getopt_long(argc, argv, "E:N:C:cdfqhlLsS:vV123456789?i:o:X:A:B:", long_options, &option_index); if (ch == -1) /* all params processed ? */ break; switch (ch) { case 'X': cpu = strtoul(optarg, NULL, 0); break; case 'A': accel = optarg; break; case 'B': card_no = strtol(optarg, (char **)NULL, 0); break; case 'E': extra_fname = optarg; break; case 'N': name = optarg; break; case 'C': comment = optarg; break; case 'd': compress = false; break; case 'f': force = true; break; case 'q': /* Currently does nothing, zless needs it */ quiet = true; break; case 'c': o_fp = stdout; break; case 'S': suffix = optarg; break; case 's': force_software = true; break; case 'l': list_contents++; break; case '1': level = Z_BEST_SPEED; break; case '2': level = 2; break; case '3': level = 3; break; case '4': level = 4; break; case '5': level = 5; break; case '6': level = 6; break; case '7': level = 7; break; case '8': level = 8; break; case '9': level = Z_BEST_COMPRESSION; break; case 'v': verbose++; break; case 'V': fprintf(stdout, "%s\n", version); exit(EXIT_SUCCESS); break; case 'i': CHUNK_i = str_to_num(optarg); break; case 'o': CHUNK_o = str_to_num(optarg); break; case 'L': userinfo(stdout, prog, version); exit(EXIT_SUCCESS); break; case 'h': case '?': usage(stdout, prog, argc, argv); exit(EXIT_SUCCESS); break; } } if (cpu != -1) pin_to_cpu(cpu); if (force_software) { zlib_set_inflate_impl(ZLIB_SW_IMPL); zlib_set_deflate_impl(ZLIB_SW_IMPL); } else { zlib_set_accelerator(accel, card_no); zlib_set_inflate_impl(ZLIB_HW_IMPL); zlib_set_deflate_impl(ZLIB_HW_IMPL); } /* FIXME loop over this ... */ if (optind < argc) { /* input file */ in_f = argv[optind++]; i_fp = fopen(in_f, "r"); if (!i_fp) { pr_err("%s\n", strerror(errno)); print_args(stderr, argc, argv); exit(EX_ERRNO); } rc = lstat(in_f, &s); if ((rc == 0) && S_ISLNK(s.st_mode)) { pr_err("%s: Too many levels of symbolic links\n", in_f); exit(EXIT_FAILURE); } if (list_contents) { rc = strip_ending(out_f, in_f, PATH_MAX, suffix); if (rc < 0) { pr_err("No .%s file!\n", suffix); print_args(stderr, argc, argv); exit(EXIT_FAILURE); } rc = do_list_contents(i_fp, out_f, list_contents); if (rc != 0) { pr_err("Unable to list contents.\n"); print_args(stderr, argc, argv); exit(EXIT_FAILURE); } fclose(i_fp); exit(EXIT_SUCCESS); } } if (in_f == NULL) o_fp = stdout; /* should not be a terminal! */ if (o_fp == NULL) { if (compress) snprintf(out_f, PATH_MAX, "%s.%s", in_f, suffix); else { rc = strip_ending(out_f, in_f, PATH_MAX, suffix); if (rc < 0) { pr_err("No .%s file!\n", suffix); print_args(stderr, argc, argv); exit(EXIT_FAILURE); } } rc = stat(out_f, &s); if (!force && (rc == 0)) { pr_err("File %s already exists!\n", out_f); print_args(stderr, argc, argv); exit(EX_ERRNO); } o_fp = fopen(out_f, "w+"); if (!o_fp) { pr_err("Cannot open output file %s: %s\n", out_f, strerror(errno)); print_args(stderr, argc, argv); exit(EX_ERRNO); } /* get mode settings for existing file and ... */ rc = fstat(fileno(i_fp), &s); if (rc == 0) { rc = fchmod(fileno(o_fp), s.st_mode); if (rc != 0) { pr_err("Cannot set mode %s: %s\n", out_f, strerror(errno)); exit(EX_ERRNO); } } else /* else ignore ... */ pr_err("Cannot set mode %s: %s\n", out_f, strerror(errno)); /* If output does not go to stdout and a filename is given, set it */ if (name == NULL) name = in_f; } if (isatty(fileno(o_fp))) { pr_err("Output must not be a terminal!\n"); print_args(stderr, argc, argv); exit(EXIT_FAILURE); } if (optind != argc) { /* now it must fit */ usage(stderr, prog, argc, argv); exit(EXIT_FAILURE); } in = malloc(CHUNK_i); /* This is the bigger Buffer by default */ if (NULL == in) { pr_err("%s\n", strerror(errno)); print_args(stderr, argc, argv); exit(EXIT_FAILURE); } out = malloc(CHUNK_o); /* This is the smaller Buffer by default */ if (NULL == out) { pr_err("%s\n", strerror(errno)); print_args(stderr, argc, argv); exit(EXIT_FAILURE); } /* allocate inflate state */ memset(&strm, 0, sizeof(strm)); strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; if (compress) { gz_header head; struct timeval tv; if (extra_fname) { extra_len = file_size(extra_fname); if (extra_len <= 0) { rc = extra_len; goto err_out; } extra = malloc(extra_len); if (extra == NULL) { rc = -ENOMEM; goto err_out; } rc = file_read(extra_fname, extra, extra_len); if (rc != 1) { fprintf(stderr, "err: Unable to read extra " "data rc=%d\n", rc); free(extra); goto err_out; } hexdump(stderr, extra, extra_len); } /* --------------- DEFALTE ----------------- */ rc = deflateInit2(&strm, level, Z_DEFLATED, window_bits, 8, Z_DEFAULT_STRATEGY); if (Z_OK != rc) goto err_out; memset(&head, 0, sizeof(head)); gettimeofday(&tv, NULL); head.time = tv.tv_sec; head.os = 0x03; if (extra != NULL) { head.extra = extra; head.extra_len = extra_len; head.extra_max = extra_len; } if (comment != NULL) { head.comment = (Bytef *)comment; head.comm_max = strlen(comment) + 1; } if (name != NULL) { head.name = (Bytef *)name; head.name_max = strlen(name) + 1; } rc = deflateSetHeader(&strm, &head); if (Z_OK != rc) { fprintf(stderr, "err: Cannot set gz header! rc=%d\n", rc); deflateEnd(&strm); goto err_out; } /* do compression if no arguments */ rc = def(i_fp, o_fp, &strm, in, out); if (Z_OK != rc) zerr(rc); if (extra != NULL) free(extra); deflateEnd(&strm); } else { /* --------------- INFALTE ----------------- */ strm.avail_in = 0; strm.next_in = Z_NULL; rc = inflateInit2(&strm, window_bits); if (Z_OK != rc) goto err_out; do { rc = inf(i_fp, o_fp, &strm, in, out); if (Z_STREAM_END != rc) { zerr(rc); break; } } while (!feof(i_fp) && !ferror(i_fp)); inflateEnd(&strm); } err_out: /* Delete the input file, only if input is not stdin and if output is not stdout */ if ((rc == EXIT_SUCCESS) && (i_fp != stdin) && (o_fp != stdout)) { rc = unlink(in_f); if (rc != 0) { pr_err("%s\n", strerror(errno)); print_args(stderr, argc, argv); exit(EXIT_FAILURE); } } fclose(i_fp); fclose(o_fp); free(in); free(out); exit(rc); }