/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. *//* * bsplit - split big binaries (copy-less plan 9 version) */#include <u.h>#include <libc.h>#include <authsrv.h> /* for ANAMELEN */enum { Stdin, Sectsiz = 512, Bufsiz = 256*Sectsiz,};/* disk address (in bytes or sectors), also type of 2nd arg. to seek */typedef uvlong Daddr;#define BLEN(s) ((s)->wp - (s)->rp)#define BALLOC(s) ((s)->lim - (s)->base)typedef struct { uchar* rp; /* first unconsumed byte */ uchar* wp; /* first empty byte */ uchar* lim; /* 1 past the end of the buffer */ uchar* base; /* start of the buffer */} Buffer;typedef struct { /* parameters */ Daddr maxoutsz; /* maximum size of output file(s) */ Daddr fileout; /* bytes written to the current output file */ char *filenm; int filesz; /* size of filenm */ char *prefix; long filenum; int outf; /* open output file */ Buffer buff;} Copy;/* global data */char *argv0;/* private data */static Copy cp = { 512*1024*1024 }; /* default maximum size */static int debug;static voidbufreset(Buffer *bp){ bp->rp = bp->wp = bp->base;}static voidbufinit(Buffer *bp, uchar *block, unsigned size){ bp->base = block; bp->lim = bp->base + size; bufreset(bp);}static int eopen(char *file, int mode){ int fd = open(file, mode); if (fd < 0) sysfatal("can't open %s: %r", file); return fd;}static int ecreate(char *file, int mode){ int fd = create(file, mode, 0666); if (fd < 0) sysfatal("can't create %s: %r", file); return fd;}static char *filename(Copy *cp){ return cp->filenm;}static int opennext(Copy *cp){ if (cp->outf >= 0) sysfatal("opennext called with file open"); snprint(cp->filenm, cp->filesz, "%s%5.5ld", cp->prefix, cp->filenum++); cp->outf = ecreate(cp->filenm, OWRITE); cp->fileout = 0; return cp->outf;}static int closeout(Copy *cp){ if (cp->outf >= 0) { if (close(cp->outf) < 0) sysfatal("error writing %s: %r", filename(cp)); cp->outf = -1; cp->fileout = 0; } return cp->outf;}/* * process - process input file */static voidprocess(int in, char *inname){ int n = 1; unsigned avail, tolim, wsz; Buffer *bp = &cp.buff; USED(inname); do { if (BLEN(bp) == 0) { if (bp->lim == bp->wp) bufreset(bp); n = read(in, bp->wp, bp->lim - bp->wp); if (n <= 0) break; bp->wp += n; } if (cp.outf < 0) opennext(&cp); /* * write from buffer's current point to end or enough bytes to * reach file-size limit. */ avail = BLEN(bp); tolim = cp.maxoutsz - cp.fileout; wsz = (tolim < avail? tolim: avail); /* try to write full sectors */ if (tolim >= avail && n > 0 && wsz >= Sectsiz) wsz = (wsz / Sectsiz) * Sectsiz; if (write(cp.outf, bp->rp, wsz) != wsz) sysfatal("error writing %s: %r", filename(&cp)); bp->rp += wsz; cp.fileout += wsz; if (cp.fileout >= cp.maxoutsz) closeout(&cp); } while (n > 0 || BLEN(bp) != 0);}static voidusage(void){ fprint(2, "usage: %s [-d][-p pfx][-s size] [file...]\n", argv0); exits("usage");}voidmain(int argc, char **argv){ int i, errflg = 0; uchar block[Bufsiz]; cp.prefix = "bs."; ARGBEGIN { case 'd': debug++; break; case 'p': cp.prefix = EARGF(usage()); break; case 's': cp.maxoutsz = atoll(EARGF(usage())); if (cp.maxoutsz < 1) errflg++; break; default: errflg++; break; } ARGEND if (errflg || argc < 0) usage(); bufinit(&cp.buff, block, sizeof block); cp.outf = -1; cp.filesz = strlen(cp.prefix) + 2*ANAMELEN; /* 2* is slop */ cp.filenm = malloc(cp.filesz + 1); if (cp.filenm == nil) sysfatal("no memory: %r"); if (argc == 0) process(Stdin, "/fd/0"); else for (i = 0; i < argc; i++) { int in = eopen(argv[i], OREAD); process(in, argv[i]); close(in); } closeout(&cp); exits(0);}
/*
* This file is part of the UCB release of Plan 9. It is subject to the license
* terms in the LICENSE file found in the top-level directory of this
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
* part of the UCB release of Plan 9, including this file, may be copied,
* modified, propagated, or distributed except according to the terms contained
* in the LICENSE file.
*/
/*
* bsplit - split big binaries (copy-less plan 9 version)
*/
#include <u.h>
#include <libc.h>
#include <authsrv.h> /* for ANAMELEN */
enum {
Stdin,
Sectsiz = 512,
Bufsiz = 256*Sectsiz,
};
/* disk address (in bytes or sectors), also type of 2nd arg. to seek */
typedef uvlong Daddr;
#define BLEN(s) ((s)->wp - (s)->rp)
#define BALLOC(s) ((s)->lim - (s)->base)
typedef struct {
uchar* rp; /* first unconsumed byte */
uchar* wp; /* first empty byte */
uchar* lim; /* 1 past the end of the buffer */
uchar* base; /* start of the buffer */
} Buffer;
typedef struct {
/* parameters */
Daddr maxoutsz; /* maximum size of output file(s) */
Daddr fileout; /* bytes written to the current output file */
char *filenm;
int filesz; /* size of filenm */
char *prefix;
long filenum;
int outf; /* open output file */
Buffer buff;
} Copy;
/* global data */
char *argv0;
/* private data */
static Copy cp = { 512*1024*1024 }; /* default maximum size */
static int debug;
static void
bufreset(Buffer *bp)
{
bp->rp = bp->wp = bp->base;
}
static void
bufinit(Buffer *bp, uchar *block, unsigned size)
{
bp->base = block;
bp->lim = bp->base + size;
bufreset(bp);
}
static int
eopen(char *file, int mode)
{
int fd = open(file, mode);
if (fd < 0)
sysfatal("can't open %s: %r", file);
return fd;
}
static int
ecreate(char *file, int mode)
{
int fd = create(file, mode, 0666);
if (fd < 0)
sysfatal("can't create %s: %r", file);
return fd;
}
static char *
filename(Copy *cp)
{
return cp->filenm;
}
static int
opennext(Copy *cp)
{
if (cp->outf >= 0)
sysfatal("opennext called with file open");
snprint(cp->filenm, cp->filesz, "%s%5.5ld", cp->prefix, cp->filenum++);
cp->outf = ecreate(cp->filenm, OWRITE);
cp->fileout = 0;
return cp->outf;
}
static int
closeout(Copy *cp)
{
if (cp->outf >= 0) {
if (close(cp->outf) < 0)
sysfatal("error writing %s: %r", filename(cp));
cp->outf = -1;
cp->fileout = 0;
}
return cp->outf;
}
/*
* process - process input file
*/
static void
process(int in, char *inname)
{
int n = 1;
unsigned avail, tolim, wsz;
Buffer *bp = &cp.buff;
USED(inname);
do {
if (BLEN(bp) == 0) {
if (bp->lim == bp->wp)
bufreset(bp);
n = read(in, bp->wp, bp->lim - bp->wp);
if (n <= 0)
break;
bp->wp += n;
}
if (cp.outf < 0)
opennext(&cp);
/*
* write from buffer's current point to end or enough bytes to
* reach file-size limit.
*/
avail = BLEN(bp);
tolim = cp.maxoutsz - cp.fileout;
wsz = (tolim < avail? tolim: avail);
/* try to write full sectors */
if (tolim >= avail && n > 0 && wsz >= Sectsiz)
wsz = (wsz / Sectsiz) * Sectsiz;
if (write(cp.outf, bp->rp, wsz) != wsz)
sysfatal("error writing %s: %r", filename(&cp));
bp->rp += wsz;
cp.fileout += wsz;
if (cp.fileout >= cp.maxoutsz)
closeout(&cp);
} while (n > 0 || BLEN(bp) != 0);
}
static void
usage(void)
{
fprint(2, "usage: %s [-d][-p pfx][-s size] [file...]\n", argv0);
exits("usage");
}
void
main(int argc, char **argv)
{
int i, errflg = 0;
uchar block[Bufsiz];
cp.prefix = "bs.";
ARGBEGIN {
case 'd':
debug++;
break;
case 'p':
cp.prefix = EARGF(usage());
break;
case 's':
cp.maxoutsz = atoll(EARGF(usage()));
if (cp.maxoutsz < 1)
errflg++;
break;
default:
errflg++;
break;
} ARGEND
if (errflg || argc < 0)
usage();
bufinit(&cp.buff, block, sizeof block);
cp.outf = -1;
cp.filesz = strlen(cp.prefix) + 2*ANAMELEN; /* 2* is slop */
cp.filenm = malloc(cp.filesz + 1);
if (cp.filenm == nil)
sysfatal("no memory: %r");
if (argc == 0)
process(Stdin, "/fd/0");
else
for (i = 0; i < argc; i++) {
int in = eopen(argv[i], OREAD);
process(in, argv[i]);
close(in);
}
closeout(&cp);
exits(0);
}