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

 
Output of file : READMAIL.C contained in archive : MSQ320.ZIP
/* readmail.c
**
** released into the PUBLIC DOMAIN 30 jul 1990 by jim nutt
** Changes released into the PUBLIC DOMAIN 10 jul 1994 by John Dennis
**
** Handles high level message i/o.
**
*/

#include "msged.h"
#include "date.h"
#include "bmg.h"
#include "main.h"
#include "menu.h"

#if 0
#ifdef __EMX__
#include
#endif
#endif
#ifdef __MSC__
#include
#include
#include
#endif
#if defined(MSDOS) && defined(__TURBOC__)
#include
#endif
#if defined(MSDOS) && defined(__WATCOMC__)
#include
#endif
#if defined(MSDOS)
#include
#endif
#if 0
#include
#endif
#ifdef __OS2__
#define INCL_DOSFILEMGR
#include
#endif

#define TEXTLEN 96

#include "normal.h"

int setcwd(char *path);
int wrap(LINE *cl, int x, int y,int rm);
int is_quote(char *text);
char * striptwhite(char *s);
void checkrecvd(msg *m, unsigned long n);
void parse_tokens(char *str, char *tokens[], int num);
static void deleteCrapLine(LINE *crap);
static int is_sameaddr(ADDRESS *msg);

extern int set_rcvd; /* located in msged.c */

#ifdef __OS2__
static unsigned long setDefaultDisk(unsigned long x);
#endif
static int changeDir(char *path);

LINE * clearbuffer(LINE *buffer)
{
LINE *curline;

if ((curline = buffer) != NULL)
{
while (curline->next != NULL)
{
curline = curline->next;
if (curline->prev == NULL)
continue;
if (curline->prev->text != NULL)
free(curline->prev->text);
curline->prev->next = NULL;
free(curline->prev);
curline->prev = NULL;
}
if (curline != NULL)
{
if (curline->text)
free(curline->text);
curline->text = NULL;
free(curline);
curline = NULL;
}
}
return NULL;
}

static void KillTrailingLF(char *text)
{
char *s;

if (text == NULL)
return;

if ((s = strchr(text, '\n')) != NULL)
*s = '\0';
}

