home *** CD-ROM | disk | FTP | other *** search
/ Beijing Paradise BBS Backup / PARADISE.ISO / software / BBSDOORW / SNWS191S.ZIP / ACTIVE.C next >
C/C++ Source or Header  |  1993-08-23  |  24KB  |  841 lines

  1. /*
  2.     SNEWS 1.91
  3.  
  4.     active - routines to manipulate the active, .nrc and .rc files
  5.  
  6.  
  7.     Copyright (C) 1991  John McCombs, Christchurch, NEW ZEALAND
  8.                         john@ahuriri.gen.nz
  9.                         PO Box 2708, Christchurch, NEW ZEALAND
  10.  
  11.     Modifications copyright (C) 1993  Daniel Fandrich
  12.                         <dan@fch.wimsey.bc.ca> or CompuServe 72365,306
  13.  
  14.     This program is free software; you can redistribute it and/or modify
  15.     it under the terms of the GNU General Public License, version 1, as
  16.     published by the Free Software Foundation.
  17.  
  18.     This program is distributed in the hope that it will be useful,
  19.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  20.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21.     GNU General Public License for more details.
  22.  
  23.     See the file COPYING, which contains a copy of the GNU General
  24.     Public License.
  25.  
  26.  
  27.     Source is formatted with a tab size of 4.
  28.  
  29. */
  30.  
  31. #define ACTIVE_C
  32.  
  33. #include "defs.h"
  34. #include <alloc.h>
  35. #include <ctype.h>
  36.  
  37. extern INFO my_stuff;
  38.  
  39. int headf = BLACK;
  40. int headb = LIGHTGRAY;
  41.  
  42. int textf = LIGHTGRAY;
  43. int textb = BLACK;
  44.  
  45. int helpf = LIGHTGRAY;
  46. int helpb = BLACK;
  47.  
  48. int msgf = BLACK;
  49. int msgb = LIGHTGRAY;
  50.  
  51. volatile int break_hit = 0;        /* incremented when control-break is hit */
  52.  
  53. /*
  54.  *  These private variables are used to do all the i/o on the active
  55.  *  file.
  56.  */
  57. static FILE        *active_file;
  58.  
  59. static ACTIVE      *local_head;
  60.  
  61.  
  62. /*--------------------------- load the active file --------------------------*/
  63. ACTIVE *load_active_file(void)
  64. {
  65.     /*
  66.      *  This routine opens the active file.  It reads the data, allocating
  67.      *  ACTIVE elements in a linked list.  Returns a pointer to the head of
  68.      *  the linked list.
  69.      */
  70.     char   fn[80], buf[81];
  71.     char   *p;
  72.     ACTIVE *this = NULL, *head = NULL;
  73.     long   posn = 0;
  74.     int    ct = 0;
  75.     int    ct_gp = 0;
  76.  
  77.     /* open the file */
  78.     strcpy(fn, my_stuff.news_dir);
  79.     strcat(fn, "active");
  80.     if ((active_file = fopen(fn, "r+b")) == NULL) {
  81.         fprintf(stderr, "cannot open %s\n", fn);
  82.         exit(1);
  83.     }
  84.  
  85.     /* read and store */
  86.     while (fgets(buf, 80, active_file) != NULL) {
  87.  
  88.         /* exit on ^Z on column 1 */
  89.         if (buf[0] == '\x1A')
  90.             break;
  91.  
  92.         ct++;
  93.  
  94.         if (strlen(buf) > 0) {
  95.  
  96.             if (head == NULL) {
  97.                 head = this = xmalloc(sizeof (ACTIVE));
  98.                 head->last = NULL;
  99.                 head->index = ct_gp;
  100.             } else {
  101.                 ct_gp++;
  102.                 this->next = xmalloc(sizeof (ACTIVE));
  103.                 this->next->last = this;
  104.                 this = this->next;
  105.                 this->index = ct_gp;
  106.             }
  107.  
  108.             if ((this) == NULL) {
  109.                 fprintf(stderr, "cannot allocate memory for active list\n");
  110.                 exit(1);
  111.             }
  112.  
  113.  
  114.             if ((p = strtok(buf, " ")) == NULL) {
  115.                 fprintf(stderr, "active file corrupt at line %d #1\n", ct);
  116.                 exit(1);
  117.             }
  118.             strcpy(this->group, p);
  119.             this->local = isupper(this->group[0]);        /* is group local? */
  120.             this->group[0] = tolower(this->group[0]);
  121.  
  122.             if ((p = strtok(NULL, " ")) == NULL) {
  123.                 fprintf(stderr, "active file corrupt at line %d #2\n", ct);
  124.                 exit(1);
  125.             }
  126.             strcpy(this->gp_file, p);
  127.  
  128.             if ((p = strtok(NULL, " ")) == NULL) {
  129.                 fprintf(stderr, "active file corrupt at line %d #3\n", ct);
  130.                 exit(1);
  131.             }
  132.             this->lo_num = atol(p);
  133.  
  134.             if ((p = strtok(NULL, " ")) == NULL) {
  135.                 fprintf(stderr, "active file corrupt at line %d #4\n", ct);
  136.                 exit(1);
  137.             }
  138.             this->hi_num = atol(p);
  139.  
  140.             if ((p = strtok(NULL, " ")) == NULL) {
  141.                 fprintf(stderr, "active file corrupt at line %d #5\n", ct);
  142.                 exit(1);
  143.             }
  144.             this->post = tolower(*p);
  145.  
  146.             this->num_pos = posn;
  147.             this->read_list = NULL;
  148.         }
  149.  
  150.         posn = ftell(active_file);
  151.     }
  152.  
  153.     if (this)
  154.         this->next = NULL;
  155.  
  156.     local_head = head;
  157.  
  158.     return(head);
  159. }
  160.  
  161.  
  162.  
  163.  
  164. /*------------------------- close the active file ---------------------------*/
  165. void close_active_file(void)
  166. {
  167.     /*
  168.      *  Close the active file and deallocate the linked list
  169.      */
  170.  
  171.     ACTIVE *this;
  172.  
  173.     this = local_head;
  174.  
  175.     while (this != NULL) {
  176.         local_head = this;
  177.         this = this->next;
  178.         free(local_head);
  179.     }
  180.  
  181.     fclose(active_file);
  182.  
  183. }
  184.  
  185.  
  186. /*------------------------- close the active file ---------------------------*/
  187. void close_active(void)
  188. {
  189.     /*
  190.      *  Close the active file
  191.      */
  192.  
  193.  
  194.     fclose(active_file);
  195.  
  196. }
  197.  
  198.  
  199.  
  200. /*------------------------- check group in post list -------------------------*/
  201. int check_valid_post_group(char *ng)
  202. {
  203.     /*
  204.      *  Check a string as a valid newsgroup name.  Returns TRUE if found and
  205.      *  posting is allowed.
  206.      *
  207.      *  Note: this should be changed to return 1 if posting is allowed,
  208.      *  0 if it is not, and -1 if the group is moderated.
  209.      */
  210.  
  211.     ACTIVE *this = local_head;
  212.  
  213.     while (this != NULL) {
  214.         if (strcmp(ng, this->group) == 0)
  215.         switch (this->post) {
  216.             case 'y': return TRUE;
  217. /*            case 'm': return -1; */
  218.             case 'n':
  219.             default: return FALSE;
  220.         }
  221.         this = this->next;
  222.     }
  223.  
  224.     return (FALSE);
  225. }
  226.  
  227.  
  228. /*-------------------- see if newsgroup is local only -----------------------*/
  229. int is_local_group(char *ng)
  230. {
  231.     ACTIVE *this = local_head;
  232.  
  233.     while (this != NULL) {
  234.         if (strcmp(ng, this->group) == 0)
  235.             return(this->local);
  236.         this = this->next;
  237.     }
  238.  
  239.     return (TRUE);        /* return TRUE if group name is not found */
  240. }
  241.  
  242.  
  243.  
  244. /*-------------------- find a newsgroup in active list ----------------------*/
  245. ACTIVE *find_news_group(char *group)
  246. {
  247.     /*
  248.      *  This routine searches the active structure for the specified
  249.      *  newsgroup, and returns a pointer to the entry, or to group
  250.      *  junk if not found.  The search for junk is made via a recursive
  251.      *  call.  Fatal if junk not found
  252.      */
  253.  
  254.     ACTIVE *this;
  255.  
  256.     this = local_head;
  257.  
  258.     while ((this != NULL) && (stricmp(group, this->group) != 0)) {
  259.         this = this->next;
  260.     }
  261.     if (this == NULL) {
  262.         if (stricmp(group, "junk") != 0) {
  263.             this = find_news_group("junk");
  264.         } else {
  265.             fprintf(stderr, "active file must have newsgroup junk\n");
  266.             exit(1);
  267.         }
  268.     }
  269.     return(this);
  270. }
  271.  
  272.  
  273.  
  274.  
  275. /*-------------------------- update active file ---------------------------*/
  276. void update_active_entry(ACTIVE *a)
  277. {
  278.     /*
  279.      *  This routine takes a pointer to an active entry and updates
  280.      *  its data on disk
  281.      */
  282.  
  283.     char buf[(ACTIVE_NUM_LEN*2) + 2];
  284.     int  n;
  285.     long where;
  286.  
  287.     sprintf(buf, "%08ld %08ld", a->lo_num, a->hi_num);
  288.  
  289.     n = (ACTIVE_NUM_LEN*2) + 1;
  290.     where = a->num_pos + strlen(a->group) + 1 + strlen(a->gp_file) + 1;
  291.     fseek(active_file, where, SEEK_SET);
  292.     if (fwrite(buf, 1, n, active_file) != n) {
  293.         fprintf(stderr, "active file update failed for %s\n", a->group);
  294.         exit(1);
  295.     }
  296.  
  297.     fflush(active_file);
  298. }
  299.  
  300.  
  301.  
  302.  
  303.  
  304. /*------------------- make newsgroup name and directory --------------------*/
  305. char *make_news_group_name(char *ng)
  306. {
  307.     /*
  308.      *  This routine takes the newsgroup name, replaces the '.' with
  309.      *  '\' and creates the directory if none exists.  The returned name
  310.      *  has a trailing '\'
  311.      */
  312.  
  313.     static char fn[512];
  314.     ACTIVE *tmp;
  315.  
  316.  
  317.     tmp = find_news_group(ng);
  318.  
  319.     sprintf(fn, "%snewsbase\\%s", my_stuff.news_dir, tmp->gp_file);
  320.  
  321.     return(&fn[0]);
  322. }
  323.  
  324.  
  325.  
  326.  
  327.  
  328. /*-------------------------- save the seen list -------------------------*/
  329. void load_read_list(void)
  330. {
  331.     /*
  332.      *  Load the user's list of seen articles
  333.      */
  334.  
  335.     FILE   *tmp_file;
  336.     ACTIVE *act;
  337.     int    i, continue_flag;
  338.     int    articles;
  339.     char   *a, buf[256], *p, real_name[80];
  340.  
  341.     /* allocate the arrays and set to unread, ie FALSE */
  342.     act = local_head;
  343.     while (act != NULL) {
  344.  
  345.         articles = (int)(act->hi_num - act->lo_num);
  346.         if (articles > 0) {
  347.             a = act->read_list = xmalloc(articles * sizeof(char));
  348.             for (i = 0; i < articles; i++) {
  349.                 *(a+i) = FALSE;
  350.             }
  351.         } else {
  352.             act->read_list = NULL;
  353.         }
  354.         act = act->next;
  355.     }
  356.  
  357.     /* read and process the file - if not present, just carry on */
  358. /*    strcpy(buf, my_stuff.news_dir);
  359.     strcat(buf, my_stuff.user);
  360.     strcat(buf, ".nrc");
  361. */
  362.     strcat(strcpy(buf, my_stuff.home), "snews.nrc");
  363.     if ((tmp_file = fopen(buf, "rt")) != NULL) {
  364.  
  365.         continue_flag = FALSE;
  366.         while (fgets(buf, 255, tmp_file) != NULL) {
  367.  
  368.             p = strtok(buf, " \n\r");
  369.  
  370.             if (!continue_flag) {
  371.  
  372.                 strcpy(real_name, p);
  373.                 act = find_news_group(p);
  374.                 articles = (int)(act->hi_num - act->lo_num);
  375.  
  376.                 /* if no articles or unknown group eat the rest */
  377.                 p = strtok(NULL, " \n\r");
  378.  
  379.             }
  380.  
  381.             /* scan the rest of the line getting numbers and setting flags */
  382.             continue_flag = FALSE;
  383.             while (p != NULL) {
  384.  
  385.                 /* check for continuation backslash */
  386.                 if (*p != '\\') {
  387.                     i = (int) (atol(p) - (act->lo_num + 1));
  388.                     if ((i >= 0) && (i < articles) &&
  389.                     ((stricmp(act->group, "junk") != 0) ||
  390.                     (stricmp(real_name, "junk") == 0))) {
  391.                         *((act->read_list)+i) = TRUE;
  392.                     }
  393.                 } else {
  394.                     continue_flag = TRUE;
  395.                     break;
  396.                 }
  397.                 p = strtok(NULL, " \n\r");
  398.             }
  399.         }
  400.  
  401.         fclose(tmp_file);
  402.     }
  403. }
  404.  
  405.  
  406.  
  407.  
  408.  
  409. /*-------------------------- load the seen list -------------------------*/
  410. void save_read_list(void)
  411. {
  412.     /*
  413.      *  Save the user's list of read articles and deallocate storage
  414.      */
  415.  
  416.  
  417.     FILE   *tmp_file;
  418.     ACTIVE *act;
  419.     int    i, articles, ct;
  420.     char   buf[256];
  421.  
  422.     /* open the file */
  423. /*    strcpy(buf, my_stuff.news_dir);
  424.     strcat(buf, my_stuff.user);
  425.     strcat(buf, ".nrc");
  426. */
  427.     strcat(strcpy(buf, my_stuff.home), "snews.nrc");
  428.     if ((tmp_file = fopen(buf, "wt")) == NULL) {
  429.         fprintf(stderr, "can't open user's rc file for output\n");
  430.         exit(1);
  431.     }
  432.  
  433.     /* write out the lists and deallocate the arrays */
  434.     act = local_head;
  435.     while (act != NULL) {
  436.  
  437.         articles = (int)(act->hi_num - act->lo_num);
  438.         if (articles > 0) {
  439.             fprintf(tmp_file, "%s ", act->group);
  440.  
  441.             ct = 0;
  442.  
  443.             if (act->read_list != NULL) {
  444.                 for (i = 0; i < articles; i++) {
  445.                     if(*((act->read_list)+i)) {
  446.                         ct++;
  447.                         fprintf(tmp_file, "%d ", i+act->lo_num+1);
  448.                         if ((ct % 10) == 0)
  449.                             fprintf(tmp_file, "\\ \n");
  450.                     }
  451.                 }
  452.             }
  453.  
  454.             fprintf(tmp_file, "\n");
  455.             if (act->read_list != NULL) {
  456.                 free(act->read_list);
  457.             }
  458.         }
  459.         act = act->next;
  460.     }
  461.  
  462.     fclose(tmp_file);
  463.  
  464. }
  465.  
  466. /*------------------------- set colors -----------------------------------*/
  467.  
  468. void set_colors(char *keyword, char *value)
  469. {
  470.     static char *colors[] = {"bla","blu","gre","cya","red","mag","yel","whi"};
  471.     int          color    = 0,
  472.                  i        = 0;
  473.     char        *f        = NULL;
  474.  
  475.     if (value)
  476.         strlwr(value);
  477.  
  478.     f = strtok(value,"\0");            /* does this do anything? [df] */
  479.  
  480.     while (isspace(*f)) f++;
  481.  
  482.     for (i = 0; (i < 8) && (strncmp(colors[i],f,3) != 0); i++)
  483.         /* empty loop */ ;
  484.  
  485.     color  = (i < 8) ? i : 0;
  486.     color |= (strchr(f, '+') != NULL) ? 8 : 0;
  487.  
  488.     helpf = (strncmp("helpf", keyword, 5)) ? helpf : (unsigned char) color;
  489.     helpb = (strncmp("helpb", keyword, 5)) ? helpb : (unsigned char) color;
  490.  
  491.     textf = (strncmp("textf", keyword, 5)) ? textf : (unsigned char) color;
  492.     textb = (strncmp("textb", keyword, 5)) ? textb : (unsigned char) color;
  493.  
  494.     headf = (strncmp("headf", keyword, 5)) ? headf : (unsigned char) color;
  495.     headb = (strncmp("headb", keyword, 5)) ? headb : (unsigned char) color;
  496.  
  497.     msgf  = (strncmp("msgf",  keyword, 4)) ? msgf  : (unsigned char) color;
  498.     msgb  = (strncmp("msgb",  keyword, 4)) ? msgb  : (unsigned char) color;
  499. }
  500.  
  501.  
  502.  
  503. /*------------------------- load UUPC rc files ---------------------------*/
  504.  
  505. int load_stuff(void)
  506. {
  507.     /*
  508.      *  Trawl the UUPC files to get the stuff we need - return TRUE
  509.      *  if completed ok
  510.      */
  511.  
  512.     int  res = 0;
  513.     int  i;
  514.     char buf[256];
  515.     char *fn, *p, *v;
  516.     FILE *tmp;
  517.  
  518.     /* news base directory */
  519.  
  520.     if ((fn = getenv("UUPCNEWS")) == NULL) {
  521.         fprintf(stderr, "UUPCNEWS environment variable undefined");
  522.         exit(1);
  523.     }
  524.  
  525.     /* give it a trailing \ */
  526.  
  527.     strcpy(my_stuff.news_dir, fn);
  528.     if (my_stuff.news_dir[ strlen(my_stuff.news_dir)-1 ] != '\\')
  529.         strcat(my_stuff.news_dir, "\\");
  530.  
  531.     /* set other defaults */
  532.     strcpy(my_stuff.replyuser, "-none-");
  533.     strcpy(my_stuff.uncompress, "compress -d %s");
  534.     my_stuff.home[0] = '\0';
  535.     my_stuff.signature[0] = '\0';
  536.     my_stuff.my_organisation[0] = '\0';
  537.     my_stuff.alias_file[0] = '\0';
  538.     strcpy(my_stuff.extract_file, "extract.nws");
  539.     strcpy(my_stuff.hotpipe, "metamail %s");
  540.     if ((v = getenv("EDITOR")) == NULL)
  541.         strcpy(my_stuff.editor, "edit %s");
  542.     else
  543.         strcat(strcpy(my_stuff.editor, v), " %s");
  544.  
  545.     /* get the temporary directory string from the environment in case
  546.        it isn't in the configuration file */
  547.     if (((v = getenv("TEMP")) != NULL) ||
  548.         ((v = getenv("TMP")) != NULL))
  549.         strcpy(my_stuff.temp_str, v);
  550.     else
  551.         my_stuff.temp_str[0] = '\0';
  552.     strcat(strcpy(my_stuff.temp_name, my_stuff.temp_str), "$unbatch");
  553.  
  554.     /* read the system file first, then the user's personal file */
  555.  
  556.     for (i = 0; i < 2; i++) {
  557.  
  558.         /* choose the file to open */
  559.  
  560.         if (i == 0) {
  561.             fn = getenv("SNEWSRC");
  562.             if (fn == NULL) {
  563.                 fn = getenv("UUPCUSRRC");
  564.                 if (fn == NULL) {
  565.                     fprintf(stderr, "Enviroment variable SNEWSRC not defined\n");
  566.                 }
  567.             }
  568.         }
  569.         else {
  570.             fn = getenv("UUPCSYSRC");
  571.             if (fn == NULL) {
  572.                 fprintf(stderr, "Enviroment variable UUPCSYSRC not defined\n");
  573.             }
  574.         }
  575.  
  576.         if ((tmp = fopen(fn, "rt")) != NULL) {
  577.  
  578.             /* read a line from the configuration file */
  579.             while (fgets(buf, 255, tmp)) {
  580.  
  581.                 if (((p = strtok(buf, " =\r\n")) != NULL) && (*p != '#')) {
  582.                     v = strtok(NULL, " =\r\n");
  583.  
  584.                     if (stricmp(p, "mailserv") == 0) {
  585.                         strcpy(my_stuff.mail_server, v);
  586.                         res++;
  587.                     }
  588.                     if (strnicmp(p, "color", 5) == 0) {
  589.                         set_colors(p+5, v);
  590.                     }
  591.                     if (stricmp(p, "nodename") == 0) {
  592.                         strcpy(my_stuff.my_site, v);
  593.                         res++;
  594.                     }
  595.                     if (stricmp(p, "newsdir") == 0) {
  596.                         strcpy(my_stuff.incoming_dir, v);
  597.                         if ((my_stuff.incoming_dir[strlen(my_stuff.incoming_dir)-1] != '/') &&
  598.                             (my_stuff.incoming_dir[strlen(my_stuff.incoming_dir)-1] != '\\'))
  599.                             strcat(my_stuff.incoming_dir, "/");
  600.                         expand_filename(my_stuff.incoming_dir);
  601.                         res++;
  602.                     }
  603.                     if (stricmp(p, "domain") == 0) {
  604.                         strcpy(my_stuff.my_domain, v);
  605.                         res++;
  606.                     }
  607.                     if (stricmp(p, "tempdir") == 0) {
  608.                         strcpy(my_stuff.temp_str, v);
  609. /* temp_str must end with \ and can't have any / because DOS doesn't like
  610.   those for redirection in a system() line
  611.   First do a very ugly kludge to see if we're operating on a system that
  612.   uses / instead of \
  613.   (note to self: don't be so lazy and look up the switchar system call! */
  614.                         if (getenv("COMSPEC")[2] != '/') {
  615.                             while (strchr(my_stuff.temp_str, '/'))
  616.                                 *strchr(my_stuff.temp_str, '/') = '\\';
  617.                             if (my_stuff.temp_str[strlen(my_stuff.temp_str)-1] != '\\')
  618.                                 strcat(my_stuff.temp_str, "\\");
  619.                         }
  620.                         expand_filename(my_stuff.temp_str);
  621.                         /* temporary unbatch file name -- can't have extension */
  622.                         strcpy(my_stuff.temp_name, my_stuff.temp_str);
  623.                         strcat(my_stuff.temp_name, "$unbatch");
  624.                     }
  625.                     if (stricmp(p, "mailbox") == 0) {
  626.                         strcpy(my_stuff.user, v);
  627.                         res++;
  628.                     }
  629.                     if (stricmp(p, "Signature") == 0) {
  630.                         strcpy(my_stuff.signature, v);
  631.                         expand_filename(my_stuff.signature);
  632.                     }
  633.                     if (stricmp(p, "name") == 0) {
  634.                         strcpy(my_stuff.my_name, v);
  635.                         v = strtok(NULL, " =\r\n");
  636.                         while (v != NULL) {
  637.                             strcat(my_stuff.my_name, " ");
  638.                             strcat(my_stuff.my_name, v);
  639.                             v = strtok(NULL, " =\r\n");
  640.                         }
  641.                         res++;
  642.                     }
  643.                     if (stricmp(p, "Organization") == 0) {
  644.                         strcpy(my_stuff.my_organisation, v);
  645.                         v = strtok(NULL, " =\r\n");
  646.                         while (v != NULL) {
  647.                             strcat(my_stuff.my_organisation, " ");
  648.                             strcat(my_stuff.my_organisation, v);
  649.                             v = strtok(NULL, " =\r\n");
  650.                         }
  651.                     }
  652.  
  653.                     if (stricmp(p, "Replyto") == 0) {
  654.                         strcpy(my_stuff.replyuser, v);
  655.                         v = strtok(NULL, " =\r\n");
  656.                         while (v != NULL) {
  657.                             strcat(my_stuff.replyuser, " ");
  658.                             strcat(my_stuff.replyuser, v);
  659.                             v = strtok(NULL, " =\r\n");
  660.                         }
  661.                     }
  662.  
  663.                     if (stricmp(p, "Editor") == 0) {
  664.                         strcpy(my_stuff.editor, v);
  665.                         v = strtok(NULL, " =\r\n");
  666.                         while (v != NULL) {
  667.                             strcat(my_stuff.editor, " ");
  668.                             strcat(my_stuff.editor, v);
  669.                             v = strtok(NULL, " =\r\n");
  670.                         }
  671.                         expand_filename(my_stuff.editor);
  672.                     }
  673.                     if (stricmp(p, "Uncompress") == 0) {
  674.                         strcpy(my_stuff.uncompress, v);
  675.                         v = strtok(NULL, " =\r\n");
  676.                         while (v != NULL) {
  677.                             strcat(my_stuff.uncompress, " ");
  678.                             strcat(my_stuff.uncompress, v);
  679.                             v = strtok(NULL, " =\r\n");
  680.                         }
  681.                         expand_filename(my_stuff.uncompress);
  682.                     }
  683.                     if (stricmp(p, "HotPipe") == 0) {
  684.                         strcpy(my_stuff.hotpipe, v);
  685.                         v = strtok(NULL, " =\r\n");
  686.                         while (v != NULL) {
  687.                             strcat(my_stuff.hotpipe, " ");
  688.                             strcat(my_stuff.hotpipe, v);
  689.                             v = strtok(NULL, " =\r\n");
  690.                         }
  691.                         expand_filename(my_stuff.hotpipe);
  692.                     }
  693.                     if (stricmp(p, "Home") == 0) {
  694.                         strcpy(my_stuff.home, v);
  695.                         if (my_stuff.home[ strlen(my_stuff.home)-1 ] != '\\')
  696.                             strcat(my_stuff.home, "/");
  697.                         res++;
  698.                     }
  699.                     if (stricmp(p, "Aliases") == 0) {
  700.                         strcpy(my_stuff.alias_file, v);
  701.                         expand_filename(my_stuff.alias_file);
  702.                     }
  703.                     if (stricmp(p, "Extract") == 0) {
  704.                         strcpy(my_stuff.extract_file, v);
  705.                         expand_filename(my_stuff.extract_file);
  706.                     }
  707.                 } /* if */
  708.             } /* while */
  709.             fclose (tmp);
  710.  
  711.         }
  712.         else {
  713.             fprintf(stderr, "Cannot open %s\n", fn);
  714.         }
  715.     }
  716.     return(res >= 7);        /* see if all mandatory items have been specified */
  717. }
  718.  
  719.  
  720.  
  721. /*--------------------------- unpack the batch ------------------------*/
  722. FILE *open_out_file(char *ng)
  723. {
  724.     /*
  725.      *  This routine creates a filename from the newsgroup name.
  726.      *  The active file counter are updated.
  727.      */
  728.  
  729.     ACTIVE *gp;
  730.     char   *fn;
  731.     FILE   *tmp;
  732.  
  733.     gp = find_news_group(ng);
  734.  
  735.     fn = make_news_group_name(gp->group);
  736.  
  737.     (gp->hi_num)++;
  738.     update_active_entry(gp);
  739.  
  740.     if ((tmp = flockopen(fn, "r+b")) == NULL) {
  741.         fprintf(stderr,"active: cannot open text file %s\n", fn);
  742.         exit(1);
  743.     }
  744.     fseek(tmp, 0, SEEK_END);
  745.  
  746.     return(tmp);
  747. }
  748.  
  749.  
  750. /*--------------------------- unpack the batch ------------------------*/
  751. FILE *open_index_file(char *ng)
  752. {
  753.     /*
  754.      *  This routine open the index file for the newsgroup
  755.      */
  756.  
  757.     ACTIVE *gp;
  758.     char   fnx[256], *fn;
  759.     FILE   *tmp;
  760.  
  761.     /* printf("news: ng found = %s\n", ng); */
  762.     gp = find_news_group(ng);
  763.     fn = make_news_group_name(gp->group);
  764.     sprintf(fnx, "%s.IDX", fn);
  765.  
  766.     if((tmp = flockopen(fnx, "r+b")) == NULL) {
  767.         fprintf(stderr, "active: cannot open index file %s\n", fn);
  768.         exit(1);
  769.     }
  770.     fseek(tmp, 0, SEEK_END);
  771.  
  772.     return(tmp);
  773.  
  774. }
  775.  
  776.  
  777.  
  778. /*------------------------- post sequence number ----------------------------*/
  779. int post_sequence(void)
  780. {
  781.     /*
  782.      *  Get the sequence number from the seq file if it exists - if
  783.      *  not create it
  784.      */
  785.  
  786.     FILE *seq_file;
  787.     char fn[256];
  788.     int  seq;
  789.  
  790.     strcpy(fn, my_stuff.news_dir);
  791.     strcat(fn, "nseq");
  792.  
  793.     if ((seq_file = flockopen(fn, "r+t")) != NULL) {
  794.         fscanf(seq_file, "%d", &seq);
  795.         seq++;
  796.         rewind(seq_file);
  797.     } else {
  798.         seq = 0;
  799.         seq_file = flockopen(fn, "wt");
  800.     }
  801.  
  802.     fprintf(seq_file, "%d", seq);
  803.  
  804.     fclose(seq_file);
  805.     return(seq);
  806. }
  807.  
  808.  
  809. /*-------------------------------- safeish malloc --------------------------*/
  810. void *xmalloc(size_t size)
  811. {
  812.     void *p;
  813.     if ((p = malloc(size)) == NULL) {
  814.         gotoxy(1,25);
  815.         fprintf(stderr, "\n\nSORRY - NO MEMORY LEFT \n");
  816.         exit(1);
  817.     }
  818.  
  819.     return(p);
  820. }
  821.  
  822.  
  823. /*------------------------ ctrl-break signal handler -----------------------*/
  824. void cdecl sig_break()
  825. {
  826.     signal(SIGINT, sig_break);    /* reactive signal */
  827.     ++break_hit;                /* indicate that control-break was hit */
  828. }
  829.  
  830.  
  831. /*------------------------- expand ~/ in file name -------------------------*/
  832. char *expand_filename(char *fn)
  833. {
  834.     /* if file name starts with ~/ change to user's home directory */
  835.     if ((fn[0] == '~') && ((fn[1] == '/') || (fn[1] == '\\')) && fn[2]) {
  836.         memmove(fn+strlen(my_stuff.home), fn+2, strlen(fn+2) + 1);
  837.         memmove(fn, my_stuff.home, strlen(my_stuff.home));
  838.     }
  839.     return fn;
  840. }
  841.