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 */
}
Example #2
0
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);
}
Example #3
0
/* 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);
}