msg * readmsg(unsigned long n)
{
ADDRESS a;
LINE *l;
char *tokens[10];
int headerfin = 0;
int afound = 0;
msg *m;
char *text;
char *t, *s;
char *ptmp;
char tmp[128];
int goteot = 0;
int gotsot = 0;

l = NULL;

memset(&a, 0, sizeof(ADDRESS));

if ((m = MsgReadHeader(n, RD_ALL)) == NULL)
return NULL;

stripSoft = 1;
while ((text = MsgReadText(n)) != NULL)
{
if (*text == '\n' || !strlen(text) || !stricmp(text, "Lines:"))
{
headerfin = 1; /* want to stop looking unix header info */
}

if (*text == '\01')
{
switch (*(text+1))
{
case 'M' :
if (strncmp(text+1,"MSGID:",6)!=0)
break;
s = text + 7;

while (isspace(*s)) s++;

release(m->msgid);
m->msgid = strdup(s);

KillTrailingLF(m->msgid);
break;

case 'R' :
if (strncmp(text+1,"REPLY:",6)!=0)
break;
s = text + 7;

while (isspace(*s)) s++;

release(m->reply);
m->reply = strdup(s);

KillTrailingLF(m->reply);
break;

case 'E' :
if (strncmp(text+1, "EOT:", 4) == 0)
{
goteot = 1;
if (gotsot && !(SW->seenbys || SW->shownotes))
{
m->soteot = 1;
}
}
break;

case 'S' :
if (strncmp(text+1, "SOT:", 4) == 0)
{
gotsot = 1;
stripSoft = 0;
}
break;

case 'F' :
if (strncmp(text+1, "FMPT", 4)!=0)
break;

s = text + 5;
m->from.point = atoi(s + 1);
break;

case 'T' :
if (strncmp(text+1, "TOPT", 4)!=0)
break;
s = text + 5;
m->to.point = atoi(s + 1);
break;

case 'D' :
if (strncmp(text+1, "DOMAIN", 6)!=0)
break;

s = text + 7;
strcpy(tmp, s);
memset(tokens, 0, sizeof(tokens));
parse_tokens(tmp, tokens, 4);

if (!tokens[3])
break;

memset(&a, 0, sizeof(ADDRESS));
a = parsenode(tokens[1]);
if (a.fidonet)
{
release(m->to.domain);
m->to = a;
m->to.domain = strdup(tokens[0]);
}

memset(&a, 0, sizeof(ADDRESS));
a = parsenode(tokens[3]);
if (a.fidonet)
{
release(m->from.domain);
m->from = a;
m->from.domain = strdup(tokens[2]);
}
break;

case 'I' :
if (strncmp(text+1,"INTL", 4)!=0)
break;

s = text + 5;
strcpy(tmp, s + 1);
memset(tokens, 0, sizeof(tokens));
parse_tokens(tmp, tokens, 2);

if (!tokens[1])
break;

memset(&a, 0, sizeof(ADDRESS));
a = parsenode(tokens[0]);
if (a.fidonet)
{
release(m->to.domain);
m->to = a;
}
memset(&a, 0, sizeof(ADDRESS));
a = parsenode(tokens[1]);
if (a.fidonet)
{
release(m->from.domain);
m->from = a;
}
break;
}

if (!SW->shownotes)
{
release(text);
continue;
}
}

if (*text == 'S')
{
if ((strncmp(text,"SEEN-BY:",8) == 0)
&& (!(SW->seenbys || SW->shownotes))
&& (!gotsot || goteot))
{
release(text);
continue;
}
}

if (goteot && (*text == '\n') && !(SW->seenbys || SW->shownotes))
{
release(text);
continue;
}

/*
** From Roland Gautschi
*/

if (SW->tabexpand && strchr(text, '\t') != NULL)
{
do
{
if ((ptmp = strdup(text)) != NULL)
{
release(text);

text = malloc(strlen(ptmp) + SW->tabsize);
t = strchr(ptmp,'\t');

/*
** characters before \t
*/

strncpy(text,ptmp, (size_t)(t - ptmp));

/*
** replace \t with spaces
*/

memset(text + (size_t)(t - ptmp), ' ', SW->tabsize);

/*
** copy the rest
*/

strcpy(text + (size_t)(t - ptmp) + SW->tabsize, t + 1);
free(ptmp);
}
else
{
outamemory(); /* shouldn't happen 🙂 */
}
} while(strchr(text, '\t') != NULL);
}

if (CurArea.echomail)
{
if (afound == 0 && strlen(text) > 10 && *(text + 1) == '*')
{
if (!strncmp(text, " * Origin:", 10)) /* probably the origin line */
{
if ((s = strrchr(text, '(')) != NULL)
{
while (*s && !isdigit(*s) && *s != ')')
s++;

if (isdigit(*s))
m->from = parsenode(s);
}
else
m->from.notfound = 1;
}
}
}

if ((strncmp(text, "---", 3) == 0)
&& (strncmp(text, "----", 4) != 0)
&& !(SW->seenbys || SW->shownotes)
&& (!gotsot || goteot))
{
release(text);
continue;
}

if ((strncmp(text, " * Origin:", 10) == 0)
&& !(SW->seenbys || SW->shownotes)
&& (!gotsot || goteot))
{
release(text);
continue;
}

if ((CurArea.uucp || CurArea.news) && headerfin == 0)
{
char *s;

if (CurArea.uucp)
{
if (strncmp(text,"To:",3) == 0)
{
s = strchr(text,' ');
m->to.fidonet = 0;
m->to.internet = 0;
m->to.bangpath = 0;
m->to.notfound = 0;
while (isspace(*s)) s++;
if (strchr(s,'@') != NULL)
m->to.internet = 1;
else
m->to.bangpath = 1;
release(m->to.domain);
m->to.domain = strdup(s);
striptwhite(m->to.domain);
if (!SW->shownotes)
{
release(text);
continue;
}
}
}

if (strncmp(text,"From:",5) == 0)
{
s = strrchr(text,'(');
if (s == NULL)
{
release(m->isfrom);
m->isfrom = strdup("UUCP");
}
else
{
*s = '\0';
if ((t = strrchr(s+1,')')) != NULL)
*t = '\0';
m->isfrom = strdup(s+1);
}
s = strchr(text,' ') + 1;
m->from.fidonet = 0;
m->from.internet = 0;
m->from.bangpath = 0;
m->from.notfound = 0;
while (isspace(*s)) s++;
if (strchr(s,'@') != NULL)
m->from.internet = 1;
else
m->from.bangpath = 1;
release(m->from.domain);
m->from.domain = strdup(s);
striptwhite(m->from.domain);
if (!SW->shownotes)
{
release(text);
continue;
}
}
/*
** Commented out code...
**
** We don't parse the date; we hope the gate has done that
** for us...
**
if (strncmp(text,"Date:",5) == 0)
{
s = strchr(text,' ');
if (s != NULL)
{
while (isspace(*s)) s++;
m->timestamp = parsedate(s);
}
if (!SW->shownotes)
{
release(text);
continue;
}
}

** End of commented out code.
**
*/
}

if ((*text != '\01') || SW->shownotes)
{
if (l == NULL)
{
l = calloc(1, sizeof(LINE));
m->text = l;
l->next = l->prev = NULL;
}
else
{
l->next = (LINE *) calloc(1, sizeof(LINE));
if (l->next == NULL)
{
free(text); /* outamemory! (?) */
break;
}
l->next->next = NULL;
l->next->prev = l;
l = l->next;
}

l->block = 0;
l->text = text;
l->hide = (*text == '\x01');

if (is_quote(text))
l->quote = 1;
else
l->quote = 0;

if (l->quote)
{
if (strlen(l->text) > maxx)
{
wrap(l,1,maxy, maxx);
while (l->next)
l = l->next;
}
}
else
{
if ((*text != '\01') && (*text != '\n') && (strlen(text) > maxx))
{
wrap(l, 1, maxy, maxx);
while (l->next)
l = l->next;
}
}
}
else
release(text);
}

MsgClose();

if (set_rcvd)
checkrecvd(m, n);

return m;
}


