home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / amiga / comms / network / amigaelm.lzh / f3.c < prev    next >
C/C++ Source or Header  |  1992-03-15  |  15KB  |  703 lines

  1. #include "prefs.h"
  2.  
  3. #include <exec/types.h>
  4. #include <exec/memory.h>
  5. #include <libraries/dos.h>
  6. #include <intuition/intuition.h>
  7.  
  8. #ifdef LATTICE
  9. #include <proto/exec.h>
  10. #include <proto/dos.h>
  11. #include <proto/reqtools.h>
  12. #endif
  13. #include <libraries/reqtools.h>
  14. #include <time.h>
  15.  
  16.  
  17.  
  18. Prototype void CreateHeader(FILE*,char*,char*);
  19. Prototype BOOL SetFolderName(char *);
  20. Prototype FILE *OpenHomeBox(void);
  21. Prototype void CloseHomeBox(FILE *);
  22. Prototype char *plural_s(int);
  23. Prototype int plural_pix(int);
  24. Prototype int send_off(char *,char *);
  25. Prototype void append_sig(FILE *);
  26. Prototype void append_elmheader(FILE *);
  27. Prototype void set_options(void);
  28. Prototype void outline(void);
  29. Prototype void OpenTTY(void);
  30. Prototype void Usage(void);
  31. Prototype void DirectSend(char *,char *);
  32. Prototype void copy_and_do_alias(FILE *,FILE *);
  33. Prototype void copy_and_do_from(FILE *,FILE *);
  34. Prototype void str_replace(char *,char *,char *);
  35. Prototype void do_introduction(FILE *,char *,struct MailItem *);
  36. Prototype void clean_exit(int);
  37. Prototype void status_msg(char *, long);
  38. Prototype char *parse_arpa_from(char *);
  39. Prototype char lastch(char *);
  40.  
  41.  
  42.  
  43. char lastch(char *str)
  44. {
  45.   int len;
  46.   len = strlen(str);
  47.   if (str && len)
  48.     return(str[len-1]);
  49.   else
  50.     return('\0');
  51. }
  52.  
  53.  
  54.  
  55. void
  56. CreateHeader(FILE* fp,char* To, char* Subject)
  57. {
  58.   fprintf(fp,"To: %s\n",STR(To));
  59.   fprintf(fp,"Subject: %s\n",STR(Subject));
  60. }
  61.  
  62.  
  63.  
  64. BOOL
  65. SetFolderName(char *file)
  66. {
  67.   char *foldername;
  68.   FILE *fp;
  69.  
  70.   if (file && strlen(file) && (foldername=strdup(file))) {
  71.     /* IMHO it's not neccessary to lock the folder here */
  72.     if (fp=fopen(foldername,"r")) {
  73.       fclose(fp);
  74.       if (FolderName) free(FolderName);
  75.       FolderName = foldername;
  76.       return(TRUE);
  77.     }
  78.     free(foldername);
  79.   }
  80.  
  81.   return(FALSE);
  82. }
  83.  
  84.  
  85.  
  86. FILE *OpenHomeBox(void)
  87. {
  88.   LockFile(FolderName);
  89.   return(fopen(FolderName,"r"));
  90. }
  91.  
  92.  
  93.  
  94. void CloseHomeBox(FILE *folder)
  95. {
  96.   fclose(folder);
  97.   UnLockFile(FolderName);
  98. }
  99.  
  100.  
  101.  
  102. /* send_off schickt die Mail in file ab, wenn die Abfrage mit 'S' */
  103. /* beantwortet wurde. Der Returnwert ist 1, wenn die Mail versandt */
  104. /* 2, wenn noch mals editiert werden soll und 0 wenn abgebrochen werden */
  105. /* soll */
  106.  
  107. int send_off(char *file,char *in_reply_to)
  108. {
  109.   FILE *in,*out;
  110.   char c;
  111.   char String[MAX_LINELENGTH];
  112.   char *tfile;
  113.   BOOL display_header = TRUE;
  114.  
  115.   /* complete header - begin */
  116.  
  117.   if (tfile=malloc(strlen(file)+3)) {         /* len + ".o" + null */
  118.     strcpy(tfile,file);
  119.     strcat(tfile,".o");
  120.     remove(tfile);
  121.     rename(file,tfile);
  122.     remove(file);
  123.     if (out=fopen(file,"w")) {
  124.       if (SendmailVersion==SM_FEULNER)
  125.         fprintf(out,"From: %s@%s%s (%s)\n",UserName,HostName,DomainName,RealName);
  126.       if (in_reply_to)
  127.         fprintf(out,"In-Reply-To: %s\n",in_reply_to);
  128.       if (WantReturn)
  129.         fprintf(out,"Return-Receipt-To: %s@%s%s\n",UserName,HostName,DomainName);
  130.       append_elmheader(out);
  131.       if (in=fopen(tfile,"r")) {
  132.         copy_and_do_alias(in,out);
  133.         copy_and_do_from(in,out);
  134.         fclose(in);
  135.       }
  136.       fclose(out);
  137.       remove(tfile);
  138.     }
  139.   }
  140.  
  141.   /* complete header - end */
  142.  
  143.   while (TRUE) {
  144.  
  145.     if (display_header) {
  146.       sprintf(TBuffer,"\033[%d;1H\033[J",Win_Height-1);
  147.       outline();
  148.       putst("And now: \n");
  149.       putst_center("Choose e)dit message, s)end, S)end without signature, or f)orget.");
  150.       sprintf(TBuffer,"\033[%d;10H",Win_Height-1);
  151.       outline();
  152.       display_header = FALSE;
  153.     }
  154.  
  155.     flush_input();
  156.  
  157.     c=getch();
  158.     if (toupper(c)=='S') {
  159.       putst("Send");
  160.  
  161.       if (c=='s') {
  162.         if (out=fopen(file,"a")) {
  163.           append_sig(out);
  164.           fclose(out);
  165.         }
  166.       }
  167.       else
  168.         putst(" (without signature)");
  169.  
  170.       if (in=fopen(file,"r")) {
  171.         if (SentArchive) {
  172.           if (out=fopen(SentArchive,"a")) {
  173.             long t;
  174.             time(&t);
  175.             fprintf(out,"From %s (ARCHIVE)\n",UserName);
  176.             fprintf(out,"Date: %s",ctime(&t));
  177.             if (SendmailVersion!=SM_FEULNER)
  178.               fprintf(out,"From: %s@%s%s (%s)\n",UserName,HostName,DomainName,RealName);
  179.             copy_and_do_from(in,out);
  180.             fclose(out);
  181.           }
  182.         }
  183.         fclose(in);
  184.       }
  185.  
  186.       if (SendmailVersion==SM_FEULNER)
  187.         sprintf(String,"sendmail <%s",file);
  188.       else if (SendmailVersion==SM_DILLON)
  189.         sprintf(String,"sendmail <%s -f %s -R \"%s\"",file,UserName,RealName);
  190.       else if (SendmailVersion==SM_OTHER)
  191.         sprintf(String,"sendmail <%s -f %s",file,UserName);
  192.  
  193.       Execute(String,0L,0L);
  194.       return 1;
  195.     }
  196.     else if (c=='e') {
  197.       putst("Edit message");
  198.       editfile(file);
  199.       display_header = TRUE;
  200.     }
  201.     else if (c=='f') {
  202.       putst("Forget");
  203.       return 0;
  204.     }
  205.   }
  206. }
  207.  
  208.  
  209.  
  210. void
  211. copy_and_expand_alias(FILE *in, FILE *out, long start, long end)
  212. {
  213.   char *buf,*ptr;
  214.   BOOL erstes = TRUE;
  215.   struct AliasItem *list,*l,*inner,*i;
  216.  
  217.   if (buf = malloc(end-start+2)) {
  218.     fseek(in,start,0);
  219.     fread(buf,1,end-start+1,in);
  220.     buf[end-start+1] = '\0';
  221.  
  222.     ptr = strchr(buf,':');
  223.     *ptr = '\0';
  224.     ptr++;
  225.  
  226.     l = list = AdrsToAList(ptr);
  227.  
  228.     if (list)
  229.       fprintf(out,"%s: ",buf);
  230.  
  231.     while (l) {
  232.       /*printf("mal sehen: %s -> %s -> %s\n",l->alias,l->real,GetAlias(AliasList,l->alias));*/
  233.       i = inner = AdrsToAList(l->real?l->real:l->alias);
  234.       while (i) {
  235.         fprintf(out,"%s%s",erstes?"":",\n\t",i->real?i->real:i->alias);
  236.         erstes = FALSE;
  237.         i = i->next;
  238.       }
  239.       FreeAliasList(&inner);
  240.       l = l->next;
  241.     }
  242.  
  243.     if (list)
  244.       fputc('\n',out);
  245.  
  246.     FreeAliasList(&list);
  247.  
  248.     if (erstes)
  249.       fprintf(stderr,"To: line is empty\n");
  250.  
  251.     free(buf);
  252.   }
  253. }
  254.  
  255.  
  256.  
  257. void
  258. copy_and_do_alias(FILE *in,FILE *out)
  259. {
  260.   char buf[MAX_LINELENGTH];
  261.   long pos,start,end;
  262.  
  263.   buf[MAX_LINELENGTH-1]='\0';   /* 100% null-terminated */
  264.  
  265.   while(getline(in,buf,&pos)) {
  266.     if (!strlen(buf)) {   /* end of header, message body begins */
  267.       fputc('\n',out);
  268.       return;
  269.     }
  270.     else if (!strnicmp(buf,"To:",3) || !strnicmp(buf,"Cc:",3) || !strnicmp(buf,"Bcc:",4)) {
  271.       start = pos;
  272.       while(getline(in,buf,&pos) && (*buf==' ' || *buf=='\t'))
  273.         ;
  274.       end = pos-1;
  275.       copy_and_expand_alias(in,out,start,end);
  276.     }
  277.     else
  278.       fprintf(out,"%s\n",buf);
  279.   }
  280. }
  281.  
  282.  
  283.  
  284. void
  285. copy_and_do_from(FILE *in,FILE *out)
  286. {
  287.   char buf[MAX_LINELENGTH];
  288.   buf[MAX_LINELENGTH-1]='\0';   /* 100% null-terminated */
  289.   while(fgets(buf,MAX_LINELENGTH-1,in)) {
  290.     if (strncmp("From ",buf,5)==0)
  291.       fprintf(out,">%s",buf);
  292.     else
  293.       fputs(buf,out);
  294.   }
  295. }
  296.  
  297.  
  298.  
  299. void
  300. append_elmheader(FILE *file)
  301. {
  302.   FILE *in;
  303.   char *headerfile;
  304.  
  305.   if (headerfile = malloc(strlen(UULIB)+strlen(UserName)+strlen(ELM_HEADERS)+1)) {
  306.  
  307.     strcpy(headerfile,UULIB);
  308.     strcat(headerfile,UserName);
  309.     strcat(headerfile,ELM_HEADERS);
  310.  
  311.     if (!(in=fopen(headerfile,"r"))) {
  312.       strcpy(headerfile,UULIB);
  313.       strcat(headerfile,ELM_HEADERS);
  314.       in=fopen(headerfile,"r");
  315.     }
  316.  
  317.     fprintf(file,"X-Mailer: //\\\\miga Electronic Mail (AmiElm %s)\n",VERSION);
  318.  
  319.     if (in) {
  320.       char line[MAX_LINELENGTH];
  321.       line[MAX_LINELENGTH-1]='\0';
  322.       while(fgets(line,MAX_LINELENGTH-1,in))
  323.         if (strlen(line) && strchr(line,':'))
  324.           fputs(line,file);
  325.       fclose(in);
  326.     }
  327.  
  328.     free(headerfile);
  329.   }
  330. }
  331.  
  332.  
  333.  
  334. void
  335. append_sig(FILE *file)
  336. {
  337.   FILE *in;
  338.   char *sigfile;
  339.  
  340.   if (sigfile = malloc(strlen(UULIB)+strlen(UserName)+strlen(SIGNATURE)+1)) {
  341.  
  342.     strcpy(sigfile,UULIB);
  343.     strcat(sigfile,UserName);
  344.     strcat(sigfile,SIGNATURE);
  345.  
  346.     if (!(in=fopen(sigfile,"r"))) {
  347.       strcpy(sigfile,UULIB);
  348.       strcat(sigfile,SIGNATURE);
  349.       in=fopen(sigfile,"r");
  350.     }
  351.  
  352.     if (in) {
  353.       register int c;
  354.       while((c=getc(in))!=EOF)
  355.         putc(c,file);
  356.       fclose(in);
  357.     }
  358.  
  359.     free(sigfile);
  360.   }
  361. }
  362.  
  363.  
  364.  
  365. void
  366. set_options(void)
  367. {
  368.   char c;
  369.   BOOL Quit = FALSE;
  370.  
  371.   while(!Quit) {
  372.     putst("\f \n\n");   /* extra space for character mapped console windows */
  373.     putst_center_bold("O p t i o n s");
  374.     putch('\n');
  375.     putst_center_bold("_______________");
  376.     putst("\033[8;1HWhich option do you want to change (toggle) ?\n");
  377.     putst(" (caution, changes are temporary!)\n\n\n");
  378.  
  379.     putst("   (1)  Handle Return-Receipt-To     (");
  380.     if (ReturnReceipt)
  381.       putst("on)\n");
  382.     else
  383.       putst("off)\n");
  384.  
  385.     putst("   (2)  Handle Return-\033[1mView\033[m-To        (");
  386.     if (ReturnView)
  387.       putst("on)\n");
  388.     else
  389.       putst("off)\n");
  390.  
  391.     putst("   (3)  Request Return-Receipt-To    (");
  392.     if (WantReturn)
  393.       putst("on)\n");
  394.     else
  395.       putst("off)\n");
  396.  
  397.     putst("   (4)  Request Return-\033[1mView\033[m-To       (");
  398.     if (WantReturn)
  399.       putst("on)\n");
  400.     else
  401.       putst("off)\n");
  402.  
  403.     putst("   (5)  Show full header             (");
  404.     if (ShowHeader)
  405.       putst("on)\n");
  406.     else
  407.       putst("off)\n");
  408.  
  409.     putst("   (6)  Show signatures              (");
  410.     if (ShowSig)
  411.       putst("on)\n");
  412.     else
  413.       putst("off)\n");
  414.  
  415.     putst("   (7)  Keep backups                 (");
  416.     if (KeepBackup)
  417.       putst("on)\n");
  418.     else
  419.       putst("off)\n");
  420.  
  421.     putst("\n\n\n");
  422.     putst_center(" Choose 1-7, or any other key to return: ");
  423.     flush_input();
  424.     c=getch();
  425.     switch (c) {
  426.       case '1': ReturnReceipt = !ReturnReceipt; break;
  427.       case '2': ReturnView    = !ReturnView;    break;
  428.       case '3': WantReturn    = !WantReturn;    break;
  429.       case '4': WantView      = !WantView;      break;
  430.       case '5': ShowHeader    = !ShowHeader;    break;
  431.       case '6': ShowSig       = !ShowSig;       break;
  432.       case '7': KeepBackup    = !KeepBackup;    break;
  433.       default : Quit          = TRUE;           break;
  434.     }
  435.   }
  436. }
  437.  
  438.  
  439.  
  440. /* Lowlevelroutinen zur Behandlung eines RAW-Fensters. Damit wird die
  441.  * Eingabepufferung der Standard-C Routinen umgangen; ausserdem koennen
  442.  * so die Cursortasten vom Programm aus abgefragt werden
  443.  */
  444.  
  445. void
  446. OpenTTY(void)
  447. {
  448.     if (!open_intuition()) {
  449.       fprintf(stderr,"elm: cannot open tty\n");
  450.       clean_exit(103);
  451.     }
  452. }
  453.  
  454.  
  455.  
  456. void
  457. outline(void)
  458. {
  459.   putst(TBuffer);
  460. }
  461.  
  462.  
  463.  
  464. /* Die naechste Prozedur gibt eine kleine Bedienungsanleitung auf dem
  465.  * Bildschirm aus und verlaesst das Programm dann
  466.  */
  467. void
  468. Usage(void)
  469. {
  470.     printf("\033[1;33mAmiga Elm \033[0m%s ⌐ 1991-1992 Andreas M. Kirchwitz (amk@zikzak.in-berlin.de)\n",VERSION);
  471.     printf("(based on hwr-mail by Heiko W. Rupp, hwr@pilhuhn.ka.sub.org)\n");
  472.     printf("Usage: elm \033[3m[?|-v|-h|-?|-f] [<user>] [-s <subject>]\033[0m\n");
  473.     clean_exit(0);
  474. }
  475.  
  476.  
  477.  
  478. void
  479. DirectSend(char *To,char *Subject)
  480. {
  481.     OpenTTY();
  482.     sendmail(To,Subject);
  483.     clean_exit(0);
  484. }
  485.  
  486.  
  487.  
  488. char *
  489. plural_s(int number)
  490. {
  491.   return( (number==1)?"":"s" );
  492. }
  493.  
  494.  
  495.  
  496. int
  497. plural_pix(int number)
  498. {
  499.   return( (number==1)?1:0 );
  500. }
  501.  
  502.  
  503.  
  504. void
  505. str_replace(char *workbuf, char *search, char *replace)
  506. {
  507.   char *p;
  508.  
  509.   if (replace && strlen(replace) && (p=strstr(workbuf,search))) {
  510.     char *s = p+strlen(search);
  511.     char *d = p;
  512.  
  513.     while (*d++=*s++)
  514.       ;
  515.  
  516.     strins(p,replace);
  517.   }
  518. }
  519.  
  520.  
  521.  
  522. void do_introduction(FILE *out, char *intro, struct MailItem *I)
  523. {
  524.   int nnum;
  525.   char *str;
  526.   char *fname = NULL;
  527.  
  528.   if (intro && strlen(intro)) {
  529.     if (I->FromName) {
  530.       fname=malloc(strlen(I->FromName)+1);
  531.       for(nnum=0;I->FromName[nnum]!='\0' && I->FromName[nnum]!=' ';nnum++)
  532.         fname[nnum]=I->FromName[nnum];
  533.       fname[nnum]='\0';
  534.     }
  535.  
  536.     if (str=malloc(strlen(intro)+2*strlen(I->From)+strlen(I->MessageID)+strlen(I->Date)+1)) {
  537.       strcpy(str,intro);
  538.       str_replace(str,"$FIRSTNAME",fname);
  539.       if (I->FromName && strlen(I->FromName))
  540.         str_replace(str,"$NAME",I->FromName);
  541.       else
  542.         str_replace(str,"$NAME",I->From);
  543.       str_replace(str,"$MSGID",I->MessageID);
  544.       str_replace(str,"$DATE",I->Date);
  545.       fprintf(out,"%s\n\n",str);
  546.     }
  547.   }
  548. }
  549.  
  550.  
  551.  
  552. void clean_exit(int err_code)
  553. {
  554.   struct MailItem *del;
  555.   close_intuition();
  556.   if (MailTmp) remove(MailTmp);
  557.   UnLockFiles();
  558.   while(MailList) {
  559.     del = MailList;
  560.     MailList = MailList->next;
  561.     free(del);
  562.   }
  563.   FreeAliasList(&AliasList);
  564.   CloseReqToolsLib();
  565.   /*
  566.      aus unerfindlichen Gruenden produziert exit() Enforcer-Hits, wenn man
  567.      Elm startet, ein Reply macht, dies jedoch dann mit f)orget abbricht
  568.      und dann das Programm beendet
  569.   */
  570.   exit(err_code);
  571. }
  572.  
  573.  
  574.  
  575. void status_msg(char *msg, long delay_time)
  576. {
  577.   int hpos;
  578.   if (intui_interface()) {
  579.     hpos = (Win_Width-strlen(msg))/2;
  580.     if (hpos<0)
  581.       hpos=0;
  582.     sprintf(TBuffer,"\033[%d;1H\033[J\033[%d;%dH[%.*s]",Win_Height,Win_Height,hpos-1,Win_Width-2,msg);
  583.     outline();
  584.     if (delay_time>0L)
  585.       Delay(delay_time);
  586.   }
  587.   else
  588.     fprintf(stderr,"elm: %s\n",msg);
  589. }
  590.  
  591.  
  592.  
  593. char *parse_arpa_from(char *str)
  594. {
  595.   /** try to parse the 'From:' line given... It can be in one of
  596.       two formats:
  597.             From: Dave Taylor <hpcnou!dat>
  598.         or  From: hpcnou!dat (Dave Taylor)
  599.       Change 'newfrom' ONLY if sucessfully parsed this entry and
  600.       the resulting name is non-null!
  601.   **/
  602.  
  603.   char *temp_buffer, *temp, *ret=NULL, *buffer;
  604.   register int i, j = 0, in_parens;
  605.  
  606.   if (!(buffer=strdup(str)))
  607.     return(NULL);
  608.  
  609.   removeCR(buffer);    /* blow away '\n' char! */
  610.   buffer = delete_wspaces_begin(buffer);
  611.   delete_wspaces_end(buffer);
  612.  
  613.   if (!(temp_buffer=malloc(strlen(buffer)+1))) {
  614.     free(buffer);
  615.     return(NULL);
  616.   }
  617.  
  618.   temp = temp_buffer;
  619.   *temp = '\0';
  620.  
  621.   if (lastch(buffer) == '>') {
  622. /*
  623.     for (i=0; buffer[i] != '\0' && buffer[i] != '<' &&
  624.          buffer[i] != '('; i++)
  625. */
  626.     for (i=0; buffer[i] != '\0' && buffer[i] != '<'; i++)
  627.       temp[j++] = buffer[i];
  628.     temp[j] = '\0';
  629.   }
  630.   else if (lastch(buffer) == ')') {
  631.     in_parens = 1;
  632.     for (i=strlen(buffer)-2; i>=0 && buffer[i] != '\0' && buffer[i] != '<'; i--) {
  633.       switch(buffer[i]) {
  634.         case ')':  in_parens++;
  635.                    break;
  636.         case '(':  in_parens--;
  637.                    break;
  638.       }
  639.       if(!in_parens) break;
  640.       temp[j++] = buffer[i];
  641.     }
  642.     temp[j] = '\0';
  643.     strrev(temp);
  644.   }
  645.  
  646. /*
  647.   /* We want a REAL name... else NULL... */
  648.  
  649.   temp = delete_wspaces_begin(temp);
  650.   delete_wspaces_end(temp);
  651.  
  652.   /** if we have a null string at this point, we must just have a
  653.       From: line that contains an address only.  At this point we
  654.       can have one of a few possibilities...
  655.  
  656.     From: address
  657.     From: <address>
  658.     From: address ()
  659.   **/
  660.  
  661.   j = 0;
  662.  
  663.   if (strlen(temp) == 0) {
  664.     if (lastch(buffer) != '>') {
  665.       for (i=0; buffer[i] != '\0' && buffer[i] != '('; i++)
  666.         temp[j++] = buffer[i];
  667.       temp[j] = '\0';
  668.     }
  669.     else {  /* get outta '<>' pair, please! */
  670.       for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':' && i>=0;i--)
  671.         temp[j++] = buffer[i];
  672.       temp[j] = '\0';
  673.       strrev(temp);
  674.     }
  675.   }
  676. */
  677.  
  678.   temp = delete_wspaces_begin(temp);
  679.   delete_wspaces_end(temp);
  680.  
  681.   if (strlen(temp) > 0) {    /* mess with buffer... */
  682.  
  683.     i = strlen(temp) - 1;
  684.  
  685.     /* remove surrounding paired quotation marks */
  686.     if((temp[i] == '"') & (temp[0] == '"')) {
  687.       temp[i] = '\0';
  688.       temp++;
  689.     }
  690.  
  691.     /* if anything is left, let's change 'from' value! */
  692.  
  693.     if (strlen(temp) > 0)
  694.       ret = strdup(temp);
  695.   }
  696.  
  697.   free(buffer);
  698.   free(temp_buffer);
  699.  
  700.   return(ret);
  701. }
  702.  
  703.