/* * This file is from embutils-0.18, which is GPL Version 2, June 1991. * I included 4 extra headers so it would build on Glibc, and changed the * write(2) to make GCC happy. * ashes */ #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include #include #include /* * if=FILE read from FILE instead of stdin * of=FILE write to FILE instead of stdout * * ibs=BYTES read BYTES bytes at a time * obs=BYTES write BYTES bytes at a time * bs=BYTES ibs=obs=BYTES * * count=BLOCKS copy only BLOCKS input blocks * * seek=BLOCKS skip BLOCKS obs-sized blocks at start of output * skip=BLOCKS skip BLOCKS ibs-sized blocks at start of input * * missing: * conv=TYPE * cbs=BYTES convert only BYTES bytes at a time */ void die(const char* s,const char* p) { struct iovec tmp[4] = { { (void*)s, strlen(s) }, {" ",1}, { (void*)p, strlen(p) }, {"\n", 1} }; writev(2,tmp,4); exit(0); } #define PAGE_ALIGN(s) (((s)+(PAGE_SIZE-1))&(~(PAGE_SIZE-1))) void *get_block(size_t size) { return mmap(0,PAGE_ALIGN(size),PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0); } void seek_skip(int fd, size_t count, size_t block) { char *buf=get_block(block); size_t dist=count*block; if (lseek(fd,SEEK_CUR,dist)==-1) { for (;dist && count;count--) { if ((dist=read(fd,buf,block))==-1) { die("error while","seek/skip"); } } } munmap(buf,PAGE_ALIGN(block)); } static inline unsigned int SOUL() { return (sizeof(unsigned long)==8)?64:32; } size_t get_block_size(const char *s) { size_t ret=0; char *r=0; ret=strtoul(s, &r, 10); if (s==r) return 0; if (*r==0) ; /* no size type */ else if (*r=='c') ; else if ((*r=='w')&&(!(ret&(1<<(SOUL()-1))))) ret<<=1; else if ((*r=='b')&&(ret<(1<<(SOUL()- 9)))) ret<<=9; else if ((*r=='k')&&(ret<(1<<(SOUL()-10)))) ret<<=10; else if ((*r=='M')&&(ret<(1<<(SOUL()-20)))) ret<<=20; else if ((*r=='G')&&(ret<(1<<(SOUL()-30)))) ret<<=30; else die("unknown or too large block:",s); return ret; } int main(int argc, char *argv[]) { int in=0, out=1, i; void *ibuf, *obuf; size_t ibs=512, obs=512,obn=0; size_t count=(size_t)-1; size_t seek=0, skip=0; size_t inumber,onumber; { for (i=1;i=obs) { register size_t d=(obs-obn); memcpy(obuf+obn,tmp,d); obn=0; if (write(out,obuf,obs)!=obs) die("error while","write output"); ++onumber; tmp+=d; n=m-obs; } } m=n; for (;m>=obs;m-=obs) { if (write(out,tmp,obs)!=obs) die("error while","write output"); ++onumber; tmp+=obs; } if (m) { memcpy(obuf+obn,tmp,m); obn+=m; } if (b) break; } if ((obn) && (write(out,obuf,obn))) return 0; }