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

  1. #include "microdot.h"
  2. #include "ogre.h"
  3. #include "ogre_protos.h"
  4.  
  5. #include <libraries/amigaguide.h>
  6. #include <clib/amigaguide_protos.h>
  7. #include <pragmas/amigaguide_pragmas.h>
  8. #include <proto/console.h>
  9. #include <proto/locale.h>
  10.  
  11. #include <dos/dostags.h>
  12. #include <dos/exall.h>
  13.  
  14. static int makefilelistexall( BPTR dirlock, char *pattern, char *buffer, int buffersize )
  15. {
  16.     struct ExAllControl *eac;
  17.     char pp[ 256 ];
  18.     struct ExAllData *ead;
  19.     void *eadmem;
  20.     int counter = 0;
  21.     int cont, entrylen;
  22.     int entries;
  23.  
  24.     ParsePatternNoCase( pattern, pp, 256 );
  25.     eadmem = AllocVec( 4096, MEMF_CLEAR );
  26.     if( !eadmem )
  27.         return( 0 );
  28.  
  29.     eac = AllocDosObjectTags( DOS_EXALLCONTROL, TAG_DONE );
  30.     if( !eac )
  31.     {
  32.         FreeVec( eadmem );
  33.         return( 0 );
  34.     }
  35.     eac->eac_MatchString = pp;
  36.     eac->eac_LastKey = 0;
  37.  
  38.     do
  39.     {
  40.         cont = ExAll( dirlock, eadmem, 4096, ED_TYPE, eac );
  41.         ead = eadmem;
  42.  
  43.         entries = eac->eac_Entries;
  44.  
  45.         while( entries-- && ead )
  46.         {
  47.             /* Dir */
  48.             if( ead->ed_Type < 0 )
  49.             {
  50.                 entrylen = strlen( ead->ed_Name ) + 1;
  51.  
  52.                 if( entrylen >= buffersize )
  53.                 {
  54.                     buffersize = 0;
  55.                     break;
  56.                 }
  57.  
  58.                 /* Anfⁿgen */
  59.                 strcpy( buffer, ead->ed_Name );
  60.                 buffer += entrylen;
  61.                 buffersize -= entrylen;
  62.                 counter++;
  63.             }
  64.             ead = ead->ed_Next;
  65.         }
  66.     } while( cont && buffersize );
  67.  
  68.     if( !buffersize && isv39 )
  69.         ExAllEnd( dirlock, eadmem, 4096, ED_TYPE, eac );
  70.  
  71.     FreeVec( eadmem );
  72.     FreeDosObject( DOS_EXALLCONTROL, eac );
  73.  
  74.     *buffer = 0;
  75.  
  76.     return( counter );
  77. }
  78.  
  79. int makefilelist( char *dir, char *pattern, char *buffer, int buffersize )
  80. {
  81.     BPTR dirlock = Lock( dir, SHARED_LOCK );
  82.     struct FileInfoBlock *fib;
  83.     int counter = 0;
  84.     int entrylen;
  85.  
  86.     if( !dirlock )
  87.     {
  88.         char buffer2[á256 ];
  89.         char *p;
  90.  
  91.         strcpy( buffer2, dir );
  92.         p = strchr( buffer2, 0 ) - 1;
  93.         if( buffer2[á0 ] && ( *p == '/' ) )
  94.             *p = 0;
  95.         dirlock = Lock( buffer2, SHARED_LOCK );
  96.         if( !dirlock )
  97.             return( 0 );
  98.     }
  99.  
  100.     if( isv37 )
  101.     {
  102.         counter =  makefilelistexall( dirlock, pattern, buffer, buffersize );
  103.         UnLock( dirlock );
  104.         return( counter );
  105.     }
  106.  
  107.     fib = allocfib();
  108.     if( !fib )
  109.     {
  110.         UnLock( dirlock );
  111.         return( 0 );
  112.     }
  113.  
  114.     if( Examine( dirlock, fib ) )
  115.     {
  116.         while( ExNext( dirlock, fib ) )
  117.         {
  118.             /* Verzeichnis? */
  119.             if( fib->fib_DirEntryType > 0 )
  120.                 continue;
  121.  
  122.             /* Pattern match */
  123.             if( !astcsma( fib->fib_FileName, pattern ) )
  124.                 continue;
  125.  
  126.             entrylen = strlen( fib->fib_FileName ) + 1;
  127.  
  128.             if( entrylen >= buffersize )
  129.                 break;
  130.  
  131.             /* Anfⁿgen */
  132.             strcpy( buffer, fib->fib_FileName );
  133.             buffer += entrylen;
  134.             buffersize -= entrylen;
  135.             counter++;
  136.         }
  137.     }
  138.  
  139.     *buffer = 0;
  140.  
  141.     freefib( fib );
  142.     UnLock( dirlock );
  143.  
  144.     return( counter );
  145. }
  146.  
  147.  
  148. BPTR OpenAppend( char *name )
  149. {
  150.     BPTR f;
  151.  
  152.     f = Open( name, MODE_OLDFILE );
  153.     if( f )
  154.     {
  155.         Seek( f, 0, OFFSET_END );
  156.         return( f );
  157.     }
  158.     f = Open( name, MODE_NEWFILE );
  159.     return( f );
  160. }
  161.  
  162. /* Prⁿft, ob File existiert */
  163.  
  164. int exists( char * filename )
  165. {
  166.     BPTR lock = Lock( filename, SHARED_LOCK );
  167.  
  168.     if( lock )
  169.     {
  170.         UnLock( lock );
  171.         return( -1 );
  172.     }
  173.     else
  174.         return( 0 );
  175. }
  176.  
  177. BPTR OpenCon( char *cfg )
  178. {
  179.     static char buf[á256 ];
  180.  
  181.     strcpy( buf, cfg );
  182.     if( pubscreenname )
  183.     {
  184.         asprintf( buf, "/SCREEN%s", pubscreenname );
  185.     }
  186.  
  187.     return( Open( buf, MODE_OLDFILE ) );
  188. }
  189.  
  190.  
  191. BPTR openconsole( char *title )
  192. {
  193.     char titmem[á128 ];
  194.  
  195.     convertstring( prefs.console_window, titmem,
  196.         't', title,
  197.         0
  198.     );
  199.  
  200.     return( OpenCon( titmem ) );
  201. }
  202.  
  203.  
  204. struct FileInfoBlock *allocfib( void )
  205. {
  206.     if( isv37 )
  207.         return( AllocDosObject( DOS_FIB, TAG_DONE ) );
  208.     else
  209.         return( AllocMem( sizeof( struct FileInfoBlock ), MEMF_CLEAR | MEMF_PUBLIC ) );
  210. }
  211.  
  212. void freefib( struct FileInfoBlock *fib )
  213. {
  214.     if( fib )
  215.     {
  216.         if( isv37 )
  217.             FreeDosObject( DOS_FIB, fib );
  218.         else
  219.             FreeMem( fib, sizeof( *fib ) );
  220.     }
  221. }
  222.  
  223. void __stdargs convertstring( char *from, char *to, ULONG id, char *data, ... )
  224. {
  225.     ULONG *idp;
  226.     char **datap;
  227.     int ch;
  228.  
  229.     while( *from )
  230.     {
  231.         if( *from != '%' )
  232.         {
  233.             *to++ = *from++;
  234.             continue;
  235.         }
  236.         from++;
  237.         ch         = *from++;
  238.         idp     = &id;
  239.         datap     = &data;
  240.         while( *idp )
  241.         {
  242.             /* Replacement char gefunden */
  243.             if( *idp == ch )
  244.             {
  245.                 strcpy( to, *datap );
  246.                 to = strchr( to, 0 );
  247.                 break;
  248.             }
  249.             idp++; idp++;
  250.             datap++; datap++;
  251.         }
  252.         /* Nicht gefunden, Zeichen 1:1 ⁿbernehmen */
  253.         if( !*idp )
  254.             *to++ = ch;
  255.     }
  256.     *to = 0;
  257. }
  258.  
  259.  
  260. void num2b64( long val, char *dest )
  261. {
  262.     int c;
  263.  
  264.     static char sextet[] =  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  265.          "abcdefghijklmnopqrstuvwxyz"
  266.          "0123456789+$";
  267.  
  268.     for( c = 4; c >= 0; c-- )
  269.     {
  270.         dest[c] = sextet[ val % 64 ];
  271.         val = val / 64;
  272.     }
  273.     dest[5]á= 0;
  274. }
  275.  
  276. int copyicon( char *from, char *to )
  277. {
  278.     struct DiskObject *obj;
  279.  
  280.     if( !from )
  281.         return( -1 );
  282.  
  283.     if( isv37 )
  284.     {
  285.         obj = GetDiskObjectNew( from );
  286.     }
  287.     else
  288.     {
  289.         obj = GetDiskObject( from );
  290.     }
  291.  
  292.     if( !obj )
  293.         return( -1 );
  294.  
  295.     PutDiskObject( to, obj );
  296.     FreeDiskObject( obj );
  297.  
  298.     return( 0 );
  299. }
  300.  
  301.  
  302. char *errorstring( int n )
  303. {
  304.     static char errorbuf[64];
  305.  
  306.     if( isv37 )
  307.     {
  308.         Fault( n, NULL, errorbuf, 64 );
  309.         return( errorbuf );
  310.  
  311.     }
  312.  
  313.     return( "" );
  314. }
  315.  
  316. int fileexistsreq( char *file )
  317. {
  318.     BPTR tl;
  319.     int rc;
  320.  
  321.     tl = Lock( file, SHARED_LOCK );
  322.     if( !tl )
  323.         return( 1 );
  324.  
  325.     UnLock( tl );
  326.     rc = askreq("Datei\n%s\nexistiert bereits!","▄ber_schreiben|AnhΣn_gen|Abbruch", file );
  327.  
  328.     return( rc );
  329. }
  330.  
  331. void nofilereq( char *file, int rc )
  332. {
  333.     askreq("Datei\n%s\nlΣ▀t sich nicht ÷ffnen (Fehler %ld)\n%s","Abbruch",file, rc, errorstring( rc ) );
  334. }
  335.  
  336. static void *windowlock;
  337. void lockwindow(void)
  338. {
  339.     if( !wbwindow )
  340.         windowlock = rtLockWindow( w );
  341.     else
  342.     {
  343.         rtSetWaitPointer( w );
  344.         w->Flags |= WFLG_RMBTRAP;
  345.     }
  346. }
  347. void unlockwindow(void)
  348. {
  349.     struct Message *m;
  350.  
  351.     if( !wbwindow )
  352.     {
  353.         rtUnlockWindow( w, windowlock );
  354.     }
  355.     else
  356.     {
  357.         while( ( m = GetMsg( w->UserPort ) ) )
  358.             ReplyMsg( m );
  359.         w->Flags &= ~WFLG_RMBTRAP;
  360.         ClearPointer( w );
  361.     }
  362. }
  363.  
  364. extern struct Screen *scr;
  365.  
  366. #define dwrite(s) Write(Output(),s,strlen(s))
  367.  
  368. void showguidenum( char *head, int n )
  369. {
  370.     if( n < 0 || n >= 65535 )
  371.     {
  372.         showguide( head );
  373.     }
  374.     else
  375.     {
  376.         char txt[64];
  377.         sprintf( txt, "%s_%ld", head, n );
  378.         showguide( txt );
  379.     }
  380. }
  381.  
  382. static AMIGAGUIDECONTEXT aga;
  383. struct Library *AmigaGuideBase;
  384.  
  385. static char guidename[á256 ];
  386. #define TESTGUIDE(s) strcpy(guidename,s);if(exists(guidename))return(0);
  387. #include <constructor.h>
  388. CONSTRUCTOR_P(findguide,25000)
  389. {
  390.     TESTGUIDE("MicroDot.GUIDE");
  391.     TESTGUIDE("HELP:MicroDot.GUIDE");
  392.     TESTGUIDE("HELP:Deutsch/MicroDot.GUIDE");
  393.     TESTGUIDE("HELP:GUIDE/MicroDot.GUIDE");
  394.     TESTGUIDE("MicroDot.GUIDE");
  395.     return( 0 );
  396. }
  397.  
  398. void showguide( char *node )
  399. {
  400.     static char cmd[á80 ];
  401.     static char *ag_context[]á= { "MAIN", 0 };
  402.  
  403.     //Printf( "showguide '%s'\n", node );
  404.  
  405.     if( !aga )
  406.     {
  407.         struct NewAmigaGuide nag;
  408.         struct AmigaGuideMsg *agm;
  409.         int ok = FALSE;
  410.  
  411.         pushhomedir();
  412.         if( !AmigaGuideBase )
  413.             AmigaGuideBase = OpenLibrary( "amigaguide.library", 34 );
  414.         if( !AmigaGuideBase )
  415.         {
  416.             displaybeep();
  417.             askreq( "Die 'amigaguide.library' V34 (oder h÷her)\nlΣ▀t sich nicht ÷ffnen!", "Keine Hilfe verfⁿgbar" );
  418.             popdir();
  419.             return;
  420.         }
  421.  
  422.         if( !exists( guidename ) )
  423.         {
  424.             displaybeep();
  425.             askreq( "Die Hilfsdatei 'MicroDot.Guide'\nlΣ▀t sich nicht ÷ffnen!","Keine Hilfe verfⁿgbar");
  426.             popdir();
  427.             return;
  428.         }
  429.         memset( &nag, 0, sizeof( nag ) );
  430.  
  431.         nag.nag_Lock           = NULL;
  432.         nag.nag_Name           = guidename;
  433.         nag.nag_Screen         = scr;
  434.         // nag.nag_Flags          = HTF_CACHE_NODE;
  435.         nag.nag_BaseName    = "MicroDot";
  436.         nag.nag_ClientPort  = "MICRODOT_HELP";
  437.         nag.nag_Context        = ag_context;
  438.         // nag.nag_Node        = "MAIN";
  439.  
  440.         aga = OpenAmigaGuideAsyncA( &nag, TAG_DONE );
  441.         if( !aga )
  442.         {
  443.             displaybeep();
  444.             popdir();
  445.             askreq( "Die Hilfsdatei 'microdot.guide'\nlΣ▀t sich nicht ÷ffnen!","Keine Hilfe verfⁿgbar");
  446.             return;
  447.         }
  448.  
  449.         SetAmigaGuideContext( aga, NULL, NULL );
  450.  
  451.         /* Active Tool-ID abwarten */
  452.         while( !ok )
  453.         {
  454.             Wait( AmigaGuideSignal( aga ) );
  455.             while( agm = GetAmigaGuideMsg( aga ) )
  456.             {
  457.                 if( agm->agm_Type == ( ActiveToolID ) )
  458.                     ok = TRUE;
  459.                 ReplyAmigaGuideMsg( agm );
  460.             }
  461.         }
  462.  
  463.         popdir();
  464.     }
  465.  
  466.     sprintf( cmd, "ALINK %s", node );
  467.     SendAmigaGuideCmdA( aga, cmd, NULL );
  468. }
  469.  
  470. void closeguide( void )
  471. {
  472.     if( aga )
  473.     {
  474.         struct AmigaGuideMsg *agm;
  475.  
  476.         while( agm = GetAmigaGuideMsg( aga ) )
  477.             ReplyAmigaGuideMsg( agm );
  478.  
  479.         CloseAmigaGuide( aga );
  480.         aga = NULL;
  481.     }
  482.  
  483.     if( AmigaGuideBase )
  484.     {
  485.         CloseLibrary( AmigaGuideBase );
  486.         AmigaGuideBase = NULL;
  487.     }
  488. }
  489.  
  490. void calleditor( char *file )
  491. {
  492.     char buff[128];
  493.     long rc;
  494.     char *p;
  495.  
  496.     p = strchr( prefs.editor, '%' );
  497.     if( p && ( p[1]=='s' || p[1]=='S' ) )
  498.     {
  499.         sprintf( buff, prefs.editor, file, "", "", "", "", 0, 0, 0 );
  500.     }
  501.     else sprintf( buff, "%s %s", prefs.editor, file );
  502.  
  503.     /*lockwindow();*/
  504.     if( !wbwindow && prefs.editor_wb )
  505.         WBenchToFront();
  506.  
  507.     if( isv37 )
  508.     {
  509.         rc = SystemTags( buff, NP_StackSize, max( prefs.editor_stack, 4096 ), TAG_DONE );
  510.     }
  511.     else
  512.     {
  513.         rc = system( buff );
  514.     }
  515.  
  516.     ScreenToFront( scr );
  517.  
  518.     /*unlockwindow();*/
  519.  
  520.     if(rc<0)
  521.     {
  522.         askreq("Fehler beim Editor-Aufruf:\n%s\n","Abbruch",buff);
  523.         return;
  524.     }
  525. }
  526.  
  527. /* Prueft & baut Pfad auf 0 = ok, != IoErr */
  528. long checkpath(char *path)
  529. {
  530.     char buff[256];
  531.     char *p;
  532.     BPTR lock;
  533.  
  534.     lock=Lock(path,SHARED_LOCK);
  535.     if(lock) {
  536.         UnLock(lock);
  537.         return(0);
  538.     }
  539.  
  540.     p=strchr(path,':');
  541.     if(!p) p=path;
  542.  
  543.     while(*p) {
  544.         strcpy(buff,path);
  545.         while(*p&&*p!='/') p++;
  546.         buff[p-path]=0; if(*p)p++;
  547.         /*Printf("check:%s\n",buff);*/
  548.         lock=Lock(buff,SHARED_LOCK);
  549.         if(!lock) {
  550.             lock=CreateDir(buff);
  551.             if(!lock) return(IoErr());
  552.         }
  553.         UnLock(lock);
  554.     }
  555.     return(0);
  556. }
  557.  
  558. void addpart(char *part,char *file)
  559. {
  560.     if(!file) return;
  561.     if(*file=='/') file++;
  562.     if(part[0] && part[strlen(part)-1]!=':' && part[strlen(part)-1]!='/') strcat(part,"/");
  563.     strcat(part,file);
  564.  
  565. }
  566.  
  567. #define D_S(type,name) char a_##name[sizeof(type)+3]; \
  568.                        type *name = (type *)((LONG)(a_##name+3) & ~3);
  569. long getfilelen( char * file )
  570. {
  571.     BPTR lock;
  572.     long size;
  573.     D_S(struct FileInfoBlock,fib);
  574.  
  575.     lock = Lock( file, SHARED_LOCK );
  576.     if( !lock )
  577.         return( -1 );
  578.  
  579.     Examine( lock, fib );
  580.     UnLock( lock );
  581.     size = fib->fib_Size;
  582.  
  583.     return( size );
  584. }
  585.  
  586. void makedospath(char *path)
  587. {
  588.     if(!path || !*path) return;
  589.     if(path[strlen(path)-1]!='/' && path[strlen(path)-1]!=':') strcat(path,"/");
  590. }
  591.  
  592. void makebrettname(char *name)
  593. {
  594.     char *p;
  595.  
  596.     if(!name || !name[0]) return;
  597.  
  598.     p = name;
  599.     strupr( p );
  600.     if( p[ 0 ] != '/' )
  601.     {
  602.         p[ 78 ] = 0;
  603.         strins( p, "/" );
  604.     }
  605.     while((p=strchr(name,' ')))
  606.         strcpy(p,&p[1]);
  607.     p=strchr(name,'/');
  608.     do
  609.     {
  610.         p++;
  611.         if(*p=='/') strcpy(p,&p[1]);
  612.         p=strchr(p,'/');
  613.     } while(p);
  614. }
  615.  
  616. void makebrettnamenoup(char *name)
  617. {
  618.     char *p;
  619.  
  620.     if(!name || !name[0]) return;
  621.  
  622.     p = name;
  623.     if( p[ 0 ] != '/' )
  624.     {
  625.         p[ 78 ] = 0;
  626.         strins( p, "/" );
  627.     }
  628.     while((p=strchr(name,' ')))
  629.         strcpy(p,&p[1]);
  630.     p=strchr(name,'/');
  631.     do
  632.     {
  633.         p++;
  634.         if(*p=='/') strcpy(p,&p[1]);
  635.         p=strchr(p,'/');
  636.     } while(p);
  637. }
  638.  
  639. char *filepart(char *path)
  640. {
  641.     char *p=strchr(path,0);
  642.  
  643.     while(p>=path) {
  644.         if(*p=='/'||*p==':') return(++p);
  645.         p--;
  646.     }
  647.     return(path);
  648. }
  649.  
  650. int copyfile(char *from,char *to)
  651. {
  652.     long len=getfilelen(from);
  653.     BPTR f1,f2;
  654.     void *buffer;
  655.     long blen;
  656.     int rc;
  657.  
  658.     if(len<0) return(IoErr());
  659.     f1 = Open( from, MODE_OLDFILE );
  660.     if(!f1) return(IoErr());
  661.     f2 = Open( to, MODE_NEWFILE );
  662.     if(!f2)
  663.     {
  664.         rc=IoErr();
  665.         Close(f1);
  666.         return(rc);
  667.     }
  668.  
  669.     buffer = allocbuffmem( len, &blen );
  670.  
  671.     while(len>0)
  672.     {
  673.         rc=Read(f1,buffer,blen);
  674.         if( rc < 1 )
  675.             break;
  676.         Write(f2,buffer,rc);
  677.         len-=rc;
  678.     }
  679.  
  680.     freebuffmem();
  681.     Close(f1);
  682.     Close(f2);
  683.  
  684.     return(0);
  685. }
  686.  
  687. int movefile( char *from, char *to )
  688. {
  689.     int rc;
  690.  
  691.     DeleteFile( to );
  692.     if( Rename( from, to ) )
  693.         return( 0 );
  694.     rc = IoErr();
  695.     if( rc != ERROR_RENAME_ACROSS_DEVICES )
  696.         return( rc );
  697.     rc = copyfile( from, to );
  698.     if( rc )
  699.         return( rc );
  700.     DeleteFile( from );
  701.     return( 0 );
  702. }
  703.  
  704. extern struct KeyMap conkeymap;
  705. int getrawkeycode( char *string )
  706. {
  707.     int c;
  708.     UBYTE cmp[4];
  709.     UBYTE *dead;
  710.  
  711.     for( c = 0; c < 64; c++ )
  712.     {
  713.  
  714.         /*if( ( conkeymap.km_LoKeyMapTypes[c] & KC_VANILLA ) != KC_VANILLA )
  715.             continue;*/
  716.         if( conkeymap.km_LoKeyMapTypes[c] & KCF_STRING )
  717.             continue;
  718.  
  719.         if( conkeymap.km_LoKeyMapTypes[c] & KCF_DEAD )
  720.         {
  721.             memcpy( &dead, &conkeymap.km_LoKeyMap[c], 4 );
  722.  
  723.             if( dead[0] & DPF_MOD )
  724.             {
  725.                 dead = &dead[ dead[1] ];
  726.  
  727.                 if( dead[0]á== string[0]á)
  728.                 {
  729.                     return( c );
  730.                 }
  731.             }
  732.             if( dead[2] & DPF_MOD )
  733.             {
  734.                 dead = &dead[ dead[3] ];
  735.  
  736.                 if( dead[0]á== string[0]á)
  737.                 {
  738.                     return( c | 0x100);
  739.                 }
  740.             }
  741.  
  742.             if( !dead[0] && dead[1] == string[0]á)
  743.             {
  744.                 return( c );
  745.             }
  746.  
  747.             if( !dead[2] && dead[3] == string[0]á)
  748.             {
  749.                 return( c | 0x100 );
  750.             }
  751.         }
  752.         else
  753.         {
  754.             memcpy( cmp, &conkeymap.km_LoKeyMap[c], 4 );
  755.             if( cmp[3]á== string[0] )
  756.             {
  757.                 return( c );
  758.             }
  759.             if( cmp[2] == string[0]á)
  760.             {
  761.                 return( c | 0x100 );
  762.             }
  763.         }
  764.     }
  765.  
  766.     return( 0 );
  767. }
  768.  
  769. char *rawkeyconvert( struct IntuiMessage *im )
  770. {
  771.     struct InputEvent ie;
  772.     static char buffer[16];
  773.  
  774.     memset( &ie, 0, sizeof( ie ) );
  775.     buffer[0] = 0;
  776.  
  777.     ie.ie_Class = IECLASS_RAWKEY;
  778.     ie.ie_Code = im->Code;
  779.     ie.ie_Qualifier = im->Qualifier;
  780.  
  781.     RawKeyConvert( &ie, buffer, 16, NULL );
  782.  
  783.     return( buffer );
  784. }
  785.  
  786. #if 0
  787. int str2_7bit( UBYTE *string, UBYTE *dest )
  788. {
  789.     int count = 0;
  790.  
  791.     while( *string )
  792.     {
  793.         if( *string>126 )
  794.         {
  795.             switch( *string )
  796.             {
  797.                 case (UBYTE)'Σ':
  798.                     *dest++ = 'a';
  799.                     *dest++ = 'e';
  800.                     count += 2;
  801.                     break;
  802.                 case (UBYTE)'÷':
  803.                     *dest++ = 'o';
  804.                     *dest++ = 'e';
  805.                     count += 2;
  806.                     break;
  807.                 case (UBYTE)'ⁿ':
  808.                     *dest++ = 'u';
  809.                     *dest++ = 'e';
  810.                     count += 2;
  811.                     break;
  812.                 case (UBYTE)'─':
  813.                     *dest++ = 'A';
  814.                     *dest++ = 'e';
  815.                     count += 2;
  816.                     break;
  817.                 case (UBYTE)'╓':
  818.                     *dest++ = 'O';
  819.                     *dest++ = 'e';
  820.                     count += 2;
  821.                     break;
  822.                 case (UBYTE)'▄':
  823.                     *dest++ = 'U';
  824.                     *dest++ = 'e';
  825.                     count += 2;
  826.                     break;
  827.                 case (UBYTE)'▀':
  828.                     *dest++ = 's';
  829.                     *dest++ = 'z';
  830.                     count += 2;
  831.                     break;
  832.                 case (UBYTE)'╗':
  833.                     *dest++ = '>';
  834.                     count++;
  835.                     break;
  836.                 case (UBYTE)'½':
  837.                     *dest++ = '<';
  838.                     count++;
  839.                     break;
  840.                 default:
  841.                     sprintf( dest, "\\%02lx", *((UBYTE*)string) );
  842.                     dest += 3;
  843.                     count += 3;
  844.                     break;
  845.             }
  846.             string++;
  847.         }
  848.         else
  849.         {
  850.             *dest++ = *string++;
  851.             count++;
  852.         }
  853.     }
  854.     *dest = 0;
  855.     return( count );
  856. }
  857. #endif
  858.  
  859. /* Wort ausschneiden (bei word==-1 das letzte) */
  860.  
  861. void sbreakword(char *to,char *from,int word,int maxlen)
  862. {
  863.     int count;
  864.     char *p;
  865.  
  866.     /* Anzahl W÷rter feststellen */
  867.     for(count=0,p=from; *p; p++) {
  868.         if(isspace(*p)) count++;
  869.     }
  870.     /* count enthΣlt anzahl w÷rter -1 */
  871.     if(word<0) word=count;
  872.  
  873.     /* word'te wort finden */
  874.     for(p=from; word; word--) {
  875.         while(*p && !isspace(*p)) p++;
  876.     }
  877.     if(isspace(*p)) p++;
  878.  
  879.     /* Kopieren */
  880.     while(*p && !isspace(*p) && maxlen--) *to++=*p++;
  881.     *to=0;
  882. }
  883.  
  884. static APTR buffmem;
  885. static ULONG buffsize;
  886. static struct SignalSemaphore buffsem;
  887.  
  888. void initbuffmem( void )
  889. {
  890.     InitSemaphore( &buffsem );
  891. }
  892.  
  893. void exitbuffmem( void )
  894. {
  895.     ObtainSemaphore( &buffsem );
  896.     if( buffmem )
  897.         FreeMem( buffmem, buffsize );
  898. }
  899.  
  900. void flushbuffmem( void )
  901. {
  902.     if( AttemptSemaphore( &buffsem ) )
  903.     {
  904.         if( buffmem )
  905.         {
  906.             FreeMem( buffmem, buffsize );
  907.             buffmem = NULL;
  908.         }
  909.         ReleaseSemaphore( &buffsem );
  910.     }
  911. }
  912.  
  913. APTR allocbuffmem( int maxsize, int *realsizeptr )
  914. {
  915.     int realsize = maxsize;
  916.  
  917.     ObtainSemaphore( &buffsem );
  918.     if( buffmem )
  919.     {
  920.         if( buffsize >= maxsize )
  921.         {
  922.             *realsizeptr = maxsize;
  923.             return( buffmem );
  924.         }
  925.         FreeMem( buffmem, buffsize );
  926.         buffmem = NULL;
  927.     }
  928.  
  929.     for(;;)
  930.     {
  931.         buffmem = AllocMem( realsize, memf_no_expunge );
  932.         if( buffmem )
  933.             break;
  934.         if( realsize > 256 )
  935.             realsize /= 2;
  936.         else
  937.             Delay( 10 );
  938.     }
  939.  
  940.     buffsize = *realsizeptr = realsize;
  941.     return( buffmem );
  942. }
  943.  
  944. void freebuffmem( void )
  945. {
  946.     if( buffsize >= 128000 )
  947.     {
  948.         FreeMem( buffmem, buffsize );
  949.         buffmem = NULL;
  950.     }
  951.     ReleaseSemaphore( &buffsem );
  952. }
  953.  
  954. char *StrDupPooled( APTR pool, char *string )
  955. {
  956.     char *new = LibAllocPooled( pool, strlen( string ) + 1 );
  957.     if( new )
  958.         strcpy( new, string );
  959.     return( new );
  960. }
  961.  
  962. void newdofrselfile( struct ogwin *ogw, UWORD id, char *title )
  963. {
  964.     char filename[108];
  965.     char path[256],*p;
  966.  
  967.     filename[0]=0;
  968.     p = ogreStringValue( ogw, id );
  969.     strcpy( filename, filepart( p ) );
  970.     strcpy( path, p );
  971.     p = filepart( path );
  972.     if( p )
  973.         *p = 0;
  974.     rtChangeReqAttr(fr[FR_PREFSMISC],RTFI_Dir,path,TAG_DONE);
  975.  
  976.     if(rtFileRequest(fr[FR_PREFSMISC],filename,title,
  977.         RT_Screen,scr,RT_ReqPos,REQPOS_CENTERSCR,
  978.         TAG_DONE)) {
  979.             strcpy(path,fr[FR_PREFSMISC]->Dir);
  980.             addpart( path, filename );
  981.             ogreSetStringValue( ogw, id, path );
  982.     }
  983.  
  984. }
  985.  
  986. void newdofrseldir( struct ogwin *ogw, UWORD id, char *title )
  987. {
  988.     char filename[108];
  989.     char path[256],*p;
  990.  
  991.     filename[0]=0;
  992.     p = ogreStringValue( ogw, id );
  993.     strcpy( path, p );
  994.     rtChangeReqAttr( fr[ FR_PREFSMISC ], RTFI_Dir, path, TAG_DONE);
  995.  
  996.     if( rtFileRequest( fr[ FR_PREFSMISC ],
  997.         filename,
  998.         title,
  999.         RT_Screen, scr,
  1000.         RTFI_Flags, /*FREQF_SELECTDIRS |*/ FREQF_NOFILES,
  1001.         RT_ReqPos, REQPOS_CENTERSCR,
  1002.         TAG_DONE ))
  1003.     {
  1004.             strcpy( path, fr[ FR_PREFSMISC ] -> Dir);
  1005.             if( path[á0 ]á)
  1006.             {
  1007.                 p = strchr( path, 0 ) - 1;
  1008.                 if( *p != ':' && *p != '/'á)
  1009.                     strcat( p, "/" );
  1010.             }
  1011.             ogreSetStringValue( ogw, id, path );
  1012.     }
  1013. }
  1014.  
  1015. static BPTR lockstack[á32 ];
  1016. static ULONG lockstackptr;
  1017.  
  1018. int pushdirlock( BPTR lock )
  1019. {
  1020.     lock = DupLock( lock );
  1021.     lockstack[álockstackptr++ ]á= CurrentDir( lock );
  1022.     return( 0 );
  1023. }
  1024.  
  1025. int pushdir( char *pfad )
  1026. {
  1027.     BPTR lock = Lock( pfad, SHARED_LOCK );
  1028.  
  1029.     if( !lock )
  1030.         return( IoErr() );
  1031.  
  1032.     lockstack[álockstackptr++ ]á= CurrentDir( lock );
  1033.  
  1034.     return( 0 );
  1035. }
  1036.  
  1037. static BPTR homelock;
  1038. void inithomedir( void )
  1039. {
  1040.     homelock = DupLock( MYPROC->pr_CurrentDir );
  1041. }
  1042.  
  1043. void pushhomedir( void )
  1044. {
  1045.     pushdirlock( homelock );
  1046. }
  1047.  
  1048. void freelockstack( void )
  1049. {
  1050.     while( lockstackptr )
  1051.     {
  1052.         UnLock( CurrentDir( lockstack[á--lockstackptr ] ) );
  1053.     }
  1054.     UnLock( homelock );
  1055. }
  1056.  
  1057. void popdir(void)
  1058. {
  1059.     if( lockstackptr )
  1060.     {
  1061.         UnLock( CurrentDir( lockstack[á--lockstackptr ] ) );
  1062.     }
  1063.     else
  1064.         Alert( 0x666 );
  1065. }
  1066.  
  1067. static FILE *logf;
  1068. static struct hlist *loghl;
  1069. void openlogmsg(char *betreff)
  1070. {
  1071.     char path[256];
  1072.  
  1073.     strcpy( path, prefs.datadir );
  1074.     addpart( path, "__mdlog.tmp" );
  1075.  
  1076.     if( isv37 )
  1077.         logf = ( FILE * ) Open( path, MODE_NEWFILE );
  1078.     else
  1079.         logf = fopen( path, "w" );
  1080.  
  1081.     if( !logf )
  1082.         return;
  1083.  
  1084.     loghl = hl_initheader();
  1085.  
  1086.     hl_addheader( loghl, "ABS", "MicroDot (Protokoll-Nachricht)" );
  1087.     hl_addheader( loghl, "MID", makemid() );
  1088.     makedateheader( path, time( 0 ) );
  1089.     hl_addheader( loghl, "EDA", path );
  1090.     hl_addheader( loghl, "BET", betreff );
  1091.  
  1092. }
  1093.  
  1094. void closelogmsg(void)
  1095. {
  1096.     if( logf )
  1097.     {
  1098.         struct mbrett *sp=findbrett("/╗PROTOKOLL",0);
  1099.         struct pindex *pix;
  1100.         struct mail mail;
  1101.         char path[ 256 ];
  1102.  
  1103.         memset( &mail, 0, sizeof( mail ) );
  1104.  
  1105.         strcpy( path, prefs.datadir );
  1106.         addpart( path, "__mdlog.tmp" );
  1107.  
  1108.         if( isv37 )
  1109.             Close( ( BPTR ) logf );
  1110.         else
  1111.             fclose( logf );
  1112.         logf = NULL;
  1113.  
  1114.         header2mail( loghl, &mail );
  1115.         pix = msg_store( NULL, 0, path, -1,
  1116.             &mail.pufferID, &mail.mailID,
  1117.             loghl
  1118.         );
  1119.  
  1120.         hl_freeheader( loghl );
  1121.  
  1122.         if( pix )
  1123.         {
  1124.             mail.maillen = pix->datasize;
  1125.             storemail2ix( &mail, sp, NULL );
  1126.         }
  1127.  
  1128.         DeleteFile( path );
  1129.     }
  1130. }
  1131.  
  1132.  
  1133. void __stdargs printlog(char *s,...)
  1134. {
  1135.     if(logf)
  1136.     {
  1137. #ifndef MDV20
  1138.         if( !LocaleBase )
  1139.             replacebigd( s );
  1140. #endif
  1141.         if( isv37 )
  1142.             VFPrintf( ( BPTR ) logf,s,(((long)&s)+4));
  1143. #ifndef MDV20
  1144.         else
  1145.             vfprintf(logf,s,(va_list)(((long)&s)+4));
  1146. #endif
  1147.     }
  1148. }
  1149.  
  1150. #define MDS "UseConnectline"
  1151.  
  1152. char *makemid(void)
  1153. {
  1154.     static char mid[128];
  1155.     static USHORT midcount;
  1156.     char sproing[40];
  1157.  
  1158.     /* Netcall3.8 kompatible MsgID erzeugen */
  1159.     if( prefs.mode == MDM_N38 )
  1160.     {
  1161.         ULONG pncrc = crc32( prefs.pointname, strlen( prefs.pointname ) );
  1162.  
  1163.         num2b64( pncrc, sproing );
  1164.         num2b64( time( 0 ), &sproing[8] );
  1165.         num2b64( registerinfo.serie, &sproing[16] );
  1166.  
  1167.         sprintf( mid, "%lc%1.1s%3.3s%3.3s@%s",
  1168.             MDS[ midcount++ % strlen( MDS ) ],
  1169.             sproing,
  1170.             &sproing[8 + 1 ],
  1171.             &sproing[16],
  1172.             prefs.boxname );
  1173.  
  1174.         strupr( strchr( mid, '@' ) );
  1175.         return( mid );
  1176.     }
  1177.  
  1178.     /* RFC/ZConnect MsgId erzeugen */
  1179.     num2b64( time( 0 ), sproing );
  1180.  
  1181.     if( prefs.mode == MDM_RFC )
  1182.     {
  1183.         sprintf( mid, "%sMD%lxa%lcz%lx@%s%s",
  1184.             sproing,
  1185.             registerinfo.serie,
  1186.             MDS[ midcount++ % strlen( MDS ) ],
  1187.             midcount,
  1188.             prefs.pointname,
  1189.             prefs.boxdomain );
  1190.     }
  1191.     else
  1192.     {
  1193.         sprintf( mid, "%sMD%lxa%lcz%lx@%s.%s%s",
  1194.             sproing,
  1195.             registerinfo.serie,
  1196.             MDS[ midcount++ % strlen( MDS ) ],
  1197.             midcount,
  1198.             prefs.pointname,
  1199.             prefs.boxname,
  1200.             prefs.boxdomain );
  1201.     }
  1202.  
  1203.     strlwr(strchr(mid,'@'));
  1204.     return(mid);
  1205. }
  1206.  
  1207. void makedateheader( char *to, long t )
  1208. {
  1209.     char x[6];
  1210.  
  1211.     t -= timezone_offset;
  1212.  
  1213.     utunpk( t, x );
  1214.  
  1215.     sprintf(to,"%04ld%02ld%02ld%02ld%02ld%02ld%lc%lc%ld",
  1216.         x[0]+1970,
  1217.         x[1],x[2],x[3],x[4],x[5],
  1218.         timezone_dst ? 'S' : 'W',
  1219.         timezone_offset >= 0 ? '+'á: '-',
  1220.         abs( timezone_offset) /3600 );
  1221. }
  1222.  
  1223. #include <exec/alerts.h>
  1224. void outofmem( void )
  1225. {
  1226.     if( Output() )
  1227.     {
  1228. #define WX(s) Write(Output(),s,strlen(s))
  1229.         WX( "\nMicroDot: *** Out of Memory!\n\007" );
  1230.     }
  1231.     else
  1232.         Alert( AG_NoMemory | AO_Unknown );
  1233. }
  1234.  
  1235. int astcsma( const char *s, const char *p )
  1236. {
  1237.     char buff[á256 ];
  1238.  
  1239.     if( ParsePatternNoCase( p, buff, sizeof( buff ) ) >= 0 )
  1240.     {
  1241.         if( MatchPatternNoCase( buff, s ) )
  1242.         {
  1243.             return( 1 );
  1244.         }
  1245.     }
  1246.     return( 0 );
  1247. }
  1248.