home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / vsoup128.zip / areas.cc next >
C/C++ Source or Header  |  1997-01-20  |  9KB  |  413 lines

  1. //  $Id: areas.cc 1.19 1997/01/20 16:13:14 hardy Exp $
  2. //
  3. //  This progam/module was written by Hardy Griech based on ideas and
  4. //  pieces of code from Chin Huang (cthuang@io.org).  Bug reports should
  5. //  be submitted to rgriech@ibm.net.
  6. //
  7. //  This file is part of soup++ for OS/2.  Soup++ including this file
  8. //  is freeware.  There is no warranty of any kind implied.  The terms
  9. //  of the GNU Gernal Public Licence are valid for this piece of software.
  10. //
  11. //  SOUP AREAS file management
  12. //
  13.  
  14.  
  15. #include <assert.h>
  16. #include <errno.h>
  17. #include <fcntl.h>
  18. #include <io.h>
  19. #include <stdarg.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <time.h>
  24.  
  25. #include "mts.hh"
  26. #include "areas.hh"
  27.  
  28.  
  29.  
  30. static TSemaphor msg;    // requested by msgStart, released by msgStop
  31. static TSemaphor mail;   // requested by mailStart, released by mailStop
  32.  
  33.  
  34.  
  35. TAreas::TAreas( const char *areasName, const char *msgNamePattern )
  36. {
  37.     int i;
  38.     
  39. #ifdef TRACE_ALL
  40.     printfT( "TAreas::TAreas(%s,%s)\n",areasName,msgNamePattern );
  41. #endif
  42.  
  43.     msgCounter = 0;
  44.     msgStarted = 0;
  45.     
  46.     TAreas::msgNamePattern = xstrdup(msgNamePattern);
  47.     
  48.     if ( !areasF.open(areasName,TFile::mwrite,TFile::obinary,1)) {
  49.     perror(areasName);
  50.     exit( EXIT_FAILURE );
  51.     }
  52.  
  53.     for (i = 0;  i < AREAS_FIFOSIZE;  ++i)
  54.     fifo[i].id = fifo[i].format = fifo[i].filename = NULL;
  55.     fifoNext = 0;
  56.     fifoMsgF = 0;
  57. }   // TAreas::TAreas
  58.  
  59.  
  60.  
  61. TAreas::~TAreas()
  62. {
  63. #ifdef TRACE_ALL
  64.     printfT( "TAreas::~TAreas()\n" );
  65. #endif
  66.     closeAll();
  67.  
  68.     ////  den ganzen Quatsch freigeben
  69. }   // TAreas::~TAreas
  70.  
  71.  
  72.  
  73. void TAreas::closeAll( void )
  74. {
  75. #ifdef TRACE_ALL
  76.     printfT( "TAreas::closeAll()\n" );
  77. #endif
  78.     //
  79.     //  if message was not completed then delete it...
  80.     //
  81.     if (msgStarted) {
  82.     msgStarted = 0;
  83.     msgF.truncate( msgLenPos );
  84.     }
  85.     msgF.close();
  86.     areasF.close(1);
  87. ////    delete msgNamePattern;
  88. }   // TAreas::closeAll
  89.  
  90.  
  91.  
  92. int TAreas::msgWrite( const char *buf, int buflen )
  93. {
  94. #ifdef TRACE_ALL
  95.     printfT( "TAreas::msgWrite(.,%d)\n",buflen );
  96. #endif
  97.     assert( msgStarted );
  98.     return msgF.write( buf,buflen );
  99. }   // TAreas::msgWrite
  100.  
  101.  
  102.  
  103. int TAreas::msgPrintf( const char *fmt, ... )
  104. {
  105.     va_list ap;
  106.     int res;
  107.  
  108.     assert( msgStarted );
  109.     va_start( ap, fmt );
  110.     res = msgF.vprintf( fmt, ap );
  111.     va_end( ap );
  112.     return res;
  113. }   // TAreas::msgPrintf
  114.  
  115.  
  116.  
  117. void TAreas::msgStart( const char *id, const char *format )
  118. {
  119.     int i, ptr;
  120.     char fname[FILENAME_MAX];
  121.     char name[FILENAME_MAX];
  122.     
  123.     msg.Request();
  124.     msgStarted = 1;
  125.  
  126. #ifdef TRACE_ALL
  127.     printfT( "TAreas::msgStart(%s,%s)\n", id,format );
  128. #endif
  129.  
  130.     //
  131.     //  is id/format in FIFO?
  132.     //
  133.     ptr = -1;
  134.     if (fifo[fifoMsgF].id != NULL  &&  stricmp(fifo[fifoMsgF].id,id) == 0  &&
  135.     stricmp(fifo[fifoMsgF].format,format) == 0) {
  136. #ifdef DEBUG_ALL
  137.     printfT( "TAreas::msgStart(): hit\n" );
  138. #endif
  139.     ptr = fifoMsgF;
  140.     }
  141.     else {
  142. #ifdef DEBUG_ALL
  143.     printfT( "TAreas::msgStart(): no hit\n" );
  144. #endif
  145.     msgF.close();
  146.     for (i = 0;  i < AREAS_FIFOSIZE;  ++i) {   //// hier kann man auch intelligenter Suchen...
  147.         if (fifo[i].id != NULL  &&  stricmp(fifo[i].id,id) == 0  &&
  148.         stricmp(fifo[i].format,format) == 0) {
  149.         ptr = i;
  150.         if ( !msgF.open(fifo[ptr].filename,TFile::mwrite,TFile::obinary)) {
  151.             perror( fifo[ptr].filename );
  152.             exit( EXIT_FAILURE );
  153.         }
  154.  
  155. #ifdef DEBUG_ALL
  156.         printfT( "TAreas::msgStart(): reopening %s\n",fifo[ptr].filename );
  157. #endif
  158.         break;
  159.         }
  160.     }
  161.     }
  162.  
  163.     //
  164.     //  wenn Id/Format nicht in FIFO drin, dann neue Datei anlegen und
  165.     //  ein Element aus dem FIFO entfernen (bei fifoNext)
  166.     //
  167.     if (ptr < 0) {
  168.     ptr = fifoNext;
  169.     if (++fifoNext >= AREAS_FIFOSIZE)
  170.         fifoNext = 0;
  171.     xstrdup( &(fifo[ptr].id),id );
  172.     xstrdup( &(fifo[ptr].format),format );
  173.  
  174.     //
  175.     //  open new message file & skip write-protected files
  176.     //
  177.     for (;;) {
  178.         ++msgCounter;
  179.         sprintfT( name, msgNamePattern,msgCounter );
  180.         strcpy( fname,name );
  181.         if (strcmp(format,"ic") == 0)
  182.         strcat( fname,".IDX" );
  183.         else
  184.         strcat( fname,".MSG" );
  185. #ifdef DEBUG_ALL
  186.         printfT( "TAreas::msgStart():  creating: %s\n", fname );
  187. #endif
  188.         if (msgF.open(fname,TFile::mwrite,TFile::obinary,1))
  189.         break;
  190. #ifndef HANDLEERR
  191.         if (errno != EACCES) {         // catch 'not enough file handles'
  192.         perror( fname );
  193.         exit( EXIT_FAILURE );
  194.         }
  195. #endif
  196.     }
  197. #ifdef DEBUG_ALL
  198.     printfT( "TAreas::msgStart(): ok %s\n", fname );
  199. #endif
  200.     xstrdup( &(fifo[ptr].filename),fname );
  201.     areasF.printf( "%s\t%s\t%s\n", name, id, format );
  202.     areasF.flush();
  203.     }
  204.     fifoMsgF = ptr;
  205.  
  206.     msgLenPos = -1;
  207.     if (*format == 'b'  ||  *format == 'B') {
  208.     static char buf[4] = {0,0,0,0};
  209.     msgLenPos = msgF.tell();
  210.     msgF.write( &buf, sizeof(buf) );
  211. #ifdef DEBUG_ALL
  212.     printfT( "TAreas::msgStart() msgLenPos = %ld\n", msgLenPos );
  213. #endif
  214.     }
  215. }   // TAreas::msgStart
  216.  
  217.  
  218.  
  219. void TAreas::msgStop( void )
  220. {
  221. #ifdef TRACE_ALL
  222.     printfT( "TAreas::msgStop()\n" );
  223. #endif
  224.     if (msgLenPos >= 0) {
  225.     char buf[4];
  226.     int r;
  227.     long msgLen = msgF.tell() - msgLenPos - 4;
  228.     buf[0] = (char)(msgLen >> 24);
  229.     buf[1] = (char)(msgLen >> 16);
  230.     buf[2] = (char)(msgLen >>  8);
  231.     buf[3] = (char)(msgLen >>  0);
  232.     r = msgF.seek( msgLenPos,SEEK_SET );
  233.     msgF.write( &buf,sizeof(buf) );
  234.     msgF.seek( 0,SEEK_END );
  235. #ifdef DEBUG_ALL
  236.     printfT( "TAreas::msgStop():  msgLen=%ld, r=%d\n",msgLen,r );
  237. #endif
  238.     }
  239.     
  240.     msgStarted = 0;
  241.     msgF.flush();
  242.     msg.Release();
  243. }   // TAreas::msgStop
  244.  
  245.  
  246.  
  247. //--------------------------------------------------------------------------------
  248.  
  249.  
  250.  
  251. TAreasMail::TAreasMail( const char *areasName, const char *msgNamePattern ): TAreas( areasName,msgNamePattern )
  252. {
  253. #ifdef TRACE_ALL
  254.     printfT( "TAreasMail::TAreasMail(%s,%s)\n",areasName,msgNamePattern );
  255. #endif
  256.     mailName = xstrdup("STSMAIL");
  257.     mailStarted = 0;
  258.     mailForced = 0;
  259.     mailExcept = 0;
  260.     conEcho = 0;
  261. #ifdef TRACE_ALL
  262.     printfT( "TAreasMail::TAreasMail: finished\n" );
  263. #endif
  264. }   // TAreasMail::TAreasMail
  265.  
  266.  
  267.  
  268. TAreasMail::~TAreasMail()
  269. {
  270. #ifdef TRACE_ALL
  271.     printfT( "TAreasMail::~TAreasMail()\n" );
  272. #endif
  273. ////    assert( !mailStarted );  thread-killerei
  274. }   // TAreasMail::~TAreasMail
  275.  
  276.  
  277.  
  278. void TAreasMail::mailOpen( const char *title )
  279. {
  280.     char fname[FILENAME_MAX];
  281.     time_t now;
  282.     char dateBuf[200];
  283.     struct tm *nowtm;
  284.  
  285.     assert( !mailStarted );
  286.     assert( !mailF.isOpen() );
  287.     
  288.     sprintfT( fname,"%s.MSG",mailName );
  289.     if ( !mailF.open(fname,TFile::mwrite,TFile::obinary,1)) {
  290.     perror(fname);
  291.     exit( EXIT_FAILURE );
  292.     }
  293.     now = time(NULL);
  294.     nowtm = localtime( &now );
  295.     strftime( dateBuf, sizeof(dateBuf), "%a, %d %b %Y %H:%M %Z",nowtm );
  296.     mailF.printf( "From POPmail %s\n",dateBuf );
  297.     mailF.printf( "To: VSoupUser\n" );
  298.     mailF.printf( "From: VSoup\n" );
  299.     mailF.printf( "Subject: VSoup status report: %s\n", title );
  300.     mailF.printf( "Date: %s\n\n", dateBuf );
  301. }   // TAreasMail::mailEffOpen
  302.  
  303.  
  304.  
  305. int TAreasMail::mailPrintf( const char *fmt, ... )
  306. {
  307.     va_list ap;
  308.     int res;
  309.  
  310.     assert( mailF.isOpen() );
  311.  
  312.     if ( !mailExcept)
  313.     mpSema.Request();
  314.  
  315.     if (mailFirstLine) {
  316.     time_t now = time(NULL);
  317.     mailF.printf( "\n---------- %s", ctime(&now) );
  318.     mailFirstLine = 0;
  319.     }
  320.     va_start( ap, fmt );
  321.     res = mailF.vprintf( fmt, ap );
  322.     if (conEcho)
  323.     res = vprintfT( fmt, ap );
  324.     va_end( ap );
  325.  
  326.     if ( !mailExcept)
  327.     mpSema.Release();
  328.     return res;
  329. }   // TAreasMail::mailPrintf
  330.  
  331.  
  332.  
  333. int TAreasMail::mailPrintf1( int doEcho, const char *fmt, ... )
  334. //
  335. //  prints a single line to the mail file without any header...
  336. //
  337. {
  338.     va_list ap;
  339.     int res;
  340.  
  341.     assert( mailF.isOpen() );
  342.  
  343.     if ( !mailExcept)
  344.     mail.Request();
  345.  
  346. ////    assert( !mailStarted );   // possible during exceptions
  347.     mailStarted = 1;
  348.  
  349.     va_start( ap, fmt );
  350.     res = mailF.vprintf( fmt, ap );
  351.     if (doEcho)
  352.     res = vprintfT( fmt, ap );
  353.     va_end( ap );
  354.     mailF.flush();
  355.  
  356.     mailStarted = 0;
  357.     if ( !mailExcept)
  358.     mail.Release();
  359.     return res;
  360. }   // TAreasMail::mailPrintf1
  361.  
  362.  
  363.  
  364. void TAreasMail::mailStart( int doEcho )
  365. {
  366. #ifdef TRACE_ALL
  367.     printfT( "TAreasMail::mailStart()\n" );
  368. #endif
  369.     if ( !mailExcept)
  370.     mail.Request();
  371.     mailStarted   = 1;
  372.     mailFirstLine = 1;
  373.     conEcho = doEcho;
  374. //// new line + datum in Mail ausgeben / mail öffnen...
  375. }   // TAreasMail::mailStart
  376.  
  377.  
  378.  
  379. void TAreasMail::mailStop( void )
  380. {
  381. #ifdef TRACE_ALL
  382.     printfT( "TAreasMail::mailStop()\n" );
  383. #endif
  384.     conEcho = 0;
  385.     if ( !mailFirstLine)
  386.     mailPrintf( "-----------------------------------\n\n" );
  387.     mailF.flush();
  388.     mailStarted = 0;
  389.     if ( !mailExcept)
  390.     mail.Release();
  391. }   // TAreasMail::mailStop
  392.  
  393.  
  394.  
  395. void TAreasMail::closeAll( void )
  396. {
  397. #ifdef TRACE_ALL
  398.     printfT( "TAreasMail::closeAll()\n" );
  399. #endif
  400.     if (mailF.isOpen()) {
  401.     mailF.flush();                       // sollte eigentlich nicht notwendig sein !?
  402.     if (mailForced) {
  403.         mailF.close(1);
  404.         areasF.printf( "%s\t%s\t%s\n",mailName,"Email","mn" );
  405.         areasF.flush();
  406.     }
  407.     else
  408.         mailF.remove();
  409. ////    delete mailName;
  410.     }
  411.     TAreas::closeAll();
  412. }   // TAreasMail::closeAll
  413.