home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 479a.lha / barn_v2.01 / source / ng.c < prev    next >
Text File  |  1991-02-10  |  11KB  |  406 lines

  1. /*
  2.  *    File Name:        ng.c
  3.  *    Project:        BARN - Bah's Amiga ReadNews.
  4.  *    Purpose:        Defines functions related to newsgroup list.
  5.  *    Functions:        GetNewsRC, ReadNextMarker, PutNewsRC, DestroyNGList,
  6.  *                    NumberCovered, UpdateReadList, Mark.
  7.  *    Author:            Jeff Van Epps
  8.  *    Created:        03 Sep 89
  9.  *    Last Modified:    14 Nov 90
  10.  *    Comments:
  11.  *    History:
  12.  *        03 Sep 89/JVE    Created.
  13.  *        21 Oct 90/JVE    Moved UpdateReadList, Mark from arn.c to here where
  14.  *                        they belong.
  15.  *        14 Nov 90/JVE    Made sure a marker for article 0 gets created if
  16.  *                        no other articles have been read.
  17.  */
  18.  
  19. # include    <stdio.h>
  20. # include    <stdlib.h>
  21. # include    <string.h>
  22. # include    <fcntl.h>
  23. # include    "standard.h"
  24. # include    "article.h"
  25. # include    "ng.h"
  26.  
  27.  
  28. /****************************************************************************/
  29. /*    FUNCTION:    GetNewsRC                                                    */
  30. /*                                                                            */
  31. /*    PURPOSE:    Read/parse the .newsrc file.                                */
  32. /*                                                                            */
  33. /*    INPUT PARAMETERS:                                                        */
  34. /*        NAME        I/O        DESCRIPTION                                        */
  35. /*        ----        ---        -----------                                        */
  36. /*        filename     I        Name of file containing read newsgroups info.    */
  37. /*                                                                            */
  38. /*    RETURNS:                                                                */
  39. /*                                                                            */
  40. /*    COMMENTS:                                                                */
  41. /*        Parses lines from user's .newsrc file to see which articles in        */
  42. /*        which newsgroups have already been read.                            */
  43. /*                                                                            */
  44. /*    HISTORY:                                                                */
  45. /*        1.    03 Sep 89        Created.                                        */
  46. /*                                                                            */
  47. /****************************************************************************/
  48.  
  49. NG_INFO    *GetNewsRC( filename )
  50.  
  51. char        *filename;
  52.  
  53. {
  54. NG_INFO        *root = NULLP( NG_INFO );    /* points to start of ng list */
  55. NG_INFO        **ptr = &root;                /* where to alloc next ng from */
  56. MARKER        **marker;                    /* where to alloc next marker from */
  57. FILE        *fp;                        /* pointer into .newsrc file */
  58. char        buf[BUFSIZ];
  59. char        *name;                        /* newsgroup name */
  60.  
  61. if ( ( fp = fopen( filename, "r" ) ) == NULLP( FILE ) )
  62.     perror( filename );
  63. else
  64.     {
  65.     while ( fgets( buf, BUFSIZ, fp ) != NULLP( char ) )
  66.         {
  67.         if ( ( name = strtok( buf, " " ) ) == NULLP( char ) )
  68.             fprintf( stderr, "Bad line in %s: %s", filename, buf );
  69.         else
  70.             {
  71.             *ptr = (NG_INFO *) malloc( sizeof( NG_INFO ) );
  72.             (*ptr)->next = NULLP( NG_INFO );
  73.             (*ptr)->markers = NULLP( MARKER );
  74.             marker = &(*ptr)->markers;
  75.             while ( ReadNextMarker( &marker ) ) ;
  76.             (*ptr)->name = strdup( name );
  77.             ptr = &(*ptr)->next;
  78.             }
  79.         }
  80.     fclose( fp );
  81.     }
  82. return root;
  83. }
  84.  
  85.  
  86. /****************************************************************************/
  87. /*    FUNCTION:    ReadNextMarker                                                */
  88. /*                                                                            */
  89. /*    PURPOSE:    Parse next marker from line.                                */
  90. /*                                                                            */
  91. /*    INPUT PARAMETERS:                                                        */
  92. /*        NAME        I/O        DESCRIPTION                                        */
  93. /*        ----        ---        -----------                                        */
  94. /*        marker        I/O        Pointer to pointer to next marker.                */
  95. /*                                                                            */
  96. /*    RETURNS:                                                                */
  97. /*        TRUE        Marker parsed.                                            */
  98. /*        FALSE        No marker parsed (end of input line).                    */
  99. /*                                                                            */
  100. /*    COMMENTS:                                                                */
  101. /*        markers = [ marker | marker + ',' + markers ]                        */
  102. /*        marker = [ XXX | XXX + '-' + YYY ]                                    */
  103. /*                                                                            */
  104. /*        There may be a list of markers with each marker separated by a        */
  105. /*        comma.  Each marker may be either a single number or two numbers    */
  106. /*        separated by a dash indicating an inclusive range.  White space        */
  107. /*        is not allowed anywhere.                                            */
  108. /*                                                                            */
  109. /*        We assume that the string we are parsing has already been subject    */
  110. /*        to a strtok() call so that we can just strtok(NULL,x) to continue    */
  111. /*        parsing the same string.                                            */
  112. /*                                                                            */
  113. /*    HISTORY:                                                                */
  114. /*        1.    03 Sep 89        Created.                                        */
  115. /*                                                                            */
  116. /****************************************************************************/
  117.  
  118. ReadNextMarker( marker )
  119.  
  120. MARKER        ***marker;
  121.  
  122. {
  123. int            rc = FALSE;
  124. char        *p, *q;
  125.  
  126. if ( ( p = strtok( NULLP( char ), "," ) ) != NULLP( char ) )
  127.     {
  128.     **marker = (MARKER *) malloc( sizeof( MARKER ) );
  129.     (**marker)->next = NULLP( MARKER );
  130.     (**marker)->from = atol( p );
  131.     if ( ( q = strchr( p, '-' ) ) != NULLP( char ) )
  132.         (**marker)->to = atol( ++q );
  133.     else
  134.         (**marker)->to = 0L;
  135.     *marker = &(**marker)->next;
  136.     rc = TRUE;
  137.     }
  138. return rc;
  139. }
  140.  
  141.  
  142. /****************************************************************************/
  143. /*    FUNCTION:    PutNewsRC                                                    */
  144. /*                                                                            */
  145. /*    PURPOSE:    Write read article markers to .newsrc file.                    */
  146. /*                                                                            */
  147. /*    INPUT PARAMETERS:                                                        */
  148. /*        NAME        I/O        DESCRIPTION                                        */
  149. /*        ----        ---        -----------                                        */
  150. /*        filename     I        Name of file to which to write .newsrc info.    */
  151. /*        root         I        List of already read articles.                    */
  152. /*                                                                            */
  153. /*    RETURNS: none                                                            */
  154. /*                                                                            */
  155. /*    COMMENTS:                                                                */
  156. /*        Tries to save old .newsrc file as .newsrc.BAK before writing new    */
  157. /*        one.                                                                */
  158. /*                                                                            */
  159. /*    HISTORY:                                                                */
  160. /*        1.    03 Sep 89        Created.                                        */
  161. /*                                                                            */
  162. /****************************************************************************/
  163.  
  164. void PutNewsRC( filename, root )
  165.  
  166. char        *filename;
  167. NG_INFO        *root;
  168.  
  169. {
  170. char        backup[BUFSIZ], temp[BUFSIZ];
  171. FILE        *fp;
  172. MARKER        *ptr;
  173.  
  174. sprintf( backup, "%s.BAK", filename );
  175. (void) remove( backup );
  176. if ( rename( filename, backup ) )
  177.     {
  178.     sprintf( temp, "rename(%s,%s)", filename, backup );
  179.     perror( temp );
  180.     }
  181. else
  182.     {
  183.     if ( ( fp = fopen( filename, "a" ) ) == NULLP( FILE ) )
  184.         perror( filename );
  185.     else 
  186.         {
  187.         while ( root != NULLP( NG_INFO ) )
  188.             {
  189.             fprintf( fp, "%s ", root->name );
  190.             for ( ptr = root->markers; ptr != NULLP( MARKER ); )
  191.                 {
  192.                 fprintf( fp, "%ld", ptr->from );
  193.                 if ( ptr->to > 0L )
  194.                     fprintf( fp, "-%ld", ptr->to );
  195.                 if ( ptr = ptr->next )
  196.                     fprintf( fp, "," );
  197.                 }
  198.             fprintf( fp, "\n" );
  199.             root = root->next;
  200.             }
  201.         fclose( fp );
  202.         }
  203.     }
  204. }
  205.  
  206.  
  207. /****************************************************************************/
  208. /*    FUNCTION:    DestroyNGList                                                */
  209. /*                                                                            */
  210. /*    PURPOSE:    Free memory taken by newsgroup list.                        */
  211. /*                                                                            */
  212. /*    INPUT PARAMETERS:                                                        */
  213. /*        NAME        I/O        DESCRIPTION                                        */
  214. /*        ----        ---        -----------                                        */
  215. /*        root         I        Pointer to list of newsgroups.                    */
  216. /*                                                                            */
  217. /*    RETURNS: none                                                            */
  218. /*                                                                            */
  219. /*    COMMENTS:                                                                */
  220. /*                                                                            */
  221. /*    HISTORY:                                                                */
  222. /*        1.    03 Sep 89        Created.                                        */
  223. /*                                                                            */
  224. /****************************************************************************/
  225.  
  226. void DestroyNGList( root )
  227.  
  228. NG_INFO        *root;
  229.  
  230. {
  231. MARKER        *ptr, *tmp;
  232. NG_INFO        *next;
  233.  
  234. while ( root != NULLP( NG_INFO ) )
  235.     {
  236.     for ( ptr = root->markers; ptr != NULLP( MARKER ); ptr = tmp )
  237.         {
  238.         tmp = ptr->next;
  239.         free( ptr );
  240.         }
  241.     free( root->name );
  242.     next = root->next;
  243.     free( root );
  244.     root = next;
  245.     }
  246. }
  247.  
  248.  
  249. /****************************************************************************/
  250. /*    FUNCTION:    NumberCovered                                                */
  251. /*                                                                            */
  252. /*    PURPOSE:    Check whether number is covered by markers.                    */
  253. /*                                                                            */
  254. /*    INPUT PARAMETERS:                                                        */
  255. /*        NAME        I/O        DESCRIPTION                                        */
  256. /*        ----        ---        -----------                                        */
  257. /*        markers         I        Marker list.                                    */
  258. /*        number         I        Number to be checked.                            */
  259. /*                                                                            */
  260. /*    RETURNS:                                                                */
  261. /*        TRUE        If number is in list.                                    */
  262. /*        FALSE        If number is not in list.                                */
  263. /*                                                                            */
  264. /*    COMMENTS:                                                                */
  265. /*        Markers are assumed to be sorted low->high and non-overlapping.        */
  266. /*                                                                            */
  267. /*    HISTORY:                                                                */
  268. /*        1.    04 Sep 89        Created.                                        */
  269. /*                                                                            */
  270. /****************************************************************************/
  271.  
  272. NumberCovered( markers, number )
  273.  
  274. MARKER        *markers;
  275. long        number;
  276.  
  277. {
  278. int            rc = FALSE;
  279.  
  280. while ( !rc && markers != NULLP( MARKER ) )
  281.     {
  282.     if ( markers->from > number )
  283.         break;
  284.     else if ( markers->from == number )
  285.         rc = TRUE;
  286.     else if ( markers->to >= number )
  287.         rc = TRUE;
  288.     markers = markers->next;
  289.     }
  290. return rc;
  291. }
  292.  
  293.  
  294. /****************************************************************************/
  295. /*    FUNCTION:    UpdateReadList                                                */
  296. /*                                                                            */
  297. /*    PURPOSE:    Update the list of articles read due to newly read ones.    */
  298. /*                                                                            */
  299. /*    INPUT PARAMETERS:                                                        */
  300. /*        NAME        I/O        DESCRIPTION                                        */
  301. /*        ----        ---        -----------                                        */
  302. /*        ng            I/O        List of read articles.                            */
  303. /*        new             I        List containing some newly read articles.        */
  304. /*                                                                            */
  305. /*    RETURNS: none                                                            */
  306. /*                                                                            */
  307. /*    COMMENTS:                                                                */
  308. /*        Look for articles which are STILL unread, and make a list which        */
  309. /*        marks everything except those. If nothing is left unread, the list    */
  310. /*        should mark to the greater of the previously highest read article    */
  311. /*        and the highest newly read article.                                    */
  312. /*                                                                            */
  313. /*    HISTORY:                                                                */
  314. /*        1.    04 Sep 89        Created.                                        */
  315. /*        2.    16 Dec 89        Fixed bug in last mark if last article unread.    */
  316. /*        3.    14 Nov 90        Make sure *something* gets marked, i.e. 0-0 if    */
  317. /*                            nothing else.                                    */
  318. /*                                                                            */
  319. /****************************************************************************/
  320.  
  321. void    UpdateReadList( ng, new )
  322.  
  323. NG_INFO                *ng;
  324. ARTICLE_INFO        *new;
  325.  
  326. {
  327. long                beginning, ending;
  328. MARKER                **where;        /* where to allocate next marker */
  329. MARKER                *first = NULL;    /* ptr to beginning of new marker list */
  330. MARKER                *ptr, *tmp;
  331.  
  332. for ( ptr = ng->markers; ptr != NULLP( MARKER ); ptr = tmp )
  333.     {
  334.     if ( ptr->to != 0L )
  335.         ending = ptr->to;
  336.     else
  337.         ending = ptr->from;
  338.     tmp = ptr->next;
  339.     free( ptr );
  340.     }
  341. beginning = 1L;
  342. where = &first;
  343. for ( ; new != NULLP( ARTICLE_INFO ); new = new->next )
  344.     {
  345.     if ( ! new->beenread )
  346.         {
  347.         if ( new->number != beginning && beginning <= ending )
  348.             {
  349.             *where = Mark( beginning, new->number - 1L );
  350.             where = & (*where)->next;
  351.             }
  352.         beginning = new->number + 1L;
  353.         }
  354.     else if ( new->number > ending )
  355.         ending = new->number;
  356.     }
  357. if ( beginning <= ending )
  358.     *where = Mark( beginning, ending );
  359. /*
  360.  *    If no markers have been created, create one for article # 0.
  361.  */
  362. if ( first == NULL )
  363.     *where = Mark( 0L, 0L );
  364. ng->markers = first;
  365. }
  366.  
  367.  
  368. /****************************************************************************/
  369. /*    FUNCTION:    Mark                                                        */
  370. /*                                                                            */
  371. /*    PURPOSE:    Create a marker.                                            */
  372. /*                                                                            */
  373. /*    INPUT PARAMETERS:                                                        */
  374. /*        NAME        I/O        DESCRIPTION                                        */
  375. /*        ----        ---        -----------                                        */
  376. /*        begin         I        From part of marker.                            */
  377. /*        end             I        To part of marker.                                */
  378. /*                                                                            */
  379. /*    RETURNS:                                                                */
  380. /*        (MARKER *)            Pointer to new marker.                            */
  381. /*                                                                            */
  382. /*    COMMENTS:                                                                */
  383. /*                                                                            */
  384. /*    HISTORY:                                                                */
  385. /*        1.    05 Sep 89        Created.                                        */
  386. /*                                                                            */
  387. /****************************************************************************/
  388.  
  389. MARKER    *Mark( begin, end )
  390.  
  391. long            begin, end;
  392.  
  393. {
  394. MARKER            *ptr;
  395.  
  396. ptr = (MARKER *) malloc( sizeof( MARKER ) );
  397. ptr->from = begin;
  398. if ( begin == end )
  399.     ptr->to = 0L;
  400. else
  401.     ptr->to = end;
  402. ptr->next = NULLP( MARKER );
  403. return ptr;
  404. }
  405.  
  406.