#define _LARGEFILE64_SOURCE 1 #include #include #include #include #include #include #include #include #include #define DEF_BLOCK 1024 #ifndef LLONG_MAX # define LLONG_MAX 9223372036854775807LL #endif char *pname; static void msg(const char *fmt,...) { va_list ap; time_t tm=time(NULL); char *ts=ctime(&tm),*s; if ((s=strchr(ts,'\n'))) *s='\0'; fprintf(stderr,"%s: %s - ",pname,ts); va_start(ap,fmt); vfprintf(stderr,fmt,ap); va_end(ap); fputc('\n',stderr); } int main(int argc,char **argv) { int block=DEF_BLOCK,r,fd; char *buf; long long offs=0,offs2=0,totsize=-1,forcedsize=0; pname=argv[0]; if (argc>1) { if ((fd=open(argv[1],O_RDONLY #ifdef O_BINARY |O_BINARY #endif ))==-1) { msg("open(\"%s\") error: %m",argv[1]); return(EXIT_FAILURE); } if (argc>2) { block=atoi(argv[2]); if (block<1||block>=INT_MAX) { block=DEF_BLOCK; msg("Forced block size %d",block); } } if (argc>3) { forcedsize=atoll(argv[3]); if (forcedsize<1||forcedsize>=LLONG_MAX) { forcedsize=0; msg("Total size NOT forced"); } } } else fd=STDIN_FILENO; if (!(buf=malloc(block))) { msg("Error allocating buffer, size=%d",block); return(EXIT_FAILURE); } if (!(totsize=forcedsize)) { if ((totsize=lseek64(fd,0,SEEK_END))>0) { if ((offs2=lseek64(fd,0,SEEK_SET))) msg("Error back-lseek64(0,SEEK_SET)=%Ld: %m",offs2); } } if (totsize) msg("Starting, size=%Ld...",totsize); else msg("Starting, size unknown...",totsize); while (errno=0,(r=read(fd,buf,block))) { if (r<0) { msg("read %Ld:%Ld(%u): %m",offs,offs+block,block); if (fd==STDIN_FILENO) { msg("Error skipping from stdin not supported!"); return(EXIT_FAILURE); } offs+=block; if ((offs2=lseek64(STDIN_FILENO,offs,SEEK_SET))!=offs) { /* FIXME */ msg("Error recovery lseek64(%Ld,SEEK_SET)=%Ld: %m",offs,offs2); return(EXIT_FAILURE); } continue; } offs+=r; printf("%Ld",offs); if (totsize>0) printf("/%Ld",totsize); putchar('\r'); fflush(stdout); } msg("Finished, total read %Ld.",offs); return(EXIT_SUCCESS); }