diff --git a/writeimg.c b/writeimg.c index 9d3c47d..6533771 100644 --- a/writeimg.c +++ b/writeimg.c @@ -29,6 +29,23 @@ #define BYTES_TO_MIB(bts) ((double)bts / (1024 * 1024)) +#define BAR_WIDTH 50 + +void print_progress(int current, int total) { + float fraction = (float)current / total; + int filled = (int)(fraction * BAR_WIDTH); + + printf("\r["); + for (int i = 0; i < BAR_WIDTH; i++) { + if (i < filled) + putchar('#'); + else + putchar(' '); + } + printf("] %3d%%", (int)(fraction * 100)); + fflush(stdout); +} + // clang-format off const char help[] = "Usage:\n" @@ -74,16 +91,24 @@ int perform_write(write_job_t *job) { int block_fd = open(job->dev_name, O_RDWR); int file_fd = open(job->filename, O_RDONLY); + assert(block_fd >= 0); + assert(file_fd >= 0); + /* TODO: Checks */ assert(job->bufsize >= job->block_size); - int crc = crc32_init(); + int crc = crc32_init(); + size_t b_written = 0; while (!job->verify_only) { ssize_t read_bytes = read(file_fd, job->buffer, job->block_size); + assert(read_bytes >= 0); + if (read_bytes == 0) { fsync(block_fd); crc = crc32_finalize(crc); + printf("\nWriting done...\n"); + assert(job->total_bytes == b_written); break; /* Finished */ } @@ -101,6 +126,7 @@ int perform_write(write_job_t *job) { perror("Write"); exit(EXIT_FAILURE); } + print_progress(b_written += written_bytes, job->total_bytes); } lseek(block_fd, 0, SEEK_SET); @@ -110,6 +136,7 @@ int perform_write(write_job_t *job) { memset(job->buffer2, 0, BLOCKSIZE); int crc_back = crc32_init(); + b_written = 0; while (1) { ssize_t read_file = read(file_fd, job->buffer2, job->block_size); @@ -122,10 +149,13 @@ int perform_write(write_job_t *job) { if (read_file == 0) { crc_back = crc32_finalize(crc_back); assert(crc_back == crc); + assert(job->total_bytes == b_written); + printf("\nVerification done!\n"); break; } crc_back = crc32_update(crc_back, job->buffer, read_file); + print_progress(b_written += read_block, job->total_bytes); int cmp = memcmp((const void *)job->buffer2, (const void *)job->buffer, (size_t)read_file); if (0 != cmp) { @@ -202,10 +232,26 @@ int main(int argc, char *argv[]) { exit(EXIT_FAILURE); } + /* Seems to be the cleanest way to check for write perm on a blockdev */ + int fd = open(wjob.dev_name, O_WRONLY); + if (fd < 0) { + printf("Cannot write to \"%s\", do you have write permissions?\n", wjob.dev_name); + exit(1); + } + close(fd); + printf("Writing %s to %s\n", wjob.filename, wjob.dev_name); + printf("Is this okay? (y/n): "); + fflush(stdout); + if ('y' != getchar()) { + exit(0); + } + wjob.buffer = malloc(BLOCKSIZE); wjob.buffer2 = malloc(BLOCKSIZE); + assert(wjob.buffer); + assert(wjob.buffer2); wjob.bufsize = BLOCKSIZE; wjob.block_size = BLOCKSIZE;