From 4df8dd2fc826b3f7194ee52dbce4a9dc16c4b8af Mon Sep 17 00:00:00 2001 From: Curtis McEnroe Date: Wed, 30 Oct 2019 19:47:24 -0400 Subject: Add option for ring size --- bounce.c | 12 +++++++++--- pounce.1 | 11 ++++++++++- ring.c | 36 +++++++++++++++++++++++++++++------- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/bounce.c b/bounce.c index 34a56a8..b26a1cb 100644 --- a/bounce.c +++ b/bounce.c @@ -102,6 +102,7 @@ int main(int argc, char *argv[]) { char certPath[PATH_MAX] = ""; char privPath[PATH_MAX] = ""; const char *save = NULL; + size_t ring = 4096; bool insecure = false; const char *host = NULL; @@ -115,7 +116,7 @@ int main(int argc, char *argv[]) { const char *away = "pounced :3"; const char *quit = "connection reset by purr"; - const char *Opts = "!A:C:H:K:NP:Q:W:a:f:h:j:n:p:r:u:vw:"; + const char *Opts = "!A:C:H:K:NP:Q:W:a:f:h:j:n:p:r:s:u:vw:"; const struct option LongOpts[] = { { "insecure", no_argument, NULL, '!' }, { "away", required_argument, NULL, 'A' }, @@ -133,6 +134,7 @@ int main(int argc, char *argv[]) { { "nick", required_argument, NULL, 'n' }, { "port", required_argument, NULL, 'p' }, { "real", required_argument, NULL, 'r' }, + { "size", required_argument, NULL, 's' }, { "user", required_argument, NULL, 'u' }, { "verbose", no_argument, NULL, 'v' }, { "pass", required_argument, NULL, 'w' }, @@ -158,6 +160,11 @@ int main(int argc, char *argv[]) { break; case 'n': nick = optarg; break; case 'p': port = optarg; break; case 'r': real = optarg; + break; case 's': { + char *rest; + ring = strtoull(optarg, &rest, 0); + if (*rest) errx(EX_USAGE, "invalid size: %s", optarg); + } break; case 'u': user = optarg; break; case 'v': verbose = true; break; case 'w': pass = optarg; @@ -171,7 +178,6 @@ int main(int argc, char *argv[]) { if (!privPath[0]) { snprintf(privPath, sizeof(privPath), DEFAULT_PRIV_PATH, bindHost); } - if (!host) errx(EX_USAGE, "no host"); if (!nick) { nick = getenv("USER"); @@ -180,7 +186,7 @@ int main(int argc, char *argv[]) { if (!user) user = nick; if (!real) real = nick; - ringAlloc(4096); + ringAlloc(ring); if (save) saveLoad(save); int bind[8]; diff --git a/pounce.1 b/pounce.1 index f83882a..a3bfdd8 100644 --- a/pounce.1 +++ b/pounce.1 @@ -1,4 +1,4 @@ -.Dd October 29, 2019 +.Dd October 30, 2019 .Dt POUNCE 1 .Os . @@ -23,6 +23,7 @@ .Op Fl n Ar nick .Op Fl p Ar port .Op Fl r Ar real +.Op Fl s Ar size .Op Fl u Ar user .Op Fl w Ar pass .Op Ar config ... @@ -144,6 +145,14 @@ Set realname to .Ar real . The default realname is the same as the nickname. . +.It Fl s Ar size , Cm size = Ar size +Set the buffer +.Ar size . +This determines the maximum number of messages +stored in memory. +The size must be a power of two. +The default size is 4096. +. .It Fl u Ar user , Cm user = Ar user Set username to .Ar user . diff --git a/ring.c b/ring.c index f99d9d4..620f490 100644 --- a/ring.c +++ b/ring.c @@ -30,7 +30,9 @@ static struct { } ring; void ringAlloc(size_t len) { - if (len & (len - 1)) errx(EX_CONFIG, "ring length must be power of two"); + if (len & (len - 1)) { + errx(EX_CONFIG, "ring length must be power of two: %zu", len); + } ring.lines = calloc(len, sizeof(*ring.lines)); if (!ring.lines) err(EX_OSERR, "calloc"); ring.times = calloc(len, sizeof(*ring.times)); @@ -116,7 +118,10 @@ void ringInfo(void) { } } -static const size_t FileVersion = 0x0165636E756F70; +static const size_t FileVersion[] = { + 0x0165636E756F70, + 0x0265636E756F70, +}; static int writeSize(FILE *file, size_t value) { return (fwrite(&value, sizeof(value), 1, file) ? 0 : -1); @@ -129,7 +134,8 @@ static int writeString(FILE *file, const char *str) { } int ringSave(FILE *file) { - if (writeSize(file, FileVersion)) return -1; + if (writeSize(file, FileVersion[1])) return -1; + if (writeSize(file, ring.len)) return -1; if (writeSize(file, producer)) return -1; if (writeSize(file, consumers.len)) return -1; for (size_t i = 0; i < consumers.len; ++i) { @@ -166,8 +172,16 @@ void ringLoad(FILE *file) { fread(&version, sizeof(version), 1, file); if (ferror(file)) err(EX_IOERR, "fread"); if (feof(file)) return; + if (version != FileVersion[0] && version != FileVersion[1]) { + errx(EX_DATAERR, "unknown file version %zX", version); + } + + size_t saveLen = 4096; + if (version == FileVersion[1]) readSize(file, &saveLen); + if (saveLen > ring.len) { + errx(EX_DATAERR, "cannot load save with larger ring"); + } - if (version != FileVersion) errx(EX_DATAERR, "unknown file version"); readSize(file, &producer); char *buf = NULL; @@ -181,15 +195,23 @@ void ringLoad(FILE *file) { readSize(file, &consumers.ptr[consumer].pos); } - for (size_t i = 0; i < ring.len; ++i) { + for (size_t i = 0; i < saveLen; ++i) { readTime(file, &ring.times[i]); } - for (size_t i = 0; i < ring.len; ++i) { + for (size_t i = 0; i < saveLen; ++i) { readString(file, &buf, &cap); if (feof(file)) break; ring.lines[i] = strdup(buf); if (!ring.lines[i]) err(EX_OSERR, "strdup"); } - free(buf); + + if (ring.len > saveLen) { + producer %= saveLen; + for (size_t i = 0; i < consumers.len; ++i) { + struct Consumer *consumer = &consumers.ptr[i]; + consumer->pos %= saveLen; + if (consumer->pos > producer) consumer->pos = 0; + } + } } -- cgit 1.4.1 2-18 23:39:46 -0500'>2022-02-18Simplify cursor positioning in inputJune McEnroe Do some extra work by adding the portion before the cursor to the input window twice, but simplify the interaction with the split point. This fixes the awkward behaviour when moving the cursor across colour codes where the code would be partially interpreted up to the cursor. 2022-02-18Fix M-f orderingJune McEnroe 2022-02-12Move sandman build to scripts/MakefileJune McEnroe 2022-02-12Use compat_readpassphrase.c on LinuxJune McEnroe 2022-02-12Copy RPP defines from oconfigureJune McEnroe