/*
**
** Checks to see if a message has been recieved. If so,
** it reads the msg header again (avoiding translations
** done in the original readinf process) and then writes
** the header to the msgbase.
**
*/

void checkrecvd(msg *m, unsigned long n)
{
msg *mn;

if (m->attrib.recvd)
return;

m->times_read++;

if ((stricmp(ST->username, m->isto) == 0) && is_sameaddr(&m->to))
{
if ((mn = MsgReadHeader(n, RD_HEADER)) == NULL)
return;

mn->attrib.recvd = 1;
m->attrib.recvd = 1;
m->newrcvd = 1;
mn->times_read++;
MsgWriteHeader(mn, WR_HEADER);
dispose(mn);
}
}

static int is_sameaddr(ADDRESS *msg)
{
if (msg->zone != CurArea.addr.zone)
{
return (0);
}
if (msg->net != CurArea.addr.net)
{
return (0);
}
if (msg->node != CurArea.addr.node)
{
return (0);
}
if (msg->point != CurArea.addr.point)
{
return (0);
}
return (1);
}

/*
**
** Clears a message only - wipes the slate clean.
**
*/

void clearmsg(msg *m)
{
if (m == NULL)
return;
/* kill the header stuff */
release(m->reply);
release(m->msgid);
release(m->isfrom);
release(m->isto);
release(m->subj);
release(m->to.domain);
release(m->from.domain);

if (m->text)
m->text = clearbuffer(m->text); /* kill the text */
/* clear the whole lot */
memset(m, 0, sizeof(msg));
/* set the defaults */
m->attrib.private = CurArea.priv;
m->attrib.crash = CurArea.crash;
m->attrib.hold = CurArea.hold;
m->attrib.direct = CurArea.direct;
m->attrib.killsent = CurArea.killsent;
m->attrib.local = 1;
}


int setcwd(char *path)
{
char *p;

if ((p = strchr(path,':')) == NULL)
p = path;

if (*p == ':') {
p++;
#ifdef __OS2__
(void) setDefaultDisk((unsigned short)(toupper(*path) - 'A'+1));
#else
bdos(14,toupper(*path) - 'A',0);
#endif
}
return(changeDir(p));
}


/* Gives us the time down to 10th of a second granulinity. */
/* Originally from MsgPost.c by Colin Wheat @ 3:690/613 */
/* Modified to reflect a routine by Lincoln Dale @ 3:690/626 */
/* Modified by Paul Edwards to make it 1 second granularity */
/* but portable */

unsigned long sec_time(void)
{
static unsigned long old_id = 0;
unsigned long i;
time_t now;
struct tm *t;

now = time(NULL);
t = localtime(&now);
i = (t->tm_sec * 10L) +
(t->tm_min * 600L) +
(t->tm_hour * 36000L) +
(t->tm_mday * 864000L) +
(t->tm_mon * 26784000L) +
(t->tm_year * 321408000L);

if (i <= old_id)
{
i = old_id + 1;
}

return (old_id = i);
}


