diff --git a/Makefile b/Makefile index 1e20af8..451e1e3 100644 --- a/Makefile +++ b/Makefile @@ -21,11 +21,12 @@ $(ALL) : % : %.o maddr magrep mdeliver mexport mflag mgenmid mhdr mpick mscan msed mshow \ msort mthread : blaze822.o mymemmem.o mytimegm.o maddr magrep mexport mflag mgenmid mhdr mpick mscan msed mseq mshow msort \ - mthread : seq.o + mthread : seq.o slurp.o maddr magrep mhdr mpick mscan mshow : rfc2047.o magrep mshow : rfc2045.o mshow : filter.o msort : mystrverscmp.o +mmime : slurp.o README: man/mblaze.7 mandoc -Tutf8 $< | col -bx >$@ diff --git a/blaze822.h b/blaze822.h index e06c8a7..f466779 100644 --- a/blaze822.h +++ b/blaze822.h @@ -77,3 +77,8 @@ int filter(char *input, size_t inlen, char *cmd, char **outputo, size_t *outleno // mygmtime.c time_t tm_to_secs(const struct tm *tm); + + +// slurp.c + +int slurp(char *filename, char **bufo, off_t *leno); diff --git a/seq.c b/seq.c index 3cbf131..7b0b9ea 100644 --- a/seq.c +++ b/seq.c @@ -1,4 +1,3 @@ -#include #include #include @@ -50,23 +49,14 @@ blaze822_home_file(char *basename) char * blaze822_seq_open(char *file) { - int fd; - struct stat st; - - // env $SEQ or something if (!file) file = getenv("MAILSEQ"); if (!file) file = blaze822_home_file("seq"); - fd = open(file, O_RDONLY); - if (!fd) - return 0; - - fstat(fd, &st); - char *map = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - close(fd); - if (map == MAP_FAILED) + char *map; + off_t len; + if (slurp(file, &map, &len) != 0) return 0; return map; diff --git a/slurp.c b/slurp.c new file mode 100644 index 0000000..6366e6f --- /dev/null +++ b/slurp.c @@ -0,0 +1,56 @@ +#include +#include + +#include +#include +#include +#include + +int +slurp(char *filename, char **bufo, off_t *leno) +{ + int fd; + struct stat st; + ssize_t nread = 0; + ssize_t n; + int r = 0; + + fd = open(filename, O_RDONLY); + if (fd < 0) { + r = errno; + goto out; + } + if (fstat(fd, &st) < 0) { + r = errno; + goto out; + } + if (st.st_size == 0) { + *bufo = ""; + *leno = 0; + return 0; + } + *bufo = malloc(st.st_size); + if (!*bufo) { + r = ENOMEM; + goto out; + } + + do { + if ((n = read(fd, *bufo + nread, st.st_size - nread)) < 0) { + if (errno == EINTR) { + continue; + } else { + r = errno; + goto out; + } + } + if (!n) + break; + nread += n; + } while (nread < st.st_size); + *leno = nread; + +out: + close(fd); + return r; +}