summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pttbbs/include/proto.h7
-rw-r--r--pttbbs/mbbsd/more.c19
-rw-r--r--pttbbs/mbbsd/pmore.c97
3 files changed, 119 insertions, 4 deletions
diff --git a/pttbbs/include/proto.h b/pttbbs/include/proto.h
index b7882091..7770cc46 100644
--- a/pttbbs/include/proto.h
+++ b/pttbbs/include/proto.h
@@ -418,12 +418,19 @@ void m_sob_brd(char *bname,char *fromdir);
/* pager */
int more(const char *fpath, int promptend);
+int more_inmemory(void *content, int size, int promptend);
/* piaip's new pager, pmore.c */
int pmore (const char *fpath, int promptend);
int pmore2(const char *fpath, int promptend, void *ctx,
int (*key_handler) (int key, void *ctx),
int (*footer_handler)(int ratio, int width, void *ctx),
int (*help_handler) (int y, void *ctx));
+int pmore2_inmemory(
+ void *content, int size,
+ int promptend, void *ctx,
+ int (*key_handler) (int key, void *ctx),
+ int (*footer_handler)(int ratio, int width, void *ctx),
+ int (*help_handler) (int y, void *ctx));
/* piaip's new telnet, telnet.c */
void telnet_init(int do_init_cmd);
ssize_t tty_read(unsigned char *buf, size_t max);
diff --git a/pttbbs/mbbsd/more.c b/pttbbs/mbbsd/more.c
index ffac2512..ae9c8523 100644
--- a/pttbbs/mbbsd/more.c
+++ b/pttbbs/mbbsd/more.c
@@ -190,6 +190,13 @@ common_pager_exit_handler(int r, const char *fpath)
return r;
}
+static int
+memory_pager_exit_handler(int r, const void *ctx GCC_UNUSED)
+{
+ // TODO: port some functionality from `common_pager_exit_handler'.
+ return r;
+}
+
#ifndef USE_PMORE ///////////////////////////////////////////////////////////
@@ -463,5 +470,17 @@ more(const char *fpath, int promptend)
return common_pager_exit_handler(r, fpath);
}
+int
+more_inmemory(void *content, int size, int promptend)
+{
+ int r = pmore2_inmemory(content, size, promptend,
+ NULL,
+ common_pager_key_handler,
+ common_pmore_footer_handler,
+ common_pmore_help_handler);
+
+ return memory_pager_exit_handler(r, NULL);
+}
+
#endif // USE_PMORE /////////////////////////////////////////////////////////
diff --git a/pttbbs/mbbsd/pmore.c b/pttbbs/mbbsd/pmore.c
index e573f4c2..f57050f6 100644
--- a/pttbbs/mbbsd/pmore.c
+++ b/pttbbs/mbbsd/pmore.c
@@ -482,11 +482,13 @@ typedef struct
// Just trying to notify you that it's
// NOT REAL MAX LINENO NOR FILELENGTH!!!
// You may consider "S" of "Start" (disps).
+ void (*detachHandler)();
} MmappedFile;
MmappedFile mf = {
0, 0, 0, 0, 0, 0L,
- 0, -1L, 0, 0, -1L, -1L, -1L,-1L
+ 0, -1L, 0, 0, -1L, -1L, -1L, -1L,
+ NULL // detachHandler
}; // current file
/* mf_* navigation commands return value meanings */
@@ -556,6 +558,12 @@ MF_BrowsingPreference bpref =
{ MFDISP_WRAP_WRAP, MFDISP_SEP_DEFAULT, 1,
0, 0, 0, };
+/* structure generalized for the one-arg mf_attach_handler */
+struct SimpleBuffer {
+ void *data;
+ int len;
+};
+
/* pretty format header */
#define FH_HEADERS (4) // how many headers do we know?
#define FH_HEADER_LEN (4) // strlen of each heads
@@ -809,9 +817,16 @@ mf_gunzip(const char *fn GCC_UNUSED, int fd)
/*
* mmap basic operations
*/
+
+MFPROTO void mf_detach();
+MFPROTO void mf_detach_nounmap();
+MFPROTO int mf_postattach();
+
MFPROTO int
-mf_attach(const char *fn)
+mf_attach_file(void *fnptr)
{
+ // We are passing pointer
+ const char *fn = *(const char **)fnptr;
struct stat st;
int fd = open(fn, O_RDONLY);
@@ -846,6 +861,26 @@ mf_attach(const char *fn)
madvise(mf.start, mf.len, MADV_SEQUENTIAL);
#endif
+ mf.detachHandler = mf_detach;
+
+ return mf_postattach();
+}
+
+MFPROTO int
+mf_attach_buffer(void *buf)
+{
+ struct SimpleBuffer *buffer = (struct SimpleBuffer *)buf;
+ if (!buffer || !buffer->data || !buffer->len)
+ return 0;
+ mf.start = buffer->data;
+ mf.len = buffer->len;
+ mf.detachHandler = mf_detach_nounmap;
+ return mf_postattach();
+}
+
+MFPROTO int
+mf_postattach()
+{
mf.end = mf.start + mf.len;
mf.disps = mf.dispe = mf.start;
mf.lineno = 0;
@@ -878,6 +913,14 @@ mf_detach()
}
}
+MFPROTO void
+mf_detach_nounmap()
+{
+ mf_freeHeaders();
+ if (mf.start)
+ RESETMF();
+}
+
/*
* lineno calculation, and moving
*/
@@ -2225,6 +2268,14 @@ PMORE_UINAV_FORWARDLINE()
/*
* piaip's more, a replacement for old more
*/
+static int
+_pmore2(
+ int promptend, void *ctx,
+ int (*mf_attach_handler)(void *), void *ahctx,
+ int (*key_handler) (int key, void *ctx),
+ int (*footer_handler)(int ratio, int width, void *ctx),
+ int (*help_handler) (int y, void *ctx));
+
int
pmore2(
const char *fpath, int promptend, void *ctx,
@@ -2233,6 +2284,43 @@ pmore2(
int (*help_handler) (int y, void *ctx)
)
{
+ return _pmore2(promptend, ctx,
+ mf_attach_file, &fpath,
+ key_handler,
+ footer_handler,
+ help_handler);
+}
+
+int
+pmore2_inmemory(
+ void *content, int size,
+ int promptend, void *ctx,
+ int (*key_handler) (int key, void *ctx),
+ int (*footer_handler)(int ratio, int width, void *ctx),
+ int (*help_handler) (int y, void *ctx)
+ )
+{
+ struct SimpleBuffer buf = {
+ .data = content,
+ .len = size
+ };
+
+ return _pmore2(promptend, ctx,
+ mf_attach_buffer, &buf,
+ key_handler,
+ footer_handler,
+ help_handler);
+}
+
+static int
+_pmore2(
+ int promptend, void *ctx,
+ int (*mf_attach_handler)(void *), void *ahctx,
+ int (*key_handler) (int key, void *ctx),
+ int (*footer_handler)(int ratio, int width, void *ctx),
+ int (*help_handler) (int y, void *ctx)
+ )
+{
int flExit = 0, retval = 0;
int ch = 0;
int invalidate = 1;
@@ -2262,7 +2350,7 @@ pmore2(
STATINC(STAT_MORE);
#endif // STAT_MORE
- if (!mf_attach(fpath))
+ if (!mf_attach_handler(ahctx))
{
REENTRANT_RESTORE();
return -1;
@@ -2775,7 +2863,8 @@ pmore2(
/* DO NOT DO ANYTHING HERE. NOT SAFE RIGHT NOW. */
}
- mf_detach();
+ if (mf.detachHandler)
+ mf.detachHandler();
outs(ANSI_RESET);
REENTRANT_RESTORE();