add gzip, bzip2
'
This commit is contained in:
parent
4314729dde
commit
ff3adf6082
44 changed files with 9880 additions and 2 deletions
186
src/cmd/bzip2/bunzip2.c
Normal file
186
src/cmd/bzip2/bunzip2.c
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <bio.h>
|
||||
#include "bzlib.h"
|
||||
|
||||
static Biobuf bin;
|
||||
static int debug;
|
||||
static int verbose;
|
||||
static char *delfile;
|
||||
static char *infile;
|
||||
static int bunzipf(char *file, int stdout);
|
||||
static int bunzip(int ofd, char *ofile, Biobuf *bin);
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "usage: bunzip2 [-cvD] [file ...]\n");
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
int i, ok, stdout;
|
||||
|
||||
stdout = 0;
|
||||
ARGBEGIN{
|
||||
case 'D':
|
||||
debug++;
|
||||
break;
|
||||
case 'c':
|
||||
stdout++;
|
||||
break;
|
||||
case 'v':
|
||||
verbose++;
|
||||
break;
|
||||
}ARGEND
|
||||
|
||||
if(argc == 0){
|
||||
Binit(&bin, 0, OREAD);
|
||||
infile = "<stdin>";
|
||||
ok = bunzip(1, "<stdout>", &bin);
|
||||
}else{
|
||||
ok = 1;
|
||||
for(i = 0; i < argc; i++)
|
||||
ok &= bunzipf(argv[i], stdout);
|
||||
}
|
||||
|
||||
exits(ok ? nil: "errors");
|
||||
}
|
||||
|
||||
static int
|
||||
bunzipf(char *file, int stdout)
|
||||
{
|
||||
char ofile[64], *s;
|
||||
int ofd, ifd, ok;
|
||||
|
||||
infile = file;
|
||||
ifd = open(file, OREAD);
|
||||
if(ifd < 0){
|
||||
fprint(2, "gunzip: can't open %s: %r\n", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Binit(&bin, ifd, OREAD);
|
||||
if(Bgetc(&bin) != 'B' || Bgetc(&bin) != 'Z' || Bgetc(&bin) != 'h'){
|
||||
fprint(2, "bunzip2: %s is not a bzip2 file\n", file);
|
||||
Bterm(&bin);
|
||||
close(ifd);
|
||||
return 0;
|
||||
}
|
||||
Bungetc(&bin);
|
||||
Bungetc(&bin);
|
||||
Bungetc(&bin);
|
||||
|
||||
if(stdout){
|
||||
ofd = 1;
|
||||
strcpy(ofile, "<stdout>");
|
||||
}else{
|
||||
s = strrchr(file, '/');
|
||||
if(s != nil)
|
||||
s++;
|
||||
else
|
||||
s = file;
|
||||
strecpy(ofile, ofile+sizeof ofile, s);
|
||||
s = strrchr(ofile, '.');
|
||||
if(s != nil && s != ofile && strcmp(s, ".bz2") == 0)
|
||||
*s = '\0';
|
||||
else if(s != nil && (strcmp(s, ".tbz") == 0 || strcmp(s, ".tbz2") == 0))
|
||||
strcpy(s, ".tar");
|
||||
else if(strcmp(file, ofile) == 0){
|
||||
fprint(2, "bunzip2: can't overwrite %s\n", file);
|
||||
Bterm(&bin);
|
||||
close(ifd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ofd = create(ofile, OWRITE, 0666);
|
||||
if(ofd < 0){
|
||||
fprint(2, "bunzip2: can't create %s: %r\n", ofile);
|
||||
Bterm(&bin);
|
||||
close(ifd);
|
||||
return 0;
|
||||
}
|
||||
delfile = ofile;
|
||||
}
|
||||
|
||||
ok = bunzip(ofd, ofile, &bin);
|
||||
Bterm(&bin);
|
||||
close(ifd);
|
||||
if(!ok){
|
||||
fprint(2, "bunzip2: can't write %s: %r\n", ofile);
|
||||
if(delfile)
|
||||
remove(delfile);
|
||||
}
|
||||
delfile = nil;
|
||||
if(!stdout && ofd >= 0)
|
||||
close(ofd);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static int
|
||||
bunzip(int ofd, char *ofile, Biobuf *bin)
|
||||
{
|
||||
int e, n, done, onemore;
|
||||
char buf[8192];
|
||||
char obuf[8192];
|
||||
Biobuf bout;
|
||||
bz_stream strm;
|
||||
|
||||
USED(ofile);
|
||||
|
||||
memset(&strm, 0, sizeof strm);
|
||||
BZ2_bzDecompressInit(&strm, verbose, 0);
|
||||
|
||||
strm.next_in = buf;
|
||||
strm.avail_in = 0;
|
||||
strm.next_out = obuf;
|
||||
strm.avail_out = sizeof obuf;
|
||||
|
||||
done = 0;
|
||||
Binit(&bout, ofd, OWRITE);
|
||||
|
||||
/*
|
||||
* onemore is a crummy hack to go 'round the loop
|
||||
* once after we finish, to flush the output buffer.
|
||||
*/
|
||||
onemore = 1;
|
||||
SET(e);
|
||||
do {
|
||||
if(!done && strm.avail_in < sizeof buf) {
|
||||
if(strm.avail_in)
|
||||
memmove(buf, strm.next_in, strm.avail_in);
|
||||
|
||||
n = Bread(bin, buf+strm.avail_in, sizeof(buf)-strm.avail_in);
|
||||
if(n <= 0)
|
||||
done = 1;
|
||||
else
|
||||
strm.avail_in += n;
|
||||
strm.next_in = buf;
|
||||
}
|
||||
if(strm.avail_out < sizeof obuf) {
|
||||
Bwrite(&bout, obuf, sizeof(obuf)-strm.avail_out);
|
||||
strm.next_out = obuf;
|
||||
strm.avail_out = sizeof obuf;
|
||||
}
|
||||
if(onemore == 0)
|
||||
break;
|
||||
if(strm.avail_in == 0 && strm.avail_out == sizeof obuf)
|
||||
break;
|
||||
} while((e=BZ2_bzDecompress(&strm)) == BZ_OK || onemore--);
|
||||
|
||||
if(e != BZ_STREAM_END) {
|
||||
fprint(2, "bunzip2: decompress failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(BZ2_bzDecompressEnd(&strm) != BZ_OK) {
|
||||
fprint(2, "bunzip2: decompress end failed (can't happen)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
Bterm(&bout);
|
||||
|
||||
return 1;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue