home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 1 / GoldFishApril1994_CD2.img / d4xx / d473 / cnewssrc / cnews_src.lzh / relay / trbatch.c < prev    next >
C/C++ Source or Header  |  1990-05-28  |  5KB  |  200 lines

  1. /*  :ts=4
  2.  * transmit batch file management
  3.  *
  4.  *    $Log$
  5.  */
  6.  
  7. #include <stdio.h>
  8. #ifdef unix
  9. # include <sys/types.h>
  10. #endif /* unix */
  11. #include "libc.h"
  12. #include "news.h"
  13. #include "msgs.h"
  14. #include "trbatch.h"
  15.  
  16. /* tunable parameters */
  17. #ifndef FLUSHEVERY
  18. #define FLUSHEVERY 1    /* fflush batch files every this many lines */
  19. #endif            /* FLUSHEVERY */
  20. #ifndef NOPENBFS
  21. #define NOPENBFS 10    /* # batchfiles kept open for batching (arbitrary) */
  22. #endif            /* NOPENBFS */
  23.  
  24. static struct batchfile batchfile[NOPENBFS];    /* try to keep open always */
  25. #define lastbf &batchfile[NOPENBFS-1]
  26. /*
  27.  * More than one pointer in ordtobfs may point at a given batchfile,
  28.  * to permit sharing of open batch files among multiple sys entries.
  29.  * ordtobfs[ordinal # of batch sys entry] -> (usually open) batch file,
  30.  * if the index is in range.
  31.  */
  32. static struct batchfile *ordtobfs[NOPENBFS];
  33. static struct batchfile fakebatf;    /* for non-cached batch files */
  34.  
  35. /* forwards */
  36. FORWARD statust bfclose(), bfrclose();
  37. FORWARD struct batchfile *bfincache(), *fakebf();
  38.  
  39. /*
  40.  * open "name" for appending, for batch sys entry with ordinal # "ord".
  41.  *
  42.  * if ord is too big, see if any batchfile has been assigned to "name" yet;
  43.  * if not, set up a fake batchfile for temporary use.  if ord is in range,
  44.  * ensure that (name, ord) are mapped to a batchfile.
  45.  *
  46.  * if an attempt to open the batchfile's stream fails, close an arbitrary
  47.  * batchfile stream and retry the open.
  48.  */
  49. struct batchfile *
  50. bfopen(name, ord)
  51. register char *name;
  52. register int ord;
  53. {
  54.     register struct batchfile *bf;
  55.  
  56.     if (ord >= NOPENBFS) {            /* no mapping possible */
  57.         bf = bfisopen(name);
  58.         if (bf == NULL)
  59.             bf = fakebf((FILE *)NULL, name);
  60.     } else
  61.         bf = bfincache(name, ord);
  62.  
  63.     if (bf->bf_str == NULL)
  64.         bf->bf_str = fopenclex(name, "a");
  65.     if (bf->bf_str == NULL) {
  66.         if (bfrclose() != ST_OKAY)
  67.             return NULL;
  68.         bf->bf_str = fopenwclex(name, "a");    /* retry, may bitch */
  69.     }
  70.     return bf;
  71. }
  72.  
  73. /*
  74.  * returns a batchfile, never NULL, corresponding to name and ord.
  75.  * if ord isn't mapped, search the batchfile cache for name;
  76.  * if missing, initialise batchfile[ord] and map ord to it.
  77.  * if ord wasn't mapped, but name was in the cache, map ord to the cache hit.
  78.  */
  79. STATIC struct batchfile *
  80. bfincache(name, ord)
  81. char *name;
  82. int ord;
  83. {
  84.     register struct batchfile *bf = ordtobfs[ord];
  85.  
  86.     if (bf == NULL) {
  87.         bf = bfisopen(name);
  88.         if (bf == NULL) {
  89.             /* establish new mapping for a new file */
  90.             bf = &batchfile[ord];
  91.             bf->bf_name = strsave(name);
  92.             bf->bf_str = NULL;    /* paranoia */
  93. #ifdef notdef
  94.             bf->bf_ref = 0;
  95. #endif
  96.             bf->bf_lines = FLUSHEVERY;
  97.         }
  98.         ordtobfs[ord] = bf;
  99.     }
  100.     /* mapping is now set (ord -> bf) */
  101.     return bf;
  102. }
  103.  
  104. /* ARGSUSED ord */
  105. statust
  106. bffkclose(ord)            /* close current (ord's) batchfile, if fake */
  107. int ord;
  108. {
  109.     register statust status = ST_OKAY;
  110.  
  111.     if (fakebatf.bf_str != NULL)
  112.         status |= bfclose(&fakebatf);
  113.     return status;
  114. }
  115.  
  116. STATIC statust
  117. bfclose(bf)
  118. register struct batchfile *bf;
  119. {
  120.     register statust status = ST_OKAY;
  121.  
  122.     if (nfclose(bf->bf_str) == EOF)
  123.         status = prfulldisk(bf->bf_name);
  124.     bf->bf_str = NULL;    /* prevent accidents; mark as closed */
  125.     return status;
  126. }
  127.  
  128. STATIC struct batchfile *
  129. fakebf(stream, name)
  130. FILE *stream;
  131. char *name;
  132. {
  133.     fakebatf.bf_name = name;
  134.     fakebatf.bf_str = stream;
  135.     return &fakebatf;
  136. }
  137.  
  138. /*
  139.  * search the batchfile cache for "name"; return the hit, if any.
  140.  */
  141. struct batchfile *
  142. bfisopen(name)
  143. register char *name;
  144. {
  145.     register struct batchfile *bf;
  146.  
  147.     for (bf = batchfile; bf <= lastbf; bf++)
  148.         if (bf->bf_name != NULL && STREQ(name, bf->bf_name))
  149.             return bf;
  150.     return NULL;
  151. }
  152.  
  153. /*
  154.  * a performance hack: only fflush bf->bf_str every FLUSHEVERY calls.
  155.  */
  156. int
  157. bfflush(bf)
  158. register struct batchfile *bf;
  159. {
  160.     register int ret = 0;
  161.  
  162.     if (--bf->bf_lines <= 0) {
  163.         bf->bf_lines = FLUSHEVERY;
  164.         ret = fflush(bf->bf_str);
  165.     }
  166.     return ret;
  167. }
  168.  
  169. STATIC statust
  170. bfrclose()                /* close an arbitrary batchfile */
  171. {
  172.     register struct batchfile *bf;
  173.     register statust status = ST_OKAY;
  174.  
  175.     for (bf = batchfile; bf <= lastbf; bf++)
  176.         if (bf->bf_str != NULL) {
  177.             status |= bfclose(bf);
  178.             break;
  179.         }
  180.     return status;
  181. }
  182.  
  183. statust
  184. bfrealclose()                /* close all open batch files */
  185. {
  186.     register struct batchfile *bf;
  187.     register statust status = ST_OKAY;
  188.  
  189.     for (bf = batchfile; bf <= lastbf; bf++) {
  190.         if (bf->bf_str != NULL)        /* batch file stream open */
  191.             status |= bfclose(bf);
  192.         nnfree(&bf->bf_name);
  193. #ifdef notdef
  194.         bf->bf_ref = 0;
  195. #endif
  196.         ordtobfs[bf - batchfile] = NULL;    /* unmap batch file */
  197.     }
  198.     return status;
  199. }
  200.