/*
**
** Inserts a line after the passed line and returns a pointer to it.
**
*/

static LINE *InsertAfter(LINE *l, char *text)
{
LINE *nl;

if ((nl = calloc(1, sizeof(LINE))) == NULL)
return NULL;

nl->text = strdup(text);

if (l == NULL)
return nl;

nl->next = l->next;
nl->prev = l;
l->next = nl;
if (nl->next)
nl->next->prev = nl;

return nl;
}


/*
**
** Strips all the kludges from the message, kludges being
** defined as ^a, SEEN-BY:, tear + origin lines.
** Also strips ^a from middle of text
**
*/

static void StripKludges(msg *m)
{
LINE *l, *ol;
char *p;

ol = NULL;
l = m->text;
while (l != NULL)
{
if ((l->text == NULL)
|| ((*(l->text) == '\x01')
|| ((!SW->soteot || SW->seenbys || SW->shownotes)
&& ((strncmp(l->text, "SEEN-BY:", 8) == 0)
|| (strncmp(l->text, "---", 3) == 0)
|| (strncmp(l->text, " * Origin:", 10) == 0)))))
{
if (ol == NULL)
{
if (l->next != NULL)
{
l->next->prev = l->prev;
}
m->text = l->next;
if (l->text != NULL)
{
release(l->text);
}
release(l);
l = m->text;
}
else
{
if (l->next != NULL)
{
l->next->prev = l->prev;
}
ol->next = l->next;
if (l->text != NULL)
{
release(l->text);
}
release(l);
l = ol;
}
}
else
{
p = l->text;
if (p != NULL)
{
while ((p = strchr(p, 0x01)) != NULL)
{
*p = '@';
}
}
ol = l;
l = l->next;
}
}

l = ol;
while (l != NULL)
{
if ((l->text == NULL)
|| (*(l->text) == '\0')
|| (*(l->text) == '\n')
|| (*(l->text) == '\r'))
{
ol = l->prev;
if (l->text != NULL)
{
release(l->text);
}
if (ol == NULL)
{
m->text = NULL;
}
else
{
ol->next = NULL;
release(l);
}
l = ol;
}
else break;
}
return;
}


/*
**
** Gets the origin line to use.
**
*/

static void GetOrigin(char *origin)
{
FILE *fp;
char path[255];

if (!SW->override)
{
if (CurArea.msgtype == SQUISH)
sprintf(path, "%s.SQO", CurArea.path);
else
sprintf(path, "%s\\origin", CurArea.path);

if ((fp = fopen(path,"r")) != NULL)
{
fgets(origin, 65, fp);
fclose(fp);
}
else
{
if (ST->origin != NULL)
strcpy(origin, ST->origin);
else
strcpy(origin, ST->username);
}
}
else
{
if (ST->origin != NULL)
strcpy(origin, ST->origin);
else
strcpy(origin, ST->username);
}
striptwhite(origin);
}


/*
** Sequence of events:
**
** Original address is saved (what is displayed);
** Domain gates are checked for and address is modified if one found;
** if no domain gates, search for UUCP gate && mod address if found.
** check INTL
** check MSGID
** check REPLY
** do PID if one,
** If we found domain gate, do DOMAIN with original saved addresses.
** if we found UUCP, then do a "to:" kludge.
*/

/*
**
** Writes a message to disk.
**
**
*/

