diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..f5a3605 --- /dev/null +++ b/.clang-format @@ -0,0 +1,20 @@ +BasedOnStyle: LLVM +IndentWidth: 4 +TabWidth: 4 +UseTab: Never +ColumnLimit: 120 +AllowShortLoopsOnASingleLine: true +AllowShortFunctionsOnASingleLine: false +AlwaysBreakTemplateDeclarations: true +BreakConstructorInitializers: BeforeComma +AlignConsecutiveDeclarations: + Enabled: true + AcrossEmptyLines: false + AcrossComments: false + AlignCompound: false + AlignFunctionPointers: false + PadOperators: false +AlignConsecutiveMacros: true +AllowShortCaseLabelsOnASingleLine: true +SeparateDefinitionBlocks: Always +BinPackArguments: false diff --git a/Makefile b/Makefile index 2b92b8c..58199f1 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ GITREV ?= $(shell git describe --dirty --always) BLDDATE ?= $(shell date -I) CR_YEAR ?= $(shell date +%Y) -VERSION ?= "v0.1.2" +VERSION ?= "v0.2.0" CFLAGS ?= -Wall -Wextra -Wpedantic -O2 -std=gnu99 CFLAGS += -DGITREV='"$(GITREV)"' CFLAGS += -DBLDDATE='"$(BLDDATE)"' CFLAGS += -DCR_YEAR='"$(CR_YEAR)"' CFLAGS += -DVERSION='$(VERSION)' +CFLAGS += $(EXTRA_CFLAGS) # Soon... # CFLAGS += $(shell pkg-config --cflags libudev) diff --git a/writeimg.c b/writeimg.c index 6533771..3d6c04b 100644 --- a/writeimg.c +++ b/writeimg.c @@ -11,6 +11,11 @@ #include #include +#if __linux__ +#include /* IOTCL flush number */ +#include /* IOCTL */ +#endif + #ifndef GITREV #define GITREV "unknown" #endif @@ -24,7 +29,7 @@ #endif #ifndef BLOCKSIZE -#define BLOCKSIZE (4 * 1024 * 1024) +#define BLOCKSIZE (1024 * 1024) #endif #define BYTES_TO_MIB(bts) ((double)bts / (1024 * 1024)) @@ -52,11 +57,12 @@ const char help[] = " writeimg [-v] -d \n" "\n" "Args:\n" - " Binary image file\n" - " -v Verify only\n" - " -d device Target block device\n" - " -h, --help Print this help message\n" - " -V, --version Print version\n" + " Binary image file\n" + " -v Verify only\n" + " -d device Target block device\n" + " -h, --help Print this help message\n" + " -n, --noconfirm Do not ask for premission\n" + " -V, --version Print version\n" "\0"; // clang-format on @@ -100,15 +106,20 @@ int perform_write(write_job_t *job) { int crc = crc32_init(); size_t b_written = 0; - while (!job->verify_only) { + while (42) { + fsync(block_fd); 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); + + if (!job->verify_only) { + printf("\nWriting done...\n"); + assert(job->total_bytes == b_written); + } else + assert(0 == b_written); + break; /* Finished */ } @@ -120,13 +131,15 @@ int perform_write(write_job_t *job) { crc = crc32_update(crc, job->buffer, read_bytes); - ssize_t written_bytes = write(block_fd, job->buffer, read_bytes); - if (written_bytes < 0) { - fprintf(stderr, "%s: Write error\n", job->dev_name); - perror("Write"); - exit(EXIT_FAILURE); - } - print_progress(b_written += written_bytes, job->total_bytes); + if (!job->verify_only) { + ssize_t written_bytes = write(block_fd, job->buffer, read_bytes); + if (written_bytes < 0) { + fprintf(stderr, "%s: Write error\n", job->dev_name); + perror("Write"); + exit(EXIT_FAILURE); + } + print_progress(b_written += written_bytes, job->total_bytes); + } /* Else maybe give some helpful insights? */ } lseek(block_fd, 0, SEEK_SET); @@ -135,6 +148,9 @@ int perform_write(write_job_t *job) { memset(job->buffer, 0, BLOCKSIZE); memset(job->buffer2, 0, BLOCKSIZE); + /* This is essentially $ blockdev --flushbufs */ + ioctl(block_fd, BLKFLSBUF); + int crc_back = crc32_init(); b_written = 0; @@ -173,16 +189,12 @@ static const struct option longopts[] = { {"help", 0, 0, 'h'}, {"version", 0, 0, 'V'}, {"device", 1, 0, 'd'}, + {"noconfirm", 0, 0, 'n'}, {NULL, 0, 0, 0}, }; int main(int argc, char *argv[]) { printf("%s %s, Rev. %s\n", basename(argv[0]), VERSION, GITREV); - fprintf(stdout, copyright, CR_YEAR); -#ifdef BLDDATE - printf("Build date: %s\n", BLDDATE); -#endif - printf("\n"); /* Line buffering, system allocated */ setvbuf(stdout, NULL, _IOLBF, 0); @@ -193,14 +205,22 @@ int main(int argc, char *argv[]) { signal(SIGHUP, int_handler); signal(SIGTERM, int_handler); + int ask_permission = 1; int c = {0}; - while ((c = getopt_long(argc, argv, "vd:hV", longopts, 0)) != -1) { + while ((c = getopt_long(argc, argv, "vd:hnV", longopts, 0)) != -1) { switch (c) { case 'v': ++wjob.verify_only; continue; case 'd': wjob.dev_name = optarg; continue; case 'h': break; + case 'n': --ask_permission; continue; case 'V': exit(EXIT_SUCCESS); } + printf("In honor of SwePwnage - the OG disk destroyer\n"); + fprintf(stdout, copyright, CR_YEAR); +#ifdef BLDDATE + printf("Build date: %s\n", BLDDATE); +#endif + printf("\n"); printf("%s\n", help); exit(EXIT_SUCCESS); } @@ -223,7 +243,7 @@ int main(int argc, char *argv[]) { } if (NULL == wjob.dev_name) { - printf("Device required...\n"); + printf("You need to specify a device.\n"); exit(EXIT_FAILURE); } @@ -240,12 +260,16 @@ int main(int argc, char *argv[]) { } close(fd); - printf("Writing %s to %s\n", wjob.filename, wjob.dev_name); + if (!wjob.verify_only) + printf("Writing %s to %s\n", wjob.filename, wjob.dev_name); - printf("Is this okay? (y/n): "); - fflush(stdout); - if ('y' != getchar()) { - exit(0); + if (ask_permission && !wjob.verify_only) { + printf("Is this okay? (y/n): "); + fflush(stdout); + if ('y' != getchar()) { + printf("Aborting...\n"); + exit(EXIT_SUCCESS); + } } wjob.buffer = malloc(BLOCKSIZE); @@ -266,7 +290,7 @@ int main(int argc, char *argv[]) { if (wjob.buffer2) free(wjob.buffer2); - printf("\n%.1f MiB's written and verified.\nAll good!\n", BYTES_TO_MIB(wjob.total_bytes)); - exit(0); - return 0; + printf("\n%.1f MiB's verified.\nAll good!\n", BYTES_TO_MIB(wjob.total_bytes)); + + exit(EXIT_SUCCESS); }