#include #include #include #include #include #include char *units[] = { "Bytes", "kBytes", "MBytes", "GBytes" }; int mode = 0; // 0 = stdin -> stdout // 1 = enocde // 2 = decode int arg_verbose = 0; long filesize = 0; long netsize = 0; long transferred = 0; long nettransferred = 0; long transfersum = 0; long nettransfersum = 0; char status[1024]; void (*restore_sig_alrm)(int sig); void sig_alrm(int sig) { long transfer = filesize - transferred; transferred += transfer; transfersum += transfer; transfer = transfersum >> 2; transfersum -= transfer; long t = transferred; int nu = 0; int nt = 0; while ((transfer > 1024)) { transfer >>= 10; nu++; if (nu == 3) break; } while ((t > 1024)) { t >>= 10; nt++; if (nt == 3) break; } sprintf(status, "sparse-tools: %li %s seen, current speed is %li %s/s \r", t, units[nt], transfer, units[nu]); write(2, status, strlen(status)); fsync(2); alarm( 1 ); } int sparse_copy(int in, int out, int blocksize) { int nread = 0, i; char block[blocksize]; while ((nread = read( in, block, blocksize))>0) { for (i=0; (i0) { for (i=0; (i 0) { switch (m) { case 'S': lseek( out, blocksize, SEEK_CUR ); filesize += blocksize; break; case 'D': nread = read( in, block, blocksize); write( out, block, nread ); filesize += nread; break; } } ftruncate( out, filesize ); return nread; } int main(int argc, char *argv[]) { int ch; while ((ch = getopt(argc, argv, "edv"))!=-1) { switch (ch) { case 'd': mode = 2; break; case 'e': mode = 1; break; case 'v': arg_verbose = 1; break; } } if (arg_verbose) { restore_sig_alrm = signal( SIGALRM, sig_alrm); alarm( 1 ); } switch (mode) { case 0: return sparse_copy( 0, 1, 4096 ); case 1: return sparse_encode( 0, 1, 4096 ); case 2: return sparse_decode( 0, 1, 4096 ); } if (arg_verbose) { alarm( 0 ); signal( SIGALRM, restore_sig_alrm ); write( 2, "\n", 1 ); } close(0); close(1); }