summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Jackson <ijackson@chiark.greenend.org.uk>2024-01-27 13:27:18 +0000
committerIan Jackson <ijackson@chiark.greenend.org.uk>2024-01-31 20:05:20 +0000
commit396a200155d4e956f93ef6528f48a23d14949787 (patch)
tree2548809d25b398b4e06e980eae0f2c092b00cace
parent3e7215242eafc89b2d0cae1f5c3952461d0dc894 (diff)
Drop __oop-read-copy.c: our bugfixes are upstream for ages
The fixes we need are those in #579604. The debian/changelog for liboop shows these arrived in upstream in 1.0.1, some time before January 2017. The fixes have been in Debian since 1.0-7, in July 2010. Comparing the file with current liboop, I also found that I hadn't upstreamed a compile fix from "fix compile warnings/errors", so I've filed that as #1061619. But we don't use that feature here in innduct so we don't need that fix.
-rw-r--r--Makefile.am2
-rw-r--r--__oop-read-copy.c486
2 files changed, 1 insertions, 487 deletions
diff --git a/Makefile.am b/Makefile.am
index 87dcf78..5560a3d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -43,7 +43,7 @@ bin_PROGRAMS = innduct
bin_SCRIPTS = innduct-stats-report innduct-forall
man_MANS = innduct.8 innduct-stats-report.8
innduct_SOURCES = duct.c conn.c filemon.c infile.c recv.c xmit.c \
- cli.c defer.c help.c statemc.c __oop-read-copy.c
+ cli.c defer.c help.c statemc.c
dist_doc_DATA = README.states README.statistics README.example
diff --git a/__oop-read-copy.c b/__oop-read-copy.c
deleted file mode 100644
index bd505c4..0000000
--- a/__oop-read-copy.c
+++ /dev/null
@@ -1,486 +0,0 @@
-/* THIS IS A COPY OF THE FILE WHICH SHOULD BE IN LIBOOP
-** When liboop gets the two tiny bugfixes which are here,
-** this file can and should be eliminated -iwj 29.4.2010
-*/
-
-/* read.c, liboop, copyright 2000 Ian jackson
-
- This is free software; you can redistribute it and/or modify it under the
- terms of the GNU Lesser General Public License, version 2.1 or later.
- See the file COPYING for details. */
-
-#include "oop.h"
-#include "oop-read.h"
-
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <limits.h>
-
-#undef MIN /* for systems that define it */
-#define MIN(a,b) ((a)<(b) ? (a) : (b))
-
-static void *on_time(oop_source*, struct timeval, void*);
-static void *on_readable(oop_source*, oop_readable*, void*);
-static void *on_process(oop_source*, oop_read*, int try_read);
-
-static int set_time_ifbuf(oop_source *oop, oop_read *rd);
-static void cancel_time(oop_source *oop, oop_read *rd);
-
-const oop_rd_style OOP_RD_STYLE_GETLINE[]= {{
- OOP_RD_DELIM_STRIP,'\n', OOP_RD_NUL_FORBID, OOP_RD_SHORTREC_EOF,
-}};
-const oop_rd_style OOP_RD_STYLE_BLOCK[]= {{
- OOP_RD_DELIM_NONE, 0, OOP_RD_NUL_PERMIT, OOP_RD_SHORTREC_EOF,
-}};
-const oop_rd_style OOP_RD_STYLE_IMMED[]= {{
- OOP_RD_DELIM_NONE, 0, OOP_RD_NUL_PERMIT, OOP_RD_SHORTREC_SOONEST,
-}};
-
-struct oop_read {
- /* set at creation time: */
- oop_source *oop;
- oop_readable *ra;
- char *userbuf;
- /* persistent state */
- oop_rd_bufctl_op readahead; /* _ENABLE or _DISABLE */
- char *allocbuf;
- size_t alloc, used, discard;
- size_t neednotcheck; /* data we've already searched for delimiter */
- int displacedchar; /* >=0, first unused */
- /* arguments to oop_rd_read */
- oop_rd_style style;
- size_t maxrecsz;
- oop_rd_call *call_ok, *call_err;
- void *data_ok, *data_err;
-};
-
-/* Buffer is structured like this if displacedchar>=0 and delim found:
- *
- * done stuff, displaced readahead - read unused
- * we've called delimiter| but not yet buffer
- * back for || returned space
- * ddddddddddddddddddddddDOaaaaaaaaaaaaaaaaaaa____________
- * <------- discard ----->
- * <----------------------- used ------------>
- * <------------------------------------- alloc --------->
- *
- * If displacedchar>=0 then the the first character of readahead has
- * been displaced by a nul byte and is stored in displacedchar. If
- * _DELIM_STRIP and the delimiter is found then the nul overwrites the
- * delimiter.
- *
- * Buffer when full {this,max} may need
- * DELIM found? <-recval-> recdata buffer required readahead
- * NONE n/a ddddddddddOaaa_ recsz recdata+1 == recsz+1 maxrecsz
- * KEEP Yes dddddddddDOaaa_ recsz recdata+1 == recsz+1 maxrecsz
- * KEEP No ddddddddddOaaa_ recsz recdata+1 == recsz+1 maxrecsz
- * STRIP Yes dddddddddd0aaaa recsz+1 recdata == recsz+1 maxrecsz+1
- * STRIP No ddddddddddOaaaa recsz recdata+1 == recsz+1 maxrecsz+1
- *
- * Key: d = data to be returned
- * D = delimiter, being returned
- * a = readahead, not to be returned
- * O = readahead character displaced by a nul
- * 0 = delimiter replaced by a nul
- * _ = unused
- */
-
-static const char *const eventstrings_nl[]= {
- "INTERNAL ERROR (_nl _OK) please report",
- "End of file",
- "Missing newline at end of file",
- "Line too long",
- "Nul byte",
- "Nul byte, in line which is also too long",
- "INTERNAL ERROR (_nl _SYSTEM) please report"
-};
-
-static const char *const eventstrings_other[]= {
- "Record read successfully",
- "End of file",
- "Incomplete record at end of file",
- "Record too long",
- "Nul byte",
- "Nul byte in record which is also too long",
- "System error"
-};
-
-oop_read *oop_rd_new(oop_source *oop, oop_readable *ra, char *buf, size_t bufsz) {
- oop_read *rd= 0;
-
- assert(buf ? bufsz>=2 : !bufsz);
-
- rd= oop_malloc(sizeof(*rd)); if (!rd) goto x_fail;
- rd->oop= oop;
- rd->ra= ra;
- rd->userbuf= buf;
- rd->readahead= OOP_RD_BUFCTL_ENABLE;
- rd->allocbuf= 0;
- rd->used= 0;
- rd->alloc= buf ? bufsz : 0;
- rd->discard= 0;
- rd->neednotcheck= 0;
- rd->displacedchar= -1;
- rd->style= *OOP_RD_STYLE_IMMED;
-
- return rd;
-
-x_fail:
- oop_free(rd);
- return 0;
-}
-
-static int set_time_ifbuf(oop_source *oop, oop_read *rd) {
- if (rd->used > rd->discard)
- return oop->on_time(oop,OOP_TIME_NOW,on_time,rd), 0; /* fixme */
- return 0;
-}
-static void cancel_time(oop_source *oop, oop_read *rd) {
- oop->cancel_time(oop,OOP_TIME_NOW,on_time,rd);
-}
-static int set_read(oop_source *oop, oop_read *rd) {
- return rd->ra->on_readable(rd->ra,on_readable,rd), 0; /* fixme */
-}
-static void cancel_read(oop_source *oop, oop_read *rd) {
- rd->ra->on_cancel(rd->ra);
-}
-
-int oop_rd_read(oop_read *rd, const oop_rd_style *style, size_t maxrecsz,
- oop_rd_call *ifok, void *data_ok,
- oop_rd_call *iferr, void *data_err) {
- oop_source *oop= rd->oop;
- int er;
-
- cancel_time(oop,rd);
- cancel_read(oop,rd);
-
- if (style->delim_mode == OOP_RD_DELIM_NONE ||
- rd->style.delim_mode == OOP_RD_DELIM_NONE ||
- style->delim != rd->style.delim)
- rd->neednotcheck= 0;
-
- rd->style= *style;
- rd->maxrecsz= maxrecsz;
- rd->call_ok= ifok; rd->data_ok= data_ok;
- rd->call_err= iferr; rd->data_err= data_err;
-
- er= set_read(oop,rd); if (er) return er;
- er= set_time_ifbuf(oop,rd); if (er) return er;
- return 0;
-}
-
-void oop_rd_delete(oop_read *rd) {
- rd->ra->on_cancel(rd->ra);
- oop_free(rd->allocbuf);
- oop_free(rd);
-}
-
-void oop_rd_cancel(oop_read *rd) {
- cancel_time(rd->oop,rd);
- cancel_read(rd->oop,rd);
-}
-
-const char *oop_rd_errmsg(oop_read *rd, oop_rd_event event, int errnoval,
- const oop_rd_style *style) {
- if (event == OOP_RD_SYSTEM)
- return strerror(errnoval);
- else if (style && style->delim_mode != OOP_RD_DELIM_NONE
- && style->delim == '\n')
- return eventstrings_nl[event];
- else
- return eventstrings_other[event];
-}
-
-static void *on_readable(oop_source *oop, oop_readable *ra, void *rd_void) {
- oop_read *rd= rd_void;
-
- assert(oop == rd->oop);
- assert(ra == rd->ra);
- return on_process(oop,rd,1);
-}
-
-static void *on_time(oop_source *oop, struct timeval when, void *rd_void) {
- oop_read *rd= rd_void;
-
- assert(oop == rd->oop);
- return on_process(oop,rd,0);
-}
-
-static size_t calc_dataspace(oop_read *rd) {
- if (rd->style.delim_mode == OOP_RD_DELIM_STRIP) {
- return rd->alloc;
- } else {
- return rd->alloc ? rd->alloc-1 : 0;
- }
-}
-
-static void *on_process(oop_source *oop, oop_read *rd, int try_read) {
- oop_rd_event event;
- int evkind; /* 0=none, -1=error, 1=something */
- int errnoval, nread, cancelnow;
- oop_rd_call *call;
- char *buf, *delimp;
- const char *errmsg;
- size_t maxrecsz; /* like in arg to oop_rd_read, but 0 -> large val */
- size_t maxbufreqd; /* maximum buffer we might possibly want to alloc */
- size_t readahead; /* max amount of data we might want to readahead */
- size_t want; /* amount we want to allocate or data we want to read */
- size_t dataspace; /* amount of buffer we can usefully fill with data */
- size_t thisrecsz; /* length of the record we've found */
- size_t thisrecdata; /* length of data representing the record */
- void *call_data;
-
- cancel_time(oop,rd);
-
- if (rd->userbuf) {
- buf= rd->userbuf;
- } else {
- buf= rd->allocbuf;
- }
-
- if (rd->discard) {
- rd->used -= rd->discard;
- if (rd->neednotcheck > rd->discard) {
- rd->neednotcheck -= rd->discard;
- } else {
- rd->neednotcheck= 0;
- }
- memmove(buf, buf + rd->discard, rd->used);
- rd->discard= 0;
- }
- if (rd->displacedchar >= 0) {
- assert(rd->used > 0);
- buf[0]= rd->displacedchar;
- rd->displacedchar= -1;
- }
-
- maxrecsz= rd->maxrecsz ? rd->maxrecsz : INT_MAX / 5 /* allows +20 and *4 */;
- maxbufreqd= maxrecsz+1;
-
- if (rd->userbuf && maxbufreqd > rd->alloc) {
- maxrecsz -= (maxbufreqd - rd->alloc);
- maxbufreqd= rd->alloc;
- }
-
- if (rd->style.delim_mode == OOP_RD_DELIM_STRIP) {
- readahead= maxrecsz+1;
- } else {
- readahead= maxrecsz;
- }
-
- for (;;) {
- evkind= 0;
- event= -1;
- thisrecdata= thisrecsz= 0;
- errnoval= 0;
-
- assert(rd->used <= rd->alloc);
- dataspace= calc_dataspace(rd);
-
- if (/* delimiter already in buffer, within max record data ? */
- rd->style.delim_mode != OOP_RD_DELIM_NONE &&
- (delimp= memchr(buf + rd->neednotcheck, rd->style.delim,
- MIN(rd->used, readahead) - rd->neednotcheck))) {
-
- thisrecsz= (delimp - buf);
- thisrecdata= thisrecsz+1;
- if (rd->style.delim_mode == OOP_RD_DELIM_KEEP)
- thisrecsz= thisrecdata;
- event= OOP_RD_OK;
- evkind= +1;
-
- } else if (rd->used >= readahead) {
-
- thisrecsz= thisrecdata= maxrecsz;
- evkind= +1;
-
- if (rd->style.delim_mode == OOP_RD_DELIM_NONE) {
- event= OOP_RD_OK;
- } else {
- event= OOP_RD_LONG;
- if (rd->style.shortrec_mode < OOP_RD_SHORTREC_LONG) {
- evkind= -1;
- thisrecsz= thisrecdata= 0;
- }
- }
-
- } else if (/* want to return ASAP, and we have something ? */
- rd->style.shortrec_mode == OOP_RD_SHORTREC_SOONEST &&
- rd->used > 0 && rd->alloc >= 2) {
-
- thisrecdata= rd->used;
- if (thisrecdata == rd->alloc) thisrecdata--;
- thisrecsz= thisrecdata;
- event= OOP_RD_OK;
- evkind= +1;
-
- }
-
- want= 0;
- if (evkind && thisrecdata && thisrecsz >= rd->alloc) {
- /* Need to make space for the trailing nul */
- want= rd->alloc+1;
- } else if (!evkind && !rd->userbuf &&
- rd->used >= dataspace && rd->alloc < maxbufreqd) {
- /* Need to make space to read more data */
- want= rd->alloc + 20;
- want <<= 2;
- want= MIN(want, maxbufreqd);
- }
-
- if (want) {
- assert(!rd->userbuf);
- assert(want <= maxbufreqd);
-
- buf= oop_realloc(rd->allocbuf,want);
- if (!buf) {
- event= OOP_RD_SYSTEM;
- evkind= -1;
- errnoval= ENOMEM;
- thisrecsz= thisrecdata= 0;
- break;
- }
- rd->allocbuf= buf;
- rd->alloc= want;
- }
-
- if (evkind) break; /* OK, process it then */
-
- if (!try_read) return OOP_CONTINUE; /* But we weren't told it was ready. */
-
- dataspace= calc_dataspace(rd);
- want= MIN(dataspace, readahead);
- assert(rd->used < want);
-
- errno= 0;
- nread= rd->ra->try_read(rd->ra, buf+rd->used, want-rd->used);
- if (errno == EAGAIN) return OOP_CONTINUE;
-
- if (nread > 0) {
- rd->neednotcheck= rd->used;
- rd->used += nread;
- continue;
- }
-
- if (nread < 0) { /* read error */
-
- event= OOP_RD_SYSTEM;
- evkind= -1;
- errnoval= errno;
- thisrecsz= thisrecdata= rd->used;
- break;
-
- } else {
-
- if (rd->used) {
- event= OOP_RD_PARTREC;
- evkind= (rd->style.shortrec_mode == OOP_RD_SHORTREC_FORBID) ? -1 : +1;
- thisrecsz= thisrecdata= rd->used;
- } else {
- event= OOP_RD_EOF;
- evkind= +1;
- }
- break;
-
- }
- }
-
- /* OK, we have an event of some kind */
-
- /* Nul byte handling */
- if (thisrecsz > 0 && rd->style.nul_mode != OOP_RD_NUL_PERMIT) {
- size_t checked;
- char *nul, *notnul;
-
- for (checked=0;
- (nul= memchr(buf+checked,0,thisrecsz-checked));
- ) {
- if (rd->style.nul_mode == OOP_RD_NUL_FORBID) {
- event= OOP_RD_NUL;
- evkind= -1;
- thisrecdata= thisrecsz= 0;
- break;
- }
- assert(rd->style.nul_mode == OOP_RD_NUL_DISCARD);
- for (notnul= nul+1;
- notnul < buf+thisrecsz && *notnul == '\0';
- notnul++);
- thisrecsz-= (notnul-nul);
- checked= nul-buf;
- memmove(nul,notnul,thisrecsz-checked);
- }
- }
-
- /* Checks that all is well */
-
- assert(evkind);
- assert(thisrecsz <= thisrecdata);
- assert(!rd->maxrecsz || thisrecsz <= rd->maxrecsz);
- assert(thisrecdata <= rd->used);
-
- rd->discard= thisrecdata;
-
- cancelnow= (evkind < 0) || (event == OOP_RD_EOF);
-
- if (!cancelnow) {
- errnoval= set_time_ifbuf(oop,rd);
- if (errnoval) {
- event= OOP_RD_SYSTEM;
- evkind= -1;
- cancelnow= 1;
- thisrecsz= thisrecdata= 0;
- rd->discard= 0;
- }
- }
-
- if (evkind < 0) {
- call= rd->call_err;
- call_data= rd->data_err;
- errmsg= oop_rd_errmsg(rd,event,errnoval,&rd->style);
- } else {
- call= rd->call_ok;
- call_data= rd->data_ok;
- errmsg= 0;
- }
-
- if (thisrecdata) {
- /* We have to fill in a nul byte. */
- assert(thisrecsz < rd->alloc);
- if (thisrecsz == thisrecdata && thisrecsz < rd->used)
- rd->displacedchar= (unsigned char)buf[thisrecdata];
- buf[thisrecsz]= 0;
- }
-
- if (cancelnow)
- oop_rd_cancel(rd);
-
- return
- call(oop,rd, event,errmsg,errnoval,
- (thisrecdata ? buf : 0), thisrecsz, call_data);
-}
-
-oop_read *oop_rd_new_fd(oop_source *oop, int fd, char *buf, size_t bufsz) {
- oop_readable *ra;
- oop_read *rd;
-
- ra= oop_readable_fd(oop,fd);
- if (!ra) return 0;
-
- rd= oop_rd_new(oop,ra,buf,bufsz);
- if (!rd) { ra->delete_tidy(ra); return 0; }
-
- return rd;
-}
-
-int oop_rd_delete_tidy(oop_read *rd) {
- oop_readable *ra= rd->ra;
- oop_rd_delete(rd);
- return ra->delete_tidy(ra);
-}
-
-void oop_rd_delete_kill(oop_read *rd) {
- oop_readable *ra= rd->ra;
- oop_rd_delete(rd);
- ra->delete_kill(ra);
-}