home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PCBOARD / PCBM102.ZIP / SOURCES.ZIP / POSTMSG.C < prev    next >
C/C++ Source or Header  |  1994-01-22  |  18KB  |  532 lines

  1. /*
  2.  ┌────────────────────────────────────────────────────────────────────────┐
  3.  │                                                                        │
  4.  │    ▒▒▒▒▒▒▄ ▒▒▒▒▒▒▄ ▒▒▒▒▒▒▒▄ ▒▒▒▒▒▒▒▒▄ ▒▒▒▒▒▒▄ ▒▒▄      ▒▒▄ ▒▒▒▒▒▒▄     │
  5.  │    ▒▒█▀▒▒█ ▒▒█▀▀▀▀  ▒▒█▀▒▒█ ▒▒█▒▒█▒▒█ ▒▒█▀▒▒█  ▒▒█    ▒▒█▀ ▒▒█▀▀▀▀     │
  6.  │    ▒▒▒▒▒▒█ ▒▒█      ▒▒▒▒▒█▀ ▒▒█▒▒█▒▒█ ▒▒█ ▒▒█   ▒▒█  ▒▒█▀  ▒▒▒▒▄       │
  7.  │    ▒▒█▀▀▀▀ ▒▒█      ▒▒█▀▒▒█ ▒▒█ ▀▀▒▒█ ▒▒█ ▒▒█    ▒▒█▒▒█▀   ▒▒█▀▀       │
  8.  │    ▒▒█     ▒▒▒▒▒▒▄ ▒▒▒▒▒▒▒█ ▒▒█   ▒▒█ ▒▒▒▒▒▒█     ▒▒▒█▀    ▒▒▒▒▒▒▄     │
  9.  │     ▀▀      ▀▀▀▀▀▀  ▀▀▀▀▀▀▀  ▀▀    ▀▀  ▀▀▀▀▀▀      ▀▀▀      ▀▀▀▀▀▀     │
  10.  │                                                                        │
  11.  ├────────────────────────────────────────────────────────────────────────┤
  12.  │                                                                        │
  13.  │    Module : Postmsg.c : Postage de messages directement dans une       │
  14.  │             base de message PcBoard - par René Cougnenc (ANALIST)      │
  15.  │                                                                        │
  16.  │             Remis au gout du jour par Vincent Gillet pour supporter    │
  17.  │             l'utilisation de variables.                                │
  18.  │                                                                        │
  19.  ╘════════════════════════════════════════════════════════════════════════╛
  20.             Compilation: modèle mémoire large.
  21. */
  22. #include <stdio.h>
  23. #include <share.h>
  24. #include <string.h>
  25. #include <time.h>
  26. #include <malloc.h>
  27. #include <sys/locking.h>
  28.  
  29. #include "postmsg.h"
  30. #include "pcbmove.h"
  31. #include "strings.h"
  32.  
  33. #define IDX_EXT     ".IDX"     /* Extension du fichier index.... */
  34.  
  35.  
  36. char index_file[80] ;          /* Fichier index base message     */
  37. char basehead[128]    ;        /* Header de la base messages     */
  38.  
  39. long HighMsg,                  /* Numéro message plus élevé      */
  40.      LowMsg ,                  /* Numéro message le plus bas     */
  41.      ActiveMsgs;               /* Nombre de messages actifs      */
  42.  
  43. indextype Index;
  44.  
  45. /*-------------------------------------------------------------------------*/
  46. /*
  47.  * PostFile: Poste le fichier fname à FromField, en private.
  48.  *
  49.  *           Retourne 1 en cas d'erreur, 0 si succès.
  50.  *
  51.  */
  52. PostFile( char *fname)
  53. {
  54.     int test ;
  55.     char *txtbuf ;
  56.                                                 /* Allocation buffers */
  57.     if( (txtbuf = (char *) calloc(1,MAXMSG)) == NULL )
  58.     {
  59.         puterrorlog(_Strings[L_MallocMessageError], MAXMSG);
  60.         return ERROR ;
  61.     }
  62.  
  63.     if( readtxt(fname,txtbuf) )         /* Lecture du texte   */
  64.     {                                   /* avec remplacement des */
  65.           free(txtbuf);                 /* variables */
  66.           return ERROR ;
  67.     }
  68.  
  69.     sprintf (tampon, "PCBMOVE (%s) ERROR", __Version__);
  70.  
  71.     test = PostMessage(PRIVATE, LOCAL,            /* Postage du message */
  72.                        Config.ToField,FromField, tampon,
  73.                        txtbuf, Config.MessageBase);
  74.  
  75.     free(txtbuf);
  76.     return test ;
  77. }
  78. /*-------------------------------------------------------------------------*/
  79. /*-------------------------------------------------------------------------
  80.  *
  81.  *   PostMessage: Fonction à appeler pour poster un message.
  82.  *
  83.  *                status :  Status du message PUBLIC, PRIVATE ou COMMENT
  84.  *                echo   :  ECHO ou NOECHO
  85.  *                From   :  Pointeur sur le nom de l'auteur
  86.  *                  To   :  Pointeur sur le nom du destinataire
  87.  *               Subject :  Pointeur sur la chaine du sujet
  88.  *                   text:  Pointeur sur le texte du message.
  89.  *            MessageBase:  Pointeur sur le nom du fichier de la base
  90.  *                          des messages.
  91.  *
  92.  *
  93.  *           La fonction retourne 0 si le message a pu être posté.
  94.  *                                1 en cas d'erreur.
  95.  */
  96. int
  97. PostMessage( char status, char echo, char *From, char *To, char *Subject,
  98.              char *text, char *MessageBase )
  99. {
  100.     FILE *fmsg,*fidx;
  101.     char msghead[128];
  102.     char  offset_val[4];
  103.     long  val;
  104.     char *msgbuf ;
  105.  
  106.     memset(msghead,0x20,128 );  /* Resette le header des messages   */
  107.     mkPCBnames( );              /* Retrouve le nom du fichier index */
  108.  
  109.     if(( fmsg = _fsopen(MessageBase,"r+b", SH_DENYNO)) == NULL )
  110.     {
  111.         puterrorlog(_Strings[L_CanNotAccesMessage], MessageBase);
  112.         return ERROR ;
  113.     }
  114.  
  115.     if(( fidx = _fsopen(index_file,"r+b", SH_DENYNO)) == NULL )
  116.     {
  117.         puterrorlog(_Strings[L_CanNotOpenIndexFile], index_file );
  118.         fclose( fmsg);
  119.         return ERROR ;
  120.     }
  121.                         /* Alloue un buffer pour le message codé */
  122.     if( (msgbuf = (char *) calloc(1,MAXMSG)) == NULL )
  123.     {
  124.         puterrorlog(_Strings[L_MallocMessageError], MAXMSG);
  125.         fclose(fmsg);
  126.         fclose(fidx);
  127.         return ERROR ;
  128.     }
  129.  
  130.     locking (fileno(fmsg), LK_LOCK, filelength (fileno(fmsg)));
  131.     locking (fileno(fidx), LK_LOCK, filelength (fileno(fidx)));
  132.                         /* verouille tout pour l'ajout d'un message */
  133.  
  134.     fread(basehead, 128, 1, fmsg );  /* lecture header base message */
  135.  
  136.     HighMsg    = BasNum ( basehead) ;
  137.     LowMsg     = BasNum ( basehead + 4 );
  138.     ActiveMsgs = BasNum ( basehead + 8 );
  139.  
  140.                                     /* Remplissage du header individuel */
  141.     msghead[0] = status ;
  142.     sprintf(msghead + 23, "%-25s", To );
  143.     sprintf(msghead + 58, "%-25s", From );
  144.     sprintf(msghead + 83, "%-25s", Subject );
  145.     msghead[120] =  225 ; /* Active Message */
  146.     msghead[121] =  echo ;
  147.     DateMessage( msghead );
  148.     msghead[9]   = CodeMessage( text , msgbuf );
  149.  
  150.     HighMsg ++ ;            /* On aura un message de plus, donc.       */
  151.     ActiveMsgs ++ ;
  152.  
  153.     ToBas ((SingleBasic *) (msghead +1),(double) HighMsg ); /* Numéro message */
  154.     ToBas ((SingleBasic *) (msghead +5),(double) 0L );      /* Pas de réf.    */
  155.  
  156.                             /* ecrit l'offset du prochain message dans */
  157.                             /* le fichier index. C'est la fin actuelle */
  158.                             /* de la base messages bien entendu.       */
  159.  
  160.     if( fseek (fidx, 0L, SEEK_END ) != 0 )
  161.     {
  162.         puterrorlog("Erreur, base de messages pleine ?\n");
  163.         fclose(fidx);
  164.         fclose(fmsg);
  165.         free(msgbuf);
  166.         return ERROR ;
  167.     }
  168.  
  169.     fseek(fmsg, 0L, SEEK_END ) ;
  170.     Index.Offset = ftell( fmsg) ;               /* fill index structure */
  171.     Index.Num    = HighMsg;
  172.     sprintf(Index.To  , "%-25s", To );
  173.     sprintf(Index.From, "%-25s", From );
  174.     Index.Status = status;
  175.     /* Index.Date updated in DateMessage() (see up) */
  176.     memset (Index.Reserved, 0, sizeof (Index.Reserved));
  177.     fwrite (&Index.Offset, sizeof (Index), 1, fidx ) ;  /* write index structure */
  178.  
  179.                                      /* Ecrit le header du message     */
  180.                                      /* puis le message lui même...    */
  181.     fwrite(msghead, 128, 1, fmsg );
  182.     fwrite(msgbuf,128, (int) msghead[9] -1, fmsg );
  183.  
  184.                             /* Update le header de la base de messages*/
  185.  
  186.     ToBas ((SingleBasic *) basehead,      (double)    HighMsg );
  187.     ToBas ((SingleBasic *) (basehead +4), (double)    LowMsg  );
  188.     ToBas ((SingleBasic *) (basehead +8), (double) ActiveMsgs );
  189.     fseek(fmsg, 0L, SEEK_SET ) ;
  190.     fwrite(basehead, 128, 1, fmsg );
  191.  
  192.     fclose(fidx );
  193.     fclose(fmsg );
  194.     free(msgbuf) ;
  195.     return OK ;
  196. }
  197. /*-------------------------------------------------------------------------
  198.  *
  199.  * mkPCBnames:Recrée le nom du fichier index (.ndx) à partir du nom de la
  200.  *            base de messages, qu'elle ait une extension ou pas.
  201.  *            Fonctionne quelque soit le path (/pcb/toto.zob/machin/msgs.msg
  202.  *            par exemple...)
  203.  *
  204.  *            Remplit la variable globale avec le noms du fichier.
  205.  */
  206. void
  207. mkPCBnames(void)
  208. {
  209.     int i ;
  210.  
  211.     strcpy( index_file, Config.MessageBase);
  212.     i = strlen( Config.MessageBase);
  213.  
  214.     while (--i)
  215.     {
  216.         if( index_file[i] == '/' || index_file[i] == '\\' )
  217.         break ;
  218.         if( index_file[i] == '.' )
  219.         {
  220.             index_file[i] = '\0' ;
  221.             break ;
  222.         }
  223.  
  224.     }
  225.  
  226.     strcat( index_file, IDX_EXT);
  227. }
  228. /*-------------------------------------------------------------------------*/
  229. /*-------------------------------------------------------------------------
  230.  *
  231.  *       readtxt: Lit  le fichier contenant le message à poster.
  232.  *                retourne 1 en cas de problème en affichant l'erreur
  233.  *                retourne 0 si tout va bien.
  234.  *                remplace aussi les variables de la forme %VARIABLES%
  235.  *
  236.  *  VARIABLES :
  237.  *  ===========
  238.  *      FILE_TO_MOVE    : Nom du fichier à déplacer
  239.  *      GOOD_AREA       : Area où a été trouvé le fichier lorsque il y a eu
  240.  *                        recherche
  241.  *      AREA_ORI        : Area spécifié en origine
  242.  *      AREA_TAR        : Area spécifié en destination
  243.  *      AREA_ORI_DESC   : Description de l'area en origine
  244.  *      AREA_TAR_DESC   : Description de l'area en destination
  245.  *      DATE_MESSAGE    : Date du message envoyé à PCBMOVE
  246.  *      HEURE_MESSAGE   : Heure du message envoyé à PCBMOVE
  247.  */
  248. int
  249. readtxt( char *fname, char *txtbuf)
  250. {
  251.     FILE *fp ;
  252.     char *ptr = txtbuf ;
  253.     char *debut_var;
  254.     int i = 0 ;
  255.     int len = 0;
  256.  
  257.     if(( fp = fopen (fname,"rt") ) == NULL )
  258.     {
  259.         printf(_Strings[L_CanNotOpenReadMode], fname);
  260.         return ERROR ;
  261.     }
  262.     setvbuf(fp, NULL, _IOFBF, 5280 );
  263.  
  264.     while( fread (ptr++,1,1,fp ) )
  265.     {
  266.         i++;
  267.         if (*(ptr-1) == '%')
  268.         {                                       /* si y'a un % */
  269.            debut_var = ptr;                     /* on cherche le % suivant */
  270.            while( fread (ptr++,1,1,fp ) && *(ptr-1) != '%');
  271.            *(ptr-1) = 0;
  272.  
  273.            /* une fois délimité la variable, regarde compare */
  274.  
  275.            if (!strcmp (debut_var, "FILE_TO_MOVE")){
  276.               strcpy (debut_var-1, file_to_move);
  277.               len = strlen(file_to_move);
  278.            } /* fin if */
  279.  
  280.            if (!strcmp (debut_var, "GOOD_AREA")){
  281.               sprintf (tampon,"%02d", AreaFound);
  282.               strcpy (debut_var-1, tampon);
  283.               len = strlen(tampon);
  284.            } /* fin if */
  285.  
  286.            if (!strcmp (debut_var, "AREA_ORI")){
  287.               sprintf (tampon,"%02d", area_ori);
  288.               strcpy (debut_var-1, tampon);
  289.               len = strlen(tampon);
  290.            } /* fin if */
  291.  
  292.            if (!strcmp (debut_var, "AREA_TAR")){
  293.               sprintf(tampon,"%02d", area_tar);
  294.               strcpy (debut_var-1, tampon);
  295.               len = strlen(tampon);
  296.            } /* fin if */
  297.  
  298.            if (!strcmp (debut_var, "AREA_ORI_DESC")){
  299.               getareaname (area_ori);
  300.               strcpy (debut_var-1, tampon);
  301.               len = strlen(tampon);
  302.            } /* fin if */
  303.  
  304.            if (!strcmp (debut_var, "AREA_TAR_DESC")){
  305.               getareaname (area_tar);
  306.               strcpy (debut_var-1, tampon);
  307.               len = strlen(tampon);
  308.            } /* fin if */
  309.  
  310.            if (!strcmp (debut_var, "GOOD_AREA_DESC")){
  311.               getareaname (AreaFound);
  312.               strcpy (debut_var-1, tampon);
  313.               len = strlen(tampon);
  314.            } /* fin if */
  315.  
  316.            if (!strcmp (debut_var, "DATE_MESSAGE")){
  317.               strcpy (debut_var-1, DateField);
  318.               len = strlen(DateField);
  319.            } /* fin if */
  320.  
  321.            if (!strcmp (debut_var, "HEURE_MESSAGE")){
  322.               strcpy (debut_var-1, HeureField);
  323.               len = strlen(HeureField);
  324.            } /* fin if */
  325.  
  326.            if (!strcmp (debut_var, "SECURITY_MIN")){
  327.               strcpy (debut_var-1, Config.Security);
  328.               len = strlen(Config.Security);
  329.            } /* fin if */
  330.  
  331.            if (!strcmp (debut_var, "FORWARD_USER")){
  332.               strcpy (debut_var-1, Config.ForwardUser);
  333.               len = strlen(Config.ForwardUser);
  334.            } /* fin if */
  335.  
  336.            ptr = debut_var + len - 1;
  337.            i += len - 1;       /* on remet le pointeur pour lire la suite */
  338.  
  339.         } /* fin if */
  340.         if (i > MAXMSG)
  341.         {
  342.             puterrorlog(_Strings[L_MessageTooLong]);
  343.             fclose(fp);
  344.             return ERROR ;
  345.         }
  346.     }
  347.  
  348.     fclose(fp);
  349.     return OK ;
  350. }
  351. /*-------------------------------------------------------------------------*/
  352. /*-------------------------------------------------------------------------
  353.  *
  354.  *   CodeMessage: Code, dans le buffer msgbuf , le texte du message
  355.  *                au format PcBoard.
  356.  *
  357.  *                Retourne le nombre de blocs de 128 bytes + le header,
  358.  *                à inscrire dans le header du message.
  359.  */
  360. int
  361. CodeMessage( char *text, char *msgbuf)
  362. {
  363.  unsigned char ch;
  364.  unsigned char *tamp = msgbuf ;
  365.  int  CountSize   = 0,  /* Sera la taille totale du texte codé sans Header */
  366.       CountChar   = 0,
  367.       CountBlocks = 2;  /* Le premier bloc de 128 chars est tjrs le Header */
  368.  
  369.    while(ch = *text++)
  370.    {
  371.           if(ch == 0x0A) ch = 227;
  372.           if(ch == 0x0D) continue ;
  373.           *tamp = ch;     tamp ++;
  374.           CountChar++; CountSize ++;
  375.           if(CountChar > 127)
  376.           {
  377.               CountBlocks++;
  378.               CountChar = 0;
  379.           }
  380.     }
  381.  
  382.                   /* Ajuste la taille du dernier bloc à 128 chars */
  383.                   /*----------------------------------------------*/
  384.  
  385.    while(CountChar < 128)
  386.    {
  387.           *tamp = 0x20;     tamp ++;
  388.           CountChar++; CountSize++;
  389.    }
  390.  
  391.    /* printf("Nb blocs = %d\n", CountBlocks  ); */
  392.     return CountBlocks  ; /* retourne nombre de blocs + header */
  393. }
  394. /*-------------------------------------------------------------------------*/
  395. /*-------------------------------------------------------------------------
  396.  *
  397.  *   DateMessage:  Positionne la date et l'heure système dans le header
  398.  *                 du message.
  399.  */
  400. void
  401. DateMessage( char *header)
  402. {
  403.     long Time;
  404.     struct tm *tm ;
  405.     char buf[20]  ;
  406.  
  407.  
  408.      time(&Time);
  409.      tm = localtime(&Time);
  410.      sprintf(buf,"%02d-%02d-%02d%02d:%02d",
  411.              tm->tm_mon +1 ,tm->tm_mday, tm->tm_year,
  412.              tm->tm_hour,tm->tm_min);
  413.  
  414.     Index.Date = (unsigned)     /* fill date Field in index structure */
  415.       (date_julien (tm->tm_mday, tm->tm_mon +1, tm->tm_year + 1900) - 2415020L);
  416.                              /* date_julien retourne 2415020 au 01.01.80) */
  417.  
  418.     strncpy(( char *) (header + 10), buf, 13 );
  419. }
  420. /*-------------------------------------------------------------------------*/
  421. /*-------------------------------------------------------------------------*/
  422. /*
  423.                     Conversions des nombres Basic en IEEE
  424.  
  425.                Fonctions adaptées de 'realcnvt', par David Terry
  426.  
  427.                       Information collected and written by
  428.                                  David W. Terry
  429.                                      2/4/88
  430.  
  431.                             DONATED TO PUBLIC DOMAIN
  432. */
  433. /*---------------------------------------------------------------------------
  434.  *
  435.  *         Lecture d'un nombre Basic 4 bytes Réel Simple précision
  436.  *
  437.  *         Retourne un double, le nombre Basic est un pointeur sur un tableau
  438.  *         de 4 caracteres.
  439.  */
  440.  
  441. double BasNum(SingleBasic OldNum)
  442. {
  443.  
  444.         IEEEdouble NewNum;
  445.         char       Sign;
  446.         int        Exp;
  447.         int        X;
  448.  
  449.         for(X = 0; X < 4; X++)
  450.                 NewNum.byte[X] = 0x00;
  451.  
  452.         Sign = OldNum[2] & 0x80;
  453.         Exp = OldNum[3] - 0x81 + 0x3FF;
  454.         NewNum.byte[6] = (Exp << 4);
  455.         NewNum.byte[7] = (Exp >> 4) | Sign;
  456.  
  457.         for(X = 2; X > 0; X--)
  458.         {
  459.                 OldNum[X] <<= 1;
  460.                 OldNum[X] |= OldNum[X-1] >> 7;
  461.         }
  462.         OldNum[0] <<= 1;
  463.  
  464.         for(X = 6; X >= 4; X--)
  465.         {
  466.                 NewNum.byte[X] |= OldNum[X-4] >> 4;
  467.                 NewNum.byte[X-1] =  OldNum[X-4] << 4;
  468.         }
  469.  
  470.         return(NewNum.value);
  471. }
  472.  
  473. /*---------------------------------------------------------------------------
  474.  *
  475.  *   Conversion d'un double en nombre Basic 4 octets double précision
  476.  *
  477.  *   Remplit un tableau de 4 caracteres correspondant au double passé.
  478.  */
  479.  
  480. void ToBas(SingleBasic *New, double Old)
  481. {
  482.         char    Sign;
  483.         int     Exp;
  484.         int     X;
  485.         unsigned char *NewNum, *OldNum;
  486.  
  487.         NewNum = (char *) New;
  488.         OldNum = (char *) &Old;
  489.  
  490.         Sign = OldNum[7] & 0x80;
  491.         Exp  = ((OldNum[7] & 0x7F) << 4) + (OldNum[6] >> 4);
  492.         if (Exp)
  493.                 Exp += 0x81 - 0x3FF;
  494.  
  495.         for (X = 2; X >= 0; X--)
  496.         {
  497.                 NewNum[X] = OldNum[X+4] << 4;
  498.                 NewNum[X] |= OldNum[X+3] >> 4;
  499.         }
  500.  
  501.         for (X = 0; X < 2; X++)
  502.         {
  503.                 NewNum[X] >>= 1;
  504.                 NewNum[X] |= NewNum[X+1] << 7;
  505.         }
  506.         NewNum[2] >>= 1;
  507.  
  508.         NewNum[2] |=  Sign;
  509.         NewNum[3] =   Exp;
  510. }
  511. /*----------------------------------------------------------------------------*/
  512. long date_julien(int jour, int mois, int annee) /* algorythme de calcul */
  513. {                                               /* by Jean-Claude Ambroise */
  514.     int valeur_mois;
  515.     int valeur_annee;
  516.     float valeur_jour;
  517.     long jour_julien;
  518.  
  519.     valeur_jour = (float) jour + 0.5;
  520.     valeur_mois = mois + 13;
  521.     valeur_annee = ((annee + 1) / 100) - 6;
  522.     if (mois < 3 && annee > 0) annee --;
  523.     if (valeur_mois > 15) valeur_mois = valeur_mois - 12;
  524.     jour_julien = (long)( 365.25 * annee) + (long)( 30.6001 * valeur_mois);
  525.     jour_julien = (long)(jour_julien + valeur_jour - valeur_annee + 1720994.5);
  526.     if (valeur_annee < 10 && jour_julien > 2299160) jour_julien --;
  527.     if (jour_julien < 2299161) jour_julien = jour_julien + valeur_annee;
  528.     return jour_julien;
  529. }
  530.  
  531. /*----------------------------------------------------------------------------*/
  532.