home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 4 / Amiga Tools 4.iso / tools / internet-tools / connect-line / cl / devkit / c / examples / inhalt / inhalt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-11-06  |  14.7 KB  |  687 lines

  1. //
  2. // Inhalt-Kommando, inhalt.c
  3. //
  4. // Copyright 1995 by Mathias Mischler
  5. //
  6. // + Realname NUR anzeigen, wenn vorhanden.
  7. // + Neue Nachrichten bold.
  8. // + BUG: Wenn KEIN Inhalt, checken. (9.7.95)
  9. // + Graphicmodus
  10. // + Merken!! ,) (12.7.95)
  11. // + BUG: mytime (struct tm) ist POINTER! (13.7.95)
  12. // + Brett mit nur gelöschten Nachrichten liefert bei i# bugs. (14.7.95)
  13. // + Bei leeren Bretter Dummy erzeugen ?! (kein Dummy, NULL wird verarbeitet). (14.7.95)
  14. // + Cursor bei I # direkt auf Neue. (14.7.95)
  15. // + Inhalt rückwärts (neue zuerst). (17.7.95)
  16. // + Inhalt.txt ausgeben. (17.7.95)
  17. // + Brettverwalter/Zensor ausgeben. (18.7.95)
  18. // + Inhalt **, I ***, etc. wird als I * behandelt (14.9.95)
  19. // - Inhalt # <Range>.
  20. // - bei "I" MOVE_NEW von CLB_MOVE verwenden... sollte schneller gehen.
  21. //
  22.  
  23. // Connectline Support Includes
  24.  
  25. #include <string.h>
  26. #include <time.h>
  27. #include <stdlib.h>
  28. #include <dos/dostags.h>
  29. #include <cl/clonline.h>
  30. typedef APTR HH; /* Headerhandle */
  31. #include <cl/cl_msg.h>
  32. #include <cl/clb.h>
  33. #include <cl/cl_userflags.h>
  34.  
  35. // Version String
  36. char version[] = { "$VER: Inhalt 1.8 " __AMIGADATE__ };
  37.  
  38. #define InhaltFilename "Inhalt.txt"
  39.  
  40. ulong  zeilenzahl, zeilen;
  41.  
  42. char *GetInhaltForm ( APTR index, char *deststr, BOOL onlynew );
  43.  
  44. long ShowGfx ( APTR *index, ulong numberall, BOOL backwards )
  45. {
  46. char   buffer [ 512 ], *ausgabe, titel [ 100 ];
  47. time_t writetime, lastcall;
  48. struct MinList indexlist;
  49. struct EntryNode *en, *en2;
  50. long count;
  51. BOOL quit;
  52. long ret_val;
  53. ulong pos;
  54. char param [ 150 ], one [ 10 ];
  55. //BOOL found
  56. BOOL suchneue;
  57.  
  58.     if ( !index ) return 1;
  59.  
  60.     ret_val = 0;
  61.  
  62.     CLONL_DrawTitle();
  63.  
  64.     PutMSG ("MSG_ACTUAL");
  65.  
  66.     lastcall = CLONL_GetUserShell() -> userprofile.LastLogin;
  67.     NEWLIST ( &indexlist );
  68.  
  69. //found = FALSE;
  70.     pos = 0; 
  71.     suchneue = TRUE;
  72.  
  73.     if ( backwards )
  74.     {
  75.         pos = 0;
  76.         for ( count = numberall - 1; count >= 0; count-- )
  77.         {
  78.             CLMSG_Move ( *index, CLMSG_MOVE_GOTO, count );
  79.             ausgabe = GetInhaltForm ( *index, buffer, FALSE );
  80.  
  81.             if ( ausgabe )
  82.             {
  83.                 if ( !( en = malloc ( sizeof ( struct EntryNode ) ) ) ) { PutStr("Can't get memory.\n"); break; }
  84.                 strcpy ( en->data, ausgabe );
  85.                 CLMSG_Get ( *index, CLMSGA_INCOMDATE, &writetime, TAG_DONE );
  86.                 en->bold = ( lastcall <= writetime );
  87.                 en->inverse = 0;
  88.                 ADDTAIL ( &indexlist, en );
  89. //            found = TRUE;
  90.             }
  91.         }
  92.     }
  93.     else
  94.     {
  95.         for ( count = 0; count < numberall; count++ )
  96.         {
  97.             CLMSG_Move ( *index, CLMSG_MOVE_GOTO, count );
  98.             ausgabe = GetInhaltForm ( *index, buffer, FALSE );
  99.  
  100.             if ( ausgabe )
  101.             {
  102.                 if ( !( en = malloc ( sizeof ( struct EntryNode ) ) ) ) { PutStr("Can't get memory.\n"); break; }
  103.                 strcpy ( en->data, ausgabe );
  104.                 CLMSG_Get ( *index, CLMSGA_INCOMDATE, &writetime, TAG_DONE );
  105.                 en->bold = ( lastcall <= writetime );
  106.                 if ( suchneue && ( lastcall <= writetime ) ) 
  107.                 {
  108.                     pos = count; // Auf neue setzen;
  109.                     suchneue = FALSE;
  110.                 }
  111.                 en->inverse = 0;
  112.                 ADDTAIL ( &indexlist, en );
  113. //            found = TRUE;
  114.             }
  115.         }
  116.     }
  117.  
  118.     if ( *index ) 
  119.     {
  120.         CLMSG_FreeIndex ( *index );
  121.         *index = NULL; // Freigeben !!
  122.     }
  123.  
  124. //if ( found )
  125. //{
  126.         quit = FALSE;
  127.  
  128.         while (!quit)
  129.         {
  130.             strcpy ( titel, MSG("MSG_INHALTAUSWAHL") );
  131.             en = CLONL_RequesterSelect ( &indexlist, pos, titel, MODE_INHALT );
  132.  
  133.             if ( en == NULL )
  134.             {
  135.                 ret_val = 0;
  136.                 quit = TRUE;
  137.             } else
  138.             if ( en == (struct EntryNode *) -1 )
  139.             {
  140.                 ret_val = 1;
  141.                 quit = TRUE;
  142.             } else
  143.             if ( en )
  144.             {
  145.                 // ALTE position bestimmen
  146.                 pos = 0;
  147.                 en2 = FIRSTNODE ( &indexlist );
  148.                 while ( NEXTNODE ( en2 ) )
  149.                 {
  150.                     if ( en2 == en ) break;
  151.                     en2 = NEXTNODE ( en2 ); pos++;
  152.                 }
  153.  
  154.                 // Parameterstring basteln
  155.                 strcpy ( param, "" );
  156.  
  157.                 en2 = FIRSTNODE ( &indexlist );
  158.                 while ( NEXTNODE ( en2 ) )
  159.                 {
  160.                     if ( en2->inverse )
  161.                     {
  162.                         one [ 0 ] = en2->data [ 0 ];
  163.                         one [ 1 ] = en2->data [ 1 ];
  164.                         one [ 2 ] = en2->data [ 2 ];
  165.                         one [ 3 ] = en2->data [ 3 ];
  166.                         one [ 4 ] = en2->data [ 4 ];
  167.                         one [ 5 ] = 0;
  168.                         strcat ( param, one );
  169.                     }
  170.                     en2 = NEXTNODE ( en2 );
  171.                 }
  172.                 if ( strlen ( param ) > 0 )
  173.                 {
  174.                     param [ strlen ( param ) - 1 ] = 0; // Komma hinten weg.
  175.                 }
  176.                 else
  177.                 {
  178.                     one [ 0 ] = en->data [ 0 ];
  179.                     one [ 1 ] = en->data [ 1 ];
  180.                     one [ 2 ] = en->data [ 2 ];
  181.                     one [ 3 ] = en->data [ 3 ];
  182.                     one [ 4 ] = en->data [ 4 ];
  183.                     one [ 5 ] = 0;
  184.                     strcpy ( param, one );
  185.                 }
  186.  
  187.                 switch ( titel [ 0 ] )
  188.                 {
  189.                     case 'L':
  190.                         CLONL_DoCommand ( "LESEN", param );
  191.                         // Einträge löschen
  192.                         en2 = FIRSTNODE ( &indexlist );
  193.                         while ( NEXTNODE ( en2 ) )
  194.                         {
  195.                             en2->inverse = 0;
  196.                             en2 = NEXTNODE ( en2 );
  197.                         }
  198.                         break;
  199.                     case 'S':
  200.                         CLONL_DoCommand ( "SENDEN", "" );
  201.                         break;
  202.                     case 'M':
  203.                         CLONL_DoCommand ( "MERKEN", param );
  204.                         // Einträge löschen
  205.                         en2 = FIRSTNODE ( &indexlist );
  206.                         while ( NEXTNODE ( en2 ) )
  207.                         {
  208.                             en2->inverse = 0;
  209.                             en2 = NEXTNODE ( en2 );
  210.                         }
  211.                         break;
  212.                     case 'R':
  213.                         CLONL_DoCommand ( "LOESCHEN", param );
  214.                         ret_val = 2; // Again !!
  215.                         quit = TRUE;
  216.                         // Einträge löschen
  217.                         en2 = FIRSTNODE ( &indexlist );
  218.                         while ( NEXTNODE ( en2 ) )
  219.                         {
  220.                             en2->inverse = 0;
  221.                             en2 = NEXTNODE ( en2 );
  222.                         }
  223.                         break;
  224.                 }
  225.             }
  226.         }
  227.  
  228. //        while ( en = REMHEAD ( &indexlist ) )
  229. //            free ( en );
  230.  
  231. //}
  232.  
  233.     CLONL_GotoXY ( 1, CLONL_GetUserShell()->userprofile.ShowLines + 1);
  234.  
  235.     return ret_val;
  236. }
  237.  
  238. char *GetInhaltForm ( APTR index, char *deststr, BOOL onlynew )
  239. {
  240. ulong number, readcount, bodylen;
  241. ulong flagbin, flaghold, flagdel, flagcensored, flagnoratio;
  242. char *subject, *from;
  243. time_t incomdate;
  244. char  flags [ 6 ];
  245. char  date  [ 6 ];
  246. char  absender [ 130 ], *absp, *abs2p;
  247. char  sizestr [ 10 ];
  248. time_t lastcall;
  249. struct tm *mytime;
  250.  
  251.     lastcall = CLONL_GetUserShell()->userprofile.LastLogin;
  252.  
  253.     CLMSG_Get ( index, 
  254.         CLMSGA_NUMBER,       &number, 
  255.         CLMSGA_SUBJECT,      &subject,
  256.         CLMSGA_FROM,                 &from,
  257.         CLMSGA_INCOMDATE,    &incomdate,
  258.         CLMSGA_READCOUNT,    &readcount,
  259.         CLMSGA_FLG_BIN,      &flagbin,
  260.         CLMSGA_FLG_HOLD,     &flaghold,
  261.         CLMSGA_FLG_DEL,      &flagdel,
  262.         CLMSGA_FLG_CENSORED, &flagcensored,
  263.         CLMSGA_FLG_NO_RATIO, &flagnoratio,
  264.         CLMSGA_BODY_LEN,         &bodylen,
  265.         TAG_DONE );
  266.  
  267.     if ( bodylen > 99999 )
  268.     {
  269.         if ( ((bodylen + 512) / 1024) > 9999 )
  270.         {    
  271.             CLONL_SPrintf ( sizestr, "%ldm", ( bodylen + (512 * 1024) ) / (1024*1024) );
  272.         }
  273.         else
  274.         {    
  275.             CLONL_SPrintf ( sizestr, "%ldk", ( bodylen + 512 ) / 1024 );
  276.         }
  277.     }
  278.     else
  279.     {
  280.         CLONL_SPrintf ( sizestr, "%ld", bodylen );
  281.     }
  282.  
  283.     strcpy ( absender, from ); // Realname extrahieren, wenn vorhanden
  284.     absp = absender;
  285.     while ( *absp && ( *absp != '(' ) ) absp++;
  286.     if ( *absp )
  287.     {
  288.         absp++;
  289.         abs2p = absp;
  290.         while ( *abs2p && ( *abs2p != ')' ) ) abs2p++;
  291.         *abs2p = 0;
  292.     }
  293.     else
  294.     {
  295.         absp = absender;
  296.     }
  297.  
  298.     mytime = gmtime ( &incomdate );
  299.     CLONL_SPrintf ( date, "%02ld.%02ld", mytime->tm_mday, mytime->tm_mon + 1);
  300.  
  301.     strcpy ( flags, "T...." );
  302.     if ( flagbin      ) flags[0] = 'B';
  303.     if ( flaghold     ) flags[1] = 'H';
  304.     if ( flagdel      ) flags[2] = 'D';
  305.     if ( flagcensored ) flags[3] = 'C';
  306.     if ( flagnoratio  ) flags[4] = '*';
  307.  
  308.     if ( ((!flagdel) || (CLONL_GetUserShell()->userprofile.InhaltFlags & USERI_SHOWDELETE))
  309.          && ((!onlynew) || (lastcall <= incomdate)) )
  310.     {
  311.         CLONL_SPrintf ( deststr, MSG ("MSG_INHALTFORMAT"), number, date, flags, sizestr, absp, subject );
  312.     }
  313.     else
  314.     {
  315.         return NULL;
  316.     }
  317.     return deststr;
  318. }
  319.  
  320. long PrintMsgActual ( APTR index, BOOL onlynew )
  321. {
  322. char  commentstr [ 1025 ], *commentp, *commentnextp;
  323. long  commentlen;
  324. time_t lastcall;
  325. time_t incomdate;
  326. char *comment, *ausgabe;
  327.  
  328.     if ( !index ) return 1;
  329.  
  330.     lastcall = CLONL_GetUserShell()->userprofile.LastLogin;
  331.  
  332.   if ( zeilen >= zeilenzahl )
  333.   {
  334.         zeilen = 1;
  335.          if ( !CLONL_Wait() ) return 1;
  336.   }
  337.     else
  338.     {
  339.         if ( !CLONL_Continue() ) return 1;
  340.     }
  341.  
  342.     ausgabe = GetInhaltForm ( index, commentstr, onlynew ); // commenstr wird ledigl. als puffer verwendet!
  343.  
  344.     if ( ausgabe )
  345.     {
  346.         CLMSG_Get ( index, 
  347.             CLMSGA_SHORTCOMMENT, &comment,
  348.             CLMSGA_INCOMDATE,    &incomdate,
  349.             TAG_DONE );
  350.  
  351.         if ( lastcall <= incomdate )
  352.         {
  353.             CLONL_Color ( COLOR_Yellow, COLOR_Black, STYLE_Bold );
  354.         }
  355.         else
  356.         {
  357.             CLONL_Color ( COLOR_Yellow, COLOR_Black, 0 );
  358.         }
  359.  
  360.         PutStr ( ausgabe );
  361.         zeilen ++;
  362.  
  363.         if ( comment && comment [ 0 ] )
  364.         {
  365.             commentlen = atoi ( MSG ("MSG_COMMENTSIZE") );
  366.             strcpy ( commentstr, comment );
  367.             commentstr [ strlen ( commentstr ) + 1 ] = 0; // Ende mit 00 markieren
  368.             commentp = commentstr;
  369.             while ( *commentp )
  370.             {
  371.                 if ( strlen ( commentp ) < commentlen )
  372.                     commentnextp = commentp + strlen ( commentp );
  373.                 else
  374.                 {
  375.                     commentnextp = commentp + commentlen - 1;
  376.                     while ( (commentnextp > commentp) && (*commentnextp != ' ')) commentnextp--;
  377.                     if ( commentnextp == commentp )
  378.                     {
  379.                         commentnextp = commentp + commentlen;
  380.                     }
  381.                     else
  382.                     {
  383.                         *commentnextp = 0; 
  384.                         commentnextp ++;
  385.                     }
  386.                 }
  387.             if ( zeilen >= zeilenzahl )
  388.                {
  389.                    zeilen = 1;
  390.                  if ( !CLONL_Wait() ) return 1;
  391.             }
  392.                 else
  393.                 {
  394.                     if ( !CLONL_Continue() ) return 1;
  395.                 }
  396.  
  397.                 CLONL_Printf ( MSG ("MSG_COMMENT"), commentp );
  398.                 zeilen ++;
  399.                 commentp = commentnextp;
  400.             }
  401.         }
  402.     }
  403.     return 0;
  404. }
  405.  
  406. long PrintMsgRange ( APTR index, struct Range *myrange, BOOL onlynew )
  407. {
  408. ulong count;
  409. long reterror;
  410.  
  411.     if ( !index ) return 1;
  412.  
  413.     reterror = 0;
  414.  
  415.     while ( myrange )
  416.     {
  417.         for ( count = (myrange->from); count <= (myrange->to); count++ )
  418.         {
  419.             CLMSG_Move ( index, CLMSG_MOVE_GOTO, count );
  420.             reterror |= PrintMsgActual ( index, onlynew );
  421.             if ( reterror ) return reterror;
  422.         }
  423.         myrange = myrange -> next;
  424.     }
  425.     return reterror;
  426. }
  427.  
  428. long PrintMsgRangeBack ( APTR index, struct Range *myrange, BOOL onlynew )
  429. {
  430. long count;
  431. long reterror;
  432.  
  433.     if ( !index ) return 1;
  434.  
  435.     reterror = 0;
  436.  
  437.     if ( myrange && myrange->next ) 
  438.     {
  439.         if ( reterror |= PrintMsgRangeBack ( index, myrange->next, onlynew ) )
  440.             return reterror;
  441.     }
  442.  
  443.     if ( myrange )
  444.         for ( count = (myrange->to); count >= (long)(myrange->from); count-- )
  445.         {
  446.             CLMSG_Move ( index, CLMSG_MOVE_GOTO, count );
  447.             reterror |= PrintMsgActual ( index, onlynew );
  448.             if ( reterror ) return reterror;
  449.         }
  450.  
  451.     return reterror;
  452. }
  453.  
  454. //
  455. // PrintInfo
  456. //
  457.  
  458. BOOL PrintInfo ( APTR board )
  459. {
  460. char *path;
  461. char mypath [ 256 ];
  462. char line   [ 82  ];
  463. BPTR lock, file;
  464. char *censor, *admin;
  465. long dlratio;
  466. BOOL leerzeile;
  467.  
  468.     if ( board )
  469.     {
  470.         CLB_Get ( board, 
  471.                             CLBA_PATH, &path, 
  472.                             CLBA_ADMIN, &admin, 
  473.                             CLBA_CENSOR, &censor, 
  474.                             CLBA_DLRATIO, &dlratio, 
  475.                             TAG_DONE );
  476.  
  477.         leerzeile = FALSE;
  478.         if ( admin && admin [ 0 ] )
  479.         {
  480.             CLONL_Printf ( MSG("MSG_BOARDADMIN"), admin );
  481.             zeilen++;
  482.             leerzeile = TRUE;
  483.         }
  484.         if ( censor && censor [ 0 ] )
  485.         {
  486.             CLONL_Printf ( MSG("MSG_BOARDCENSOR"), censor );
  487.             zeilen++;
  488.             leerzeile = TRUE;
  489.         }
  490.         if ( !dlratio )
  491.         {
  492.             PutMSG ("MSG_BOARDRATIO");
  493.             zeilen++;
  494.             leerzeile = TRUE;
  495.         }
  496.         if ( leerzeile ) 
  497.         {
  498.             PutStr ("\n");
  499.             zeilen++;
  500.         }
  501.         strncpy ( mypath, path, 256 );
  502.         AddPart ( mypath, InhaltFilename, 256 );
  503.     }
  504.     else
  505.     {
  506.         strncpy ( mypath, CLONL_GetUserShell()->user.Pfad, 256 );
  507.         AddPart ( mypath, InhaltFilename, 256 );
  508.     }
  509.  
  510.     if ( lock = Lock ( mypath, ACCESS_READ ) )
  511.     {
  512.         UnLock ( lock );
  513.         if ( file = Open ( mypath, MODE_OLDFILE ) )
  514.         {
  515.             while ( FGets ( file, line, 80 ) )
  516.             { 
  517.             if ( zeilen >= zeilenzahl )
  518.               {
  519.                    zeilen = 1;
  520.                     if ( !CLONL_Wait() ) return FALSE;
  521.             }
  522.                 else
  523.                 {
  524.                     if ( !CLONL_Continue() ) return FALSE;
  525.                 }
  526.                 CLONL_Printf ( line );
  527.                 zeilen++;
  528.             }
  529.             Close ( file );
  530.         }
  531.     }
  532.     return TRUE;
  533.  
  534. }
  535.  
  536.  
  537. //
  538. // main
  539. //
  540.  
  541. int main(int argc, char *argv[])
  542. {
  543. APTR index;
  544. APTR board;
  545. ulong count, numberall;
  546. char eingabe [ 256 ];
  547. struct Range *myrange;
  548. char *argument;
  549. int ret_val;
  550. bool again;
  551.  
  552.     if ( !CLONL_Open ("Online_Inhalt.clcat") ) { PutStr("Can't init ANSI-System.\n"); return 1; }
  553.  
  554.     do
  555.     {
  556.  
  557.     again = FALSE;
  558.  
  559.   zeilenzahl = CLONL_GetUserShell()->userprofile.ShowLines;
  560.     strcpy ( eingabe, "");
  561.     ret_val = 0;
  562.  
  563.     // Test auf PM (siehe CLMFT_USER)
  564.     board = CLB_FindBrett ( CLONL_GetUserShell()->currentboard );
  565.  
  566.     if ( board || !CLONL_GetUserShell()->currentboard [ 0 ] || ( stricmp ( CLONL_GetUserShell()->currentboard, CLONL_GetUserShell()->user.Username) == 0 ) )
  567.     {
  568.         if ( !board )
  569.             index = CLMSG_GetIndexTags ( (APTR) &CLONL_GetUserShell()->user,
  570.                 CLMFT_USER, TRUE, TAG_DONE );
  571.         else
  572.             index = CLMSG_GetIndexTags ( board, TAG_DONE );
  573.  
  574.         if ( !index ) goto ende;
  575.  
  576.         CLMSG_Get ( index, CLMSGA_NUMBEROFMSGS, &numberall, TAG_DONE );
  577.  
  578.         if ( argc > 1 )
  579.         {
  580.             argument = argv [ 1 ];
  581.  
  582.             if ( !CLONL_IsTTY() && strcmp ( argument, "#" ) == 0 )
  583.             {
  584.                 ret_val = ShowGfx ( &index, numberall, (BOOL) CLONL_GetUserShell()->userprofile.InhaltFlags & USERI_BACKWARDS );
  585.                 if ( ret_val == 2 ) again = TRUE;
  586.             } else
  587.             if ( argument [ 0 ] == '*' )
  588.             {
  589.                 CLONL_DrawTitle();
  590.                 zeilen = 3;
  591.                 PrintInfo ( board );
  592.                 PutMSG ( "MSG_INHALTWHATIS" );
  593.                 if ( numberall > 0 )
  594.                 {
  595.                     myrange = CLONL_ParseExpression ( "0-", numberall - 1 );
  596.                     if ( CLONL_GetUserShell()->userprofile.InhaltFlags & USERI_BACKWARDS )
  597.                         PrintMsgRangeBack ( index, myrange, FALSE );
  598.                     else
  599.                         PrintMsgRange ( index, myrange, FALSE );
  600.                     CLONL_FreeRange ( myrange );
  601.                 }
  602.                 else
  603.                 {    
  604.                     PutMSG ("MSG_NOMSG");
  605.                 }
  606.             }    else
  607.             if ( (strcmp ( argument, "n" ) == 0) || (strcmp ( argument, "N" ) == 0) )
  608.             {
  609.                 zeilen = 2;
  610.                 PrintInfo ( board );
  611.                 PutMSG ( "MSG_INHALTWHATIS" );
  612.                 if ( numberall > 0 )
  613.                 {
  614.                     myrange = CLONL_ParseExpression ( "0-", numberall - 1 );
  615.                     if ( CLONL_GetUserShell()->userprofile.InhaltFlags & USERI_BACKWARDS )
  616.                         PrintMsgRangeBack ( index, myrange, TRUE );
  617.                     else
  618.                         PrintMsgRange ( index, myrange, TRUE );
  619.                     CLONL_FreeRange ( myrange );
  620.                 }
  621.                 else
  622.                 {
  623.                     PutMSG ("MSG_NOMSG");
  624.                 }
  625.             }    else
  626.             {
  627.                 CLONL_DrawTitle();
  628.                 zeilen = 3;
  629.                 PrintInfo ( board );
  630.                 PutMSG ( "MSG_INHALTWHATIS" );
  631.                 strcpy ( eingabe, "" );
  632.                 for ( count = 1; count < argc; count ++ )
  633.                 {
  634.                     strcat ( eingabe, argv [ count ] );
  635.                     strcat ( eingabe, " ");
  636.                 }
  637.                 if ( numberall > 0 )
  638.                 {
  639.                     myrange = CLONL_ParseExpression ( eingabe, numberall - 1 );
  640.                     if ( CLONL_GetUserShell()->userprofile.InhaltFlags & USERI_BACKWARDS )
  641.                         PrintMsgRangeBack ( index, myrange, FALSE );
  642.                     else
  643.                         PrintMsgRange ( index, myrange, FALSE );
  644.                     CLONL_FreeRange ( myrange );
  645.                 }
  646.                 else
  647.                 {
  648.                     PutMSG ("MSG_NOMSG");
  649.                 }
  650.             }
  651.         }
  652.         else
  653.         {
  654.             CLONL_DrawTitle();
  655.             zeilen = 3;
  656.             PrintInfo ( board );
  657.             PutMSG ( "MSG_INHALTWHATIS" );
  658.             if ( numberall > 0 )
  659.             {
  660.                 myrange = CLONL_ParseExpression ( "0-", numberall - 1 );
  661.                 if ( CLONL_GetUserShell()->userprofile.InhaltFlags & USERI_BACKWARDS )
  662.                     PrintMsgRangeBack ( index, myrange, TRUE );
  663.                 else
  664.                     PrintMsgRange ( index, myrange, TRUE );
  665.                 CLONL_FreeRange ( myrange );
  666.             }
  667.             else
  668.             {
  669.                 PutMSG ("MSG_NOMSG");
  670.             }
  671.         }
  672.         if ( index ) CLMSG_FreeIndex ( index );
  673.     }
  674.     else
  675.     {
  676.         PutMSG("MSG_NOBOARD");
  677.     }
  678.  
  679.     }
  680.     while ( again );
  681.  
  682.     ende:
  683.  
  684.     CLONL_Close();
  685.     return ret_val;
  686. }
  687.