Category : Recently Uploaded Files
Archive   : MSQ320.ZIP
Filename : FIDO.C

 
Output of file : FIDO.C contained in archive : MSQ320.ZIP
/* fido.c
**
** released into the PUBLIC DOMAIN 30 jul 1990 by jim nutt
** Changes released into the PUBLIC DOMAIN 10 jul 1994 by John Dennis
**
** Fido/Opus style message base support functions for msgedsq.
** NOTE: These routines are slated for extinction in the near future.
** They're to be replaced by the Squish msgAPI. Possibly.
**
** 17/12/91 Added share support to all file routines and converted ansi file
** access code to low level read()/write().
** 26/01/92 Fixed bug in msg routines that seemed to cause a crash on zero
** length msgs (zero, as in no ctrl info and text).
** 23/02/92 Removed locking routines.
** 01/04/92 Made New msgs remain open until writing the text, also added
** some kludge code to handle the reading of opus msgs.
** 12/07/92 Added some more functions to make the interface solid.
** 03/12/92 Fix to WriteHeader.
**
*/

#define CHUNKSZ 256
#define TEXTLEN 96
#define NO_STDLIB /* causes conflicts with errno.h with MSC */
#define DEBUG 0

/*#include */
#include "msged.h"
#include "date.h"
#include
#include
#include
#ifdef __MSC__
# include
#endif
#include
#include
#if DEBUG
#include
#endif

/* file access shortcuts */

#define OPENC O_WRONLY|O_BINARY|O_CREAT /* open/create */
#define OPENRW O_RDWR|O_BINARY /* open read/write */
#define OPENR O_RDONLY|O_BINARY /* open read-only */
#define S_IMODE S_IREAD|S_IWRITE /* open mode */

/* prototypes */

#include "normal.h"

static int compare(const void *i, const void *j);

/* externs */

extern char msgbuf[];

/* structures used in this module */

/* typedef struct _dosdate {
unsigned int day:5;
unsigned int mon:4;
unsigned int year:7;
unsigned int sec:5;
unsigned int min:6;
unsigned int hour:5;
} DOSDATE; */

typedef struct _fidoheader {
char from[36]; /* who from, */
char to[36]; /* who to, */
char subj[72]; /* message subject, */
char date[20]; /* creation date, */
unsigned char times[2]; /* number of times read, */
unsigned char dest[2]; /* destination node, */
unsigned char orig[2]; /* originating node */
unsigned char cost[2]; /* actual cost this msg */
unsigned char orig_net[2]; /* originating net */
unsigned char dest_net[2]; /* destination net */
unsigned char written[4]; /* when it was written */
unsigned char arrived[4]; /* when it arrived */
unsigned char reply[2]; /* thread to previous msg */
unsigned char attrib[2]; /* message attributes */
unsigned char up[2]; /* thread to next msg */
} MFIDO;

/* local vars */

static int fp = -1; /* current file handle */
static unsigned long *msgarr = NULL; /* array of *.msg numbers */
static unsigned long msgarrsz = 0; /* # of numbers in the array */
static unsigned long oldsz = 0; /* total size of the array */


unsigned long FidoMsgnToUid(unsigned long n)
{
if (n > msgarrsz || n == 0)
return 0;

return msgarr[(size_t)(n - 1)];
}

unsigned long FidoUidToMsgn(unsigned long n)
{
unsigned long i;

for (i = 0; i < msgarrsz; i++)
if (msgarr[(size_t)i] == n)
break;

return (i == msgarrsz) ? 0 : i + 1;
}

int FidoMsgWriteText(char *text, unsigned long n, unsigned long mlen)
{
char i = 0;

unused(n);
unused(mlen);
#if DEBUG
assert(fp!=-1);
#endif

if (text == NULL)
{
write(fp, &i, sizeof(char));
return(TRUE);
}

write(fp, text, strlen(text));
return TRUE;
}

