1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "razf.h"
#define WINDOW_SIZE 4096
static int razf_main_usage()
{
printf("\n");
printf("Usage: razip [options] [file] ...\n\n");
printf("Options: -c write on standard output, keep original files unchanged\n");
printf(" -d decompress\n");
printf(" -l list compressed file contents\n");
printf(" -b INT decompress at INT position in the uncompressed file\n");
printf(" -s INT decompress INT bytes in the uncompressed file\n");
printf(" -h give this help\n");
printf("\n");
return 0;
}
static int write_open(const char *fn, int is_forced)
{
int fd = -1;
char c;
if (!is_forced) {
if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC | O_EXCL, 0666)) < 0 && errno == EEXIST) {
printf("razip: %s already exists; do you wish to overwrite (y or n)? ", fn);
scanf("%c", &c);
if (c != 'Y' && c != 'y') {
printf("razip: not overwritten\n");
exit(1);
}
}
}
if (fd < 0) {
if ((fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
fprintf(stderr, "razip: %s: Fail to write\n", fn);
exit(1);
}
}
return fd;
}
int main(int argc, char **argv)
{
int c, compress, pstdout, is_forced;
RAZF *rz;
void *buffer;
long start, end, size;
compress = 1; pstdout = 0; start = 0; size = -1; end = -1; is_forced = 0;
while((c = getopt(argc, argv, "cdlhfb:s:")) >= 0){
switch(c){
case 'h': return razf_main_usage();
case 'd': compress = 0; break;
case 'c': pstdout = 1; break;
case 'l': compress = 2; break;
case 'b': start = atol(optarg); break;
case 's': size = atol(optarg); break;
case 'f': is_forced = 1; break;
}
}
if (size >= 0) end = start + size;
if(end >= 0 && end < start){
fprintf(stderr, " -- Illegal region: [%ld, %ld] --\n", start, end);
return 1;
}
if(compress == 1){
int f_src, f_dst = -1;
if(argc > optind){
if((f_src = open(argv[optind], O_RDONLY)) < 0){
fprintf(stderr, " -- Cannot open file: %s --\n", argv[optind]);
return 1;
}
if(pstdout){
f_dst = fileno(stdout);
} else {
char *name = malloc(sizeof(strlen(argv[optind]) + 5));
strcpy(name, argv[optind]);
strcat(name, ".rz");
f_dst = write_open(name, is_forced);
if (f_dst < 0) return 1;
free(name);
}
} else if(pstdout){
f_src = fileno(stdin);
f_dst = fileno(stdout);
} else return razf_main_usage();
rz = razf_dopen(f_dst, "w");
buffer = malloc(WINDOW_SIZE);
while((c = read(f_src, buffer, WINDOW_SIZE)) > 0) razf_write(rz, buffer, c);
razf_close(rz); // f_dst will be closed here
if (argc > optind && !pstdout) unlink(argv[optind]);
free(buffer);
close(f_src);
return 0;
} else {
if(argc <= optind) return razf_main_usage();
if(compress == 2){
rz = razf_open(argv[optind], "r");
if(rz->file_type == FILE_TYPE_RZ) {
printf("%20s%20s%7s %s\n", "compressed", "uncompressed", "ratio", "name");
printf("%20lld%20lld%6.1f%% %s\n", (long long)rz->end, (long long)rz->src_end, rz->end * 100.0f / rz->src_end,
argv[optind]);
} else fprintf(stdout, "%s is not a regular rz file\n", argv[optind]);
} else {
int f_dst;
if (argc > optind && !pstdout) {
char *name;
if (strstr(argv[optind], ".rz") - argv[optind] != strlen(argv[optind]) - 3) {
printf("razip: %s: unknown suffix -- ignored\n", argv[optind]);
return 1;
}
name = strdup(argv[optind]);
name[strlen(name) - 3] = '\0';
f_dst = write_open(name, is_forced);
free(name);
} else f_dst = fileno(stdout);
rz = razf_open(argv[optind], "r");
buffer = malloc(WINDOW_SIZE);
razf_seek(rz, start, SEEK_SET);
while(1){
if(end < 0) c = razf_read(rz, buffer, WINDOW_SIZE);
else c = razf_read(rz, buffer, (end - start > WINDOW_SIZE)? WINDOW_SIZE:(end - start));
if(c <= 0) break;
start += c;
write(f_dst, buffer, c);
if(end >= 0 && start >= end) break;
}
free(buffer);
if (!pstdout) unlink(argv[optind]);
}
razf_close(rz);
return 0;
}
}
|