Example #1
0
int compress_file(void)
{
	FILE *in = NULL, *out = NULL;
	unsigned char *inbuf = NULL, *outbuf = NULL, *level_buf = NULL;
	size_t inbuf_size, outbuf_size;
	int level_size = 0;
	struct isal_zstream stream;
	struct isal_gzip_header gz_hdr;
	int ret, success = 0;

	char *infile_name = global_options.infile_name, *outfile_name =
	    global_options.outfile_name;
	char *suffix = global_options.suffix;
	size_t infile_name_len = global_options.infile_name_len;
	size_t outfile_name_len = global_options.outfile_name_len;
	size_t suffix_len = global_options.suffix_len;

	int level = global_options.level;

	if (suffix == NULL) {
		suffix = default_suffixes[0];
		suffix_len = default_suffixes_lens[0];
	}

	if (infile_name_len == stdin_file_name_len &&
	    memcmp(infile_name, stdin_file_name, infile_name_len) == 0) {
		infile_name = NULL;
		infile_name_len = 0;
	}

	if (outfile_name == NULL && infile_name != NULL && !global_options.use_stdout) {
		outfile_name_len = infile_name_len + suffix_len;
		outfile_name = malloc_safe(outfile_name_len + 1);
		strcpy(outfile_name, infile_name);
		strcat(outfile_name, suffix);
	}

	open_in_file(&in, infile_name);
	if (in == NULL)
		goto compress_file_cleanup;

	if (infile_name_len != 0 && infile_name_len == outfile_name_len
	    && strncmp(infile_name, outfile_name, infile_name_len) == 0) {
		log_print(ERROR, "igzip: Error input and output file names must differ\n");
		goto compress_file_cleanup;
	}

	open_out_file(&out, outfile_name);
	if (out == NULL)
		goto compress_file_cleanup;

	inbuf_size = BLOCK_SIZE;
	outbuf_size = BLOCK_SIZE;

	inbuf = malloc_safe(inbuf_size);
	outbuf = malloc_safe(outbuf_size);
	level_size = level_size_buf[level];
	level_buf = malloc_safe(level_size);

	isal_gzip_header_init(&gz_hdr);
	if (global_options.name == NAME_DEFAULT || global_options.name == YES_NAME) {
		gz_hdr.time = get_posix_filetime(in);
		gz_hdr.name = infile_name;
	}
	gz_hdr.os = UNIX;
	gz_hdr.name_buf_len = infile_name_len + 1;

	isal_deflate_init(&stream);
	stream.avail_in = 0;
	stream.flush = NO_FLUSH;
	stream.level = level;
	stream.level_buf = level_buf;
	stream.level_buf_size = level_size;
	stream.gzip_flag = IGZIP_GZIP_NO_HDR;
	stream.next_out = outbuf;
	stream.avail_out = outbuf_size;

	isal_write_gzip_header(&stream, &gz_hdr);

	do {
		if (stream.avail_in == 0) {
			stream.next_in = inbuf;
			stream.avail_in =
			    fread_safe(stream.next_in, 1, inbuf_size, in, infile_name);
			stream.end_of_stream = feof(in);
		}

		if (stream.next_out == NULL) {
			stream.next_out = outbuf;
			stream.avail_out = outbuf_size;
		}

		ret = isal_deflate(&stream);

		if (ret != ISAL_DECOMP_OK) {
			log_print(ERROR,
				  "igzip: Error encountered while compressing file %s\n",
				  infile_name);
			goto compress_file_cleanup;
		}

		fwrite_safe(outbuf, 1, stream.next_out - outbuf, out, outfile_name);
		stream.next_out = NULL;

	} while (!feof(in) || stream.avail_out == 0);
	success = 1;

      compress_file_cleanup:
	if (out != NULL && out != stdout)
		fclose(out);

	if (in != NULL && in != stdin) {
		fclose(in);
		if (success && global_options.remove)
			remove(infile_name);
	}

	if (global_options.outfile_name == NULL && outfile_name != NULL)
		free(outfile_name);

	if (inbuf != NULL)
		free(inbuf);

	if (outbuf != NULL)
		free(outbuf);

	if (level_buf != NULL)
		free(level_buf);

	return (success == 0);
}
Example #2
0
int decompress_file(void)
{
	FILE *in = NULL, *out = NULL;
	unsigned char *inbuf = NULL, *outbuf = NULL;
	size_t inbuf_size, outbuf_size;
	struct inflate_state state;
	struct isal_gzip_header gz_hdr;
	const int terminal = 0, implicit = 1, stripped = 2;
	int ret = 0, success = 0, outfile_type = terminal;

	char *infile_name = global_options.infile_name, *outfile_name =
	    global_options.outfile_name;
	char *suffix = global_options.suffix;
	size_t infile_name_len = global_options.infile_name_len;
	size_t outfile_name_len = global_options.outfile_name_len;
	size_t suffix_len = global_options.suffix_len;
	int suffix_index = 0;
	uint32_t file_time;

	if (infile_name_len == stdin_file_name_len &&
	    memcmp(infile_name, stdin_file_name, infile_name_len) == 0) {
		infile_name = NULL;
		infile_name_len = 0;
	}

	if (outfile_name == NULL && !global_options.use_stdout) {
		if (infile_name != NULL) {
			outfile_type = stripped;
			while (suffix_index <
			       sizeof(default_suffixes) / sizeof(*default_suffixes)) {
				if (suffix == NULL) {
					suffix = default_suffixes[suffix_index];
					suffix_len = default_suffixes_lens[suffix_index];
					suffix_index++;
				}

				outfile_name_len = infile_name_len - suffix_len;
				if (infile_name_len >= suffix_len
				    && memcmp(infile_name + outfile_name_len, suffix,
					      suffix_len) == 0)
					break;
				suffix = NULL;
				suffix_len = 0;
			}

			if (suffix == NULL && global_options.test == NO_TEST) {
				log_print(ERROR, "igzip: %s: unknown suffix -- ignored\n",
					  infile_name);
				return 1;
			}
		}
		if (global_options.name == YES_NAME) {
			outfile_name_len = 0;
			outfile_type = implicit;
		}
		if (outfile_type != terminal)
			outfile_name = malloc_safe(outfile_name_len >=
						   MAX_FILEPATH_BUF ? outfile_name_len +
						   1 : MAX_FILEPATH_BUF);
	}

	open_in_file(&in, infile_name);
	if (in == NULL)
		goto decompress_file_cleanup;

	file_time = get_posix_filetime(in);

	inbuf_size = BLOCK_SIZE;
	outbuf_size = BLOCK_SIZE;

	inbuf = malloc_safe(inbuf_size);
	outbuf = malloc_safe(outbuf_size);

	isal_gzip_header_init(&gz_hdr);
	if (outfile_type == implicit) {
		gz_hdr.name = outfile_name;
		gz_hdr.name_buf_len = MAX_FILEPATH_BUF;
	}

	isal_inflate_init(&state);
	state.crc_flag = ISAL_GZIP_NO_HDR_VER;
	state.next_in = inbuf;
	state.avail_in = fread_safe(state.next_in, 1, inbuf_size, in, infile_name);

	ret = isal_read_gzip_header(&state, &gz_hdr);
	if (ret != ISAL_DECOMP_OK) {
		log_print(ERROR, "igzip: Error invalid gzip header found for file %s\n",
			  infile_name);
		goto decompress_file_cleanup;
	}

	if (outfile_type == implicit)
		file_time = gz_hdr.time;

	if (outfile_type == stripped || (outfile_type == implicit && outfile_name[0] == 0)) {
		outfile_name_len = infile_name_len - suffix_len;
		memcpy(outfile_name, infile_name, outfile_name_len);
		outfile_name[outfile_name_len] = 0;
	}

	if (infile_name_len != 0 && infile_name_len == outfile_name_len
	    && strncmp(infile_name, outfile_name, infile_name_len) == 0) {
		log_print(ERROR, "igzip: Error input and output file names must differ\n");
		goto decompress_file_cleanup;
	}

	if (global_options.test == NO_TEST) {
		open_out_file(&out, outfile_name);
		if (out == NULL)
			goto decompress_file_cleanup;
	}

	do {
		if (state.avail_in == 0) {
			state.next_in = inbuf;
			state.avail_in =
			    fread_safe(state.next_in, 1, inbuf_size, in, infile_name);
		}

		state.next_out = outbuf;
		state.avail_out = outbuf_size;

		ret = isal_inflate(&state);
		if (ret != ISAL_DECOMP_OK) {
			log_print(ERROR,
				  "igzip: Error encountered while decompressing file %s\n",
				  infile_name);
			goto decompress_file_cleanup;
		}

		if (out != NULL)
			fwrite_safe(outbuf, 1, state.next_out - outbuf, out, outfile_name);

	} while (!feof(in) || state.avail_out == 0);

	if (state.block_state != ISAL_BLOCK_FINISH)
		log_print(ERROR, "igzip: Error %s does not contain a complete gzip file\n",
			  infile_name);
	else
		success = 1;

      decompress_file_cleanup:
	if (out != NULL && out != stdout) {
		fclose(out);
		if (success)
			set_filetime(outfile_name, file_time);
	}

	if (in != NULL && in != stdin) {
		fclose(in);
		if (success && global_options.remove)
			remove(infile_name);
	}

	if (global_options.outfile_name == NULL && outfile_name != NULL)
		free(outfile_name);

	if (inbuf != NULL)
		free(inbuf);

	if (outbuf != NULL)
		free(outbuf);

	return (success == 0);
}
Example #3
0
static
rc_t	run_kar_create(const char * archive, const char * directory)
{
    rc_t rc;
    const KFile * fin;
    KFile * fout;

    rc = open_out_file (archive, &fout);
    if (rc == 0)
    {
        char * directorystr;

        rc = derive_directory_name (&directorystr, archive, directory);

        if (rc != 0)
            LOGERR (klogErr, rc,"failed to derive directory name");
        else
        {
            assert (directorystr != NULL);
            assert (directorystr[0] != '\0');

            STSMSG (4, ("start creation of archive"));

            /* Jira ticket: SRA-1876
               Date: September 13, 2013
               raw usage of "directorystr" causes tests to fail within libs/kfs/arc.c */
            {
                char full [ 4096 ];
                rc = KDirectoryResolvePath ( kdir, true, full, sizeof full, "%s", directorystr );
                if ( rc == 0 )
                {
                    /* string should be non-empty based upon behavior of
                       "derive_directory_name" ( also fixed today ) */
                    assert ( full [ 0 ] != 0 );

                    /* eliminate double-slashes */
                    if ( full [ 1 ] != 0 )
                    {
                        uint32_t i, j;

                        /* ALLOW double slashes at the very start
                           set starting index to 2 for that reason */
                        for ( i = j = 2; full [ i ] != 0; ++ i )
                        {
                            if ( ( full [ j ] = full [ i ] ) != '/' || full [ j - 1 ] != '/' )
                                ++ j;
                        }

                        full [ j ] = 0;
                    }

                    rc = open_dir_as_archive ( full, & fin );
                }
            }
            if (rc != 0)
                PLOGERR (klogErr, (klogErr, rc,"failed to open directory '$(D)' as archive",
                                   PLOG_S(D),directorystr));
            else
            {
                assert (fin != NULL);
                assert (fout != NULL);

                STSMSG (4, ("start copy_file"));
                rc = copy_file (fin, fout);
                if (rc != 0)
                    LOGERR (klogErr, rc, "failed copy file in create");
                KFileRelease (fin);
            }
        }
        KFileRelease (fout);
        free (directorystr);

        if (rc)
        {
            remove_out_file (archive);
        }

    }
    return rc;
}