home *** CD-ROM | disk | FTP | other *** search
/ The Mac 1996 October / The Mac (October 1996).dmg / Web Authoring / Digester / sources / digester.c next >
Encoding:
C/C++ Source or Header  |  1996-01-18  |  39.7 KB  |  1,814 lines  |  [TEXT/EDIT]

  1. /*     file: digester2.1.1b.c
  2.         purpose:    digest e-mails from info-mac digest into HTML format
  3.         author:        Andre' C. van der Ham
  4.         e-mail:        A.C.vanderHam@ET.TUDelft.NL
  5.     
  6.         notice:        Don't forget to set the path to your scripts directory
  7.             
  8.         for THINK C users:
  9.         project profile:
  10.             segment 1:     digester
  11.                         MacTraps
  12.             segment 2:    ANSI
  13.                         unix
  14.                         
  15.         project type:    size:     100K
  16.                         flags:    0080    32-bit compatibility
  17.                             
  18.         You had better also delete all the num_args and arg_strings stuff in main.
  19.         So, 'int main( void )'.
  20.         
  21. */
  22.  
  23. /* includes */
  24.  
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #ifdef __THINK__
  29. #include <Files.h>
  30. #include <console.h>
  31. #include <StandardFile.h>
  32. #endif
  33.  
  34. #define    LINELENGTH    80
  35. #define    DRE            "http://dutera.et.tudelft.nl/people/vdham/vdham.html"
  36. #define    PARMS        "digester.par"
  37. #define    notify        printf
  38.  
  39. int    debug=0;
  40.  
  41. FILE    *outTPrg, *outTMes, *outPrg, *outMes, *inP;
  42.  
  43. typedef struct Pars
  44. {
  45.     char    scriptPath[80];        /* path to mail script */
  46.     char    imagePath[80];        /* path to images of buttons */
  47.     char    sitesFile[20];        /* path to sites file */
  48.     char    destPath[80];        /* additional path for destination files */
  49.     char    Ftype[10];            /* finder type */
  50.     char    Fcreator[10];        /* finder creator */
  51.     
  52.     char    DigestName[20];        /* name of the original digest file */
  53.     char    nameAll[20];        /* name of the complete HTML digest file */
  54.     char    nameTOC[20];        /* name of the toc only file */
  55.     char    nameProg[20];        /* name of the programs file (either with or without toc) */
  56.     char    nameMess[20];        /* name of the messages file (either with or without toc) */
  57.     
  58.     char    BegOfDigest[80];    /* begin of digest text */
  59.     char    Volume[80];            /* volume number prefix */
  60.     char    Issue[80];            /* issue number prefix */
  61.     char    Date[20];            /* date text prefix */
  62.     
  63.     char    EndOfDigest[80];    /* end of digest text */
  64.     char    BeginOfTopics[80];    /* begin of topics text */
  65.     char    EndOfTopics[80];    /* end of topics text */
  66.     char    EndOfMessage[80];    /* end of message text */
  67.     
  68.     char    RootPath[20];        /* begin of root directory of mirror */
  69.     char    BegOfFile[40];        /* begin of file path */
  70.     char    EndOfFile[20];        /* end of file path */
  71.     
  72.     int        Type;                /* type of digest */
  73.     int        Buttons;            /* buttons on/off */
  74.     int        Mail;                /* mail button on/off */
  75.     int        Files;                /* archive files link on/off */
  76.     int        URLs;                /* URL link on/off */
  77.     int        MURLs;                /* mail URLs on/off */
  78.  
  79.     char    *sites;                /* pointer to array of strings of mirror sites */
  80.     int        nSites;                /* number of sites in array */
  81.     
  82. } *ParsP;
  83.  
  84.  
  85. typedef struct Vars
  86. {
  87.     char     whichFile[512];
  88.     int        VolNum;
  89.     int        Issue;
  90.     int        itemCount;
  91.     char    header[100];    /* header of digest */
  92.  
  93.     char    nameAll[20];        /* name of the complete digest file */
  94.     char    nameTOC[20];        /* name of the toc only file */
  95.     char    nameProg[20];        /* name of the programs file (either with or without toc) */
  96.     char    nameMess[20];        /* name of the messages file (either with or without toc) */
  97.     
  98. } *VarsP;
  99.  
  100.  
  101. #ifdef __THINK__
  102.  
  103. /**********************************
  104.  
  105.     Mac specific file get function
  106.     
  107. */
  108.  
  109. int GetName( char *name )
  110. {
  111.     SFReply        theReply;
  112.     Point        where;
  113.     SFTypeList    typeList;
  114.  
  115.     typeList[0]='TEXT';            /* file type to search for */
  116.     where.h=20;  where.v=90;    /* SF dialog window position */
  117.  
  118.     SFGetFile(where,0,0L,1,typeList,NULL,&theReply);
  119.  
  120.     if ( theReply.good == TRUE ) 
  121.     { 
  122.         strncpy( name, (char *)(theReply.fName+1), theReply.fName[0] );
  123.         name[theReply.fName[0]]=0;
  124.         return(1);
  125.     }
  126.     else
  127.         return(0);
  128. }
  129.  
  130. #endif
  131.  
  132. /**********************************
  133.  
  134.     Find the DIGEST header and fill-in the volume and issue numbers
  135.     also the header is copied for future use
  136.     
  137. */
  138.  
  139. int findHeader( ParsP p, VarsP v, char *line, int parse )
  140. {
  141.     char    *cptr;
  142.     int    found=0;
  143.     
  144.     /* init header vars */
  145.     
  146.     if(parse)
  147.     {
  148.         v->VolNum=0;
  149.         v->Issue=0;
  150.     }
  151.     
  152.     /* while there is still a line to read find header */
  153.     
  154.     do {    
  155.             if( feof( inP ) )
  156.             {
  157.                 notify("End of file reached.\n");
  158.                 notify("Could not find Begin of Digest (BOD) tag.\n");
  159.                 notify("Closing file ...\n");
  160.                 return(0);
  161.             }
  162.             
  163.             /* check if the line is not empty */
  164.             
  165.             if( fgets( line, 256, inP ) != NULL )
  166.             {
  167.                 /* check for the begin of digest string */
  168.                 
  169.                 if( strncmp( line, p->BegOfDigest, strlen(p->BegOfDigest) ) == 0 )
  170.                 {
  171.                     notify("Found %s\n", p->BegOfDigest);
  172.                     notify(line);
  173.                     
  174.                     strcpy( v->header, line );            /* make a copy for use as heading */
  175.                     
  176.                     found = 1;
  177.                     
  178.                     /* extract volume number */
  179.                     
  180.                     if( parse )
  181.                     {
  182.                         if( p->Volume!=NULL )
  183.                         {
  184.                             if( strlen(p->Volume)>0 )
  185.                             {
  186.                                 cptr = (char *)strstr( line, p->Volume );
  187.                                 if( cptr==NULL )
  188.                                 {
  189.                                     notify("Can't find volume number\n");
  190.                                     notify("Please specify Volume number: ");
  191.                                     scanf("%d", &(v->VolNum));
  192.                                 }
  193.                                 else
  194.                                     v->VolNum = atoi( cptr+strlen(p->Volume) );
  195.                             }
  196.                         }
  197.                         
  198.                         /* extract issue number */
  199.                         
  200.                         if( p->Issue!=NULL )
  201.                         {
  202.                             if( strlen(p->Issue)>0 )
  203.                             {
  204.                                 cptr = (char *)strstr( line, p->Issue );
  205.                                 if( cptr==NULL )
  206.                                 {
  207.                                     notify("Can't find issue number\n");
  208.                                     notify("Please specify Issue number: ");
  209.                                     scanf("%d", &(v->Issue));
  210.                                 }
  211.                                 else
  212.                                     v->Issue = atoi( cptr+strlen(p->Issue) );
  213.                             }
  214.                             else
  215.                             {
  216.                                 notify("Please specify Issue number: ");
  217.                                 scanf("%d", &(v->Issue));
  218.                             }
  219.                         }    
  220.                     }
  221.                 }
  222.             }
  223.     } while( !found );
  224.     
  225.     return(1);
  226. }
  227.  
  228. void GetDestName( char *format, VarsP v, char *name, char *path, char *comment )
  229. {
  230.     char    dummy[200];
  231.     
  232.     if( (v->Issue!=0) && (v->VolNum!=0) )
  233.     {
  234.         sprintf(name, format, v->Issue, v->VolNum );
  235.     }
  236.     else if( (v->Issue!=0 ) )
  237.     {
  238.         sprintf(name, format, v->Issue );
  239.     }
  240.     else
  241.     {
  242.         notify( comment );
  243.         fgets(name,38,stdin);
  244.         
  245.         if( strlen(name)<1 )
  246.         {
  247.             notify("Illegal file name!\n");
  248.             strcpy( name, "digest.html");
  249.             notify("Using default ");
  250.         }
  251.     }
  252.     
  253.     strcat(path, name);
  254.     notify("name = '%s'\n", path);
  255. }
  256.  
  257. #ifdef __THINK__
  258.                 
  259. void SetupFinderInfo( char *name, OSType type, OSType creator, char *path )
  260. {
  261.     char    fileN[200];
  262.     Str255     fileName;
  263.     FInfo    fndrInfo;
  264.     
  265.     strcpy( fileN, path );
  266.     strcat( fileN, name );
  267.     
  268.     notify("Setting up finder info for '%s'.\n", fileN);
  269.     
  270.     strncpy( (char *)fileName+1, fileN, strlen(fileN) );
  271.     
  272.     fileName[0] = strlen(fileN);
  273.     
  274.     if( GetFInfo(fileName,0,&fndrInfo)==0 )
  275.     {
  276.         fndrInfo.fdType = type;
  277.         fndrInfo.fdCreator = creator;
  278.         if( SetFInfo(fileName, 0, &fndrInfo)!=0 )
  279.         {
  280.             notify("OS error setting finder info.\n");
  281.         }
  282.     }
  283.     else
  284.     {
  285.         notify("Couldn't set type creator due to OS error.\n");
  286.     }
  287. }
  288.  
  289. void SetUpAllFinderInfo( ParsP p, VarsP v )
  290. {
  291.     OSType     type, creator;
  292.     int        i;
  293.     OSType     k, test;
  294.     
  295.     
  296.     if( (strlen(p->Ftype)<4) || (strlen(p->Fcreator)<4) )
  297.     {
  298.         notify("Illegal type (FTYPE) and creator (FCREAT) specified.\n");
  299.         notify("Type and creator parameters should be 4 characters long.\n");
  300.         notify("Please, check your parameters file.\n");
  301.         return;
  302.     }
  303.     
  304.     k=1;
  305.     type=0;
  306.     creator=0;
  307.     
  308.     test=255;
  309.     
  310.     if( (char)test!=255 )    /* if little endian */
  311.     {    
  312.         notify("You have a Little Endian processor. Great, so what! Just checking.\n");
  313.  
  314.         for(i=0; i<4; i++)
  315.         {
  316.             type+=(OSType)(p->Ftype[3-i])*k;    
  317.             creator+=(OSType)(p->Fcreator[3-i])*k;
  318.             if(i<3) k *= 256;
  319.         }
  320.     }
  321.     else
  322.     {
  323.         notify("You have a Big Endian processor. Great, so what! Just checking.\n");
  324.  
  325.         for(i=0; i<4; i++)
  326.         {
  327.             type+=(OSType)(p->Ftype[i])*k;    
  328.             creator+=(OSType)(p->Fcreator[i])*k;
  329.             if(i<3) k *= 256;
  330.         }
  331.     }
  332.  
  333.     notify("Type: '%s', Creator '%s'.\n", p->Ftype, p->Fcreator);
  334.  
  335.     switch( p->Type )                        
  336.     {
  337.         case 1:        /* type 1: the entire digest in 1 file */
  338.         
  339.                 SetupFinderInfo( v->nameAll, type, creator, p->destPath );
  340.         break;
  341.         
  342.         case 2:        /* type 2: topics, programs and messages as separate files */
  343.         
  344.                 SetupFinderInfo( v->nameTOC, type, creator, p->destPath );
  345.                 if( p->Files )
  346.                 {
  347.                     SetupFinderInfo( v->nameProg, type, creator, p->destPath );
  348.                 }
  349.                 SetupFinderInfo( v->nameMess, type, creator, p->destPath );
  350.         break;
  351.         
  352.         case 3:        /* type 3: toc + progs, toc + mes */
  353.         
  354.                 /* toc + progs files */
  355.                 
  356.                 if( p->Files )
  357.                 {
  358.                     SetupFinderInfo( v->nameProg, type, creator, p->destPath );
  359.                 }
  360.                 
  361.                 SetupFinderInfo( v->nameMess, type, creator, p->destPath );
  362.         break;
  363.     }
  364.  
  365. }
  366.  
  367. #endif
  368.  
  369.  
  370.  
  371. int SetUpFiles( ParsP p, VarsP v )
  372. {
  373.     char    name[200];
  374.     
  375.     /* set-up output files */
  376.     
  377.     switch( p->Type )                        
  378.     {
  379.         case 1:        /* type 1: the entire digest in 1 file */
  380.         
  381.                 notify("Type 1:\n");
  382.                 
  383.                 strcpy( name, p->destPath );
  384.                 GetDestName( p->nameAll, v, v->nameAll, name,
  385.                             "Please specify destination file name for entire digest: " );
  386.                 
  387.                 if( (outTMes = fopen( name,"w")) == NULL )
  388.                 {
  389.                     notify( "Can't open '%s'\n", name );
  390.                     return(0);
  391.                 }
  392.                 
  393.                 if(debug)
  394.                     notify( "outTMes = %x\n", outTMes );
  395.                 
  396.                 outTPrg = NULL;
  397.                 outMes = NULL;
  398.                 outPrg = NULL;
  399.         break;
  400.         
  401.         case 2:        /* type 2: topics, programs and messages as separate files */
  402.         
  403.                 notify("Type 2:\n");
  404.                 
  405.                 strcpy( name, p->destPath );
  406.                 GetDestName( p->nameTOC, v, v->nameTOC, name,
  407.                             "Please specify destination file name for topics: " );
  408.               
  409.                   if( (outTMes = fopen( name,"w")) == NULL )
  410.                   {
  411.                     notify("Can't open '%s'\n", name );
  412.                       return(0);
  413.                   }
  414.               
  415.                   outTPrg = NULL;
  416.  
  417.                 if( p->Files )
  418.                 {
  419.                     strcpy( name, p->destPath );
  420.                     GetDestName( p->nameProg, v, v->nameProg, name,
  421.                                 "Please specify destination file name for programs: " );
  422.                   
  423.                       if( (outPrg = fopen( name,"w")) == NULL )
  424.                       {
  425.                         notify("Can't open '%s'\n", name );
  426.                           return(0);
  427.                       }
  428.  
  429.                 }
  430.                 
  431.                 strcpy( name, p->destPath );
  432.                 GetDestName( p->nameMess, v, v->nameMess, name,
  433.                             "Please specify destination file name for messages: " );
  434.               
  435.                   if( (outMes = fopen( name,"w")) == NULL )
  436.                   {
  437.                       notify("Can't open '%s'\n", name );
  438.                       return(0);
  439.                   }
  440.               
  441.         break;
  442.         
  443.         case 3:        /* type 3: toc + progs, toc + mes */
  444.         
  445.                 /* toc + progs files */
  446.                 
  447.                 if( p->Files )
  448.                 {
  449.                     strcpy( name, p->destPath );
  450.                     GetDestName( p->nameProg, v, v->nameProg, name,
  451.                                 "Please specify destination file name for programs: " );
  452.               
  453.                     if( (outTPrg = fopen( name,"w")) == NULL )
  454.                     {
  455.                         notify("Can't open '%s'\n", name );
  456.                         return(0);
  457.                     }
  458.                 }
  459.                 
  460.                 outPrg = NULL;
  461.                 
  462.                 /* toc + messages files */
  463.                 
  464.                 strcpy( name, p->destPath );
  465.                 GetDestName( p->nameMess, v, v->nameMess, name,
  466.                             "Please specify destination file name for messages: " );
  467.                 
  468.                 if( (outTMes = fopen( name,"w")) == NULL )
  469.                 {
  470.                     notify("Can't open '%s'\n", name );
  471.                     return(0);
  472.                 }
  473.                 
  474.                 outMes = NULL;              
  475.         break;
  476.         
  477.         default:
  478.                 notify( "Type of digest has not been specified, please check %s file.\n", PARMS);
  479.                 return(0);
  480.         break;
  481.     }
  482.  
  483.     return(1);
  484. }
  485.  
  486.  
  487. void SetUpTitle( ParsP p, VarsP v, FILE *out, char *Message )
  488. {
  489.     if( out != NULL )
  490.     {
  491.         fprintf(out,"<TITLE>Volume %d : Issue %d</TITLE>\n", v->VolNum, v->Issue);
  492.         fprintf(out,"<pre>\n\n");
  493.         fprintf(out,"<a href=index.html#issue%d-%d><img src=%sdigester.gif alt=Index></a> %s",
  494.                         v->Issue+1, v->VolNum, p->imagePath, Message);
  495.         
  496.         fprintf(out,"</pre>\n\n");
  497.         fprintf(out,"<hr>\n\n");
  498.     }
  499. }
  500.  
  501. char *findALink( char *line )
  502. {
  503.     char *cptr;
  504.     
  505.     if( (cptr=strstr(line, "http://"))!=NULL )         return(cptr);
  506.     if( (cptr=strstr(line, "ftp://"))!=NULL )         return(cptr);
  507.     if( (cptr=strstr(line, "mailto:"))!=NULL )         return(cptr);
  508.     if( (cptr=strstr(line, "gopher://"))!=NULL )     return(cptr);
  509.  
  510.     return(NULL);
  511. }
  512.  
  513. void linkLine( char *line )
  514. {
  515.     char    *cptr, *bptr, tempLine[512], resultLine[512];
  516.     int        found;
  517.     
  518.     cptr = line;
  519.     resultLine[0]=0;
  520.     
  521.     do {
  522.         found=0;
  523.         bptr=cptr;
  524.         
  525.         if( (cptr=findALink(bptr))!=NULL )
  526.         {
  527.             found=1;
  528.             if(debug) puts("found URL");
  529.             strncpy(tempLine, bptr, cptr-bptr);    /* copy preceeding stuff */
  530.             tempLine[cptr-bptr]=0;
  531.             strcat(resultLine, tempLine);
  532.             bptr=cptr;
  533.             while(     (*cptr!=0) && (*cptr!='\n')        /* find delimiter */
  534.                     && ( (*cptr=='.') || (*cptr=='~') || (*cptr=='/') || (*cptr=='@') 
  535.                          || (*cptr==':') || (*cptr=='-') || (*cptr=='+') || (*cptr=='_')
  536.                          || ((*cptr>='a') && (*cptr<='z'))
  537.                          || ((*cptr>='A') && (*cptr<='Z'))
  538.                          || ((*cptr>='0') && (*cptr<='9'))
  539.                        )
  540.                  ) cptr++;
  541.             strncpy(tempLine, bptr, cptr-bptr);    /* copy link */
  542.             tempLine[cptr-bptr]=0;
  543.             strcat(resultLine, "<a href=");
  544.             strcat(resultLine, tempLine);
  545.             strcat(resultLine, ">");
  546.             strcat(resultLine, tempLine);
  547.             strcat(resultLine, "</a>");
  548.         }
  549.     } while( found );
  550.     
  551.     if( bptr==line ) return;                    /* nothing happened */
  552.     strcat( resultLine, bptr );                    /* copy rest of the line */
  553.     strcpy( line, resultLine );                    /* copy it back */
  554. }
  555.  
  556.  
  557. void filterEntities( char *line )
  558. {
  559.     char     tempLine[512];
  560.     int    l, i;
  561.     
  562.     tempLine[0]=0;
  563.     l = 0;
  564.     for(i=0; i<strlen(line); i++ )
  565.     {
  566.         if( line[i]=='<' )
  567.         {
  568.             tempLine[l++] = '&';
  569.             tempLine[l++] = 'l';
  570.             tempLine[l++] = 't';
  571.             tempLine[l++] = ';';
  572.         }
  573.         else
  574.         if( line[i]=='>' )
  575.         {
  576.             tempLine[l++] = '&';
  577.             tempLine[l++] = 'g';
  578.             tempLine[l++] = 't';
  579.             tempLine[l++] = ';';
  580.         }
  581.         else
  582.         if( line[i]=='"' )
  583.         {
  584.             tempLine[l++] = '&';
  585.             tempLine[l++] = 'q';
  586.             tempLine[l++] = 'u';
  587.             tempLine[l++] = 'o';
  588.             tempLine[l++] = 't';
  589.             tempLine[l++] = ';';
  590.         }
  591.         else
  592.         if( line[i]=='&' )
  593.         {
  594.             tempLine[l++] = '&';
  595.             tempLine[l++] = 'a';
  596.             tempLine[l++] = 'm';
  597.             tempLine[l++] = 'p';
  598.             tempLine[l++] = ';';
  599.         }
  600.         else
  601.         {
  602.             tempLine[l++] = line[i];
  603.             tempLine[l] = 0;
  604.         }
  605.     }
  606.     strcpy( line, tempLine );
  607. }
  608.  
  609.  
  610. int SkipTOC( ParsP p, VarsP v, int addInfo )
  611. {
  612.     int     found;
  613.     char    line[256];
  614.  
  615.     found = 0;
  616.     
  617.     if( strlen(p->BeginOfTopics)<1 )
  618.     {
  619.         /* don't bother with TOC */
  620.         if( strlen(p->EndOfTopics)>0 )
  621.         {
  622.             do {
  623.                 if( fgets( line, 256, inP ) != NULL )
  624.                 if(strstr( line, p->EndOfTopics ) != NULL)
  625.                 {
  626.                     if( debug )
  627.                         notify( "Found end of Topics\n");
  628.                         
  629.                     return(1);
  630.                 }
  631.             } while( !feof(inP ) );
  632.             
  633.             notify("Couldn't find the begining of the messages.\n");
  634.             notify("Please, check the %s file EOT tag.\n", PARMS);
  635.             
  636.             return(0);
  637.         }
  638.         
  639.         notify("No BOT or EOT tag in %s\n", PARMS);
  640.         
  641.         return(1);
  642.     }
  643.     
  644.     do {
  645.             if( fgets( line, 256, inP ) != NULL )
  646.             {
  647.                 if( strstr( line, p->BeginOfTopics ) != NULL )
  648.                 {
  649.                     if( debug )
  650.                         notify( "Found begin of Topics\n");
  651.                         
  652.                     found = 1;
  653.                 }
  654.                 
  655.                 if(strstr( line, p->EndOfTopics ) != NULL)
  656.                 {
  657.                     if( debug )
  658.                         notify( "Found end of Topics\n");
  659.                         
  660.                     return(1);
  661.                 }
  662.             }
  663.             else
  664.             {                    
  665.                 return(0);
  666.             }
  667.     } while( !found );
  668.  
  669.     fgets( line, 256, inP ); /* get empty line */
  670.  
  671.     /* skip TOC */
  672.     
  673.     do{
  674.         fgets( line, 256, inP );
  675.     }while( (strlen(line)>1) 
  676.             && !feof(inP)
  677.             && (strstr( line, p->EndOfTopics ) == NULL)
  678.            );
  679.  
  680.     if(debug)
  681.         notify("TOC skipped\n");
  682.  
  683.     if( strstr( line, p->EndOfTopics ) != NULL ) return(1);
  684.     
  685.     /* Now copy all lines to message files */
  686.     
  687.     if( outTMes!=NULL && addInfo==1 )
  688.         fputs( "<HR><P><PRE>", outTMes );
  689.  
  690.     if( outTPrg!=NULL && addInfo==1 )
  691.         fputs( "<HR><P><PRE>", outTPrg );
  692.     
  693.     do
  694.     {
  695.         fgets( line, 256, inP );
  696.         filterEntities(line);
  697.         if( p->URLs ) linkLine( line );
  698.         
  699.         if( outTMes!=NULL && addInfo==1 )
  700.             fputs( line, outTMes );
  701.             
  702.         if( outTPrg!=NULL && addInfo==1 )
  703.             fputs( line, outTPrg );
  704.     }
  705.     while( (strstr( line, p->EndOfTopics ) == NULL ) && !feof(inP) );
  706.  
  707.     if( outTMes!=NULL && addInfo==1 )
  708.         fputs( "</PRE>", outTMes );
  709.  
  710.     if( outTPrg!=NULL && addInfo==1 )
  711.         fputs( "</PRE>", outTPrg );
  712.     
  713.     if( feof(inP) )
  714.     {
  715.         notify( "Cannot find end of Topics phrase ... aborting\n");
  716.         return(0);
  717.     }
  718.     
  719.     if(debug)
  720.         notify("Found end of TOC\n");
  721.  
  722.     return(1);
  723. }
  724.  
  725. void DoFTPMessage( ParsP p, FILE *outP )
  726. {
  727.     int i;
  728.     char    name[20];
  729.     
  730.     fputs("\n<HR>\n<CENTER>\n", outP);
  731.     fputs("<H4>Direct FTP to mirror site</H4>", outP);
  732.     fputs("</CENTER>\n", outP);
  733.     
  734.     fprintf(outP, "Make FTP connection with: ");
  735.     strcpy( name, "/info-mac/");
  736.  
  737.     for(i=0; i<p->nSites; i++)
  738.     {
  739.         fputs( "", outP );
  740.         fprintf( outP, p->sites+i*LINELENGTH, name);
  741.     }        
  742.  
  743.     fputs( ".\n<P><HR><P>\n", outP );
  744. }
  745.  
  746. int MakeTOC(ParsP p, VarsP v, char *line)
  747. {
  748.     int        msgItem;
  749.     char    subject[80];
  750.     char    topic[200];
  751.     int        found;
  752.     
  753.     msgItem = 0;
  754.     
  755.     if( outTMes==NULL )
  756.     {
  757.         notify( "Error in making TOC, Message output file is not open (pointer NULL)\n\n");
  758.         return(0);
  759.     }
  760.         
  761.     if( outTPrg != NULL )
  762.     {
  763.         fputs( "<HR><CENTER>", outTPrg );
  764.         fputs( "<HR><CENTER>", outTMes );
  765.         fputs( "<H3>Programs: Table of Contents</H3>", outTPrg );
  766.         fputs( "<H3>Messages: Table of Contents</H3>", outTMes );
  767.         fputs( "</CENTER><HR>", outTPrg );
  768.         fputs( "</CENTER><HR>", outTMes );
  769.         fputs( "<UL>", outTPrg );
  770.         fputs( "<UL>", outTMes );
  771.     }
  772.     else
  773.     {
  774.         fputs( "<HR><CENTER>", outTMes );
  775.         fputs( "<H3>Table of Contents</H3>", outTMes );
  776.         fputs( "</CENTER><HR>", outTMes );
  777.         fputs( "<UL>", outTMes );
  778.     }
  779.     
  780.     do{
  781.         msgItem++;
  782.         
  783.         strcpy( subject, "" );        /* default */
  784.         found=0;
  785.         
  786.         fgets( line, 256, inP );
  787.         while( (strncmp( line, p->EndOfMessage, strlen(p->EndOfMessage) )!=0) &&
  788.                  (strstr( line, p->BegOfDigest ) == NULL) && 
  789.                  (strstr( line, p->EndOfDigest ) == NULL) && 
  790.                  !feof(inP) )
  791.         {
  792.             filterEntities( line );
  793.             
  794.             if( (strncmp( line, "From: ", strlen( "From: " ) )==0)
  795.                 && !found )
  796.             {
  797.                 strcpy( subject, "(NO SUBJECT)" );        /* default */
  798.                 v->whichFile[msgItem]='m';
  799.             }
  800.                 
  801.             /* find subject */
  802.             if( (strncmp( line, "Subject: ", strlen( "Subject: " ) )==0)
  803.                 && !found )
  804.             {
  805.                 strncpy( subject, line+strlen( "Subject: " ), 78);
  806.                 subject[79]=0;
  807.                 found=1;
  808.             }
  809.             
  810.             if( p->Files )
  811.             if( strstr( line, p->BegOfFile ) != NULL )
  812.             {
  813.                 if(debug)
  814.                     notify("Found file link for item %d!\n", msgItem);
  815.                 
  816.                 v->whichFile[msgItem]='p';
  817.             }
  818.             
  819.             fgets( line, 256, inP );
  820.         }    /* while not end of message */
  821.         
  822.         /* end of message, write TOC entry */
  823.  
  824.         if( subject[0]!=0 )        /* check if there is a subject anyway */
  825.         {
  826.             /* set correct icon */
  827.             if( v->whichFile[msgItem] == 'p' )
  828.                 sprintf(topic, "<IMG SRC=%sprog_topic.gif ALT=Program> ", p->imagePath);
  829.             else
  830.                 sprintf(topic, "<IMG SRC=%smsg_topic.gif ALT=Message> ", p->imagePath);
  831.             
  832.             if( !p->Buttons )
  833.                 strcpy( topic, "<LI> " );
  834.                 
  835.             switch( p->Type )
  836.             {
  837.                 case 1:
  838.                     fprintf(outTMes, "%s<a name=toc%d> </a><a href=#item%d>%s</a>\n",
  839.                                             topic, msgItem, msgItem, subject);
  840.                             
  841.                     if( p->Buttons )
  842.                         fputs( "<BR>\n", outTMes );
  843.                 break;
  844.                 
  845.                 case 2:
  846.                     if( v->whichFile[msgItem]=='m' )
  847.                         fprintf(outTMes, "%s<a name=toc%d> </a><a href=%s#item%d>%s</a>\n",
  848.                                                 topic, msgItem, v->nameMess, msgItem, subject);
  849.                     else
  850.                         fprintf(outTMes, "%s<a name=toc%d> </a><a href=%s#item%d>%s</a>\n",
  851.                                                 topic, msgItem, v->nameProg, msgItem, subject);
  852.                             
  853.                     if( p->Buttons )
  854.                         fputs( "<BR>\n", outTMes );
  855.                 break;
  856.                 
  857.                 case 3:
  858.                     if( v->whichFile[msgItem]=='m' )
  859.                     {
  860.                         fprintf(outTMes, "%s<a name=toc%d> </a><a href=#item%d>%s</a>\n",
  861.                                                 topic, msgItem, msgItem, subject);
  862.                             
  863.                         if( p->Buttons )
  864.                             fputs( "<BR>\n", outTMes );
  865.                     }
  866.                     else
  867.                     {
  868.                         fprintf(outTPrg, "%s<a name=toc%d> </a><a href=#item%d>%s</a>\n",
  869.                                                 topic, msgItem, msgItem, subject);
  870.                             
  871.                         if( p->Buttons )
  872.                             fputs( "<BR>\n", outTPrg );
  873.                     }
  874.                     
  875.                     
  876.                 break;
  877.                 
  878.                 default:
  879.                     return(0);    /* error occured: illegal type specified */
  880.                 break;
  881.                 
  882.             }
  883.         }
  884.         
  885.     }while( (strncmp( line, p->BegOfDigest, strlen(p->BegOfDigest) ) != 0) 
  886.             && (strstr( line, p->EndOfDigest ) == NULL) 
  887.                 && !feof( inP ) );
  888.                 
  889.     if( p->Type==3 )    /* make link between program and Q&A files */
  890.     {
  891.         if( !p->Buttons )
  892.         {
  893.             fprintf( outTMes, "<LI> " );
  894.             fprintf( outTPrg, "<LI> " );
  895.         }
  896.         else
  897.         {
  898.             fprintf( outTMes, "<IMG SRC=%sprog_topic.gif ALT=Program> ", p->imagePath);
  899.             fprintf( outTPrg, "<IMG SRC=%smsg_topic.gif ALT=Message> ", p->imagePath);
  900.                             
  901.         }
  902.         fprintf( outTMes, "<a href=%s>[*] PROGRAMS TABLE OF CONTENTS</a><BR>\n", v->nameProg );
  903.         fprintf( outTPrg, "<a href=%s>MESSAGES TABLE OF CONTENTS</a><BR>\n", v->nameMess );
  904.  
  905.     }
  906.  
  907.     if( outTMes!=NULL ) fputs( "</UL>\n<P>\n", outTMes );
  908.     if( outTPrg!=NULL ) fputs( "</UL>\n<P>\n", outTPrg );
  909.     
  910.  
  911.     /* write intro */
  912.     
  913.     if(p->Files)
  914.     {
  915.     switch( p->Type )
  916.     {
  917.         case 1:
  918.             DoFTPMessage( p, outTMes );
  919.         break;
  920.  
  921.         case 2:
  922.             DoFTPMessage( p, outTMes );
  923.         break;
  924.  
  925.         case 3:
  926.             DoFTPMessage( p, outTPrg );
  927.         break;
  928.     }
  929.     }
  930.     else
  931.     {
  932.         if( outTMes!=NULL)
  933.             fputs( ".\n<P><HR><P>\n", outTMes );
  934.     }
  935.  
  936.     return(1);
  937. }
  938.  
  939. void FetchAddress( char *cptr, char *address )
  940. {
  941.     strcpy(address, cptr);
  942.     if( (cptr=strstr(address,"\n")) != NULL)
  943.         *cptr=0;
  944.  
  945.     if( (cptr=strstr(address,"<")) != NULL)
  946.     {
  947.         strcpy(address, cptr+1);
  948.         if( (cptr=strstr(address,">")) != NULL)
  949.             *cptr=0;
  950.     }
  951.  
  952.     if( (cptr=strstr(address," ")) != NULL)
  953.         *cptr=0;
  954. }
  955.  
  956. int DoMessages(ParsP p, VarsP v, char *line)
  957. {
  958.     int        msgItem;
  959.     char    topic[200];
  960.     char    next[200];
  961.     char    prev[200];
  962.     char    toc[200];
  963.     char    post[200];
  964.     char    index[200];
  965.     char    address[256];
  966.     FILE    *outP;
  967.     char    name[80], *bptr, *eptr;
  968.     int        i, pre;
  969.     char     filteredLine[256];
  970.     
  971.     if( p->Buttons )
  972.     {
  973.         sprintf( next, "<img src=%snext.gif alt=Next>", p->imagePath );
  974.         sprintf( prev, "<img src=%sprev.gif alt=Previous>", p->imagePath);
  975.         sprintf( toc, "<img src=%stoc.gif alt=TOC>", p->imagePath);
  976.         sprintf( post, "<img src=%spost.gif alt=MakeReply>", p->imagePath);
  977.         sprintf( index, "<img src=%sdigester.gif alt=Index>", p->imagePath);
  978.     }
  979.     else
  980.     {
  981.         strcpy( next, "Next" );
  982.         strcpy( prev, "Previous" );
  983.         strcpy( toc, "Table of Contents" );
  984.         strcpy( post, "Select Message for Posting" );
  985.         strcpy( index, "Back to INDEX" );
  986.     }
  987.     
  988.     msgItem = 0;
  989.  
  990.     /* do messages */
  991.     
  992.     do{
  993.         msgItem++;
  994.  
  995.         /* choose destination file */        
  996.  
  997.         switch( p->Type )
  998.         {
  999.             case 1:
  1000.                 outP = outTMes;
  1001.             break;
  1002.             
  1003.             case 2:
  1004.                 if( (v->whichFile[msgItem]=='m') || (outPrg==NULL) )
  1005.                     outP = outMes;
  1006.                 else
  1007.                     outP = outPrg;
  1008.             break;
  1009.             
  1010.             case 3:
  1011.                 if( (v->whichFile[msgItem]=='m')  || (outTPrg==NULL) )
  1012.                     outP = outTMes;
  1013.                 else
  1014.                     outP = outTPrg;
  1015.             break;
  1016.         }
  1017.         
  1018.         if( outP == NULL )
  1019.         {
  1020.             notify("Output file not open!!\n");
  1021.             return(0);
  1022.         }
  1023.  
  1024.         /* label the thing */
  1025.         fprintf( outP, "<a name=item%d> </a> ", msgItem);
  1026.         
  1027.         /* write navigation panel */
  1028.         if( v->whichFile[msgItem]!='0' )
  1029.         switch( p->Type )
  1030.         {
  1031.             case 1:
  1032.                 fprintf( outP, "<a href=#item%d>%s</a> ", msgItem+1, next);
  1033.                 if( msgItem>1) fprintf( outP, "<a href=#item%d>%s</a> ", msgItem-1, prev );
  1034.                 fprintf( outP, "<a href=#toc%d>%s</a> ", msgItem, toc);
  1035.                 if(p->Mail) fprintf( outP, "<a href=%spost-send?%d,%s>%s</a> ", 
  1036.                                             p->scriptPath, msgItem, v->nameAll, post);
  1037.             break;
  1038.  
  1039.             case 2:
  1040.                 if(v->whichFile[msgItem+1]!='0') 
  1041.                 {
  1042.                     if( v->whichFile[msgItem+1]!=v->whichFile[msgItem])
  1043.                     {
  1044.                         if( v->whichFile[msgItem+1]=='m' )
  1045.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1046.                                         v->nameMess, msgItem+1, next);
  1047.                         else
  1048.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1049.                                         v->nameProg, msgItem+1, next);
  1050.                     }
  1051.                     else
  1052.                         fprintf( outP, "<a href=#item%d>%s</a> ", msgItem+1, next);
  1053.                 }
  1054.                 
  1055.                 if( msgItem>1 && (v->whichFile[msgItem-1]!='0') )
  1056.                 {
  1057.                     if( v->whichFile[msgItem-1]!=v->whichFile[msgItem] )
  1058.                     {
  1059.                         if( v->whichFile[msgItem-1]=='m' )
  1060.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1061.                                                 v->nameMess, msgItem-1, prev);
  1062.                         else
  1063.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1064.                                                 v->nameProg, msgItem-1, prev);
  1065.                     }
  1066.                     else 
  1067.                         fprintf( outP, "<a href=#item%d>%s</a> ", msgItem-1, prev);
  1068.                 }
  1069.  
  1070.                 fprintf( outP, "<a href=%s#toc%d>%s</a> ", v->nameTOC, msgItem, toc);
  1071.  
  1072.                 if( p->Mail )
  1073.                     if( v->whichFile[msgItem]=='m' )
  1074.                         fprintf( outP, "<a href=%spost-send?%d,%s>%s</a> ",
  1075.                                          p->scriptPath, msgItem, v->nameMess, post);
  1076.                     else
  1077.                         fprintf( outP, "<a href=%spost-send?%d,%s>%s</a> ",
  1078.                                          p->scriptPath, msgItem, v->nameProg, post);
  1079.  
  1080.             break;
  1081.  
  1082.             case 3:
  1083.                 if(v->whichFile[msgItem+1]!='0') 
  1084.                 {
  1085.                     if(v->whichFile[msgItem+1]!=v->whichFile[msgItem] )
  1086.                     {
  1087.                         if( v->whichFile[msgItem+1]=='m' )
  1088.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1089.                                         v->nameMess, msgItem+1, next);
  1090.                         else
  1091.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1092.                                         v->nameProg, msgItem+1, next);
  1093.                     }
  1094.                     else
  1095.                         fprintf( outP, "<a href=#item%d>%s</a> ", msgItem+1, next);
  1096.                 }
  1097.                 
  1098.                 if( (msgItem>1) && (v->whichFile[msgItem-1]!='0') ) 
  1099.                 {
  1100.                     if( v->whichFile[msgItem-1]!=v->whichFile[msgItem] )
  1101.                     {
  1102.                         if( v->whichFile[msgItem-1]=='m' )
  1103.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1104.                                                 v->nameMess, msgItem-1, prev);
  1105.                         else
  1106.                             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1107.                                                 v->nameProg, msgItem-1, prev);
  1108.                     }
  1109.                     else 
  1110.                         fprintf( outP, "<a href=#item%d>%s</a> ", msgItem-1, prev);
  1111.                 }
  1112.  
  1113.                 fprintf( outP, "<a href=#toc%d>%s</a> ", msgItem, toc);
  1114.  
  1115.                 if( p->Mail )
  1116.                     if( v->whichFile[msgItem]=='m' )
  1117.                         fprintf( outP, "<a href=%spost-send?%d,%s>%s</a> ",
  1118.                                          p->scriptPath, msgItem, v->nameMess, post);
  1119.                     else
  1120.                         fprintf( outP, "<a href=%spost-send?%d,%s>%s</a> ",
  1121.                                          p->scriptPath, msgItem, v->nameProg, post);
  1122.  
  1123.             break;
  1124.         }
  1125.  
  1126.         if( v->whichFile[msgItem]!='0' )
  1127.         fprintf( outP, "<a href=index.html#issue%d-%d>%s</a>\n\n", 
  1128.                                 v->Issue+1, v->VolNum, index);
  1129.  
  1130.         /* end of navigation bar, now do the message */
  1131.  
  1132.         fputs( "\n<PRE>", outP);
  1133.         pre=1;
  1134.         
  1135.         fgets( line, 256, inP );
  1136.         while( (strncmp( line, p->EndOfMessage, strlen(p->EndOfMessage) )!=0) &&
  1137.                  (strstr( line, p->BegOfDigest ) == NULL) && 
  1138.                  (strstr( line, p->EndOfDigest ) == NULL) && 
  1139.                  !feof(inP) )
  1140.         {
  1141.  
  1142.             if( v->whichFile[msgItem]!='0' )
  1143.             {
  1144.                 strcpy( filteredLine, line );
  1145.                 filterEntities( filteredLine );
  1146.                 if( p->URLs ) linkLine( filteredLine );
  1147.     
  1148.                 /* find Subject, Date or From */
  1149.                 if( (strncmp( line, "Subject: ", strlen( "Subject: " ) )==0) ||
  1150.                      (strncmp( line, "Date: ", strlen( "Date: " ) )==0) ||
  1151.                      (strncmp( line, "From: ", strlen( "From: " ) )==0) ||
  1152.                      (strncmp( line, "To: ", strlen( "To: " ) )==0)
  1153.                   )
  1154.                 {
  1155.                     if( pre ) fprintf( outP, "</PRE>");
  1156.                     pre=0;
  1157.                     if( (strncmp( line, "From: ", strlen( "From: " ) )==0) && p->MURLs )
  1158.                     {
  1159.                         FetchAddress( line+strlen( "From: " ), address );
  1160.                         fprintf( outP, "From: <a href=mailto:%s>%s</a><BR>\n", 
  1161.                                         address, address );
  1162.  
  1163.                     }
  1164.                     else if( (strncmp( line, "To: ", strlen( "To: " ) )==0)  && p->MURLs )
  1165.                     {
  1166.                         FetchAddress( line+strlen( "To: " ), address );
  1167.                         fprintf( outP, "To: <a href=mailto:%s>%s</a><BR>\n", 
  1168.                                         address, address );
  1169.  
  1170.                     }
  1171.                     else
  1172.                     {
  1173.                         fprintf( outP, "%s\n<BR>\n", line);
  1174.                     }
  1175.                 }
  1176.                 else
  1177.                 {
  1178.                     if( !pre ) fprintf( outP, "<PRE>");
  1179.                     pre=1;
  1180.                     
  1181.                     fputs(filteredLine, outP);
  1182.     
  1183.                     /* check for begin of file */
  1184.                     
  1185.                     if( (strstr( line, p->BegOfFile ) != NULL) && p->Files )
  1186.                     {
  1187.                         if(debug)
  1188.                             notify("Found file link for item %d!\n", msgItem);
  1189.                     
  1190.                         bptr=strstr( line, p->RootPath );
  1191.                         eptr=strstr( line, p->EndOfFile );
  1192.     
  1193.                         if( bptr!=NULL && eptr!=NULL )
  1194.                         {
  1195.                             strncpy(name, bptr, eptr-bptr);
  1196.                             name[eptr-bptr]=0;
  1197.                     
  1198.                             fprintf( outP, "\n</pre>\nFetch from " );
  1199.     
  1200.     
  1201.                             for(i=0; i<p->nSites; i++)
  1202.                             {
  1203.                                 fprintf( outP, "\n");
  1204.                                 fprintf( outP, p->sites+i*LINELENGTH, name);
  1205.                             }        
  1206.     
  1207.                             fprintf( outP, ".\n<pre>\n" );
  1208.                         }
  1209.                         else
  1210.                         {
  1211.                             notify("Failed to make link, sorry :(\n");
  1212.                         }
  1213.                     }
  1214.                 }
  1215.             }
  1216.             fgets( line, 256, inP );
  1217.         }    /* while not end of message */
  1218.         
  1219.         fputs("</PRE>\n<HR>", outP );
  1220.         
  1221.     } while( (strncmp( line, p->BegOfDigest, strlen(p->BegOfDigest) ) != 0) 
  1222.                 && (strstr( line, p->EndOfDigest ) == NULL) 
  1223.                 && !feof( inP )
  1224.             );
  1225.  
  1226.     /* write last navigation panel */
  1227.     
  1228.     msgItem++;
  1229.     
  1230.     /* label the thing */
  1231.     fprintf( outP, "<a name=item%d> </a> ", msgItem);
  1232.  
  1233.     if( debug )
  1234.         notify( "Doing Message %d ...\n", msgItem );
  1235.     
  1236.     switch( p->Type )
  1237.     {
  1238.         case 1:
  1239.             if( msgItem>1) fprintf( outP, "<a href=#item%d>%s</a> ", msgItem-1, prev);
  1240.             fprintf( outP, "<a href=#toc1>%s</a> ", toc);
  1241.         break;
  1242.     
  1243.         case 2:
  1244.             fprintf( outP, "<a href=%s#item%d>%s</a> ", 
  1245.                                 v->nameMess, msgItem-1, prev);
  1246.     
  1247.             fprintf( outP, "<a href=%s#toc1>%s</a> ", v->nameMess, toc);
  1248.         break;
  1249.     
  1250.         case 3:
  1251.             fprintf( outP, "<a href=#item%d>%s</a> ", msgItem-1, prev);
  1252.             fprintf( outP, "<a href=#toc1>%s</a> ", toc);
  1253.         break;
  1254.     }
  1255.     
  1256.     fprintf( outP, "<a href=index.html#issue%d-%d>%s</a>\n\n", 
  1257.                             v->Issue+1, v->VolNum, index);
  1258.     
  1259.     notify( "Messages done.\n");
  1260.  
  1261.     if( (strncmp( line, p->BegOfDigest, strlen(p->BegOfDigest) ) == 0) )
  1262.     {
  1263.         notify("Found new begin of digest...\n");
  1264.         notify("Please, only use one digest per file.\n");
  1265.         notify("This version of DIGESTER does not work with multiple digests files.\n");
  1266.     }
  1267.  
  1268.  
  1269.     return(1);
  1270. }
  1271.  
  1272. void WriteTrailer( FILE *outP )
  1273. {
  1274.  
  1275.     fputs("<p><hr><p>\n", outP);
  1276.     fputs("HTML file created by digester 2.0<p>\n", outP);
  1277.     fprintf(outP,"Digester developed by: <a href=%s>André  C. van der Ham</a><p>\n", DRE);
  1278.     fputs("<address>\n", outP);
  1279.     fputs("Send bug reports, questions, etc. to: A.C.vanderHam@ET.TUDelft.NL<p>\n", outP);
  1280.     fputs("</address>\n", outP);    
  1281. }
  1282.  
  1283.  
  1284. /***************************************
  1285.  
  1286.     Parse one digest at a time
  1287.     returns 1 if there is still data left after the end-of-digest phrase
  1288.     
  1289. */
  1290.  
  1291. void ParseOne( ParsP p, char *digestName )
  1292. {
  1293.     char    line[512];
  1294.     char    name[256];
  1295.     int        i;
  1296.     struct Vars    v;
  1297.         
  1298.     for(i=0; i<512; i++)                        /* init destination of all messages to nowhere */
  1299.         v.whichFile[i]='0';
  1300.     
  1301.     /* initialize all file pointers */
  1302.     
  1303.     outTPrg =    NULL;
  1304.     outTMes =    NULL;
  1305.     outPrg  =    NULL;
  1306.     outMes  =    NULL;
  1307.  
  1308.     /*  B E G I N   O F   P A S S  1 */
  1309.  
  1310.     notify("PASS1: '%s'...\n", digestName);
  1311.  
  1312.     if( (inP = fopen( digestName, "r" )) == NULL )
  1313.     {
  1314.         notify("Cannot open '%s'\n", digestName);
  1315.         notify("Please make sure '%s' is in the same folder as digester.\n", digestName);
  1316.         return;
  1317.     }
  1318.     
  1319.     notify("Parsing...\n");
  1320.             
  1321.     if( findHeader( p, &v, line, 1 )==0 )    /* set-up header */
  1322.         return;
  1323.  
  1324.     if(debug)
  1325.         notify("Title found\n");
  1326.  
  1327.     if( SetUpFiles( p, &v )==0 )    /* set-up output files */
  1328.     {
  1329.         if( outTPrg!=NULL ) fclose( outTPrg );
  1330.         if( outTMes!=NULL ) fclose( outTMes );
  1331.         if( outPrg!=NULL )  fclose( outPrg );
  1332.         if( outMes!=NULL )  fclose( outMes );
  1333.         if( inP!=NULL )     fclose( inP );
  1334.         return;
  1335.     }
  1336.     
  1337.     if( debug )
  1338.     {
  1339.         notify( "outTPrg = %x\n", outTPrg );
  1340.         notify( "outTMes = %x\n", outTMes );
  1341.         notify( "outPrg = %x\n", outPrg );
  1342.         notify( "outMes = %x\n", outMes );
  1343.     }
  1344.     
  1345.  
  1346.     if( outTPrg!=NULL )
  1347.         SetUpTitle( p, &v, outTPrg, line );
  1348.  
  1349.     if( outTMes!=NULL )
  1350.         SetUpTitle( p, &v, outTMes, line );
  1351.  
  1352.     if( SkipTOC( p, &v, 0 ) == 0 )
  1353.     {
  1354.         if( outTPrg!=NULL ) fclose( outTPrg );
  1355.         if( outTMes!=NULL ) fclose( outTMes );
  1356.         if( outPrg!=NULL )  fclose( outPrg );
  1357.         if( outMes!=NULL )  fclose( outMes );
  1358.         if( inP!=NULL )     fclose( inP );
  1359.         return;
  1360.     }
  1361.     
  1362.     if( MakeTOC( p, &v, line )==0 )
  1363.     {
  1364.         if( outTPrg!=NULL ) fclose( outTPrg );
  1365.         if( outTMes!=NULL ) fclose( outTMes );
  1366.         if( outPrg!=NULL )  fclose( outPrg );
  1367.         if( outMes!=NULL )  fclose( outMes );
  1368.         return;
  1369.     }
  1370.  
  1371.     fclose( inP );
  1372.  
  1373.     /*  E N D   O F   P A S S  1 */
  1374.     
  1375.     notify("PASS2: '%s'...\n", digestName);
  1376.     
  1377.     if( (inP = fopen( digestName, "r" )) == NULL )
  1378.     {
  1379.         notify("Cannot open '%s',\n");
  1380.         return;
  1381.     }
  1382.     
  1383.     notify("Parsing...\n");
  1384.             
  1385.     if( findHeader( p, &v, line, 0 )==0 )    /* set-up header */
  1386.         return;
  1387.  
  1388.     if(debug)
  1389.         notify("Title found\n");
  1390.  
  1391.     if( SkipTOC( p, &v, 1 ) == 0 )
  1392.     {
  1393.         if( outTPrg!=NULL ) fclose( outTPrg );
  1394.         if( outTMes!=NULL ) fclose( outTMes );
  1395.         if( outPrg!=NULL )  fclose( outPrg );
  1396.         if( outMes!=NULL )  fclose( outMes );
  1397.         if( inP!=NULL )     fclose( inP );
  1398.         return;
  1399.     }
  1400.  
  1401.     if( DoMessages( p, &v, line )==0 )
  1402.     {
  1403.         if( outTPrg!=NULL ) fclose( outTPrg );
  1404.         if( outTMes!=NULL ) fclose( outTMes );
  1405.         if( outPrg!=NULL )  fclose( outPrg );
  1406.         if( outMes!=NULL )  fclose( outMes );
  1407.         if( inP!=NULL )     fclose( inP );
  1408.         return;
  1409.     }
  1410.     
  1411.     if(debug)
  1412.         notify("End of digest found...\n");
  1413.  
  1414.     if( outTPrg!=NULL ) 
  1415.     {
  1416.         WriteTrailer(outTPrg);
  1417.         fclose(outTPrg);
  1418.     }
  1419.     
  1420.     if( outTMes!=NULL ) 
  1421.     {
  1422.         WriteTrailer(outTMes);
  1423.         fclose(outTMes);
  1424.     }
  1425.     
  1426.     if( outPrg!=NULL ) 
  1427.     {
  1428.         WriteTrailer(outPrg);
  1429.         fclose(outPrg);
  1430.     }
  1431.     
  1432.     if( outMes!=NULL ) 
  1433.     {
  1434.         WriteTrailer(outMes);
  1435.         fclose(outMes);
  1436.     }
  1437.     
  1438.     notify("file closed.\n");
  1439.  
  1440. #ifdef __THINK__
  1441.     SetUpAllFinderInfo( p, &v );
  1442. #endif
  1443. }
  1444.  
  1445. int HandleArgs( ParsP p, int num_args, char *arg_strings[], char *digestName, char *parsName )
  1446. {
  1447.     int i;
  1448.     
  1449.     strcpy( parsName, PARMS);
  1450.     
  1451.     if( num_args<2 )
  1452.     {
  1453.         notify("You can also start digester from the command line.\n");
  1454.         notify("%s <filename> <b> <2> <3> <p> <f=digest.par>\n", arg_strings[0]);
  1455.         notify("b: use fancy buttons and icons.\n");
  1456.         notify("2: split up file in 2 parts\n");
  1457.         notify("3: split up file in 3 parts\n");
  1458.         notify("p: enable post reply.\n");
  1459.         notify("f=: alternative parameters file.\n");
  1460.     }
  1461.     else
  1462.     {
  1463.         p->Type=1;
  1464.         p->Buttons=0;
  1465.         p->Mail=0;
  1466.         
  1467.         strcpy( digestName, arg_strings[1] );
  1468.         
  1469.         for(i=2; i<num_args; i++)
  1470.         {
  1471.             switch( (arg_strings[i])[0] )
  1472.             {
  1473.                 case 'b':
  1474.                     p->Buttons=1;
  1475.                     notify("Buttons on!\n");
  1476.                 break;
  1477.                 
  1478.                 case '3':
  1479.                     p->Type=2;
  1480.                     notify("Split into 3 files!\n");
  1481.                 break;
  1482.                 
  1483.                 case '2':
  1484.                     p->Type=3;
  1485.                     notify("Split into 2 files!\n");
  1486.                 break;
  1487.                 
  1488.                 case 'p':
  1489.                     p->Mail=1;
  1490.                     notify("Enable post reply.\n");
  1491.                 break;
  1492.  
  1493.                 case 'f':
  1494.                     if( ((arg_strings[i])[1]=='=') && (strlen(arg_strings[i])>2) )
  1495.                     {
  1496.                         strcpy( parsName, (arg_strings[i]+2) );
  1497.                     }
  1498.                 break;
  1499.  
  1500.                 default:
  1501.                     notify("Usage: %s <filename> <b> <2> <3> <p>\n", arg_strings[0]);
  1502.                     notify("b: use fancy buttons and icons.\n");
  1503.                     notify("2: split up file in 2 parts\n");
  1504.                     notify("3: split up file in 3 parts\n");
  1505.                     notify("p: enable post reply.\n");
  1506.                     return(0);
  1507.             }
  1508.         }
  1509.     }
  1510.     
  1511.     return(1);
  1512. }
  1513.  
  1514. int GetSites( ParsP p )
  1515. {
  1516.     char    line[256];
  1517.     FILE    *sitesP;
  1518.     int        i;
  1519.     
  1520.     notify("\nGetting file of sites...\n");
  1521.     
  1522.     if((sitesP=fopen(p->sitesFile,"r"))==NULL)
  1523.     {
  1524.         notify("Can't open file sites file.\n");
  1525.         return(0);
  1526.     }
  1527.     
  1528.     p->nSites=atoi(fgets( line, 256, sitesP));
  1529.     
  1530.     if((p->sites=malloc(p->nSites*LINELENGTH))==NULL)
  1531.     {
  1532.         notify("Out of memory error...\n");
  1533.         return(0);
  1534.     }
  1535.     
  1536.     for( i=0; i<p->nSites; i++ )
  1537.         fgets( i*LINELENGTH+p->sites, LINELENGTH, sitesP);
  1538.     
  1539.     fclose(sitesP);
  1540.     
  1541.     return(1);
  1542. }
  1543.  
  1544. void convertCodes( char *line )
  1545. {
  1546.     char     tempLine[256];
  1547.     int    l, i;
  1548.     
  1549.     tempLine[0]=0;
  1550.     l = 0;
  1551.     for(i=0; i<strlen(line); i++ )
  1552.     {
  1553.         if( line[i]=='\\' )
  1554.         {
  1555.             tempLine[l++] = line[i]-'a'+1;
  1556.             tempLine[l] = 0;
  1557.         }        
  1558.         else
  1559.         {
  1560.             tempLine[l++] = line[i];
  1561.             tempLine[l] = 0;
  1562.         }
  1563.     }
  1564.     strcpy( line, tempLine );
  1565. }
  1566.  
  1567. void checkPar( char *line, char *token, char *par, int max )
  1568. {
  1569.     char *bptr, *eptr;
  1570.     
  1571.     if( strncmp( line, token, strlen(token) )!=0 ) return;
  1572.     
  1573.     bptr = line+strlen(token);
  1574.     
  1575.     while( (*bptr!='"') && (*bptr!=0) ) bptr++;        /* find first quote */
  1576.     
  1577.     if(*bptr==0)
  1578.     {
  1579.         notify("Failed to read parameter value of '%s'\n", token);
  1580.         return;
  1581.     }
  1582.     
  1583.     eptr=bptr+1;
  1584.  
  1585.     while( (*eptr!='"') && (*eptr!=0) ) eptr++;        /* find second quote */
  1586.     
  1587.     if(*eptr==0)
  1588.     {
  1589.         notify("Failed to read parameter string of '%s'\n", token);
  1590.         return;
  1591.     }
  1592.     
  1593.     if((eptr-bptr)>max)
  1594.     {
  1595.         notify("Parameter string of '%s' too long\n", token);
  1596.         return;
  1597.     }
  1598.  
  1599.     *eptr=0;    /* terminate the string */
  1600.     
  1601.     strcpy( par, bptr+1 );    /* copy the parameter string */
  1602.     
  1603.     if( debug )
  1604.         notify( "Parameter '%s': %s\n", token, par );
  1605.         
  1606.     convertCodes( par );
  1607. }
  1608.  
  1609. void checkParNum( char *line, char *token, int *par )
  1610. {
  1611.     if( strncmp( line, token, strlen(token) )!=0 ) return;
  1612.  
  1613.     if( sscanf( line+strlen(token), "%d", par )!=1 )
  1614.         notify("Failed to get parameter '%s'.\n", token);    
  1615.     else
  1616.     if( debug )
  1617.         notify("Parameter '%s': %d\n", token, *par );
  1618. }
  1619.  
  1620. void InitPars( ParsP p )
  1621. {
  1622.     /* initialize all struct variables */
  1623.     
  1624.     strcpy( p->scriptPath,     "/vdham-bin/" );
  1625.     strcpy( p->sitesFile,     "sites.asc" );
  1626.     strcpy( p->imagePath, "" );
  1627.     strcpy( p->destPath,     "" );
  1628.     strcpy( p->Ftype, "TEXT" );
  1629.     strcpy( p->Fcreator, "MOSS" );
  1630.  
  1631.     strcpy( p->DigestName,     "infomac.txt" );
  1632.     strcpy( p->nameAll,     "IM%d-%d.html" );
  1633.     strcpy( p->nameTOC,     "IMt%d-%d.html" );
  1634.     strcpy( p->nameProg,     "IMp%d-%d.html" );
  1635.     strcpy( p->nameMess,     "IMm%d-%d.html" );
  1636.     
  1637.     strcpy( p->BegOfDigest, "Info-Mac Digest      " );
  1638.     strcpy( p->Volume,         "Volume" );
  1639.     strcpy( p->Issue,         "Issue" );
  1640.     strcpy( p->Date,         "" );
  1641.     
  1642.     strcpy( p->EndOfDigest, "End of Info-Mac Digest" );
  1643.     strcpy( p->BeginOfTopics, "Today's Topics:" );
  1644.     strcpy( p->EndOfTopics, "----------------------------------------------------------------------" );
  1645.     strcpy( p->EndOfMessage, "------------------------------\n" );
  1646.     
  1647.     strcpy( p->RootPath,     "/info-mac/" );
  1648.     strcpy( p->BegOfFile,     "[Archived as " );
  1649.     strcpy( p->EndOfFile,     ";" );
  1650.     
  1651.     p->Type        = 1;
  1652.     p->Buttons    = 1;
  1653.     p->Mail     = 1;
  1654.     p->Files     = 1;
  1655.     p->URLs     = 1;
  1656.     p->MURLs     = 0;
  1657.  
  1658.     p->sites     = NULL;
  1659.     p->nSites     = 0;
  1660. }
  1661.  
  1662. int GetParameters( ParsP p, char *name, int *promptP )
  1663. {
  1664.     FILE     *inP;
  1665.     char    *cptr;
  1666.     char    line[256];
  1667.     
  1668.     notify("Using parameter file: '%s'.\n", name );
  1669.     
  1670.     if( (inP = fopen(name, "r")) == NULL )
  1671.     {
  1672.         notify("Cannot open '%s', using default values\n", name);
  1673.         return(1);
  1674.     }
  1675.     
  1676.     while( !feof(inP) )
  1677.     {
  1678.         fgets( line, 256, inP );
  1679.         
  1680.         if( (cptr=strstr(line, "#")) != NULL )    /* mask comments */
  1681.         {
  1682.             *cptr=0;
  1683.         }
  1684.         
  1685.         if(strlen(line)>2)
  1686.         {
  1687.             checkPar( line, "SCRIPT", p->scriptPath,80 );
  1688.             checkPar( line, "SITE", p->sitesFile,20 );
  1689.             checkPar( line, "PATH", p->destPath,80 );
  1690.             checkPar( line, "IMAGES", p->imagePath,80 );
  1691.             checkPar( line, "FTYPE", p->Ftype,6 );
  1692.             checkPar( line, "FCREAT", p->Fcreator, 6 );
  1693.     
  1694.             checkPar( line, "DIGNAM", p->DigestName,20);
  1695.             checkPar( line, "NAMA", p->nameAll,20);
  1696.             checkPar( line, "NAMT", p->nameTOC,20);
  1697.             checkPar( line, "NAMP", p->nameProg,20);
  1698.             checkPar( line, "NAMM", p->nameMess,20);
  1699.     
  1700.             checkPar( line, "BOD", p->BegOfDigest,80);
  1701.             checkPar( line, "VOL", p->Volume,80);
  1702.             checkPar( line, "ISS", p->Issue,80);
  1703.             checkPar( line, "DAT", p->Date,20);
  1704.     
  1705.             checkPar( line, "EOD", p->EndOfDigest,80);
  1706.             checkPar( line, "BOT", p->BeginOfTopics,80);
  1707.             checkPar( line, "EOT", p->EndOfTopics,80);
  1708.             checkPar( line, "EOM", p->EndOfMessage,80);
  1709.     
  1710.             checkPar( line, "RTD", p->RootPath,20);
  1711.             checkPar( line, "BOF", p->BegOfFile,40);
  1712.             checkPar( line, "EOF", p->EndOfFile,20);
  1713.     
  1714.             checkParNum( line, "TYP", &(p->Type));
  1715.             checkParNum( line, "BUT", &(p->Buttons));
  1716.             checkParNum( line, "MAI", &(p->Mail));
  1717.             checkParNum( line, "FIL", &(p->Files));
  1718.             checkParNum( line, "URL", &(p->URLs));
  1719.             checkParNum( line, "MURL", &(p->MURLs));
  1720.             checkParNum( line, "DEBUG", &debug);
  1721.             checkParNum( line, "PROMPT", promptP);
  1722.         }
  1723.     }
  1724.     return(0);
  1725. }
  1726.  
  1727. int main( int num_args, char *arg_strings[] )
  1728. {
  1729.     char    digestName[80], answer[80], parsName[80];
  1730.     char    line[256];
  1731.     struct Pars    p;
  1732.     int        nopars;
  1733.     int        prompt=1;
  1734.  
  1735.     InitPars( &p );
  1736.     
  1737.     if( HandleArgs( &p, num_args, arg_strings, digestName, parsName )==0 )
  1738.         return(1);
  1739.  
  1740.     nopars=GetParameters( &p, parsName, &prompt );
  1741.  
  1742.     if( p.Files )
  1743.     {
  1744.         if( GetSites( &p )==0 )
  1745.             return(1);
  1746.     }
  1747.  
  1748.  
  1749.     notify("\n\n*** D I G E S T E R ***\n\n");
  1750.     notify("by Andre' C. van der Ham\n\n");
  1751.     notify("This program parses info-mac digests you get by e-mail.\n");
  1752.     notify("Save the e-mail without headers and paragraph recognition (Eudora)\n");
  1753.     notify("Please, use one digest per file.\n");
  1754.     notify("Convert file to appropriate ascii format, for example: Mac->Unix\n\n");
  1755.     notify("The file can contain a number of digests.\n");
  1756.     notify("An HTML file is generated for each issue.\n");
  1757.     notify("Send bug reports, questions, etc... to:\n");
  1758.     notify("e-mail: A.C.vanderHam@ET.TUDelft.NL\n\n\n");
  1759.  
  1760.     if( num_args<2 )
  1761.     { 
  1762. #ifndef __THINK__
  1763.  
  1764.         notify("Input file (%s): ", p.DigestName);        
  1765.         gets( digestName );
  1766.         if(strlen(digestName)<2)
  1767.             strcpy( digestName, p.DigestName);
  1768. #else
  1769.         if( GetName( digestName )==0 ) return(1);
  1770. #endif
  1771.  
  1772.         if(prompt)
  1773.         {
  1774.             notify("Use fancy buttons and icons (y/N): ");
  1775.             gets( answer );
  1776.         
  1777.             if( answer[0]=='y' )
  1778.                 p.Buttons=1;
  1779.             else
  1780.                 p.Buttons=0;
  1781.         
  1782.             notify("Include message selection button for reply (y/N): ");
  1783.             gets( answer );
  1784.         
  1785.             if( answer[0]=='y' )
  1786.                 p.Mail=1;
  1787.             else
  1788.                 p.Mail=0;
  1789.         
  1790.             notify("Split file into 3 separate files for topics, programs and messages (y/N): ");
  1791.             gets( answer );
  1792.         
  1793.             if( answer[0]=='y' ) 
  1794.                 p.Type=2;
  1795.             else
  1796.                 p.Type=1;
  1797.     
  1798.             notify("Split file into 2 separate files for programs and messages (y/N): ");
  1799.             gets( answer );
  1800.         
  1801.             if( answer[0]=='y' ) 
  1802.                 p.Type=3;
  1803.         }
  1804.     }
  1805.  
  1806.     ParseOne( &p, digestName );
  1807.     
  1808.     notify("Thanks for using Digester.\nHave a nice day.\n");
  1809. #ifdef __THINK__
  1810.     notify("Please press Return to continue.\n");
  1811. #endif
  1812.  
  1813.     return(0);
  1814. }