/*
* QUICK.C
*
* Written on 30-Jul-90 by jim nutt and released to the public domain.
*
* Support for QuickBBS-style message bases.
*/
#include <stdio.h>
#include <string.h>
#include <time.h>
#ifndef PACIFIC
#include <sys/types.h>
#include <sys/stat.h>
#else
#include <stat.h>
#endif
#include <assert.h>
#include <smapi/compiler.h>
#include "addr.h"
#include "nedit.h"
#include "msged.h"
#include "unused.h"
#include "memextra.h"
#include "date.h"
#include "normal.h"
#include "quick.h"
#include "charset.h"
typedef unsigned int bits;
#define CHUNKSZ 32
#define QLASTN 200
short qlast[QLASTN];
static char msgtxt[FILENAME_MAX];
static char msghdr[FILENAME_MAX];
/* I/O macros for platform independent
binary I/O. copied from smapi, as
msged with quick can be compiled
without/smapi (!) */
static void put_word(unsigned char *ptr, unsigned short value)
{
ptr[0] = (value & 0xFF);
ptr[1] = (value >> 8) & 0xFF;
}
#define get_word(ptr) \
((unsigned short)((unsigned char)(ptr)[0]) | \
(((unsigned short)((unsigned char)(ptr)[1])) << 8 ))
int read_qlast(FILE *f, short *p)
{
unsigned char buf[QLASTN * 2], *pbuf = buf;
int i;
if (fread(buf, 2*QLASTN, 1, f) != 1)
{
return 0;
}
for (i=0; i < QLASTN; i++)
{
p[i] = get_word(pbuf);
pbuf += 2;
}
return 1;
}
int write_qlast(FILE *f, short *p)
{
unsigned char buf[QLASTN * 2], *pbuf = buf;
int i;
for (i=0; i < QLASTN; i++)
{
put_word(pbuf, p[i]); pbuf+=2;
}
assert(pbuf - buf == QLASTN * 2);
return (fwrite(buf, 2*QLASTN, 1, f) == 2*QLASTN);
}
struct qinfo
{
short low;
short high;
short active;
short areas[200];
};
#define QINFO_SIZE (6+200*2)
int read_qinfo(FILE *f, struct qinfo *qinfo)
{
unsigned char buf[QINFO_SIZE], *pbuf = buf;
int i;
if (fread(buf, QINFO_SIZE, 1, f) != 1)
{
return 0;
}
qinfo->low = get_word(pbuf); pbuf+=2;
qinfo->high = get_word(pbuf); pbuf+=2;
qinfo->active = get_word(pbuf); pbuf+=2;
for (i=0; i < 200; i++)
{
qinfo->areas[i] = get_word(pbuf); pbuf+=2;
}
assert (pbuf - buf == QINFO_SIZE);
return 1;
}
int write_qinfo(FILE *f, struct qinfo *qinfo)
{
unsigned char buf[QINFO_SIZE], *pbuf = buf;
int i;
put_word(pbuf, qinfo->low); pbuf+=2;
put_word(pbuf, qinfo->high); pbuf+=2;
put_word(pbuf, qinfo->active); pbuf+=2;
for (i=0; i < 200; i++)
{
put_word(pbuf, qinfo->areas[i]); pbuf+=2;
}
assert (pbuf - buf == QINFO_SIZE);
if (fwrite(buf, QINFO_SIZE, 1, f) != 1)
{
return 0;
}
return 1;
}
struct qidx
{
short number;
char board;
};
#define QIDX_SIZE 3
int read_qidx(FILE *f, struct qidx *qidx)
{
unsigned char buf[QIDX_SIZE], *pbuf = buf;
if (fread(buf, QIDX_SIZE, 1, f) != 1)
{
return 0;
}
qidx->number = get_word(pbuf); pbuf+=2;
qidx->board = *pbuf; pbuf++;
assert (pbuf - buf == QIDX_SIZE);
return 1;
}
int write_qidx(FILE *f, struct qidx *qidx)
{
unsigned char buf[QIDX_SIZE], *pbuf = buf;
put_word(pbuf, qidx->number); pbuf+=2;
*pbuf = qidx->board; pbuf++;
assert (pbuf - buf == QIDX_SIZE);
if (fwrite(buf, QIDX_SIZE, 1, f) != 1)
{
return 0;
}
return 1;
}
struct qmsg
{
short number;
short replyto;
short replyfrom;
short times_read; /* 8 bytes */
unsigned short start;
unsigned short count;
short destnet;
short destnode; /* 16 bytes */
short orignet;
short orignode;
char destzone;
char origzone;
short cost; /* 24 bytes */
/* message attributes */
bits deleted : 1;
bits outnet : 1;
bits netmail : 1;
bits priv : 1;
bits rcvd : 1;
bits echo : 1;
bits local : 1;
bits xx1 : 1;
bits killsent : 1;
bits sent : 1;
bits attach : 1;
bits crash : 1;
bits rreq : 1;
bits areq : 1;
bits rrcpt : 1;
bits xx2 : 1; /* 26 bytes */
char board; /* 27 bytes */
char posttime[6]; /* 33 bytes */
char postdate[9]; /* 42 bytes */
char whoto[36]; /* 78 bytes */
char whofrom[36]; /* 114 bytes */
char subject[73]; /* 187 bytes */
};
#define QMSG_SIZE 187
static int read_qmsg(FILE *f, struct qmsg *qmsg)
{
unsigned char buf[QMSG_SIZE], *pbuf = buf;
unsigned short attr;
if (fread(buf, QMSG_SIZE, 1, f) != 1)
{
return 0;
}
qmsg->number=get_word(pbuf); pbuf+=2;
qmsg->replyto=get_word(pbuf); pbuf+=2;
qmsg->replyfrom=get_word(pbuf); pbuf+=2;
qmsg->times_read=get_word(pbuf); pbuf+=2;
qmsg->start=get_word(pbuf); pbuf+=2;
qmsg->count=get_word(pbuf); pbuf+=2;
qmsg->destnet=get_word(pbuf); pbuf+=2;
qmsg->destnode=get_word(pbuf); pbuf+=2;
qmsg->orignet=get_word(pbuf); pbuf+=2;
qmsg->orignode=get_word(pbuf); pbuf+=2;
qmsg->destzone = *pbuf; pbuf++;
qmsg->origzone = *pbuf; pbuf++;
qmsg->cost=get_word(pbuf); pbuf+=2;
attr = get_word(pbuf); pbuf+=2;
qmsg->deleted = attr & 1; attr = attr >> 1;
qmsg->outnet = attr & 1; attr = attr >> 1;
qmsg->netmail = attr & 1; attr = attr >> 1;
qmsg->priv = attr & 1; attr = attr >> 1;
qmsg->rcvd = attr & 1; attr = attr >> 1;
qmsg->echo = attr & 1; attr = attr >> 1;
qmsg->local = attr & 1; attr = attr >> 1;
qmsg->xx1 = attr & 1; attr = attr >> 1;
qmsg->killsent = attr & 1; attr = attr >> 1;
qmsg->sent = attr & 1; attr = attr >> 1;
qmsg->attach = attr & 1; attr = attr >> 1;
qmsg->crash = attr & 1; attr = attr >> 1;
qmsg->rreq = attr & 1; attr = attr >> 1;
qmsg->areq = attr & 1; attr = attr >> 1;
qmsg->rrcpt = attr & 1; attr = attr >> 1;
qmsg->xx2 = attr & 1; attr = attr >> 1;
qmsg->board = *pbuf; pbuf++;
memcpy(qmsg->posttime, pbuf, 6); pbuf+=6;
memcpy(qmsg->postdate, pbuf, 9); pbuf+=9;
memcpy(qmsg->whoto, pbuf, 36); pbuf+=36;
memcpy(qmsg->whofrom, pbuf, 36); pbuf+=36;
memcpy(qmsg->subject, pbuf, 73); pbuf+=73;
assert (pbuf - buf == QMSG_SIZE);
return 1;
}
static int write_qmsg(FILE *f, struct qmsg *qmsg)
{
unsigned char buf[QMSG_SIZE], *pbuf = buf;
unsigned short attr;
put_word(pbuf,qmsg->number); pbuf+=2;
put_word(pbuf,qmsg->replyto); pbuf+=2;
put_word(pbuf,qmsg->replyfrom); pbuf+=2;
put_word(pbuf,qmsg->times_read); pbuf+=2;
put_word(pbuf,qmsg->start); pbuf+=2;
put_word(pbuf,qmsg->count); pbuf+=2;
put_word(pbuf,qmsg->destnet); pbuf+=2;
put_word(pbuf,qmsg->destnode); pbuf+=2;
put_word(pbuf,qmsg->orignet); pbuf+=2;
put_word(pbuf,qmsg->orignode); pbuf+=2;
*pbuf = qmsg->destzone; pbuf++;
*pbuf = qmsg->origzone; pbuf++;
put_word(pbuf,qmsg->cost); pbuf+=2;
attr =
(qmsg->deleted ? 1 : 0) +
(qmsg->outnet ? 2 : 0) +
(qmsg->netmail ? 4 : 0) +
(qmsg->priv ? 8 : 0 )+
(qmsg->rcvd ? 16 : 0 ) +
(qmsg->echo ? 32 : 0 ) +
(qmsg->local ? 64 : 0 ) +
(qmsg->xx1 ? 128 : 0 ) +
(qmsg->killsent ? 256 : 0 ) +
(qmsg->sent ? 512 : 0 ) +
(qmsg->attach ? 1024 : 0 ) +
(qmsg->crash ? 2048 : 0 ) +
(qmsg->rreq ? 4096 : 0 ) +
(qmsg->areq ? 8192 : 0 ) +
(qmsg->rrcpt ? 16384 : 0 ) +
(qmsg->xx2 ? 32768U : 0 );
put_word(pbuf, attr); pbuf+=2;
*pbuf = qmsg->board; pbuf++;
memcpy(pbuf, qmsg->posttime, 6); pbuf+=6;
memcpy(pbuf, qmsg->postdate, 9); pbuf+=9;
memcpy(pbuf, qmsg->whoto, 36); pbuf+=36;
memcpy(pbuf, qmsg->whofrom, 36); pbuf+=36;
memcpy(pbuf, qmsg->subject, 73); pbuf+=73;
assert (pbuf - buf == QMSG_SIZE);
if (fwrite(buf, QMSG_SIZE, 1, f) != 1)
{
return 0;
}
return 1;
}
struct qtext
{
unsigned char length;
char text[BLOCKLEN];
};
#define QTEXT_SIZE (BLOCKLEN+1)
static int read_qtext(FILE *f, struct qtext *qtext)
{
unsigned char buf[QTEXT_SIZE], *pbuf = buf;
if (fread(buf, QTEXT_SIZE, 1, f) != 1)
{
return 0;
}
qtext->length= *pbuf; pbuf++;
memcpy(qtext->text, pbuf, BLOCKLEN); pbuf+=BLOCKLEN;
assert (pbuf - buf == QTEXT_SIZE);
return 1;
}
static int write_qtext(FILE *f, struct qtext *qtext)
{
unsigned char buf[QTEXT_SIZE], *pbuf = buf;
*pbuf = qtext->length; pbuf++;
memcpy(pbuf, qtext->text, BLOCKLEN); pbuf+=BLOCKLEN;
assert (pbuf - buf == QTEXT_SIZE);
if (fwrite(buf, QTEXT_SIZE, 1, f) != 1)
{
return 0;
}
return 1;
}
static struct qinfo info;
static struct qmsg header;
static char path[80];
static long start = -1;
static long count = 0;
static int position = 0;
static FILE *infofp = NULL;
static FILE *idxfp = NULL;
static FILE *textfp = NULL;
static FILE *hdrfp = NULL;
static FILE *toidxfp = NULL;
static short *messages = NULL;
static int maxmsgs;
int QuickMsgDelete(unsigned long n)
{
struct qidx index;
header.deleted = 1;
if (fseek(hdrfp, (long)(messages[(size_t) (n - 1)] *
(long)QIDX_SIZE), SEEK_SET))
{
return FALSE;
}
write_qmsg(hdrfp, &header);
fflush(hdrfp);
fseek(idxfp, messages[(size_t) (n - 1)] * (long)QIDX_SIZE, SEEK_SET);
index.board = (char)CurArea.board;
index.number = -1;
write_qidx(idxfp, &index);
fflush(idxfp);
start = count = 0;
position = 0;
info.areas[CurArea.board - 1]--;
fseek(infofp, 0L, SEEK_SET);
write_qinfo(infofp, &info);
fflush(infofp);
return TRUE;
}
int QuickMsgWriteText(char *text, unsigned long n, unsigned long mlen)
{
static struct qtext block;
char *s;
static char buf[768];
struct stat b;
static int f = 0;
unused(mlen);
if (f == 0)
{
f = 1;
#if defined(PACIFIC) || defined(LATTICE)
stat(msgtxt, &b);
#else
fstat(fileno(textfp), &b);
#endif
start = b.st_size / QTEXT_SIZE;
count = 0;
}
if (text == NULL)
{
n = position;
memset(block.text, 0, sizeof block.text);
strcpy(block.text, buf);
block.length = (char)strlen(buf);
fseek(textfp, (long)(start + count) * (long)QTEXT_SIZE, SEEK_SET);
write_qtext(textfp, &block);
fflush(textfp);
header.start = (unsigned short)start;
header.count = (unsigned short)++count;
fseek(hdrfp, (long)n * (long)QMSG_SIZE, SEEK_SET);
write_qmsg(hdrfp, &header);
fflush(hdrfp);
f = 0;
memset(buf, 0, sizeof buf);
return TRUE;
}
strcat(buf, text);
while (strlen(buf) > sizeof block.text)
{
s = buf + sizeof block.text;
memcpy(block.text, buf, sizeof block.text);
strcpy(buf, s);
block.length = sizeof block.text;
fseek(textfp, (long)(start + count) * (long)QTEXT_SIZE, SEEK_SET);
write_qtext(textfp, &block);
fflush(textfp);
count++;
}
return TRUE;
}
short quick2msg(short number)
{
struct qidx index;
int i = 0;
if (number == 0)
{
return 0;
}
for (i = 0; i < CurArea.messages; i++)
{
if (fseek(idxfp, messages[(size_t) i] * (long) QIDX_SIZE, SEEK_SET))
{
return 0;
}
if (read_qidx(idxfp, &index) != 1)
{
return 0;
}
if (index.number == number)
{
return (short) (i + 1);
}
}
return 0;
}
short msg2quick(short n)
{
struct qidx index;
if (n > (CurArea.messages + 1) || n == 0)
{
return 0;
}
if (fseek(idxfp, messages[(size_t) (n - 1)] * (long)QIDX_SIZE, SEEK_SET))
{
return 0;
}
if (read_qidx(idxfp, &index) != 1)
{
return 0;
}
return index.number;
}
short find_link(unsigned long n)
{
struct qmsg header;
struct stat b;
long i;
if (messages == NULL)
{
return 0;
}
#if defined(PACIFIC) || defined(LATTICE)
stat(msghdr, &b);
#else
fstat(fileno(hdrfp), &b);
#endif
i = (long)(messages[(size_t) (n - 1)]) * (long)QMSG_SIZE;
if (i > b.st_size)
{
return 0;
}
fseek(hdrfp, i, SEEK_SET);
if (read_qmsg(hdrfp, &header) != 1)
{
return 0;
}
#if defined(PACIFIC) || defined(LATTICE)
fclose(textfp);
textfp = fopen(msgtxt, "r+b");
stat(msgtxt, &b);
#else
fstat(fileno(textfp), &b);
#endif
if ((((long)header.start + (long)header.count) *
(long)QTEXT_SIZE) > b.st_size)
{
return 0;
}
if (header.deleted)
{
return 0;
}
return quick2msg(header.replyfrom);
}
msg *QuickMsgReadHeader(unsigned long n, int type)
{
struct stat b;
char path[80];
msg *m;
long i;
unused(type);
if (messages == NULL || n == 0)
{
return NULL;
}
memset(path, 0, sizeof path);
#if defined(PACIFIC) || defined(LATTICE)
stat(msghdr, &b);
#else
fstat(fileno(hdrfp), &b);
#endif
i = (long)(messages[(size_t) (n - 1)]) * (long) QMSG_SIZE;
if (i > b.st_size)
{
return NULL;
}
position = messages[(size_t) (n - 1)];
fseek(hdrfp, i, SEEK_SET);
if (read_qmsg(hdrfp, &header) != 1)
{
return NULL;
}
start = (long)header.start;
count = (long)header.count;
#ifdef PACIFIC
fclose(textfp);
textfp = fopen(msgtxt, "r+b");
stat(msgtxt, &b);
#else
fstat(fileno(textfp), &b);
#endif
if (((start + count) * (long)QTEXT_SIZE) > b.st_size)
{
return NULL;
}
if (header.deleted)
{
return NULL;
}
m = xcalloc(1, sizeof *m);
m->msgnum = quick2msg(header.number);
m->isfrom = xcalloc(header.whofrom[0] + 1, 1);
strncpy(m->isfrom, header.whofrom + 1, header.whofrom[0]);
m->isto = xcalloc(header.whoto[0] + 1, 1);
strncpy(m->isto, header.whoto + 1, header.whoto[0]);
m->subj = xcalloc(header.subject[0] + 1, 1);
strncpy(m->subj, header.subject + 1, header.subject[0]);
strncpy(path, header.postdate + 1, header.postdate[0]);
strcat(path, " ");
strncat(path, header.posttime + 1, header.posttime[0]);
m->timestamp = parsedate(path);
if (!(type & RD_HEADER_BRIEF))
{
if (header.replyto)
{
m->replyto = quick2msg(header.replyto);
}
if (header.replyfrom)
{
m->replies[0] = quick2msg(header.replyfrom);
}
if (type & RD_ALL)
{
header.times_read++;
fseek(hdrfp, (long)position * (long)QMSG_SIZE, SEEK_SET);
write_qmsg(hdrfp, &header);
}
}
m->attrib.priv = header.priv;
m->attrib.crash = header.crash;
m->attrib.rcvd = header.rcvd;
m->attrib.sent = header.sent;
m->attrib.attach = header.attach;
m->attrib.forward = 0;
m->attrib.orphan = 0;
m->attrib.killsent = header.killsent;
m->attrib.local = header.local;
m->attrib.hold = header.xx1;
m->attrib.direct = header.xx2;
m->attrib.freq = 0;
m->attrib.rreq = header.rreq;
m->attrib.rcpt = header.rrcpt;
m->attrib.areq = header.areq;
m->attrib.ureq = 0;
m->to.zone = header.destzone;
m->to.net = header.destnet;
m->to.node = header.destnode;
m->times_read = header.times_read;
m->from.zone = header.destzone;
m->from.net = header.destnet;
m->from.node = header.destnode;
m->to.fidonet = m->from.fidonet = 1;
return m;
}
int QuickMsgWriteHeader(msg * m, int type)
{
struct qidx index;
struct tm *ts;
struct stat b;
FILE *fp;
size_t len_to, len_from, len_subj;
int c = (int)(CurArea.current - 1);
unused(type);
memset(&header, 0, sizeof header);
if (m->new)
{
c = (int)CurArea.messages;
#ifdef PACIFIC
stat(msghdr, &b);
#else
fstat(fileno(hdrfp), &b);
#endif
if (c >= maxmsgs)
{
messages = xrealloc(messages, (maxmsgs += CHUNKSZ) * sizeof(short));
}
messages[c] = (short)(b.st_size / QMSG_SIZE);
start = (unsigned short)(header.start = 0);
count = (unsigned short)(header.count = 0);
info.areas[CurArea.board - 1]++;
info.active++;
header.number = ++info.high;
}
else
{
if ((header.number = msg2quick((short)m->msgnum)) == 0)
{
return FALSE;
}
header.start = (unsigned short)start;
header.count = (unsigned short)count;
}
position = messages[c];
header.replyto = msg2quick((short)m->replyto);
header.replyfrom = msg2quick((short)(m->replies[0]));
header.times_read = (short)m->times_read;
header.destzone = (char)m->to.zone;
header.destnet = (short)m->to.net;
header.destnode = (short)m->to.node;
header.origzone = (char)m->from.zone;
header.orignet = (short)m->from.net;
header.orignode = (short)m->from.node;
header.cost = (short)m->cost;
header.deleted = 0;
header.outnet = 0;
header.netmail = 0;
header.echo = 0;
if (CurArea.netmail)
{
header.netmail = 1;
header.outnet = 1;
}
if (CurArea.echomail)
{
header.echo = 1;
}
header.priv = m->attrib.priv;
header.rcvd = m->attrib.rcvd;
header.local = m->attrib.local;
header.xx1 = m->attrib.hold;
header.killsent = m->attrib.killsent;
header.sent = m->attrib.sent;
header.attach = m->attrib.attach;
header.crash = m->attrib.crash;
header.rreq = m->attrib.rreq;
header.areq = m->attrib.areq;
header.rrcpt = m->attrib.rcpt;
header.xx2 = m->attrib.direct;
header.board = (char)CurArea.board;
ts = localtime(&m->timestamp);
header.posttime[0] = 5;
sprintf(header.posttime + 1, "%02d:%02d", ts->tm_hour, ts->tm_min);
header.postdate[0] = 8;
sprintf(header.postdate + 1, "%02d-%02d-%02d", ts->tm_mon + 1,
ts->tm_mday, (ts->tm_year % 100));
if (m->isto == NULL)
{
header.whoto[0] = 0;
}
else
{
len_to = strlen(m->isto);
header.whoto[0] = (char)min(len_to, sizeof(header.whoto) - 1);
memcpy(header.whoto + 1, m->isto, header.whoto[0]);
}
if (m->isfrom == NULL)
{
header.whofrom[0] = 0;
}
else
{
len_from = strlen(m->isfrom);
header.whofrom[0] = (char)min(len_from, sizeof(header.whofrom));
memcpy(header.whofrom + 1, m->isfrom, header.whofrom[0]);
}
if (m->subj == NULL)
{
header.subject[0] = 0;
}
else
{
len_subj = strlen(m->subj);
header.subject[0] = (char)min(len_subj, sizeof(header.subject) - 1);
memcpy(header.subject + 1, m->subj, header.subject[0]);
}
fseek(hdrfp, (long)position * (long)QMSG_SIZE, SEEK_SET);
write_qmsg(hdrfp, &header);
fseek(infofp, 0L, SEEK_SET);
write_qinfo(infofp, &info);
index.number = header.number;
index.board = (char)CurArea.board;
fseek(idxfp, (long)position * (long)QIDX_SIZE, SEEK_SET);
write_qidx(idxfp, &index);
fflush(idxfp);
fflush(infofp);
fflush(hdrfp);
strcpy(path, ST->quickbbs);
strcat(path, "/msgtoidx.bbs");
fp = fopen(path, "r+b");
if (fp == NULL)
{
fp = fopen(path, "w+b");
if (fp == NULL)
{
return TRUE;
}
}
fseek(fp, (long)position * (long)sizeof(header.whoto), SEEK_SET);
fwrite(header.whoto, sizeof(header.whoto), 1, fp);
fclose(fp);
return TRUE;
}
char *QuickMsgReadText(unsigned long n)
{
static struct qtext text;
static long int b = -1;
static long int c = -1;
static char *next = NULL;
char *t, *t2, ch = '\0';
static char *s = NULL;
if ((long)n < 0)
{
b = c = -1;
next = NULL;
if (s)
{
xfree(s);
}
s = NULL;
return NULL;
}
if (next == NULL && s != NULL)
{
xfree(s);
b = c = -1;
s = NULL;
return NULL;
}
if (s == NULL)
{
if (b == -1)
{
b = (long)(start = (long)header.start);
c = (long)(count = (long)header.count);
}
if (c < 1 || b < 0)
{
b = c = -1;
return NULL;
}
s = xmalloc((size_t) count * sizeof text + 1);
memset(s, 0, (size_t) c * sizeof text + 1);
fseek(textfp, (long)(start * (long)QTEXT_SIZE), SEEK_SET);
while (c)
{
memset(&text, 0, sizeof text);
if (read_qtext(textfp, &text) == 1)
{
if (text.length > sizeof text.text)
{
text.length = sizeof text.text;
}
strncat(s, text.text, text.length);
}
c--;
}
normalize(s);
next = s;
}
t = next;
next = strchr(t, '\n');
if (next)
{
ch = *(next + 1);
*(next + 1) = '\0';
}
t2 = xstrdup(t);
if (next)
{
*(next + 1) = ch;
next++;
}
return t2;
}
int QuickAreaSetLast(AREA * a)
{
FILE *fp;
strcpy(path, ST->quickbbs);
strcat(path, "/lastread.bbs");
if (messages == NULL || a->current == 0)
{
qlast[a->board - 1] = 0;
}
else
{
qlast[a->board - 1] = msg2quick((short) a->lastread);
}
fp = fopen(path, "wb");
if (fp != NULL)
{
write_qlast(fp, qlast);
fclose(fp);
}
return TRUE;
}
static int quick_scan(AREA * a)
{
struct qidx index;
FILE *fp;
int i, idx;
position = 0;
if (infofp != NULL)
{
fclose(infofp);
}
strcpy(path, ST->quickbbs);
strcat(path, "/msginfo.bbs");
infofp = fopen(path, "r+b");
if (infofp == NULL)
{
infofp = fopen(path, "w+b");
if (infofp == NULL)
{
return 0;
}
}
if (idxfp != NULL)
{
fclose(idxfp);
}
strcpy(path, ST->quickbbs);
strcat(path, "/msgidx.bbs");
idxfp = fopen(path, "r+b");
if (idxfp == NULL)
{
idxfp = fopen(path, "w+b");
if (idxfp == NULL)
{
return 0;
}
}
if (textfp != NULL)
{
fclose(textfp);
}
strcpy(path, ST->quickbbs);
strcat(path, "/msgtxt.bbs");
strcpy(msgtxt, path);
textfp = fopen(path, "r+b");
if (textfp == NULL)
{
textfp = fopen(path, "w+b");
if (textfp == NULL)
{
return 0;
}
}
if (hdrfp != NULL)
{
fclose(hdrfp);
}
strcpy(path, ST->quickbbs);
strcat(path, "/msghdr.bbs");
strcpy(msghdr, path);
hdrfp = fopen(path, "r+b");
if (hdrfp == NULL)
{
hdrfp = fopen(path, "w+b");
if (hdrfp == NULL)
{
return 0;
}
}
if (toidxfp != NULL)
{
fclose(toidxfp);
}
strcpy(path, ST->quickbbs);
strcat(path, "/msgtoidx.bbs");
toidxfp = fopen(path, "r+b");
if (toidxfp == NULL)
{
toidxfp = fopen(path, "w+b");
if (toidxfp == NULL)
{
return 0;
}
}
if (messages != NULL)
{
xfree(messages);
}
messages = NULL;
rewind(infofp);
if (read_qinfo(infofp, &info) != 1)
{
memset(&info, 0, sizeof info);
}
i = 0;
maxmsgs = 0;
idx = 0;
rewind(idxfp);
while (read_qidx(idxfp, &index) == 1)
{
if (index.board == (char)a->board && index.number > 0)
{
if (i >= maxmsgs)
{
messages = xrealloc(messages, (maxmsgs += CHUNKSZ) * sizeof(short));
}
messages[i++] = (short)idx;
}
idx++;
}
a->first = 1;
a->last = i;
a->messages = i;
strcpy(path, ST->quickbbs);
strcat(path, "/lastread.bbs");
fp = fopen(path, "rb");
if (fp != NULL)
{
read_qlast(fp, qlast);
a->lastread = qlast[a->board - 1];
fclose(fp);
}
a->current = quick2msg((short) a->lastread);
a->lastread = a->current;
if (a->lastread > i || i <= 0)
{
a->lastread = 0;
}
if (a->current > i || i <= 0)
{
a->current = 0;
}
info.areas[a->board - 1] = (short)i;
return i;
}
int QuickMsgClose(void)
{
return 0;
}
long QuickMsgAreaOpen(AREA * a)
{
long ret;
ret = quick_scan(a);
a->status = 1;
a->scanned = 1;
return ret;
}
int QuickMsgAreaClose(void)
{
CurArea.status = 0;
return TRUE;
}
unsigned long QuickMsgnToUid(unsigned long n)
{
return n;
}
unsigned long QuickUidToMsgn(unsigned long n)
{
return n;
}
int QuickMsgLock(void)
{
return 0;
}
int QuickMsgUnlock(void)
{
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1