home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 September / Simtel20_Sept92.cdr / msdos / fido / maildmn.arc / MAILDMN.C next >
C/C++ Source or Header  |  1987-12-16  |  11KB  |  457 lines

  1. /*
  2.     maildmn -- a program for implementing FIDO gateways
  3.  
  4.         mail addressee:        body requirements:    notify:
  5.  
  6.     Telex ### (ans)        ...            Username
  7.     Telegram        name, address, BT,...    Username
  8.     Internet addressee    ....            Username
  9.     Dialcom id        ....            Username
  10.     Purolater deliverType   name, adress, etc, ...  Username
  11.  
  12.  
  13.     Usage: maildmn [-uUserfile] [-aAliasfile] [<daemon-name>]
  14.  
  15.     Synopsis: maildmn will search current directory for all files
  16.     that match *.MSG. These it assumes are FIDO(tm) message files.
  17.     These message files are then tested for addressee. If the
  18.     addressee is the name of a gateway (unimplemented here), then
  19.     gateway processing occurs and no further checking is done. Then the
  20.     address is checked in a linked list of aliases. The alias data
  21.     file is an ASCII text file called (default) \fido\ALIASES.BBS.
  22.     It takes the following form:
  23.  
  24.     "<realname>" [=] "<nickname>" {[ , "<nickname>" ]}
  25.  
  26.     Example: 
  27.     "Sysop" = "Bill", "Bill Smith"
  28.     "All"   = "Everyone", "All Users", "Users", "People", "Friends"
  29.  
  30.     Capitalization is important in this file, it is NOT done by this
  31.     program for you so you must get it right. Many, if not all FIDO
  32.     systems capitalize for you on message entry.
  33.  
  34.     If the name is found as a nickname, then the realname is substituted
  35.     and the message re-written on the disk. An earlier version of this
  36.     program rewrote the message incorrectly for fido, by not setting the
  37.     file length to precisely the length of the header and the message
  38.     body. It appears that some FIDO versions insist that the file length
  39.     be precise. The message must not include any trailing \0 characters
  40.     or the FIDO gives up! Lest you think that I'm blaiming FIDO for the
  41.     inadequacies of my previous action, please note that there was a
  42.     fairly severe lack of understanding of CRLF translation or lack thereof
  43.     in returned messages. This is now corrected.
  44.  
  45.     Bear in mind that the aliasing system works independantly and prior
  46.     to the userfile check. So if you alias: "Jim" = "Mary" and then,
  47.     later, rename "Jim" to "Mary" in the userfile, mail addressed to
  48.     Mary will first be re-addressed to Jim and then returned to sender!
  49.  
  50.     Keep the alias file up-to-date!
  51.  
  52.     etc: Please note that FIDO is a trademark of FIDO software, in,
  53.     I believe, California, USA. This program is free - quite free. Also
  54.     I'm not guaranteeing the bug-freedness of this thing. (That's why
  55.     it's free).
  56.  
  57. */
  58. #include <stdio.h>
  59. #include <dos.h>
  60. #include <string.h>
  61. #include <errno.h>
  62. #include <assert.h>
  63. #include <stddef.h>
  64. #include <stdlib.h>
  65. #include <malloc.h>
  66.  
  67. struct _usr {
  68.     char name[36];
  69.     char city[36];
  70.     int date[20];
  71.     char pwd[16];
  72.     int times;
  73.     int help;
  74.     int tabs;
  75.     int nulls;
  76.     int msg;
  77.     int more;
  78.     int priv;
  79.     char ldate[20];
  80.     int time;
  81.     unsigned flag;
  82.     unsigned upld;
  83.     unsigned dnld;
  84.     unsigned dnldl;
  85.     int files;
  86.     char width;
  87.     char len;
  88.     int credit;
  89.     int debit;
  90. } usr;
  91.  
  92.  
  93. struct _msg 
  94. {
  95.     char from[36];
  96.     char to[36];
  97.     char subj[72];
  98.     char date[20];
  99.     int times;
  100.     int dest;
  101.     int orig;
  102.     int cost;
  103.     int caca[6];
  104.     unsigned reply;
  105.     int attr;
  106.     int up;
  107.     char content[4096];
  108. } msg;
  109.  
  110. struct alias_t {
  111.    char nickname[36];
  112.    char realname[36];
  113.    struct alias_t *above;
  114.    struct alias_t *below;
  115. };
  116.  
  117. #define USERFILEDEFAULT "\\fido\\USER.BBS"
  118. #define ALIASFILEDEFAULT "\\fido\\ALIASES.BBS"
  119. #define DAEMONNAMEDEFAULT "Mailer Daemon"
  120. #define EVERYONE "All"
  121. #define TELEXBILLS "Sysop"
  122. #define TELEGRAMBILLS "Sysop"
  123. #define INTERNETBILLS "Sysop"
  124. #define DIALCOMBILLS "Sysop"
  125. #define PUROLATERBILLS "Sysop"
  126. #define MAXLINELENGTH 1024
  127.  
  128.    char retmsghdr1[]="Addressee \"";
  129.    char retmsghdr2[]="\" not known!\r\nPlease re-enter mail but CHECK the "
  130.             "usernames with the U option on the main menu\r\n"
  131.             "******* Message returned as follows:\r\n";
  132.             
  133.    char msgbuffer[4091];
  134.    char userfile[127];
  135.    char mailfile[12];
  136.    char aliasfile[127];
  137.    char badname[36];
  138.    char me[127];
  139.    struct alias_t *aliases;
  140.    struct find_t ft;
  141.  
  142. void main(int, char*[]);
  143. void telex(char *);
  144. void telegram(char *);
  145. void purolater(char *);
  146. void internet(char *);
  147. void dialcom(char *);
  148. char *strskip(char *, char *);
  149. struct alias_t *buildaliases(FILE *);
  150. void checkaliases(struct alias_t *);
  151. void returnmail(char *,char *,char *);
  152. int pickoutname(char **,char **);
  153.  
  154. void main(argc, argv)
  155. int argc;
  156. char *argv[];
  157. {
  158.    int i;
  159.    char *c, *cme;
  160.  
  161.    FILE *ufp, *mfp;
  162.  
  163.  
  164.  
  165.    strcpy(userfile,USERFILEDEFAULT);
  166.    strcpy(aliasfile,ALIASFILEDEFAULT);
  167.    strcpy(me,DAEMONNAMEDEFAULT);
  168.    cme=me;
  169.  
  170.    for(i=1; i<argc; i++) {
  171.     if (*(c=argv[i])=='-') {
  172.         c++;
  173.         switch (tolower(*c)) {
  174.         case 'u' :     strcpy(userfile,++c);
  175.                    break;
  176.         case 'a' :     strcpy(aliasfile,++c);
  177.                 break;
  178.         default  :    printf("Usage: daemon [-uUserfile] "
  179.                     "[-aAliasfile] [<daemon name>]"
  180.                 "\n       -u default: %s"
  181.                 "\n       -a default: %s"
  182.                 "\n       <name> default: %s"
  183.                 "\n       <name> can be multiple words"
  184.                 "\n Current working directory *.MSG files "
  185.                 "are processed by this program."
  186.                 "\n Nik Habermel, (c) copyright 1988, \n",
  187.                 USERFILEDEFAULT, ALIASFILEDEFAULT,
  188.                 DAEMONNAMEDEFAULT);
  189.                 break;
  190.             }
  191.         }
  192.     else {
  193.         if (me!=cme) {
  194.             assert((*cme)=='\0');
  195.             *cme=' ';
  196.             *(++cme)='\0';
  197.             }
  198.         cme+=strlen(strcpy(cme,c));
  199.         }
  200.     }
  201.    me[35]='\0';
  202.  
  203.    if (!(ufp=fopen(userfile,"rb"))) {
  204.     printf("Error: %s not found\n",userfile);
  205.     exit(1);
  206.     }
  207.    fclose(ufp);
  208.    
  209.    if (*aliasfile) {
  210.     if (!(ufp=fopen(aliasfile,"ra"))) {
  211.         printf("Error: %s not found\n",aliasfile);
  212.         exit(1);
  213.         }
  214.     aliases=buildaliases(ufp);
  215.     fclose(ufp);
  216.     }
  217.    else aliases=NULL;
  218.     
  219.  
  220.    _dos_findfirst("*.MSG",(unsigned) 0, &ft);
  221.    while (errno!=ENOENT) {
  222.     mfp=fopen(ft.name,"rb");
  223.     fread((void *)&msg,sizeof(msg),1,mfp);
  224.     fclose(mfp);
  225.  
  226.     if (!strncmp(msg.to,me,strlen(me))) {
  227.         /* addressed to mailer daemon itself */
  228.         _dos_findnext(&ft);
  229.         continue;
  230.         }
  231.     
  232.     if (!strncmp(msg.to,"Telex",5)) {
  233.         /* addressed to telex */
  234.         telex(TELEXBILLS);
  235.         _dos_findnext(&ft);
  236.         continue;
  237.         }
  238.  
  239.     if (!strncmp(msg.to,"Telegram",8)) {
  240.         /* addressed to telegram */
  241.         telegram(TELEGRAMBILLS);
  242.         _dos_findnext(&ft);
  243.         continue;
  244.         }
  245.  
  246.     if (!strncmp(msg.to,"Internet",8)) {
  247.         /* addressed to internet */
  248.         internet(INTERNETBILLS);
  249.         _dos_findnext(&ft);
  250.         continue;
  251.         }
  252.  
  253.     if (!strncmp(msg.to,"Dialcom",7)) {
  254.         /* addressed to dialcom */
  255.         dialcom(DIALCOMBILLS);
  256.         _dos_findnext(&ft);
  257.         continue;
  258.         }
  259.  
  260.     if (!strncmp(msg.to,"Purolater",9)) {
  261.         /* addressed to purolater */
  262.         purolater(PUROLATERBILLS);
  263.         _dos_findnext(&ft);
  264.         continue;
  265.         }
  266.  
  267.     checkaliases(aliases);
  268.  
  269.     if (!strncmp(msg.to,EVERYONE,3)) {
  270.         /* addressed to all */
  271.         _dos_findnext(&ft);
  272.         continue;
  273.         }
  274.  
  275.  
  276.     ufp=fopen(userfile,"rb");
  277.     usr.name[0]='\0';
  278.  
  279.     while ((!feof(ufp)) && (strcmp(msg.to,usr.name))) {
  280.         fread((void *)&usr,sizeof(usr),1,ufp);
  281.         }
  282.     fclose(ufp);
  283.     if (strcmp(msg.to,usr.name)) 
  284.         returnmail(retmsghdr1,badname,retmsghdr2);
  285.  
  286.     _dos_findnext(&ft);
  287.     }
  288.    exit(0);
  289. }
  290.  
  291. char *strskip(target,skipchars)
  292. char *target, *skipchars;
  293. {
  294.    char *p;
  295.    for(p=target;(*p)&&strchr(skipchars,*p);++p);
  296.    return(p);
  297. }
  298.  
  299.  
  300. struct alias_t *buildaliases(afp)
  301. FILE *afp;
  302. {
  303.    char *line;
  304.    char *t1, *t2, *nickname, *realname;
  305.    struct alias_t *x, *y, *z;
  306.    int i,linenumber=0;
  307.   
  308.    x=y=z=NULL;
  309.    line=(char *)calloc(MAXLINELENGTH,sizeof(char));
  310.  
  311.    while (!feof(afp)) {
  312.     linenumber++;
  313.     if (!fgets(t1=line,MAXLINELENGTH,afp)) break;
  314.     if (strchr(line,'\n')) *strchr(line,'\n')='\0';
  315.     if (*(t1=strskip(line," \t\b"))!='\"') {
  316.         printf("Error: Aliasfile on line %d\n"
  317.             "       Cannot find opening \"\n"
  318.             "       Line: %s\n",linenumber,line);
  319.         continue;
  320.         }
  321.     if (pickoutname(&t1,&t2)) {
  322.         printf("Error: Aliasfile on line d:\n"
  323.             "       2nd \" missing\n       Line: %s\n",
  324.             linenumber,line);
  325.         continue;
  326.         }
  327.     strncpy(realname=(char *)(calloc(36<=t2-t1?36:(t2-t1)+1,sizeof(char))),
  328.         t1,35<=t2-t1?35:t2-t1);
  329.     t1=t2+1;
  330.     if (*(t1=strskip(t1,"\b\t ="))!='\"') {
  331.         printf("Warning: Aliasfile on line %d\n"
  332.             "         Missing nickname\nLine: %s\n",
  333.             linenumber,line);
  334.         continue;
  335.         }
  336.     if (pickoutname(&t1,&t2)) {
  337.         printf("Error: Aliasfile on line %d:\n"
  338.             "       2nd \" missing\n       Line: %s\n",
  339.             linenumber,line);
  340.         continue;
  341.         }
  342.     strncpy(nickname=(char *)(calloc(36,sizeof(char)))
  343.         ,t1,35<=t2-t1?35:t2-t1);
  344.     t1=t2+1;
  345.     x=(struct alias_t *)(calloc(1,sizeof(*x)));
  346.     x->above=y;
  347.     if (y!=NULL) y->below=x;
  348.     x->below=NULL;
  349.     strcpy(x->realname,realname);
  350.     strcpy(x->nickname,nickname);
  351.     y=x;
  352.  
  353.     if (z==NULL) z=x;
  354.  
  355.     while (*(t1=strskip(t1,"\b\t ,"))) {
  356.         if (*t1!='\"') {
  357.             printf("Warning: Aliasfile on line %d\n"
  358.                 "         Line ends illegally\n"
  359.                 "Line: %s\n",linenumber,line);
  360.             break;
  361.             }
  362.         if (pickoutname(&t1,&t2)) {
  363.             printf("Warning: Aliasfile on line %d:\n"
  364.                 "         Second \" missing in nickname\n"
  365.                 "Line: %s\n",linenumber,line);
  366.             break;
  367.             }
  368.         for (i=0;i<36;i++) nickname[i]='\0';
  369.         strncpy(nickname,t1,35<=t2-t1?35:t2-t1);
  370.         t1=t2+1;
  371.         x=(struct alias_t *)(calloc(1,sizeof(*x)));
  372.         x->above=y;
  373.         y->below=x;
  374.         x->below=NULL;
  375.         strcpy(x->realname,realname);
  376.         strcpy(x->nickname,nickname);
  377.         y=x;
  378.         }
  379.     }
  380.    return(z);
  381. }    
  382.  
  383. void returnmail(error1, error2, error3)
  384. char *error1, *error2, *error3;
  385. {
  386.    FILE *fp;
  387.    printf("-mail to \"%s\" returned to sender\n",msg.to);
  388.    strcpy(badname,msg.to);
  389.    strcpy(msg.to,msg.from);
  390.    strcpy(msg.from,me);
  391.    msg.content[4095-strlen(error1)-strlen(error2)-strlen(error3)]='\0';
  392.    strcpy(msgbuffer,msg.content);
  393.    strcpy(msg.content,error1);
  394.    strcpy(msg.content+strlen(msg.content),error2);
  395.    strcpy(msg.content+strlen(msg.content),error3);
  396.    strcpy(msg.content+strlen(msg.content),msgbuffer);
  397.  
  398.    if (fp=fopen(ft.name,"wb")) {
  399.     fwrite((void *)&msg,1,sizeof(msg)-4096+strlen(msg.content),fp);
  400.     fclose(fp);
  401.     }
  402.    else printf("Cannot reopen %s for write!\n",ft.name);
  403. }
  404.  
  405. void checkaliases(alias)
  406. struct alias_t *alias;
  407. {
  408.    struct alias_t *x;
  409.    FILE *fp;
  410.  
  411.    for(x=alias;x!=NULL;x=x->below) {
  412.     if (!strcmp(x->nickname,msg.to)) {
  413.         strcpy(msg.to,x->realname);
  414.         if (fp=fopen(ft.name,"wb")) {
  415.             fwrite((void *)&msg,1,sizeof(msg)-4096+
  416.                 strlen(msg.content),fp);
  417.             fclose(fp);
  418.             }
  419.         else printf("Error: Failed to rewrite %s message to \"%s\""
  420.             " (\"%s\")\n",ft.name,msg.to,x->nickname);
  421.         x=NULL;
  422.         }
  423.     }
  424. }
  425.  
  426. void telex(controller)
  427. char *controller;
  428. {
  429. }
  430.  
  431. void telegram(controller)
  432. char *controller;
  433. {
  434. }
  435.  
  436. void dialcom(controller)
  437. char *controller;
  438. {
  439. }
  440.  
  441. void purolater(controller)
  442. char *controller;
  443. {
  444. }
  445.  
  446. void internet(controller)
  447. char *controller;
  448. {
  449. }
  450.  
  451.  
  452. int pickoutname(tp1,tp2)
  453. char **tp1, **tp2;
  454. {
  455.    return(!(*tp2=strpbrk((*tp1=strskip(*tp1,"\"")),"\"")));
  456. }
  457.