home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
fido
/
maildmn.arc
/
MAILDMN.C
next >
Wrap
C/C++ Source or Header
|
1987-12-16
|
11KB
|
457 lines
/*
maildmn -- a program for implementing FIDO gateways
mail addressee: body requirements: notify:
Telex ### (ans) ... Username
Telegram name, address, BT,... Username
Internet addressee .... Username
Dialcom id .... Username
Purolater deliverType name, adress, etc, ... Username
Usage: maildmn [-uUserfile] [-aAliasfile] [<daemon-name>]
Synopsis: maildmn will search current directory for all files
that match *.MSG. These it assumes are FIDO(tm) message files.
These message files are then tested for addressee. If the
addressee is the name of a gateway (unimplemented here), then
gateway processing occurs and no further checking is done. Then the
address is checked in a linked list of aliases. The alias data
file is an ASCII text file called (default) \fido\ALIASES.BBS.
It takes the following form:
"<realname>" [=] "<nickname>" {[ , "<nickname>" ]}
Example:
"Sysop" = "Bill", "Bill Smith"
"All" = "Everyone", "All Users", "Users", "People", "Friends"
Capitalization is important in this file, it is NOT done by this
program for you so you must get it right. Many, if not all FIDO
systems capitalize for you on message entry.
If the name is found as a nickname, then the realname is substituted
and the message re-written on the disk. An earlier version of this
program rewrote the message incorrectly for fido, by not setting the
file length to precisely the length of the header and the message
body. It appears that some FIDO versions insist that the file length
be precise. The message must not include any trailing \0 characters
or the FIDO gives up! Lest you think that I'm blaiming FIDO for the
inadequacies of my previous action, please note that there was a
fairly severe lack of understanding of CRLF translation or lack thereof
in returned messages. This is now corrected.
Bear in mind that the aliasing system works independantly and prior
to the userfile check. So if you alias: "Jim" = "Mary" and then,
later, rename "Jim" to "Mary" in the userfile, mail addressed to
Mary will first be re-addressed to Jim and then returned to sender!
Keep the alias file up-to-date!
etc: Please note that FIDO is a trademark of FIDO software, in,
I believe, California, USA. This program is free - quite free. Also
I'm not guaranteeing the bug-freedness of this thing. (That's why
it's free).
*/
#include <stdio.h>
#include <dos.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <malloc.h>
struct _usr {
char name[36];
char city[36];
int date[20];
char pwd[16];
int times;
int help;
int tabs;
int nulls;
int msg;
int more;
int priv;
char ldate[20];
int time;
unsigned flag;
unsigned upld;
unsigned dnld;
unsigned dnldl;
int files;
char width;
char len;
int credit;
int debit;
} usr;
struct _msg
{
char from[36];
char to[36];
char subj[72];
char date[20];
int times;
int dest;
int orig;
int cost;
int caca[6];
unsigned reply;
int attr;
int up;
char content[4096];
} msg;
struct alias_t {
char nickname[36];
char realname[36];
struct alias_t *above;
struct alias_t *below;
};
#define USERFILEDEFAULT "\\fido\\USER.BBS"
#define ALIASFILEDEFAULT "\\fido\\ALIASES.BBS"
#define DAEMONNAMEDEFAULT "Mailer Daemon"
#define EVERYONE "All"
#define TELEXBILLS "Sysop"
#define TELEGRAMBILLS "Sysop"
#define INTERNETBILLS "Sysop"
#define DIALCOMBILLS "Sysop"
#define PUROLATERBILLS "Sysop"
#define MAXLINELENGTH 1024
char retmsghdr1[]="Addressee \"";
char retmsghdr2[]="\" not known!\r\nPlease re-enter mail but CHECK the "
"usernames with the U option on the main menu\r\n"
"******* Message returned as follows:\r\n";
char msgbuffer[4091];
char userfile[127];
char mailfile[12];
char aliasfile[127];
char badname[36];
char me[127];
struct alias_t *aliases;
struct find_t ft;
void main(int, char*[]);
void telex(char *);
void telegram(char *);
void purolater(char *);
void internet(char *);
void dialcom(char *);
char *strskip(char *, char *);
struct alias_t *buildaliases(FILE *);
void checkaliases(struct alias_t *);
void returnmail(char *,char *,char *);
int pickoutname(char **,char **);
void main(argc, argv)
int argc;
char *argv[];
{
int i;
char *c, *cme;
FILE *ufp, *mfp;
strcpy(userfile,USERFILEDEFAULT);
strcpy(aliasfile,ALIASFILEDEFAULT);
strcpy(me,DAEMONNAMEDEFAULT);
cme=me;
for(i=1; i<argc; i++) {
if (*(c=argv[i])=='-') {
c++;
switch (tolower(*c)) {
case 'u' : strcpy(userfile,++c);
break;
case 'a' : strcpy(aliasfile,++c);
break;
default : printf("Usage: daemon [-uUserfile] "
"[-aAliasfile] [<daemon name>]"
"\n -u default: %s"
"\n -a default: %s"
"\n <name> default: %s"
"\n <name> can be multiple words"
"\n Current working directory *.MSG files "
"are processed by this program."
"\n Nik Habermel, (c) copyright 1988, \n",
USERFILEDEFAULT, ALIASFILEDEFAULT,
DAEMONNAMEDEFAULT);
break;
}
}
else {
if (me!=cme) {
assert((*cme)=='\0');
*cme=' ';
*(++cme)='\0';
}
cme+=strlen(strcpy(cme,c));
}
}
me[35]='\0';
if (!(ufp=fopen(userfile,"rb"))) {
printf("Error: %s not found\n",userfile);
exit(1);
}
fclose(ufp);
if (*aliasfile) {
if (!(ufp=fopen(aliasfile,"ra"))) {
printf("Error: %s not found\n",aliasfile);
exit(1);
}
aliases=buildaliases(ufp);
fclose(ufp);
}
else aliases=NULL;
_dos_findfirst("*.MSG",(unsigned) 0, &ft);
while (errno!=ENOENT) {
mfp=fopen(ft.name,"rb");
fread((void *)&msg,sizeof(msg),1,mfp);
fclose(mfp);
if (!strncmp(msg.to,me,strlen(me))) {
/* addressed to mailer daemon itself */
_dos_findnext(&ft);
continue;
}
if (!strncmp(msg.to,"Telex",5)) {
/* addressed to telex */
telex(TELEXBILLS);
_dos_findnext(&ft);
continue;
}
if (!strncmp(msg.to,"Telegram",8)) {
/* addressed to telegram */
telegram(TELEGRAMBILLS);
_dos_findnext(&ft);
continue;
}
if (!strncmp(msg.to,"Internet",8)) {
/* addressed to internet */
internet(INTERNETBILLS);
_dos_findnext(&ft);
continue;
}
if (!strncmp(msg.to,"Dialcom",7)) {
/* addressed to dialcom */
dialcom(DIALCOMBILLS);
_dos_findnext(&ft);
continue;
}
if (!strncmp(msg.to,"Purolater",9)) {
/* addressed to purolater */
purolater(PUROLATERBILLS);
_dos_findnext(&ft);
continue;
}
checkaliases(aliases);
if (!strncmp(msg.to,EVERYONE,3)) {
/* addressed to all */
_dos_findnext(&ft);
continue;
}
ufp=fopen(userfile,"rb");
usr.name[0]='\0';
while ((!feof(ufp)) && (strcmp(msg.to,usr.name))) {
fread((void *)&usr,sizeof(usr),1,ufp);
}
fclose(ufp);
if (strcmp(msg.to,usr.name))
returnmail(retmsghdr1,badname,retmsghdr2);
_dos_findnext(&ft);
}
exit(0);
}
char *strskip(target,skipchars)
char *target, *skipchars;
{
char *p;
for(p=target;(*p)&&strchr(skipchars,*p);++p);
return(p);
}
struct alias_t *buildaliases(afp)
FILE *afp;
{
char *line;
char *t1, *t2, *nickname, *realname;
struct alias_t *x, *y, *z;
int i,linenumber=0;
x=y=z=NULL;
line=(char *)calloc(MAXLINELENGTH,sizeof(char));
while (!feof(afp)) {
linenumber++;
if (!fgets(t1=line,MAXLINELENGTH,afp)) break;
if (strchr(line,'\n')) *strchr(line,'\n')='\0';
if (*(t1=strskip(line," \t\b"))!='\"') {
printf("Error: Aliasfile on line %d\n"
" Cannot find opening \"\n"
" Line: %s\n",linenumber,line);
continue;
}
if (pickoutname(&t1,&t2)) {
printf("Error: Aliasfile on line d:\n"
" 2nd \" missing\n Line: %s\n",
linenumber,line);
continue;
}
strncpy(realname=(char *)(calloc(36<=t2-t1?36:(t2-t1)+1,sizeof(char))),
t1,35<=t2-t1?35:t2-t1);
t1=t2+1;
if (*(t1=strskip(t1,"\b\t ="))!='\"') {
printf("Warning: Aliasfile on line %d\n"
" Missing nickname\nLine: %s\n",
linenumber,line);
continue;
}
if (pickoutname(&t1,&t2)) {
printf("Error: Aliasfile on line %d:\n"
" 2nd \" missing\n Line: %s\n",
linenumber,line);
continue;
}
strncpy(nickname=(char *)(calloc(36,sizeof(char)))
,t1,35<=t2-t1?35:t2-t1);
t1=t2+1;
x=(struct alias_t *)(calloc(1,sizeof(*x)));
x->above=y;
if (y!=NULL) y->below=x;
x->below=NULL;
strcpy(x->realname,realname);
strcpy(x->nickname,nickname);
y=x;
if (z==NULL) z=x;
while (*(t1=strskip(t1,"\b\t ,"))) {
if (*t1!='\"') {
printf("Warning: Aliasfile on line %d\n"
" Line ends illegally\n"
"Line: %s\n",linenumber,line);
break;
}
if (pickoutname(&t1,&t2)) {
printf("Warning: Aliasfile on line %d:\n"
" Second \" missing in nickname\n"
"Line: %s\n",linenumber,line);
break;
}
for (i=0;i<36;i++) nickname[i]='\0';
strncpy(nickname,t1,35<=t2-t1?35:t2-t1);
t1=t2+1;
x=(struct alias_t *)(calloc(1,sizeof(*x)));
x->above=y;
y->below=x;
x->below=NULL;
strcpy(x->realname,realname);
strcpy(x->nickname,nickname);
y=x;
}
}
return(z);
}
void returnmail(error1, error2, error3)
char *error1, *error2, *error3;
{
FILE *fp;
printf("-mail to \"%s\" returned to sender\n",msg.to);
strcpy(badname,msg.to);
strcpy(msg.to,msg.from);
strcpy(msg.from,me);
msg.content[4095-strlen(error1)-strlen(error2)-strlen(error3)]='\0';
strcpy(msgbuffer,msg.content);
strcpy(msg.content,error1);
strcpy(msg.content+strlen(msg.content),error2);
strcpy(msg.content+strlen(msg.content),error3);
strcpy(msg.content+strlen(msg.content),msgbuffer);
if (fp=fopen(ft.name,"wb")) {
fwrite((void *)&msg,1,sizeof(msg)-4096+strlen(msg.content),fp);
fclose(fp);
}
else printf("Cannot reopen %s for write!\n",ft.name);
}
void checkaliases(alias)
struct alias_t *alias;
{
struct alias_t *x;
FILE *fp;
for(x=alias;x!=NULL;x=x->below) {
if (!strcmp(x->nickname,msg.to)) {
strcpy(msg.to,x->realname);
if (fp=fopen(ft.name,"wb")) {
fwrite((void *)&msg,1,sizeof(msg)-4096+
strlen(msg.content),fp);
fclose(fp);
}
else printf("Error: Failed to rewrite %s message to \"%s\""
" (\"%s\")\n",ft.name,msg.to,x->nickname);
x=NULL;
}
}
}
void telex(controller)
char *controller;
{
}
void telegram(controller)
char *controller;
{
}
void dialcom(controller)
char *controller;
{
}
void purolater(controller)
char *controller;
{
}
void internet(controller)
char *controller;
{
}
int pickoutname(tp1,tp2)
char **tp1, **tp2;
{
return(!(*tp2=strpbrk((*tp1=strskip(*tp1,"\"")),"\"")));
}