home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
rtsi.com
/
2014.01.www.rtsi.com.tar
/
www.rtsi.com
/
OS9
/
OSK
/
TELECOM
/
OSKBox.lzh
/
MAILBOX
/
CC
/
mailbox.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-25
|
36KB
|
1,745 lines
#include <stdio.h>
#include <ctype.h>
#include <direct.h>
#include <signal.h>
#include <modes.h>
#include <errno.h>
#include <procid.h>
#include "mailbox.h"
#define BBSONLY
#define FWDPORT "T3"
#define ALARM ((1 << 31) + 10 * 60 * 256)
#define MAXLIST 50
char line[256];
char *noname = "new user";
char *filedir = "FILES/";
char *maildir = "MAIL/";
char *banner = BANNER;
char *ownerfile = "file_owners";
char *days[] = {"Sunday","Monday","Tuesday","Wednesday",
"Thursday","Friday","Saturday"};
int signalman(), quit = 0, interrupt = 0;
int connect_time, connect_date;
struct userstruct user;
long user_rec;
int user_nmr;
int sid_bbs, mid_flag, bid_flag, hflag;
extern struct dist_list *distboxes;
int last_read = -1;
int fwdport = 0;
int msg_proc = 0;
main (argc, argv)
char *argv[];
{
chdir (HOME);
intercept (signalman);
login (argc, argv);
while (!quit) {
if (msg_proc )
{
struct pdsc buffer;
if (_get_process_desc (msg_proc, sizeof (buffer), &buffer) != -1 &&
buffer._state & (1 << 8))
if (wait (0) == msg_proc)
msg_proc = 0;
}
if (!(user.usopt & ISEXPERT)) {
printf ("Commands are:\n");
printf (
" B - bye X - expert/novice I - info N - enter your name\n");
printf (
" L - list messages R - read S - send K - kill C - copy M - modify\n");
printf (
" W - list files D - download U - upload Z - erase V - rename\n");
printf (
" Q - query E - execute H - help\n");
}
if (sid_bbs)
printf (">\n");
else
printf ("\nCommand: >\n");
getline ();
switch (toupper (*line)) {
case '\0':
break;
case 'B':
logout (argc, argv);
case 'D':
download ();
break;
case 'E':
execute ();
break;
case 'U':
upload ();
break;
case 'Z':
zap ();
break;
case 'V':
rename ();
break;
case 'I':
if (!printfile ("info"))
printf ("No info available at this time\n");
break;
case 'N':
name ();
break;
case 'W':
what ();
break;
case 'X':
user.usopt ^= ISEXPERT;
break;
case 'S':
send ();
break;
case 'L':
list ();
break;
case 'R':
readmsg ();
break;
case 'K':
killmsg ();
break;
case 'Q':
query ();
break;
case 'C':
copy ();
break;
case 'M':
modify ();
break;
case 'H':
case '?':
help ();
break;
case '*':
link (argc, argv);
break;
case '@':
if (!sysop ()) goto what;
break;
case 'F':
if (!reverse ()) goto what;
logout (argc, argv);
case '[':
if (!sid ()) goto what;
break;
default:
what: if (user.usopt & ISEXPERT)
printf ("What? Type H for help, X for command list.\n");
else
printf ("What? Type H for help.\n");
break;
}
}
logout (argc, argv);
}
#define MAXTFC 100
login (argc, argv)
char *argv[];
{
int ssid = 0;
int date, time, tick;
short day;
struct fildes buffer;
char *p;
int i, len, userfile, found;
struct msg_header *head;
int flag = 1;
int f;
struct {
int count;
char whoto[7];
} traffic[MAXTFC];
int traffic_count = 0;
char *usercall;
int downfile;
char downname[69];
_sysdate (0, &time, &date, &day, &tick);
connect_time = time;
connect_date = date;
for (i = 1; i < argc; i++)
upper (argv[i]);
if (argc < 2) {
if ((usercall = getenv ("CALL")) == NULL) {
printf ("Welcome to the WD6CMU OSKbox.\n");
read_dist_list ();
user.usopt = ISEXPERT + ISSUPER;
strcpy (user.uscall, "SYSOP");
strcpy (user.usname, "Master");
return;
}
}
else
usercall = argv[1];
if ((userfile = open ("users", 1)) <= 0) {
printf ("Error: can't open user file\n");
exit (0);
}
ssid = get_ssid (usercall);
found = 0;
while (1) {
user_rec = lseek (userfile, 0L, 1);
if (read (userfile, &user, sizeof (user)) == 0) break;
if (!(user.usopt & ISDELETED) && strcmp (user.uscall, usercall) == 0) {
found = 1;
break;
}
}
if (!found) {
strcpy (user.usname, noname);
strcpy (user.uscall, usercall);
user.usopt = 0;
user.ustime = 0;
user.usdate = 0;
user.uscnt = 0;
open_mail ();
user.usnmr = 0;
while ((head = next_mail (is_gnum, 0)) != NULL)
if (head->mhnr > user.usnmr) user.usnmr = head->mhnr;
close_mail ();
close (userfile);
userfile = open ("users", 3);
user_rec = lseek (userfile, 0L, 2);
write (userfile, &user, sizeof (user));
close (userfile);
userfile = open ("users", 1);
}
close (userfile);
if (user.usopt & ISPNG)
exit (0); /* persona non grata */
sprintf (downname, "%s/down", FWDIR);
if (!(user.usopt & ISSUPER) && (downfile = open (downname, 1)) > 0)
{
char line[99];
int len;
while ((len = readln (downfile, line, 99)) > 0)
writeln (0, line, len);
close (downfile);
exit (0);
}
if (user.usopt & ISSTUPID) {
printf ("You have not set the MYCALL parameter on your TNC\n");
printf ("Please read the manual for your TNC and set MYCALL to your\n");
printf ("callsign and try your connect again.\n");
exit (0);
}
if (strcmp (argv[2], FWDPORT) == 0)
fwdport++;
user_nmr = user.usnmr;
read_dist_list ();
if (user.usopt & ISBBS) {
printf ("%s\n", SID);
printbanner (date, time, day);
}
else {
strcpy (line, user.usname);
upper (line);
if (strcmp (line, "DOC") == 0 && (time & 3) == 1)
printf ("What's up, %s? %d\n", user.usname);
else
printf ("Hello %s.\n", user.usname);
printbanner (date, time, day);
if (strcmp (user.usname, "new user") == 0)
printf ("(Remember to use the 'N' command to enter your name.)\n");
if ((i = open ("motd", 1)) >= 0) {
int comp;
_gs_gfd (i, &buffer, sizeof (buffer));
if ((comp = buffer.fd_date[0] - (user.usdate >> 16) % 100) == 0)
if ((comp = buffer.fd_date[1] - ((user.usdate >> 8) & 0xff)) == 0)
if ((comp = buffer.fd_date[2] - (user.usdate & 0xff)) == 0)
if ((comp = buffer.fd_date[3] - ((user.ustime >> 16) & 0xff)) == 0)
comp = buffer.fd_date[4] - ((user.ustime >> 8) & 0xff);
if (comp >= 0)
while ((len = readln (i, line, sizeof (line))) > 0)
writeln (1, line, len);
close (i);
}
open_mail ();
while ((head = next_mail (is_type, 'T')) != NULL &&
traffic_count < MAXTFC) {
for (i = 0; i < traffic_count; i++)
if (strcmp (head->mhto, traffic[i].whoto) == 0)
break;
if (i == traffic_count) {
strcpy (traffic[traffic_count].whoto, head->mhto);
traffic[traffic_count++].count = 1;
}
else
traffic[i].count++;
}
if (traffic_count) {
printf ("QTC");
for (i = 0; i < traffic_count; i++)
printf (" %d %s", traffic[i].count, traffic[i].whoto);
printf ("\n");
}
reset_mail ();
while ((head = next_mail (is_mail, user.uscall)) != NULL) {
if (flag) printf ("You have mail:\n");
print_header (head, 1, flag);
flag = 0;
}
close_mail ();
}
user.usssid = ssid;
user.uscnt++;
user.uspath[0] = '\0';
if (argc < 3)
strcat (user.uspath, getenv ("PORT"));
else
for (i = 2; i < argc; i++) {
strcat (user.uspath, argv[i]);
strcat (user.uspath, " ");
}
log ("c -%d %s", user.usssid, user.uspath);
}
printbanner (date, time, day)
{
printf ("%s %s %d/%d/%d %02d:%02d:%02d\n",
banner,
days[day],
(date >> 8) & 0xff,
date & 0xff,
(date >> 16) % 100,
(time >> 16) & 0xff,
(time >> 8) & 0xff,
time & 0xff);
}
logout (argc, argv)
char *argv[];
{
int date, time, tick;
short day;
int userfile, flag;
_sysdate (0, &time, &date, &day, &tick);
if (argc >= 2 || getenv ("CALL")) {
user.usnmr = user_nmr;
user.usdate = connect_date;
user.ustime = connect_time;
userfile = open ("users", 3);
lseek (userfile, user_rec, 0);
write (userfile, &user, sizeof (user));
close (userfile);
}
if (!quit && !(user.usopt & ISBBS) &&
strcmp (user.usname, noname) != 0) {
printf ("Good ");
if ((time >> 16) < 12)
printf ("morning");
else if ((time >> 16) < 17)
printf ("afternoon");
else
printf ("evening");
printf (" %s.\n", user.usname);
}
if (strcmp (user.uscall, "SYSOP") != 0)
log ("d");
close_mail ();
exit (0);
}
download ()
{
char *p, path[80];
int f, len;
#ifdef BBSONLY
if (fwdport && !(user.usopt & ISSUPER))
{
printf ("No downloading allowed on forwarding port.\n");
return; /* Can't download files on fwd port */
}
#endif
p = line;
strcpy (path, filedir);
p += scanword (p, path+6, 80 - 6);
p += scanword (p, path+6, 80 - 6);
if (path[6] == '\0') {
printf ("File to download:\n");
getline ();
if (quit) return;
scanword (line, path+6, 80 - 6);
}
if (path[6] == '\0') return;
if (findstr (1, path, "/.")) {
return;
}
if (!printfile (path)) {
if (errno == 214)
printf ("That's a directory, not a file.\n");
else if (errno == 216)
printf ("No such file\n");
else
printf ("Error %d while trying to open %s\n", errno, path+6);
return;
}
else {
write (1, "\032", 1);
log ("D %s", path);
}
}
upload ()
{
char *p, path[80];
int i, f, len;
FILE *owners;
p = line;
strcpy (path, filedir);
i = strlen (path);
p += scanword (p, path + i, 80 - i);
p += scanword (p, path + i, 80 - i);
if (path[i] == '\0') {
printf ("File to upload:\n");
getline ();
if (quit) return;
scanword (line, path + i, 80 - i);
}
if (path[i] == '\0') return;
if (findstr (1, path, "/.")) {
return;
}
lower (path + i);
if ((f = create (path, 2, 3)) == -1) {
printf ("Error creating file. Upload aborted.\n");
return;
}
printf ("Send the file, ^Z to end.\n");
getfile (f, 0, NULL);
close (f);
if (quit || interrupt) {
unlink (path);
return;
}
if (owners = fopen (ownerfile, "a")) {
fprintf (owners, "%s %s\n", user.uscall, path+i);
fclose (owners);
}
log ("U %s", path+i);
}
zap ()
{
char *p, path[80];
int i, j, f, len;
FILE *owners;
p = line;
strcpy (path, filedir);
i = strlen (path);
p += scanword (p, path + i, 80 - i);
p += scanword (p, path + i, 80 - i);
if (path[i] == '\0') {
printf ("File to erase:\n");
getline ();
if (quit) return;
p = line + scanword (line, path + i, 80 - i);
}
if (path[i] == '\0') return;
if (findstr (1, path, "/.")) {
return;
}
lower (path + i);
if (access (path, 0) == -1) {
printf ("No such file.\n");
return;
}
if ((j = isowner (path + i, user.uscall)) != -1) {
if (unlink (path) == -1) {
printf ("Error %d during delete\n", errno);
return;
}
if (owners = fopen (ownerfile, "r+")) {
fseek (owners, (long)j, 0);
putc ('*', owners);
fclose (owners);
}
else
printf ("Error %d opening ownerfile.\n", errno);
log ("Z %s", path+i);
}
else
printf ("Sorry, that file doesn't belong to you.\n");
}
rename ()
{
char *p, path[80], path2[29];
int i, j, f, len;
FILE *owners;
p = line;
strcpy (path, filedir);
i = strlen (path);
p += scanword (p, path + i, 80 - i);
p += scanword (p, path + i, 80 - i);
if (path[i] == '\0') {
printf ("File to rename:\n");
getline ();
if (quit) return;
p = line + scanword (line, path + i, 80 - i);
}
if (path[i] == '\0') return;
if (findstr (1, path, "/.")) {
return;
}
lower (path + i);
if (access (path, 0) == -1) {
printf ("No such file.\n");
return;
}
if ((j = isowner (path + i, user.uscall)) != -1) {
p += scanword (p, path2, 29);
if (path2[0] == '\0') {
printf ("New name:\n");
getline ();
if (quit) return;
scanword (line, path2, 29);
}
if (path2[0] == '\0') return;
lower (path2);
if (rename_file (path, path2) == -1) return;
if (j != -2 && (owners = fopen (ownerfile, "r+"))) {
fseek (owners, (long)j, 0);
putc ('*', owners);
for (p = path + strlen (path); *p != '/'; p--)
;
strcpy (p+1, path2);
fseek (owners, 0L, 2);
fprintf (owners, "%s %s\n", user.uscall, path + strlen (filedir));
fclose (owners);
}
log ("V %s %s", path+i, path2);
}
else
printf ("Sorry, that file doesn't belong to you.\n");
}
isowner (path, call)
char *path, *call;
{
int owners;
char _call[7], _path[80];
char str[90], *p;
int len;
long pos;
if ((owners = open (ownerfile, 1)) == -1)
return ((user.usopt & ISSUPER) ? -2 : -1);
pos = lseek (owners, 0L, 1);
while (len = readln (owners, str, 90)) {
str[len-1] = '\0';
p = str + scanword (str, _call, 7);
p += scanword (p, _path, 80);
if (*_call != '*' && strcmp (path, _path) == 0) {
close (owners);
return ((user.usopt & ISSUPER) || strcmp (call, _call) == 0) ?
pos : -1;
}
pos = lseek (owners, 0L, 1);
}
close (owners);
return ((user.usopt & ISSUPER) ? -2 : -1);
}
name ()
{
char *p, str[80];
p = line;
p += scanword (p, str, 80);
p += scanword (p, str, 80);
if (str[0] == '\0') {
printf ("Enter your name (12 chars max):\n");
getline ();
if (quit) return;
scanword (line, str, 80);
}
if (*str == '\0') return;
strncpy (user.usname, str, 13);
sprintf (str, "register %s %s", user.uscall, user.usname);
system (str);
}
what ()
{
char *p, str[80], str2[90];
p = line;
p += scanword (p, str, 80);
strcpy (str2, "dir -d ");
if (toupper (str[1]) == 'X')
strcat (str2, "-e ");
else if (toupper (str[1]) == 'N') {
whatsnew ();
return;
}
strcpy (str, filedir);
p += scanword (p, str+6, 80 - 6);
if (str[6] == '\0')
str[5] = '\0';
if (findstr (1, str, "/.")) {
return;
}
strcat (str2, str);
system (str2);
}
whatsnew ()
{
char *p, str[80], str2[90];
int year, month, day, hour, min;
p = line;
p += scanword (p, str, 80);
p += scanword (p, str, 80);
year = (user.usdate >> 16) % 100;
month = (user.usdate >> 8) & 0xff;
day = user.usdate & 0xff;
hour = (user.ustime >> 16) & 0xff;
min = (user.ustime >> 8) & 0xff;
if (*str) {
hour = min = 0;
sscanf (str, "%d/%d/%d", &month, &day, &year);
}
sprintf (str2, "latest FILES %d/%d/%d %d:%d", month, day, year, hour, min);
system (str2);
}
send ()
{
char *p, w[40], w2[40];
struct msg_header *head;
int date, time, tick;
short day;
int f, n;
int fromflag = 0, makebid = 0, repeat = 0;
char type, to[40], from[7], bbs[39], bid[13], title[90];
p = line;
p += scanword (p, w, 40);
strcpy (from, user.uscall);
to[0] = '\0';
bbs[0] = '\0';
bid[0] = '\0';
title[0] = '\0';
type = (isalpha (w[1])) ? toupper (w[1]) : ' ';
if (type == 'R') {
int n, len;
char str[256], out[256], *p2;
type = 'P';
p += scanword (p, w, 40);
while (!*w) {
if (last_read >= 0)
printf ("Message number to reply to [%d]:\n", last_read);
else
printf ("Message number to reply to:\n");
getline ();
if (quit) return;
scanword (line, w, 40);
if (!*w && last_read >= 0)
sprintf (w, "%d", last_read);
}
n = atoi (w);
open_mail ();
if ((head = next_mail (is_num, n)) == NULL) {
printf ("Can't find message number %s\n", w);
close_mail ();
return;
}
strcpy (to, head->mhfrom);
sprintf (title, "Re: %s", head->mhtit);
f = open_msg (head);
while (len = readln (f, str, 256)) {
str[len-1] = '\0';
if (parse_head (str, out) < 2 || *out != 'R')
break; /* not a header */
for (p2 = out; *p2; p2 += strlen (p2) + 1)
if (*p2 == '@') {
scanword (p2+1, bbs, sizeof (bbs));
get_ssid (bbs);
upper (bbs);
}
}
close (f);
close_mail ();
printf ("Enter new title, or <CR> for `Re:' the same title:\n");
getline ();
if (quit) return;
if (*line)
strncpy (title, line, 81);
}
else {
p += scanword (p, w, 40);
if (! *w) {
printf ("Enter callsign of addressee:\n");
getline ();
if (quit)
return;
p = line + scanword (line, w, 40);
}
if (! *w)
return; /* no addressee */
upper (w);
get_ssid (w);
strcpy (to, w);
}
p += scanword (p, w, 40);
again:
if (*w) {
if (*w == '@') {
p += scanword (p, w, 40);
if (*w) {
upper (w);
get_ssid (w);
strncpy (bbs, w, 39);
p += scanword (p, w, 40);
goto again;
}
}
else if (*w == '<') {
p += scanword (p, w, 40);
if (*w) {
upper (w);
get_ssid (w);
if ((user.usopt & ISBBS) || (user.usopt & ISSUPER))
strncpy (from, w, 7);
p += scanword (p, w, 40);
fromflag++;
goto again;
}
}
else if (*w == '$') {
if (strlen (w) == 1) {
p += scanword (p, w, 40);
if (!*w)
makebid++;
}
else
strcpy (w, w+1);
if (*w) {
upper (w);
strncpy (bid, w, 13);
p += scanword (p, w, 40);
goto again;
}
}
}
if (p = strchr (to, '@'))
{
*p = '\0';
strncpy (bbs, p+1, 39);
}
if (type == 'T') {
bid[0] = '\0';
makebid = 0;
}
open_mail ();
if (bid[0] && (head = find_bid (bid))) {
printf ("NO - duplicate BID\n");
checkoff (head, user.uscall);
close_mail ();
return;
}
#ifdef NO_WW
if (strcmp (bbs, "WW") == 0 && strcmp (to, "SALE") == 0) {
printf ("NO - don't want 'em\n");
close_mail ();
return;
}
if (strcmp (bbs, "ALLUS") == 0 && strcmp (to, "SALE") == 0) {
printf ("NO - don't want 'em\n");
close_mail ();
return;
}
#endif
if ((head = new_mail (0)) == NULL) {
printf ("WAIT - mail system is full\n");
close_mail ();
return;
}
if (strcmp (from, "SYSOP") == 0)
strcpy (from, MYCALL);
strcpy (head->mhbid, bid);
head->mhtype = type;
strcpy (head->mhfrom, from);
strncpy (head->mhto, to, 7);
strcpy (head->mhbbs, bbs);
if (head->mhtype == ' ')
if (bulletin (head))
head->mhtype = 'B';
else
head->mhtype = 'P';
update_mail ();
if (!*title) {
if (sid_bbs)
printf ("OK %d\n", head->mhnr);
else
printf ("Enter title of message:\n");
getline ();
if (quit) return;
strncpy (head->mhtit, line, 81);
}
else
strncpy (head->mhtit, title, 81);
strcpy (w, maildir);
header_to_name (head, w + strlen (maildir));
if ((f = create (w, S_IWRITE, S_IOREAD+S_IREAD+S_IWRITE)) == -1) {
printf ("Error %d creating message file %s.\n", errno, w);
close_mail ();
return;
}
if (!sid_bbs)
printf ("Enter the message, ^Z to end. It will be number %d\n",
head->mhnr);
if (getfile (f, 1, &repeat))
write (f, "\n", 1);
head->mhsize = _gs_size (f);
close (f);
header_to_name (head, w);
if (quit || interrupt) {
head->mhbid[0] = '\0';
head->mhsize = 0;
update_mail ();
close_mail ();
return;
}
if (bulletin (head) && !(user.usopt & ISBBS))
makebid++;
if (makebid && !*head->mhbid)
sprintf (head->mhbid, "%d_%s", head->mhnr, MYCALL);
checkoff (head, user.uscall);
head->mhstat = 'N';
update_mail ();
log_send (head, fromflag);
close_mail ();
process (head);
return;
}
list ()
{
struct msg_header *head;
char *p, w1[20], w2[80];
int f;
int flag = 1;
int max_msg = 0;
int (*comp)();
int arg, arg2;
extern int xflag, eflag;
p = line + scanword (line, w1, 20);
scanword (p, w2, 20);
while (*p && isspace (*p)) p++;
upper (w1);
upper (w2);
if ((user.usopt & ISSUPER) && w1[1] == 'X') {
xflag++;
strcpy (w1+1, w1+2);
}
if ((user.usopt & ISSUPER) && w1[1] == 'E') {
eflag++;
strcpy (w1+1, w1+2);
}
switch (w1[1]) {
case '\0':
comp = is_gnum;
arg = (*w2) ? atoi (w2) : user.usnmr;
break;
case '>':
comp = is_to;
arg = (int)w2;
break;
case '<':
comp = is_from;
arg = (int)w2;
break;
case '@':
comp = is_at;
arg = (int)w2;
break;
case 'M':
comp = is_to;
arg = (int)user.uscall;
break;
case 'Y':
comp = is_read;
arg = atoi (w2);
break;
case 'F':
comp = is_forwarded;
arg = atoi (w2);
break;
case 'L':
comp = is_last;
if ((arg = atoi (w2)) == 0) return;
break;
case 'H':
comp = is_hold;
arg = (*w2) ? atoi (w2) : user.usnmr;
break;
case 'T':
comp = is_type;
arg = w1[1];
arg2 = (*w2) ? atoi (w2) : 0;
break;
case 'S':
w2[0] = '*';
strcpy (w2+1, p);
strcat (w2, "*");
comp = is_title;
arg = (int)w2;
break;
default:
comp = is_type;
arg = w1[1];
arg2 = (*w2) ? atoi (w2) : user.usnmr;
break;
}
open_mail ();
interrupt = 0;
while ((head = next_mail (comp, arg, arg2)) != NULL && !interrupt) {
print_header (head, 1, flag);
flag = 0;
if (head->mhnr > max_msg) max_msg = head->mhnr;
}
close_mail ();
if (interrupt)
printf ("\n\007Listing interrupted\n");
interrupt = 0;
if (!w1[1] && !w2[0])
user_nmr = max (user_nmr, max_msg + 1);
if (flag)
printf ("*** Not found\n");
}
readmsg ()
{
struct msg_header *head;
char *p, w1[20], w2[20];
char name[40], newname[40];
int f;
int flag = 1;
int (*comp)(), arg, list[MAXLIST];
int i, len;
int with_headers;
p = line + scanword (line, w1, 20);
if (toupper (w1[1]) == 'H') {
with_headers = 1;
strcpy (w1+1, w1+2);
}
else
with_headers = 0;
p += scanword (p, w2, 20);
if (!*w2 && toupper (w1[1]) != 'M') {
printf ("Message to read:\n");
getline ();
if (quit) return;
scanword (line, w2, 20);
}
if (toupper (w1[1]) == 'M') {
comp = is_to;
arg = (int) user.uscall;
}
else if (isdigit (*w2)) {
comp = is_multnum;
arg = (int)list;
for (i = 0; i < MAXLIST - 1 && isdigit (*w2); i++) {
list[i] = atoi (w2);
p += scanword (p, w2, 20);
}
list[i] = -1;
}
else return;
open_mail ();
while ((head = next_mail (comp, arg)) != NULL) {
#ifdef BBSONLY
if (bulletin (head) && fwdport && !(user.usopt & ISSUPER))
{
printf ("Can't read #%d: No bulletins on forwarding port.\n", head->mhnr);
continue; /* Can't read bulletins on fwd port */
}
#endif
f = open_msg (head);
print_header (head, 1, 1);
if (with_headers)
printpath (f);
else
printmsg (f);
close (f);
last_read = head->mhnr;
if (strcmp (head->mhto, user.uscall) == 0 &&
strcmp (user.uscall, "SYSOP") != 0 && head->mhstat == 'N') {
head->mhstat = 'Y';
update_mail ();
}
flag = 0;
}
close_mail ();
if (flag)
printf ("*** Not found\n");
}
killmsg ()
{
struct msg_header *head;
char *p, w1[20], w2[20];
char name[40], newname[40];
int f;
int flag = 1;
int tflag = 0;
int (*comp)(), arg, list[MAXLIST];
int i;
p = line + scanword (line, w1, 20);
p += scanword (p, w2, 20);
if (!*w2 && toupper (w1[1]) != 'M') {
printf ("Message to kill:\n");
getline ();
if (quit) return;
scanword (line, w2, 20);
}
if (toupper (w1[1]) == 'M') {
comp = is_nmail;
arg = (int) user.uscall;
}
else if (toupper (w1[1]) == 'F')
comp = is_forwarded;
else if (toupper (w1[1]) == 'T' && isdigit (*w2)) {
comp = is_num;
arg = atoi (w2);
tflag++;
}
else if (isdigit (*w2)) {
comp = is_multnum;
arg = (int)list;
for (i = 0; i < MAXLIST - 1 && isdigit (*w2); i++) {
list[i] = atoi (w2);
p += scanword (p, w2, 20);
}
list[i] = -1;
}
else return;
open_mail ();
while ((head = next_mail (comp, arg)) != NULL) {
if (strcmp (user.uscall, head->mhfrom) != 0 &&
strcmp (user.uscall, head->mhto) != 0 &&
!(tflag && head->mhtype == 'T') &&
!(user.usopt & ISSUPER)) continue;
header_to_name (head, name);
head->mhstat = 'X';
update_mail ();
if (tflag)
log ("KT %d", head->mhnr);
else
log ("K %d", head->mhnr);
printf ("*** Message #%d killed.\n", head->mhnr);
flag = 0;
}
close_mail ();
if (flag)
printf ("*** Not found\n");
}
query ()
{
char call[30], *p;
p = line;
p += scanword (p, call, 30);
p += scanword (p, call, 30);
if (!*call) {
printf ("Callsign to search for:\n");
getline ();
if (quit) return;
scanword (line, call, 30);
}
if (!*call) return;
sprintf (line, "query %s", call);
system (line);
}
copy ()
{
char *p, w[40];
struct msg_header *head, newhead;
int f1, f2, len;
int fromflag = 0;
int makebid = 0;
open_mail ();
p = line;
p += scanword (p, w, 40);
newhead.mhtype = (isalpha (w[1])) ? toupper (w[1]) : ' ';
newhead.mhstat = 'N';
newhead.mhbbs[0] = '\0';
strcpy (newhead.mhfrom, user.uscall);
p += scanword (p, w, 40);
if (!w[0]) {
printf ("Message number:\n");
getline ();
if (quit) return;
p += scanword (line, w, 40);
}
if (!isdigit (*w))
return;
reset_mail (0);
if ((head = next_mail (is_num, atoi (w))) != NULL) {
p += scanword (p, w, 40);
if (! *w) {
printf ("Enter callsign of addressee:\n");
getline ();
if (quit) return;
p = line + scanword (line, w, 40);
}
if (! *w)
return; /* no addressee */
upper (w);
strncpy (newhead.mhto, w, 7);
p += scanword (p, w, 40);
again:
if (*w) {
if (*w == '@') {
p += scanword (p, w, 40);
if (*w) {
upper (w);
strncpy (newhead.mhbbs, w, 39);
p += scanword (p, w, 40);
goto again;
}
}
else if (*w == '<') {
p += scanword (p, w, 40);
if (*w) {
upper (w);
if ((user.usopt & ISBBS) || (user.usopt & ISSUPER))
strncpy (newhead.mhfrom, w, 7);
p += scanword (p, w, 40);
fromflag++;
goto again;
}
}
else if (*w == '$') {
if (strlen (w) == 1) {
p += scanword (p, w, 40);
if (!*w)
makebid++;
}
else
strcpy (w, w+1);
if (*w) {
upper (w);
strncpy (head->mhbid, w, 13);
p += scanword (p, w, 40);
goto again;
}
}
}
if (strcmp (newhead.mhfrom, "SYSOP") == 0)
strcpy (newhead.mhfrom, MYCALL);
get_ssid (newhead.mhto);
get_ssid (newhead.mhbbs);
header_to_name (head, w + strlen (maildir));
if ((f1 = open_msg (head)) == -1) {
printf ("Error %d opening message file\n", errno);
return;
}
printf ("Enter new title, or <CR> for same as original:\n");
getline ();
if (quit) return;
if (*line)
strncpy (newhead.mhtit, line, 81);
else
strcpy (newhead.mhtit, head->mhtit);
newhead.mhsize = head->mhsize;
if ((f2 = creat_msg (&newhead, &head)) == -1) {
printf ("Error %d creating message file\n", errno);
return;
}
while ((len = readln (f1, line, 256)) > 0)
writeln (f2, line, len);
close (f1);
close (f2);
if (makebid && !*head->mhbid)
sprintf (head->mhbid, "%d_%s", head->mhnr, MYCALL);
update_mail ();
close_mail ();
log_send (head, fromflag);
printf ("Your copy is now message #%d\n", head->mhnr);
}
else
printf ("*** Not found\n");
}
modify ()
{
char *p, *p2, w[81], w2[81];
struct msg_header *head, newhead;
int f1, f2, len, num;
int fromflag = 0;
extern int eflag;
int i, list[MAXLIST];
p = line;
p += scanword (p, w, 40);
p += scanword (p, w, 40);
if (!*w) {
printf ("Message to modify:\n");
getline ();
if (quit) return;
scanword (line, w, 40);
}
else if (isdigit (*w)) {
for (i = 0; i < MAXLIST - 1 && isdigit (*w); i++) {
list[i] = atoi (w);
p += scanword (p, w, 20);
}
list[i] = -1;
}
open_mail ();
while (head = next_mail (is_multnum, list)) {
if (!(user.usopt & ISSUPER) && strcmp (user.uscall, head->mhfrom) != 0 &&
(head->mhtype != 'T')) {
printf ("Sorry, can only modify messages you've sent.\n");
close_mail ();
return;
}
if (!(user.usopt & ISEXPERT)) {
printf ("Modify commands are:\n");
printf (
" T - type > - to @ - BBS L - title $ - bid\n");
if (user.usopt & ISSUPER)
printf (
" < - from S - size D - distribution X- expiration\n");
}
eflag = 1;
while (1) {
print_header (head, 1, 1);
printf ("\nModify: >\n");
getline ();
if (quit) {
close_mail ();
return;
}
p = line;
p += scanword (p, w, 81);
if (!*w) break;
if (strlen (w) > 1) {
strcpy (w2, w+1);
w[1] = '\0';
}
else
scanword (p, w2, 81);
switch (toupper (*w)) {
case 'T':
if (!(user.usopt & ISSUPER) &&
strcmp (user.uscall, head->mhfrom) != 0)
break;
if (!*w2)
head->mhtype = ' ';
else
head->mhtype = toupper (*w2);
log ("M %d T %c", head->mhnr, *w2);
break;
case 'R':
if (!(user.usopt & ISSUPER))
break;
if (!*w2) break;
upper (w2);
head->mhstat = *w2;
log ("M %d R %c", head->mhnr, *w2);
break;
case '>':
if (*w2 || head->mhstat == 'X')
strncpy (head->mhto, w2, 7);
upper (head->mhto);
get_ssid (newhead.mhto);
log ("M %d > %s", head->mhnr, head->mhto);
break;
case '<':
if (!(user.usopt & ISSUPER)) break;
if (*w2) strncpy (head->mhfrom, w2, 39);
upper (head->mhfrom);
get_ssid (newhead.mhfrom);
log ("M %d < %s", head->mhnr, head->mhfrom);
break;
case '@':
strncpy (head->mhbbs, w2, 39);
upper (head->mhbbs);
log ("M %d @ %s", head->mhnr, head->mhbbs);
break;
case 'L':
while (isspace (*p)) p++;
strncpy (head->mhtit, p, 81);
log ("M %d L %s", head->mhnr, head->mhtit);
break;
case 'S':
if (!(user.usopt & ISSUPER)) break;
len = (*w2) ? atoi (w2) : -1;
if (len >= 0)
head->mhsize = len;
log ("M %d S %d", head->mhnr, head->mhsize);
break;
case '$':
strncpy (head->mhbid, w2, 13);
upper (head->mhbid);
log ("M %d $ %s", head->mhnr, head->mhbid);
break;
case 'D':
if (!(user.usopt & ISSUPER)) break;
if (*w2) update_dist (head, xtoi (w2));
log ("M %d D %s", head->mhnr, w2);
break;
case 'X':
if (!(user.usopt & ISSUPER)) break;
if (*w2) {
int y,m,d;
if (sscanf (w2, "%d/%d/%d", &m, &d, &y) == 3)
if (y > 50)
head->mhdate_xpir = ((1900+y) << 16) + (m << 8) + d;
else
head->mhdate_xpir = ((2000+y) << 16) + (m << 8) + d;
else
head->mhdate_xpir = 0;
log ("M %d X %s", head->mhnr, w2);
}
break;
}
update_mail ();
}
}
eflag = 0;
close_mail ();
}
help ()
{
char *p, w[20];
p = line;
p += scanword (p, w, 20);
p += scanword (p, w, 20);
printf ("\n");
switch (toupper (*w)) {
case '\0':
if (!printfile ("help/general")) goto nohelp;
break;
case 'D':
if (!printfile ("help/download")) goto nohelp;
break;
case 'W':
if (!printfile ("help/what")) goto nohelp;
break;
case 'B':
if (!printfile ("help/bye")) goto nohelp;
break;
case 'I':
if (!printfile ("help/info")) goto nohelp;
break;
case 'N':
if (!printfile ("help/name")) goto nohelp;
break;
case 'X':
if (!printfile ("help/expert")) goto nohelp;
break;
case 'U':
if (!printfile ("help/upload")) goto nohelp;
break;
case 'S':
if (!printfile ("help/send")) goto nohelp;
break;
case 'L':
if (!printfile ("help/list")) goto nohelp;
break;
case 'R':
if (!printfile ("help/read")) goto nohelp;
break;
case 'K':
if (!printfile ("help/kill")) goto nohelp;
break;
case 'E':
if (!printfile ("help/execute")) goto nohelp;
break;
case 'Z':
if (!printfile ("help/zap")) goto nohelp;
break;
case 'V':
if (!printfile ("help/rename")) goto nohelp;
break;
case 'Q':
if (!printfile ("help/query")) goto nohelp;
break;
case 'C':
if (!printfile ("help/copy")) goto nohelp;
break;
case 'M':
if (!printfile ("help/modify")) goto nohelp;
break;
default:
nohelp:
printf ("Sorry, no help on that command.\n");
break;
}
printf ("\n");
}
printfile (path)
char *path;
{
int f;
if ((f = open (path, 1)) <= 0)
return 0;
printpath (f);
close (f);
return (1);
}
printpath (f)
{
int len;
interrupt = 0;
while ((len = readln (f, line, sizeof (line))) > 0 && !interrupt)
writeln (1, line, len);
if (interrupt)
printf ("\n\007File interrupted\n");
interrupt = 0;
}
printmsg (f)
{
int len = 0;
char out[256], oldline[256];
interrupt = 0;
oldline[0] = line[0] = '\0';
do {
if (len > 1) strcpy (oldline, line);
len = readln (f, line, sizeof (line));
*(line+len) = '\0';
}
while (len > 0 && (line[0] == '\n' || parse_head (line, out) > 1 && *out == 'R'));
if (len <= 0) return;
if (*oldline) writeln (1, oldline, strlen (oldline));
writeln (1, "\n", 1);
writeln (1, line, len);
while ((len = readln (f, line, sizeof (line))) > 0 && !interrupt)
writeln (1, line, len);
if (interrupt)
printf ("\n\007File interrupted\n");
interrupt = 0;
}
getfile (f, message, repeat)
int *repeat;
{
int len, alarm;
char *p, *p2, header[200];
alarm = alm_set (SIGQUIT, ALARM);
while ((len = readln (0, line, 255)) > 0) {
alm_delete (alarm);
line[len] = '\0';
if (stricmp (line, "/ex\n") == 0)
continue;
for (p = line; p - line < len; p++)
if (*p == '\032') {
write (f, line, p-line);
goto exit;
}
if (repeat && parse_head (line, header) > 1 && *header == 'R') {
for (p = header; *p; p += strlen (p) + 1)
if (*p == '@') {
if (strncmp (p+1, MYCALL, strlen (MYCALL)) == 0)
(*repeat)++;
}
}
write (f, line, len);
}
alm_delete (alarm);
exit:
if (quit)
printf ("*** TIMEOUT ***\n");
if (len <= 0 && !interrupt)
quit++;
return (p-line);
}
signalman (signal)
{
switch (signal) {
case SIGQUIT:
quit = 1;
break;
case SIGINT:
interrupt = 1;
break;
default:
break;
}
}
execute ()
{
char *p, w[29];
p = line + scanword (line, w, 29);
p += scanword (p, w, 29);
if (*w == '\0') {
system ("dir PROGRAMS");
printf ("\nProgram to execute:\n");
getline ();
if (quit) return;
scanword (line, w, 29);
}
if (*w == '\0') return;
for (p = w; *p; p++)
if (*p == '!' || *p == '&' || *p == '^' || *p == ';') return;
sprintf (line, "/dd/MAILBOX/PROGRAMS/%s %s", w, user.uscall);
if (system (line) == -1)
printf ("Sorry, can't execute that program\n");
else
log ("E %s", w);
}
process (head)
struct msg_header *head;
{
static char w[10];
static char *argv[8];
int argc = 0;
char *bflag = "-b";
char *sflag = "-s";
char *qflag = "-q";
extern char **environ;
extern int os9fork();
if (msg_proc)
wait (msg_proc);
argv[argc++] = "msgproc";
argv[argc++] = qflag;
if (user.usopt & ISBBS) argv[argc++] = bflag;
if (user.usopt & ISSUPER) argv[argc++] = sflag;
sprintf (w, "%d", head->mhnr);
argv[argc++] = w;
argv[argc++] = NULL;
msg_proc = os9exec (os9fork, argv[0], argv, environ, 0, 50, 3);
}
sysop ()
{
char *p, w[20];
unsigned char str[6];
int accum = -1;
p = line + scanword (line, w, 20);
scanword (p, w, 20);
if (*w == '\0') {
log ("@ x");
return 0;
}
str[0] = (connect_date >> 8) & 0xff;
str[1] = connect_date & 0xff;
str[2] = (connect_date >> 16) % 100;
str[3] = (connect_time >> 16) & 0xff;
str[4] = (connect_time >> 8) & 0xff;
str[5] = connect_time & 0xff;
crc (str, 6, &accum);
if (atoi (w) != (accum & 0xffffff)) {
log ("@ %d", atoi (w));
return 0;
}
log ("@");
system ("");
return (1);
}
reverse ()
{
char w[40];
int flag = 0;
if (!user.usopt & ISBBS || !sid_bbs)
return 0;
scanword (line, w, 20);
if (strcmp (w, "F>") != 0)
return 0;
sprintf (w, "reverse %s %d %d %d\n", user.uscall, mid_flag, bid_flag, hflag);
system (w);
return (1);
}
sid ()
{
char *f1, *f2, *f3, *f4, *p;
if (!user.usopt & ISBBS) return 0;
if ((f1 = strchr (line, '[')) == line && (f2 = strrchr (f1, ']')) &&
(f3 = strchr (f1, '-')) && f3 < f2 && (f4 = strrchr (f1, '-')) &&
f4 > f3) {
sid_bbs = 1;
for (p = f4 + 1; p < f2; p++)
switch (*p) {
case '$': bid_flag++; break;
case 'M': mid_flag++; break;
case 'H': hflag++; break;
default: break;
}
}
else if ((f1 = strchr (line, '[')) == line && (f2 = strchr (f1, ']'))) {
*(f1+4) = '\0';
if (strcmp (f1+1, "MBL" == 0))
sid_bbs = bid_flag = 1;
}
return sid_bbs;
}
getline ()
{
int alarm;
interrupt = 0;
alarm = alm_set (SIGQUIT, ALARM);
while (fgets (line, 256, stdin) == 0) {
if (quit || feof (stdin)) {
clearerr (stdin);
cleareof (stdin);
if (quit)
printf ("*** TIMEOUT ***\n");
if (interrupt)
interrupt = 0;
else
quit = 1;
*line = '\0';
alm_delete (alarm);
return;
}
clearerr (stdin);
}
line[strlen (line) - 1] = '\0';
alm_delete (alarm);
}
lower (s)
char *s;
{
while (*s) {
*s = tolower (*s);
s++;
}
}
max (a, b)
{
return ((a > b) ? a : b);
}
link (argc, argv)
char *argv[];
{
static char w[40];
char *p;
p = line;
p += scanword (p, w, 40);
if (strcmp (w, "***") != 0) return;
p += scanword (p, w, 40);
if (strcmp (w, "LINKED") != 0) return;
p += scanword (p, w, 40);
if (strcmp (w, "to") != 0) return;
p += scanword (p, w, 40);
log ("* %s", w);
printf ("You don't fool me!\n");
argv[1] = w;
login (argc, argv);
}
xtoi (str)
char *str;
{
int i;
sscanf (str, "%x", &i);
return (i);
}