home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / ftp.vapor.com / microdot-1 / md1_src_02.lzx / msg.c < prev    next >
C/C++ Source or Header  |  2014-05-19  |  103KB  |  5,303 lines

  1. #include "microdot.h"
  2.  
  3. #include <dos/dostags.h>
  4. #include <proto/datatypes.h>
  5. #include <proto/whatis.h>
  6. #include <datatypes/datatypesclass.h>
  7.  
  8. #include "ogre.h"
  9. #include "ogre_protos.h"
  10.  
  11. static struct List mlist;
  12. static USHORT usecmpid;
  13. static ULONG cmpid;
  14. struct mbrett *cmb;
  15. struct mindex *mix;
  16.  
  17. long mmcount;
  18. USHORT wrotenewmails, oldbrettmaxnum;
  19. static int lastmailnum;
  20. int donextnewboard;
  21. static struct mmail *newmailptr;
  22.  
  23. static struct vmail *currentreadermail;
  24.  
  25. extern BOOL didsortin;
  26.  
  27. void *mlistpool;
  28.  
  29. #define TCONV (char*)1
  30.  
  31. static char *skipre( char *txt );
  32.  
  33. static char *headertab[]={
  34.     "EMP",            "EmpfΣnger",         FALSE,
  35.     "ABS",            "Absender",            FALSE,
  36.     "ROT",            "Routweg",            FALSE,
  37.     "LEN",            "LΣnge",            FALSE,
  38.     "BET",            "Betreff",            FALSE,
  39.     "PRIO",            "PrioritΣt",        FALSE,
  40.     "MID",            "Message-ID",        FALSE,
  41.     "BEZ",            "Bezugs-ID",        FALSE,
  42.     "ZNETZ-CONV",    "Z38-Converter",    FALSE,
  43.     "ANTWORT-AN",    "Antwort an",        FALSE,
  44.     "DISKUSSION-IN","Diskussion in",    FALSE,
  45.     "MAILER",        "Mailer",            FALSE,
  46.     "WAB",            "W-Absender",        FALSE,
  47.     "O-ROT",        "O-Routweg",        FALSE,
  48.     "OAB",            "O-Absender",        FALSE,
  49.     "OEM",            "O-EmpfΣnger",        FALSE,
  50.     "ORG",            "Organisation",        FALSE,
  51.     "FILE",            "Dateiname",        FALSE,
  52.     "TELEFON",        "Telefonnummer",    FALSE,
  53.     "POST",            "Postanschrift",    FALSE,
  54.  
  55.     "EDA",            "Datum",            TCONV,
  56.     "SPERRFRIST",    "Sperrfrist",        TCONV,
  57.     "LDA",            "L÷schdatum",        TCONV,
  58.     "DDA",            "Dateidatum",        TCONV,
  59.     "VIA",            "Via Routesystem",    TCONV,
  60.     0
  61. };
  62.  
  63. static char datmem[ 256 ];
  64. static char *translateheader( char *head, char *data )
  65. {
  66.     char **p = headertab;
  67.  
  68.     datmem[0]á= 0;
  69.     while( p[0] )
  70.     {
  71.         if( !stricmp( head, p[0] ) )
  72.         {
  73.             /* Datumskonvertierung */
  74.             if( p[2] && data )
  75.             {
  76.                 char tmpdata[á64 ];
  77.  
  78.                 strncpy( tmpdata, data, 64 );
  79.                 tmpdata[á63 ]á= 0;
  80.                 while( strlen( tmpdata ) < 20 ) 
  81.                     strcat( tmpdata, " " );
  82.  
  83.                 sprintf( datmem, "%.2s.%.2s.%.4s %.2s:%.2s:%.2s (%3.3s) %s",
  84.                     &tmpdata[6],&tmpdata[4],tmpdata,
  85.                     &tmpdata[8],&tmpdata[10],&tmpdata[12],
  86.                     &tmpdata[ 14 ],
  87.                     &tmpdata[á17 ]
  88.                 );
  89.             }
  90.             return( p[1] );
  91.         }
  92.         p++;
  93.         p++;
  94.         p++;
  95.     }
  96.     return( head );
  97. }
  98.  
  99. static void freemlist(void)
  100. {
  101.     if( mlistpool )
  102.     {
  103.         LibDeletePool( mlistpool );
  104.         mlistpool = 0;
  105.     }
  106. }
  107.  
  108. struct msghandle *msg_openv( struct vmail *n )
  109. {
  110.     struct msghandle *msg;
  111.  
  112.     if( !n )
  113.     {
  114.         displaybeep();
  115.         return( NULL );
  116.     }
  117.  
  118.     msg = msg_open( n->m->m.pufferID, n->m->m.mailID );
  119.  
  120.     if( !msg )
  121.         displaybeep();
  122.  
  123.     return( msg );
  124. }
  125.  
  126.  
  127. void calcmcount(void)
  128. {
  129.     struct vmail *mm=(struct vmail*)mlist.lh_Head;
  130.     long newcount=0,delcount=0,mailcount=0,foldcount=0,unreadcount=0;
  131.     char buffer[128];
  132.  
  133.     mmcount=0;
  134.     while( mm->n.mln_Succ )
  135.     {
  136.         if( ! ( mm->m->m.flags & MMF_KILL ) )
  137.         {
  138.             mailcount++;
  139.             if(mm->sel) mmcount++;
  140.             if(mm->m->m.flags & MMF_DEL ) delcount++;
  141.             if(mm->m->m.flags & MMF_FOLD) foldcount++;
  142.             if(mm->m->m.flags & (MMF_UNSEEN|MMF_SHOW)) newcount++;
  143.             if(!(mm->m->m.flags & MMF_READ)) unreadcount++;
  144.         }
  145.         mm=(struct vmail*)mm->n.mln_Succ;
  146.     }
  147.     cmb->b.mails=mailcount;
  148.     cmb->b.newmails=newcount;
  149.     cmb->b.unreadmails=unreadcount;
  150.  
  151.     sprintf(buffer,"%lD Nachrichten, %lD neu, %lD ungelesen, %lD gel÷scht",mailcount,newcount,unreadcount,delcount);
  152.     if(mmcount)
  153.     {
  154.         asprintf(buffer,", %lD markiert",mmcount);
  155.     }
  156.     if(foldcount)
  157.     {
  158.         asprintf(buffer,", %lD gefaltet",foldcount);
  159.     }
  160.     
  161.     preport(1,1,buffer);
  162.  
  163.     if(cmb->b.betreff[0])
  164.         preport(0,1,"NACHRICHTENAUSWAHL: Brett %s (%s)",cmb->b.name,cmb->b.betreff);
  165.     else
  166.         preport(0,1,"NACHRICHTENAUSWAHL: Brett %s",cmb->b.name);
  167. }
  168.  
  169. /*
  170.  *  Markierungen speichern
  171.  */
  172.  
  173. void savesel( void )
  174. {
  175.     struct vmail *mm=(struct vmail*)mlist.lh_Head;
  176.  
  177.     while( mm->n.mln_Succ )
  178.     {
  179.         mm->savedsel = mm->sel;
  180.         mm=(struct vmail*)mm->n.mln_Succ;
  181.     }
  182.  
  183. }
  184.  
  185. /*
  186.  *  Markierungen wiederherstellen
  187.  */
  188.  
  189. static void restoresel( void )
  190. {
  191.     struct vmail *mm=(struct vmail*)mlist.lh_Head;
  192.  
  193.     while( mm->n.mln_Succ )
  194.     {
  195.         mm->sel = mm->savedsel;
  196.         mm=(struct vmail*)mm->n.mln_Succ;
  197.     }
  198.  
  199. }
  200.  
  201.  
  202. #if 0
  203. static void makemmailhash( struct mmail *m )
  204. {
  205.     char *p = skipre( m->m.betreff );
  206.  
  207.     m->hash_bet =    ( tolower( p[á0 ]á) << 24 ) +
  208.                     ( tolower( p[á1 ]á) << 16 ) +
  209.                     ( tolower( p[á2 ]á) << 8 ) +
  210.                     ( tolower( p[á3 ]á) );
  211.  
  212. //    Printf( "hash %s %lx\n", p, m->hash_bet smake);
  213. }
  214. #endif
  215.  
  216.  
  217. static struct vmail *findvmail(struct mmail *m)
  218. {
  219.     struct vmail *vm=(struct vmail*)mlist.lh_Head;
  220.  
  221.     while(vm->n.mln_Succ)
  222.     {
  223.         if(vm->m==m) return(vm);
  224.         vm=(struct vmail*)vm->n.mln_Succ;
  225.     }
  226.     return(0);
  227. }
  228.  
  229. static struct vmail *findparentmail( struct vmail *vm )
  230. {
  231.     struct mmail *m;
  232.  
  233.     if( !vm )
  234.         return( NULL );
  235.  
  236.      m = vm->m;
  237.  
  238.     while( m->parent )
  239.         m = m->parent;
  240.  
  241.     vm = findvmail( m );
  242.     return( vm );
  243. }
  244.  
  245. static void resendmail( struct vmail *n )
  246. {
  247.     struct msghandle *msg;
  248.     struct hlist *hlist;
  249.     struct header *abs, *emp, *bet;
  250.     struct mbrett *sp=findbrett("/╗SPOOL",0);
  251.     struct mail tmp;
  252.  
  253.     msg = msg_openv( n );
  254.     if( !msg )
  255.         return;
  256.     hlist = msg_loadheader( msg );
  257.     msg_close( msg );
  258.     if( !hlist )
  259.     {
  260.         return;
  261.     }
  262.  
  263.     abs = hl_findheader( hlist, "ABS" );
  264.     emp = hl_findheader( hlist, "EMP" );
  265.     bet = hl_findheader( hlist, "BET" );
  266.  
  267.     if( abs )
  268.     {
  269.         askreq( "Fehler: Sie k÷nnen nur Ihre eigenen\nNachrichten erneut verschicken.", "Abbruch" );
  270.         hl_freeheader( hlist );
  271.         return;
  272.     }
  273.     if( !askreq( "Wollen Sie Ihre Nachricht\nmit BET: %s\nund EMP: %s\nerneut verschicken?", "Verschicken|Abbruch",
  274.         bet->data, emp->data ) )
  275.     {
  276.         hl_freeheader( hlist );
  277.         return;
  278.     }
  279.     hl_freeheader( hlist );
  280.  
  281.     tmp = n->m->m;
  282.     tmp.flags &= ~(MMF_ARCHIVE|MMF_DEL);
  283.     storemail2ix( &tmp, sp, NULL );
  284. }
  285.  
  286. static char *getcookie( struct mbrett * cmb )
  287. {
  288.     static char buffer[ 1024 ];
  289.     int counter=0;
  290.     char b2[128];
  291.     FILE *f;
  292.  
  293.     strcpy( buffer, "microdot.cookies" );
  294.     if( cmb && cmb->b.language )
  295.         asprintf( buffer, ".%ld", cmb->b.language );
  296.  
  297.     f = fopen( buffer, "r" );
  298.     if( !f )
  299.         return( "" );
  300.  
  301.     fsetbuf( f, 8192 );
  302.  
  303.     while( ( fgets( buffer, 128, f ) ) )
  304.     {
  305.         clnl( buffer );
  306.         if( !buffer[0] )
  307.             counter++;
  308.     }
  309.     fseek( f, 0, 0 );
  310.     if( counter )
  311.         counter = ( prefs.counter++ ) % counter;
  312.     while( counter && ( fgets( buffer, 256, f ) ) )
  313.     {
  314.         clnl( buffer );
  315.         if( !buffer[ 0 ]á)
  316.             counter--;
  317.     }
  318.     buffer[á0 ]á= 0;
  319.     while( ( fgets( b2, 128, f ) ) )
  320.     {
  321.         clnl( b2 );
  322.         if( !b2[ 0 ]á)
  323.             break;
  324.         
  325.         if( strlen( buffer ) + strlen( b2 ) > 1021 )
  326.             break;
  327.  
  328.         asprintf( buffer, "%s\n", b2 );
  329.     }
  330.     fclose(f);
  331.     if( buffer[á0 ]á)
  332.         buffer[ástrlen( buffer ) - 1 ]á= 0;
  333.     return( buffer );
  334. }
  335.  
  336. void doorigin(FILE *f,int public,struct mbrett *cmb)
  337. {
  338.     char *p;
  339.     int c,ch;
  340.     FILE *f2;
  341.     char buffer[256];
  342.  
  343.     p=(public)?"md_orig.pub":"md_orig.priv";
  344.  
  345.     strcpy( buffer, p );
  346.     if( cmb && cmb->b.language )
  347.         asprintf( buffer, ".%ld", cmb->b.language );
  348.     p = buffer;
  349.  
  350.     if( cmb )
  351.     {
  352.         if(cmb->b.flags&BFLAG_NOORIGIN) p=0;
  353.         if(cmb->b.flags&BFLAG_SPECIALORIGIN)
  354.         {
  355.             brettpfad(buffer,cmb);
  356.             addpart(buffer,".Origin");
  357.             p=buffer;
  358.         }
  359.     }
  360.  
  361.     if(p)
  362.     {
  363.         c=getfilelen(p);
  364.         if(c>2) {
  365.             f2=fopen(p,"r");
  366.             fsetbuf(f2,2048);
  367.             /*fprintf(f,"\n\n\n\n");*/
  368.             for(;;)
  369.             {
  370.                 ch=fgetc(f2);
  371.                 if(ch<0) break;
  372.                 if(ch=='$')
  373.                 {
  374.                     for( c = 0; c < 16; c++ )
  375.                     {
  376.                         ch = fgetc( f2 );
  377.                         if( ch == EOF || ch == '$' )
  378.                             break;
  379.                         buffer[c] = ch;
  380.                     }
  381.                     buffer[c]á= 0;
  382.  
  383.                     if( !stricmp( buffer, "cookie" ) )
  384.                         fputs( getcookie( cmb ), f );
  385.                     else if( !stricmp( buffer, "ver" ) )
  386.                         fputs( "MicroDot V" MDVER, f );
  387.                     else
  388.                         fputc( '$', f );
  389.                 }
  390.                 else fputc(ch,f);
  391.             }
  392.             fclose(f2);
  393.         }
  394.     }
  395.  
  396. }
  397.  
  398. static struct vmail *findnextunread(struct vmail *vm)
  399. {
  400.     struct vmail *mm;
  401.  
  402.     if( !vm )
  403.         return( NULL );
  404.     vm= (struct vmail *) vm->n.mln_Succ;
  405.     if( !vm )
  406.         return( NULL );
  407.     while( ( mm= (struct vmail*) vm->n.mln_Succ ) )
  408.     {
  409.         if( !( vm->m->m.flags & MMF_READ ) )
  410.             break;
  411.         vm = mm;
  412.     }
  413.     return( ( mm ) ? vm : NULL);
  414. }
  415.  
  416. static void checksignature(struct vmail *n)
  417. {
  418.     struct header *hl, *hl2;
  419.     struct msghandle *msg;
  420.     struct hlist *hlist;
  421.     BPTR f;
  422.     char signature[á1024 ];
  423.     int siglen, isbin;
  424.  
  425.     if( n->m->m.flags & MMF_PGPSIGNED )
  426.     {
  427.         if( !askreq( "Die Signatur dieser Nachricht\nist bereits geprⁿft und\nfⁿr korrekt befunden worden.", "Trotzem prⁿfen|Abbruch" ) )
  428.             return;
  429.     }
  430.  
  431.     DeleteFile( "T:mdpgp.iso" );
  432.     DeleteFile( "T:mdpgp.txt" );
  433.  
  434.     msg = msg_open( n->m->m.pufferID, n->m->m.mailID );
  435.     if( !msg )
  436.     {
  437.         displaybeep();
  438.         return;
  439.     }
  440.  
  441.     /* Emps suchen */
  442.     hlist = msg_loadheader( msg );
  443.  
  444.     isbin = hl_testheader( hlist, "TYP", 0 );
  445.  
  446.     hl = hl_findheader( hlist, "SIGNED" );
  447.     while( hl )
  448.     {
  449.         if( !stricmp( hl->data, "PGP" ) )
  450.             break;
  451.         hl = hl_findnextheader(hl);
  452.     }
  453.  
  454.     //
  455.     //    Keine Signatur gefunden
  456.     //
  457.  
  458.     hl2 = hl_findheader( hlist, "PGP-SIG" );
  459.  
  460.     if( !hl || !hl2 )
  461.     {
  462.         hl_freeheader( hlist );
  463.         msg_close( msg );
  464.         askreq( "Diese Nachricht enthΣlt keine PGP-Signatur.", "Abbruch" );
  465.         return;
  466.     }
  467.  
  468.     if( dpem_buffer( hl2->data, signature, &siglen ) )
  469.     {
  470.         hl_freeheader( hlist );
  471.         msg_close( msg );
  472.         askreq( "Die Signatur dieser Nachricht\nist offenbar zerst÷rt.", "Abbruch" );
  473.         return;
  474.     }
  475.  
  476.     f = Open( "T:mdpgp.sig", MODE_NEWFILE );
  477.     Write( f, signature, siglen );
  478.     Close( f );
  479.  
  480.     if( isbin )
  481.     {
  482.         msg_copy( msg, "T:mdpgp.iso", MC_COMMENT );
  483.         convpgpmsg();
  484.         DeleteFile( "T:mdpgp.iso" );
  485.         f = Open( "T:mdpgp.txt", MODE_READWRITE );
  486.         Seek( f, 0, OFFSET_END );
  487.         msg_copyfh( msg, f, MC_DATA );
  488.         Close( f );
  489.     }
  490.     else
  491.     {
  492.         msg_copy( msg, "T:mdpgp.iso", MC_DATA | MC_COMMENT );
  493.         convpgpmsg();
  494.         DeleteFile( "T:mdpgp.iso" );
  495.     }
  496.  
  497.     msg_close( msg );
  498.  
  499.     if( !runpgp( "T:mdpgp.sig T:mdpgp.txt", 0, 1 ) )
  500.     {
  501.         n->m->m.flags |= MMF_PGPSIGNED;
  502.         mix->changed = 1;
  503.     }
  504.  
  505.     hl_freeheader( hlist );
  506.  
  507.     DeleteFile( "T:mdpgp.sig" );
  508.     DeleteFile( "T:mdpgp.txt" );
  509. }
  510.  
  511. static void iteratemsglist( void (*func)( struct vmail * ) )
  512. {
  513.     struct vmail *n = ( struct vmail * ) mlist.lh_Head;
  514.  
  515.     mix->changed=1;
  516.  
  517.     if(!mmcount)
  518.     {
  519.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  520.         if( n )
  521.             func( n );
  522.     }
  523.     else
  524.     {
  525.         savesel();
  526.         while( n->n.mln_Succ )
  527.         {
  528.             if( n->sel )
  529.             {
  530.                 func( n );
  531.                 n->sel = 0;
  532.             }
  533.             n=(struct vmail*)n->n.mln_Succ;
  534.         }
  535.     }
  536. }
  537.  
  538. static void checksignatures( void )
  539. {
  540.     iteratemsglist( checksignature );
  541. }
  542.  
  543. static int doweitermail(struct vmail *n)
  544. {
  545.     char buffer[256],bet[256],comment[256];
  546.     long empcount=0;
  547.     char **emplist;
  548.     void *rkey;
  549.     struct header *hl;
  550.     int rc;
  551.     struct msghandle *msg;
  552.     struct hlist *hlist;
  553.  
  554.     DeleteFile( TMPMSGNAME );
  555.     DeleteFile( TMPCOMMENTNAME );
  556.  
  557.     msg = msg_open( n->m->m.pufferID, n->m->m.mailID );
  558.     if( !msg )
  559.     {
  560.         displaybeep();
  561.         return( 0 );
  562.     }
  563.  
  564.     rkey = LibCreatePool( MEMF_CLEAR, 1024, 256 );
  565.  
  566.     msg_copy( msg, TMPMSGNAME, MC_DATA );
  567.     msg_copy( msg, TMPCOMMENTNAME, MC_COMMENT );
  568.  
  569.     /* Emps suchen */
  570.     hlist = msg_loadheader( msg );
  571.  
  572.     hl = hl_findheader( hlist, "EMP" );
  573.     while( hl )
  574.     {
  575.         empcount++;
  576.         hl = hl_findnextheader(hl);
  577.     }
  578.  
  579.     emplist=LibAllocPooled(rkey,empcount*4+4);
  580.     empcount=0;
  581.     hl=hl_findheader(hlist,"EMP");
  582.     while(hl)
  583.     {
  584.         emplist[empcount]=LibAllocPooled(rkey,strlen(hl->data)+1);
  585.         strcpy(emplist[empcount++],hl->data);
  586.         hl=hl_findnextheader(hl);
  587.     }
  588.     emplist[empcount]=0;
  589.  
  590.     hl=hl_findheader(hlist,"ABS");
  591.     buffer[0]=0;
  592.     if(hl) strcpy(buffer,hl->data);
  593.  
  594.     hl=hl_findheader(hlist,"BET");
  595.     bet[255]=bet[0]=0;
  596.     if(hl) strncpy(bet,hl->data,255);
  597.  
  598.     hl=hl_findheader(hlist,"ZUSAMMENFASSUNG");
  599.     comment[255]=comment[0]=0;
  600.     if(hl) strncpy(comment,hl->data,255);
  601.  
  602.     msg_close( msg );
  603.  
  604.     hl = hl_findheader( hlist, "FILE" );
  605.  
  606.     rc=dosendwin("Nachricht weiterleiten...",bet,comment,0, 0,n->m->m.flags&MMF_BIN?1:0,
  607.         buffer,emplist,0,0, NULL, NULL, hl ? hl->data : NULL, NULL
  608.     );
  609.  
  610.     hl_freeheader( hlist );
  611.  
  612.     LibDeletePool(rkey);
  613.  
  614.     return(rc);
  615. }
  616.  
  617. static int doweiterquiet( char **destlist, struct vmail *n )
  618. {
  619.     char buffer[256],bet[256],comment[256];
  620.     long empcount=0;
  621.     char **emplist;
  622.     void *rkey;
  623.     struct header *hl;
  624.     int rc;
  625.     struct msghandle *msg;
  626.     struct hlist *hlist;
  627.  
  628.     DeleteFile( TMPMSGNAME );
  629.     DeleteFile( TMPCOMMENTNAME );
  630.  
  631.     msg = msg_open( n->m->m.pufferID, n->m->m.mailID );
  632.     if( !msg )
  633.     {
  634.         displaybeep();
  635.         return( 0 );
  636.     }
  637.  
  638.     rkey = LibCreatePool( MEMF_CLEAR, 1024, 256 );
  639.  
  640.     msg_copy( msg, TMPMSGNAME, MC_DATA );
  641.     msg_copy( msg, TMPCOMMENTNAME, MC_COMMENT );
  642.  
  643.     /* Emps suchen */
  644.     hlist = msg_loadheader( msg );
  645.  
  646.     hl = hl_findheader( hlist, "EMP" );
  647.     while( hl )
  648.     {
  649.         empcount++;
  650.         hl = hl_findnextheader(hl);
  651.     }
  652.  
  653.     emplist=LibAllocPooled(rkey,empcount*4+4);
  654.     empcount=0;
  655.     hl=hl_findheader(hlist,"EMP");
  656.     while(hl)
  657.     {
  658.         emplist[empcount]=LibAllocPooled(rkey,strlen(hl->data)+1);
  659.         strcpy(emplist[empcount++],hl->data);
  660.         hl=hl_findnextheader(hl);
  661.     }
  662.     emplist[empcount]=0;
  663.  
  664.     hl=hl_findheader(hlist,"ABS");
  665.     buffer[0]=0;
  666.     if(hl) strcpy(buffer,hl->data);
  667.  
  668.     hl=hl_findheader(hlist,"BET");
  669.     bet[255]=bet[0]=0;
  670.     if(hl) strncpy(bet,hl->data,255);
  671.  
  672.     hl=hl_findheader(hlist,"ZUSAMMENFASSUNG");
  673.     comment[255]=comment[0]=0;
  674.     if(hl) strncpy(comment,hl->data,255);
  675.  
  676.     msg_close( msg );
  677.  
  678.     hl = hl_findheader( hlist, "FILE" );
  679.  
  680.     rc = dosendwin( "Nachricht weiterleiten",
  681.         bet,
  682.         comment,
  683.         NULL,
  684.         destlist,
  685.         n->m->m.flags & MMF_BIN ? 1 : 0,
  686.         buffer,
  687.         emplist,
  688.         NULL,
  689.         NULL,
  690.         NULL,
  691.         NULL,
  692.         hl ? hl->data : NULL,
  693.         NULL
  694.     );
  695.  
  696.     //rc=dosendweiter( destlist, emplist, buffer, bet, comment, n->m->m.flags & MMF_BIN );
  697.  
  698.     hl_freeheader( hlist );
  699.  
  700.     LibDeletePool(rkey);
  701.  
  702.     return(rc);
  703. }
  704.  
  705. static char *findqh( struct hlist *hlist, char *head )
  706. {
  707.     struct header *hl;
  708.     static char buff2[128];
  709.     char *p;
  710.  
  711.     if(!stricmp(head,"DAT") || !stricmp( head, "DATE" ) )
  712.     {
  713.         hl = hl_findheader( hlist, "EDA" );
  714.         if( hl )
  715.         {
  716.             sprintf( buff2, "%2.2s.%2.2s.%4.4s",
  717.                 &hl->data[6],
  718.                 &hl->data[4],
  719.                 hl->data );
  720.             return( buff2 );
  721.                 
  722.                 
  723.         }
  724.     }
  725.     else if( !stricmp( head, "TIM" ) || !stricmp( head, "TIME" ) )
  726.     {
  727.         hl = hl_findheader(hlist,"EDA");
  728.         if( hl )
  729.         {
  730.             int hoffset = atoi( &hl->data[á15 ] );
  731.             char hour[á4 ];
  732.  
  733.             hour[á0 ]á= hl->data[á8 ];
  734.             hour[á1 ]á= hl->data[á9 ];
  735.             hour[ 2 ] = 0;
  736.  
  737.             sprintf( buff2, "%02ld:%2.2s:%2.2s",
  738.                 ( atoi( hour ) + hoffset ) % 24,
  739.                 &hl->data[10],
  740.                 &hl->data[12] );
  741.             return( buff2 );
  742.         }
  743.     }
  744.     else if( !stricmp( head, "VORNAME" ) || !stricmp( head, "NAME1" ) )
  745.     {
  746.         hl = hl_findheader(hlist,"ABS");
  747.         if( hl )
  748.         {
  749.             p = strchr( hl->data, '(' );
  750.             if( p && !isspace( p[ 1 ]á) )
  751.             {
  752.                 sbreakword( buff2, ++p, 0, 127);
  753.                 skillatch( buff2, ')'á);
  754.                 return( buff2 );
  755.             }
  756.             else
  757.             {
  758.                 strncpy( buff2, hl->data, 127 );
  759.                 skillatch( buff2, '%'á);
  760.                 skillatch( buff2, '@'á);
  761.                 return( buff2 );
  762.             }
  763.         }
  764.     }
  765.     else if(!stricmp(head,"NACHNAME") || !stricmp( head, "NAME2" ) )
  766.     {
  767.         hl=hl_findheader(hlist,"ABS");
  768.         if(hl)
  769.         {
  770.             p=strchr(hl->data,'(');
  771.             if(p++)
  772.             {
  773.                 sbreakword(buff2,p,-1,127);
  774.                 skillatch( buff2, ')'á);
  775.                 return( buff2 );
  776.             }
  777.         }
  778.     }
  779.     hl = hl_findheader( hlist, head );
  780.     if(hl)
  781.     {
  782.         return( hl->data );
  783.     }
  784.  
  785.     return( "" );
  786. }
  787.  
  788.  
  789. static void doquoteheader(struct hlist *hlist, FILE *to,long public)
  790. {
  791.     FILE *head;
  792.     char buff[64];
  793.     int ch,c;
  794.  
  795.     strcpy( buff, ( public ) ? "md_qh.pub" : "md_qh.priv" );
  796.     if( cmb->b.language )
  797.         asprintf( buff, ".%ld", cmb->b.language );
  798.  
  799.     head = fopen( buff, "r" );
  800.     if(!head)
  801.         return; 
  802.  
  803.     while((ch=fgetc(head))!=EOF)
  804.     {
  805.         if(ch=='$')
  806.         {
  807.             for(c=0; c<64; c++)
  808.             {
  809.                 ch=fgetc(head);
  810.                 if(ch==EOF||ch=='$') break;
  811.                 buff[c]=ch;
  812.             }
  813.             buff[c]=0;
  814.  
  815.             if( !c )
  816.             {
  817.                 fputc( '$', to );
  818.                 continue;
  819.             }
  820.  
  821.             fprintf( to, findqh( hlist, buff ) );
  822.         }
  823.         else
  824.             fputc( ch, to );
  825.     }
  826.     fclose( head );
  827. }
  828.  
  829. static int donewmail( char *binfile, struct mbrett *cmb, char *emp )
  830. {
  831.     int rc;
  832.     char *emplist[2];
  833.     struct brettinfo *bi=getbrettinfo(cmb);
  834.     FILE *f;
  835.     int origin = 1;
  836.  
  837.     emplist[á0 ]á= emp;
  838.     emplist[á1 ]á= NULL;
  839.  
  840.     if( ( cmb->b.name[0] == '/' ) && ( cmb->b.name[ 1 ]á!= '╗' ) )
  841.     {
  842.         emplist[0] = cmb->b.name;
  843.     }
  844.     else
  845.     {
  846.         origin = 0;
  847.         if( bi->antwortan[á0 ] )
  848.             emplist[á0 ]á= bi->antwortan;
  849.     }
  850.  
  851.     f = fopen( TMPMSGNAME, "w" );
  852.     if( !f )
  853.     {
  854.         displaybeep();
  855.         return(0);
  856.     }
  857.     doorigin( f, origin, cmb );
  858.     fclose(f);
  859.  
  860.     rc=dosendwin( "Neue Nachricht...",
  861.         NULL,NULL,
  862.         NULL,
  863.         emplist,
  864.         binfile ? 2 : 0,
  865.         0,0,bi->diskussionin[0]?bi->diskussionin:0,0,
  866.         NULL,
  867.         binfile,
  868.         NULL,
  869.         NULL
  870.     );
  871.     return(rc);
  872. }
  873.  
  874. static int doanswermail(struct vmail *n,int public,int quote)
  875. {
  876.     char *emp[128],*p;
  877.     char qc[4];
  878.     int rc,c;
  879.     int flags = 0;
  880.     char buffer[1024];
  881.     char betreff[256];
  882.     char fto[á128 ];
  883.     struct header *hl, *hl2;
  884.     struct brettinfo *bi=getbrettinfo(cmb);
  885.     struct msghandle *msg;
  886.     struct hlist *hlist;
  887.     FILE *f;
  888.  
  889.     if( !n )
  890.     {
  891.         displaybeep();
  892.         return( 0 );
  893.     }
  894.  
  895.     /* Falls PM, keine ÷ffentliche Antwort m÷glich */
  896.     if( public && cmb->b.name[0] != '/' && !( cmb->b.flags & BFLAG_EXTEND_PM ) )
  897.     {
  898.         return( donewmail( NULL, cmb, !strnicmp( n->m->m.absender, "an ", 3 ) ? &n->m->m.absender[á3 ] : n->m->m.absender ) );
  899.     }
  900.  
  901.     qc[0]=0;
  902.  
  903.     // Filter flag errors...
  904.  
  905.     if( quote )
  906.         quote = 1;
  907.  
  908.     if( ( n->m->m.flags & MMF_BIN ) && quote )
  909.         quote = 2;
  910.  
  911.     msg = msg_open( n->m->m.pufferID, n->m->m.mailID );
  912.     if( !msg )
  913.     {
  914.         displaybeep();
  915.         return( 0 );
  916.     }
  917.  
  918.     hlist = msg_loadheader( msg );
  919.  
  920.     f = fopen( TMPMSGNAME, "w" );
  921.  
  922.     /* Header alle vorhanden */
  923.     hl = hl_findheader(hlist,"BET");
  924.     betreff[255]=0;
  925.     sprintf( betreff, "Re: %.247s", skipre( hl->data ) );
  926.     fto[á0 ]á= 0;
  927.  
  928.     hl=hl_findheader(hlist,"ABS");
  929.     if(!hl)
  930.     {
  931.         /* Von uns */
  932.         hl = hl_findheader( hlist, "EMP" );
  933.         if( hl && hl->data && ( ( cmb->b.name[ 0 ] != '/' ) || ( !strcmp( cmb->b.name, "/╗SPOOL" ) ) ) )
  934.             strcpy( buffer, hl->data );
  935.         else
  936.             sprintf( buffer, "%s@%s%s (%s)", prefs.username, ISRFC ? prefs.pointname : prefs.boxname, prefs.boxdomain, prefs.userrealname );
  937.         hl_addheader( hlist, "ABS", buffer );
  938.     }
  939.     else
  940.     {
  941.         p = strchr( hl->data, '(' );
  942.         if( p )
  943.         {
  944.             stccpy( fto, stpblk( p + 1 ), sizeof( fto ) );
  945.             p = strrchr( fto, ')' );
  946.             if( p )
  947.                 *p = 0;
  948.         }
  949.     }
  950.  
  951.     if(!public)
  952.     {
  953.         int gotaa = FALSE;
  954.  
  955.         c = 0;
  956.         hl = hl_findheader( hlist, "ANTWORT-AN" );
  957.         if( hl )
  958.         {
  959.             // check for mailinglist
  960.             if( cmb->b.flags & BFLAG_EXTEND_PM )
  961.             {
  962.                 struct brettinfo *bi = getbrettinfo( cmb );
  963.  
  964.                 if( !stricmp( hl->data, bi->antwortan ) )
  965.                     hl = NULL;
  966.             }
  967.  
  968.  
  969.             while( hl )
  970.             {
  971.                 emp[ác++ ] = hl->data;
  972.                 hl = hl_findnextheader( hl );
  973.                 gotaa = TRUE;
  974.             }
  975.         }
  976.  
  977.         if( !gotaa )
  978.         {
  979.             hl = hl_findheader( hlist, "ABS" );
  980.             if( hl )
  981.                 emp[ác++á] = hl->data;
  982.         }
  983.  
  984.         hl = hl_findheader( hlist, "OAB" );
  985.         if( hl )
  986.             emp[ác++á] = hl->data;
  987.  
  988.         /*hl = hl_findheader( hlist, "WAB" );
  989.         if( hl )
  990.             emp[ác++á] = hl->data;*/
  991.  
  992.         emp[ác ] = 0;
  993.     }
  994.     else
  995.     {
  996.         hl=hl_findheader( hlist, "DISKUSSION-IN" );
  997.         if(!hl)
  998.         {
  999.             if( bi->diskussionin[0] )
  1000.             {
  1001.                 emp[0]=bi->diskussionin;
  1002.                 emp[1]=0;
  1003.             }
  1004.             else if( bi->antwortan[0] )
  1005.             {
  1006.                 emp[0]=bi->antwortan;
  1007.                 emp[1]=0;
  1008.             }
  1009.             else            
  1010.             {
  1011.                 hl = hl_findheader( hlist, "EMP" );
  1012.                 for(c=0; hl && c<127; c++)
  1013.                 {
  1014.                     emp[c]=hl->data;
  1015.                     hl=hl_findnextheader(hl);
  1016.                 }
  1017.                 emp[c] = NULL;
  1018.             }
  1019.         }
  1020.         else
  1021.         {
  1022.             /* Diskussion in vorhanden */
  1023.             for( c=0; hl && c<127; c++ )
  1024.             {
  1025.                 emp[c]=hl->data;
  1026.                 hl=hl_findnextheader(hl);
  1027.             }
  1028.             emp[c]á= NULL;
  1029.         }
  1030.     }
  1031.  
  1032.     /* Quoten */
  1033.     if( quote && ( quote != 2 || msg_getsize( msg, MC_COMMENT ) ) )
  1034.     {
  1035.         hl=hl_findheader(hlist,"ABS");
  1036. /*        p=strchr(hl->data,'(');
  1037.         if(p && p[1] != ')' && p[2] != ')' )
  1038.         {
  1039.             if( p[1] == '\"' )
  1040.                 p++;
  1041.             qc[0]=p[1];
  1042.             if( p[2] )
  1043.                 qc[1]=p[2];
  1044.             else
  1045.                 qc[1]=qc[0];
  1046.             p = strrchr(p,' ');
  1047.             if(p) qc[1]=p[1];
  1048.         }
  1049.         else
  1050.         {
  1051.             strcpy( buffer, hl->data );
  1052.             p = strchr( buffer, '%' );
  1053.             if( p )
  1054.                 *p = 0;
  1055.             p = strchr( buffer, '@' );
  1056.             if( p )
  1057.                 *p = 0;
  1058.             qc[0]=buffer[0];
  1059.             p=strchr(buffer,'_');
  1060.             if(!p) p=strchr(buffer,'.');
  1061.             if(!p) p=strchr(buffer,'-');
  1062.             if(p)
  1063.                 qc[1]=p[1];
  1064.              else
  1065.                 qc[1] = buffer[strlen(buffer) - 1 ];
  1066.         }
  1067.         qc[2] = '>';
  1068.         qc[3] = 0; 
  1069.         qc[á0 ]á= '>';
  1070.         qc[á1 ] = 0;*/
  1071.         doquoteheader(hlist,f,public);
  1072.         c=0;
  1073.  
  1074.         // Kommentar auch quoten
  1075.  
  1076.         if( msg_getsize( msg, MC_COMMENT ) > 0 )
  1077.         {
  1078.             msg_initread( msg, MC_COMMENT );
  1079.  
  1080.             while( msg_read( msg, buffer, sizeof( buffer ) ) )
  1081.             {
  1082.                 clnl(buffer);
  1083.                 if(!buffer[0] && !c) continue;
  1084.                 else c=1;
  1085.                 fprintf(f,"> %s\n",buffer);
  1086.             }
  1087.  
  1088.             if( quote != 2 )
  1089.                 fprintf( f, "\n" );
  1090.  
  1091.             msg_endread( msg );
  1092.         }
  1093.  
  1094.         c = 0;
  1095.         if( quote != 2 )
  1096.         {
  1097.             msg_initread( msg, MC_DATA );
  1098.  
  1099.             while( msg_read( msg, buffer, sizeof( buffer ) ) )
  1100.             {
  1101.                 clnl(buffer);
  1102.                 if(!buffer[0] && !c) continue;
  1103.                 else c=1;
  1104.                 fprintf(f,"> %s\n", buffer );
  1105.             }
  1106.             msg_endread( msg );
  1107.         }
  1108.     }
  1109.  
  1110.     doorigin(f,public,cmb);
  1111.  
  1112.     fclose(f);
  1113.  
  1114.     msg_close( msg );
  1115.  
  1116.     hl2 = hl_findheader( hlist, "BEZ" );
  1117.     if( hl2 == hl_findlastheader( hlist, "BEZ" ) )
  1118.         hl2 = NULL;
  1119.     /*if( !hl2 )
  1120.         hl2 = hl_findheader( hlist, "BEZ" );*/
  1121.  
  1122.     hl = hl_findheader( hlist, "MID" );
  1123.     rc = dosendwin((public)?"╓ffentliche Antwort...":"Private Antwort...",
  1124.         betreff,0,
  1125.         hl->data, emp,
  1126.         flags,
  1127.         0,0,
  1128.         bi->diskussionin[0] ? bi->diskussionin : NULL,
  1129.         qc[0]?qc:NULL,
  1130.         hl2 ? hl2->data : NULL,
  1131.         NULL,
  1132.         NULL,
  1133.         fto[á0 ]á? fto : NULL
  1134.     );
  1135.  
  1136.     hl_freeheader( hlist );
  1137.     return(rc);
  1138.  
  1139. }
  1140.  
  1141. static int doanswer(int public,int quote)
  1142. {
  1143.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  1144.     int rc=0;
  1145.     struct mbrett *personal=findbrett(0,0);
  1146.  
  1147.     /* Im privaten Brett */
  1148.     if(personal==cmb) public=0;
  1149.  
  1150.     if(!mmcount)
  1151.     {
  1152.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  1153.         rc=doanswermail(n,public,quote);
  1154.         return(rc);
  1155.     }
  1156.     savesel();
  1157.     while(n->n.mln_Succ)
  1158.     {
  1159.         if(n->sel)
  1160.         {
  1161.             rc|=doanswermail(n,public,quote);
  1162.             n->sel=0;
  1163.         }
  1164.         n=(struct vmail*)n->n.mln_Succ;
  1165.     }
  1166.     return(rc);
  1167. }
  1168.  
  1169. void excludemail(struct msghandle *msg,char *to,BOOL withheader,int bin)
  1170. {
  1171.     BPTR f2;
  1172.     int rc;
  1173.  
  1174.     /* Prⁿfen, ob Datei da */
  1175.     rc = fileexistsreq( to );
  1176.  
  1177.     if( !rc )
  1178.         return;
  1179.     else if( rc == 1 )
  1180.         f2 = Open( to, MODE_NEWFILE );
  1181.     else if( rc == 2 )
  1182.     {
  1183.         f2 = Open( to, MODE_OLDFILE );
  1184.         if( !f2 )
  1185.         {
  1186.             return;
  1187.         }
  1188.         Seek( f2, 0, OFFSET_END );
  1189.     }
  1190.  
  1191.     if(!f2) {
  1192.         rc = IoErr();
  1193.         nofilereq( to, rc );
  1194.         return;
  1195.     }
  1196.  
  1197.     msg_copyfh( msg, f2, MC_DATA | ( withheader ? ( MC_HEADER | MC_COMMENT ) : 0 ) );
  1198.  
  1199.     Close(f2);
  1200.  
  1201.     /* Icon erzeugen */
  1202.     if(bin!=42)
  1203.     {
  1204.         createdataicon(to,(bin)?prefs.binex_defaulttool:prefs.txtex_defaulttool);
  1205.     }
  1206. }
  1207.  
  1208. void excludemailquiet(struct msghandle *msg,char *to,BOOL withheader,BOOL bin,BOOL append)
  1209. {
  1210.     BPTR f2;
  1211.     int rc;
  1212.  
  1213.     if( append )
  1214.     {
  1215.         f2 = Open( to, MODE_OLDFILE );
  1216.         if( f2 )
  1217.             Seek( f2, 0, OFFSET_END );
  1218.         else
  1219.             f2 = Open( to, MODE_NEWFILE );
  1220.     }
  1221.     else
  1222.         f2 = Open( to, MODE_NEWFILE );
  1223.  
  1224.     if(!f2)
  1225.     {
  1226.         rc = IoErr();
  1227.         nofilereq( to, rc );
  1228.         return;
  1229.     }
  1230.  
  1231.     msg_copyfh( msg, f2, MC_DATA | ( withheader ? ( MC_HEADER | MC_COMMENT ) : 0 ) );
  1232.  
  1233.     Close(f2);
  1234.  
  1235.     /* Icon erzeugen */
  1236.     if(bin!=42)
  1237.     {
  1238.         createdataicon(to,(bin)?prefs.binex_defaulttool:prefs.txtex_defaulttool);
  1239.     }
  1240. }
  1241.  
  1242. static void domailinfo( struct vmail * n )
  1243. {
  1244.     struct msghandle *msg = msg_openv( n );
  1245.  
  1246.     if( !msg )
  1247.         return;
  1248.  
  1249.     askreq( "\Position: %ld:%ld\nFlags...: %ld\nOffset..: %ld\nHeader..: %ld\nComment.: %ld\nData....: %ld",
  1250.         "Absturz",
  1251.         n->m->m.pufferID, n->m->m.mailID,
  1252.         msg->pix.flags,
  1253.         msg->pix.offset,
  1254.         msg->pix.headersize,
  1255.         msg->pix.commentsize,
  1256.         msg->pix.datasize
  1257.     );
  1258.  
  1259.     msg_close( msg );
  1260.  
  1261. }
  1262.  
  1263. static void doviewmail(struct vmail *n)
  1264. {
  1265.     char ex[ 256 ];
  1266.     struct msghandle *msg;
  1267.     struct mmail *m = n->m;
  1268.  
  1269.     if( ( ( ! ( m->m.flags & MMF_READ ) || ( m->m.flags&MMF_SHOW ) ) ) )
  1270.     {
  1271.         m->m.flags|=MMF_READ;
  1272.         m->m.flags&=~MMF_SHOW;
  1273.         mix->changed=1;
  1274.     }
  1275.  
  1276.     if( ( prefs.flags2 & MDF2_AUTOCLRNEW ) && ( m->m.flags & MMF_UNSEEN ) )
  1277.     {
  1278.         m->m.flags &= ~MMF_UNSEEN;
  1279.         mix->changed = 1;
  1280.     }
  1281.  
  1282.     msg = msg_openv( n );
  1283.     if( !msg )
  1284.         return;
  1285.     msg_copy( msg, "T:mdview.temp", MC_DATA );
  1286.     msg_close( msg );
  1287.  
  1288.     sprintf( ex, prefs.binviewer, "T:mdview.temp", 0, 0, 0, 0, 0, 0 );
  1289.  
  1290.     if( !wbwindow && prefs.viewer_wb )
  1291.         WBenchToFront();
  1292.  
  1293.     if( isv37 )
  1294.     {
  1295.         SystemTags( ex, NP_StackSize, max( prefs.viewer_stack, 4096 ), TAG_DONE );
  1296.     }
  1297.     else
  1298.     {
  1299.         system( ex );
  1300.     }
  1301.     DeleteFile("T:mdview.temp");
  1302.     ScreenToFront( scr );
  1303. }
  1304.  
  1305.  
  1306. static void makebetfilename(char *name)
  1307. {
  1308.     char *to=name;
  1309.  
  1310.     while(*name) {
  1311.         if( ! ( ( isalpha(*name) ) || ( isdigit(*name) ) || ( *name == '.' ) || ( *name == '_' ) || ( *name == '-' ) ) )
  1312.         {
  1313.             *to++='_';
  1314.             while(*name && !isalpha(*name)) name++;
  1315.         }
  1316.         else *to++=*name++;
  1317.     }
  1318.     if( to[-1] == '_' ) to[-1]=0;
  1319.     else *to=0;
  1320. }
  1321.  
  1322. static int huntit( char *from, char ch )
  1323. {
  1324.     if( *from == ch )
  1325.         return( 0 );
  1326.  
  1327.     while( *from && strchr( "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789÷Σⁿ╓─▄▀°╪«⌐", *from ) )
  1328.         from++;
  1329.     return( ( *from == ch ) && strchr( "`'┤`():;!.,  \t", from[ 1 ]á) );
  1330. }
  1331.  
  1332. #define STYLE_ITALIC
  1333. static void stylenode( char *txt, int len, char *cpy, char *sty )
  1334. {
  1335.     int c, d;
  1336.     int cs = FS_NORMAL;
  1337.  
  1338.     for( c = 0, d = 0; c < len; c++ )
  1339.     {
  1340.         sty[ dá] = cs;
  1341.         if( txt[ác ]á== '*' )
  1342.         {
  1343.             if( cs & FSF_BOLD )
  1344.             {
  1345.                 cs &= ~FSF_BOLD;
  1346.             }
  1347.             else
  1348.             {
  1349.                 if( ( !c || isspace( txt[ác - 1 ]á) ) && huntit( &txt[ c + 1 ], '*' ) )
  1350.                     cs |= FSF_BOLD;
  1351.                 else
  1352.                 {
  1353.                     cpy[ d++ ]á= txt[ c ];
  1354.                 }
  1355.             }
  1356.         }
  1357.         else if( txt[ác ]á== '_' )
  1358.         {
  1359.             if( cs & FSF_UNDERLINED )
  1360.             {
  1361.                 cs &= ~FSF_UNDERLINED;
  1362.             }
  1363.             else
  1364.             {
  1365.                 if( ( !c || isspace( txt[ác - 1 ]á) ) && huntit( &txt[ c + 1 ], '_' ) )
  1366.                     cs |= FSF_UNDERLINED;
  1367.                 else
  1368.                     cpy[ d++ ]á= txt[ c ];
  1369.             }
  1370.         }
  1371. #ifdef STYLE_ITALIC
  1372.         else if( txt[ác ]á== '/' )
  1373.         {
  1374.             if( cs & FSF_ITALIC )
  1375.             {
  1376.                 cs &= ~FSF_ITALIC;
  1377.             }
  1378.             else
  1379.             {
  1380.                 if( ( !c || isspace( txt[ác - 1 ]á) ) && huntit( &txt[ c + 1 ], '/' ) )
  1381.                     cs |= FSF_ITALIC;
  1382.                 else
  1383.                     cpy[ d++ ]á= txt[ c ];
  1384.             }
  1385.         }
  1386. #endif
  1387.         else
  1388.             cpy[ád++ ]á= txt[ác ];
  1389.         
  1390.     }
  1391.     cpy[ád ]á= 0;
  1392. }
  1393.  
  1394. #define PW_CANCEL 1
  1395. #define PW_GCM 2
  1396. #define PW_INFO 3
  1397. #define PW_GALL 4
  1398.  
  1399. static APTR printogw;
  1400. static int printcount, printmax, printabort;
  1401. static void initprintwin( void )
  1402. {
  1403.     static char windowtitle[ 80 ];
  1404.     APTR ogw;
  1405.     struct Window *iw;
  1406.  
  1407.     printmax = mmcount ? mmcount : 1;
  1408.     printcount = 0;
  1409.     printabort = FALSE;
  1410.  
  1411.     lockwindow();
  1412.     if( mmcount )
  1413.         sprintf( windowtitle, "%lD Nachrichten drucken...", mmcount );
  1414.     else
  1415.         strcpy( windowtitle, "Nachricht drucken" );
  1416.     ogw = ogreInitWindow( scr, 0, 0, windowtitle );
  1417.     ogreAddGroup( ogw, 0 | OGGP_EXPANDSTRING, OGFRAME_NONE, NULL );
  1418.     ogreAddText( ogw, 0, "Info:", PW_INFO, "", 40, 1 );
  1419.     ogreAddFuelGauge( ogw, 1, PW_GCM, 0 );
  1420.     if( mmcount )
  1421.         ogreAddFuelGauge( ogw, 2, PW_GALL, mmcount );
  1422.     ogreAddButton( ogw, ( mmcount ? 3 : 2 ) | OGB_ONESC, 'a', "_Abbruch", PW_CANCEL );
  1423.  
  1424.     iw = ogreOpenWindow( ogw );
  1425.     if( !iw )
  1426.     {
  1427.         unlockwindow();
  1428.         return;
  1429.     }
  1430.     printogw = ogw;
  1431. }
  1432.  
  1433. static void closeprintwin( void )
  1434. {
  1435.     if( !printogw )
  1436.         return;
  1437.  
  1438.     ogreExitWindow( printogw );
  1439.     printogw = NULL;
  1440.     unlockwindow();
  1441. }
  1442.  
  1443. static int safeprint( BPTR pr, char *buffer, int len )
  1444. {
  1445.     int rc;
  1446.  
  1447.     if( len < 0 )
  1448.         len = strlen( buffer );
  1449.  
  1450.     for(;;)
  1451.     {
  1452.         struct IntuiMessage *im;
  1453.  
  1454.         while( im = ogreIM( printogw ) )
  1455.         {
  1456.             if( ( im->Class == IDCMP_GADGETUP )    && ( im->Code == PW_CANCEL ) )
  1457.                 printabort = TRUE;
  1458.             ogreIMReply( printogw, im );
  1459.         }
  1460.  
  1461.         if( printabort )
  1462.         {
  1463.             if( askreq( "Druckvorgang abbrechen?", "Drucken abbrechen|Weiter" ) )
  1464.                 return( -1 );
  1465.             printabort = FALSE;
  1466.         }
  1467.  
  1468.         rc = Write( pr, buffer, len );
  1469.         if( rc == len )
  1470.             return( 0 );
  1471.  
  1472.         rc = askreq( "Fehler %ld beim Drucken!", "Wiederholen|Abbruch", IoErr() );
  1473.         if( !rc )
  1474.             return( -1 );
  1475.     }
  1476. }
  1477.  
  1478. static int printmsg( struct msghandle *msg, LONG what, BPTR prt )
  1479. {
  1480.     UBYTE buf[ 1024 ];
  1481.     UBYTE new[ 1024 ];
  1482.     UBYTE sty[ 1024 ];
  1483.     int c, cs, e, slen;
  1484.     char stycmd[á32 ];
  1485.     int len;
  1486.     int rc = 0;
  1487.     int ppos = 0;
  1488.  
  1489.     msg_initread( msg, what );
  1490.  
  1491.     while( msg_read( msg, buf, 1024 ) )
  1492.     {
  1493.         ppos += strlen ( buf );
  1494.         ogreSetValue( printogw, PW_GCM, ppos );
  1495.  
  1496.         if( prefs.flags & MDF_NOREADERSTYLES )
  1497.         {
  1498.             rc = safeprint( prt, buf, -1 );
  1499.             if( rc )
  1500.                 goto xit;
  1501.         }        
  1502.         else
  1503.         {
  1504.             stylenode( buf, 1024, new, sty );
  1505.             len = strlen( new );
  1506.             // Nun printen
  1507.             for( c = 0; c < len; )
  1508.             {
  1509.                 cs = sty[ác ];
  1510.                 for( e = c + 1; ( e < len ) && ( sty[ e ]á== cs ); e++ );
  1511.                 slen = e - c;
  1512.  
  1513.                 strcpy( stycmd, "\x1b[0m" );
  1514.                 if( cs )
  1515.                 {
  1516.                     strcat( stycmd, "\x1b[" );
  1517.                     if( cs & FSF_BOLD )
  1518.                         strcat( stycmd, "1;" );
  1519.                     if( cs & FSF_UNDERLINED )
  1520.                         strcat( stycmd, "4;" );
  1521.                     if( cs & FSF_ITALIC )
  1522.                         strcat( stycmd, "3;" );
  1523.                     strcpy( strchr( stycmd, 0 ) - 1, "m" );
  1524.                 }
  1525.                 rc = safeprint( prt, stycmd, -1 );
  1526.                 if( rc )
  1527.                     goto xit;
  1528.                 rc = safeprint( prt, &new[ác ], slen );
  1529.                 if( rc )
  1530.                     goto xit;
  1531.                 c += slen;
  1532.             }
  1533.         }
  1534.         rc = safeprint( prt, "\n", 1 );
  1535.         if( rc )
  1536.             goto xit;
  1537.     }
  1538.     rc = safeprint( prt, "\x1b[0m\n", -1 );
  1539. xit:
  1540.     msg_endread( msg );
  1541.     return( rc );
  1542. }
  1543.  
  1544. static int doprintmail(struct vmail *n)
  1545. {
  1546.     struct header *hl;
  1547.     char *p2;
  1548.     int rc;
  1549.     BPTR prt;
  1550.     int bin;
  1551.     struct msghandle *msg;
  1552.     struct hlist *hlist;
  1553.     int cpw = FALSE;
  1554.     int msgsize;
  1555.  
  1556.     if( printabort )
  1557.         return( -1 );
  1558.  
  1559.     if( !printogw )
  1560.     {
  1561.         initprintwin();
  1562.         cpw = TRUE;
  1563.     }
  1564.  
  1565.     if( printogw )
  1566.     {
  1567.         char bf[á128 ];
  1568.         sprintf( bf, "Drucke Nachricht %ld von %ld", ++printcount, printmax );
  1569.         ogreSetStringValue( printogw, PW_INFO, bf );
  1570.         if( mmcount )
  1571.             ogreSetValue( printogw, PW_GALL, printcount );
  1572.         ogreSetValue( printogw, PW_GCM, 0 );
  1573.     }
  1574.  
  1575.     msg = msg_openv( n );
  1576.     if( !msg )
  1577.     {
  1578.         if( cpw )
  1579.             closeprintwin();
  1580.         printabort = TRUE;
  1581.         return( -1 );
  1582.     }
  1583.  
  1584.     msgsize = msg_getsize( msg, MC_COMMENT ) + msg_getsize( msg, MC_DATA );
  1585.     ogreSetMaxVal( printogw, PW_GCM, msgsize );
  1586.  
  1587.     bin = n->m->m.flags & MMF_BIN;
  1588.  
  1589.     hlist = msg_loadheader( msg );
  1590.  
  1591. /*    hl = hl_findheader( hlist, "TYP" );
  1592.     if( hl && hl->data && !stricmp( hl->data, "BIN" ) )
  1593.         bin = TRUE;*/
  1594.  
  1595. retry:
  1596.     prt = Open( "PRT:", MODE_NEWFILE );
  1597.     if( !prt )
  1598.     {
  1599.         if( askreq("Drucker ist nicht ansprechbar (%ld)!","Wiederholen|Abbruch", IoErr() ) )
  1600.             goto retry;
  1601.         hl_freeheader( hlist );
  1602.         msg_close( msg );
  1603.         if( cpw )
  1604.             closeprintwin();
  1605.         printabort = TRUE;
  1606.         return( -1 );
  1607.     }
  1608.  
  1609.     /* Erst Header drucken... */
  1610.     hl = hl_findheader( hlist, NULL );
  1611.     while( hl->n.mln_Succ )
  1612.     {
  1613.         p2 = translateheader( hl->head, hl->data );
  1614.     
  1615.         if( rc = safeprint( prt, "\x1b[1m", -1 ) )
  1616.             goto abortprint;
  1617.         if( rc = safeprint( prt, p2, -1 ) )
  1618.             goto abortprint;
  1619.         rc = 20 - strlen( p2 );
  1620.  
  1621.         if( rc > 0 )
  1622.         {
  1623.             if( rc = safeprint( prt, "....................", rc ) )
  1624.                 goto abortprint;
  1625.         }
  1626.         if( rc = safeprint( prt, ":\x1b[0m ", -1 ) )
  1627.             goto abortprint;
  1628.         if( rc = safeprint( prt, (datmem[0]) ? datmem : hl->data, -1 ) )
  1629.             goto abortprint;
  1630.         if( rc = safeprint( prt, "\n", 1 ) )
  1631.             goto abortprint;
  1632.         hl = ( struct header * ) hl->n.mln_Succ;
  1633.     }
  1634.  
  1635.     if( rc = safeprint( prt, "\n", 1 ) )
  1636.         goto abortprint;
  1637.  
  1638.     /* Copy rest der nachricht */
  1639.     if( bin )
  1640.     {
  1641.         if( rc = printmsg( msg, MC_COMMENT, prt ) )
  1642.             goto abortprint;
  1643.         rc = safeprint( prt, "\nBinΣrdatei.\n", -1 );
  1644.     }
  1645.     else
  1646.     {
  1647.         if( rc = printmsg( msg, MC_COMMENT, prt ) )
  1648.             goto abortprint;
  1649.         rc = printmsg( msg, MC_DATA, prt );
  1650.     }
  1651.  
  1652. abortprint:
  1653.     Close( prt );
  1654.     msg_close( msg );
  1655.     hl_freeheader( hlist );
  1656.     if( cpw )
  1657.         closeprintwin();
  1658.  
  1659.     if( rc )
  1660.         printabort = TRUE;
  1661.     return( rc );
  1662. }
  1663.  
  1664. static void doprintmsg( void )
  1665. {
  1666.     initprintwin();
  1667.     iteratemsglist( doprintmail );
  1668.     closeprintwin();
  1669. }
  1670.  
  1671. struct vmail *getcurrentmail( void )
  1672. {
  1673.     if( rexxmode == 2)
  1674.         return( currentreadermail );
  1675.     else
  1676.         return( ( struct vmail * ) GetEntry( &mlist, getscrollercurrent() ) );
  1677. }
  1678.  
  1679. struct msghandle *opencurrentmail( void )
  1680. {
  1681.     struct vmail *vm = getcurrentmail();
  1682.     struct msghandle *msg = NULL;
  1683.  
  1684.     if( vm )
  1685.     {
  1686.         msg = msg_open( vm->m->m.pufferID, vm->m->m.mailID );
  1687.     }
  1688.     return( msg );
  1689. }
  1690.  
  1691. struct mbrett *getcurrentbrett( void )
  1692. {
  1693.     return( cmb );
  1694. }
  1695.  
  1696. #define DEC(c)  (((c) - ' ') & 077)
  1697.  
  1698. static void outdec( char *p, FILE *f, int n)
  1699. {
  1700.     int c1, c2, c3;
  1701.  
  1702.     c1 = DEC(*p) << 2 | DEC(p[1]) >> 4;
  1703.     c2 = DEC(p[1]) << 4 | DEC(p[2]) >> 2;
  1704.     c3 = DEC(p[2]) << 6 | DEC(p[3]);
  1705.     if (n >= 1)
  1706.         putc(c1, f);
  1707.     if (n >= 2)
  1708.         putc(c2, f);
  1709.     if (n >= 3)
  1710.         putc(c3, f);
  1711. }
  1712.  
  1713. void excludemailuudecode( struct msghandle *msg, char *to )
  1714. {
  1715.     FILE *f;
  1716.     int rc;
  1717.     char line[á256 ];
  1718.     char *p;
  1719.     int endfound = FALSE;
  1720.  
  1721.     /* Prⁿfen, ob Datei da */
  1722.     rc = fileexistsreq( to );
  1723.  
  1724.     if( !rc )
  1725.         return;
  1726.     else if( rc == 1 )
  1727.         f = fopen( to, "w" );
  1728.     else if( rc == 2 )
  1729.         f = fopen( to, "a" );
  1730.  
  1731.     if(!f)
  1732.     {
  1733.         rc = IoErr();
  1734.         nofilereq( to, rc );
  1735.         return;
  1736.     }
  1737.  
  1738.     while( msg_read( msg, line, 256 ) )
  1739.     {
  1740.         if( !strnicmp( line, "end", 3 ) )
  1741.         {
  1742.             endfound = TRUE;
  1743.             break;
  1744.         }
  1745.  
  1746.         rc = DEC( line[ 0 ]á) ;
  1747.         if( rc < 0 || rc > 63 )
  1748.         {
  1749.             break;
  1750.         }
  1751.  
  1752.         p = &line[á1 ];
  1753.         while( rc > 0 )
  1754.         {
  1755.             outdec( p, f, rc );
  1756.             rc -= 3;
  1757.             p += 4;
  1758.         }
  1759.     }
  1760.  
  1761.     if( !endfound )
  1762.     {
  1763.         askreq( "Warnung! Keine \"end\"-Zeile gefunden.\nDie Datei kann unvollstΣndig sein.", "Weiter" );
  1764.     }
  1765.  
  1766.     msg_endread( msg );
  1767.  
  1768.     fclose( f );
  1769.  
  1770.     /* Icon erzeugen */
  1771.     createdataicon( to, prefs.binex_defaulttool );
  1772. }
  1773.  
  1774.  
  1775. static void doextractmailuudecode( struct vmail *n )
  1776. {
  1777.     char file[108],path[256];
  1778.     struct msghandle *msg;
  1779.     struct brettinfo *bi=getbrettinfo(cmb);
  1780.     char *p;
  1781.  
  1782.     file[0]=file[107]=0;
  1783.  
  1784.     msg = msg_openv( n );
  1785.     if( !msg )
  1786.         return;
  1787.  
  1788.     msg_initread( msg, MC_DATA );
  1789.  
  1790.     while( msg_read( msg, path, 256 ) )
  1791.     {
  1792.         if( !strncmp( path, "begin ", 6 ) )
  1793.             goto found;
  1794.     }
  1795.  
  1796.     msg_endread( msg );
  1797.     msg_close( msg );
  1798.     askreq( "Keine \"begin\"-Zeile gefunden.\nDies ist keine UUEncodete Nachricht.", "Abbruch" );
  1799.  
  1800.     return;
  1801.  
  1802. found:
  1803.  
  1804.     p = stpblk( &path[ 6 ]á);
  1805.     if( p )
  1806.     {
  1807.         p = strchr( p, ' 'á);
  1808.         if( p )
  1809.             strcpy( file, stpblk( p ) );
  1810.     }
  1811.  
  1812.     if( bi && bi->autoexpfad[0] )
  1813.         rtChangeReqAttr( fr[ FR_EXCLUDE_BIN ], RTFI_Dir, bi->autoexpfad, TAG_DONE );
  1814.  
  1815.     if( rtFileRequest(fr[ FR_EXCLUDE_BIN ],file,"Nachricht UUDecoden...",
  1816.         RT_Window,w,
  1817.         RT_ReqPos,REQPOS_CENTERSCR,
  1818.         RT_LockWindow,TRUE,
  1819.         RTFI_Flags,FREQF_SAVE,
  1820.         TAG_DONE))
  1821.     {
  1822.             strcpy(path,fr[ FR_EXCLUDE_BIN ]->Dir);
  1823.             addpart(path,file);
  1824.             excludemailuudecode( msg, path );
  1825.     }
  1826.     msg_close( msg );
  1827. }
  1828.  
  1829.  
  1830. static void doextractmail(struct vmail *n,BOOL withheader)
  1831. {
  1832.     char file[108],path[256];
  1833.     struct header *hl;
  1834.     struct hlist *hlist;
  1835.     struct msghandle *msg;
  1836.     struct brettinfo *bi=getbrettinfo(cmb);
  1837.     int frnum;
  1838.  
  1839.     file[0]=file[107]=0;
  1840.  
  1841.     msg = msg_openv( n );
  1842.     if( !msg )
  1843.         return;
  1844.  
  1845.     frnum = (n->m->m.flags & MMF_BIN) ? FR_EXCLUDE_BIN : FR_EXCLUDE;
  1846.  
  1847.     hlist = msg_loadheader( msg );
  1848.     hl = hl_findheader(hlist,"FILE");
  1849.     if(!hl) {
  1850.         hl=hl_findheader(hlist,"BET");
  1851.         if(hl) {
  1852.             strncpy(file,hl->data,107);
  1853.             makebetfilename(file);
  1854.         }
  1855.     }
  1856.     else strncpy(file,hl->data,107);
  1857.  
  1858.     if( bi && bi->autoexpfad[0] )
  1859.         rtChangeReqAttr( fr[ frnum ], RTFI_Dir, bi->autoexpfad, TAG_DONE );
  1860.  
  1861.     if( rtFileRequest(fr[frnum],file,"Nachricht exportieren...",
  1862.         RT_Window,w,
  1863.         RT_ReqPos,REQPOS_CENTERSCR,
  1864.         RT_LockWindow,TRUE,
  1865.         RTFI_Flags,FREQF_SAVE,
  1866.         TAG_DONE))
  1867.     {
  1868.             strcpy(path,fr[frnum]->Dir);
  1869.             addpart(path,file);
  1870.             excludemail(msg,path,withheader,n->m->m.flags&MMF_BIN);
  1871.     }
  1872.     hl_freeheader(hlist);
  1873.     msg_close( msg );
  1874. }
  1875.  
  1876. static void doextractmailquiet( struct vmail *n, char *dir, BOOL withheader )
  1877. {
  1878.     char file[108],path[256];
  1879.     struct header *hl;
  1880.     struct hlist *hlist;
  1881.     struct msghandle *msg;
  1882.  
  1883.     msg = msg_openv( n );
  1884.  
  1885.     if( !msg )
  1886.         return;
  1887.  
  1888.     hlist = msg_loadheader( msg );
  1889.  
  1890.     hl = hl_findheader(hlist,"FILE");
  1891.     if(!hl)
  1892.     {
  1893.         hl=hl_findheader(hlist,"BET");
  1894.         if(hl)
  1895.         {
  1896.             strncpy(file,hl->data,107);
  1897.             makebetfilename(file);
  1898.         }
  1899.     }
  1900.     else strncpy(file,hl->data,107);
  1901.  
  1902.     strcpy(path,dir);
  1903.     addpart(path,file);
  1904.     excludemailquiet( msg, path, withheader, n->m->m.flags & MMF_BIN, FALSE );
  1905.     hl_freeheader(hlist);
  1906.  
  1907.     msg_close( msg );
  1908. }
  1909.  
  1910.  
  1911. #define DX_OK 1
  1912. #define DX_CANCEL 2
  1913. #define DX_MODE 3
  1914. #define DX_HEADER 4
  1915. #define DX_DIR 5
  1916. #define DX_DIRSEL 6
  1917.  
  1918. static char *dx_options[]á= { "einzelne Dateien", "Einzeln ohne Nachfrage", "Gesammelt in eine Datei", NULL };
  1919.  
  1920. static void doextractmsg( BOOL withheader )
  1921. {
  1922.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  1923.     char windowtitle[á42 ];
  1924.     int Done = FALSE;
  1925.     struct ogwin *ogw;
  1926.     struct IntuiMessage *im;
  1927.     struct Window *iw;
  1928.     static UWORD xmode, xheader;
  1929.     static char xpath[ 256 ];
  1930.     int rc;
  1931.  
  1932.     if( !mmcount )
  1933.     {
  1934.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  1935.         doextractmail( n, withheader );
  1936.         return;
  1937.     }
  1938.  
  1939.     if( !xpath[á0 ]á)
  1940.         strcpy( xpath, prefs.binex_pfad );
  1941.  
  1942.     /* Mehrere Markiert */
  1943.     lockwindow();
  1944.     sprintf( windowtitle, "%lD Nachrichten auslagern...", mmcount );
  1945.     ogw = ogreInitWindow( scr, 0, 0, windowtitle );
  1946.     ogreAddGroup( ogw, 0 | OGGP_EXPANDSTRING, OGFRAME_OUTLINE, " Parameter " );
  1947.     ogreAddCycle( ogw, 0, 'd', "_Dateien", DX_MODE, dx_options, 28, xmode );
  1948.     ogreAddCheckbox( ogw, 1, 'h', "mit _Header auslagern", DX_HEADER, xheader );
  1949.     ogreAddString( ogw, 2, 'p', "_Pfad:", DX_DIR, xpath, 30, 128 );
  1950.     ogreAddButton( ogw, 2 | OGGP_KEEPSIZE, 'P', "?", DX_DIRSEL );
  1951.  
  1952.     ogreAddGroup( ogw, 1, OGFRAME_NONE, NULL );
  1953.     ogreAddButton( ogw, 0 | OGB_ONENTER, 'o', "_OK", DX_OK );
  1954.     ogreAddHelp( ogw, 0 );
  1955.     ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", DX_CANCEL );
  1956.  
  1957.     iw = ogreOpenWindow( ogw );
  1958.     if( !iw )
  1959.     {
  1960.         unlockwindow();
  1961.         return;
  1962.     }
  1963.  
  1964.     while( !Done )
  1965.     {
  1966.         ogreEnable( ogw, xmode, DX_DIR, DX_DIRSEL, 0 );
  1967.  
  1968.         im = ogreWaitIM( ogw );
  1969.         if( im->Class == IDCMP_GADGETHELP)
  1970.             showguidenum( "excludewin_gads", im->Code );
  1971.         else if( im->Class == IDCMP_GADGETUP )
  1972.         {
  1973.             switch( im->Code )
  1974.             {
  1975.                 case DX_MODE:
  1976.                     xmode = ogreValue( ogw, DX_MODE );
  1977.                     break;
  1978.  
  1979.                 case DX_OK:
  1980.                     if( xmode == 2 )
  1981.                     {
  1982.                         BPTR lock;
  1983.  
  1984.                         ogreCopyStringValue( ogw, DX_DIR, xpath );
  1985.                         if( lock = Lock( xpath, SHARED_LOCK ) )
  1986.                         {
  1987.                             struct FileInfoBlock *fib = allocfib();
  1988.                             int isdir;
  1989.                             Examine( lock, fib );
  1990.                             isdir = fib->fib_DirEntryType > 0;
  1991.                             UnLock( lock );
  1992.                             freefib( fib );
  1993.                             if( isdir )
  1994.                             {
  1995.                                 askreq( "Beim gesammelten Auslagern in eine Datei\nmⁿssen Sie einen Dateinamen angeben!", "Abbruch" );
  1996.                                 break;
  1997.                             }
  1998.                         }
  1999.                     }
  2000.  
  2001.                     Done = 2;
  2002.                     break;
  2003.  
  2004.                 case DX_CANCEL:
  2005.                     Done = 1;
  2006.                     break;
  2007.  
  2008.                 case DX_DIRSEL:
  2009.                     if( xmode == 1 )
  2010.                         newdofrseldir( ogw, DX_DIR, "Auslagerpfad:" );
  2011.                     else
  2012.                         newdofrselfile( ogw, DX_DIR, "Auslagerdatei:" );
  2013.                     break;
  2014.             }
  2015.         }
  2016.         ogreIMReply( ogw, im );
  2017.     }
  2018.  
  2019.     xmode = ogreValue( ogw, DX_MODE );
  2020.     xheader = ogreValue( ogw, DX_HEADER );
  2021.     ogreCopyStringValue( ogw, DX_DIR, xpath );
  2022.  
  2023.     if( Done == 2 )
  2024.     {
  2025.         savesel();
  2026.         switch( xmode )
  2027.         {
  2028.             case 0:
  2029.                 while( n->n.mln_Succ )
  2030.                 {
  2031.                     if( n->sel )
  2032.                     {
  2033.                         doextractmail( n, xheader );
  2034.                         n->sel = 0;
  2035.                     }
  2036.                     n = ( struct vmail * ) n->n.mln_Succ;
  2037.                 }
  2038.                 break;
  2039.  
  2040.             case 1:
  2041.                 while( n->n.mln_Succ )
  2042.                 {
  2043.                     if( n->sel )
  2044.                     {
  2045.                         doextractmailquiet( n, xpath, xheader );
  2046.                         n->sel = 0;
  2047.                     }
  2048.                     n = ( struct vmail * ) n->n.mln_Succ;
  2049.                 }
  2050.                 break;
  2051.  
  2052.             case 2:
  2053.                 rc = fileexistsreq( xpath );
  2054.                 if( rc == 1 )
  2055.                     DeleteFile( xpath );
  2056.                 else if( !rc )
  2057.                     break;
  2058.  
  2059.                 while( n->n.mln_Succ )
  2060.                 {
  2061.                     if( n->sel )
  2062.                     {
  2063.                         struct msghandle *msg = msg_openv( n );
  2064.                         excludemailquiet( msg, xpath, xheader, n->m->m.flags & MMF_BIN, TRUE );
  2065.                         msg_close( msg );
  2066.                         n->sel = 0;
  2067.                     }
  2068.                     n = ( struct vmail * ) n->n.mln_Succ;
  2069.                 }
  2070.                 break;
  2071.         }
  2072.     }
  2073.  
  2074.     ogreExitWindow( ogw );
  2075.     unlockwindow();
  2076.  
  2077.     return;
  2078. }
  2079.  
  2080. static void doviewmsg(void)
  2081. {
  2082.     iteratemsglist( doviewmail );
  2083. }
  2084.  
  2085. void freeinhalt(void)
  2086. {
  2087.     if(mix)
  2088.     {
  2089.         preport( 1, 1, "Speichere Brettindex..." );
  2090.         freemlist();
  2091.         savebrettix(mix,cmb);
  2092.         freebrettix(mix);
  2093.         mix=0;
  2094.     }
  2095. }
  2096.  
  2097.  
  2098.  
  2099. static void dofold(int mode)
  2100. {
  2101.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  2102.  
  2103.     /*rtSetWaitPointer(w);*/
  2104.  
  2105.     mix->changed=1;
  2106.  
  2107.     if( mode == 3 )
  2108.     {
  2109.         n = (struct vmail *) GetEntry( &mlist, getscrollercurrent() );
  2110.         if( !n )
  2111.             return;
  2112.         n = findparentmail( n );
  2113.         if( !n )
  2114.             return;
  2115.         n->m->m.flags ^= MMF_FOLD;
  2116.         lastmailnum = GetEntryNum( &mlist, (struct Node *) n );
  2117.  
  2118.         return;
  2119.     }
  2120.  
  2121.     if(mode)
  2122.     {
  2123.         while(n->n.mln_Succ)
  2124.         {
  2125.             if(mode==1 && !n->m->parent && n->m->firstbez )
  2126.                 n->m->m.flags |= MMF_FOLD;
  2127.             else
  2128.                 n->m->m.flags &= ~MMF_FOLD;
  2129.             n=(struct vmail*)n->n.mln_Succ;
  2130.         }
  2131.         return;
  2132.     }
  2133.  
  2134.     if(!mmcount)
  2135.     {
  2136.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  2137.         if( n )
  2138.             n->m->m.flags^=MMF_FOLD;
  2139.         return;
  2140.     }
  2141.     savesel();
  2142.     while(n->n.mln_Succ)
  2143.     {
  2144.         if(n->sel)
  2145.         {
  2146.             n->m->m.flags^=MMF_FOLD;
  2147.             n->sel=0;
  2148.         }
  2149.         n=(struct vmail*)n->n.mln_Succ;
  2150.     }
  2151. }
  2152.  
  2153. static void removekilled( struct mindex *mix )
  2154. {
  2155.     struct mmail *m = ( struct mmail * )mix->maillist.lh_Head, *next;
  2156.  
  2157.     while( next = ( struct mmail * ) m->n.mln_Succ )
  2158.     {
  2159.         if( m->m.flags & MMF_KILL )
  2160.             Remove( m );
  2161.         m = next;
  2162.     }
  2163. }
  2164.  
  2165. static void dokillthread(struct mmail *n,int deep, FILE *f)
  2166. {
  2167.     struct msghandle *msg;
  2168.     struct hlist *hlist;
  2169.     struct header *hl;
  2170.  
  2171.     rtSetWaitPointer(w);
  2172.     n->m.flags |= MMF_KILL;
  2173.     mix->changed = 1;
  2174.  
  2175.     msg = msg_open( n->m.pufferID, n->m.mailID );
  2176.     if( !msg )
  2177.         return;
  2178.  
  2179.     hlist = msg_loadheader( msg );
  2180.     hl = hl_findheader( hlist, "MID" );
  2181.     if( hl )
  2182.     {
  2183.         if( !f )
  2184.             addmke( hl->data );
  2185.         else
  2186.         {
  2187.             long t;
  2188.             time( &t );
  2189.             fwrite( &t, 4, 1, f );
  2190.             fprintf( f, "%s\n", hl->data );
  2191.         }
  2192.     }
  2193.  
  2194.     hl_freeheader( hlist );
  2195.     msg_close( msg );
  2196.  
  2197.     Remove( n );
  2198.  
  2199.     if(n->firstbez)
  2200.         dokillthread(n->firstbez,1,f);
  2201.     if(deep && n->bezlink)
  2202.         dokillthread(n->bezlink,1,f);
  2203. }
  2204.  
  2205. static int killthread(void)
  2206. {
  2207.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  2208.     FILE *f;
  2209.  
  2210.     if( !mmcount && !GetNumEntries( &mlist ) )
  2211.     {
  2212.         displaybeep();
  2213.         return( 0 );
  2214.     }
  2215.  
  2216.     if( !askreq(
  2217.         "WARNUNG! %lD Thread%s wirklich killen?\nDie Nachrichten und alle Antworten darauf werden\ngel÷scht und k÷nnen nicht mehr restauriert werden!",
  2218.         "Killen|Abbruch",
  2219.             mmcount ? mmcount : 1,
  2220.             mmcount > 1 ? "s" : "") )
  2221.         return(0);
  2222.  
  2223.     pushhomedir();
  2224.     f = fopen("microdot.kill","a");
  2225.     if(!f) f=fopen("microdot.kill","w");
  2226.     popdir();
  2227.  
  2228.     rtSetWaitPointer(w);
  2229.     mix->changed=1;
  2230.     if( !mmcount )
  2231.     {
  2232.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  2233.         dokillthread( n->m, 0, f );
  2234.         if( f )
  2235.             fclose( f );
  2236.         n->m->m.flags|=MMF_KILL;
  2237.         removekilled( mix );
  2238.         return(-1);
  2239.     }
  2240.     savesel();
  2241.     while( n->n.mln_Succ )
  2242.     {
  2243.         if( n->sel )
  2244.         {
  2245.             dokillthread(n->m,0,f);
  2246.             n->sel=0;
  2247.         }
  2248.         n=(struct vmail*)n->n.mln_Succ;
  2249.     }
  2250.     if( f )
  2251.         fclose( f );
  2252.     removekilled( mix );
  2253.     return(-1);
  2254. }
  2255.  
  2256. static long inhaltscstate;
  2257.  
  2258. static void domarkseen(void)
  2259. {
  2260.     struct mmail *mm=(struct mmail*)mix->maillist.lh_Head;
  2261.     long nc=0;
  2262.     int onlyread = prefs.flags2 & MDF2_ESCCLRONLYREAD;
  2263.  
  2264.     while(mm->n.mln_Succ)
  2265.     {
  2266.         if( mm->m.flags & MMF_UNSEEN )
  2267.         {
  2268.             if( !onlyread || ( mm->m.flags & MMF_READ ) )
  2269.             {
  2270.                 mm->m.flags &= ~MMF_UNSEEN;
  2271.                 mix->changed = 1;
  2272.             }
  2273.         }
  2274.  
  2275.         if(mm->m.flags & ( MMF_SHOW | MMF_UNSEEN ) )
  2276.             nc++;
  2277.  
  2278.         mm=(struct mmail*)mm->n.mln_Succ;
  2279.     }
  2280.     cmb->b.newmails = nc;
  2281. }
  2282.  
  2283. static int newinfold(struct mmail *m)
  2284. {
  2285.     while(m && m->n.mln_Succ)
  2286.     {
  2287.         if(m->m.flags&(MMF_SHOW|MMF_UNSEEN)) return(-1);
  2288.         if(m->firstbez) if(newinfold(m->firstbez)) return(-1);
  2289.         m=m->bezlink;
  2290.     }
  2291.     return(0);
  2292. }
  2293.  
  2294. /* nΣchste neue suchen */
  2295. static struct vmail *fnvm(struct vmail *vm)
  2296. {
  2297.     if( vm )
  2298.         vm=(struct vmail*)vm->n.mln_Succ;
  2299.     while(vm && vm->n.mln_Succ) {
  2300.         if(vm->m->m.flags&(MMF_UNSEEN|MMF_SHOW)||(vm->m->m.flags&MMF_FOLD&&newinfold(vm->m->firstbez)))
  2301.         {
  2302.             return(vm);
  2303.         }
  2304.         vm=(struct vmail*)vm->n.mln_Succ;
  2305.     }
  2306.     return(0);
  2307. }
  2308.  
  2309. static char *findnextboardwithnewmails( struct mbrett *mb )
  2310. {
  2311.     mb = ( struct mbrett * ) mb->n.ln_Succ;    
  2312.     while( mb && mb->n.ln_Succ )
  2313.     {
  2314.         if( mb->b.newmails && strncmp( mb->b.name, "/╗", 2 ) )
  2315.             return( mb->b.name );
  2316.         mb = ( struct mbrett * ) mb->n.ln_Succ;
  2317.     }
  2318.     return( NULL );
  2319. }
  2320.  
  2321.  
  2322. static void domarknew(int mode)
  2323. {
  2324.     struct vmail *vm;
  2325.     int didchange = FALSE;
  2326.  
  2327.     if( mode )
  2328.     {
  2329.         vm=(struct vmail*)mlist.lh_Head;
  2330.         while(vm->n.mln_Succ)
  2331.         {
  2332.             if(vm->m->m.flags&(MMF_UNSEEN|MMF_SHOW))
  2333.                 vm->sel=0xff;
  2334.             vm=(struct vmail*)vm->n.mln_Succ;
  2335.         }
  2336.         displayscroller();
  2337.         return;
  2338.     }
  2339.  
  2340.     /* naechste neue suchen */
  2341.     vm=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  2342.  
  2343.     if( ( prefs.flags2 & MDF2_AUTOCLRNEW ) && vm && ( vm->m->m.flags & MMF_UNSEEN ) )
  2344.     {
  2345.         vm->m->m.flags &= ~ MMF_UNSEEN;
  2346.         mix->changed = 1;
  2347.         didchange = TRUE;
  2348.     }
  2349.  
  2350.     vm=fnvm(vm);
  2351.     if(vm)
  2352.     {
  2353.         setscrollercurrent( GetEntryNum( &mlist, (struct Node*)vm ) );
  2354.         showcurrentitem(); 
  2355.         return;
  2356.     }
  2357.  
  2358.     if( didchange )
  2359.         displaycurrentline();
  2360.  
  2361.     /* Weiterspringen? */
  2362.     if( prefs.flags2 & MDF2_NEXTNEWBOARD )
  2363.     {
  2364.         if( prefs.flags2 & MDF2_NEXTNEWBOARDASK )
  2365.         {
  2366.             char *p = findnextboardwithnewmails( cmb );
  2367.  
  2368.             if( !p )
  2369.             {
  2370.                 askreq( "Keine weiteren neuen Nachrichten\nin diesem Brett.\n\nKeine weiteren Bretter mit neuen Nachrichten.", "Ok" );
  2371.                 return;
  2372.             }
  2373.             if( !askreq( "Keine weiteren neuen Nachrichten\nin diesem Brett. Wollen Sie in das\nnΣchste Brett mit neuen Nachrichten:\n%s\nspringen?",
  2374.                 "Weiterspringen|Stopp", p
  2375.             ))
  2376.             return;
  2377.         }
  2378.  
  2379.         donextnewboard = TRUE;
  2380.     }
  2381.     else displaybeep();
  2382. }
  2383.  
  2384. static void domarknextunread(void)
  2385. {
  2386.     struct vmail *vm;
  2387.  
  2388.     /* naechste neue suchen */
  2389.     vm=(struct vmail*)GetEntry( &mlist, getscrollercurrent() );
  2390.     vm=findnextunread(vm);
  2391.     if(vm)
  2392.     {
  2393.         setscrollercurrent(GetEntryNum(&mlist,(struct Node*)vm));
  2394.         showcurrentitem(); 
  2395.         return;
  2396.     }
  2397.     else
  2398.         displaybeep();
  2399. }
  2400.  
  2401. static void doinvsel(void)
  2402. {
  2403.     struct vmail *vm=(struct vmail*)mlist.lh_Head;
  2404.  
  2405.     while(vm->n.mln_Succ)
  2406.     {
  2407.         vm->sel ^= 0xff;
  2408.         vm=(struct vmail*)vm->n.mln_Succ;
  2409.     }
  2410.  
  2411. }
  2412.  
  2413. #define SR_DO 1
  2414. #define SR_CANCEL 2
  2415. #define SR_USEABS 3
  2416. #define SR_ABS 4
  2417. #define SR_USEBET 5
  2418. #define SR_BET 6
  2419. #define SR_USEIN 7
  2420. #define SR_IN 8
  2421. #define SR_INFO 9
  2422. #define SR_FG 10
  2423.  
  2424. void expandpattern( char *from, char *to )
  2425. {
  2426.     while( *from )
  2427.     {
  2428.         if( *from == '*'á)
  2429.         {
  2430.             *to++ = '#';
  2431.             *to++ = '?';
  2432.         }
  2433.         else *to++ = *from;
  2434.         from++;
  2435.     }
  2436.     *to = 0;
  2437. }
  2438.  
  2439. static int matchmailcontents( struct msghandle *msg, char *pattern, BOOL matchheader, BOOL matchcomment )
  2440. {
  2441.     UBYTE maildata[ 1024 ];
  2442.     int rc = 0;
  2443.     int what = MC_DATA;
  2444.  
  2445.     if( matchcomment )
  2446.         what |= MC_COMMENT;
  2447.     if( matchheader )
  2448.         what |= MC_HEADER;
  2449.  
  2450.     msg_initread( msg, what );
  2451.  
  2452.     maildata[á1023 ]á= 0;
  2453.     while( msg_read( msg, maildata, 1023 ) )
  2454.     {
  2455.         rc |= astcsma( maildata, pattern );
  2456.     }
  2457.  
  2458.     msg_endread( msg );
  2459.  
  2460.     return( rc );
  2461. }
  2462.  
  2463. static void domarkbyabsender(struct IntuiMessage *im)
  2464. {
  2465.     struct vmail *vm=(struct vmail*)mlist.lh_Head;
  2466.     struct ogwin *ogw;
  2467.     struct Window *iw;
  2468.     static BYTE use_abs, use_bet, use_inhalt;
  2469.     int Done = FALSE;
  2470.     static char inhalt[á128 ];
  2471.     char betpat[ 64 ];
  2472.     char abspat[ 64 ];
  2473.     char inpat[ 256 ];
  2474.     int counter = 0;
  2475.     int mark1, mark2, mark3;
  2476.  
  2477.     if( ISSHIFT( im ) )
  2478.     {
  2479.         while( vm->n.mln_Succ )
  2480.         {
  2481.             vm->sel = 0x0ff;
  2482.             vm = ( struct vmail * ) vm->n.mln_Succ;
  2483.         }
  2484.         return;
  2485.     }
  2486.  
  2487.     vm = ( struct vmail* ) GetEntry( &mlist, getscrollercurrent() );
  2488.  
  2489.     /*if(vm) strcpy(absender,vm->m->m.absender);*/
  2490.  
  2491.     ogw = ogreInitWindow( scr, 0, 0, "Nach Muster suchen" );
  2492.     ogreAddGroup( ogw, 0, OGFRAME_OUTLINE, " Muster " );
  2493.     ogreAddCheckbox( ogw, 0, 'b', "A_bsenderfilter?", SR_USEABS, use_abs );
  2494.     ogreAddString( ogw, 0, 'B', "", SR_ABS, vm ? vm->m->m.absender : "", 32, 32 );
  2495.     ogreAddCheckbox( ogw, 1, 't', " Be_treffilter?", SR_USEBET, use_bet );
  2496.     ogreAddString( ogw, 1, 'T', "", SR_BET, vm ? vm->m->m.betreff: "", 32, 32 );
  2497.     ogreAddCheckbox( ogw, 2, 'i', " _Inhaltsfilter?", SR_USEIN, use_inhalt );
  2498.     ogreAddString( ogw, 2, 'I', "", SR_IN, inhalt, 32, 128 );
  2499.  
  2500.     ogreAddGroup( ogw, 1 | OGGP_EXPANDSTRING, OGFRAME_OUTLINE, " Ergebnis " );
  2501.     ogreAddText( ogw, 0, "Nachricht:", SR_INFO, "", 32, 1 );
  2502.     ogreAddFuelGauge( ogw, 1, SR_FG, GetNumEntries( &mlist ) );
  2503.  
  2504.     ogreAddGroup( ogw, 2, OGFRAME_NONE, NULL );
  2505.     ogreAddButton( ogw, 0 | OGB_ONENTER, 's', "_Suche starten", SR_DO );
  2506.     ogreAddHelp( ogw, 0 );
  2507.     ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", SR_CANCEL );
  2508.  
  2509.     iw = ogreOpenWindow( ogw );
  2510.     if( !iw )
  2511.     {
  2512.         return;
  2513.     }
  2514.  
  2515.     while( !Done )
  2516.     {
  2517.         use_abs = ogreValue( ogw, SR_USEABS );
  2518.         use_bet = ogreValue( ogw, SR_USEBET );
  2519.         use_inhalt = ogreValue( ogw, SR_USEIN );
  2520.  
  2521.         ogreEnable( ogw, use_abs, SR_ABS, 0 );
  2522.         ogreEnable( ogw, use_bet, SR_BET, 0 );
  2523.         ogreEnable( ogw, use_inhalt, SR_IN, 0 );
  2524.  
  2525.         ogreEnable( ogw, use_abs || use_bet || use_inhalt, SR_DO, 0 );
  2526.  
  2527.         im = ogreWaitIM( ogw );
  2528.  
  2529.         if( im->Class == IDCMP_GADGETHELP)
  2530.             showguidenum( "brettsuchreq_gads", im->Code );
  2531.         else if( im->Class == GADGETUP )
  2532.         {
  2533.             switch( im->Code )
  2534.             {
  2535.                 case SR_DO:
  2536.                     Done = 2;
  2537.                     break;
  2538.  
  2539.                 case SR_CANCEL:
  2540.                     Done = 1;
  2541.                     break;
  2542.             }
  2543.         }
  2544.  
  2545.         ogreIMReply( ogw, im );
  2546.     }
  2547.  
  2548.     if( Done == 2 )
  2549.     {
  2550.         vm = (struct vmail*)mlist.lh_Head;
  2551.  
  2552.         ogreEnable( ogw, FALSE, SR_DO, SR_ABS, SR_BET, SR_IN, SR_USEABS, SR_USEBET, SR_USEIN, 0 );
  2553.         ogreCopyStringValue( ogw, SR_IN, inhalt );
  2554.  
  2555.         expandpattern( ogreStringValue( ogw, SR_ABS ), abspat );
  2556.         expandpattern( ogreStringValue( ogw, SR_BET ), betpat );
  2557.         expandpattern( ogreStringValue( ogw, SR_IN ), inpat );
  2558.  
  2559.         strcat( abspat, "#?" );
  2560.         strcat( betpat, "#?" );
  2561.         strcat( inpat, "#?" );
  2562.         strins( inpat, "#?" );
  2563.  
  2564.         Done = FALSE;
  2565.  
  2566.         while( !Done && vm->n.mln_Succ )
  2567.         {
  2568.             if( im = ogreIM( ogw ) )
  2569.             {
  2570.                 if( ( im->Class == IDCMP_GADGETUP )    && ( im->Code == SR_CANCEL ) )
  2571.                     Done = TRUE;
  2572.                 ogreIMReply( ogw, im );
  2573.             }
  2574.  
  2575.             ogreSetStringValue( ogw, SR_INFO, vm->m->m.betreff );
  2576.             mark1 = mark2 = mark3 = FALSE;
  2577.             if( use_abs )
  2578.             {
  2579.                 if( astcsma( vm->m->m.absender, abspat ) )
  2580.                     mark1 = TRUE;
  2581.             }
  2582.             else
  2583.                 mark1 = TRUE;
  2584.  
  2585.             if( use_bet )
  2586.             {
  2587.                 if( astcsma( vm->m->m.betreff, betpat ) )
  2588.                     mark2 = TRUE;
  2589.             }
  2590.             else
  2591.                 mark2 = TRUE;
  2592.  
  2593.             if( use_inhalt )
  2594.             {
  2595.                 struct msghandle *msg = msg_openv( vm );
  2596.                 if( matchmailcontents( msg, inpat, 0, 0 ) )
  2597.                     mark3 = TRUE;
  2598.                 msg_close( msg );
  2599.             }
  2600.             else
  2601.                 mark3 = TRUE;
  2602.  
  2603.             if( mark1 && mark2 && mark3 )
  2604.                 vm->sel = 0xff;
  2605.             vm = ( struct vmail * ) vm->n.mln_Succ;
  2606.             ogreSetValue( ogw, SR_FG, counter++ );
  2607.         }
  2608.     }
  2609.  
  2610.     ogreExitWindow( ogw );
  2611.  
  2612. }
  2613.  
  2614. static struct vmail *findfup2(struct IntuiMessage *im,struct vmail *vm)
  2615. {
  2616.     struct mmail *m;
  2617.  
  2618.     if(!vm) { displaybeep(); return(0); }
  2619.     m=vm->m;
  2620.  
  2621.     if((im->Code==0x4e||im->Code==0x2f) && !ISSHIFT(im)) {
  2622.         vm=findvmail(m->bezlink);
  2623.         return(vm);
  2624.     }
  2625.     else if((im->Code==0x4e||im->Code==0x2f) && ISSHIFT(im)) {
  2626.         vm=findvmail(m->firstbez);
  2627.         return(vm);
  2628.     }
  2629.     else if((im->Code==0x4f||im->Code==0x2d) && !ISSHIFT(im)) {
  2630.         while(vm->n.mln_Pred && vm->m->bezlink!=m) vm=(struct vmail*)vm->n.mln_Pred;
  2631.         if(!vm->n.mln_Pred || vm->m->bezlink!=m) vm=0;
  2632.         return(vm);
  2633.     }
  2634.     else if((im->Code==0x4f||im->Code==0x2d) && ISSHIFT(im)) {
  2635.         vm=findvmail(m->parent);
  2636.         return(vm);
  2637.     }
  2638. }
  2639.  
  2640. static void findfup(struct IntuiMessage *im)
  2641. {
  2642.     struct vmail *vm=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  2643.  
  2644.     vm=findfup2(im,vm);
  2645.     if(vm) {
  2646.         int rc=GetEntryNum(&mlist,(struct Node*)vm);
  2647.         setscrollercurrent(rc);
  2648.         showcurrentitem();
  2649.     }
  2650. }
  2651.  
  2652. static void doarcmail( struct vmail *n )
  2653. {
  2654.     struct mbrett *mb=findbrett("/╗ARCHIV",0);
  2655.  
  2656.     storemail2ix( &n->m->m, mb, NULL );
  2657. }
  2658.  
  2659. static void doarcmsg(void)
  2660. {
  2661.     iteratemsglist( doarcmail );
  2662. }
  2663.  
  2664. static void addusertouserlist(char *user,char *teflon, char *post, char *pgpid, BOOL pgp )
  2665. {
  2666.     char username[128];
  2667.     char realname[40];
  2668.     struct user u,u2;
  2669.     FILE *f;
  2670.     char *p,*p2;
  2671.  
  2672.     pushhomedir();
  2673.  
  2674.     realname[0]=realname[39]=0;
  2675.     username[127]=0;
  2676.     strncpy(username,user,127);
  2677.     p=strchr(username,' ');
  2678.     if(p) {
  2679.         *p++=0;
  2680.         p=strchr(p,'(');
  2681.         if(p) {
  2682.             *p++=0;
  2683.             p=stpblk(p);
  2684.             p2=strchr(p,')');
  2685.             if(p2) *p2=0;
  2686.             strncpy(realname,p,39);
  2687.         }
  2688.     }
  2689.  
  2690.     if(!realname[0]) strncpy(realname,username,39);
  2691.  
  2692.     memset(&u,0,sizeof(struct user));
  2693.     strcpy(u.net,username);
  2694.     strcpy(u.realname,realname);
  2695.     if( teflon )
  2696.         strncpy(u.telefon,teflon,31);
  2697.     if( post ) 
  2698.         strncpy( u.adresse, post, 63 );
  2699.     if( pgpid )
  2700.         strncpy( u.pgp_id, pgpid, 39 );
  2701.  
  2702.     //if( pgp && pgpavail )
  2703.     //    u.flags |= UF_PGP;
  2704.  
  2705.     f=fopen("microdot.userdb","r");
  2706.     if(f) {
  2707.         fsetbuf(f,8192);
  2708.         while(fread(&u2,sizeof(struct user),1,f)==1) {
  2709.             if(!stricmp(u2.net,username))
  2710.             {
  2711.                 fclose(f);
  2712.                 displaybeep();
  2713.                 popdir();
  2714.                 return;
  2715.             }
  2716.         }
  2717.         fclose(f);
  2718.     }
  2719.     f=fopen("microdot.userdb","a+");
  2720.     popdir();
  2721.     if(!f)
  2722.     {
  2723.         displaybeep();
  2724.         return;
  2725.     }
  2726.     fwrite(&u,sizeof(struct user),1,f);
  2727.     fclose(f);
  2728. }
  2729.  
  2730. static void dosaveuser(struct vmail *n)
  2731. {
  2732.     struct header *hl,*hl2, *hl3;
  2733.     struct hlist *hlist;
  2734.     struct msghandle *msg;
  2735.     int usepgp;
  2736.  
  2737.     msg = msg_openv( n );
  2738.     if( !msg )
  2739.         return;
  2740.  
  2741.     usepgp = n->m->m.flags & ( MMF_PGPSIGNED | MMF_PGPCRYPT );
  2742.  
  2743.     hlist = msg_loadheader( msg );
  2744.     msg_close( msg );
  2745.     hl = hl_findheader( hlist, "ABS");
  2746.     if(!hl || !hl->data || !hl->data[0])
  2747.     {
  2748.         hl_freeheader( hlist );
  2749.         displaybeep();
  2750.         return;
  2751.     }
  2752.  
  2753.     hl2 = hl_findheader( hlist, "TELEFON");
  2754.     hl3 = hl_findheader( hlist, "POST" );
  2755.     if( !usepgp )
  2756.     {
  2757.         if( hl_findheader( hlist, "PGP-KEY-AVAIL" ) || hl_findheader( hlist, "PGP-PUBLIC-KEY" ) )
  2758.             usepgp = TRUE;
  2759.     }
  2760.  
  2761.     addusertouserlist(
  2762.         hl->data,
  2763.         (hl2&&hl2->data)?hl2->data:NULL,
  2764.         (hl3&&hl3->data)?hl3->data:NULL,
  2765.         NULL,
  2766.         usepgp ? TRUE : FALSE
  2767.     );
  2768.  
  2769.     hl_freeheader( hlist );
  2770. }
  2771.  
  2772. static void dokilluser(struct vmail *n)
  2773. {
  2774.     struct header *hl;
  2775.     FILE *f;
  2776.     int rc;
  2777.  
  2778.     struct hlist *hlist;
  2779.     struct msghandle *msg;
  2780.  
  2781.     msg = msg_openv( n );
  2782.     if( !msg )
  2783.         return;
  2784.  
  2785.     hlist = msg_loadheader( msg );
  2786.     msg_close( msg );
  2787.     hl = hl_findheader( hlist, "ABS");
  2788.     if(!hl || !hl->data || !hl->data[0])
  2789.     {
  2790.         hl_freeheader( hlist );
  2791.         displaybeep();
  2792.         return;
  2793.     }
  2794.  
  2795.     rc = askreq( "Wollen Sie User\n%s\nwirklich filtern?\nAlle Nachrichten mit diesem Absender\nwerden dann in Zukunft nicht mehr\neinsortiert, sondern sofort gel÷scht.", 
  2796.         "User filtern|Abbruch",
  2797.         hl->data
  2798.     );
  2799.  
  2800.     if( !rc )
  2801.     {
  2802.         hl_freeheader( hlist );
  2803.         return;
  2804.     }
  2805.  
  2806.     f = fopen( "microdot.killuser", "a" );
  2807.     if( !f )
  2808.         f = fopen( "microdot.killuser", "w" );
  2809.     if( !f )
  2810.     {
  2811.         displaybeep();
  2812.         hl_freeheader( hlist );
  2813.         return;
  2814.     }
  2815.     fprintf( f, "%s\n", hl->data );
  2816.     fclose( f );
  2817.     hl_freeheader( hlist );
  2818. }
  2819.  
  2820. static void dosaveusers(void)
  2821. {
  2822.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  2823.     int count=0;
  2824.  
  2825.     if(!mmcount)
  2826.     {
  2827.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  2828.         dosaveuser(n);
  2829.         return;
  2830.     }
  2831.     savesel();
  2832.     while(n->n.mln_Succ) {
  2833.         if(n->sel) {
  2834.             dosaveuser(n);
  2835.             n->sel=0;
  2836.             count++;
  2837.         }
  2838.         n=(struct vmail*)n->n.mln_Succ;
  2839.     }
  2840.     preport(1,1,"%lD User gespeichert.",count);
  2841. }
  2842.  
  2843. #define GID_LV 1
  2844. #define GID_EMPS 2
  2845. #define GID_LVNEU 3
  2846. #define GID_LVBRETT 4
  2847. #define GID_LVUSER 5
  2848. #define GID_LVLOESCH 6
  2849. #define GID_SEND 7
  2850. #define GID_CANCEL 8
  2851.  
  2852. static char ** getemplist( char *title )
  2853. {
  2854.     struct IntuiMessage *im;
  2855.     struct ogwin *ogw;
  2856.     struct ogrevn *vn;
  2857.     struct Window *iw;
  2858.     int Done = FALSE;
  2859.     int isediting = -1;
  2860.     int c;
  2861.     int size;
  2862.     char **emp = NULL;
  2863.     char *store, *p;
  2864.     APTR rtwinlock;
  2865.  
  2866.     ogw = ogreInitWindow( scr, WFLG_RMBTRAP, 0, title );
  2867.  
  2868.     ogreAddGroup( ogw, 0 | OGGP_EXPANDSTRING , OGFRAME_OUTLINE, " EmpfΣnger " );
  2869.     ogreAddList( ogw, 0, 0xff, NULL, GID_LV, 40, 8, 0, NULL );
  2870.     ogreLVInit( ogw, GID_LV );
  2871.  
  2872.     ogreAddString( ogw, 1, '\n', NULL, GID_EMPS, NULL, 40, 256 | OGSF_NONEXTACT );
  2873.     ogreAddButton( ogw, 2, 'n', "_Neu", GID_LVNEU );
  2874.     ogreAddButton( ogw, 2, 'b', "_Brett", GID_LVBRETT );
  2875.     ogreAddButton( ogw, 2, 'u', "_UserIn", GID_LVUSER );
  2876.     ogreAddButton( ogw, 2, 'l', "_L÷schen", GID_LVLOESCH );
  2877.  
  2878.     ogreAddGroup( ogw, 1 | OGGP_EXPANDSTRING, OGFRAME_NONE, NULL );
  2879.  
  2880.     ogreAddButton( ogw, 0 | OGB_ONENTER, 'v', "_Verschicken", GID_SEND );
  2881.     ogreAddHelp( ogw, 0 );
  2882.     ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", GID_CANCEL );
  2883.  
  2884.     iw = ogreOpenWindow( ogw );
  2885.     if( !iw )
  2886.     {
  2887.         return( 0 );
  2888.     }
  2889.  
  2890.     while( !Done )
  2891.     {
  2892.         ogreEnable( ogw, isediting >= 0, GID_EMPS, GID_LVLOESCH, 0 );
  2893.         mWaitPort( iw->UserPort );
  2894.         while( ( im = ogreIM( ogw ) ) )
  2895.         {
  2896.             if( im->Class == IDCMP_GADGETHELP)
  2897.                 showguidenum( "getemps_gads", im->Code );
  2898.             else if( im->Class == GADGETUP )
  2899.             {
  2900.                 switch( im->Code )
  2901.                 {
  2902.                     case GID_EMPS:
  2903.                         if( isediting >= 0 )
  2904.                         {
  2905.                             ogreLVSelect( ogw, GID_LV, -1 );
  2906.                             ogreLVSetEntry( ogw, GID_LV, isediting, ogreStringValue( ogw, GID_EMPS ), 2 );
  2907.                             ogreLVRefresh( ogw, GID_LV );                    
  2908.                             isediting = -1;
  2909.                             ogreSetStringValue( ogw, GID_EMPS, "" );
  2910.                         }
  2911.                         break;
  2912.  
  2913.                     case GID_LV:
  2914.                         isediting = ogreValue( ogw, GID_LV );
  2915.                         vn = ogreLVGetEntry( ogw, GID_LV, isediting );
  2916.                         if( vn )
  2917.                         {
  2918.                             ogreEnable( ogw, TRUE, GID_EMPS, 0 );
  2919.                             ogreSetStringValue( ogw, GID_EMPS, vn->txt );
  2920.                             if( im->Qualifier )
  2921.                                 ogreActivate( ogw, GID_EMPS );
  2922.                         }
  2923.                         break;
  2924.  
  2925.                     case GID_LVLOESCH:
  2926.                         if( isediting >= 0 )
  2927.                         {
  2928.                             ogreLVRemEntry( ogw, GID_LV, isediting );
  2929.                             ogreLVRefresh( ogw, GID_LV );
  2930.                             isediting = -1;
  2931.                             ogreSetStringValue( ogw, GID_EMPS, "" );
  2932.                         }
  2933.                         break;
  2934.  
  2935.                     case GID_LVBRETT:
  2936.                         rtwinlock = rtLockWindow( iw );
  2937.                         p = dobrettreq();
  2938.                         rtUnlockWindow( iw, rtwinlock );
  2939.                         if( p )
  2940.                             goto addent;
  2941.                         break;
  2942.                     
  2943.                     case GID_LVUSER:
  2944.                         rtwinlock = rtLockWindow( iw );
  2945.                         p = douserreq();
  2946.                         rtUnlockWindow( iw, rtwinlock );
  2947.                         if( !p )
  2948.                             break;
  2949.                       addent:
  2950.                         ogreLVAddEntry( ogw, GID_LV, p, 2, 0 );
  2951.                         isediting = -1;
  2952.                         ogreLVSelect( ogw, GID_LV, -1 );
  2953.                         ogreLVRefresh( ogw, GID_LV );
  2954.                         break;
  2955.  
  2956.                     case GID_LVNEU:
  2957.                         isediting = ogreLVAddEntry( ogw, GID_LV, "", 1, 0 );
  2958.                         ogreLVRefresh( ogw, GID_LV );
  2959.                         ogreSetStringValue( ogw, GID_EMPS, "" );
  2960.                         ogreActivate( ogw, GID_EMPS );
  2961.                         break;
  2962.  
  2963.                     case GID_SEND:
  2964.                         Done = 2;
  2965.                         break;
  2966.  
  2967.                     case GID_CANCEL:
  2968.                         Done = 1;
  2969.                         break;
  2970.                 }
  2971.             }
  2972.         }
  2973.     }
  2974.  
  2975.     if( Done == 2 )
  2976.     {
  2977.         /* Calc size */
  2978.         for( size = c = 0; vn = ogreLVGetEntry( ogw, GID_LV, c ); c++ )
  2979.         {
  2980.             size += 5 + strlen( vn->txt );
  2981.         }
  2982.         emp = myAllocVec( size + 4, MEMF_CLEAR );
  2983.         if( emp )
  2984.         {
  2985.             store = ( char * ) &emp[ c + 1 ];
  2986.             for( c = 0; vn = ogreLVGetEntry( ogw, GID_LV, c ); c++ )
  2987.             {
  2988.                 emp[ c ]á= store;
  2989.                 strcpy( store, vn->txt );
  2990.                 store = strchr( store, 0 ) + 1;
  2991.             }
  2992.         }
  2993.     }
  2994.  
  2995.     ogreExitWindow( ogw );
  2996.     return( emp );
  2997. }
  2998.  
  2999. extern int sendwinauto;
  3000. static int doweiter(struct IntuiMessage *im)
  3001. {
  3002.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  3003.     int rc, rv = 0;
  3004.     char **emplist;
  3005.     char buffer[á128 ];
  3006.  
  3007.     if(!mmcount)
  3008.     {
  3009.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  3010.         if(n)
  3011.             rv = doweitermail(n);
  3012.         return( rv );
  3013.     }
  3014.  
  3015.     rc = askreq( "Weiterleiten:\nInsgesamt %lD Nachrichten markiert",
  3016.         "_Einzeln weiterleiten|_Gesammelt weiterleiten|Gesammelt _ohne Nachfrage|Abbruch",
  3017.         mmcount
  3018.     );
  3019.  
  3020.     if( !rc )
  3021.         return( 0 );
  3022.  
  3023.     if( rc == 1 )
  3024.     {
  3025.         savesel();
  3026.         while(n->n.mln_Succ)
  3027.         {
  3028.             if(n->sel)
  3029.             {
  3030.                 rv |= doweitermail(n);
  3031.                 n->sel=0;
  3032.             }
  3033.             n=(struct vmail*)n->n.mln_Succ;
  3034.         }
  3035.         return( rv );
  3036.     }
  3037.  
  3038.     /* Gesammelt weiterleiten */
  3039.  
  3040.     sprintf( buffer, "%lD Nachrichten weiterleiten", mmcount );
  3041.  
  3042.     emplist = getemplist( buffer );
  3043.  
  3044.     if( !emplist )
  3045.         return( 0 );
  3046.  
  3047.     while(n->n.mln_Succ)
  3048.     {
  3049.         savesel();
  3050.         if(n->sel)
  3051.         {
  3052.             if( rc == 3 )
  3053.                 sendwinauto = TRUE;
  3054.             rv |= doweiterquiet( emplist, n );
  3055.             n->sel=0;
  3056.         }
  3057.         n=(struct vmail*)n->n.mln_Succ;
  3058.     }
  3059.  
  3060.     myFreeVec( emplist );
  3061.  
  3062.     return( rv );
  3063. }
  3064.  
  3065. extern int ml_kb, ml_date;
  3066. static char * makekb( int val )
  3067. {
  3068.     static char mem[ 32 ];
  3069.  
  3070.     sprintf( mem, "%lD", val );
  3071.     if( strlen( mem ) <= ml_kb )
  3072.         return( mem );
  3073.  
  3074.     sprintf(mem, "%lDK", ( val + 1023 ) / 1024 );
  3075.     if( strlen( mem ) <= ml_kb )
  3076.         return( mem );
  3077.  
  3078.     sprintf(mem, "%lDM", ( val + ( 1024 * 1024 - 1 ) ) / ( 1024 * 1024 ) );
  3079.     return( mem );
  3080. }
  3081.  
  3082. static void __inline makevnode( struct vmail *n )
  3083. {
  3084.     char x[á8 ], *p;
  3085.     int plen;
  3086.  
  3087.     utunpk( n->m->m.time, x );
  3088.     n->date[á0 ]á= '0'á+ x[á2 ]á/ 10;
  3089.     n->date[á1 ]á= '0'á+ x[á2 ]á% 10;
  3090.     n->date[á2 ]á= '.';
  3091.     n->date[á3 ]á= '0'á+ x[á1 ]á/ 10;
  3092.     n->date[á4 ]á= '0'á+ x[á1 ]á% 10;
  3093.  
  3094.     //sprintf( n->date, "%02ld.%02ld", x[á2 ], x[á1 ]á);
  3095.     if( ml_date == 11 )
  3096.     {
  3097.         utunpk( n->m->m.incomtime, x );
  3098.         //sprintf( &n->date[ 5 ], "\005%02ld.%02ld", x[á2 ], x[á1 ]á);
  3099.         n->date[á5 ]á= 5;
  3100.         n->date[á6 ]á= '0'á+ x[á2 ]á/ 10;
  3101.         n->date[á7 ]á= '0'á+ x[á2 ]á% 10;
  3102.         n->date[á8 ]á= '.';
  3103.         n->date[á9 ]á= '0'á+ x[á1 ]á/ 10;
  3104.         n->date[á10 ]á= '0'á+ x[á1 ]á% 10;
  3105.         n->date[á11 ]á= 0;
  3106.     }
  3107.     else
  3108.         n->date[ 5 ]á= 0;
  3109.  
  3110.     memset( n->kb, 32, 12 );
  3111.     p = makekb( n->m->m.maillen );
  3112.     plen = strlen( p );
  3113.     memcpy( &n->kb[áml_kb - plen ], p, plen );
  3114. }
  3115.  
  3116. void makevnodemlist( struct List *what )
  3117. {
  3118.     struct vmail *n = ( struct vmail * ) what->lh_Head;
  3119.  
  3120.     while( n->n.mln_Succ )
  3121.     {
  3122.         makevnode( n );
  3123.         n = ( struct vmail * ) n->n.mln_Succ;
  3124.     }
  3125. }
  3126.  
  3127.  
  3128. static void attachtree(struct List *to,struct mmail *parent,UBYTE indent,UBYTE *indentspace)
  3129. {
  3130.     struct vmail *n;
  3131.  
  3132.     /* gekillt */
  3133.     if( parent->m.flags & MMF_KILL )
  3134.         return;
  3135. #if 0
  3136.     if( ( prefs.flags & MDF_HIDEDEL ) && ( parent->m.flags & MMF_DEL ) )
  3137.         return;
  3138. #endif
  3139.  
  3140.     /* Eine Muttermehl */
  3141.     n = LibAllocPooled( mlistpool, sizeof( struct vmail ) );
  3142.     if( !n )
  3143.     {
  3144.         displaybeep();
  3145.         return;
  3146.     }
  3147.     n->m = parent;
  3148.     n->indent = indent;
  3149. //    makemmailhash( parent );
  3150.  
  3151.     makevnode( n );
  3152.  
  3153.     // Display-Werte eintragen
  3154.  
  3155.     if( indent )
  3156.     {
  3157.         if( parent->bezlink)
  3158.             indentspace[ indent - 1 ] = 1;
  3159.         else
  3160.             indentspace[ indent - 1 ] = 4;
  3161.     }
  3162.     memcpy( n->indentspace, indentspace, 63 );
  3163.     AddTail( to, ( struct Node * ) n );
  3164.     /* Bezuege auf diese Mail? */
  3165.     if( parent->firstbez && !( n->m->m.flags & MMF_FOLD ) )
  3166.     { 
  3167.         if(parent->bezlink) indentspace[indent-1]=2;
  3168.         else indentspace[indent-1]=32;
  3169.         indentspace[indent]=4;
  3170.         attachtree(to,parent->firstbez,indent+1,indentspace);
  3171.     }
  3172.     if( parent->bezlink )
  3173.     {
  3174.         attachtree( to, parent->bezlink, indent, indentspace );
  3175.     }
  3176.     indentspace[ indent ] = 0;
  3177. }
  3178.  
  3179. static char *skipre( char *txt )
  3180. {
  3181.     txt = stpblk( txt );
  3182.     if( !strnicmp( txt, "re", 2 ) )
  3183.     {
  3184.         char *newtxt = txt + 2;
  3185.         if( *newtxt == '^' )
  3186.         {
  3187.             newtxt++;
  3188.             while( isdigit( *newtxt ) )
  3189.                 newtxt++;
  3190.         }
  3191.         if( *newtxt == ':' )
  3192.         {
  3193.             return( skipre( newtxt + 1 ) );
  3194.         }
  3195.     }
  3196.     return( txt );
  3197. }
  3198.  
  3199. static int __stdargs sortmcmpf(struct mmail **s1,struct mmail **s2)
  3200. {
  3201.     int rc;
  3202.     char *p1=(*s1)->m.betreff;
  3203.     char *p2=(*s2)->m.betreff;
  3204.  
  3205.     rc = strnicmp( &p1[á(*s1)->reoffset ], &p2[á(*s2)->reoffset ], min( strlen( p1 ), strlen( p2 ) ) );
  3206.     if( !rc )
  3207.         rc = ((*s1)->m.time)-((*s2)->m.time);
  3208.     return( rc );
  3209. }
  3210.  
  3211. static int __stdargs sortmcmpf_date( struct mmail **s1, struct mmail **s2 )
  3212. {
  3213.     int rc;
  3214.  
  3215.     rc=((*s1)->m.time)-((*s2)->m.time);
  3216.     if( !rc )
  3217.     {
  3218.         char *p1=(*s1)->m.betreff;
  3219.         char *p2=(*s2)->m.betreff;
  3220.         rc = strnicmp( &p1[á(*s1)->reoffset ], &p2[á(*s2)->reoffset ], min( strlen( p1 ), strlen( p2 ) ) );
  3221.     }
  3222.     return( rc );
  3223. }
  3224.  
  3225. void makemlist(struct List *from,struct List *to)
  3226. {
  3227.     int c,d,count;
  3228.     struct mmail **array,*n=(struct mmail*)from->lh_Head;
  3229.     char indentspace[ 256 ];
  3230.  
  3231.     if( wrotenewmails )
  3232.     {
  3233.         newmailptr = (struct mmail *) from->lh_TailPred;
  3234.     }
  3235.  
  3236.     mlistpool = LibCreatePool( MEMF_CLEAR, 8192, 2048 );
  3237.  
  3238.     memset( indentspace, 0, 256 );
  3239.     NewList(to);
  3240.     count=0;
  3241.     while( n->n.mln_Succ )
  3242.     {
  3243.         n->reoffset = ( skipre( n->m.betreff ) ) - n->m.betreff;
  3244.         if( !n->parent ) count++;
  3245.         n=( struct mmail * ) n->n.mln_Succ;
  3246.     }
  3247.     if( !count )
  3248.         return;
  3249.     array=myAllocVec( 4*count, 0 );
  3250.     if( !array )
  3251.     {
  3252.         displaybeep();
  3253.         return;
  3254.     }
  3255.     n=(struct mmail*)from->lh_Head;
  3256.     for(c=d=0; d<count; c++)
  3257.     {
  3258.         if( !n->parent )
  3259.             array[d++]=n;
  3260.         n=(struct mmail*)n->n.mln_Succ;
  3261.     }
  3262.     qsort(array,count,4,(prefs.flags&MDF_SORTDATE)?sortmcmpf_date:sortmcmpf);
  3263.     for(c=0; c<count; c++) 
  3264.         attachtree( to, array[ c ], 0, indentspace );
  3265.     myFreeVec( array );
  3266. }
  3267.  
  3268. static void dodelfunc( struct vmail * n )
  3269. {
  3270.     n->m->m.flags |= MMF_DEL;
  3271.     if( prefs.flags2 & MDF2_HARDDEL )
  3272.         n->m->m.flags &= ~MMF_ARCHIVE;
  3273. }
  3274.  
  3275. static void dodelmsg(void)
  3276. {
  3277.     int oldmmcount = mmcount;
  3278.  
  3279.     iteratemsglist( dodelfunc );
  3280.  
  3281.     if( oldmmcount )
  3282.     {
  3283.         displayscroller();
  3284.     }
  3285.     else
  3286.     {
  3287.         displaycurrentline();
  3288.         incscroller();
  3289.     }
  3290.  
  3291. }
  3292.  
  3293. static void doholdmsg(int set)
  3294. {
  3295.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  3296.  
  3297.     mix->changed=1;
  3298.     if(!mmcount)
  3299.     {
  3300.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  3301.         if(!set) n->m->m.flags|=MMF_ARCHIVE;
  3302.         else n->m->m.flags&=~MMF_ARCHIVE;
  3303.  
  3304.         displaycurrentline();
  3305.         incscroller();
  3306.     }
  3307.     else
  3308.     {
  3309.         savesel();
  3310.         while(n->n.mln_Succ)
  3311.         {
  3312.             if(n->sel)
  3313.             {
  3314.                 if(!set) n->m->m.flags|=MMF_ARCHIVE;
  3315.                 else n->m->m.flags&=~MMF_ARCHIVE;
  3316.                 n->sel=0;
  3317.             }
  3318.             n=(struct vmail*)n->n.mln_Succ;
  3319.         }
  3320.         displayscroller();
  3321.     }
  3322. }
  3323.  
  3324. static void dosetunread( struct vmail * n )
  3325. {
  3326.     n->m->m.flags &= ~MMF_READ;
  3327. }
  3328.  
  3329.  
  3330. static void dosetreadmsg(int set)
  3331. {
  3332.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  3333.     int oldmmcount = mmcount;
  3334.  
  3335.     mix->changed=1;
  3336.     if(set)
  3337.     {
  3338.         while(n->n.mln_Succ)
  3339.         {
  3340.             if(!(n->m->m.flags&MMF_READ)) n->sel=0xff;
  3341.             n=(struct vmail*)n->n.mln_Succ;
  3342.         }
  3343.         displayscroller();
  3344.         return;
  3345.     }
  3346.  
  3347.     iteratemsglist( dosetunread );
  3348.  
  3349.     if( oldmmcount )
  3350.     {
  3351.         displayscroller();
  3352.     }
  3353.     else
  3354.     {
  3355.         displaycurrentline();
  3356.         incscroller();
  3357.     }
  3358. }
  3359.  
  3360.  
  3361. /* Nachrichten auf Gelesen setzen */
  3362.  
  3363. static void dosetread( struct vmail *n )
  3364. {
  3365.     n->m->m.flags |= MMF_READ;
  3366. }
  3367.  
  3368. static void dosetreadsel( void )
  3369. {
  3370.     int oldmmcount = mmcount;
  3371.  
  3372.     iteratemsglist( dosetread );
  3373.  
  3374.     if( oldmmcount )
  3375.     {
  3376.         displayscroller();
  3377.     }
  3378.     else
  3379.     {
  3380.         displaycurrentline();
  3381.         incscroller();
  3382.     }
  3383.  
  3384. }
  3385.  
  3386. static void dosetnewmsg( void )
  3387. {
  3388.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  3389.  
  3390.     mix->changed=1;
  3391.     if(!mmcount)
  3392.     {
  3393.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  3394.         if(n)
  3395.         {
  3396.             n->m->m.flags |= MMF_SHOW;
  3397.             displaycurrentline();
  3398.             incscroller();
  3399.         }
  3400.         return;
  3401.     }
  3402.     while(n->n.mln_Succ)
  3403.     {
  3404.         if(n->sel) n->m->m.flags |= MMF_SHOW;
  3405.         n=(struct vmail*)n->n.mln_Succ;
  3406.     }
  3407.     displayscroller();
  3408. }
  3409.  
  3410. static void doundelfunc( struct vmail * n )
  3411. {
  3412.     n->m->m.flags &= ~MMF_DEL;
  3413. }
  3414.  
  3415.  
  3416. static void doundelmsg(void)
  3417. {
  3418.     int oldmmcount = mmcount;
  3419.  
  3420.     iteratemsglist( doundelfunc );
  3421.  
  3422.     if( oldmmcount )
  3423.     {
  3424.         displayscroller();
  3425.     }
  3426.     else
  3427.     {
  3428.         displaycurrentline();
  3429.         incscroller();
  3430.     }
  3431.  
  3432. }
  3433.  
  3434. static void *dlistpool;
  3435. static void initdlist(struct List *l)
  3436. {
  3437.     NewList( l );
  3438.     dlistpool = LibCreatePool( MEMF_CLEAR, 8192, 4096 );
  3439. }
  3440.  
  3441. // Puren Text schreiben, aber mit Style-Konvertierung
  3442.  
  3443. static void __stdargs addd(struct List *to,int b,char *txt,...)
  3444. {
  3445.     char buff[ 8192 ];
  3446.     struct dnode *new;
  3447.     int x,x2,offs=0;
  3448.  
  3449.     dofmtextabs(buff,txt,(void*)(((long)&txt)+4));
  3450.     x=strlen(buff);
  3451.  
  3452.     if(!x)
  3453.     {
  3454.         new = LibAllocPooled( dlistpool, sizeof( struct dnode ) );
  3455.         if( !new )
  3456.             return;
  3457.         new->txt = "";
  3458.         AddTail( to, ( struct Node * ) new );
  3459.         return;
  3460.     }        
  3461.  
  3462.     while( x )
  3463.     {
  3464.         x2 = x;
  3465.         if( x2 > screencols )
  3466.             x2 = screencols;
  3467.         x -= x2;
  3468.         new = LibAllocPooled ( dlistpool, sizeof(struct dnode) );
  3469.         if( !new )
  3470.             return;
  3471.         new->txt = LibAllocPooled( dlistpool, x2 + 1 );
  3472.         new->sty = LibAllocPooled( dlistpool, x2 );
  3473.  
  3474.         new->bold = b;
  3475.  
  3476.         if( b == 2 || ( prefs.flags & MDF_NOREADERSTYLES ) )
  3477.         {
  3478.             new->len  = x2;
  3479.             strncpy( new->txt, &buff[ offs ], x2 );
  3480.         }
  3481.         else
  3482.         {
  3483.             stylenode( &buff[áoffs ], x2, new->txt, new->sty );
  3484.             new->len = strlen( new->txt );
  3485.         }
  3486.  
  3487.         AddTail(to,(struct Node*)new);
  3488.         offs += x2;
  3489.     }
  3490. }
  3491.  
  3492. static int getquotelevel( char *txt )
  3493. {
  3494.     int c;
  3495.     char *p = txt;
  3496.  
  3497.     txt = stpblk( txt );
  3498.     if( txt - p > 12 )
  3499.         return( 0 );
  3500.  
  3501.     if( *txt == ':' && isspace( txt[ 1 ]á) )
  3502.     {
  3503.         return( getquotelevel( &txt[á2 ]á) + 1 );
  3504.     }
  3505.     if( *txt == '|'á)
  3506.     {
  3507.         if( isspace( txt[á1 ]á) || txt[ 1 ]á== '>'á)
  3508.             return( getquotelevel( &txt[á2 ] ) + 1 );
  3509.     }
  3510.  
  3511.     for( c = 0; c < 3; c++ )
  3512.     {
  3513.         if( !isalnum( *txtá) )
  3514.             break;
  3515.         txt++;
  3516.     }
  3517.     if( *txtá== '>'á|| *txt == ']' )
  3518.         return( getquotelevel( &txt[á1 ]á) + 1 );
  3519.     else
  3520.         return( 0 );
  3521. }
  3522.  
  3523. static void __stdargs addqt( struct List *to, int style, int showquote, char *txt )
  3524. {
  3525.     struct dnode *new;
  3526.     int x,x2,offs = 0;
  3527.     int b = 0;
  3528.     char buffer[ 2048 ];
  3529.  
  3530.     x = strlen( txt );
  3531.  
  3532.     if( !x )
  3533.     {
  3534.         new = LibAllocPooled( dlistpool, sizeof( struct dnode ) );
  3535.         new->txt = "";
  3536.         AddTail( to, ( struct Node * ) new );
  3537.         return;
  3538.     }        
  3539.  
  3540.     expandtabs( txt, buffer, prefs.reader_tabsize );
  3541.  
  3542.     txt = buffer;
  3543.     x = strlen( txt );
  3544.  
  3545.     if( showquote )
  3546.     {
  3547.         b = getquotelevel( txt );
  3548.         if( b > 1 )
  3549.             b++;    
  3550.     }
  3551.     else
  3552.         b = 0;
  3553. #if 0
  3554.     p = stpblk( txt );
  3555.     if( ql && !strncmp(p,quoteid,ql) )
  3556.         b=1;
  3557.     else if((*p=='>'||p[1]=='>'||p[2]=='>'))
  3558.         b=1;
  3559. #endif
  3560.  
  3561.     while( x )
  3562.     {
  3563.         x2 = x;
  3564.         if( x2 > screencols )
  3565.             x2 = screencols;
  3566.         x -= x2;
  3567.         new = LibAllocPooled ( dlistpool, sizeof( struct dnode ) );
  3568.         if( !new )
  3569.             break;
  3570.  
  3571.         new->txt = LibAllocPooled( dlistpool, x2 + 1 );
  3572.         new->sty = LibAllocPooled( dlistpool, x2 );
  3573.  
  3574.         new->bold = b;
  3575.  
  3576.         if( !style )
  3577.         {
  3578.             new->len  = x2;
  3579.             strncpy( new->txt, &txt[ offs ], x2 );
  3580.         }
  3581.         else
  3582.         {
  3583.             stylenode( &txt[áoffs ], x2, new->txt, new->sty );
  3584.             new->len = strlen( new->txt );
  3585.         }
  3586.  
  3587.         AddTail(to,(struct Node*)new);
  3588.         offs += x2;
  3589.     }
  3590. }
  3591.  
  3592. static void freedlist(void)
  3593. {
  3594.     if(dlistpool)
  3595.     {
  3596.         LibDeletePool(dlistpool);
  3597.         dlistpool=0;
  3598.     }
  3599. }
  3600.  
  3601. /*static int cmpstr(char *s1,char *s2)
  3602. {
  3603.     int c;
  3604.  
  3605.     for(c=0; s1[c]; c++) {
  3606.         if(s1[c]!=s2[c]) return(c);
  3607.     }
  3608.     return(0);
  3609. }*/
  3610.  
  3611.  
  3612. /*static void quotedlist(struct List *l,char *quoteid)
  3613. {
  3614.     struct dnode *n=(struct dnode*)l->lh_Head;
  3615.     char *p;
  3616.     int ql;
  3617.  
  3618.     ql=strlen(quoteid);
  3619.  
  3620.     while(n->n.mln_Succ)
  3621.     {
  3622.         p=stpblk(n->txt);
  3623.         if( ql && !strncmp(p,quoteid,ql) )
  3624.             n->bold=1;
  3625.         else if((*p=='>'||p[1]=='>'||p[2]=='>'))
  3626.             n->bold=1;
  3627.         n=(struct dnode*)n->n.mln_Succ;
  3628.     }
  3629. }
  3630. */
  3631.  
  3632. static ULONG lastmsgcs;
  3633.  
  3634. static void procheader(struct List *l,char *header,char *p)
  3635. {
  3636.     int c;
  3637.     char headmem[32];
  3638.  
  3639.     header = translateheader( header, p );
  3640.     if( datmem[0]á)
  3641.         p = datmem;
  3642.  
  3643.     strncpy(headmem,header,18);
  3644.     headmem[18]=0;
  3645.     for(c=strlen(headmem); c<18; headmem[c++]='.');
  3646.  
  3647.     addd(l,2,"%s: %s",headmem,p);
  3648. }
  3649.  
  3650. static void getmailinfo(char *mid,char *to)
  3651. {
  3652.     ULONG crc;
  3653.     struct mmail *m=(struct mmail*)mix->maillist.lh_Head;
  3654.  
  3655.     *to=0;
  3656.     crc=crc32(mid,strlen(mid));
  3657.  
  3658.     while(m->n.mln_Succ)
  3659.     {
  3660.         if(m->m.midcrc==crc) goto foundcrc;
  3661.         m=(struct mmail*)m->n.mln_Succ;
  3662.     }
  3663.     return;
  3664. foundcrc:
  3665.     if( !strncmp( m->m.absender, "an ", 3 ) )
  3666.         sprintf(to,"%s, \"%s\"",
  3667.             m->m.absender,m->m.betreff);
  3668.     else
  3669.         sprintf(to,"von %s, \"%s\"",
  3670.             m->m.absender,m->m.betreff);
  3671. }
  3672.  
  3673. extern int brettreqshowpmboards;
  3674. static int docopymail( struct vmail * n )
  3675. {
  3676.     char *dest;
  3677.     struct mbrett *mb;
  3678.     struct mail m;
  3679.  
  3680.     brettreqshowpmboards = TRUE;
  3681.     dest = dobrettreqtitle( "Nachricht kopieren: Zielbrett auswΣhlen" );
  3682.     brettreqshowpmboards = FALSE;
  3683.     if( !dest )
  3684.         return( 0 );
  3685.  
  3686.     mb = findbrett( dest, 0 );
  3687.     if( !mb )
  3688.     {
  3689.         askreq( "Brett %s unbekannt.\n", "Abbruch", dest );
  3690.         return( 0 );
  3691.     }
  3692.  
  3693.     m = n->m->m;
  3694.     //m.absenderreal[á0 ]á= 0;
  3695.     storemail2ix( &m, mb, NULL );
  3696.  
  3697.     return( -1 );
  3698. }
  3699.  
  3700.  
  3701. static void docopymails( void )
  3702. {
  3703.     struct vmail *n = ( struct vmail * ) mlist.lh_Head;
  3704.     char title[á64 ];
  3705.     char *dest;
  3706.     struct mbrett *mb;
  3707.  
  3708.     mix->changed=1;
  3709.  
  3710.     if(!mmcount)
  3711.     {
  3712.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  3713.         if( n )
  3714.         {
  3715.             docopymail( n );
  3716.             incscroller();
  3717.         }
  3718.     }
  3719.     else
  3720.     {
  3721.         savesel();
  3722.  
  3723.         sprintf( title, "%lD Nachrichten kopieren: Zielbrett auswΣhlen", mmcount );
  3724.         brettreqshowpmboards = TRUE;
  3725.         dest = dobrettreqtitle( title );
  3726.         brettreqshowpmboards = FALSE;
  3727.         if( !dest )
  3728.             return;
  3729.  
  3730.         mb = findbrett( dest, 0 );
  3731.         if( !mb )
  3732.         {
  3733.             askreq( "Brett %s unbekannt.\n", "Abbruch" );
  3734.             return;
  3735.         }
  3736.  
  3737.         while( n->n.mln_Succ )
  3738.         {
  3739.             if( n->sel )
  3740.             {
  3741.                 storemail2ix( &n->m->m, mb, NULL );
  3742.                 n->sel = 0;
  3743.             }
  3744.             n=(struct vmail*)n->n.mln_Succ;
  3745.         }
  3746.     }
  3747.     displayscroller();
  3748. }
  3749.  
  3750. #define XBSIZE 512
  3751. static int readmail(struct vmail *n)
  3752. {
  3753.     struct List tlist;
  3754.     struct vmail *tmv;
  3755.     struct mmail *m;
  3756.     char path[512];
  3757.     int Done, redo = FALSE, donttouchflags = FALSE;
  3758.     struct IntuiMessage im,*mp;
  3759.     int rc;
  3760.     void *scs=0;
  3761.     long rt;
  3762.     struct header *hl;
  3763.     char *p;
  3764.     USHORT oldflags;
  3765.     ULONG sigs, wsig;
  3766.     struct msghandle *msg;
  3767.     struct hlist *hlist;
  3768.     int redoasc;
  3769.     int redotop = 0;
  3770.  
  3771.     execrexx( "Reader" );
  3772.  
  3773.     OffMenu(w,SHIFTMENU(0)|SHIFTITEM(NOITEM));
  3774.  
  3775.     for(rc=0; rc<12; rc++)
  3776.         OffMenu(w,SHIFTMENU(3)|SHIFTITEM(rc));
  3777.  
  3778.     OffMenu(w,SHIFTMENU(4)|SHIFTITEM(NOITEM));
  3779.     OffMenu(w,SHIFTMENU(5)|SHIFTITEM(NOITEM));
  3780.     OffMenu(w,SHIFTMENU(6)|SHIFTITEM(NOITEM));
  3781.  
  3782.     OffMenu(w,SHIFTMENU(2)|SHIFTITEM(0));
  3783.  
  3784.     scs = pushscs();
  3785.  
  3786. redo:
  3787.     redoasc = FALSE;
  3788.     initdlist( &tlist );
  3789.     oldflags = prefs.flags & ( MDF_SHOWALL | MDF_GADGETS | MDF_NOREADERSTYLES );
  3790.     if( !n )
  3791.     {
  3792.         displaybeep();
  3793.         displayscroller();
  3794.         ClearPointer(w);
  3795.         goto xit;
  3796.     }
  3797.  
  3798.     currentreadermail = n;
  3799.  
  3800.     m=n->m;
  3801.     lastmailnum = GetEntryNum( &mlist, (struct Node*) n );
  3802.     cmpid = n->m->m.midcrc;
  3803.  
  3804.     if( !donttouchflags )
  3805.     {
  3806.         if( ( ( ! ( m->m.flags & MMF_READ ) || ( m->m.flags&MMF_SHOW ) ) ) )
  3807.         {
  3808.             m->m.flags|=MMF_READ;
  3809.             m->m.flags&=~MMF_SHOW;
  3810.             mix->changed=1;
  3811.         }
  3812.  
  3813.         if( ( prefs.flags2 & MDF2_AUTOCLRNEW ) && ( m->m.flags & MMF_UNSEEN ) )
  3814.         {
  3815.             m->m.flags &= ~MMF_UNSEEN;
  3816.             mix->changed = 1;
  3817.         }
  3818.     }
  3819.     donttouchflags = FALSE;
  3820.  
  3821.     redo = Done = FALSE;
  3822.  
  3823.     msg = msg_openv( n );
  3824.     if( !msg )
  3825.     {
  3826.         displayscroller();
  3827.         ClearPointer(w);
  3828.         goto xit;
  3829.     }
  3830.  
  3831.     /* header erstellen */
  3832.     hlist = msg_loadheader( msg );
  3833.  
  3834.     if( prefs.flags & MDF_SHOWALL )
  3835.     {
  3836.         hl = hl_findheader( hlist, NULL );
  3837.         while( hl->n.mln_Succ )
  3838.         {
  3839.             procheader(&tlist,hl->head,hl->data);
  3840.             hl=(struct header*)hl->n.mln_Succ;
  3841.         }
  3842.     }
  3843.     else
  3844.     {
  3845.         /*
  3846.              Standard-Header
  3847.         */
  3848.         hl=hl_findheader(hlist,"ABS");
  3849.         if(hl) addd(&tlist,2,"Absender..........: %s",hl->data);
  3850.  
  3851.         path[0]=0;
  3852.         hl=hl_findheader(hlist,"EMP");
  3853.         while(hl)
  3854.         {
  3855.             if( strlen( path ) + strlen( hl->data ) > XBSIZE - 20 )
  3856.             {
  3857.                 strcat( path, "...  " );
  3858.                 break;
  3859.             }
  3860.  
  3861.             strcat(path,hl->data);
  3862.             strcat(path,", ");
  3863.             hl=hl_findnextheader(hl);
  3864.         }
  3865.         if(path[0])
  3866.         {
  3867.             path[strlen(path)-2]=0;
  3868.             addd(&tlist,2,"EmpfΣnger.........: %s",path);
  3869.         }
  3870.  
  3871.  
  3872.         path[0]=0;
  3873.         hl=hl_findheader(hlist,"KOP");
  3874.         while(hl)
  3875.         {
  3876.             if( strlen( path ) + strlen( hl->data ) > XBSIZE - 20 )
  3877.             {
  3878.                 strcat( path, "...  " );
  3879.                 break;
  3880.             }
  3881.  
  3882.             strcat(path,hl->data);
  3883.             strcat(path,", ");
  3884.             hl=hl_findnextheader(hl);
  3885.         }
  3886.         if(path[0])
  3887.         {
  3888.             path[strlen(path)-2]=0;
  3889.             addd(&tlist,2,"KopieempfΣnger....: %s",path);
  3890.         }
  3891.  
  3892.  
  3893.         hl=hl_findheader(hlist,"OAB");
  3894.         if(hl) addd(&tlist,2,"Originalabsender..: %s",hl->data);
  3895.  
  3896.         hl=hl_findheader(hlist,"WAB");
  3897.         if(hl) addd(&tlist,2,"Weiterleitungsabs.: %s",hl->data);
  3898.  
  3899.         path[0]=0;
  3900.         hl=hl_findheader(hlist,"OEM");
  3901.         while(hl)
  3902.         {
  3903.             if( strlen( path ) + strlen( hl->data ) > XBSIZE - 20 )
  3904.             {
  3905.                 strcat( path, "...  " );
  3906.                 break;
  3907.             }
  3908.             strcat( path, hl->data );
  3909.             strcat( path, ", " );
  3910.             hl=hl_findnextheader(hl);
  3911.         }
  3912.         if(path[0])
  3913.         {
  3914.             path[strlen(path)-2]=0;
  3915.             addd(&tlist,2,"OrignalempfΣnger..: %s",path);
  3916.         }
  3917.     
  3918.         /* Status */
  3919.         path[0]=0;
  3920.         hl=hl_findheader(hlist,"TYP");
  3921.         if(hl) sprintf(path,"%s ",hl->data);
  3922.         hl=hl_findheader(hlist,"STAT");
  3923.         while(hl)
  3924.         {
  3925.             if( strlen( path ) + strlen( hl->data ) > XBSIZE - 20 )
  3926.             {
  3927.                 strcat( path, "...  " );
  3928.                 break;
  3929.             }
  3930.             strcat(path,hl->data);
  3931.             strcat(path," ");
  3932.             hl=hl_findnextheader(hl);
  3933.         }
  3934.         if(path[0])
  3935.         {
  3936.             path[strlen(path)-1]=0;
  3937.             addd(&tlist,2,"Status............: %s",path);
  3938.         }
  3939.     
  3940.         hl=hl_findheader(hlist,"BET");
  3941.         if(hl) addd(&tlist,2,"Betreff...........: %s",hl->data);
  3942.  
  3943.         hl=hl_findheader( hlist, "ZUSAMMENFASSUNG" );
  3944.         if(hl) addd(&tlist,2,"Kommentar.........: %s",hl->data);
  3945.         
  3946.         hl=hl_findheader( hlist, "LEN" );
  3947.         if(hl) addd(&tlist,2,"LΣnge.............: %s Bytes",hl->data);
  3948.  
  3949.         hl=hl_findheader( hlist, "EDA" );
  3950.         if(hl) {
  3951.             p=hl->data;
  3952.             addd(&tlist,2,"Datum.............: %.2s.%.2s.%.4s %.2s:%.2s:%.2s (%s)",
  3953.                 &p[6],&p[4],p,
  3954.                 &p[8],&p[10],&p[12],
  3955.                 &p[14]);
  3956.         }
  3957.     }    
  3958.     hl=hl_findheader( hlist, "BEZ" );
  3959.     if(hl) {
  3960.         getmailinfo(hl->data,path);
  3961.         if(path[0]) addd(&tlist,2,"Bezugsnachricht...: %s",path);
  3962.     }
  3963.  
  3964.     rt= m->m.incomtime - m->m.time;
  3965.  
  3966.     if( rt > ( 3600 * 24 ) )
  3967.     {
  3968.         addd(&tlist,2,"Laufzeit..........: %ld Tag%s, %ld Stunde%s, %ld Minute%s, %ld Sekunde%s",
  3969.             rt / ( 3600 * 24 ), ( rt / ( 3600 * 24 ) == 1 ) ? "" : "e",
  3970.             ( rt/3600 ) % 24 ,(((rt/3600)%24)==1)?"":"n",
  3971.             (rt/60)%60,((rt/60)%60)==1?"":"n",
  3972.             rt%60,(rt%60)==1?"":"n");
  3973.     }
  3974.     else
  3975.     {
  3976.         addd(&tlist,2,"Laufzeit..........: %ld Stunde%s, %ld Minute%s, %ld Sekunde%s",
  3977.             rt/3600,((rt/3600)==1)?"":"n",
  3978.             (rt/60)%60,((rt/60)%60)==1?"":"n",
  3979.             rt%60,(rt%60)==1?"":"n");
  3980.     }
  3981.     hl_freeheader( hlist );
  3982.     addd(&tlist,2,"Flags.............: %s%s%s%s%s%s%s%s%s%s%s",
  3983.         (m->m.flags&MMF_GOTEB)?"!EMPFANG BEST─TIGT! ":"",
  3984.         (m->m.flags&MMF_READ)?"GELESEN ":"",
  3985.         (m->m.flags&MMF_ARCHIVE)?"HALTEN ":"",
  3986.         (m->m.flags&MMF_DEL)?"L╓SCHEN ":"",
  3987.         (m->m.flags&MMF_UNSEEN)?"NEU ":"",
  3988.         (m->m.flags&MMF_OUT)?"AUSGEHEND ":"",
  3989.         (m->m.flags&MMF_SHOW)?"WIEDERVORLAGE ":"",
  3990.         (m->m.flags&MMF_MDCRYPT)?"MDCRYPT ":"",
  3991.         (m->m.flags&MMF_PGPCRYPT)?"PGP-CRYPT ":"",
  3992.         (m->m.flags&MMF_PGPSIGNED)?"PGP-SIGNIERT ":"",
  3993.         (m->m.flags&MMF_FOLD)?"GEFALTET":""
  3994.     );
  3995.  
  3996.     if( msg->pix.commentsize )
  3997.     {
  3998.         int style = ! ( prefs.flags & MDF_NOREADERSTYLES );
  3999.         int quote = TRUE;
  4000.  
  4001.         msg_initread( msg, MC_COMMENT );
  4002.         addd( &tlist, 0, "" );
  4003.         addd( &tlist, 2, "Kommentar:" );
  4004.         addd( &tlist, 0, "" );
  4005.         while( msg_read( msg, path, 512 ) )
  4006.         {
  4007.             if( style )
  4008.             {
  4009.                 if( path[á0 ]á== '-' && path[ 1 ]á== '-' )
  4010.                 {
  4011.                     if( !*stpblk( &path[ 2 ] ) )
  4012.                     {
  4013.                         quote = 0;
  4014.                         style = 0;
  4015.                     }
  4016.                 }
  4017.             }
  4018.             addqt( &tlist, style, quote, path );
  4019.         }
  4020.         msg_endread( msg );
  4021.         addd( &tlist, 0, "" );
  4022.         addd( &tlist, 2, "Nachrichteninhalt:" );
  4023.         addd( &tlist, 0, "" );
  4024.     }
  4025.     else
  4026.         addd( &tlist, 0, "" );
  4027.  
  4028.     if( m->m.flags & MMF_BIN )
  4029.     {
  4030.         addd( &tlist, 0, "BinΣrnachricht. Auslagern mit 'x'");
  4031.  
  4032.         path[á0 ]á= 0;
  4033.  
  4034.         if( DataTypesBase )
  4035.         {
  4036.             BPTR lock;
  4037.             struct DataType *dt;
  4038.             struct DataTypeHeader *dth;
  4039.             STRPTR tdesc;
  4040.             STRPTR gdesc;
  4041.             ULONG ttype;
  4042.  
  4043.             strcpy( path, prefs.datadir );
  4044.             addpart( path, "__mddt.temp" );
  4045.             msg_copy( msg, path, MC_DATA );
  4046.  
  4047.             lock = Lock( path, SHARED_LOCK );
  4048.             if( lock )
  4049.             {
  4050.                 dt = ObtainDataType( DTST_FILE, ( APTR ) lock, TAG_DONE );
  4051.                 if( dt )
  4052.                 {
  4053.                     dth = dt->dtn_Header;
  4054.  
  4055.                     /* Get the coarse type */
  4056.                     ttype = dth->dth_Flags & DTF_TYPE_MASK;
  4057.  
  4058.                     /* Get a pointer to the text strings */
  4059.                     tdesc = GetDTString (ttype + DTMSG_TYPE_OFFSET);
  4060.                     gdesc = GetDTString (dth->dth_GroupID);
  4061.  
  4062.                     addd( &tlist, 0, "" );
  4063.  
  4064.                     addd( &tlist, 0, "DataTypes-Analyse:" );
  4065.  
  4066.                     addd( &tlist, 0, "   Beschreibung..: %s", dth->dth_Name );
  4067.                     addd( &tlist, 0, "   Base Name.....: %s", dth->dth_BaseName);
  4068.                     addd( &tlist, 0, "   Typ...........: %ld - %s", ttype, tdesc);
  4069.                     addd( &tlist, 0, "   Gruppe........: %s", gdesc);
  4070.                     addd( &tlist, 0, "   ID............: %4.4s", &dth->dth_ID );
  4071.  
  4072.                     if( ttype == 1 )
  4073.                         redoasc = TRUE;
  4074.  
  4075.                     ReleaseDataType( dt );
  4076.                 }
  4077.                 UnLock( lock );
  4078.             }
  4079.         }
  4080.         if( WhatIsBase )
  4081.         {
  4082.             BPTR lock;
  4083.  
  4084.             if( !path[á0 ]á)
  4085.             {
  4086.                 strcpy( path, prefs.datadir );
  4087.                 addpart( path, "__mddt.temp" );
  4088.                 msg_copy( msg, path, MC_DATA );
  4089.             }
  4090.  
  4091.             lock = Lock( path, SHARED_LOCK );
  4092.             if( lock )
  4093.             {
  4094.                 p = GetIDString( WhatIsTags( path, WI_Deep, DEEPTYPE, TAG_DONE ) );
  4095.  
  4096.                 addd( &tlist, 0, "" );
  4097.                 addd( &tlist, 0, "WhatIs-Analyse...: %s", p );
  4098.  
  4099.                 if( !strcmp( p, "Text" ) )
  4100.                     redoasc = TRUE;
  4101.  
  4102.                 UnLock( lock );
  4103.             }
  4104.         }
  4105.         if( path[á0 ]á)
  4106.             DeleteFile( path );
  4107.     }
  4108.     if( ! ( m->m.flags & MMF_BIN ) || redoasc )
  4109.     {
  4110.         int style = ! ( prefs.flags & MDF_NOREADERSTYLES );
  4111.         int quote = TRUE;
  4112.  
  4113.         if( redoasc )
  4114.         {
  4115.             addd( &tlist, 0, "" );
  4116.             addd( &tlist, 2, "Nachrichteninhalt in Textform:" );
  4117.             addd( &tlist, 0, "" );
  4118.         }
  4119.  
  4120.         msg_initread( msg, MC_DATA );
  4121.         while( msg_read( msg, path, 512 ) )
  4122.         {
  4123.             if( style )
  4124.             {
  4125.                 if( path[á0 ]á== '-' && path[ 1 ]á== '-' )
  4126.                 {
  4127.                     if( !*stpblk( &path[ 2 ] ) )
  4128.                     {
  4129.                         style = 0;
  4130.                         quote = 0;
  4131.                     }
  4132.                 }
  4133.             }
  4134.             addqt( &tlist, style, quote, path );
  4135.         }
  4136.         msg_endread( msg );
  4137.     }
  4138.  
  4139.     msg_close( msg );
  4140.  
  4141.     setupscroller( &tlist, 2 );
  4142.     if( redotop > 0 )
  4143.     {
  4144.         setscrollerstate( redotop );
  4145.         redotop = 0;
  4146.     }
  4147.     else
  4148.         displayscroller();
  4149.  
  4150.     if( mmcount )
  4151.     {
  4152.         struct vmail *vm=(struct vmail*)mlist.lh_Head;
  4153.         int count = 0;
  4154.  
  4155.         while( vm->n.mln_Succ )
  4156.         {
  4157.             if( vm->sel )
  4158.                 count++;
  4159.  
  4160.             if( vm == n )
  4161.                 break;
  4162.  
  4163.             vm = ( struct vmail * ) vm->n.mln_Succ;
  4164.         }
  4165.         preport( 0, 1, "NACHRICHT LESEN: Brett %s (%lD. von %lD markierten)", cmb->b.name, count, mmcount );
  4166.     }
  4167.     else
  4168.     {
  4169.         preport( 0, 1, "NACHRICHT LESEN: Brett %s",cmb->b.name);
  4170.     }
  4171.  
  4172.     if( !strncmp( m->m.absender, "an ", 3 ) )
  4173.         preport(1,1,"\"%s\" %s",m->m.betreff,m->m.absenderreal[0]?m->m.absenderreal:m->m.absender);
  4174.     else
  4175.         preport(1,1,"\"%s\" von %s",m->m.betreff,m->m.absenderreal[0]?m->m.absenderreal:m->m.absender);
  4176.  
  4177.     dorexx( 2 );
  4178.  
  4179.     ClearPointer( w );
  4180.     wsig = 1 << w->UserPort->mp_SigBit;
  4181.     while(!Done)
  4182.     {
  4183.         while(!(mp=(struct IntuiMessage*)GetMsg(w->UserPort))) 
  4184.         {
  4185.             sigs = Wait( wsig | rexxsig );
  4186.             if( rexxsig && ( sigs & rexxsig ) )
  4187.                 dorexx( 2 );
  4188.         }
  4189.         im=*mp;
  4190.         ReplyMsg(mp);
  4191.  
  4192.         switch(im.Class)
  4193.         {
  4194.             case IDCMP_REFRESHWINDOW:
  4195.                 BeginRefresh( w );
  4196.                 displayscroller();
  4197.                 EndRefresh( w, TRUE );
  4198.                 break;
  4199.  
  4200.             case IDCMP_CLOSEWINDOW:
  4201.                 doaskquit();
  4202.                 break;
  4203.  
  4204.             case IDCMP_NEWSIZE:
  4205.                 scrollerresize();
  4206.                 break;
  4207.  
  4208.             case MOUSEBUTTONS:
  4209.                 if( scrollerdoclick( &im ) == -1 )
  4210.                     Done = 1;
  4211.                 break;
  4212.             case MOUSEMOVE: scrollerdomove(&im); break;
  4213.             case GADGETDOWN: scrollerdogad(&im); break;
  4214.             case GADGETUP:
  4215.                 rc = scrollerdogad( &im );
  4216.                 if( !rc )
  4217.                     break;
  4218.                 im.Class    = RAWKEY;
  4219.                 im.Code     = rc & 0xff;
  4220.                 im.Qualifier = (rc & 0x100) ? QSHIFT : 0;
  4221.                 goto rawkey;
  4222.             case MENUPICK:
  4223.                         rc=procmenu(im.Code,im.Qualifier);
  4224.                         calcmcount();
  4225.                         if(rc<0)
  4226.                         {
  4227.                             if( oldflags != ( prefs.flags & ( MDF_SHOWALL | MDF_GADGETS | MDF_NOREADERSTYLES ) ) )
  4228.                             {
  4229.                                 redotop = getscrollerstate();
  4230.                                 redo=1;
  4231.                                 Done=1;
  4232.                             }
  4233.                             break;
  4234.                         }
  4235.                         
  4236.                        im.Code=rc&0xff;
  4237.                        im.Qualifier=(rc&0x100)?IEQUALIFIER_LSHIFT:0;
  4238.                     /* fallthrough */
  4239. rawkey:
  4240.             case RAWKEY: if(scrollerdokey(&im)) switch(im.Code) {
  4241.                     case 0x0d:
  4242.                         if( im.Qualifier & IEQUALIFIER_RSHIFT )
  4243.                         {
  4244.                             domailinfo( n );
  4245.                         }
  4246.                         break;
  4247.  
  4248.                     case 0x50:
  4249.                     case 0x51:
  4250.                     case 0x52:
  4251.                     case 0x53:
  4252.                     case 0x54:
  4253.                         dorexxcmd( 0, im.Code - 0x50 + ( ISSHIFT( &im ) ? 5 : 0 ) );
  4254.                         break;
  4255.  
  4256.                     case 0x55:
  4257.                     case 0x56:
  4258.                     case 0x57:
  4259.                     case 0x58:
  4260.                     case 0x59:
  4261.                         dorexxcmd( 2, im.Code - 0x55 + ( ISSHIFT( &im ) ? 5 : 0 ) );
  4262.                         break;
  4263.  
  4264.                     case 0x27:  if( ISSHIFT( &im ) )
  4265.                                 {
  4266.                                     if( askreq( "Thread wirklich killen?\nDie Nachrichten und alle Antworten darauf werden\ngel÷scht und k÷nnen nicht mehr restauriert werden!", "Killen|Abbruch" ) )
  4267.                                     {
  4268.                                         dokillthread( n->m, 0, 0 );
  4269.                                         removekilled( mix );
  4270.                                         ClearPointer( w );
  4271.                                         wrotenewmails = TRUE;
  4272.                                         Done = 1;
  4273.                                     }
  4274.                                 }
  4275.                                 else
  4276.                                     docopymail( n );
  4277.                                 break;
  4278.  
  4279.                     case 0x16: if( ISSHIFT( &im ) )
  4280.                                     dokilluser( n );
  4281.                                 else
  4282.                                     doextractmailuudecode( n );
  4283.                                 break;
  4284.  
  4285.                     case 0x5f: showguidegads(&im, "nachrichtenlesen"); break;
  4286.  
  4287.                     case 0x40: im.Code=0x4d; im.Qualifier=IEQUALIFIER_LSHIFT; scrollerdokey(&im); break;
  4288.  
  4289.                     case 0x43:
  4290.                     case 0x44: im.Code=0x4d; scrollerdokey(&im); break;
  4291.  
  4292.                     case 0x5d:
  4293.                     case 0x0f: 
  4294.                     case 0x45: if( ISSHIFT( &im ) )
  4295.                                 Done = 2;
  4296.                                else
  4297.                                 Done = 1;
  4298.                                break;
  4299.                                 
  4300.                     /* Mailfunktionen */
  4301.  
  4302.                     case 0x34:    lockwindow();
  4303.                                 doviewmail( n );
  4304.                                 unlockwindow();
  4305.                                 break;
  4306.  
  4307.                     case 0x32:  lockwindow();
  4308.                                 doextractmail( n, ISSHIFT( &im ) );
  4309.                                 unlockwindow();
  4310.                                 break;
  4311.  
  4312.                     case 0x22:  lockwindow();
  4313.                                 doprintmail( n );
  4314.                                 unlockwindow();
  4315.                                 break;
  4316.  
  4317.                     case 0x11:    
  4318.                                 lockwindow();
  4319.                                 if( ISSHIFT( &im ) )
  4320.                                 {
  4321.                                     resendmail( n );
  4322.                                 }
  4323.                                 else
  4324.                                 {
  4325.                                     if(doweitermail(n))
  4326.                                         wrotenewmails = cmb->newmails;
  4327.                                 }
  4328.                                 unlockwindow();
  4329.                                 break;
  4330.  
  4331.                     case 0x21:    if(ISSHIFT(&im)) dosaveuser(n);
  4332.                                 else
  4333.                                 {
  4334.                                     lockwindow();
  4335.                                     doarcmail(n);
  4336.                                     preport(1,1,"Nachricht archiviert.");
  4337.                                     unlockwindow();
  4338.                                 }
  4339.                                 break;
  4340.  
  4341.                     case 0x20:    lockwindow();
  4342.                                 if(doanswermail(n,1,ISSHIFT(&im)))
  4343.                                     wrotenewmails = cmb->newmails;
  4344.                                 unlockwindow();
  4345.                                 break;
  4346.  
  4347.                     case 0x19:    lockwindow();
  4348.                                 if(doanswermail(n,0,ISSHIFT(&im)))
  4349.                                     wrotenewmails = cmb->newmails;
  4350.                                 unlockwindow();
  4351.                                 break;
  4352.  
  4353.                     case 0x04:    lockwindow();
  4354.                                 checksignature( n );
  4355.                                 unlockwindow();
  4356.                                 break;
  4357.  
  4358.                     case 0x5b:
  4359.                     case 0x24:    n->m->m.flags^=MMF_READ;
  4360.                                 Done=redo=1;
  4361.                                 mix->changed = 1;
  4362.                                 donttouchflags = TRUE;
  4363.                                 break;
  4364.  
  4365.                     case 0x5a:
  4366.                     case 0x25:    n->m->m.flags^=MMF_ARCHIVE;
  4367.                                 mix->changed = 1;
  4368.                                 Done=redo=1; break;
  4369.  
  4370.                     case 0x4a:
  4371.                     case 0x46:    n->m->m.flags^=MMF_DEL;
  4372.                                 if( ( n->m->m.flags & MMF_DEL ) && ( prefs.flags2 & MDF2_HARDDEL ) )
  4373.                                     n->m->m.flags &= ~MMF_ARCHIVE;    
  4374.                                 mix->changed = 1;
  4375.                                 Done=redo=1; break;
  4376.  
  4377.                     case 0x5c:    im.Qualifier |= QSHIFT;    // Simulate Shift
  4378.                     case 0x01:    if(ISSHIFT(&im))
  4379.                                 {
  4380.                                     mix->changed = 1;
  4381.                                     n->m->m.flags |= MMF_SHOW;
  4382.                                     Done=redo=1;
  4383.                                     donttouchflags = TRUE;
  4384.                                 }
  4385.                                 break;
  4386.  
  4387.                     case 0x5e:
  4388.                     case 0x36:    tmv = fnvm( n );
  4389.                                 if( tmv )
  4390.                                 {
  4391.                                     n = tmv;
  4392.                                     Done = redo = 1;
  4393.                                 }
  4394.                                 else
  4395.                                 {
  4396.                                     if( prefs.flags2 & MDF2_NEXTNEWBOARD )
  4397.                                     {
  4398.                                         if( prefs.flags2 & MDF2_NEXTNEWBOARDASK )
  4399.                                         {
  4400.                                             char *p = findnextboardwithnewmails( cmb );
  4401.  
  4402.                                             if( !p )
  4403.                                             {
  4404.                                                 askreq( "Keine weiteren neuen Nachrichten\nin diesem Brett.\n\nKeine weiteren Bretter mit neuen Nachrichten.", "Ok" );
  4405.                                                 break;
  4406.                                             }
  4407.                                             if( !askreq( "Keine weiteren neuen Nachrichten\nin diesem Brett. Wollen Sie in das\nnΣchste Brett mit neuen Nachrichten:\n%s\nspringen?",
  4408.                                                 "Weiterspringen|Stopp", p
  4409.                                             ))
  4410.                                             break;
  4411.                                         }
  4412.                                         donextnewboard = 2;
  4413.                                         Done = TRUE;
  4414.                                     }
  4415.                                     else displaybeep();
  4416.                                 }
  4417.                                 break;
  4418.  
  4419.                     case 0x42:    /* TAB naechste ungelesene */
  4420.                                 tmv=findnextunread(n); if(tmv) { n=tmv; Done=redo=1; }
  4421.                                 break;
  4422.  
  4423.                     case 0x2d:
  4424.                     case 0x2f:
  4425.                     case 0x4e:
  4426.                     case 0x4f:    tmv=findfup2(&im,n);
  4427.                             if(tmv) { n=tmv; Done=redo=1; }
  4428.                             break;
  4429.  
  4430.                      }
  4431.                      break;
  4432.  
  4433.             case IDCMP_MENUHELP: domenuhelp("brett",&im); break;
  4434.         }
  4435.         
  4436.     }
  4437.  
  4438. xit:
  4439.     freedlist();    
  4440.     if( redo )
  4441.         goto redo;
  4442.  
  4443.     if( scs )
  4444.     {
  4445.         if( !mmcount && !donextnewboard )
  4446.             popscs( scs );
  4447.         else
  4448.             popscsnv( scs );
  4449.     }
  4450.  
  4451.     OnMenu(w,SHIFTMENU(0)|SHIFTITEM(NOITEM));
  4452.     OnMenu(w,SHIFTMENU(2)|SHIFTITEM(0));
  4453.     OnMenu(w,SHIFTMENU(4)|SHIFTITEM(NOITEM));
  4454.     for(rc=0; rc<12; rc++)
  4455.         OnMenu(w,SHIFTMENU(3)|SHIFTITEM(rc));
  4456.     OnMenu(w,SHIFTMENU(5)|SHIFTITEM(NOITEM));
  4457.     if( pgpavail )
  4458.         OnMenu(w,SHIFTMENU(6)|SHIFTITEM(NOITEM));
  4459.  
  4460.     return( Done == 2 );
  4461. }
  4462.  
  4463. static void readmails(void)
  4464. {
  4465.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  4466.     APTR scs;
  4467.  
  4468.     rtSetWaitPointer(w);
  4469.     wrotenewmails = FALSE;
  4470.  
  4471.     if(!mmcount)
  4472.     {
  4473.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  4474.         readmail(n);
  4475.         return;
  4476.     }
  4477.  
  4478.     scs = pushscs();
  4479.     savesel();
  4480.     while(n->n.mln_Succ)
  4481.     {
  4482.         if( n->sel )
  4483.         {
  4484.             if( readmail( n ) )
  4485.                 break;
  4486.         }
  4487.         n=(struct vmail*)n->n.mln_Succ;
  4488.     }
  4489.     n=(struct vmail*)mlist.lh_Head;
  4490.     while(n->n.mln_Succ)
  4491.     {
  4492.         n->sel = 0;
  4493.         n=(struct vmail*)n->n.mln_Succ;
  4494.     }
  4495.     n->sel=0;
  4496.     popscs( scs );
  4497. }
  4498.  
  4499. #define EM_OK 1
  4500. #define EM_CANCEL 2
  4501. #define EM_EDIT 3
  4502. #define EM_EDITCOMMENT 4
  4503. #define EM_EDITHEADER 5
  4504. #define EM_INFO 6
  4505. #define EM_PARK 7
  4506.  
  4507. static struct mmail *findmailbymidpid( struct mindex *mix, ULONG mID, ULONG pID )
  4508. {
  4509.     struct mmail * mm = ( struct mmail * ) mix->maillist.lh_Head;
  4510.  
  4511.     while( mm->n.mln_Succ )
  4512.     {
  4513.         if( mm->m.pufferID == pID && mm->m.mailID == mID )
  4514.             return( mm );
  4515.         mm = ( struct mmail * ) mm->n.mln_Succ;
  4516.     }
  4517.     return( NULL );
  4518. }
  4519.  
  4520. static int doeditmail( struct vmail *n )
  4521. {
  4522.     struct msghandle *msg;
  4523.     struct hlist *hlist;
  4524.     int Done = FALSE;
  4525.     struct ogwin *ogw;
  4526.     struct IntuiMessage *im;
  4527.     struct Window *w;
  4528.     ULONG mID, pID;
  4529.     char buffer[á128 ];
  4530.     int c, d;
  4531.     struct mindex *spoolmix;
  4532.     struct mbrett *spool = findbrett( "/╗SPOOL", 0 );
  4533.  
  4534.     /*if(n->m->m.flags&MMF_BIN) { displaybeep(); return(0); }*/
  4535.  
  4536.     msg = msg_openv( n );
  4537.     if( !msg )
  4538.         return( 0 );
  4539.  
  4540.     DeleteFile( TMPCOMMENTNAME );
  4541.     DeleteFile( TMPEDITNAME );
  4542.  
  4543.     msg_copy( msg, TMPEDITNAME, MC_DATA );
  4544.     msg_copy( msg, TMPCOMMENTNAME, MC_COMMENT );
  4545.     hlist = msg_loadheader( msg );
  4546.  
  4547.     mID = n->m->m.mailID;
  4548.     pID = n->m->m.pufferID;
  4549.  
  4550.     msg_close( msg );
  4551.  
  4552.     ogw = ogreInitWindow( scr, 0, 0, "Nachricht editieren" );
  4553.     ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
  4554.     ogreAddText( ogw, 0, "Info:", EM_INFO, "", 46, TRUE );
  4555.     ogreAddButton( ogw, 1, 'e', "Text _editieren", EM_EDIT );
  4556.     ogreAddButton( ogw, 1, 'k', "_Kommentar editieren", EM_EDITCOMMENT );
  4557.     ogreAddButton( ogw, 1, 'h', "_Header editieren", EM_EDITHEADER );
  4558.     ogreAddButton( ogw, 2 | OGB_ONENTER, 'v', "_Verschicken", EM_OK );
  4559.     ogreAddButton( ogw, 2 , 'p', "_Parken", EM_PARK );
  4560.     ogreAddHelp( ogw, 2 );
  4561.     ogreAddButton( ogw, 2 | OGB_ONESC, 'a', "_Abbruch", EM_CANCEL );
  4562.     w = ogreOpenWindow( ogw );
  4563.  
  4564.     if( !w )
  4565.     {
  4566.         return( 0 );
  4567.     }
  4568.  
  4569.     ogreEnable( ogw, !( n->m->m.flags & MMF_BIN ), EM_EDIT, 0 );
  4570.  
  4571.     while( !Done )
  4572.     {
  4573.         /* Infotext erzeugen */
  4574.         c = getfilelen( TMPCOMMENTNAME );
  4575.         d = getfilelen( TMPEDITNAME );
  4576.         buffer[á0 ]á= 0;
  4577.         if( d > 0 )
  4578.             sprintf( buffer, "%lD Byte Inhalt ", d );
  4579.         if( c > 0 )
  4580.         {
  4581.             if( buffer[á0 ]á)
  4582.                 strcat( buffer, ", " );
  4583.             asprintf( buffer, "%lD Byte Kommentar", c );
  4584.         }
  4585.         ogreSetStringValue( ogw, EM_INFO, buffer );
  4586.  
  4587.         im = ogreWaitIM( ogw );
  4588.  
  4589.         if( im->Class == IDCMP_GADGETHELP)
  4590.             showguidenum( "editwin_gads", im->Code );
  4591.         else if( im->Class == GADGETUP )
  4592.             switch( im->Code )
  4593.             {
  4594.                 case EM_OK:
  4595.                     Done = 2;
  4596.                     break;
  4597.  
  4598.                 case EM_PARK:
  4599.                     Done = 3;
  4600.                     break;
  4601.  
  4602.                 case EM_CANCEL:
  4603.                     Done = 1;
  4604.                     break;
  4605.  
  4606.                 case EM_EDIT:
  4607.                     calleditor( TMPEDITNAME );
  4608.                     ActivateWindow( w );
  4609.                     break;
  4610.  
  4611.                 case EM_EDITCOMMENT:
  4612.                     calleditor( TMPCOMMENTNAME );
  4613.                     ActivateWindow( w );
  4614.                     break;
  4615.  
  4616.                 case EM_EDITHEADER:
  4617.                     doeditheader( hlist, "Header editieren" );
  4618.                     break;
  4619.             }
  4620.             ogreIMReply( ogw, im );
  4621.  
  4622.     }
  4623.  
  4624.     ogreExitWindow( ogw );
  4625.  
  4626.     /* GeΣnderte Nachricht abspeichern... */
  4627.     if( Done > 1 )
  4628.     {
  4629.         msg_replace( TMPCOMMENTNAME, -1, TMPEDITNAME, -1,
  4630.             pID, mID, hlist
  4631.         );
  4632.  
  4633.         /* Mail-Struktur updaten */
  4634.         header2mail( hlist, &n->m->m );
  4635.  
  4636.         n->m->m.maillen = getfilelen( TMPEDITNAME );
  4637.  
  4638.         // Im Spoolbrett updaten?
  4639.         if( spool != cmb )
  4640.         {
  4641.             struct mmail *mm;
  4642.             spoolmix = loadbrettixquiet( spool );
  4643.  
  4644.             if( spoolmix )
  4645.             {
  4646.                 mm = findmailbymidpid( spoolmix, mID, pID );
  4647.  
  4648.                 if( mm )
  4649.                 {
  4650.                     ULONG oldflags;
  4651.  
  4652.                     oldflags = mm->m.flags;
  4653.                     mm->m = n->m->m;
  4654.                     mm->m.flags = oldflags;
  4655.                     spoolmix->changed = 1;
  4656.  
  4657.                     if( Done == 2 )
  4658.                         mm->m.flags &= ~MMF_ARCHIVE;
  4659.                     else
  4660.                         mm->m.flags |= MMF_ARCHIVE;
  4661.                 }
  4662.                 savebrettix( spoolmix, spool );
  4663.                 freebrettix( spoolmix );
  4664.             }        
  4665.             if( cmb->b.name[á0 ]á== '/'á&& !hl_findheader( hlist, "ABS" ) )
  4666.             {
  4667.                 sprintf( n->m->m.absender, "%s@%s%s", prefs.username, prefs.boxname, prefs.boxdomain ); 
  4668.                 strcpy( n->m->m.absenderreal, prefs.userrealname );
  4669.             }
  4670.         }
  4671.         else
  4672.         {
  4673.             //struct header *hl = hl_findheader( hlist, "ABS" );
  4674.             struct header *hl2 = hl_findheader( hlist, "EMP" );
  4675.             /* Im Spoolbrett editiert; wir mⁿssen EMP:s absuchen */
  4676.  
  4677.             if( Done == 2 )
  4678.                 n->m->m.flags &= ~MMF_ARCHIVE;
  4679.             else
  4680.                 n->m->m.flags |= MMF_ARCHIVE;
  4681.  
  4682.             while( hl2 )
  4683.             {
  4684.                 struct mbrett *mb;
  4685.  
  4686.                 if( hl2->data[á0 ]á== '/'á)
  4687.                     mb = findbrett( hl2->data, 0 );
  4688.                 else
  4689.                     mb = findpmbrett( hlist );
  4690.  
  4691.                 if( mb )
  4692.                 {
  4693.                     struct mindex *mix = loadbrettixquiet( mb );
  4694.  
  4695.                     if( mix )
  4696.                     {
  4697.                         struct mmail *mm = findmailbymidpid( mix, mID, pID );
  4698.  
  4699.                         if( mm )
  4700.                         {
  4701.                             ULONG oldflags;
  4702.  
  4703.                             oldflags = mm->m.flags;
  4704.                             mm->m = n->m->m;
  4705.                             mm->m.flags = oldflags;
  4706.                             if( hl2->data[á0 ]á== '/'á)
  4707.                             {
  4708.                                 sprintf( mm->m.absender, "%s@%s%s", prefs.username, prefs.boxname, prefs.boxdomain ); 
  4709.                                 strcpy( mm->m.absenderreal, prefs.userrealname );
  4710.                             }
  4711.                             mix->changed = 1;
  4712.                         }
  4713.                         savebrettix( mix, mb );
  4714.                         freebrettix( mix );
  4715.                     }
  4716.                 }
  4717.                 hl2 = hl_findnextheader( hl2 );
  4718.             }
  4719.  
  4720.             n->m->m.absenderreal[á0 ]á= 0;
  4721.         }
  4722.     }
  4723.     DeleteFile( TMPCOMMENTNAME );
  4724.     DeleteFile( TMPEDITNAME );
  4725.     return( -1 );
  4726. }
  4727.  
  4728. static int doeditmails(void)
  4729. {
  4730.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  4731.     int rc=0;
  4732.  
  4733.     /*if(stricmp(cmb->b.name,"/╗SPOOL")) return(0);*/
  4734.  
  4735.     rtSetWaitPointer(w);
  4736.     if(!mmcount) {
  4737.         n=(struct vmail*)GetEntry(&mlist,getscrollercurrent());
  4738.         if(n) rc|=doeditmail(n);
  4739.         if( rc )
  4740.         {
  4741.             mix->changed = 1;
  4742.             cmb->newmails = 1;
  4743.         }
  4744.         return(rc);
  4745.     }
  4746.     savesel();
  4747.     while(n->n.mln_Succ) {
  4748.         if(n->sel) {
  4749.             rc|=doeditmail(n);
  4750.             n->sel=0;
  4751.         }
  4752.         n=(struct vmail*)n->n.mln_Succ;
  4753.     }
  4754.  
  4755.     if( rc )
  4756.     {
  4757.         cmb->newmails = 1;
  4758.         mix->changed = 1;
  4759.     }
  4760.     return(rc);
  4761. }
  4762.  
  4763. static int findmailnumbymidcrc( ULONG cmpid )
  4764. {
  4765.     struct vmail *n=(struct vmail*)mlist.lh_Head;
  4766.     int count = 0;
  4767.  
  4768.     while( n->n.mln_Succ )
  4769.     {
  4770.         if( n->m->m.midcrc == cmpid )
  4771.             return( count );
  4772.         count++;
  4773.         n = ( struct vmail * ) n->n.mln_Succ;    
  4774.     }
  4775.     return( -1 );
  4776. }
  4777.  
  4778. extern int scrollerenter;
  4779.  
  4780. static int doinhalt1( struct mbrett *mbrett, int nextnew )
  4781. {
  4782.     struct IntuiMessage *mp,im;
  4783.     long rc;
  4784.     int Done=0;
  4785.     ULONG oldflags;
  4786.     struct AppMessage *am;
  4787.     ULONG sig;
  4788.  
  4789.     cmb=mbrett;
  4790.  
  4791.     preport(0,1,"Brett: %s",mbrett->b.name);
  4792.     preport(1,1,"Lade Brettindex...");
  4793.  
  4794.     mix=loadbrettix(mbrett);
  4795.     if(!mix)
  4796.         return(0);
  4797.  
  4798.     /* Menus umschalten */
  4799.     OffMenu(w,SHIFTMENU(1)|SHIFTITEM(NOITEM));
  4800.  
  4801.     OnMenu(w,SHIFTMENU(2)|SHIFTITEM(NOITEM));
  4802.     OnMenu(w,SHIFTMENU(3)|SHIFTITEM(NOITEM));
  4803.  
  4804.     if(stricmp(mbrett->b.name,"/╗SPOOL"))
  4805.         OffMenu(w,SHIFTMENU(2)|SHIFTITEM(9));
  4806.     else
  4807.         OnMenu(w,SHIFTMENU(2)|SHIFTITEM(9));
  4808.  
  4809.     if(stricmp(mbrett->b.name,"/╗ARCHIV"))
  4810.         OnMenu(w,SHIFTMENU(2)|SHIFTITEM(5));
  4811.     else
  4812.         OffMenu(w,SHIFTMENU(2)|SHIFTITEM(5));
  4813.  
  4814.     if(mbrett->b.name[0]!='/')
  4815.     {
  4816.         OffMenu(w,SHIFTMENU(2)|SHIFTITEM(3)|SHIFTSUB(2));
  4817.         OffMenu(w,SHIFTMENU(2)|SHIFTITEM(3)|SHIFTSUB(3));
  4818.     }
  4819.     else
  4820.     {
  4821.         OnMenu(w,SHIFTMENU(2)|SHIFTITEM(3)|SHIFTSUB(2));
  4822.         OnMenu(w,SHIFTMENU(2)|SHIFTITEM(3)|SHIFTSUB(3));
  4823.     }
  4824.  
  4825.     if( rexxsig )
  4826.     {
  4827.         OffMenu( w, FULLMENUNUM( 7, 3, NOSUB ) );
  4828.         OnMenu( w, FULLMENUNUM( 7, 4, NOSUB ) );
  4829.     }
  4830.  
  4831.     /*lastmailnum = -1;*/
  4832.  
  4833. redo:
  4834.     preport( 1, 1, "Sortiere Brettindex..." );
  4835.     oldflags = prefs.flags & ( MDF_SHOWREAL | MDF_SORTDATE | MDF_GADGETS | MDF_FILTERRE );
  4836.     makemlist( &mix->maillist, &mlist );
  4837.     wrotenewmails = 0;
  4838.     cmb->newmails = 0;
  4839.  
  4840.     if( nextnew )
  4841.     {
  4842.         struct vmail *vm = ( struct vmail * ) mlist.lh_Head;
  4843.         lastmailnum = 0;
  4844.         while( vm->n.mln_Succ )
  4845.         {
  4846.             if( ( vm->m->m.flags & ( MMF_UNSEEN | MMF_SHOW ) ) ||
  4847.                 ( ( vm->m->m.flags & MMF_FOLD ) && newinfold( vm->m->firstbez ) ) )
  4848.             {
  4849.                 break;
  4850.             }
  4851.             vm = ( struct vmail * ) vm->n.mln_Succ;
  4852.             lastmailnum++;
  4853.         }
  4854.         nextnew--;
  4855.     }
  4856.     else if( newmailptr && ( oldbrettmaxnum != cmb->b.mails ) )
  4857.     {
  4858.         struct vmail *vm = (struct vmail *) mlist.lh_Head;
  4859.  
  4860.         lastmailnum = 0;
  4861.         while( vm->n.mln_Succ )
  4862.         {
  4863.             if( vm->m == newmailptr )
  4864.                 break;
  4865.             vm = (struct vmail *) vm->n.mln_Succ;
  4866.             lastmailnum++;
  4867.         }
  4868.         newmailptr = NULL;
  4869.     }
  4870.  
  4871.     oldbrettmaxnum = cmb->b.mails;
  4872.  
  4873.     calcmcount();
  4874.     setupscroller( &mlist, 1 );
  4875.     setscrollerstate( inhaltscstate );
  4876.     if( usecmpid )
  4877.     {
  4878.         usecmpid = FALSE;
  4879.         lastmailnum = findmailnumbymidcrc( cmpid );
  4880.     }
  4881.  
  4882.     if( lastmailnum >= 0 )
  4883.     {
  4884.         setscrollercurrent( lastmailnum );
  4885.         normalizescroller();
  4886.         updateprop();
  4887.         lastmailnum = -1;
  4888.     }
  4889.     displayscroller();
  4890.  
  4891.     dorexx( 1 );
  4892.  
  4893.     ClearPointer(w);
  4894.  
  4895.     if( nextnew )
  4896.     {
  4897.         nextnew = 0;
  4898.         readmails();
  4899.         dorexx( 1 );
  4900.         if( donextnewboard )
  4901.         {
  4902.             freeinhalt();
  4903.             return( 0 );
  4904.         }
  4905.         if( wrotenewmails)
  4906.         {
  4907.             wrotenewmails = FALSE;
  4908.             usecmpid = TRUE;
  4909.             freeinhalt();
  4910.             return(-1);
  4911.         }
  4912.         setscrollercurrent( lastmailnum );
  4913.         showcurrentitem();
  4914.     }
  4915.  
  4916.     while( !Done )
  4917.     {
  4918.         if( scrollerenter )
  4919.         {
  4920.             scrollerenter = FALSE;
  4921.             goto readmailslabel;
  4922.         }
  4923.  
  4924.         if(!(mp=(struct IntuiMessage*)GetMsg(w->UserPort)))
  4925.         {
  4926.             sig = Wait( rexxsig | appwindowsig | ( 1 << w->UserPort->mp_SigBit ) );
  4927.  
  4928.             if( sig & appwindowsig )
  4929.             {
  4930.                 while( ( am = ( struct AppMessage *) GetMsg( appwindowmp ) ) )
  4931.                 {
  4932.                     if( am->am_NumArgs )
  4933.                     {
  4934.                         char name[ 256 ];
  4935.                         struct WBArg *wba = am->am_ArgList;
  4936.  
  4937.                         NameFromLock( wba->wa_Lock, name, 255 );
  4938.                         AddPart( name, wba->wa_Name, 255 );
  4939.                     
  4940.                         lockwindow();
  4941.                         rc = donewmail( name, cmb, NULL );
  4942.                         unlockwindow();
  4943.                         if( rc )
  4944.                         {
  4945.                             ReplyMsg( am );
  4946.                             freeinhalt();
  4947.                             inhaltscstate = getscrollerstate();
  4948.                             wrotenewmails = cmb->newmails;
  4949.                             if( wrotenewmails )
  4950.                                 return( -1 );
  4951.                         }
  4952.                             
  4953.                     }
  4954.                     ReplyMsg( am );
  4955.                 }
  4956.             }
  4957.  
  4958.             if( rexxsig && ( sig & rexxsig ) )
  4959.                 dorexx( 1 );
  4960.  
  4961.             continue;
  4962.         }
  4963.         im=*mp;
  4964.         ReplyMsg(mp);
  4965.  
  4966.         switch(im.Class)
  4967.         {
  4968.             case IDCMP_REFRESHWINDOW:
  4969.                 BeginRefresh( w );
  4970.                 displayscroller();
  4971.                 EndRefresh( w, TRUE );
  4972.                 break;
  4973.  
  4974.             case IDCMP_CLOSEWINDOW:
  4975.                 doaskquit();
  4976.                 break;
  4977.  
  4978.             case IDCMP_NEWSIZE:
  4979.                 scrollerresize();
  4980.                 break;
  4981.  
  4982.             case MOUSEBUTTONS:
  4983.                 rc=scrollerdoclick(&im);
  4984.                 if( rc > 0 )
  4985.                 {
  4986. readmailslabel:
  4987.                     readmails();
  4988.                     dorexx( 1 );
  4989.                     if( donextnewboard )
  4990.                     {
  4991.                         Done = TRUE;
  4992.                         break;
  4993.                     }
  4994.                     if( wrotenewmails)
  4995.                     {
  4996.                         wrotenewmails = FALSE;
  4997.                         usecmpid = TRUE;
  4998.                         freeinhalt();
  4999.                         return(-1);
  5000.                     }
  5001.                     setscrollercurrent( lastmailnum );
  5002.                     showcurrentitem();
  5003.                 }
  5004.                 else if( rc == -1 )
  5005.                 {
  5006.                     Done = 1;
  5007.                     break;
  5008.                 }
  5009.                 else if( rc == -2 )
  5010.                 {
  5011.                     im.Class    = RAWKEY;
  5012.                     im.Code     = 0x36;
  5013.                     im.Qualifier     = 0;
  5014.                     goto rawkey;
  5015.                 }
  5016.                  calcmcount(); break;
  5017.             case MOUSEMOVE: scrollerdomove(&im); break;
  5018.             case GADGETDOWN: scrollerdogad(&im); break;
  5019.             case GADGETUP:
  5020.                 rc = scrollerdogad( &im );
  5021.                 if( !rc )
  5022.                     break;
  5023.                 else if( rc == 0x200 )
  5024.                 {
  5025.                     if( prefs.flags2 & MDF2_ESCCLRNEW )
  5026.                         im.Qualifier = 0;
  5027.                     else
  5028.                         im.Qualifier = QSHIFT;
  5029.  
  5030.                     Done = 1;
  5031.                     break;
  5032.                 }
  5033.                 else if( rc == 0x201 )
  5034.                 {
  5035.                     if( prefs.flags2 & MDF2_ESCCLRNEW )
  5036.                         im.Qualifier = QSHIFT;
  5037.                     else
  5038.                         im.Qualifier = 0;
  5039.  
  5040.                     Done = 1;
  5041.                     break;
  5042.                 }
  5043.  
  5044.                 im.Class    = RAWKEY;
  5045.                 im.Code     = rc & 0xff;
  5046.                 im.Qualifier = (rc & 0x100) ? QSHIFT : 0;
  5047.                 goto rawkey;
  5048.             case MENUPICK: rc=procmenu(im.Code,im.Qualifier);
  5049.                     if(rc<0)
  5050.                     {
  5051.                         if( didsortin )
  5052.                         {
  5053.                             /* Falls Spoolbrett, l÷schen */
  5054.                             if( !strcmp( cmb->b.name, "/╗SPOOL" ) )
  5055.                                 mix->changed = 0;
  5056.                             freeinhalt();
  5057.                             return( 0 );
  5058.                         }
  5059.                         if((prefs.flags&(MDF_SHOWREAL|MDF_SORTDATE|MDF_GADGETS|MDF_FILTERRE))!=oldflags)
  5060.                         {
  5061.                             inhaltscstate=getscrollerstate();
  5062.                             freemlist();
  5063.                             goto redo;
  5064.                         }
  5065.                         calcmcount();
  5066.                         break;
  5067.                     }
  5068.                     if( wrotenewmails )
  5069.                     {
  5070.                         freeinhalt();
  5071.                         unlockwindow();
  5072.                         return( -1 );
  5073.                     }
  5074.                     im.Code=rc&0xff;
  5075.                     im.Qualifier=(rc&0x100)?IEQUALIFIER_LSHIFT:0;
  5076.                     /* fallthrough */
  5077. rawkey:
  5078.             case RAWKEY: 
  5079.                     rc = scrollerdokey( &im );
  5080.                     if( rc == 1 )
  5081.                         calcmcount();
  5082.                     else if( rc ) switch(im.Code) {
  5083.  
  5084.                     case 0x0d:
  5085.                         if( im.Qualifier & IEQUALIFIER_RSHIFT )
  5086.                         {
  5087.                             domailinfo( getcurrentmail() );
  5088.                         }
  5089.                         break;
  5090.  
  5091.                     case 0x50:
  5092.                     case 0x51:
  5093.                     case 0x52:
  5094.                     case 0x53:
  5095.                     case 0x54:
  5096.                         dorexxcmd( 0, im.Code - 0x50 + ( ISSHIFT( &im ) ? 5 : 0 ) );
  5097.                         break;
  5098.  
  5099.                     case 0x55:
  5100.                     case 0x56:
  5101.                     case 0x57:
  5102.                     case 0x58:
  5103.                     case 0x59:
  5104.                         dorexxcmd( 2, im.Code - 0x55 + ( ISSHIFT( &im ) ? 5 : 0 ) );
  5105.                         break;
  5106.  
  5107.  
  5108.                     case 0x16: if( ISSHIFT( &im ) )
  5109.                                     dokilluser( getcurrentmail () );
  5110.                                 else
  5111.                                 {
  5112.                                     lockwindow();
  5113.                                     iteratemsglist( doextractmailuudecode );
  5114.                                     displayscroller();
  5115.                                     unlockwindow();
  5116.                                 }
  5117.                                 break;
  5118.                     case 0x2d:
  5119.                     case 0x2f:
  5120.                     case 0x4e:
  5121.                     case 0x4f: findfup(&im); break;
  5122.  
  5123.                     case 0x21: if(ISSHIFT(&im)) dosaveusers(); else { xscroller(); doarcmsg(); incscroller(); displayscroller(); } break;
  5124.  
  5125.                     case 0x5c: im.Qualifier |= QSHIFT;
  5126.  
  5127.                     case 0x1: if(ISSHIFT(&im)) { dosetnewmsg(); } break;
  5128.  
  5129.                     case 0x32: xscroller(); doextractmsg(ISSHIFT(&im)); incscroller(); displayscroller(); break;
  5130.  
  5131.                     case 0x34: xscroller(); doviewmsg(); displayscroller(); incscroller(); break;
  5132.  
  5133.                     case 0x22: xscroller(); doprintmsg(); displayscroller(); incscroller(); break;
  5134.  
  5135.                     case 0x04: xscroller(); lockwindow(); checksignatures(); unlockwindow(); displayscroller(); incscroller(); break;
  5136.  
  5137.                     case 0x5a:
  5138.                     case 0x25: doholdmsg(ISSHIFT(&im)); break;
  5139.  
  5140.                     case 0x5b:
  5141.                     case 0x24: dosetreadmsg(ISSHIFT(&im)); break;
  5142.  
  5143.                     case 0x28: dosetreadsel(); break;
  5144.  
  5145.                     case 0x3c: im.Qualifier |= QSHIFT;
  5146.                     case 0x2e: /* NUM-5 */
  5147.                     case 0x23: /* Mail falten */
  5148.                         inhaltscstate=getscrollerstate();
  5149.                         lastmailnum = getscrollercurrent();
  5150.                         dofold( ISSHIFT( &im ) ? 3 : 0);
  5151.                         freemlist();
  5152.                         goto redo;
  5153.                     case 0x14: inhaltscstate=getscrollerstate(); dofold(ISSHIFT(&im)?2:1); freemlist(); lastmailnum = 0; goto redo;
  5154.  
  5155.                     case 0x20: lockwindow(); inhaltscstate=getscrollerstate(); if(doanswer(1,ISSHIFT(&im)) && cmb->newmails ) { freeinhalt(); unlockwindow(); wrotenewmails = TRUE; return(-1); } unlockwindow(); break;
  5156.                     case 0x19: lockwindow(); inhaltscstate=getscrollerstate(); if(doanswer(0,ISSHIFT(&im)) && cmb->newmails ) { freeinhalt(); unlockwindow(); wrotenewmails = TRUE; return(-1); } unlockwindow(); break;
  5157.  
  5158.                     case 0x27:
  5159.                         if( ISSHIFT( &im ) )
  5160.                         {    
  5161.                             inhaltscstate = getscrollerstate();
  5162.                             
  5163.                             if( killthread() )
  5164.                             {
  5165.                                 if( getscrollercurrent() )
  5166.                                     inhaltscstate = ( inhaltscstate & 0xffff0000 ) + ( ( inhaltscstate & 0xffff ) - 1 );
  5167.  
  5168.                                 freemlist();
  5169.                                 makerlinks( mix );
  5170.                                 goto redo;
  5171.                             }
  5172.                         }
  5173.                         else
  5174.                             docopymails();
  5175.                         break;
  5176.  
  5177.                     case 0x43:
  5178.                     case 0x44:
  5179.                         readmails(); 
  5180.                         dorexx( 1 );
  5181.                         if( donextnewboard )
  5182.                         {
  5183.                             Done = TRUE;
  5184.                             break;
  5185.                         }
  5186.                         if( wrotenewmails )
  5187.                         {
  5188.                             wrotenewmails = FALSE;
  5189.                             usecmpid = TRUE;
  5190.                             freeinhalt();
  5191.                             return( -1 );
  5192.                         }
  5193.                         setscrollercurrent( lastmailnum );
  5194.                         showcurrentitem();
  5195.                         break;
  5196.  
  5197.                     case 0x0f:
  5198.                     case 0x5d:
  5199.                     case 0x45: Done=1; break;
  5200.  
  5201.                     case 0x5e:
  5202.                     case 0x36:
  5203.                                  /*n naechste neue, oder N alle neuen markieren */
  5204.                                  domarknew(ISSHIFT(&im));
  5205.  
  5206.                                  if( donextnewboard )
  5207.                                     Done = TRUE;
  5208.  
  5209.                                  break;
  5210.  
  5211.                     case 0x42: /* TAB naechste ungelesene */
  5212.                                  domarknextunread(); break;
  5213.  
  5214.                     case 0x37: /*m = nach absender, M alle */
  5215.                                 domarkbyabsender(&im); displayscroller(); break;
  5216.  
  5217.                     case 0x12: lockwindow();
  5218.                         inhaltscstate=getscrollerstate();
  5219.                         if( (ISSHIFT(&im) ? doeditmails() : donewmail( NULL, cmb, NULL )) && cmb->newmails )
  5220.                         {
  5221.                             freeinhalt();
  5222.                             unlockwindow();
  5223.                             wrotenewmails = TRUE;
  5224.                             return(-1);
  5225.                         }
  5226.                         unlockwindow();
  5227.                         break;
  5228.  
  5229.                     case 0x17: /*i*/ doinvsel(); displayscroller(); break;
  5230.  
  5231.                     case 0x4a:
  5232.                     case 0x46: 
  5233.                         if(ISSHIFT(&im))
  5234.                             doundelmsg();
  5235.                         else
  5236.                             dodelmsg();
  5237.                         break;
  5238.  
  5239.                     case 0x5f: showguidegads(&im,"nachrichtenauswahl"); break;
  5240.  
  5241.                     case 0x11:
  5242.                         lockwindow();
  5243.                         if( ISSHIFT( &im ) )
  5244.                         {
  5245.                             iteratemsglist( resendmail );
  5246.                         }
  5247.                         else
  5248.                         {
  5249.                             if( doweiter(&im) && cmb->newmails )
  5250.                             {
  5251.                                 wrotenewmails = TRUE;
  5252.                                 freeinhalt();
  5253.                                 unlockwindow();
  5254.                                 return( -1 );
  5255.                             }
  5256.                         }
  5257.                         displayscroller();
  5258.                         unlockwindow();
  5259.                         break;
  5260.  
  5261.                     case 0x18:    // Markierungen wiederherstellen
  5262.                             restoresel();
  5263.                             displayscroller();
  5264.                             break;
  5265.  
  5266.                      }
  5267.                      calcmcount();
  5268.                      break;
  5269.  
  5270.             case IDCMP_MENUHELP: domenuhelp("brett",&im); break;
  5271.         }
  5272.  
  5273.     }
  5274.  
  5275.     if( prefs.flags2 & MDF2_ESCCLRNEW )
  5276.     {
  5277.         if( ! ISSHIFT( &im ) )
  5278.             domarkseen();
  5279.     }
  5280.     else
  5281.     {
  5282.         if( ISSHIFT( &im ) )
  5283.             domarkseen();
  5284.     }
  5285.  
  5286.     freeinhalt();
  5287.     return(0);
  5288. }
  5289.  
  5290. void doinhalt( struct mbrett *m, int nextnew )
  5291. {
  5292.     inhaltscstate    = 0;
  5293.     lastmailnum     = 0;
  5294.     oldbrettmaxnum    = 0;
  5295.     newmailptr        = 0;
  5296.     wrotenewmails     = 0;
  5297.  
  5298.     didsortin = FALSE;
  5299.  
  5300.     while( doinhalt1( m, nextnew ) )
  5301.         nextnew = 0;
  5302. }
  5303.