From d5d0883ec84653c13c01d35824c95fa3dd682348 Mon Sep 17 00:00:00 2001 From: Daniel Jones Date: Thu, 26 Dec 2019 16:54:07 +1030 Subject: added ability to write to an offset in a file --- pages.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ pages.h | 1 + 2 files changed, 88 insertions(+) diff --git a/pages.c b/pages.c index 49f95c4..c4172ea 100644 --- a/pages.c +++ b/pages.c @@ -200,6 +200,92 @@ deletebytes(const char *file, long offset, size_t bytes) return 1; } +int +writefileatbyte(const char *dest, const char *source, long offset) +{ + /* + * write file 'source' into 'output_dir'/'file' starting at offset 'offset' + * return 1 on success. 0 on failure + */ + + char filename[512] = {0}; + size_t length = 512; + strncat(filename, output_dir, length-1); + length = length - strlen(output_dir); + strncat(filename, dest, length-1); + + FILE *in = fopen(filename, "r"); + if (!in) + { + fprintf(stderr, "unable to open file '%s', unrecoverable failure\n", filename); + return 0; + } + + FILE *tmp = fopen("tmp.tmp", "w"); + if (!tmp) + { + fprintf(stderr, "unable to open temp file, unrecoverable failure\n"); + fclose(in); + return 0; + } + + FILE *src = fopen(source, "r"); + if (!src) + { + fprintf(stderr, "unable to open file '%s', unrecoverable failure\n", source); + fclose(in); + fclose(tmp); + return 0; + } + + /* + * read file 'in' until byte 'offset', writing into file 'tmp' + * write file 'src' into 'tmp' + * finish writing file 'in' into 'tmp' + * delete file 'filename' + * rename file 'tmp' 'filename' + */ + + char c, t, a; + long curpos = 1; + while ((c = fgetc(in)) != EOF) + { + if (curpos == offset) + { + while ((t = fgetc(src)) != EOF) + { + /* prevent writing end of line '\n' if the next char is EOF */ + a = fgetc(src); + ungetc(a, src); + if (a == EOF && t == '\n') + continue; + fputc(t, tmp); + } + } + fputc(c, tmp); + curpos++; + } + + fclose(tmp); + fclose(in); + fclose(src); + + if (remove(filename) == -1) + { + fprintf(stderr, "unable to delete file '%s', unrecoverable failure\n", filename); + return 0; + } + + if (rename("tmp.tmp", filename) == -1) + { + + fprintf(stderr, "unable to rename tmp file to '%s', unrecoverable failure\n", filename); + return 0; + } + + return 1; +} + int frontpage(int flags) { @@ -227,5 +313,6 @@ frontpage(int flags) fprintf(stderr, "unable to generate frontpage\n"); return 0; } + writefileatbyte(frontpage_index_output, "source.txt", substrpos); return 1; } diff --git a/pages.h b/pages.h index 907d66e..658f17a 100644 --- a/pages.h +++ b/pages.h @@ -25,6 +25,7 @@ int createfile(const char *file); long findstring(const char *file, const char *str); int deletebytes(const char *file, long offset, size_t bytes); +int writefileatbyte(const char *dest, const char *source, long offset); /* generators (to be put into the pages array) */ int frontpage(int flags); -- cgit v1.2.3