int FidoMsgWriteHeader(msg *m, int type)
{
MFIDO msghead;
char path[PATHLEN];
time_t now = time(NULL);
unsigned long n = m->msgnum;
int done = 0;
struct tm *ts;
unsigned long x;

#if DEBUG
assert(fp==-1);
#endif

if (fp != -1)
{
close(fp);
fp = -1;
}

sprintf(path, "%s/%ld.MSG", CurArea.path, n);
if (m->new)
{
while (!done)
{
if ((fp = sopen(path, OPENR, SH_DENYNO, S_IMODE)) != -1)
{
close(fp); fp = -1; n++;
}
else
{
if ((fp = sopen(path, OPENC, SH_DENYNO, S_IMODE)) == -1)
return(ERR_OPEN_MSG);

done = 1;
}
sprintf(path, "%s/%ld.MSG", CurArea.path, n);
}
}
else
{
if ((fp = sopen(path, OPENRW, SH_DENYNO, S_IMODE)) == -1)
return(ERR_OPEN_MSG);
}

if (m->new)
{
if ((++msgarrsz) > oldsz)
{
unsigned long *t;

if ((t = calloc(1,
(size_t)((oldsz+=CHUNKSZ) * sizeof(unsigned long)))) == NULL)
outamemory();

memcpy(t, msgarr, (size_t)(sizeof(unsigned long) * msgarrsz));
release(msgarr);
msgarr = t;
}
msgarr[(size_t)(msgarrsz - 1)] = n;
}

memset(&msghead,0,sizeof msghead);

m->msgnum = n;

msghead.attrib[0] = (unsigned char)
((m->attrib.killsent << 7)
| (m->attrib.orphan << 6)
| (m->attrib.forward << 5)
| (m->attrib.attached << 4)
| (m->attrib.sent << 3)
| (m->attrib.recvd << 2)
| (m->attrib.crash << 1)
| (m->attrib.private));

msghead.attrib[1] = (unsigned char)
((m->attrib.ureq << 7)
| (m->attrib.areq << 6)
| (m->attrib.rcpt << 5)
| (m->attrib.rreq << 4)
| (m->attrib.freq << 3)
| (m->attrib.direct << 2)
| (m->attrib.hold << 1)
| (m->attrib.local));

x = FidoMsgnToUid((unsigned long) m->replyto);
msghead.reply[0] = (unsigned char)(x & 0xff);
msghead.reply[1] = (unsigned char)((x >> 8) & 0xff);
x = FidoMsgnToUid((unsigned long) m->replies[0]);
msghead.up[0] = (unsigned char)(x & 0xff);
msghead.up[1] = (unsigned char)((x >> 8) & 0xff);
msghead.times[0] = (unsigned char)(m->times_read & 0xff);
msghead.times[1] = (unsigned char)((m->times_read >> 8) & 0xff);
msghead.cost[0] = (unsigned char)(m->cost & 0xff);
msghead.cost[1] = (unsigned char)((m->cost >> 8) & 0xff);

msghead.dest_net[0] = (unsigned char)(m->to.net & 0xff);
msghead.dest_net[1] = (unsigned char)((m->to.net >> 8) & 0xff);
msghead.dest[0] = (unsigned char)(m->to.node & 0xff);
msghead.dest[1] = (unsigned char)((m->to.node >> 8) & 0xff);

if (m->isfrom != NULL)
{
memcpy(msghead.from,
m->isfrom,
min(sizeof msghead.from, strlen(m->isfrom)));
}
else
{
msghead.from[0] = '\0';
}
if (m->isto != NULL)
{
memcpy(msghead.to,
m->isto,
min(sizeof msghead.to, strlen(m->isto)));
}
else
{
msghead.to[0] = '\0';
}
if (m->subj != NULL)
{
memcpy(msghead.subj, m->subj, min(sizeof msghead.subj, strlen(m->subj)));
}
else
{
msghead.subj[0] = '\0';
}
memcpy(msghead.date, mtime(m->timestamp), 20);

msghead.orig_net[0] = (unsigned char)(m->from.net & 0xff);
msghead.orig_net[1] = (unsigned char)((m->from.net >> 8) & 0xff);
msghead.orig[0] = (unsigned char)(m->from.node & 0xff);
msghead.orig[1] = (unsigned char)((m->from.node >> 8) & 0xff);

if (SW->opusdate)
{
ts = localtime(&now);
x = ts->tm_year - 80;
x = (x << 4) | (ts->tm_mon + 1);
x = (x << 5) | ts->tm_mday;
x = (x << 5) | ts->tm_hour;
x = (x << 6) | ts->tm_min;
x = (x << 5) | (ts->tm_sec / 2);
msghead.written[0] = (unsigned char)((x >> 16) & 0xff);
msghead.written[1] = (unsigned char)((x >> 24) & 0xff);
msghead.written[2] = (unsigned char)(x & 0xff);
msghead.written[3] = (unsigned char)((x >> 8) & 0xff);
memcpy(msghead.arrived, msghead.written, sizeof msghead.arrived);
}

write(fp, (char *) &msghead, sizeof(MFIDO));

if (type == WR_HEADER)
{
close(fp);
fp = -1;
}

return TRUE;
}


