home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff319.lzh / CNewsSrc / cnews.orig.lzh / relay / sys.c < prev    next >
C/C++ Source or Header  |  1989-06-27  |  8KB  |  321 lines

  1. /*
  2.  * news sys file reading functions
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <ctype.h>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include "libc.h"
  10. #include "fgetmfs.h"
  11. #include "news.h"
  12. #include "config.h"
  13. #include "system.h"
  14.  
  15. #define BTCHDIR "out.going/"    /* prefix of relative batch file name */
  16. #define BTCHPFX BTCHDIR        /* prefix of default batch file name */
  17. #define BTCHSFX "/togo"        /* suffix of same */
  18. #define CMDPFX "uux - -r -z "    /* prefix of default command */
  19. #define CMDSFX "!rnews"        /* suffix of same */
  20.  
  21. /* private */
  22. static FILE *fp = NULL;            /* stream for ctlfile(filerelname) */
  23. static char filerelname[] = "sys";    /* filename relative to $NEWSCTL */
  24.  
  25. /* forward decls */
  26. FORWARD char *parsecolon(), *reparse();
  27. FORWARD void readsys(), parsesysln(), parse(), parseflags();
  28.  
  29. /* exports */
  30. struct system *firstsys = NULL;    /* cache: 1st sys of in-core sys file */
  31. struct system *currsys = NULL;    /* current system */
  32.  
  33. /* imports */
  34. extern boolean justone;
  35. extern struct system *mysysincache();
  36. extern void rewsys(), remmysys(), freecurrsys();
  37.  
  38. struct system *
  39. oursys()            /* return our sys entry */
  40. {
  41.     register struct system *sys = mysysincache();
  42.     static struct system fakesys;
  43.  
  44.     if (sys == NULL) {
  45.         rewsys(fp);
  46.         while ((sys = nextsys()) != NULL &&
  47.             !STREQ(sys->sy_name, hostname()))
  48.             ;
  49.         if (sys == NULL) {
  50.             /* no entry: cook one up; no need to malloc members */
  51.             fakesys.sy_name = hostname();
  52.             fakesys.sy_excl = NULL;
  53.             fakesys.sy_ngs = "all";
  54.             fakesys.sy_distr = "all";
  55.             fakesys.sy_flags = 0;
  56.             fakesys.sy_lochops = 0;
  57.             fakesys.sy_cmd = "";
  58.             fakesys.sy_next = NULL;
  59.             sys = &fakesys;
  60.         }
  61.         remmysys(sys);            /* for future reference */
  62.     }
  63.     return sys;
  64. }
  65.  
  66. /*
  67.  * Return the next sys entry, which may span multiple lines.
  68.  * Returned pointer points at a static struct whose members
  69.  * point at static storage.
  70.  *
  71.  * It would be clearer to rewrite the justone/nextsys/readsys dance
  72.  * to get rid of justone, but I haven't the energy.  Sorry.  Beware that
  73.  * justone is set in either ../libbig/sys.fast.c or ../libsmall/sys.slow.c.
  74.  */
  75. struct system *
  76. nextsys()
  77. {
  78.     struct system *retsys;
  79.  
  80.     if (firstsys == NULL && fp == NULL)
  81.         if ((fp = fopenwclex(ctlfile(filerelname), "r")) == NULL)
  82.             return NULL;
  83.     if (fp != NULL && firstsys == NULL)
  84.         readsys();
  85.     retsys = currsys;
  86.     if (currsys != NULL)
  87.         currsys = currsys->sy_next;
  88.     return retsys;
  89. }
  90.  
  91. /*
  92.  * If justone, read one entry; else read whole sys file (done once only).
  93.  * Ignores '#' comments and blank lines; uses cfgetms to read possibly-
  94.  * continued lines of arbitrary length.
  95.  */
  96. STATIC void
  97. readsys()
  98. {
  99.     register char *sysline;
  100.  
  101.     if (justone)
  102.         freecurrsys();
  103.     else
  104.         rewind(fp);
  105.     while ((sysline = cfgetms(fp)) != NULL) {
  106.         if (sysline[0] != '#' && sysline[0] != '\n')
  107.             parsesysln(sysline);
  108.         free(sysline);
  109.         if (justone && firstsys != NULL) {    /* parsed an entry */
  110.             firstsys = NULL;
  111.             return;
  112.         }
  113.     }
  114.     (void) nfclose(fp);
  115.     fp = NULL;
  116.     rewsys(fp);
  117. }
  118.  
  119. static char *curr, *next;            /* parsing state */
  120.  
  121. /*
  122.  * Parse (and modify) sysline into *currsys, which is malloced here
  123.  * and freed iff "justone", in readsys(), see freecursys().
  124.  *
  125.  * Side-effect: sysline has a trailing newline removed.
  126.  */
  127. STATIC void
  128. parsesysln(sysline)
  129. register char *sysline;
  130. {
  131.     register struct system *sysp =(struct system *)nemalloc(sizeof *sysp);
  132.     char *flagstring;
  133.  
  134.     trim(sysline);
  135.     next = sysline;
  136.     parse(&sysp->sy_name);
  137.     parse(&sysp->sy_ngs);
  138.     parse(&flagstring);
  139.     parse(&sysp->sy_cmd);
  140.     /* could check for extra fields here */
  141.  
  142.     parseflags(flagstring, sysp);
  143.     free(flagstring);        /* malloced by parse */
  144.     sysp->sy_next = NULL;
  145.  
  146.     /* reparse for embedded slashes */
  147.     sysp->sy_excl = reparse(sysp->sy_name, '/');
  148.     sysp->sy_distr = reparse(sysp->sy_ngs, '/');
  149.     if (sysp->sy_distr == NULL)    /* default distr is ngs... */
  150.         sysp->sy_distr = sysp->sy_ngs;
  151.  
  152.     sysdeflt(sysp);            /* fill in any defaults */
  153.  
  154.     /* stash *sysp away on the tail of the current list of systems */
  155.     if (firstsys == NULL)
  156.         firstsys = sysp;
  157.     else
  158.         currsys->sy_next = sysp;
  159.     currsys = sysp;
  160. }
  161.  
  162. /*
  163.  * fill in defaults in sysp.
  164.  *
  165.  * expand a name of "ME" to hostname().
  166.  * If an empty batch file name was given, supply a default
  167.  * ($NEWSARTS/BTCHPFX system BTCHSFX).
  168.  * Prepend $NEWSARTS/BTCHDIR to relative file names.
  169.  * If an empty command was given, supply a default (uux - -r -z system!rnews).
  170.  * (This *is* yucky and uucp-version-dependent.)
  171.  */
  172. void
  173. sysdeflt(sysp)
  174. register struct system *sysp;
  175. {
  176.     if (STREQ(sysp->sy_name, "ME")) {
  177.         free(sysp->sy_name);    /* malloced by parse */
  178.         sysp->sy_name = strsave(hostname());
  179.     }
  180.     if (sysp->sy_flags&FLG_BATCH && sysp->sy_cmd[0] == '\0') {
  181.         register char *deffile = nemalloc((unsigned) STRLEN(BTCHPFX) +
  182.             strlen(sysp->sy_name) + STRLEN(BTCHSFX) + 1);
  183.  
  184.         (void) strcpy(deffile, BTCHPFX);
  185.         (void) strcat(deffile, sysp->sy_name);
  186.         (void) strcat(deffile, BTCHSFX);
  187.         free(sysp->sy_cmd);    /* malloced by parse */
  188.         sysp->sy_cmd = strsave(fullartfile(deffile));
  189.         free(deffile);
  190.     }
  191.     if (sysp->sy_flags&FLG_BATCH && sysp->sy_cmd[0] != FNDELIM) {
  192.         register char *absfile = nemalloc((unsigned) STRLEN(BTCHDIR) +
  193.             strlen(sysp->sy_cmd) + 1);
  194.  
  195.         (void) strcpy(absfile, BTCHDIR);
  196.         (void) strcat(absfile, sysp->sy_cmd);
  197.         free(sysp->sy_cmd);    /* malloced by parse */
  198.         sysp->sy_cmd = strsave(artfile(absfile));
  199.         free(absfile);
  200.     }
  201.     if (!(sysp->sy_flags&FLG_BATCH) && sysp->sy_cmd[0] == '\0') {
  202.         free(sysp->sy_cmd);    /* malloced by parse */
  203.         sysp->sy_cmd = nemalloc((unsigned) STRLEN(CMDPFX) +
  204.             strlen(sysp->sy_name) + STRLEN(CMDSFX) + 1);
  205.         (void) strcpy(sysp->sy_cmd, CMDPFX);
  206.         (void) strcat(sysp->sy_cmd, sysp->sy_name);
  207.         (void) strcat(sysp->sy_cmd, CMDSFX);
  208.     }
  209. }
  210.  
  211. /*
  212.  * Parse "next" to colon into malloced storage, return its ptr via "into".
  213.  * *into is freed iff "justone", in readsys(), see freecursys().
  214.  */
  215. STATIC void
  216. parse(into)
  217. register char **into;
  218. {
  219.     curr = next;
  220.     if (curr == NULL)
  221.         *into = strsave("");
  222.     else {
  223.         next = parsecolon(curr);
  224.         *into = strsave(curr);
  225.     }
  226. }
  227.  
  228. STATIC char *
  229. parsecolon(line)        /* return NULL or ptr. to byte after colon */
  230. char *line;
  231. {
  232.     register char *colon;
  233.  
  234.     INDEX(line, ':', colon);
  235.     if (colon != NULL)
  236.         *colon++ = '\0';
  237.     return colon;
  238. }
  239.  
  240. /*
  241.  * replace "delim" in "field" with a NUL and return the address of the byte
  242.  * after the NUL (the address of the second subfield), or NULL if no
  243.  * "delim" was present.
  244.  */
  245. STATIC char *
  246. reparse(field, delim)
  247. char *field;
  248. int delim;
  249. {
  250.     register char *delimp = index(field, delim);
  251.  
  252.     if (delimp != NULL)
  253.         *delimp++ = '\0';
  254.     return delimp;
  255. }
  256.  
  257. /*
  258.  * Parse sys file flags into sysp.
  259.  */
  260. STATIC void
  261. parseflags(flags, sysp)
  262. register char *flags;
  263. register struct system *sysp;
  264. {
  265.     sysp->sy_flags = 0;
  266.     sysp->sy_lochops = 0;        /* default L value */
  267.     for (; *flags != '\0'; flags++)
  268.         switch (*flags) {
  269.         case 'A':
  270.             errunlock("A news format not supported", "");
  271.             /* NOTREACHED */
  272.         case 'B':        /* mostly harmless */
  273.             break;
  274.         case 'f':
  275.             sysp->sy_flags |= FLG_BATCH|FLG_SZBATCH;
  276.             break;
  277.         case 'F':
  278.             sysp->sy_flags |= FLG_BATCH;
  279.             break;
  280.         case 'I':        /* NNTP hook: write msgids, !files */
  281.             sysp->sy_flags |= FLG_BATCH|FLG_IHAVE;
  282.             break;
  283.         case 'L':        /* Ln */
  284.             sysp->sy_flags |= FLG_LOCAL;
  285.             sysp->sy_lochops = 0;
  286.             while (isascii(flags[1]) && isdigit(flags[1])) {
  287.                 sysp->sy_lochops *= 10;
  288.                 sysp->sy_lochops += *++flags - '0';
  289.             }
  290.             break;
  291.         case 'm':        /* send only moderated groups */
  292.             sysp->sy_flags |= FLG_MOD;
  293.             break;
  294.         case 'N':
  295.             errunlock(
  296.     "The N flag is a wasteful old kludge; see the I flag instead.", "");
  297.             /* NOTREACHED */
  298.         case 'n':        /* NNTP hook: write files+msgids */
  299.             sysp->sy_flags |= FLG_BATCH|FLG_NBATCH;
  300.             break;
  301.         case 'u':        /* send only unmoderated groups */
  302.             sysp->sy_flags |= FLG_UNMOD;
  303.             break;
  304.         case 'U':        /* mostly harmless */
  305.             break;
  306.         case 'H':        /* bugger off */
  307.         case 'S':        /* bugger off */
  308.         case 'M':        /* multicast: obs., see batcher */
  309.         case 'O':        /* multicast: obs., see batcher */
  310.         default:
  311.             errunlock("unknown sys flag `%s' given", flags);
  312.             /* NOTREACHED */
  313.         }
  314. }
  315.  
  316. void
  317. rewndsys()
  318. {
  319.     rewsys(fp);
  320. }
  321.