home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / EXTRAS / UUCODE / UUPC / TEST / UPC12ES4.ZIP / RNEWS / history.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-07  |  9.5 KB  |  333 lines

  1. /*--------------------------------------------------------------------*/
  2. /*    h i s t o r y . c                                               */
  3. /*                                                                    */
  4. /*    News history file maintenance for UUPC/extended.                */
  5. /*                                                                    */
  6. /*--------------------------------------------------------------------*/
  7.  
  8. /* new version, rewritten for history-based news database
  9.  *
  10.  * Author:  Kai Uwe Rommel <rommel@ars.muc.de>
  11.  * Created: Sun Aug 15 1993
  12.  */
  13.  
  14. static char *rcsid = "$Id: history.c 1.3 1993/11/06 17:54:55 rhg Exp $";
  15. static char *rcsrev = "$Revision: 1.3 $";
  16.  
  17. /* $Log: history.c $
  18.  * Revision 1.3  1993/11/06  17:54:55  rhg
  19.  * Drive Drew nuts by submitting cosmetic changes mixed in with bug fixes
  20.  *
  21.  * Revision 1.2  1993/10/30  11:39:26  rommel
  22.  * fixed some function error returns missing a value
  23.  *
  24.  * Revision 1.1  1993/09/05  10:56:49  rommel
  25.  * Initial revision
  26.  * */
  27.  
  28. /*--------------------------------------------------------------------*/
  29. /*                        System include files                        */
  30. /*--------------------------------------------------------------------*/
  31.  
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <time.h>
  36. #include <fcntl.h>
  37. #include <io.h>
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40.  
  41. /*--------------------------------------------------------------------*/
  42. /*                    UUPC/extended include files                     */
  43. /*--------------------------------------------------------------------*/
  44.  
  45. #include "lib.h"
  46. #include "hlib.h"
  47. #include "timestmp.h"
  48. #include "active.h"
  49. #include "history.h"
  50. #include "importng.h"
  51. #include "hdbm.h"
  52.  
  53. /*--------------------------------------------------------------------*/
  54. /*    o p e n _ h i s t o r y                                         */
  55. /*                                                                    */
  56. /*    Open the history file.                                          */
  57. /*--------------------------------------------------------------------*/
  58.  
  59. void *open_history(char *name)
  60. {
  61.    char hfile_name[FILENAME_MAX];
  62.    DBM *hdbm_file = NULL;
  63.  
  64.    mkfilename(hfile_name, E_newsdir, name);
  65.    hdbm_file = dbm_open(hfile_name, O_RDWR | O_CREAT, 0666);
  66.  
  67.    if (hdbm_file == NULL) {
  68.       printmsg(0,"Unable to open history file");
  69.       return NULL;
  70.    }
  71.  
  72.    return hdbm_file;
  73. }
  74.  
  75. /*--------------------------------------------------------------------*/
  76. /*    c l o s e _ h i s t o r y                                       */
  77. /*                                                                    */
  78. /*    Close the history file.                                         */
  79. /*--------------------------------------------------------------------*/
  80.  
  81. void close_history(void *hdbm_file)
  82. {
  83.   if (hdbm_file != NULL)
  84.     dbm_close(hdbm_file);
  85. }
  86.  
  87. /*--------------------------------------------------------------------*/
  88. /*    g e t _ h i s t e n t r y                                       */
  89. /*                                                                    */
  90. /*    Check whether messageID is already in the history file.         */
  91. /*--------------------------------------------------------------------*/
  92.  
  93. char *get_histentry(void *hdbm_file, char *messageID)
  94. {
  95.   datum key, val;
  96.  
  97.   if (hdbm_file == NULL)
  98.     return NULL;
  99.  
  100.   key.dptr = messageID;
  101.   key.dsize = strlen(key.dptr) + 1;
  102.  
  103.   val = dbm_fetch(hdbm_file, key);
  104.  
  105.   return val.dptr;
  106. }
  107.  
  108. /*--------------------------------------------------------------------*/
  109. /*    g e t _ * _ h i s t e n t r y                                   */
  110. /*                                                                    */
  111. /*    Retrieve all entries from the history file in order.            */
  112. /*--------------------------------------------------------------------*/
  113.  
  114. static int get_entry(void *hdbm_file, char **messageID, char **histentry,
  115.              datum (*dbm_getkey)(DBM *hdbm_file))
  116. {
  117.   datum key, val;
  118.  
  119.   if (hdbm_file == NULL)
  120.     return FALSE;
  121.  
  122.   key = dbm_getkey(hdbm_file);
  123.  
  124.   if (key.dptr == NULL)
  125.     return FALSE;
  126.  
  127.   val = dbm_fetch(hdbm_file, key);
  128.  
  129.   *messageID = key.dptr;
  130.   *histentry = val.dptr;
  131.  
  132.   return TRUE;
  133. }
  134.  
  135. int get_first_histentry(void *hdbm_file, char **messageID, char **histentry)
  136. {
  137.   return get_entry(hdbm_file, messageID, histentry, dbm_firstkey);
  138. }
  139.  
  140. int get_next_histentry(void *hdbm_file, char **messageID, char **histentry)
  141. {
  142.   return get_entry(hdbm_file, messageID, histentry, dbm_nextkey);
  143. }
  144.  
  145.  
  146. /*--------------------------------------------------------------------*/
  147. /*    a d d _ h i s t e n t r y                                       */
  148. /*                                                                    */
  149. /*    Add messageID to the history file.                              */
  150. /*--------------------------------------------------------------------*/
  151.  
  152. int add_histentry(void *hdbm_file, char *messageID, char *hist_record)
  153. {
  154.   datum key, val;
  155.  
  156.   if (hdbm_file == NULL)
  157.     return FALSE;
  158.  
  159.   key.dptr = messageID;
  160.   key.dsize = strlen(key.dptr) + 1;
  161.   val.dptr = hist_record;
  162.   val.dsize = strlen(val.dptr) + 1;
  163.  
  164.   if (dbm_store(hdbm_file, key, val, DBM_REPLACE))
  165.     return FALSE;
  166.  
  167.   return TRUE;
  168. }
  169.  
  170. /*--------------------------------------------------------------------*/
  171. /*    d e l e t e _ h i s t e n t r y                                 */
  172. /*                                                                    */
  173. /*    Delete messageID from the history file.                         */
  174. /*--------------------------------------------------------------------*/
  175.  
  176. int delete_histentry(void *hdbm_file, char *messageID)
  177. {
  178.   datum key;
  179.  
  180.   if (hdbm_file == NULL)
  181.     return FALSE;
  182.  
  183.   key.dptr = messageID;
  184.   key.dsize = strlen(key.dptr) + 1;
  185.  
  186.   if (dbm_delete(hdbm_file, key))
  187.     return FALSE;
  188.  
  189.   return TRUE;
  190. }
  191.  
  192. /*--------------------------------------------------------------------*/
  193. /*    c o u n t _ p o s t i n g s                                     */
  194. /*                                                                    */
  195. /*    Count number of postings in a history entry                     */
  196. /*--------------------------------------------------------------------*/
  197.  
  198. int count_postings(char *histentry)
  199. {
  200.   char value[BUFSIZ], *ptr, *num;
  201.   int count;
  202.   long article;
  203.  
  204.   strcpy(value, histentry);
  205.   strtok(value, " ");    /* strip off date */
  206.   strtok(NULL, " ");    /* strip off size */
  207.   count = 0;
  208.   
  209.   while ((ptr = strtok(NULL, " ,\n")) != NULL) 
  210.   {
  211.     num = strchr(ptr, ':') + 1;
  212.  
  213.     if ((article = atol(num)) != 0)
  214.       count++;
  215.   }
  216.  
  217.   return count;
  218. }
  219.  
  220. /*--------------------------------------------------------------------*/
  221. /*    p u r g e _ a r t i c l e                                       */
  222. /*                                                                    */
  223. /*    Actually delete an article's file(s) and return remaining ones. */
  224. /*--------------------------------------------------------------------*/
  225.  
  226. static int matches(char *group, char **grouplist)
  227. {
  228.   int len1 = strlen(group), len2, subgroups;
  229.  
  230.   if (grouplist == NULL)
  231.     return TRUE;
  232.  
  233.   for (; *grouplist != NULL; grouplist++)
  234.   {
  235.     len2 = strlen(*grouplist);
  236.     subgroups = FALSE;
  237.  
  238.     if (*grouplist[len2 - 1] == '*')
  239.       len2--, subgroups = TRUE;
  240.  
  241.     if (strnicmp(group, *grouplist, min(len1, len2)) == 0)
  242.     {
  243.       if (len1 < len2)
  244.     continue;
  245.       else if (len1 == len2)
  246.     return TRUE;
  247.       else /* len1 > len2 */
  248.       {
  249.     if (group[len2] == '.' && subgroups)
  250.       return TRUE;
  251.       }
  252.  
  253.       return TRUE;
  254.     }
  255.   }
  256.  
  257.   return FALSE;
  258. }
  259.  
  260. char *purge_article(char *histentry, char **groups)
  261. {
  262.   static char remain[BUFSIZ];
  263.   char value[BUFSIZ];
  264.   char filename[FILENAME_MAX];
  265.   char *group, *num;
  266.   long article, remaining;
  267.  
  268.   strcpy(value, histentry);
  269.   num = strtok(value, " ");    /* strip off date */
  270.   strcpy(remain, num);
  271.   strcat(remain, " ");
  272.   num = strtok(NULL, " ");    /* strip off size */
  273.   strcat(remain, num);
  274.   strcat(remain, " ");
  275.   remaining = 0;
  276.   
  277.   while ((group = strtok(NULL, " ,\n")) != NULL) 
  278.   {
  279.     num = strchr(group, ':');
  280.     *num++ = 0;
  281.  
  282.     if (matches(group, groups))
  283.     {
  284.       if ((article = atol(num)) != 0)
  285.       {
  286.     ImportNewsGroup(filename, group, article);
  287.     unlink(filename);
  288.       }
  289.     }
  290.     else
  291.     {
  292.       strcat(remain, remaining ? "," : "");
  293.       strcat(remain, group);
  294.       strcat(remain, ":");
  295.       strcat(remain, num);
  296.       remaining++;
  297.     }
  298.   }
  299.  
  300.   return remaining ? remain : NULL;
  301. }
  302.  
  303. /*--------------------------------------------------------------------*/
  304. /*    c a n c e l _ a r t i c l e                                     */
  305. /*                                                                    */
  306. /*    Cancel an article in the database                               */
  307. /*--------------------------------------------------------------------*/
  308.  
  309. void cancel_article(void *hdbm_file, char *messageID)
  310. {
  311.   datum key, val;
  312.   char *groups;
  313.  
  314.   if (hdbm_file == NULL)
  315.     return;
  316.  
  317.   key.dptr = messageID;
  318.   key.dsize = strlen(key.dptr) + 1;
  319.  
  320.   val = dbm_fetch(hdbm_file, key);
  321.  
  322.   if (val.dptr == NULL) 
  323.     printmsg(4,"Cannot find article to cancel in history");
  324.   else
  325.   {
  326.     groups = strchr(val.dptr, ' ') + 1;  /* date */
  327.     groups = strchr(groups, ' ') + 1;    /* size */
  328.     printmsg(0,"cancelling %s", groups);
  329.     delete_histentry(hdbm_file, messageID);
  330.     purge_article(val.dptr, NULL);
  331.   }
  332. }
  333.