msg *FidoMsgReadHeader(unsigned long n, int type)
{
MFIDO msghead;
char path[PATHLEN];
unsigned long msgn = msgarr[(size_t)(n - 1)];
msg *m;

#if DEBUG
assert(fp==-1);
#endif
if (fp != -1)
{
close(fp);
fp = -1;
}

memset(&msghead,0,sizeof msghead);
sprintf(path, "%s/%ld.MSG", CurArea.path, msgn);
if ((fp = sopen(path, OPENR, SH_DENYNO, S_IMODE)) == -1)
return NULL;

if ((m = calloc(1, sizeof(msg))) == NULL)
outamemory();

read(fp, (char *) &msghead, (int) sizeof(MFIDO));

m->msgnum = msgn;
m->from.net = (msghead.orig_net[1] << 8) | msghead.orig_net[0];
m->from.node = (msghead.orig[1] << 8) | msghead.orig[0];
m->to.net = (msghead.dest_net[1] << 8) | msghead.dest_net[0];
m->to.node = (msghead.dest[1] << 8) | msghead.dest[0];

memset(path, 0, sizeof path);
memcpy(path,msghead.date,sizeof msghead.date);

m->timestamp = parsedate(path);

if ((m->isto = calloc(1, sizeof msghead.to + 1)) == NULL) outamemory();
if ((m->isfrom = calloc(1, sizeof msghead.from + 1)) == NULL) outamemory();
if ((m->subj = calloc(1, sizeof msghead.subj + 1)) == NULL) outamemory();

memcpy(m->isto, msghead.to, sizeof msghead.to);
memcpy(m->isfrom, msghead.from, sizeof msghead.from);
memcpy(m->subj, msghead.subj, sizeof msghead.subj);

m->replyto = FidoUidToMsgn((unsigned long) ((msghead.reply[1] << 8)
| msghead.reply[0]));
m->replies[0] = FidoUidToMsgn((unsigned long) ((msghead.up[1] << 8)
| msghead.up[0]));

m->attrib.ureq = ((msghead.attrib[1] >> 7) & 0x01);
m->attrib.areq = ((msghead.attrib[1] >> 6) & 0x01);
m->attrib.rcpt = ((msghead.attrib[1] >> 5) & 0x01);
m->attrib.rreq = ((msghead.attrib[1] >> 4) & 0x01);
m->attrib.freq = ((msghead.attrib[1] >> 3) & 0x01);
m->attrib.direct = ((msghead.attrib[1] >> 2) & 0x01);
m->attrib.hold = ((msghead.attrib[1] >> 1) & 0x01);
m->attrib.local = ((msghead.attrib[1]) & 0x01);

m->attrib.killsent = ((msghead.attrib[0] >> 7) & 0x01);
m->attrib.orphan = ((msghead.attrib[0] >> 6) & 0x01);
m->attrib.forward = ((msghead.attrib[0] >> 5) & 0x01);
m->attrib.attached = ((msghead.attrib[0] >> 4) & 0x01);
m->attrib.sent = ((msghead.attrib[0] >> 3) & 0x01);
m->attrib.recvd = ((msghead.attrib[0] >> 2) & 0x01);
m->attrib.crash = ((msghead.attrib[0] >> 1) & 0x01);
m->attrib.private = ((msghead.attrib[0]) & 0x01);

m->from.zone = CurArea.addr.zone;
m->to.zone = CurArea.addr.zone;
m->cost = (msghead.cost[1] << 8) | msghead.cost[0];
m->times_read = (msghead.times[1] << 8) | msghead.times[0];

m->to.fidonet = 1;
m->from.fidonet = 1;
m->text = NULL;

if (type == RD_HEADER) {
close(fp);
fp = -1;
}

return m;
}

char *FidoMsgReadText(unsigned long n)
{
static char *next = NULL;
static char *end = NULL;
static unsigned long s = 0;
int i, l;
char *t = NULL;
char *text = NULL;
char eol = '\0';

#if DEBUG
assert(fp!=-1);
assert(n>0);
#else
unused(n);
#endif

if (next == NULL && s != 0) { /* we are finished */
s = 0;
return NULL;
}

if (s == 0) {
s = BUFLEN;
memset(msgbuf, 0, (size_t)(s-1));
lseek(fp, (long) sizeof(MFIDO), SEEK_SET);
}

if (next == NULL) {
i = read(fp, msgbuf, (size_t)(s - 1));
if (i < 1) {
next = NULL;
s = 0;
return(NULL);
}
next = msgbuf;
while (i && (*next == '\0'))
i--, next++;
normalize(next);
end = msgbuf + strlen(msgbuf);
if (end < next)
next = end;
}

if ((end - next) == 0) t = NULL;
else t = memchr(next,'\n',(int) (end - next));

if (t == NULL) {
l = strlen(next);
memcpy(msgbuf,next,l+1);
i = read(fp,msgbuf+l, (size_t)(s - l - 1));
if (i < 1) {
next = NULL;
return(strdup(msgbuf));
}
*(msgbuf + l + i) = '\0';
normalize(msgbuf+l);
end = msgbuf + strlen(msgbuf);
next = msgbuf;
t = memchr(next,'\n', l + i);
}

if (t != NULL) {
eol = *(t+1);
*(t+1) = '\0';
}

text = strdup(next);

if (t != NULL) {
*(t+1) = eol;
next = t+1;
}
else
next = NULL;

return text;
}

