#include #include #include #include #include #define __imdumb(one,two,three) strncpy(one,three,two) int openOutputs(const char** ops, FILE*** fps, int* _cnt) { int ok =0; register int cnt = 0; for(;ops[cnt];cnt++); (void)0; *_cnt = cnt; if (cnt < 1) return -1; else { *fps = malloc(sizeof(FILE**)*cnt); for (int i=0;i0) { snprintf(buf, 255, "%.2f g", _D(lsz, (1024*2014*1024))); return buf; } mb = sz / (1024+1024); sz %= (1024*1024); if(mb>0) { snprintf(buf, 255, "%.2f m", _D(lsz, (1024*2014))); return buf; } kb = sz / 1024; sz %= 1024; if(kb>0) { snprintf(buf, 255, "%.2f k", _D(lsz, 1024)); return buf; } b = sz; snprintf(buf, 255, "%u b", (unsigned int)lsz); return buf; } char* secstr(double tm) { static char buf[256]; double sec = tm; int min,hr; min=hr=0; while(sec>=60.0) { min +=1; sec-=6.0; } while(min>=60) { hr +=1; min -= 60; } char* _buf=buf; int sz= 255; memset(_buf,0,256); if(hr>0) { snprintf(_buf, sz, "%d h ", hr); sz -= strlen(_buf); _buf+=strlen(_buf); } if(min>0) { snprintf(_buf, sz, "%d m ", min); sz -= strlen(_buf); _buf+=strlen(_buf); } snprintf(_buf, sz, "%.2f s", sec); return buf; } char* remain(size_t small, size_t large, double bps) { static char buf[256]; memset(buf,0,256); if(bps==0) __imdumb(buf, 255, "?"); else { double vl = (large-small)/bps; __imdumb(buf, 255, secstr(vl)); } return buf; } struct lastp { int fnum; int f2dp; int b2dp; char rem[256]; }; int lastp_equalp(const struct lastp *v1, const struct lastp *v2) { return memcmp(v1, v2, sizeof(struct lastp)) == 0; } void progress(size_t small, size_t large, size_t inc, time_t start, time_t elapsed) { static char* largesz = NULL; static char befores[256]; static struct lastp *lastvls = NULL; struct lastp thisvls; if(!largesz) largesz = strdup(humanbytes(large)); double frac = ((double)small)/((double)large); double pct = (long)(frac*PROGRESS_SIZE); double before = ((double)small)/((double)(elapsed-start)); if(lastvls == NULL) { lastvls = malloc(sizeof(struct lastp)); memset(lastvls, 0, sizeof(struct lastp)); } else { memset(&thisvls, 0, sizeof(struct lastp)); thisvls.fnum = (int) (frac*PROGRESS_SIZE); thisvls.f2dp = (int)round(frac*100.00 *100.00); thisvls.b2dp = (int)round(before*100.00); __imdumb(thisvls.rem, 255, remain(small,large,before)); if (lastp_equalp(&thisvls, lastvls)) return; } memset(befores, 0, 256); __imdumb(befores, 255, humanbytes((size_t)before)); //printf("%c[2K", 27); printf("\r["); for(register int i=0;i \n", argv[0]); } else { if(output[0][0] == '-') { flag(output[0]+1); output+=1; goto redo; } FILE* finput = fopen(input, "rb"); if(!input) printf("Error: could not open `%s' for reading.\n", input); else { size_t input_sz = sizeof_file(finput); FILE** foutput; int ok, cnt; if((ok = openOutputs(output, &foutput, &cnt))>=0) { if(ok==1&& !ask("\nOne or more outputs failed to open, continue? (y/N) ")) printf("Error: aborted\n"); else { printf("Will copy %s to %d files with a blocksize of %d\n", humanbytes(input_sz), cnt, BLOCKSIZE); time_t start = time(NULL); int rd; size_t read=0; while( (rd=copyBlock(finput, foutput, cnt))>0) { read+=rd; progress(read, input_sz, rd,start, time(NULL)); } time_t end = time(NULL); char* dDone = strdup(humanbytes(read)); printf("\n\nCopied %s to %d files in %s. (~%s /s)\n", dDone, cnt, secstr(end-start), humanbytes(((double)read)/((double)(end-start)))); free(dDone); rv = 0; } closeOutputs(foutput, cnt); } else printf("Error: no output files could be opened\n"); fclose(finput); } } return rv; }