home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume7 / 2.11news / part17 < prev    next >
Text File  |  1986-11-30  |  62KB  |  2,754 lines

  1. Subject:  v07i056:  2.11 News Source, Part07/09
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: seismo!rick (Rick Adams)
  6. Mod.sources: Volume 7, Issue 56
  7. Archive-name: 2.11news/Part07
  8.  
  9. # To extract, sh this file
  10. #    news 2.11 source part 7 of 9
  11. if test ! -d src
  12. then
  13.     mkdir src
  14. fi
  15. echo x - src/funcs2.c 1>&2
  16. sed 's/.//' >src/funcs2.c <<'*-*-END-of-src/funcs2.c-*-*'
  17. -/*
  18. - * This software is Copyright (c) 1985 by Rick Adams.
  19. - *
  20. - * Permission is hereby granted to copy, reproduce, redistribute or
  21. - * otherwise use this software as long as: there is no monetary
  22. - * profit gained specifically from the use or reproduction or this
  23. - * software, it is not sold, rented, traded or otherwise marketed, and
  24. - * this copyright notice is included prominently in any copy
  25. - * made.
  26. - *
  27. - * The author make no claims as to the fitness or correctness of
  28. - * this software for any use whatsoever, and it is provided as is. 
  29. - * Any use of this software is at the user's own risk.
  30. - *
  31. - *
  32. - * funcs2 - functions used by both inews and readnews.
  33. - */
  34. -
  35. -#ifdef SCCSID
  36. -static char    *SccsId = "@(#)funcs2.c    1.16    10/23/86";
  37. -#endif /* SCCSID */
  38. -
  39. -#include "params.h"
  40. -
  41. -#ifdef SunIII
  42. -#ifndef INTERNET
  43. -#define    INTERNET
  44. -#endif /* !INTERNET */
  45. -#endif /* SunIII */
  46. -
  47. -/*LINTLIBRARY*/
  48. -
  49. -/*
  50. - * Get user name and home directory.
  51. - */
  52. -getuser()
  53. -{
  54. -    static int flag = TRUE;
  55. -    register struct passwd *p;
  56. -
  57. -    if (flag) {
  58. -        if ((p = getpwuid(uid)) == NULL)
  59. -            xerror("Cannot get user's name");
  60. -        if ( username == NULL || username[0] == 0)
  61. -            username = AllocCpy(p->pw_name);
  62. -        userhome = AllocCpy(p->pw_dir);
  63. -        flag = FALSE;
  64. -    }
  65. -    (void) strcpy(header.path, username);
  66. -}
  67. -
  68. -static    FILE    *sysfile;
  69. -
  70. -char *fldget();
  71. -
  72. -static int sfline;
  73. -
  74. -/*
  75. - * Open SUBFILE.
  76. - */
  77. -s_openr()
  78. -{
  79. -    sysfile = xfopen(SUBFILE, "r");
  80. -    sfline = 0;
  81. -}
  82. -
  83. -/*
  84. - * Read SUBFILE.
  85. - */
  86. -s_read(sp)
  87. -register struct srec *sp;
  88. -{
  89. -    register char *p;
  90. -    register int  c;
  91. -    char *e;
  92. -    int chop_spaces = 0;
  93. -again:
  94. -    p = bfr;
  95. -        /*
  96. -         * Read  the  SUBFILE  (/usr/lib/news/sys)  from   the   current
  97. -     * position  to  the  first  unescaped newline.  If a newline is
  98. -     * escaped with a backslash (\) continue reading but throw  away
  99. -     * the backslash and newline; read the next line skipping spaces
  100. -     * and tabs until the first non-space/tab character, then  start
  101. -     * looking   for   a   newline   again.   Skipping  the  leading
  102. -     * spaces/tabs after a escaped newline  keeps  the  news  groups
  103. -     * together.  If  a  line  begins  with a newline, just skip it.
  104. -     */
  105. -    for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) {
  106. -        *p = c;
  107. -        if (c == '\n') {
  108. -            sfline++;
  109. -            if (p == bfr || p[-1] != '\\') {
  110. -                p[1] = '\0';
  111. -                break;
  112. -            } else {
  113. -                chop_spaces++;
  114. -                p -= 2;
  115. -            }
  116. -        } else if (chop_spaces) {
  117. -            if (c == '\t' || c == ' ')
  118. -                p--;
  119. -            else
  120. -                chop_spaces = 0;
  121. -        }
  122. -    }
  123. -    if (c == EOF) {
  124. -        return FALSE;
  125. -    }
  126. -    p = bfr;
  127. -    while (*p == ' ' || *p == '\t') /* skip leading white space */
  128. -        p++;
  129. -    if (*p == '\n')
  130. -        goto again;         /* skip newlines */
  131. -    if (!nstrip(p))
  132. -        xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline);
  133. -    if (*p == '#')
  134. -        goto again;
  135. -    sp->s_xmit[0] = '\0';
  136. -    sp->s_flags[0] = '\0';
  137. -    sp->s_nosend = (char *)0;
  138. -
  139. -    p = fldget(sp->s_name, p);
  140. -    if (*p++ == '\0')
  141. -        xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline);
  142. -/*
  143. - * A sys file line reading "ME" means the name of the local system.
  144. - */
  145. -    if (strcmp(sp->s_name, "ME") == 0)
  146. -        (void) strcpy(sp->s_name, FULLSYSNAME);
  147. -    e = index(sp->s_name, '/');
  148. -    if (e) {
  149. -        *e++ = '\0';
  150. -        sp->s_nosend = e;
  151. -    }
  152. -    p = fldget(sp->s_nbuf, p);
  153. -    lcase(sp->s_nbuf);
  154. -    if (*p++ == '\0')
  155. -        return TRUE;
  156. -
  157. -    p = fldget(sp->s_flags, p);
  158. -    if (*p++ == '\0')
  159. -        return TRUE;
  160. -
  161. -    (void) fldget(sp->s_xmit, p);
  162. -    return TRUE;
  163. -}
  164. -
  165. -char *
  166. -fldget(q, p)
  167. -register char *q, *p;
  168. -{
  169. -    while (*p && *p != ':') {
  170. -        if (*p == '\\' && p[1]==':')
  171. -            p++;
  172. -        *q++ = *p++;
  173. -    }
  174. -    *q = '\0';
  175. -    return p;
  176. -}
  177. -
  178. -/*
  179. - * Find the SUBFILE record for a system.
  180. - */
  181. -s_find(sp, system)
  182. -register struct srec *sp;
  183. -char *system;
  184. -{
  185. -    s_openr();
  186. -    while (s_read(sp))
  187. -        if (strncmp(system, sp->s_name, SNLN) == 0) {
  188. -            s_close();
  189. -            return TRUE;
  190. -        }
  191. -    s_close();
  192. -    return FALSE;
  193. -}
  194. -
  195. -/*
  196. - * Close sysfile.
  197. - */
  198. -s_close()
  199. -{
  200. -    (void) fclose(sysfile);
  201. -}
  202. -
  203. -extern struct timeb Now;
  204. -
  205. -time_t
  206. -cgtdate(datestr)
  207. -char *datestr;
  208. -{
  209. -    char    junk[40],month[40],day[30],tod[60],year[50];
  210. -    static time_t lasttime;
  211. -    static char lastdatestr[BUFLEN] = "";
  212. -
  213. -    if ( lastdatestr[0] && strcmp(datestr, lastdatestr) == 0)
  214. -        return lasttime;
  215. -    lasttime = getdate(datestr, &Now);
  216. -    if (lasttime < 0 &&
  217. -      sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) {
  218. -        (void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod);
  219. -        lasttime = getdate(bfr, &Now);
  220. -    }
  221. -    strncpy(lastdatestr, datestr, BUFLEN);
  222. -    return lasttime;
  223. -}
  224. -
  225. -lcase(s)
  226. -register char *s;
  227. -{
  228. -    register char *ptr;
  229. -
  230. -    for (ptr = s; *ptr; ptr++)
  231. -        if (isupper(*ptr))
  232. -            *ptr = tolower(*ptr);
  233. -}
  234. -
  235. -/*
  236. - * Return a compact representation of the person who posted the given
  237. - * message.  A sender or internet name will be used, otherwise
  238. - * the last part of the path is used preceded by an optional ".."
  239. - */
  240. -char *
  241. -tailpath(hp)
  242. -struct hbuf *hp;
  243. -{
  244. -    char *p, *r;
  245. -    static char resultbuf[BUFLEN];
  246. -    char pathbuf[PATHLEN];
  247. -    char *malloc();
  248. -
  249. -    /*
  250. -     * This only happens for articles posted by old news software
  251. -     * in non-internet format.
  252. -     */
  253. -    resultbuf[0] = '\0';
  254. -    (void) strncpy(pathbuf, hp->path, PATHLEN);
  255. -    p = index(pathbuf, ' ');
  256. -    if (p)
  257. -        *p = '\0';    /* Chop off trailing " (name)" */
  258. -    r = rindex(pathbuf, '!');
  259. -    if (r == 0) {
  260. -        r = pathbuf;
  261. -    } else {
  262. -        while (r > pathbuf && *--r != '!')
  263. -            ;
  264. -        if (r > pathbuf) {
  265. -            r++;
  266. -            (void) strcpy(resultbuf, "..!");
  267. -        }
  268. -    }
  269. -    (void) strcat(resultbuf, r);
  270. -    return resultbuf;
  271. -}
  272. -
  273. -/*
  274. - * arpadate is like ctime(3) except that the time is returned in
  275. - * an acceptable ARPANET time format instead of ctime format.
  276. - */
  277. -char *
  278. -arpadate(longtime)
  279. -time_t *longtime;
  280. -{
  281. -    register char *p, *q, *ud;
  282. -    register int i;
  283. -    static char b[40];
  284. -    extern struct tm *gmtime();
  285. -    extern char *asctime();
  286. -
  287. -    /*  Get current time. This will be used resolve the timezone. */
  288. -    ud = asctime(gmtime(longtime));
  289. -
  290. -    /*  Crack the UNIX date line in a singularly unoriginal way. */
  291. -    q = b;
  292. -
  293. -#ifdef notdef
  294. -/* until every site installs the fix to getdate.y, the day
  295. -   of the week can cause time warps */
  296. -    p = &ud[0];        /* Mon */
  297. -    *q++ = *p++;
  298. -    *q++ = *p++;
  299. -    *q++ = *p++;
  300. -    *q++ = ','; *q++ = ' ';
  301. -#endif
  302. -
  303. -    p = &ud[8];        /* 16 */
  304. -    if (*p == ' ')
  305. -        p++;
  306. -    else
  307. -        *q++ = *p++;
  308. -    *q++ = *p++; *q++ = ' ';
  309. -
  310. -    p = &ud[4];        /* Sep */
  311. -    *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' ';
  312. -
  313. -    p = &ud[22];        /* 1979 */
  314. -    *q++ = *p++; *q++ = *p++; *q++ = ' ';
  315. -
  316. -    p = &ud[11];        /* 01:03:52 */
  317. -    for (i = 8; i > 0; i--)
  318. -        *q++ = *p++;
  319. -
  320. -    *q++ = ' ';
  321. -    *q++ = 'G';        /* GMT */
  322. -    *q++ = 'M';
  323. -    *q++ = 'T';
  324. -    *q = '\0';
  325. -
  326. -    return b;
  327. -}
  328. -
  329. -char *
  330. -replyname(hptr)
  331. -struct hbuf *hptr;
  332. -{
  333. -    register char *ptr;
  334. -    static char tbuf[PATHLEN];
  335. -
  336. -    ptr = hptr->path;
  337. -    if (prefix(ptr, FULLSYSNAME) &&
  338. -        index(NETCHRS, ptr[strlen(FULLSYSNAME)]))
  339. -        ptr = index(ptr, '!') + 1;
  340. -#ifdef INTERNET
  341. -    if (hptr->from[0])
  342. -        ptr = hptr->from;
  343. -    if (hptr->replyto[0])
  344. -        ptr = hptr->replyto;
  345. -#endif
  346. -    (void) strcpy(tbuf, ptr);
  347. -    ptr = index(tbuf, '(');
  348. -    if (ptr) {
  349. -        while (ptr[-1] == ' ')
  350. -            ptr--;
  351. -        *ptr = 0;
  352. -    }
  353. -#ifdef    SunIII
  354. -    if (ptr = rindex(tbuf, '.')) {
  355. -        if (prefix(++ptr, "OZ")) {
  356. -            /* some people only allow it in lower case ... */
  357. -            strcpy(ptr, "oz");
  358. -            return tbuf;
  359. -        }
  360. -        if (prefix(ptr, "UUCP") || prefix(ptr, "ARPA") ||
  361. -            prefix(ptr, "DEC") || prefix(ptr, "CSNET")) {
  362. -            strcat(tbuf, "@munnari.oz");    /* via sun to munnari */
  363. -            return tbuf;
  364. -        }
  365. -    }
  366. -    /*
  367. -     * must(?) have come from a uucp site, lets look see if path passes
  368. -     * through munnari, and if so delete the fake uucp path after that.
  369. -     */
  370. -    for (ptr = tbuf ;; ptr++) {
  371. -        if (prefix(ptr, "munnari!")) {
  372. -            strcpy(tbuf, ptr+8);
  373. -            break;
  374. -        }
  375. -        ptr = index(ptr, '!');
  376. -        if (ptr == (char *)0)
  377. -            break;
  378. -    }
  379. -    /*
  380. -     * now, just send the address we have left to munnari, and
  381. -     * hope that something sensible will be done with it there.
  382. -     * (This works in more cases than you'd think ...)
  383. -     */
  384. -    strcat(tbuf, "@munnari.oz");
  385. -#else /* !SunIII */
  386. -#ifndef INTERNET
  387. -    /*
  388. -     * Play games stripping off multiple berknet
  389. -     * addresses (a!b!c:d:e => a!b!d:e) here.
  390. -     */
  391. -    for (ptr=tbuf; *ptr; ptr++) {
  392. -        register char *ptr2;
  393. -
  394. -        if (index(NETCHRS, *ptr) && *ptr == ':' &&
  395. -            (ptr2=index(ptr+1, ':')))
  396. -            (void) strcpy(ptr, ptr2);
  397. -    }
  398. -#else    /* INTERNET */
  399. -    {
  400. -    char mbuf[BUFLEN], modadd[BUFLEN];
  401. -    FILE *mfd;
  402. -    /* Let's find a path to the backbone */
  403. -    sprintf(mbuf, "%s/mailpaths", LIBDIR);
  404. -    mfd = xfopen(mbuf, "r");
  405. -    do {
  406. -        if (fgets(mbuf, sizeof mbuf, mfd) == NULL)
  407. -            xerror("Can't find internet in %s/mailpaths",
  408. -                LIBDIR);
  409. -    } while (!prefix(mbuf, "internet"));
  410. -    if (sscanf(mbuf, "%*s %s", modadd) != 1)
  411. -        xerror("backbone address corrupted");
  412. -    (void) fclose(mfd);
  413. -    (void)strcpy(mbuf, tbuf);
  414. -    /* If we are lucky, there is no ! or @ in the forward address */
  415. -    if (strpbrk(modadd, "!@") == NULL) {
  416. -        sprintf(tbuf, modadd, mbuf);
  417. -    } else {
  418. -        char *cp = index(mbuf, '@');
  419. -        if (index(modadd, '@') == NULL && cp) {
  420. -            /* we have to rearrange the address so no @ are in it */
  421. -            char atbuf[BUFLEN];
  422. -            *cp++ = '\0';
  423. -            sprintf(atbuf, "%s!%s", cp, mbuf);
  424. -            sprintf(tbuf, modadd, atbuf);
  425. -        } else if (cp) {
  426. -            /* some days you don't get lucky. presume the % hack */
  427. -            *cp = '%';
  428. -            sprintf(tbuf, modadd, mbuf);
  429. -        }
  430. -    }
  431. -    }
  432. -#endif /* INTERNET */
  433. -#endif /* !SunIII */
  434. -    return tbuf;
  435. -}
  436. -
  437. -#ifdef DBM
  438. -typedef struct {
  439. -    char *dptr;
  440. -    int dsize;
  441. -} datum;
  442. -#endif /* DBM */
  443. -
  444. -/*
  445. - * Given an article ID, find the line in the history file that mentions it.
  446. - * Return the text of the line, or NULL if not found.  A pointer to a
  447. - * static area is returned.
  448. - */
  449. -char *
  450. -findhist(artid)
  451. -char *artid;
  452. -{
  453. -    static char lbuf[256];
  454. -    char oidbuf[BUFSIZ];
  455. -    FILE *hfp;
  456. -    register char *p;
  457. -#ifdef DBM
  458. -    datum lhs, rhs;
  459. -    datum fetch();
  460. -    long fpos; /* We have to use an explicit variable to insure alignment */
  461. -#else /* !DBM */
  462. -    char *histfile();
  463. -#endif /* !DBM */
  464. -
  465. -    /* Try to understand old artid's as well.  Assume .UUCP domain. */
  466. -    if (artid[0] != '<') {
  467. -        p = index(artid, '.');
  468. -        if (p)
  469. -            *p++ = '\0';
  470. -        (void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid);
  471. -        if (p)
  472. -            *--p = '.';
  473. -    } else
  474. -        (void) strcpy(oidbuf, artid);
  475. -    lcase(oidbuf);
  476. -#ifdef DBM
  477. -    initdbm(ARTFILE);
  478. -    lhs.dptr = oidbuf;
  479. -    lhs.dsize = strlen(lhs.dptr) + 1;
  480. -    rhs = fetch(lhs);
  481. -    if (rhs.dptr == NULL)
  482. -        return NULL;
  483. -    hfp = xfopen(ARTFILE, "r");
  484. -    /* The bcopy is NECESSARY to insure alignment on some machines */
  485. -    bcopy(rhs.dptr, (char *)&fpos, sizeof (long));
  486. -    fseek(hfp, fpos, 0);
  487. -#else /* !DBM */
  488. -    hfp = xfopen(histfile(oidbuf), "r");
  489. -#endif /* !DBM */
  490. -    while (fgets(lbuf, BUFLEN, hfp) != NULL) {
  491. -        p = index(lbuf, '\t');
  492. -        if (p == NULL)
  493. -            p = index(lbuf, '\n');
  494. -        *p = 0;
  495. -        if (strcmp(lbuf, artid) == 0 || strcmp(lbuf, oidbuf) == 0) {
  496. -            (void) fclose(hfp);
  497. -            *p = '\t';
  498. -            *(lbuf + strlen(lbuf) - 1) = 0;    /* zap the \n */
  499. -            return lbuf;
  500. -        }
  501. -#ifdef DBM
  502. -        break;
  503. -#endif /* DBM */
  504. -    }
  505. -    (void) fclose(hfp);
  506. -    return NULL;
  507. -}
  508. -
  509. -/*
  510. - * Hunt up the article "artid", and return the newsgroup/artnum
  511. - * where it can be found.
  512. - */
  513. -char *
  514. -findfname(artid)
  515. -char *artid;
  516. -{
  517. -    char *line, *p, *q;
  518. -    char *findhist();
  519. -    static char fname[BUFLEN];
  520. -
  521. -    line = findhist(artid);
  522. -    if (line) {
  523. -        /* Look for it stored as an article, where it should be */
  524. -        p = index(line, '\t');
  525. -        p = index(p+1, '\t');
  526. -        p++;
  527. -        if (*p) {
  528. -            q = index(p, ' ');
  529. -            if (q)
  530. -                *q = 0;
  531. -            (void) strcpy(fname, p);
  532. -            return fname;
  533. -        }
  534. -    }
  535. -    return NULL;
  536. -}
  537. -
  538. -/*
  539. - * Hunt up the article "artid", fopen it for read, and return a
  540. - * file descriptor to it.  We look everywhere we can think of.
  541. - */
  542. -FILE *
  543. -hfopen(artid)
  544. -char *artid;
  545. -{
  546. -    char *p;
  547. -    char *findhist();
  548. -    FILE *rv = NULL;
  549. -    char fname[BUFLEN];
  550. -
  551. -    p = findfname(artid);
  552. -    if (p) {
  553. -        (void) strcpy(fname, dirname(p));
  554. -        rv = fopen(fname, "r");    /* NOT xfopen! */
  555. -        if (rv == NULL)
  556. -            xerror("Cannot hfopen article %s", artid);
  557. -    }
  558. -    return rv;
  559. -}
  560. -
  561. -#ifdef DBM
  562. -/*
  563. -** Avoid problems of multiple dbminit calls.
  564. -*/
  565. -initdbm(name)
  566. -char *name;
  567. -{
  568. -    static int called = 0;
  569. -
  570. -    if (called != 0)
  571. -        return;
  572. -    called = 1;
  573. -    (void) dbminit(name);
  574. -}
  575. -#endif
  576. -
  577. -#ifndef BSD4_2
  578. -/*
  579. - * move n bytes from a to b
  580. - */
  581. -bcopy(a, b, n)
  582. -register char *a, *b;
  583. -register n;
  584. -{
  585. -    while (--n >= 0)
  586. -        *b++ = *a++;
  587. -}
  588. -#endif
  589. -
  590. -#if !defined(BSD4_2) && !defined(BSD4_1C)
  591. -rename(from,to)
  592. -register char *from, *to;
  593. -{
  594. -    (void) unlink(to);
  595. -    if (link(from, to) < 0)
  596. -        return -1;
  597. -
  598. -    (void) unlink(from);
  599. -    return 0;
  600. -}
  601. -#endif /* !BSD4_2 && ! BSD4_1C */
  602. -
  603. -#ifndef DBM
  604. -/*
  605. -** Generate the appropriate history subfile name
  606. -*/
  607. -char *
  608. -histfile(hline)
  609. -char *hline;
  610. -{
  611. -    char *p;
  612. -    char chr;    /* least significant digit of article number */
  613. -    static char subfile[BUFLEN];
  614. -
  615. -    p = strchr(hline, '@');
  616. -    if (p != NULL && p > hline)
  617. -        chr = *(p - 1);
  618. -    else
  619. -        chr = '0';
  620. -    if (!isdigit(chr))
  621. -        chr = '0';
  622. -    sprintf(subfile, "%s.d/%c", ARTFILE, chr);
  623. -    if (access(subfile, 04) < 0)
  624. -        return(ARTFILE);
  625. -    return(subfile);
  626. -}
  627. -#endif /* !DBM */
  628. -
  629. -#ifdef VMS
  630. -/*
  631. - * These functions open an article with one level of indirection,
  632. - * to support symbolic links. xart_open exits if the open fails.
  633. - */
  634. -FILE *
  635. -xart_open (filename,mode)
  636. -char *filename,*mode;
  637. -{
  638. -    FILE *fp = art_open (filename, mode);
  639. -    extern int errno;
  640. -    if (fp == NULL)
  641. -        xerror("Cannot open article %s (%s): %s\n",
  642. -             filename, mode, errmsg(errno));
  643. -    return fp;
  644. -}
  645. -
  646. -FILE *
  647. -art_open (filename,mode)
  648. -char *filename,*mode;
  649. -{
  650. -    char linkfile[BUFSIZ];
  651. -    FILE *fp;
  652. -
  653. -    if ((fp = fopen (filename, mode)) == NULL)
  654. -        return NULL;
  655. -    if (fgets (linkfile, BUFSIZ, fp) == NULL || linkfile[0] != '/') {
  656. -        rewind (fp);
  657. -        return fp;
  658. -    }
  659. -/* Chase the symbolic link. */
  660. -    (void) fclose (fp);
  661. -    if ((fp = fopen (linkfile, mode)) == NULL)
  662. -/* Clean up dangling link, if we have the power. Ignore error if we don't. */
  663. -        (void) unlink (filename);
  664. -    return fp;
  665. -}
  666. -#endif /* VMS */
  667. *-*-END-of-src/funcs2.c-*-*
  668. echo x - src/getdate.y 1>&2
  669. sed 's/.//' >src/getdate.y <<'*-*-END-of-src/getdate.y-*-*'
  670. -%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
  671. -%{
  672. -    /*     Steven M. Bellovin (unc!smb)            */
  673. -    /*    Dept. of Computer Science            */
  674. -    /*    University of North Carolina at Chapel Hill    */
  675. -    /*    @(#)getdate.y    2.13    9/16/86 */
  676. -
  677. -#include <sys/types.h>
  678. -#ifdef USG
  679. -struct timeb
  680. -{
  681. -    time_t    time;
  682. -    unsigned short millitm;
  683. -    short    timezone;
  684. -    short    dstflag;
  685. -};
  686. -#else
  687. -#include <sys/timeb.h>
  688. -#endif
  689. -#include <ctype.h>
  690. -
  691. -#include "defs.h"
  692. -#if defined(BSD4_2) || defined (BSD4_1C)
  693. -#include <sys/time.h>
  694. -#else sane
  695. -#include <time.h>
  696. -#endif sane
  697. -
  698. -#define    NULL    0
  699. -#define daysec (24L*60L*60L)
  700. -    static int timeflag, zoneflag, dateflag, dayflag, relflag;
  701. -    static time_t relsec, relmonth;
  702. -    static int hh, mm, ss, merid, daylight;
  703. -    static int dayord, dayreq;
  704. -    static int month, day, year;
  705. -    static int ourzone;
  706. -#define AM 1
  707. -#define PM 2
  708. -#define DAYLIGHT 1
  709. -#define STANDARD 2
  710. -#define MAYBE    3
  711. -%}
  712. -
  713. -%%
  714. -timedate:         /* empty */
  715. -    | timedate item;
  716. -
  717. -item:    tspec =
  718. -        {timeflag++;}
  719. -    | zone =
  720. -        {zoneflag++;}
  721. -    | dtspec =
  722. -        {dateflag++;}
  723. -    | dyspec =
  724. -        {dayflag++;}
  725. -    | rspec =
  726. -        {relflag++;}
  727. -    | nspec;
  728. -
  729. -nspec:    NUMBER =
  730. -        {if (timeflag && dateflag && !relflag) year = $1;
  731. -        else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
  732. -
  733. -tspec:    NUMBER MERIDIAN =
  734. -        {hh = $1; mm = 0; ss = 0; merid = $2;}
  735. -    | NUMBER ':' NUMBER =
  736. -        {hh = $1; mm = $3; merid = 24;}
  737. -    | NUMBER ':' NUMBER MERIDIAN =
  738. -        {hh = $1; mm = $3; merid = $4;}
  739. -    | NUMBER ':' NUMBER NUMBER =
  740. -        {hh = $1; mm = $3; merid = 24;
  741. -        daylight = STANDARD; ourzone = $4%100 + 60*$4/100;}
  742. -    | NUMBER ':' NUMBER ':' NUMBER =
  743. -        {hh = $1; mm = $3; ss = $5; merid = 24;}
  744. -    | NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
  745. -        {hh = $1; mm = $3; ss = $5; merid = $6;}
  746. -    | NUMBER ':' NUMBER ':' NUMBER NUMBER =
  747. -        {hh = $1; mm = $3; ss = $5; merid = 24;
  748. -        daylight = STANDARD; ourzone = $6%100 + 60*$6/100;};
  749. -
  750. -zone:    ZONE =
  751. -        {ourzone = $1; daylight = STANDARD;}
  752. -    | DAYZONE =
  753. -        {ourzone = $1; daylight = DAYLIGHT;};
  754. -
  755. -dyspec:    DAY =
  756. -        {dayord = 1; dayreq = $1;}
  757. -    | DAY ',' =
  758. -        {dayord = 1; dayreq = $1;}
  759. -    | NUMBER DAY =
  760. -        {dayord = $1; dayreq = $2;};
  761. -
  762. -dtspec:    NUMBER '/' NUMBER =
  763. -        {month = $1; day = $3;}
  764. -    | NUMBER '/' NUMBER '/' NUMBER =
  765. -        {month = $1; day = $3; year = $5;}
  766. -    | MONTH NUMBER =
  767. -        {month = $1; day = $2;}
  768. -    | MONTH NUMBER ',' NUMBER =
  769. -        {month = $1; day = $2; year = $4;}
  770. -    | NUMBER MONTH =
  771. -        {month = $2; day = $1;}
  772. -    | NUMBER MONTH NUMBER =
  773. -        {month = $2; day = $1; year = $3;};
  774. -
  775. -
  776. -rspec:    NUMBER UNIT =
  777. -        {relsec +=  60L * $1 * $2;}
  778. -    | NUMBER MUNIT =
  779. -        {relmonth += $1 * $2;}
  780. -    | NUMBER SUNIT =
  781. -        {relsec += $1;}
  782. -    | UNIT =
  783. -        {relsec +=  60L * $1;}
  784. -    | MUNIT =
  785. -        {relmonth += $1;}
  786. -    | SUNIT =
  787. -        {relsec++;}
  788. -    | rspec AGO =
  789. -        {relsec = -relsec; relmonth = -relmonth;};
  790. -%%
  791. -
  792. -static int mdays[12] =
  793. -    {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
  794. -#define epoch 1970
  795. -
  796. -extern struct tm *localtime();
  797. -time_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
  798. -int mm, dd, yy, h, m, s, mer, zone, dayflag;
  799. -{
  800. -    time_t tod, jdate;
  801. -    register int i;
  802. -    time_t timeconv();
  803. -
  804. -    if (yy < 0) yy = -yy;
  805. -    if (yy < 100) yy += 1900;
  806. -    mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
  807. -    if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
  808. -        dd < 1 || dd > mdays[--mm]) return (-1);
  809. -    jdate = dd-1;
  810. -        for (i=0; i<mm; i++) jdate += mdays[i];
  811. -    for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
  812. -    jdate *= daysec;
  813. -    jdate += zone * 60L;
  814. -    if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
  815. -    jdate += tod;
  816. -    if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
  817. -        jdate += -1*60*60;
  818. -    return (jdate);
  819. -}
  820. -
  821. -time_t dayconv(ord, day, now) int ord, day; time_t now;
  822. -{
  823. -    register struct tm *loctime;
  824. -    time_t tod;
  825. -    time_t daylcorr();
  826. -
  827. -    tod = now;
  828. -    loctime = localtime(&tod);
  829. -    tod += daysec * ((day - loctime->tm_wday + 7) % 7);
  830. -    tod += 7*daysec*(ord<=0?ord:ord-1);
  831. -    return daylcorr(tod, now);
  832. -}
  833. -
  834. -time_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
  835. -{
  836. -    if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
  837. -    switch (mer) {
  838. -        case AM: if (hh < 1 || hh > 12) return(-1);
  839. -             return (60L * ((hh%12)*60L + mm)+ss);
  840. -        case PM: if (hh < 1 || hh > 12) return(-1);
  841. -             return (60L * ((hh%12 +12)*60L + mm)+ss);
  842. -        case 24: if (hh < 0 || hh > 23) return (-1);
  843. -             return (60L * (hh*60L + mm)+ss);
  844. -        default: return (-1);
  845. -    }
  846. -}
  847. -time_t monthadd(sdate, relmonth) time_t sdate, relmonth;
  848. -{
  849. -    struct tm *ltime;
  850. -    time_t dateconv();
  851. -    time_t daylcorr();
  852. -    int mm, yy;
  853. -
  854. -    if (relmonth == 0) return 0;
  855. -    ltime = localtime(&sdate);
  856. -    mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
  857. -    yy = mm/12;
  858. -    mm = mm%12 + 1;
  859. -    return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
  860. -        ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
  861. -}
  862. -
  863. -time_t daylcorr(future, now) time_t future, now;
  864. -{
  865. -    int fdayl, nowdayl;
  866. -
  867. -    nowdayl = (localtime(&now)->tm_hour+1) % 24;
  868. -    fdayl = (localtime(&future)->tm_hour+1) % 24;
  869. -    return (future-now) + 60L*60L*(nowdayl-fdayl);
  870. -}
  871. -
  872. -static char *lptr;
  873. -
  874. -yylex()
  875. -{
  876. -    extern int yylval;
  877. -    int sign;
  878. -    register char c;
  879. -    register char *p;
  880. -    char idbuf[20];
  881. -    int pcnt;
  882. -
  883. -    for (;;) {
  884. -        while (isspace(*lptr)) lptr++;
  885. -
  886. -        if (isdigit(c = *lptr) || c == '-' || c == '+') {
  887. -            if (c== '-' || c == '+') {
  888. -                if (c=='-') sign = -1;
  889. -                else sign = 1;
  890. -                if (!isdigit(*++lptr)) {
  891. -                    /* yylval = sign; return (NUMBER); */
  892. -                    return yylex();    /* skip the '-' sign */
  893. -                }
  894. -            } else sign = 1;
  895. -            yylval = 0;
  896. -            while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
  897. -            yylval *= sign;
  898. -            lptr--;
  899. -            return (NUMBER);
  900. -
  901. -        } else if (isalpha(c)) {
  902. -            p = idbuf;
  903. -            while (isalpha(c = *lptr++) || c=='.')
  904. -                *p++ = c;
  905. -            *p = '\0';
  906. -            lptr--;
  907. -            return (lookup(idbuf));
  908. -        }
  909. -
  910. -        else if (c == '(') {
  911. -            pcnt = 0;
  912. -            do {
  913. -                c = *lptr++;
  914. -                if (c == '\0') return(c);
  915. -                else if (c == '(') pcnt++;
  916. -                else if (c == ')') pcnt--;
  917. -            } while (pcnt > 0);
  918. -        }
  919. -
  920. -        else return (*lptr++);
  921. -    }
  922. -}
  923. -
  924. -struct table {
  925. -    char *name;
  926. -    int type, value;
  927. -};
  928. -
  929. -struct table mdtab[] = {
  930. -    {"January", MONTH, 1},
  931. -    {"February", MONTH, 2},
  932. -    {"March", MONTH, 3},
  933. -    {"April", MONTH, 4},
  934. -    {"May", MONTH, 5},
  935. -    {"June", MONTH, 6},
  936. -    {"July", MONTH, 7},
  937. -    {"August", MONTH, 8},
  938. -    {"September", MONTH, 9},
  939. -    {"Sept", MONTH, 9},
  940. -    {"October", MONTH, 10},
  941. -    {"November", MONTH, 11},
  942. -    {"December", MONTH, 12},
  943. -
  944. -    {"Sunday", DAY, 0},
  945. -    {"Monday", DAY, 1},
  946. -    {"Tuesday", DAY, 2},
  947. -    {"Tues", DAY, 2},
  948. -    {"Wednesday", DAY, 3},
  949. -    {"Wednes", DAY, 3},
  950. -    {"Thursday", DAY, 4},
  951. -    {"Thur", DAY, 4},
  952. -    {"Thurs", DAY, 4},
  953. -    {"Friday", DAY, 5},
  954. -    {"Saturday", DAY, 6},
  955. -    {0, 0, 0}};
  956. -
  957. -#define HRS *60
  958. -#define HALFHR 30
  959. -struct table mztab[] = {
  960. -    {"a.m.", MERIDIAN, AM},
  961. -    {"am", MERIDIAN, AM},
  962. -    {"p.m.", MERIDIAN, PM},
  963. -    {"pm", MERIDIAN, PM},
  964. -    {"nst", ZONE, 3 HRS + HALFHR},        /* Newfoundland */
  965. -    {"n.s.t.", ZONE, 3 HRS + HALFHR},
  966. -    {"ast", ZONE, 4 HRS},        /* Atlantic */
  967. -    {"a.s.t.", ZONE, 4 HRS},
  968. -    {"adt", DAYZONE, 4 HRS},
  969. -    {"a.d.t.", DAYZONE, 4 HRS},
  970. -    {"est", ZONE, 5 HRS},        /* Eastern */
  971. -    {"e.s.t.", ZONE, 5 HRS},
  972. -    {"edt", DAYZONE, 5 HRS},
  973. -    {"e.d.t.", DAYZONE, 5 HRS},
  974. -    {"cst", ZONE, 6 HRS},        /* Central */
  975. -    {"c.s.t.", ZONE, 6 HRS},
  976. -    {"cdt", DAYZONE, 6 HRS},
  977. -    {"c.d.t.", DAYZONE, 6 HRS},
  978. -    {"mst", ZONE, 7 HRS},        /* Mountain */
  979. -    {"m.s.t.", ZONE, 7 HRS},
  980. -    {"mdt", DAYZONE, 7 HRS},
  981. -    {"m.d.t.", DAYZONE, 7 HRS},
  982. -    {"pst", ZONE, 8 HRS},        /* Pacific */
  983. -    {"p.s.t.", ZONE, 8 HRS},
  984. -    {"pdt", DAYZONE, 8 HRS},
  985. -    {"p.d.t.", DAYZONE, 8 HRS},
  986. -    {"yst", ZONE, 9 HRS},        /* Yukon */
  987. -    {"y.s.t.", ZONE, 9 HRS},
  988. -    {"ydt", DAYZONE, 9 HRS},
  989. -    {"y.d.t.", DAYZONE, 9 HRS},
  990. -    {"hst", ZONE, 10 HRS},        /* Hawaii */
  991. -    {"h.s.t.", ZONE, 10 HRS},
  992. -    {"hdt", DAYZONE, 10 HRS},
  993. -    {"h.d.t.", DAYZONE, 10 HRS},
  994. -
  995. -    {"gmt", ZONE, 0 HRS},
  996. -    {"g.m.t.", ZONE, 0 HRS},
  997. -    {"bst", DAYZONE, 0 HRS},        /* British Summer Time */
  998. -    {"b.s.t.", DAYZONE, 0 HRS},
  999. -    {"eet", ZONE, 0 HRS},        /* European Eastern Time */
  1000. -    {"e.e.t.", ZONE, 0 HRS},
  1001. -    {"eest", DAYZONE, 0 HRS},    /* European Eastern Summer Time */
  1002. -    {"e.e.s.t.", DAYZONE, 0 HRS},
  1003. -    {"met", ZONE, -1 HRS},        /* Middle European Time */
  1004. -    {"m.e.t.", ZONE, -1 HRS},
  1005. -    {"mest", DAYZONE, -1 HRS},    /* Middle European Summer Time */
  1006. -    {"m.e.s.t.", DAYZONE, -1 HRS},
  1007. -    {"wet", ZONE, -2 HRS },        /* Western European Time */
  1008. -    {"w.e.t.", ZONE, -2 HRS },
  1009. -    {"west", DAYZONE, -2 HRS},    /* Western European Summer Time */
  1010. -    {"w.e.s.t.", DAYZONE, -2 HRS},
  1011. -
  1012. -    {"jst", ZONE, -9 HRS},        /* Japan Standard Time */
  1013. -    {"j.s.t.", ZONE, -9 HRS},    /* Japan Standard Time */
  1014. -                    /* No daylight savings time */
  1015. -
  1016. -    {"aest", ZONE, -10 HRS},    /* Australian Eastern Time */
  1017. -    {"a.e.s.t.", ZONE, -10 HRS},
  1018. -    {"aesst", DAYZONE, -10 HRS},    /* Australian Eastern Summer Time */
  1019. -    {"a.e.s.s.t.", DAYZONE, -10 HRS},
  1020. -    {"acst", ZONE, -(9 HRS + HALFHR)},    /* Australian Central Time */
  1021. -    {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
  1022. -    {"acsst", DAYZONE, -(9 HRS + HALFHR)},    /* Australian Central Summer */
  1023. -    {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
  1024. -    {"awst", ZONE, -8 HRS},        /* Australian Western Time */
  1025. -    {"a.w.s.t.", ZONE, -8 HRS},    /* (no daylight time there, I'm told */
  1026. -    {0, 0, 0}};
  1027. -
  1028. -struct table unittb[] = {
  1029. -    {"year", MUNIT, 12},
  1030. -    {"month", MUNIT, 1},
  1031. -    {"fortnight", UNIT, 14*24*60},
  1032. -    {"week", UNIT, 7*24*60},
  1033. -    {"day", UNIT, 1*24*60},
  1034. -    {"hour", UNIT, 60},
  1035. -    {"minute", UNIT, 1},
  1036. -    {"min", UNIT, 1},
  1037. -    {"second", SUNIT, 1},
  1038. -    {"sec", SUNIT, 1},
  1039. -    {0, 0, 0}};
  1040. -
  1041. -struct table othertb[] = {
  1042. -    {"tomorrow", UNIT, 1*24*60},
  1043. -    {"yesterday", UNIT, -1*24*60},
  1044. -    {"today", UNIT, 0},
  1045. -    {"now", UNIT, 0},
  1046. -    {"last", NUMBER, -1},
  1047. -    {"this", UNIT, 0},
  1048. -    {"next", NUMBER, 2},
  1049. -    {"first", NUMBER, 1},
  1050. -    /* {"second", NUMBER, 2}, */
  1051. -    {"third", NUMBER, 3},
  1052. -    {"fourth", NUMBER, 4},
  1053. -    {"fifth", NUMBER, 5},
  1054. -    {"sixth", NUMBER, 6},
  1055. -    {"seventh", NUMBER, 7},
  1056. -    {"eigth", NUMBER, 8},
  1057. -    {"ninth", NUMBER, 9},
  1058. -    {"tenth", NUMBER, 10},
  1059. -    {"eleventh", NUMBER, 11},
  1060. -    {"twelfth", NUMBER, 12},
  1061. -    {"ago", AGO, 1},
  1062. -    {0, 0, 0}};
  1063. -
  1064. -struct table milzone[] = {
  1065. -    {"a", ZONE, 1 HRS},
  1066. -    {"b", ZONE, 2 HRS},
  1067. -    {"c", ZONE, 3 HRS},
  1068. -    {"d", ZONE, 4 HRS},
  1069. -    {"e", ZONE, 5 HRS},
  1070. -    {"f", ZONE, 6 HRS},
  1071. -    {"g", ZONE, 7 HRS},
  1072. -    {"h", ZONE, 8 HRS},
  1073. -    {"i", ZONE, 9 HRS},
  1074. -    {"k", ZONE, 10 HRS},
  1075. -    {"l", ZONE, 11 HRS},
  1076. -    {"m", ZONE, 12 HRS},
  1077. -    {"n", ZONE, -1 HRS},
  1078. -    {"o", ZONE, -2 HRS},
  1079. -    {"p", ZONE, -3 HRS},
  1080. -    {"q", ZONE, -4 HRS},
  1081. -    {"r", ZONE, -5 HRS},
  1082. -    {"s", ZONE, -6 HRS},
  1083. -    {"t", ZONE, -7 HRS},
  1084. -    {"u", ZONE, -8 HRS},
  1085. -    {"v", ZONE, -9 HRS},
  1086. -    {"w", ZONE, -10 HRS},
  1087. -    {"x", ZONE, -11 HRS},
  1088. -    {"y", ZONE, -12 HRS},
  1089. -    {"z", ZONE, 0 HRS},
  1090. -    {0, 0, 0}};
  1091. -
  1092. -lookup(id) char *id;
  1093. -{
  1094. -#define gotit (yylval=i->value,  i->type)
  1095. -#define getid for(j=idvar, k=id; *j++ = *k++; )
  1096. -
  1097. -    char idvar[20];
  1098. -    register char *j, *k;
  1099. -    register struct table *i;
  1100. -    int abbrev;
  1101. -
  1102. -    getid;
  1103. -    if (strlen(idvar) == 3) abbrev = 1;
  1104. -    else if (strlen(idvar) == 4 && idvar[3] == '.') {
  1105. -        abbrev = 1;
  1106. -        idvar[3] = '\0';
  1107. -    }
  1108. -    else abbrev = 0;
  1109. -
  1110. -    if (islower(*idvar)) *idvar = toupper(*idvar);
  1111. -
  1112. -    for (i = mdtab; i->name; i++) {
  1113. -        k = idvar;
  1114. -        for (j = i->name; *j++ == *k++;) {
  1115. -            if (abbrev && j==i->name+3) return gotit;
  1116. -            if (j[-1] == 0) return gotit;
  1117. -        }
  1118. -    }
  1119. -
  1120. -    getid;
  1121. -    for (i = mztab; i->name; i++)
  1122. -        if (strcmp(i->name, idvar) == 0) return gotit;
  1123. -
  1124. -    for (j = idvar; *j; j++)
  1125. -        if (isupper(*j)) *j = tolower(*j);
  1126. -    for (i=mztab; i->name; i++)
  1127. -        if (strcmp(i->name, idvar) == 0) return gotit;
  1128. -
  1129. -    getid;
  1130. -    for (i=unittb; i->name; i++)
  1131. -        if (strcmp(i->name, idvar) == 0) return gotit;
  1132. -
  1133. -    if (idvar[strlen(idvar)-1] == 's')
  1134. -        idvar[strlen(idvar)-1] = '\0';
  1135. -    for (i=unittb; i->name; i++)
  1136. -        if (strcmp(i->name, idvar) == 0) return gotit;
  1137. -
  1138. -    getid;
  1139. -    for (i = othertb; i->name; i++)
  1140. -        if (strcmp(i->name, idvar) == 0) return gotit;
  1141. -
  1142. -    getid;
  1143. -    if (strlen(idvar) == 1 && isalpha(*idvar)) {
  1144. -        if (isupper(*idvar)) *idvar = tolower(*idvar);
  1145. -        for (i = milzone; i->name; i++)
  1146. -            if (strcmp(i->name, idvar) == 0) return gotit;
  1147. -    }
  1148. -
  1149. -    return(ID);
  1150. -}
  1151. -
  1152. -time_t getdate(p, now) char *p; struct timeb *now;
  1153. -{
  1154. -#define mcheck(f)    if (f>1) err++
  1155. -    time_t monthadd();
  1156. -    int err;
  1157. -    struct tm *lt;
  1158. -    struct timeb ftz;
  1159. -
  1160. -    time_t sdate, tod;
  1161. -
  1162. -    lptr = p;
  1163. -    if (now == ((struct timeb *) NULL)) {
  1164. -        now = &ftz;
  1165. -        ftime(&ftz);
  1166. -    }
  1167. -    lt = localtime(&now->time);
  1168. -    year = lt->tm_year;
  1169. -    month = lt->tm_mon+1;
  1170. -    day = lt->tm_mday;
  1171. -    relsec = 0; relmonth = 0;
  1172. -    timeflag=zoneflag=dateflag=dayflag=relflag=0;
  1173. -    ourzone = now->timezone;
  1174. -    daylight = MAYBE;
  1175. -    hh = mm = ss = 0;
  1176. -    merid = 24;
  1177. -
  1178. -    if (err = yyparse()) return (-1);
  1179. -
  1180. -    mcheck(timeflag);
  1181. -    mcheck(zoneflag);
  1182. -    mcheck(dateflag);
  1183. -    mcheck(dayflag);
  1184. -
  1185. -    if (err) return (-1);
  1186. -    if (dateflag || timeflag || dayflag) {
  1187. -        sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight);
  1188. -        if (sdate < 0) return -1;
  1189. -    }
  1190. -    else {
  1191. -        sdate = now->time;
  1192. -        if (relflag == 0)
  1193. -            sdate -= (lt->tm_sec + lt->tm_min*60 +
  1194. -                lt->tm_hour*(60L*60L));
  1195. -    }
  1196. -
  1197. -    sdate += relsec;
  1198. -    sdate += monthadd(sdate, relmonth);
  1199. -
  1200. -    if (dayflag && !dateflag) {
  1201. -        tod = dayconv(dayord, dayreq, sdate);
  1202. -        sdate += tod;
  1203. -    }
  1204. -
  1205. -    return sdate;
  1206. -}
  1207. -
  1208. -yyerror(s) char *s;
  1209. -{}
  1210. *-*-END-of-src/getdate.y-*-*
  1211. echo x - src/funcs.c 1>&2
  1212. sed 's/.//' >src/funcs.c <<'*-*-END-of-src/funcs.c-*-*'
  1213. -/*
  1214. - * This software is Copyright (c) 1986 by Rick Adams.
  1215. - *
  1216. - * Permission is hereby granted to copy, reproduce, redistribute or
  1217. - * otherwise use this software as long as: there is no monetary
  1218. - * profit gained specifically from the use or reproduction or this
  1219. - * software, it is not sold, rented, traded or otherwise marketed, and
  1220. - * this copyright notice is included prominently in any copy
  1221. - * made.
  1222. - *
  1223. - * The author make no claims as to the fitness or correctness of
  1224. - * this software for any use whatsoever, and it is provided as is. 
  1225. - * Any use of this software is at the user's own risk.
  1226. - *
  1227. - * funcs - functions used by many programs
  1228. - */
  1229. -
  1230. -#ifdef SCCSID
  1231. -static char    *SccsId = "@(#)funcs.c    2.33    10/23/86";
  1232. -#endif /* SCCSID */
  1233. -
  1234. -/*LINTLIBRARY*/
  1235. -
  1236. -#include "params.h"
  1237. -#include <errno.h>
  1238. -#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
  1239. -#include <fcntl.h>
  1240. -#endif /* !v7 */
  1241. -
  1242. -extern char *Progname;
  1243. -
  1244. -/*
  1245. - * News group matching.
  1246. - *
  1247. - * nglist is a list of newsgroups.
  1248. - * sublist is a list of subscriptions.
  1249. - * sublist may have "meta newsgroups" in it.
  1250. - * All fields are NGDELIM separated,
  1251. - * and there is an NGDELIM at the end of each argument.
  1252. - *
  1253. - * Currently implemented glitches:
  1254. - * sublist uses 'all' like shell uses '*', and '.' like shell '/'.
  1255. - * If subscription X matches Y, it also matches Y.anything.
  1256. - */
  1257. -ngmatch(nglist, sublist)
  1258. -register char *nglist, *sublist;
  1259. -{
  1260. -    register char *n, *s;
  1261. -    register int rc;
  1262. -
  1263. -    rc = FALSE;
  1264. -    for (n = nglist; *n != '\0' && rc == FALSE;) {
  1265. -        for (s = sublist; *s != '\0';) {
  1266. -            if (*s != NEGCHAR)
  1267. -                rc = rc || ptrncmp(s, n);
  1268. -            else
  1269. -                rc = rc && !ptrncmp(s+1, n);
  1270. -            while (*s++ != NGDELIM && *s != '\0')
  1271. -                ;
  1272. -        }
  1273. -        while (*n++ != NGDELIM && *n != '\0')
  1274. -            ;
  1275. -    }
  1276. -    return rc;
  1277. -}
  1278. -
  1279. -/*
  1280. - * Compare two newsgroups for equality.
  1281. - * The first one may be a "meta" newsgroup.
  1282. - */
  1283. -ptrncmp(ng1, ng2)
  1284. -register char *ng1, *ng2;
  1285. -{
  1286. -    while (*ng1 != NGDELIM && *ng1 != '\0') {
  1287. -        if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') {
  1288. -            ng1 += 3;
  1289. -            while (*ng2 != NGDELIM && *ng2 != '.' && *ng2 != '\0')
  1290. -                if (ptrncmp(ng1, ng2++))
  1291. -                    return(TRUE);
  1292. -            return ptrncmp(ng1, ng2);
  1293. -        } else if (*ng1++ != *ng2++)
  1294. -            return FALSE;
  1295. -    }
  1296. -    return *ng2 == '.' || *ng2 == NGDELIM || *ng2 == '\0';
  1297. -}
  1298. -
  1299. -/*
  1300. - * Exec the shell.
  1301. - * This version resets uid, gid, and umask.
  1302. - * Called with fsubr(ushell, s, NULL)
  1303. - */
  1304. -/* ARGSUSED */
  1305. -ushell(s, dummy)
  1306. -char *s, *dummy;
  1307. -{
  1308. -    (void) umask(savmask);
  1309. -    (void) setgid(gid);
  1310. -    (void) setuid(uid);
  1311. -    xshell(s);
  1312. -}
  1313. -
  1314. -/*
  1315. - * Exec the shell.
  1316. - */
  1317. -
  1318. -#ifdef lint
  1319. -char    **environ;
  1320. -#else /* !lint */
  1321. -extern char    **environ;
  1322. -#endif /* !lint */
  1323. -
  1324. -xshell(s)
  1325. -char *s;
  1326. -{
  1327. -    char *env[100], **envp;
  1328. -    char a[BUFLEN + 2];
  1329. -    extern char filename[];
  1330. -    /* set $A */
  1331. -    (void) sprintf(a, "A=%s", filename);
  1332. -    env[0] = a;
  1333. -    for (envp = env + 1 ; *environ != NULL && envp < env + 98 ; environ++)
  1334. -        if ((*environ)[0] != 'A' || (*environ)[1] != '=')
  1335. -            *envp++ = *environ;
  1336. -    *envp = NULL;
  1337. -
  1338. -    execle(SHELL, SHELL, "-c", s, (char *)0, env);
  1339. -    xerror("No shell!");
  1340. -}
  1341. -
  1342. -/*
  1343. - * Fork and call a subroutine with two args.
  1344. - * Return pid without waiting.
  1345. - */
  1346. -fsubr(f, s1, s2)
  1347. -int (*f)();
  1348. -char *s1, *s2;
  1349. -{
  1350. -    register int pid;
  1351. -
  1352. -    /* this may NOT be a vfork */
  1353. -    while ((pid = fork()) == -1)
  1354. -        sleep((unsigned)1);
  1355. -    if (pid == 0) {
  1356. -        (*f)(s1, s2);
  1357. -        exit(0);
  1358. -    }
  1359. -    return pid;
  1360. -}
  1361. -
  1362. -/*
  1363. - * Wait on a child process.
  1364. - */
  1365. -fwait(pid)
  1366. -register int pid;
  1367. -{
  1368. -    register int w;
  1369. -    int status;
  1370. -    int (*onhup)(), (*onint)();
  1371. -
  1372. -    onint = signal(SIGINT, SIG_IGN);
  1373. -    onhup = signal(SIGHUP, SIG_IGN);
  1374. -    while ((w = wait(&status)) != pid && w != -1)
  1375. -        ;
  1376. -    if (w == -1)
  1377. -        status = -1;
  1378. -    (void) signal(SIGINT, onint);
  1379. -    (void) signal(SIGHUP, onhup);
  1380. -    return status;
  1381. -}
  1382. -
  1383. -/*
  1384. - * Strip trailing newlines, blanks, and tabs from 's'.
  1385. - * Return TRUE if newline was found, else FALSE.
  1386. - */
  1387. -nstrip(s)
  1388. -register char *s;
  1389. -{
  1390. -    register char *p;
  1391. -    register int rc;
  1392. -
  1393. -    rc = FALSE;
  1394. -    p = s;
  1395. -    while (*p)
  1396. -        if (*p++ == '\n')
  1397. -            rc = TRUE;
  1398. -    while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t'));
  1399. -    *++p = '\0';
  1400. -    return rc;
  1401. -}
  1402. -
  1403. -/*
  1404. - * Local open routine.
  1405. - */
  1406. -FILE *
  1407. -xfopen(name, fmode)
  1408. -register char *name, *fmode;
  1409. -{
  1410. -    register FILE *fp;
  1411. -    char    *fname;
  1412. -    extern int errno;
  1413. -
  1414. -    if ((fp = fopen(name, fmode)) == NULL) {
  1415. -#ifdef IHCC
  1416. -        /*
  1417. -         * IHCC users only see the "filename" that was in trouble,
  1418. -         * not the whole path.  (for security!)
  1419. -         */
  1420. -        fname = rindex(name, '/') + 1;
  1421. -#else
  1422. -        fname = name;
  1423. -#endif
  1424. -        xerror("Cannot open %s (%s): %s", fname, fmode, errmsg(errno));
  1425. -    }
  1426. -    /* kludge for setuid not being honored for root */
  1427. -    if ((uid == 0) && (duid != 0) && ((*fmode == 'a') || (*fmode == 'w')))
  1428. -        (void) chown(name, duid, dgid);
  1429. -    return fp;
  1430. -}
  1431. -
  1432. -char *
  1433. -errmsg(code)
  1434. -int code;
  1435. -{
  1436. -    extern int sys_nerr;
  1437. -    extern char *sys_errlist[];
  1438. -    static char ebuf[6+5+1];
  1439. -
  1440. -    if (code > sys_nerr) {
  1441. -        (void) sprintf(ebuf, "Error %d", code);
  1442. -        return ebuf;
  1443. -    } else
  1444. -        return sys_errlist[code];
  1445. -}
  1446. -
  1447. -prefix(full, pref)
  1448. -register char *full, *pref;
  1449. -{
  1450. -    register char fc, pc;
  1451. -
  1452. -    while ((pc = *pref++) != '\0') {
  1453. -        fc = *full++;
  1454. -        if (isupper(fc))
  1455. -            fc = tolower(fc);
  1456. -        if (isupper(pc))
  1457. -            pc = tolower(pc);
  1458. -        if (fc != pc)
  1459. -            return FALSE;
  1460. -    }
  1461. -    return TRUE;
  1462. -}
  1463. -
  1464. -char *
  1465. -dirname(ngname)
  1466. -char *ngname;
  1467. -{
  1468. -    static char rbuf[BUFLEN];
  1469. -    register char *p;
  1470. -
  1471. -    (void) sprintf(rbuf, "%s/%s", SPOOL, ngname);
  1472. -
  1473. -    for (p=rbuf+strlen(SPOOL); *p; p++)
  1474. -        if (*p == '.')
  1475. -            *p = '/';
  1476. -    return rbuf;
  1477. -}
  1478. -
  1479. -/*
  1480. - * Return TRUE iff ngname is a valid newsgroup name
  1481. - */
  1482. -validng(ngname)
  1483. -char *ngname;
  1484. -{
  1485. -    register FILE *fp;
  1486. -    register char *p, *q;
  1487. -    char abuf[BUFLEN];
  1488. -
  1489. -    fp = xfopen(ACTIVE, "r");
  1490. -    while(fgets(abuf, BUFLEN, fp) != NULL) {
  1491. -        p = abuf;
  1492. -        q = ngname;
  1493. -        while (*p++ == *q++)
  1494. -            ;
  1495. -        if (*--q == '\0' && *--p == ' ') {
  1496. -            (void) fclose(fp);
  1497. -            return TRUE;
  1498. -        }
  1499. -    }
  1500. -    (void) fclose(fp);
  1501. -    return FALSE;
  1502. -}
  1503. -
  1504. -/* VARARGS1 */
  1505. -xerror(message, arg1, arg2, arg3)
  1506. -char *message;
  1507. -long arg1, arg2, arg3;
  1508. -{
  1509. -    char buffer[LBUFLEN];
  1510. -
  1511. -    fflush(stdout);
  1512. -    (void) sprintf(buffer, message, arg1, arg2, arg3);
  1513. -    logerr(buffer);
  1514. -    xxit(1);
  1515. -}
  1516. -
  1517. -/* VARARGS1 */
  1518. -log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  1519. -char *fmt;
  1520. -long a1, a2, a3, a4, a5, a6, a7, a8, a9;
  1521. -{
  1522. -    _dolog(0, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  1523. -}
  1524. -
  1525. -/* VARARGS1 */
  1526. -logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  1527. -char *fmt;
  1528. -long a1, a2, a3, a4, a5, a6, a7, a8, a9;
  1529. -{
  1530. -    _dolog(1, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  1531. -}
  1532. -
  1533. -char *lfsuffix[] = {
  1534. -    "log",
  1535. -    "errlog",
  1536. -    0
  1537. -};
  1538. -
  1539. -/*
  1540. - * Log the given message, with printf strings and parameters allowed,
  1541. - * on the log file, if it can be written.  The date and an attempt at
  1542. - * figuring out the remote system name are also logged.
  1543. - */
  1544. -/* VARARGS1 */
  1545. -_dolog(which, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  1546. -char *fmt;
  1547. -long a1, a2, a3, a4, a5, a6, a7, a8, a9;
  1548. -{
  1549. -    FILE *logfile;
  1550. -    register char *p, *logtime;
  1551. -    int i;
  1552. -    char logfname[BUFLEN];        /* the log file */
  1553. -    char rmtsys[BUFLEN];
  1554. -    char msg[LBUFLEN];
  1555. -    time_t t;
  1556. -
  1557. -    (void) strcpy(rmtsys, header.path);
  1558. -    p = index(rmtsys, '!');
  1559. -    if (p == NULL)
  1560. -        p = index(rmtsys, ':');
  1561. -    if (p)
  1562. -        *p = 0;
  1563. -    else {
  1564. -        p = rindex(rmtsys, '@');
  1565. -        if (p)
  1566. -            (void) strcpy(rmtsys, p+1);
  1567. -        else
  1568. -            (void) strcpy(rmtsys, "local");
  1569. -    }
  1570. -
  1571. -    (void) time(&t);
  1572. -    logtime = ctime(&t);
  1573. -    logtime[16] = 0;
  1574. -    logtime += 4;
  1575. -
  1576. -
  1577. -    (void) sprintf(msg, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
  1578. -
  1579. -    if (which)
  1580. -        fprintf(stderr,"%s: %s\n", Progname, msg);
  1581. -
  1582. -    for (i=0; i<=which;i++) {
  1583. -        (void) sprintf(logfname, "%s/%s", LIB, lfsuffix[i]);
  1584. -
  1585. -        if (access(logfname, 0) == 0 && (logfile = fopen(logfname, "a")) != NULL) {
  1586. -#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C)
  1587. -            int flags;
  1588. -            flags = fcntl(fileno(logfile), F_GETFL, 0);
  1589. -            (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND);
  1590. -#else /* v7 */
  1591. -            (void) lseek(fileno(logfile), 0L, 2);
  1592. -#endif /* v7 */
  1593. -            if (i)
  1594. -                fprintf(logfile, "%s\t%s\t%s: %s\n", logtime,
  1595. -                    header.ident[0] ? header.ident : username, Progname, msg);
  1596. -            else
  1597. -                fprintf(logfile, "%s\t%s\t%s\n", logtime,
  1598. -                    rmtsys, msg);
  1599. -            (void) fclose(logfile);
  1600. -        }
  1601. -    }
  1602. -}
  1603. -#ifdef VMS
  1604. -
  1605. -/*
  1606. - * vmslink allows simulation of file linking under VMS.
  1607. - */
  1608. -vmslink(infile,outfile)
  1609. -char *infile, *outfile;
  1610. -{
  1611. -    FILE *fp;
  1612. -
  1613. -    if (access(outfile,0) == 0) {
  1614. -        errno = EEXIST;
  1615. -        return -1;
  1616. -    }
  1617. -
  1618. -    fp = fopen(outfile, "w");
  1619. -    if (fp == NULL) {
  1620. -        errno = EACCES;
  1621. -        return -1;
  1622. -    }
  1623. -
  1624. -    (void) fprintf(fp, "%s", infile);
  1625. -    (void) fclose(fp);
  1626. -
  1627. -    return 0;
  1628. -}
  1629. -
  1630. -/*
  1631. - * vmsdelete deletes all revisions of a file.  It attempts to
  1632. - * appear as unlink(2) under conventional Unix in other respects.
  1633. - */
  1634. -vmsdelete(file)
  1635. -char *file;
  1636. -{
  1637. -    int i;
  1638. -
  1639. -    i = unlink(file);
  1640. -    if (i != 0)
  1641. -        return i;
  1642. -
  1643. -    i = errno;
  1644. -    while (unlink(file) == 0)
  1645. -        ;
  1646. -    errno = i;
  1647. -
  1648. -    return 0;
  1649. -}
  1650. -
  1651. -/*
  1652. - * Convert a Unix file to a VMS fixed record format file by
  1653. - * executing the 'unixtovms' command.
  1654. - */
  1655. -unixtovms(file)
  1656. -char *file;
  1657. -{
  1658. -    char buf[BUFLEN];
  1659. -    sprintf(buf, "exec /etc/unixtovms %s", file);
  1660. -    return system(buf);
  1661. -}
  1662. -
  1663. -/*
  1664. - * Convert a VMS fixed record format file to a Unix file by
  1665. - * executing the 'vmstounix' command.
  1666. - */
  1667. -vmstounix(file)
  1668. -char *file;
  1669. -{
  1670. -    char buf[BUFLEN];
  1671. -    sprintf(buf,"exec /etc/vmstounix %s", file);
  1672. -    return system(buf);
  1673. -}
  1674. -#endif /* VMS */
  1675. -
  1676. -#if !defined(BSD4_2) && !defined(BSD4_1C)
  1677. -/*
  1678. - * make a directory. Also make sure that the directory is owned
  1679. - * by the right userid
  1680. - */
  1681. -mkdir(path, perm)
  1682. -char *path;
  1683. -int perm;
  1684. -{
  1685. -    int pid, status;
  1686. -
  1687. -    if (pid=vfork()) {
  1688. -        status = fwait(pid);
  1689. -#if defined(USG) && !defined(CHEAP)
  1690. -        if (pid=vfork())
  1691. -            (void) fwait(pid);
  1692. -        else {
  1693. -            setgid(gid);
  1694. -            setuid(uid);
  1695. -            if (chown(path, duid, dgid) == 0)
  1696. -                (void) chmod(path, perm&(~N_UMASK));
  1697. -            _exit(0);
  1698. -        }
  1699. -#endif /* USG && !CHEAP */
  1700. -    } else {
  1701. -        (void) setgid(dgid);
  1702. -        if (setuid(duid) < 0)
  1703. -            (void) umask(0);
  1704. -        else
  1705. -            (void) umask(perm&N_UMASK);
  1706. -        (void) execlp("mkdir", "mkdir", path, (char *)NULL);
  1707. -        perror(path);
  1708. -        _exit(1);
  1709. -    }
  1710. -    return status;
  1711. -}
  1712. -#endif /* !BSD4_2 && ! BSD4_1C */
  1713. -#ifndef USG
  1714. -char *
  1715. -strpbrk(str, chars)
  1716. -register char *str, *chars;
  1717. -{
  1718. -    register char *cp;
  1719. -
  1720. -    do {
  1721. -        cp = chars - 1;
  1722. -        while (*++cp) {
  1723. -            if (*str == *cp)
  1724. -                return str;
  1725. -        }
  1726. -    } while (*str++);
  1727. -    return NULL;
  1728. -}
  1729. -#endif /* !USG */
  1730. -
  1731. -#ifdef FASCIST
  1732. -/*
  1733. - *  This routine checks to see if the posting user is allowed to
  1734. - *  post to the given newsgroup.  If the username is not in the file
  1735. - *  $LIBDIR/authorized then the default in the symbol FASCIST is used.
  1736. - *
  1737. - *  Format of the call:
  1738. - *     fascist(user, newgroups)
  1739. - *
  1740. - *  Returns:
  1741. - *     FALSE, if authorized
  1742. - *     TRUE, if not
  1743. - *
  1744. - *  Format of the file "authorized" is:
  1745. - *    user:allowed groups  
  1746. - *
  1747. - *  Example:
  1748. - *    root:net.all,mod.all
  1749. - *    naughty_person:junk,net.politics
  1750. - *    operator:!net.all,general,test,mod.unix
  1751. - *
  1752. - *  An open environment could have FASCIST set to "all"
  1753. - *  and then individual entries could be made in the authorized file
  1754. - *  to prevent certain individuals from posting to such a wide
  1755. - *  area.
  1756. - *
  1757. - *  Note that a distribution of "all" does NOT mean to allow postings
  1758. - *  only to local groups -- "all" includes "all.all".  
  1759. - *  Use "all,!all.all" to get this behavior
  1760. - *
  1761. - *    Eugene Spafford        spaf@gatech    May 22, 1985
  1762. - */
  1763. -
  1764. -fascist(user, newsgroups)
  1765. -register char *user, *newsgroups;
  1766. -{
  1767. -    FILE *facfd;
  1768. -    char facuser[BUFLEN], facgroups[BUFLEN], factemp[BUFLEN];
  1769. -    register char  *facptr;
  1770. -
  1771. -    /* First, open the necessary file...$LIBDIR/authorized and see if there
  1772. -     * is an entry for this user 
  1773. -     */
  1774. -
  1775. -    (void) strncpy(facgroups, FASCIST, BUFLEN);
  1776. -    sprintf(factemp, "%s/%s", LIBDIR, "authorized");
  1777. -    facfd = fopen(factemp, "r");
  1778. -
  1779. -    if (facfd != NULL) { /* If no such file, we go with the global default */
  1780. -        while (fscanf(facfd, "%[^:]:%s\n", facuser, factemp) != EOF)
  1781. -            if (strncmp(facuser, user, BUFLEN) == 0) {
  1782. -                (void) strcat(facgroups, ",");
  1783. -                (void) strcat(facgroups, factemp);
  1784. -                break;
  1785. -            }
  1786. -        fclose (facfd);
  1787. -    }
  1788. -#ifdef DEBUG
  1789. -    fprintf(stderr, "facgroups = %s\n", facgroups);
  1790. -    fprintf(stderr, "newsgroups = %s\n", newsgroups);
  1791. -#endif DEBUG
  1792. -
  1793. -    /* We step through the newsgroups being posted to and check each against
  1794. -     * the restriction list.  *ALL* posted groups must match the restriction
  1795. -     * list or we don't allow the posting.
  1796. -     */
  1797. -
  1798. -    while (*newsgroups != '\0') {
  1799. -        facptr = factemp;
  1800. -        while (*newsgroups != '\0' && *newsgroups != NGDELIM)
  1801. -            *facptr++ = *newsgroups++;
  1802. -        *facptr = '\0';
  1803. -        if (*newsgroups == NGDELIM)
  1804. -            newsgroups++;
  1805. -
  1806. -#ifdef DEBUG
  1807. -        fprintf(stderr, "Checking newsgroup '%s'\n", factemp);
  1808. -#endif
  1809. -
  1810. -        if (ngmatch(factemp, facgroups) == FALSE)
  1811. -            return TRUE;
  1812. -    }
  1813. -
  1814. -    /* must be okay -- return */
  1815. -#ifdef DEBUG
  1816. -    fprintf (stderr, "Newsgroups approved for this poster.\n");
  1817. -#endif DEBUG
  1818. -    return FALSE;
  1819. -}
  1820. -#endif FASCIST
  1821. *-*-END-of-src/funcs.c-*-*
  1822. echo x - src/checknews.c 1>&2
  1823. sed 's/.//' >src/checknews.c <<'*-*-END-of-src/checknews.c-*-*'
  1824. -/*
  1825. - * This software is Copyright (c) 1986 by Rick Adams.
  1826. - *
  1827. - * Permission is hereby granted to copy, reproduce, redistribute or
  1828. - * otherwise use this software as long as: there is no monetary
  1829. - * profit gained specifically from the use or reproduction or this
  1830. - * software, it is not sold, rented, traded or otherwise marketed, and
  1831. - * this copyright notice is included prominently in any copy
  1832. - * made.
  1833. - *
  1834. - * The author make no claims as to the fitness or correctness of
  1835. - * this software for any use whatsoever, and it is provided as is. 
  1836. - * Any use of this software is at the user's own risk.
  1837. - *
  1838. - * checknews - news checking program
  1839. - */
  1840. -
  1841. -#ifdef SCCSID
  1842. -static char    *SccsId = "@(#)checknews.c    2.25    5/27/86";
  1843. -#endif /* SCCSID */
  1844. -
  1845. -char *Progname = "checknews";        /* used by xerror */
  1846. -
  1847. -#include "params.h"
  1848. -
  1849. -char    bfr[LBUFLEN];            /* general-use scratch area    */
  1850. -char    optbuf[BUFLEN];            /* NEWSOPTS buffer        */
  1851. -int    line = -1, y, e, n, q;
  1852. -int    verbose;            /* For debugging.        */
  1853. -int    nflag;                /* for spec. newsgroup        */
  1854. -char    narggrp[BUFLEN];        /* spec newsgroup        */
  1855. -FILE    *rcfp, *actfp;
  1856. -char    newsrc[BUFLEN],*rcline[LINES],rcbuf[LBUFLEN],*argvrc[LINES];
  1857. -struct hbuf header;
  1858. -char    coptbuf[BUFLEN],datebuf[BUFLEN];
  1859. -int    mode = 1;
  1860. -#ifndef SHELL
  1861. -char    *SHELL;
  1862. -#endif
  1863. -
  1864. -main(argc, argv)
  1865. -int argc;
  1866. -register char **argv;
  1867. -{
  1868. -    register char *ptr;    /* pointer to rest of buffer        */
  1869. -    char *user, *home;
  1870. -    struct passwd *pw;
  1871. -    struct group *gp;
  1872. -    int sflag = 0, optflag = FALSE, space = FALSE;
  1873. -    int i;
  1874. -
  1875. -    y = 0;
  1876. -    n = 0;
  1877. -    e = 0;
  1878. -    q = 0;
  1879. -    nflag = 0;
  1880. -    pathinit();
  1881. -    if (--argc > 0) {
  1882. -        for (argv++; **argv; ++*argv) {
  1883. -            switch(**argv) {
  1884. -            case 'y':
  1885. -                y++;
  1886. -                break;
  1887. -            case 'q':
  1888. -                q++;
  1889. -                break;
  1890. -            case 'v':
  1891. -                verbose++;
  1892. -                break;
  1893. -            case 'n':
  1894. -                n++;
  1895. -                break;
  1896. -            case 'N':
  1897. -                nflag++;
  1898. -                strcpy(narggrp,argv[1]);
  1899. -                strcat(narggrp,",");
  1900. -                break;
  1901. -            case 'e':
  1902. -            case 'f':
  1903. -                e++;
  1904. -                break;
  1905. -            }
  1906. -        }
  1907. -    }
  1908. -    if (!n && !e && !y && !q)
  1909. -        y++;
  1910. -    if (nflag)
  1911. -        argv++;
  1912. -
  1913. -#ifndef V6
  1914. -    if ((user = getenv("USER")) == NULL)
  1915. -        user = getenv("LOGNAME");
  1916. -    if ((home = getenv("HOME")) == NULL)
  1917. -        home = getenv("LOGDIR");
  1918. -    if (user == NULL || home == NULL)
  1919. -        getuser();
  1920. -    else {
  1921. -        username = AllocCpy(user);
  1922. -        userhome = AllocCpy(home);
  1923. -    }
  1924. -    if (ptr = getenv("NEWSOPTS"))
  1925. -        strcpy(rcbuf, ptr);
  1926. -    else
  1927. -        *rcbuf = '\0';
  1928. -    if (*rcbuf) {
  1929. -        strcat(rcbuf, " \1");
  1930. -        ptr = rcbuf;
  1931. -        while (*++ptr)
  1932. -            if (isspace(*ptr))
  1933. -                *ptr = '\0';
  1934. -        for (ptr = rcbuf;; ptr++) {
  1935. -            if (!*ptr)
  1936. -                continue;
  1937. -            if (*ptr == '\1')
  1938. -                break;
  1939. -            if (++line > LINES)
  1940. -                xerror("Too many options.");
  1941. -            if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL)
  1942. -                xerror("Not enough memory.");
  1943. -            argvrc[line] = rcline[line];
  1944. -            strcpy(rcline[line], ptr);
  1945. -            while (*ptr)
  1946. -                ptr++;
  1947. -        }
  1948. -    }
  1949. -#else
  1950. -    getuser();
  1951. -#endif
  1952. -    ptr = getenv("NEWSRC");
  1953. -    if (ptr == NULL)
  1954. -        sprintf(newsrc, "%s/%s", userhome, NEWSRC);
  1955. -    else
  1956. -        strcpy(newsrc, ptr);
  1957. -    if ((rcfp = fopen(newsrc, "r")) != NULL) {
  1958. -        while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
  1959. -            if (!(space = isspace(*rcbuf)))
  1960. -                optflag = FALSE;
  1961. -            if (!strncmp(rcbuf, "options ", 8))
  1962. -                optflag = TRUE;
  1963. -            if (optflag) {
  1964. -                strcat(rcbuf, "\1");
  1965. -                if (space)
  1966. -                    ptr = rcbuf - 1;
  1967. -                else
  1968. -                    ptr = &rcbuf[7];
  1969. -                while (*++ptr)
  1970. -                    if (isspace(*ptr))
  1971. -                        *ptr = '\0';
  1972. -                if (space)
  1973. -                    ptr = rcbuf;
  1974. -                else
  1975. -                    ptr = &rcbuf[8];
  1976. -                for (;; ptr++) {
  1977. -                    if (!*ptr)
  1978. -                        continue;
  1979. -                    if (*ptr == '\1')
  1980. -                        break;
  1981. -                    if (++line > LINES)
  1982. -                        xerror("Too many options.");
  1983. -                    if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL)
  1984. -                        xerror("Not enough memory.");
  1985. -                    argvrc[line] = rcline[line];
  1986. -                    strcpy(rcline[line], ptr);
  1987. -                    while (*ptr)
  1988. -                        ptr++;
  1989. -                }
  1990. -            }
  1991. -        }
  1992. -        fclose(rcfp);
  1993. -    }
  1994. -    header.nbuf[0] = 0;
  1995. -    if (line != -1) {
  1996. -#ifdef DEBUG
  1997. -        for (i = 0; i <= line; i++)
  1998. -            fprintf(stderr, "options:  %s\n", rcline[i]);
  1999. -#endif
  2000. -        process(line+2, argvrc);
  2001. -        do {
  2002. -#ifdef DEBUG
  2003. -            fprintf(stderr, "Freeing %d\n", line);
  2004. -#endif
  2005. -            free(rcline[line]);
  2006. -        } while (line--);
  2007. -    }
  2008. -
  2009. -    if (!*header.nbuf) {
  2010. -        strcpy(header.nbuf, DFLTSUB);
  2011. -        ngcat(header.nbuf);
  2012. -    }
  2013. -    strcat(header.nbuf, ADMSUB);
  2014. -    ngcat(header.nbuf);
  2015. -    if (*header.nbuf)
  2016. -        lcase(header.nbuf);
  2017. -    makehimask(header.nbuf, "junk");
  2018. -    makehimask(header.nbuf, "control");
  2019. -    makehimask(header.nbuf, "test");
  2020. -    if (access(newsrc, 0)) {
  2021. -        if (verbose > 1)
  2022. -            printf("No newsrc\n");
  2023. -        yep(argv);
  2024. -    }
  2025. -    if ((rcfp = fopen(newsrc, "r")) == NULL)
  2026. -        xerror("Cannot open .newsrc file");
  2027. -    while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
  2028. -        if (!nstrip(rcbuf))
  2029. -            xerror(".newsrc line too long");
  2030. -        if (++line >= LINES)
  2031. -            xerror("Too many .newsrc lines");
  2032. -        if ((rcline[line] = malloc(strlen(rcbuf)+1)) == NULL)
  2033. -            xerror("Not enough memory");
  2034. -        strcpy(rcline[line], rcbuf);
  2035. -    }
  2036. -    if ((actfp = fopen(ACTIVE, "r")) == NULL)
  2037. -        xerror("Cannot open active newsgroups file");
  2038. -
  2039. -#ifdef DEBUG
  2040. -    fprintf(stderr, "header.nbuf = %s\n", header.nbuf);
  2041. -#endif
  2042. -    nchk(argv);
  2043. -    exit(0);
  2044. -}
  2045. -
  2046. -nchk(argv)
  2047. -char **argv;
  2048. -{
  2049. -    register int i;
  2050. -    register char *ptr;
  2051. -    long l;
  2052. -    long narts;
  2053. -    char saveptr;
  2054. -    int isnews = 0;
  2055. -    char aline[BUFLEN];
  2056. -
  2057. -#ifdef DEBUG
  2058. -    fprintf(stderr, "nchk()\n");
  2059. -#endif
  2060. -    while (fgets(aline, sizeof aline, actfp) != NULL) {
  2061. -        sscanf(aline, "%s %ld", bfr, &narts);
  2062. -#ifdef DEBUG
  2063. -        fprintf(stderr, "bfr = '%s'\n", bfr);
  2064. -#endif
  2065. -        ngcat(bfr);
  2066. -        if (!ngmatch(bfr, nflag ? narggrp : header.nbuf))
  2067. -            continue;
  2068. -        ngdel(bfr);
  2069. -        i = findrcline(bfr);
  2070. -        if (i < 0) {
  2071. -            if (verbose>1)
  2072. -                printf("No newsrc line for newsgroup %s\n", bfr);
  2073. -            strcpy(rcbuf, " 0");
  2074. -        } else
  2075. -            strcpy(rcbuf, rcline[i]);
  2076. -        ptr = rcbuf;
  2077. -
  2078. -        if (index(rcbuf, '!') != NULL)
  2079. -            continue;
  2080. -        if (index(rcbuf, ',') != NULL) {
  2081. -            if (verbose > 1)
  2082. -                printf("Comma in %s newsrc line\n", bfr);
  2083. -            else {
  2084. -                isnews++;
  2085. -                continue;
  2086. -            }
  2087. -        }
  2088. -        while (*ptr)
  2089. -            ptr++;
  2090. -        while (!isdigit(*--ptr) && *ptr != ':' && ptr >= rcbuf)
  2091. -            ;
  2092. -        if (*ptr == ':')
  2093. -            continue;
  2094. -        if (ptr < rcbuf) {
  2095. -            if (verbose > 1)
  2096. -                printf("Ran off beginning of %s newsrc line.\n", bfr);
  2097. -            yep(argv);
  2098. -        }
  2099. -        while (isdigit(*--ptr))
  2100. -            ;
  2101. -        sscanf(++ptr, "%ld", &l);
  2102. -        if (narts > l) {
  2103. -            if (verbose) {
  2104. -                printf("News: %s ...\n", bfr);
  2105. -                if (verbose < 2)
  2106. -                    y = 0;
  2107. -            }
  2108. -            yep(argv);
  2109. -        }
  2110. -contin:;
  2111. -    }
  2112. -    if (isnews)
  2113. -        yep(argv);
  2114. -    if (n)
  2115. -        printf("No news is good news.\n");
  2116. -}
  2117. -
  2118. -yep(argv)
  2119. -char **argv;
  2120. -{
  2121. -    if (y) {
  2122. -        if (verbose)
  2123. -            printf("There is probably news");
  2124. -        else
  2125. -            printf("There is news");
  2126. -        if (nflag) {
  2127. -            narggrp[strlen(narggrp)-1] = '.';
  2128. -            printf(" in %s\n",narggrp);
  2129. -        }
  2130. -        else
  2131. -            printf(".\n");
  2132. -    }
  2133. -    if (e) {
  2134. -#ifdef V6
  2135. -        execv("/usr/bin/readnews", argv);
  2136. -#else
  2137. -        execvp("readnews", argv);
  2138. -#endif
  2139. -        perror("Cannot exec readnews.");
  2140. -    }
  2141. -    if (q)
  2142. -        exit(1);
  2143. -    else
  2144. -        exit(0);
  2145. -}
  2146. -
  2147. -xerror(message, arg1, arg2)
  2148. -char *message;
  2149. -int arg1, arg2;
  2150. -{
  2151. -    char buffer[128];
  2152. -
  2153. -    sprintf(buffer, message, arg1, arg2);
  2154. -    fprintf(stderr, "checknews: %s.\n", buffer);
  2155. -    exit(1);
  2156. -}
  2157. -
  2158. -/*
  2159. - * Append NGDELIM to string.
  2160. - */
  2161. -ngcat(s)
  2162. -register char *s;
  2163. -{
  2164. -    if (*s) {
  2165. -        while (*s++);
  2166. -        s -= 2;
  2167. -        if (*s++ == NGDELIM)
  2168. -            return;
  2169. -    }
  2170. -    *s++ = NGDELIM;
  2171. -    *s = '\0';
  2172. -}
  2173. -
  2174. -/*
  2175. - * News group matching.
  2176. - *
  2177. - * nglist is a list of newsgroups.
  2178. - * sublist is a list of subscriptions.
  2179. - * sublist may have "meta newsgroups" in it.
  2180. - * All fields are NGDELIM separated,
  2181. - * and there is an NGDELIM at the end of each argument.
  2182. - *
  2183. - * Currently implemented glitches:
  2184. - * sublist uses 'all' like shell uses '*', and '.' like shell '/'.
  2185. - * If subscription X matches Y, it also matches Y.anything.
  2186. - */
  2187. -ngmatch(nglist, sublist)
  2188. -register char *nglist, *sublist;
  2189. -{
  2190. -    register char *n, *s;
  2191. -    register int rc;
  2192. -
  2193. -    rc = FALSE;
  2194. -    for (n = nglist; *n != '\0' && rc == FALSE;) {
  2195. -        for (s = sublist; *s != '\0';) {
  2196. -            if (*s != NEGCHAR)
  2197. -                rc |= ptrncmp(s, n);
  2198. -            else
  2199. -                rc &= ~ptrncmp(s+1, n);
  2200. -            while (*s++ != NGDELIM);
  2201. -        }
  2202. -        while (*n++ != NGDELIM);
  2203. -    }
  2204. -    return(rc);
  2205. -}
  2206. -
  2207. -/*
  2208. - * Compare two newsgroups for equality.
  2209. - * The first one may be a "meta" newsgroup.
  2210. - */
  2211. -ptrncmp(ng1, ng2)
  2212. -register char *ng1, *ng2;
  2213. -{
  2214. -    while (*ng1 != NGDELIM) {
  2215. -        if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') {
  2216. -            ng1 += 3;
  2217. -            while (*ng2 != NGDELIM && *ng2 != '.')
  2218. -                if (ptrncmp(ng1, ng2++))
  2219. -                    return(TRUE);
  2220. -            return (ptrncmp(ng1, ng2));
  2221. -        } else if (*ng1++ != *ng2++)
  2222. -            return(FALSE);
  2223. -    }
  2224. -    return (*ng2 == '.' || *ng2 == NGDELIM);
  2225. -}
  2226. -
  2227. -/*
  2228. - * Get user name and home directory.
  2229. - */
  2230. -getuser()
  2231. -{
  2232. -    static int flag = TRUE;
  2233. -    register struct passwd *p;
  2234. -
  2235. -    if (flag) {
  2236. -        if ((p = getpwuid(getuid())) == NULL)
  2237. -            xerror("Cannot get user's name");
  2238. -        if (username == NULL || *username == '\0')
  2239. -            username = AllocCpy(p->pw_name);
  2240. -        userhome = AllocCpy(p->pw_dir);
  2241. -        flag = FALSE;
  2242. -    }
  2243. -}
  2244. -
  2245. -/*
  2246. - * Strip trailing newlines, blanks, and tabs from 's'.
  2247. - * Return TRUE if newline was found, else FALSE.
  2248. - */
  2249. -nstrip(s)
  2250. -register char *s;
  2251. -{
  2252. -    register char *p;
  2253. -    register int rc;
  2254. -
  2255. -    rc = FALSE;
  2256. -    p = s;
  2257. -    while (*p)
  2258. -        if (*p++ == '\n')
  2259. -            rc = TRUE;
  2260. -    while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t'));
  2261. -    *++p = '\0';
  2262. -    return(rc);
  2263. -}
  2264. -
  2265. -/*
  2266. - * Delete trailing NGDELIM.
  2267. - */
  2268. -ngdel(s)
  2269. -register char *s;
  2270. -{
  2271. -    if (*s++) {
  2272. -        while (*s++);
  2273. -        s -= 2;
  2274. -        if (*s == NGDELIM)
  2275. -            *s = '\0';
  2276. -    }
  2277. -}
  2278. -
  2279. -lcase(s)
  2280. -register char *s;
  2281. -{
  2282. -    register char *ptr;
  2283. -
  2284. -    for (ptr = s; *ptr; ptr++)
  2285. -        if (isupper(*ptr))
  2286. -            *ptr = tolower(*ptr);
  2287. -}
  2288. -
  2289. -/*
  2290. - * finds the line in your .newsrc file (actually the in-core "rcline"
  2291. - * copy of it) and returns the index into the array where it was found.
  2292. - * -1 means it didn't find it.
  2293. - *
  2294. - * We play clever games here to make this faster.  It's inherently
  2295. - * quadratic - we spend lots of CPU time here because we search through
  2296. - * the whole .newsrc for each line.  The "prev" variable remembers where
  2297. - * the last match was found; we start the search there and loop around
  2298. - * to the beginning, in the hopes that the calls will be roughly in order.
  2299. - */
  2300. -int
  2301. -findrcline(name)
  2302. -char *name;
  2303. -{
  2304. -    register char *p, *ptr;
  2305. -    register int cur;
  2306. -    register int i;
  2307. -    register int top;
  2308. -    static int prev = 0;
  2309. -
  2310. -    top = line; i = prev;
  2311. -loop:
  2312. -    for (; i <= top; i++) {
  2313. -        for (p = name, ptr = rcline[i]; (cur = *p++); ) {
  2314. -            if (cur != *ptr++)
  2315. -                goto contin2;
  2316. -        }
  2317. -        if (*ptr != ':' && *ptr != '!')
  2318. -            continue;
  2319. -        prev = i;
  2320. -        return i;
  2321. -contin2:
  2322. -        ;
  2323. -    }
  2324. -    if (i > line && line > prev-1) {
  2325. -        i = 0;
  2326. -        top = prev-1;
  2327. -        goto loop;
  2328. -    }
  2329. -    return -1;
  2330. -}
  2331. -
  2332. -/*
  2333. - * Forbid newsgroup ng, unless he asked for it in nbuf.
  2334. - */
  2335. -makehimask(nbuf, ng)
  2336. -char *nbuf, *ng;
  2337. -{
  2338. -    if (!findex(nbuf, ng)) {
  2339. -        ngcat(nbuf);
  2340. -        strcat(nbuf, "!");
  2341. -        strcat(nbuf, ng);
  2342. -        ngcat(nbuf);
  2343. -    }
  2344. -}
  2345. -
  2346. -/*
  2347. - * Return true if the string searchfor is in string, but not if preceded by !.
  2348. - */
  2349. -findex(string, searchfor)
  2350. -char *string, *searchfor;
  2351. -{
  2352. -    register char first;
  2353. -    register char *p;
  2354. -
  2355. -    first = *searchfor;
  2356. -    for (p=index(string, first); p; p = index(p+1, first)) {
  2357. -        if (p>string && p[-1] != '!' && strncmp(p, searchfor, strlen(searchfor)) == 0)
  2358. -            return TRUE;
  2359. -    }
  2360. -    return FALSE;
  2361. -}
  2362. -
  2363. -xxit(i)
  2364. -{
  2365. -    exit(i);
  2366. -}
  2367. *-*-END-of-src/checknews.c-*-*
  2368. echo x - src/recnews.c 1>&2
  2369. sed 's/.//' >src/recnews.c <<'*-*-END-of-src/recnews.c-*-*'
  2370. -/*
  2371. - * recnews [to newsgroup] [from user]
  2372. - *
  2373. - * Process a news article which has been mailed to some group like msgs.
  2374. - * Such articles are in normal mail format and have never seen the insides
  2375. - * of netnews.  If the "to newsgroup" is included, the article is posted
  2376. - * to this newsgroup instead of trying to intuit it from the headers.
  2377. - * If the "from user" is included, the return address is forged to look
  2378. - * like that user instead of what getuid or a from line says.
  2379. - *
  2380. - * It is recommended that you always include the to newsgroup, since the
  2381. - * intuition code is flakey and out of date.  The from user is probably
  2382. - * appropriate for arpanet mailing lists being funnelled at ucbvax but
  2383. - * not otherwise.  Sample lines in /usr/lib/aliases (if you run delivermail):
  2384. - *    worldnews: "|/usr/lib/news/recnews net.general"
  2385. - *        Allows you to mail to worldnews rather than using inews.
  2386. - *        Intended for humans to mail to.
  2387. - *    post-unix-wizards: "|/usr/lib/news/recnews fa.unix-wizards unix-wizards"
  2388. - *        Causes mail to post-unix-wizards to be fed into fa.unix-wizards
  2389. - *        and the return address forged as unix-wizards on the local
  2390. - *        machine.  post-unix-wizards (on the local machine) should
  2391. - *        be part of the master mailing list somewhere (on a different
  2392. - *        machine.)
  2393. - *
  2394. - * Recnews is primarily useful in remote places on the usenet which collect
  2395. - * mail from mailing lists and funnel them into the network.  It is also
  2396. - * useful if you like to send mail to some user instead of invoking
  2397. - * inews -t .. -n .. when you want to submit an article.  (Many mailers give
  2398. - * you nice facilities like editing the message.)  It is not, however,
  2399. - * essential to use recnews to be able to join usenet.
  2400. - *
  2401. - * WARNING: recnews disables the "recording" check - it has to because
  2402. - * by the time inews is run, it's in the background and too late to
  2403. - * ask permission.  If you depend heavily on recordings you probably
  2404. - * should not allow recnews (and thus the mail interface) to be used.
  2405. -*
  2406. - * 1) We leave the from line alone.  Just escape the double quotes, but let the
  2407. - *    mailer do the rest.
  2408. - * 2) We give precedence to "From:" over "From " or ">From " in determining
  2409. - *    who the article is really from.
  2410. - *    Modifications by rad@tek
  2411. - */
  2412. -
  2413. -#ifdef SCCSID
  2414. -static char    *SccsId = "@(#)recnews.c    2.13    10/23/86";
  2415. -#endif /* SCCSID */
  2416. -
  2417. -#include "defs.h"
  2418. -
  2419. -#include <stdio.h>
  2420. -#include <ctype.h>
  2421. -
  2422. -/*
  2423. - * Note: we assume there are 2 kinds of hosts using recnews:
  2424. - * Those that have delivermail (and hence this program will never
  2425. - * have to deal with more than one message at a time) and those on the arpanet
  2426. - * that do not (and hence all messages end with a sentinel).  It is
  2427. - * supposed that regular v7 type systems without delivermail or some
  2428. - * other automatic forwarding device will just use rnews.  We do
  2429. - * not attempt to tell where a message ends on all systems due to the
  2430. - * different conventions in effect.  (This COULD be fixed, I suppose.)
  2431. - */
  2432. -
  2433. -/*
  2434. - * Kinds of lines in a message.
  2435. - */
  2436. -#define FROM    001        /* From line */
  2437. -#define SUBJ    002        /* Subject */
  2438. -#define TO    003        /* To (newgroup based on this) */
  2439. -#define BLANK    004        /* blank line */
  2440. -#define EOM    005        /* End of message (4 ctrl A's) */
  2441. -#define HEADER    006        /* any unrecognized header */
  2442. -#define TEXT    007        /* anything unrecognized */
  2443. -#define INCLUSIVE 010        /* newsgroup is already in header */
  2444. -
  2445. -/*
  2446. - * Possible states program can be in.
  2447. - */
  2448. -#define SKIPPING    0100    /* In header of message */
  2449. -#define READING        0200    /* In body of message */
  2450. -
  2451. -#define BFSZ 250
  2452. -
  2453. -#define EOT    '\004'
  2454. -
  2455. -char    from[BFSZ];        /* mailing address for replies */
  2456. -char    sender[BFSZ];        /* mailing address of author, if different */
  2457. -char    to[BFSZ];        /* Destination of mail (msgs, etc) */
  2458. -char    subject[BFSZ];        /* subject of message */
  2459. -char    newsgroup[BFSZ];    /* newsgroups of message */
  2460. -int    fromset;        /* from passed on command line */
  2461. -char    cmdbuf[BFSZ];        /* command to popen */
  2462. -
  2463. -extern    char    *strcat(), *strcpy();
  2464. -extern    FILE    *popen();
  2465. -char    *any();
  2466. -
  2467. -main(argc, argv)
  2468. -int argc;
  2469. -char **argv;
  2470. -{
  2471. -    char buf[BFSZ], inews[BFSZ];
  2472. -    register char *p, *q;
  2473. -    register FILE *pipe = NULL;
  2474. -    register int state;
  2475. -
  2476. -    /* build inews command */
  2477. -#ifdef IHCC
  2478. -    sprintf(inews, "%s/%s/%s", logdir(HOME), LIBDIR, "inews");
  2479. -#else
  2480. -    sprintf(inews, "%s/%s", LIBDIR, "inews");
  2481. -#endif
  2482. -
  2483. -    if (argc > 1)
  2484. -        strcpy(to, argv[1]);
  2485. -    if (argc > 2)
  2486. -        strcpy(from, argv[2]);
  2487. -
  2488. -    /*
  2489. -     * Flag that we know who message is from to avoid trying to 
  2490. -     * decipher the From line.
  2491. -     */
  2492. -    if (argc > 2 && (argv[2][0] != '\0'))
  2493. -        fromset++;
  2494. -
  2495. -#ifdef debug
  2496. -    printf("argv[0] is <%s>, argv[1] is <%s>, argv[2] is <%s>\n",
  2497. -        argv[0], argv[1], argv[2]);
  2498. -#endif
  2499. -    state = SKIPPING;
  2500. -    while (fgets(buf, BFSZ, stdin) != NULL) {
  2501. -        if (state == READING) {
  2502. -            fputs(buf,pipe);
  2503. -            continue;
  2504. -        }
  2505. -        switch (type(buf)) {
  2506. -
  2507. -        case FROM:
  2508. -            frombreak(buf, from);
  2509. -            break;
  2510. -
  2511. -        case SUBJ:
  2512. -            p = any(buf, " \t");
  2513. -            if (p == NULL)
  2514. -                p = buf + 8;
  2515. -            q = subject;
  2516. -            while (*++p) {
  2517. -                if (*p == '"')
  2518. -                    *q++ = '\\';
  2519. -                *q++ = *p;
  2520. -            }
  2521. -            q[-1] = '\0';
  2522. -            break;
  2523. -
  2524. -        case TO:
  2525. -            if (to[0])
  2526. -                break;        /* already have one */
  2527. -            p = any(buf, " \t");
  2528. -            if (p == NULL)
  2529. -                p = buf + 3;
  2530. -            q = to;
  2531. -            while (*++p) {
  2532. -                if (*p == '"')
  2533. -                    *q++ = '\\';
  2534. -                *q++ = *p;
  2535. -            }
  2536. -            q[-1] = '\0';
  2537. -            break;
  2538. -
  2539. -        case INCLUSIVE:
  2540. -            sprintf(cmdbuf,"exec %s -p", inews);
  2541. -            pipe = popen(cmdbuf,"w");
  2542. -            if (pipe == NULL){
  2543. -                perror("recnews: open failed");
  2544. -                exit(1);
  2545. -            }
  2546. -            state = READING;
  2547. -            fputs(buf,pipe);
  2548. -            break;
  2549. -            
  2550. -        /*
  2551. -         * Kludge to compensate for messages without real headers
  2552. -         */
  2553. -        case HEADER:
  2554. -            break;
  2555. -
  2556. -        case BLANK:
  2557. -            state = READING;
  2558. -            strcpy(newsgroup, to);
  2559. -            sprintf(cmdbuf, "exec %s -t \"%s\" -n \"%s\" -f \"%s\"",
  2560. -                inews, *subject ? subject : "(none)",
  2561. -                newsgroup, from);
  2562. -#ifdef debug
  2563. -            pipe = stdout;
  2564. -            printf("BLANK: %s\n", cmdbuf);
  2565. -#else
  2566. -            pipe = popen(cmdbuf, "w");
  2567. -            if (pipe == NULL) {
  2568. -                perror("recnews: popen failed");
  2569. -                exit(1);
  2570. -            }
  2571. -#endif
  2572. -            if (sender[0]) {
  2573. -                fputs(sender, pipe);
  2574. -                putc('\n', pipe);
  2575. -            }
  2576. -            break;
  2577. -
  2578. -        case TEXT:
  2579. -            strcpy(newsgroup, to);
  2580. -            state = READING;
  2581. -            if (subject[0] == 0) {
  2582. -                strcpy(subject, buf);
  2583. -                if (subject[strlen(subject)-1] == '\n')
  2584. -                    subject[strlen(subject)-1] = '\0';
  2585. -            }
  2586. -            sprintf(cmdbuf, "exec \"%s\" -t \"%s\" -n \"%s\" -f \"%s\"",
  2587. -                inews, subject, newsgroup, from);
  2588. -#ifdef debug
  2589. -            pipe = stdout;
  2590. -            printf("TEXT: %s\n", cmdbuf);
  2591. -#else
  2592. -            pipe = popen(cmdbuf, "w");
  2593. -            if (pipe == NULL) {
  2594. -                perror("pipe failed");
  2595. -                exit(1);
  2596. -            }
  2597. -#endif
  2598. -            if (sender[0]){
  2599. -                fputs(sender, pipe);
  2600. -                putc('\n',pipe);
  2601. -            }
  2602. -            break;
  2603. -        }
  2604. -    }
  2605. -    exit(0);
  2606. -}
  2607. -
  2608. -type(p)
  2609. -register char *p;
  2610. -{
  2611. -    char *firstbl;
  2612. -    static char lasthdr = 1;        /* prev line was a header */
  2613. -
  2614. -    if ((*p == ' ' || *p == '\t') && lasthdr)
  2615. -        return HEADER;        /* continuation line */
  2616. -    firstbl = any(p, " \t");
  2617. -    while (*p == ' ' || *p == '?' || *p == '\t')
  2618. -        ++p;
  2619. -
  2620. -    if (*p == '\n' || *p == 0)
  2621. -        return BLANK;
  2622. -    if (strncmp(p, ">From", 5) == 0 || strncmp(p, "From", 4) == 0)
  2623. -        return FROM;
  2624. -    if (strncmp(p, "Subj", 4)==0 || strncmp(p, "Re:", 3)==0 ||
  2625. -        strncmp(p, "re:", 3)==0)
  2626. -        return SUBJ;
  2627. -    if (strncmp(p, "To", 2)==0)
  2628. -        return TO;
  2629. -    if (strncmp(p, "\1\1\1\1", 4)==0)
  2630. -        return EOM;
  2631. -    if (firstbl && firstbl[-1] == ':' && isalpha(*p))
  2632. -        return HEADER;
  2633. -    lasthdr = 0;
  2634. -    return TEXT;
  2635. -}
  2636. -
  2637. -/*
  2638. - * Figure out who a message is from.
  2639. - */
  2640. -frombreak(buf, fbuf)
  2641. -register char *buf, *fbuf;
  2642. -{
  2643. -    register char *p, *q;
  2644. -
  2645. -    if (fbuf[0] && fromset) {    /* we already know who it's from */
  2646. -        if (sender[0] == 0 || buf[4] == ':') {
  2647. -#ifdef debug
  2648. -            printf("sender set to: %s", buf);
  2649. -#endif
  2650. -            strcpy(sender, buf);
  2651. -        }
  2652. -        return;
  2653. -    }
  2654. -    /*
  2655. -     * Leave fancy Froms alone - this parsing is done by mail
  2656. -     * Just quote the double quotes to prevent interpetation 
  2657. -     * by the shell.
  2658. -     * rad@tek
  2659. -     */
  2660. -    p = any(buf, " \t");
  2661. -    if (p==NULL)
  2662. -        p = buf + 4;
  2663. -    q = fbuf;
  2664. -    while (*++p) {
  2665. -        if (*p == '"')
  2666. -            *q++ = '\\';
  2667. -        *q++ = *p;
  2668. -    }
  2669. -    q[-1] = '\0';
  2670. -    if ((p=(char *)index(fbuf,'\n')) != NULL)
  2671. -        *p = '\0';
  2672. -    if (buf[4] == ':')
  2673. -        fromset++;
  2674. -}
  2675. -
  2676. -/*
  2677. - * Return the ptr in sp at which a character in sq appears;
  2678. - * NULL if not found
  2679. - *
  2680. - */
  2681. -char *
  2682. -any(sp, sq)
  2683. -char *sp, *sq;
  2684. -{
  2685. -    register c1, c2;
  2686. -    register char *q;
  2687. -
  2688. -    while (c1 = *sp++) {
  2689. -        q = sq;
  2690. -        while (c2 = *q++)
  2691. -            if (c1 == c2)
  2692. -                return(--sp);
  2693. -    }
  2694. -    return(NULL);
  2695. -}
  2696. *-*-END-of-src/recnews.c-*-*
  2697. echo x - src/rextern.c 1>&2
  2698. sed 's/.//' >src/rextern.c <<'*-*-END-of-src/rextern.c-*-*'
  2699. -/*
  2700. - * rextern - external definitions for readnews
  2701. - */
  2702. -
  2703. -#ifdef SCCSID
  2704. -static char    *SccsId = "@(#)rextern.c    2.15    4/16/85";
  2705. -#endif /* SCCSID */
  2706. -
  2707. -/*LINTLIBRARY*/
  2708. -
  2709. -#include "rparams.h"
  2710. -
  2711. -int    uid, gid;            /* real user/group I.D.        */
  2712. -int    duid, dgid;            /* effective user/group I.D.    */
  2713. -int    SigTrap;            /* set if signal trapped    */
  2714. -int    savmask;            /* old umask            */
  2715. -int    mode;                /* mode of news program        */
  2716. -struct hbuf header;            /* general-use header structure    */
  2717. -char    bfr[LBUFLEN];            /* general-use scratch area    */
  2718. -
  2719. -#ifndef ROOTID
  2720. -int    ROOTID;                /* special users id #        */
  2721. -#endif
  2722. -
  2723. -char    *outfile = "/tmp/M1XXXXXX";    /* output file for -M and -c    */
  2724. -char    *infile = "/tmp/M2XXXXXX";    /* -T output from Mail        */
  2725. -int    ngrp, line = -1;
  2726. -
  2727. -char    filename[BUFLEN], coptbuf[BUFLEN], datebuf[BUFLEN];
  2728. -char    afline[BUFLEN];
  2729. -FILE    *rcfp, *actfp;
  2730. -time_t    atime;
  2731. -char    newsrc[BUFLEN], groupdir[BUFLEN], *rcline[LINES], rcbuf[LBUFLEN];
  2732. -char    *bitmap, *argvrc[LINES];
  2733. -long    bit, obit, last;
  2734. -int    readmode = NEXT;
  2735. -int    news = 0;        /* Was there any news to read */
  2736. -int    actdirect = FORWARD;    /* read direction in ACTIVE file */
  2737. -int    rcreadok = FALSE;    /* NEWSRC has been read OK */
  2738. -int    zapng = FALSE;        /* ! out this newsgroup on next updaterc */
  2739. -long    ngsize;            /* max article # in this newsgroup */
  2740. -long    minartno;        /* min article # in this newsgroup */
  2741. -
  2742. -#ifndef SHELL
  2743. -char    *SHELL;
  2744. -#endif
  2745. -
  2746. -#ifndef MAILER
  2747. -char    *MAILER;
  2748. -#endif
  2749. -
  2750. -char    *PAGER = "";
  2751. *-*-END-of-src/rextern.c-*-*
  2752. exit
  2753.  
  2754.