int FidoMsgClose(void)
{
if (fp != -1)
{
close(fp);
fp = -1;
}
return TRUE;
}

int FidoMsgAreaClose(void)
{
CurArea.status = 0;
return TRUE;
}

int compare(const void *i, const void *j)
{
return ((int)(* (unsigned long *) i - * (unsigned long *) j));
}

void ScanArea(char *path)
{
struct _dta fileinfo;
int status;
unsigned long msgnum;
unsigned long *t = NULL;

status = dir_findfirst(path, 0, &fileinfo);
msgarrsz = 0;

while (status != -1)
{
if (fileinfo.size >= sizeof(MFIDO))
{
msgnum = atol(fileinfo.name);
msgarrsz++;
if (msgarrsz >= oldsz)
{
if ((t = (unsigned long *) calloc((size_t)(oldsz += CHUNKSZ),
sizeof(unsigned long))) == NULL) {
outamemory();
}
if (msgarr != NULL) /* copy old array accross */
{
memcpy(t, msgarr, (size_t)(sizeof(unsigned long) * msgarrsz));
}
release(msgarr);
msgarr = t;
}
msgarr[(size_t)(msgarrsz - 1)] = msgnum; /* assign new msgnumber */
}
status = dir_findnext(&fileinfo);
}

if (msgarr == NULL) { /* no files at all in dir */
msgarr = malloc(sizeof(unsigned long)*CHUNKSZ);
}
else {
qsort((void *) msgarr, (int) msgarrsz, (size_t) sizeof(unsigned long), compare);
}
}

long FidoMsgAreaOpen(AREA *a)
{
char path[PATHLEN];
short int c = 10, l;
unsigned long msgnum;

sprintf(path,"%s/*.msg",a->path);
a->last = a->first = 1;
a->current = a->lastread = 1;
a->status = 1;

ScanArea(path);

sprintf(path, "%s/%s",a->path, ST->lastread);
if ((fp = sopen(path, OPENR, SH_DENYNO, S_IMODE)) != -1)
{
read(fp, &c, sizeof c);
if (read(fp, &l, sizeof l) != sizeof l)
l = c;

close(fp);
fp = -1;
}
else
l = c = 0;

if (msgarrsz != 0)
{
a->last = msgarrsz;
msgnum = a->last;

for (msgnum=msgarrsz;
(msgnum>1) && (msgarr[(size_t)(msgnum-1)] != (unsigned long) c);
msgnum--) ;
/* void loop */

a->current = (!msgnum) ? a->last : msgnum;
msgnum = a->last;

for (msgnum=msgarrsz;
(msgnum>1) && (msgarr[(size_t)(msgnum-1)] != (unsigned long) l);
msgnum--);
/* void loop */

a->lastread = (!msgnum) ? a->last : msgnum;
}
return msgarrsz;
}


int FidoAreaSetLast(AREA *a)
{
int fp;
char path[PATHLEN];
short i = 0;

sprintf(path, "%s/%s", a->path, ST->lastread);
if ((fp = sopen(path, OPENRW, SH_DENYNO, S_IMODE)) == -1)
{
if (fp == -1 && (errno != EACCES && errno != EMFILE))
{
if ((fp = sopen(path, OPENC, SH_DENYNO, S_IMODE)) == -1)
return FALSE;

lseek(fp,0L,SEEK_SET);

write(fp, &i, sizeof(short));
write(fp, &i, sizeof(short));

close(fp);

return TRUE;
}
return FALSE;
}
lseek(fp, 0L, SEEK_SET);
if (msgarr)
{
i = (short)msgarr[(size_t)(a->current - 1)];
write(fp, (char *)&i, sizeof(short));
i = (short)msgarr[(size_t)(a->lastread - 1)];
write(fp, (char *)&i, sizeof(short));
}
else
{
write(fp, &i, sizeof(short));
write(fp, &i, sizeof(short));
}
close(fp);
return TRUE;
}


int FidoMsgDelete(unsigned long n)
{
char path[TEXTLEN];

/* delete the message */

sprintf(path, "%s/%lu.msg", CurArea.path, n);
remove(path);

/* we now re-scan the area just for the sake of it */

sprintf(path, "%s/*.msg", CurArea.path);
ScanArea(path);

return TRUE;
}

/* --- end of file --- */


  3 Responses to “Category : Recently Uploaded Files
Archive   : MSQ320.ZIP
Filename : FIDO.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/