int writemsg(msg *m)
{
LINE *curr, *l, *ufrom, *uto, *xblank, *xtear, *xorigin;
ADDRESS to;
ADDRESS from;
unsigned long now;
unsigned long n; /* UMSGID msgnum */
unsigned long length; /* length in bytes of the message */
char text [255]; /* buffer useage */
char origin [255]; /* out origin line */
char *uucp_from; /* saved UUCP from address */
char *uucp_to; /* saved UUCP to address */
int domain_gated;
int uucp_gated;
char *s;
int i;
int abortWrite;

domain_gated = 0;
uucp_gated = 0;
length = 0;
n = m->msgnum;
curr = NULL;
uto = NULL;
ufrom = NULL;
uucp_from = NULL;
uucp_to = NULL;
xorigin = NULL;
xtear = NULL;
xblank = NULL;
now = sec_time();

StripKludges(m);

/*
** Save the original address.
*/

to = m->to;
from = m->from;

/*
**
** Do domain gating...
**
*/

if ((SW->gate == GDOMAINS || SW->gate == BOTH) && SW->domains && m->to.domain)
{
/*
** If we have two domains and they're different, then we want to gate.
** If we have a to: domain and no from: domain, then we still may
** wand to gate. If we don't have a to: domain, then we don't want
** to gate the message (we assume it's destined to our own network).
*/

if (m->to.domain || (m->from.domain && m->to.domain && stricmp(m->from.domain, m->to.domain)))
{
for (i = 0; i < SW->domains; i++)
{
if (!stricmp(domain_list[i].domain, m->to.domain))
{
domain_gated = 1;

if (m->attrib.crash || m->attrib.crash)
{
int ret;

ret = ChoiceBox(" Crash ", "Crash message to?", "Domain Gate", "Dest Node", NULL);
if (ret == ID_ONE)
{
m->to = domain_list[i];
if (domain_list[i].domain)
m->to.domain = strdup(domain_list[i].domain);
}
}
else
{
m->to = domain_list[i];
if (domain_list[i].domain)
m->to.domain = strdup(domain_list[i].domain);
}
break;
}
}
}
}

/*
**
** Do UUCP gating...
**
*/

if (m->to.internet || m->to.bangpath)
{
uucp_gated = 1;
uucp_to = m->to.domain;
m->to = uucp_gate;
if (uucp_gate.domain)
m->to.domain = strdup(uucp_gate.domain);
}

if (m->from.internet || m->from.bangpath)
{
uucp_gated = 1;
uucp_from = m->from.domain;
m->from = uucp_gate;
if (uucp_gate.domain)
m->from.domain = strdup(uucp_gate.domain);
}

/*
**
** Do the netmail stuff;
**
*/

if (CurArea.netmail || CurArea.uucp)
{
if (m->from.zone != m->to.zone || m->from.zone != thisnode.zone)
{
sprintf(text, "\01INTL %d:%d/%d %d:%d/%d\r", m->to.zone, m->to.net, m->to.node, m->from.zone, m->from.net, m->from.node);
curr = InsertAfter(curr, text);
}
if (m->to.point)
{
sprintf(text, "\01TOPT %d\r", m->to.point);
curr = InsertAfter(curr, text);
}
if (m->from.point)
{
sprintf(text, "\01FMPT %d\r", m->from.point);
curr = InsertAfter(curr, text);
}
}

/*
**
** These babies go everywhere.
**
*/

if (m->new)
{
if (SW->msgids)
{
sprintf(text, "\01MSGID: %s %08lx\r", show_address(&from), now);
curr = InsertAfter(curr, text);
}
}
else
{
if (m->msgid)
{
sprintf(text, "\01MSGID: %s\r", m->msgid);
curr = InsertAfter(curr, text);
}
}

if (m->reply && (!m->new || SW->msgids))
{
sprintf(text, "\01REPLY: %s\r", m->reply);
curr = InsertAfter(curr, text);
}

if (SW->usepid || CurArea.netmail)
{
sprintf(text, "\01PID: %s %s\r", PROG, PIDVER PIDALPHA);
curr = InsertAfter(curr, text);
}

/*
**
** Domain gating?
**
*/

if (domain_gated)
{
sprintf(text, "\01DOMAIN %s %d:%d/%d.%d %s %d:%d/%d.%d\r",
to.domain,
to.zone,
to.net,
to.node,
to.point,
from.domain,
from.zone,
from.net,
from.node,
from.point);
curr = InsertAfter(curr, text);
}

if (SW->soteot)
{
strcpy(text, "\01SOT:\r");
curr = InsertAfter(curr, text);
}

if (uucp_gated)
{
int cr = 0; /* we want to insert a \n after header info */

if (uucp_from)
{
sprintf(text, "From: %s\r", uucp_from);
curr = InsertAfter(curr, text);
ufrom = curr;
cr = 1;
}
if (uucp_to)
{
sprintf(text, "To: %s\r", uucp_to);
curr = InsertAfter(curr, text);
uto = curr;
cr = 1;
}
if (cr == 1)
{
strcpy(text, "\n");
curr = InsertAfter(curr, text);
}
}

/*
** Actually assign the kludges we just created to
** the message body (before the text);
*/

if (curr)
{
curr->next = m->text;
if (m->text)
m->text->prev = curr;

while (curr->prev)
curr = curr->prev;

m->text = curr;
}

l = m->text;
while (l)
{
if (l->text == NULL)
l->text = strdup("\r");

if (strlen(l->text) > 0)
{
if ((s = strchr(l->text, '\n')) != NULL)
*s = '\r';

if (s == NULL)
{
strcpy(text, l->text);
if (l->quote)
strcat(text, "\r");
else
{
if (l->next && *(l->next->text) == '\n')
strcat(text, "\r");
else
{
if (!isspace(*(text + strlen(text) - 1)))
strcat(text, " ");
}
}
release(l->text);
l->text = strdup(text);
}
}
else
{
if (l->next)
{
release(l->text);
l->text = strdup("\r");
}
}
l = l->next;
}

/*
** Find the end of the message.
*/

curr = m->text;
while (curr->next)
{
curr = curr->next;
}
/*
** If there isnt't a terminating '\r' on the last line, add one.
*/

if (!curr->text || (curr->text && strchr(curr->text, '\r') == NULL))
{
sprintf(text, "%s\r", curr->text);
release(curr->text);
curr->text = strdup(text);
}

if (SW->soteot)
{
strcpy(text, "\01EOT:\r");
curr = InsertAfter(curr, text);
}

if (CurArea.echomail)
{
strcpy(text, "\r");
curr = InsertAfter(curr, text);
xblank = curr;

/*
** Do the tearline.
*/

if (SW->usepid)
sprintf(text, "---\r");
else
sprintf(text, "--- %s %s\r", PROG, VERSION CLOSED);

curr = InsertAfter(curr, text);
xtear = curr;

/*
** Do the origin line.
*/

GetOrigin(origin);
sprintf(text, " * Origin: %s (%s)\r", origin, show_4d(&from));

curr = InsertAfter(curr, text);
xorigin = curr;
}

/*
** Ok, we've made the new message up; return it's length.
*/

l = m->text;
while (l)
{
length += strlen(l->text);
l = l->next;
}

/*
**
** Remap point originated crashmail.
**
*/

if (!m->attrib.direct && !m->attrib.crash && m->from.point && SW->pointnet != 0 && CurArea.netmail)
{
m->from.net = SW->pointnet;
m->from.node = m->from.point;
m->from.point = 0;
}

/*
**
** Do any required zone gating.
**
*/

if (CurArea.addr.zone != m->to.zone && !m->attrib.direct && !m->attrib.crash && CurArea.netmail && (SW->gate == GZONES || SW->gate == BOTH))
{
m->to.node = m->to.zone;
m->to.zone = CurArea.addr.zone;
m->to.net = CurArea.addr.zone;
}

abortWrite = 0;
while ((MsgWriteHeader(m, WR_ALL) == ERR_OPEN_MSG) && !abortWrite)
{
int ret;

ret = ChoiceBox(" Error! ", "Could not write message!", "Retry", "Cancel", NULL);
if (ret == ID_TWO)
{
abortWrite = 1;
}
}

if (!abortWrite)
{
l = m->text;
while (l)
{
MsgWriteText(l->text, n, length);

/*
** The \r's have to be turned back into \n's because
** the message might be a CC: and so be needed again.
*/

if ((s = strchr(l->text, '\r')) != NULL)
*s = '\n';

l = l->next;
}

MsgWriteText(NULL, n, length);
MsgClose();
}

CurArea.new = 1;

/*
** Clean up; If this message is a CC, then we
** don't want this temporary information to remain.
*/

if (uucp_from)
{
release(uucp_from);
deleteCrapLine(ufrom);
}

if (uucp_to)
{
release(uucp_to);
deleteCrapLine(uto);
}

deleteCrapLine(xblank);
deleteCrapLine(xtear);
deleteCrapLine(xorigin);

if (abortWrite) return FALSE;
else return TRUE;
}

static void deleteCrapLine(LINE *crap)
{
if (crap != NULL)
{
if (crap->prev != NULL) crap->prev->next = crap->next;
if (crap->next != NULL) crap->next->prev = crap->prev;
release(crap->text);
release(crap);
}
return;
}

#ifdef __OS2__

#include

static unsigned long setDefaultDisk(unsigned long x)
{
return (DosSetDefaultDisk(x));
}

static int changeDir(char *path)
{
return (DosSetCurrentDir(path));
}

void mygetcwd(char *buf, int len)
{
unsigned long ulen;

ulen = len;
DosQueryCurrentDir(0, buf, &ulen);
return;
}

#else

static int changeDir(char *path)
{
return (chdir(path));
}

void mygetcwd(char *buf, int len)
{
getcwd(buf, len);
return;
}

#endif

/*--- end ---*/




  3 Responses to “Category : Recently Uploaded Files
Archive   : MSQ320.ZIP
Filename : READMAIL.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/