home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / cnews2 / part09 < prev    next >
Text File  |  1989-06-29  |  45KB  |  2,077 lines

  1. Subject:  v19i086:  Cnews production release, Part09/19
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: utzoo!henry
  7. Posting-number: Volume 19, Issue 86
  8. Archive-name: cnews2/part09
  9.  
  10. : ---CUT HERE---
  11. echo 'hfake/timeb.h':
  12. sed 's/^X//' >'hfake/timeb.h' <<'!'
  13. X/*
  14. X * simulation of research unix's <sys/timeb.h> for Uglix.
  15. X */
  16. Xstruct timeb {
  17. X    time_t time;
  18. X    unsigned short millitm;
  19. X    short timezone;
  20. X    short dstflag;
  21. X};
  22. !
  23. echo 'hfake/Makefile':
  24. sed 's/^X//' >'hfake/Makefile' <<'!'
  25. XI = ../include
  26. X
  27. X# beware -- build knows about NEEDED
  28. XNEEDED =  ../include/stdlib.h
  29. X
  30. Xall:    $(NEEDED)
  31. X
  32. X$(I)/stdlib.h:    stdlib.h
  33. X    cp stdlib.h $@
  34. X$(I)/string.h:    string.h
  35. X    cp string.h $@
  36. X$(I)/sys/timeb.h:    timeb.h
  37. X    cp timeb.h $@
  38. X
  39. Xclean:
  40. !
  41. echo 'input/bdecode.c':
  42. sed 's/^X//' >'input/bdecode.c' <<'!'
  43. X/*
  44. X * bdecode [file]
  45. X */
  46. X#include <stdio.h>
  47. X#include "coder.h"
  48. Xchar *myname, *inputfile = "(stdin)";
  49. X
  50. Xmain(argc, argv) 
  51. X    char **argv;
  52. X{
  53. X    register long word;
  54. X    register int c, bcount;
  55. X    register FILE *fin = stdin, *fout = stdout;    /* in regs for speed */
  56. X    register char *map, *p;
  57. X    register long nbytes;
  58. X    register int crc;
  59. X    long nbytes2;
  60. X    int w, crc2;
  61. X    char buf[512];
  62. X    extern char *index();
  63. X
  64. X    myname = argv[0];
  65. X    if (sizeof(word) < 4)
  66. X        fprintf(stderr, "%s: word size too small\n", myname), exit(1);
  67. X    if (argc > 2)
  68. X        fprintf(stderr, "Usage: %s [file]\n", myname), exit(1);
  69. X    if (argc == 2) {
  70. X        if ((fin = fopen(argv[1], "r")) == NULL) {
  71. X            fprintf(stderr, "%s: ", myname);
  72. X            perror(argv[1]);
  73. X            exit(1);
  74. X        }
  75. X        inputfile = argv[1];
  76. X    }
  77. X    /* skip to beginning of encoded data */
  78. X    do {
  79. X        if (fgets(buf, sizeof buf, fin) == NULL)
  80. X            fatal("Missing header");
  81. X        /* trim trailing blanks (sigh) */
  82. X        p = index(buf, '\n');
  83. X        if (p == 0)
  84. X            continue;
  85. X        while (*--p == ' ')
  86. X            ;
  87. X        p[1] = '\n';
  88. X        p[2] = '\0';
  89. X    } while (strcmp(buf, header) != 0);
  90. X    
  91. X    /* define input mapping table */
  92. X    map = buf+1;
  93. X    for (c = 0; c < 256; c++)
  94. X        map[c] = 64;        /* illegal */
  95. X    for (c = 0; c < 64; c++)
  96. X        map[ENCODE(c)] = c;
  97. X    map[EOF] = 65;        /* special cases */
  98. X    map['/'] = 66;
  99. X
  100. X    word = 0;
  101. X    bcount = 4;
  102. X    nbytes = 0;
  103. X    crc = 0;
  104. X#define PUTC(x)  { c = (x) & 0xff; CRC(crc, c); putc(c, fout); nbytes++; }
  105. X    for (;;) {
  106. X        c = map[getc(fin)];
  107. X        if ((unsigned)c < 64) {
  108. X            word <<= 6;
  109. X            word |= c;
  110. X            if (--bcount == 0) {
  111. X                PUTC(word >> 16);
  112. X                PUTC(word >>  8);
  113. X                PUTC(word);
  114. X                word = 0;
  115. X                bcount = 4;
  116. X            }
  117. X            continue;
  118. X        }
  119. X        switch (c) {
  120. X
  121. X        default:
  122. X            /*
  123. X             * Ignore stuff not in the code set.
  124. X             */
  125. X            continue;
  126. X
  127. X        case 65:    /* EOF */
  128. X            fatal("Unexpected EOF");
  129. X
  130. X        case 66:    /* '/' */
  131. X            /* trailer follows: %d%x */
  132. X            c = getc(fin);
  133. X            if (fscanf(fin, "%x", &w) != 1)
  134. X                fatal("Corrupted input (trailer)");
  135. X            switch (c) {
  136. X            case '2': PUTC(w >> 8);
  137. X            case '1': PUTC(w);
  138. X            case '0': break;
  139. X            default: fatal("Corrupted input (trailer)");
  140. X            }
  141. X            /*
  142. X             * Byte count and CRC follow.
  143. X             */
  144. X            if (fscanf(fin, "%ld%x", &nbytes2, &crc2) != 2)
  145. X                fatal("Corrupted input (missing byte count/CRC)");
  146. X            if (nbytes2 != nbytes)
  147. X                fatal("Corrupted input (byte count is wrong)");
  148. X            if (crc2 != (crc & 0xffff))
  149. X                fatal("Corrupted input (CRC mismatch)");
  150. X            exit(0);
  151. X        }
  152. X    }
  153. X}
  154. X
  155. Xfatal(s)
  156. X    char *s;
  157. X{
  158. X    fprintf(stderr, "%s: %s: %s\n", myname, inputfile, s);
  159. X    exit(2);
  160. X}
  161. !
  162. echo 'input/newsspool.c':
  163. sed 's/^X//' >'input/newsspool.c' <<'!'
  164. X/*
  165. X * newsspool - copy incoming news into incoming directory
  166. X *
  167. X * The -i option relies on the parent setting (and exporting) $PATH.
  168. X *
  169. X * $Log$
  170. X */
  171. X
  172. X#include <stdio.h>
  173. X#include <sys/types.h>
  174. X#include <sys/stat.h>
  175. X#include <string.h>
  176. X#include <errno.h>
  177. X#include "libc.h"
  178. X#include "news.h"
  179. X#include "config.h"
  180. X
  181. X#ifndef lint
  182. Xstatic char RCSid[] = "$Header$";
  183. X#endif
  184. X
  185. X#ifndef MAXTRIES
  186. X#define    MAXTRIES    100    /* limit on attempts to make links */
  187. X#endif
  188. X
  189. Xint debug = 0;
  190. Xchar *progname;
  191. X
  192. Xextern void error(), exit();
  193. X#ifdef UTZOOERR
  194. Xextern char *mkprogname();
  195. X#else
  196. X#define    mkprogname(a)    (a)
  197. X#endif
  198. X
  199. Xchar buf[BUFSIZ*16];    /* try to get a batch in a few gulps */
  200. Xint immed = 0;        /* try an immediate newsrun? */
  201. X
  202. Xvoid process();
  203. XFILE *outopen();
  204. Xvoid outclose();
  205. Xextern time_t time();
  206. Xchar *outname();
  207. X
  208. X/*
  209. X - main - parse arguments and handle options
  210. X */
  211. Xmain(argc, argv)
  212. Xint argc;
  213. Xchar *argv[];
  214. X{
  215. X    int c;
  216. X    int errflg = 0;
  217. X    FILE *in;
  218. X    struct stat statbuf;
  219. X    extern int optind;
  220. X    extern char *optarg;
  221. X    extern FILE *efopen();
  222. X    void process();
  223. X
  224. X    progname = mkprogname(argv[0]);
  225. X
  226. X    while ((c = getopt(argc, argv, "id")) != EOF)
  227. X        switch (c) {
  228. X        case 'i':    /* try immediate newsrun */
  229. X            immed++;
  230. X            break;
  231. X        case 'd':    /* Debugging. */
  232. X            debug++;
  233. X            setbuf(stderr, (char *)NULL);
  234. X            break;
  235. X        case '?':
  236. X        default:
  237. X            errflg++;
  238. X            break;
  239. X        }
  240. X    if (errflg) {
  241. X        fprintf(stderr, "usage: %s [file] ...\n", progname);
  242. X        exit(2);
  243. X    }
  244. X
  245. X    /* probe to get unprivileged() called if necessary */
  246. X    (void) ctlfile((char *)NULL);
  247. X
  248. X    /* mktemp() uses access(2) [ARGH!] so minimize chances of trouble */
  249. X    (void) setgid(getegid());
  250. X    (void) setuid(geteuid());
  251. X
  252. X    (void) umask(newsumask());
  253. X
  254. X    if (optind >= argc)
  255. X        process(stdin, "stdin");
  256. X    else
  257. X        for (; optind < argc; optind++)
  258. X            if (STREQ(argv[optind], "-"))
  259. X                process(stdin, "-");
  260. X            else {
  261. X                in = efopen(argv[optind], "r");
  262. X                if (fstat(fileno(in), &statbuf) < 0)
  263. X                    error("can't fstat `%s'", argv[optind]);
  264. X                if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
  265. X                    error("`%s' is directory!", argv[optind]);
  266. X                process(in, argv[optind]);
  267. X                (void) fclose(in);
  268. X            }
  269. X
  270. X    if (immed) {
  271. X        /* execlp because shell files may not be directly execable */
  272. X        execlp(binfile("input/newsrun"), "newsrun", (char *)NULL);
  273. X        error("attempt to run newsrun failed!", "");
  274. X    }
  275. X    exit(0);
  276. X}
  277. X
  278. X/*
  279. X * process - process input file
  280. X */
  281. X/* ARGSUSED */
  282. Xvoid
  283. Xprocess(in, inname)
  284. XFILE *in;
  285. Xchar *inname;
  286. X{
  287. X    register int count;
  288. X    register int firstblock;
  289. X    FILE *out;
  290. X    register char *p;
  291. X    register int n;
  292. X    char *name;
  293. X
  294. X    name = outname();
  295. X    out = outopen(name);
  296. X
  297. X    /* do the copying */
  298. X    firstblock = 1;
  299. X    while ((count = fread(buf, sizeof(char), sizeof(buf), in)) > 0) {
  300. X        if (firstblock) {
  301. X            n = cunskip(buf, count);
  302. X            p = buf + n;
  303. X            count -= n;
  304. X            firstblock = 0;
  305. X        } else
  306. X            p = buf;
  307. X        n = fwrite(p, sizeof(char), count, out);
  308. X        if (n != count)
  309. X            error("write error in output to `%s'", name);
  310. X    }
  311. X
  312. X    outclose(out, name);
  313. X}
  314. X
  315. X/*
  316. X - outname - construct name for the temporary output file
  317. X */
  318. Xchar *
  319. Xoutname()
  320. X{
  321. X    register char *p;
  322. X
  323. X    p = strsave(fullartfile("in.coming/nspool.XXXXXX"));
  324. X    mktemp(p);
  325. X    return(p);
  326. X}
  327. X
  328. X/*
  329. X - outopen - acquire an output file
  330. X */
  331. XFILE *
  332. Xoutopen(name)
  333. Xchar *name;
  334. X{
  335. X    FILE *f;
  336. X
  337. X    f = fopen(name, "w");
  338. X    if (f == NULL)
  339. X        error("unable to create temporary `%s'", name);
  340. X    if (debug)
  341. X        fprintf(stderr, "output into %s\n", name);
  342. X
  343. X    return(f);
  344. X}
  345. X
  346. X/*
  347. X - outclose - close output file, moving it to the right place
  348. X *
  349. X * Names are based on the current time in hopes of keeping input in order.
  350. X */
  351. Xvoid
  352. Xoutclose(f, tmpname)
  353. XFILE *f;
  354. Xchar *tmpname;
  355. X{
  356. X    register char *p;
  357. X    register char *name;
  358. X    register int ntries;
  359. X    time_t now;
  360. X    extern int errno;
  361. X
  362. X    if (fclose(f) == EOF)
  363. X        error("fclose error on file `%s'", tmpname);
  364. X
  365. X    p = fullartfile("in.coming/");
  366. X    name = emalloc(strlen(p) + 20);    /* plenty for a number */
  367. X    (void) strcpy(name, p);
  368. X    p = name + strlen(name);
  369. X
  370. X    ntries = 0;
  371. X    for (;;) {
  372. X        now = time((time_t *)NULL);
  373. X        sprintf(p, "%ld", now);
  374. X        if (debug)
  375. X            fprintf(stderr, "trying renaming to %s\n", name);
  376. X        if (link(tmpname, name) >= 0)
  377. X            break;        /* NOTE BREAK OUT */
  378. X        if (errno != EEXIST)    /* something strange is wrong */
  379. X            error("unable to link `%s'", tmpname);
  380. X        errno = 0;
  381. X        if (ntries > MAXTRIES)    /* sanity check */
  382. X            error("too many attempts to link `%s'", tmpname);
  383. X        if (debug)
  384. X            fprintf(stderr, "failed\n");
  385. X        sleep(2);    /* avoid rumored race in 1-sec sleep */
  386. X        ntries++;
  387. X    }
  388. X
  389. X    if (debug)
  390. X        fprintf(stderr, "succeeded\n");
  391. X    (void) unlink(tmpname);
  392. X}
  393. X
  394. X/*
  395. X - cunskip - inspect block for silly #! cunbatch headers
  396. X */
  397. Xint                /* number of chars at start to skip */
  398. Xcunskip(bufp, count)
  399. Xchar *bufp;
  400. Xint count;
  401. X{
  402. X    static char goop[] = "cunbatch";
  403. X#    define    GOOPLEN    (sizeof(goop)-1)    /* strlen(goop) */
  404. X    static char goop2[] = "c7unbatch";
  405. X#    define    GOOP2LEN    (sizeof(goop2)-1)    /* strlen(goop2) */
  406. X    register char *p;
  407. X    register int nleft;
  408. X
  409. X    nleft = count;
  410. X    p = bufp;
  411. X
  412. X    if (nleft < 2)                /* no room for a header */
  413. X        return(0);
  414. X    if (*p++ != '#' || *p++ != '!')        /* doesn't start with #! */
  415. X        return(0);
  416. X    nleft -= 2;
  417. X
  418. X    /* skip space */
  419. X    while (nleft > 0 && (*p == ' ' || *p == '\t')) {
  420. X        p++;
  421. X        nleft--;
  422. X    }
  423. X
  424. X    /* recognize headers (the +1s ensure room for the newline) */
  425. X    if (nleft >= GOOPLEN+1 && STREQN(p, goop, GOOPLEN)) {
  426. X        p += GOOPLEN;
  427. X        nleft -= GOOPLEN;
  428. X    } else if (nleft >= GOOP2LEN+1 && STREQN(p, goop2, GOOP2LEN)) {
  429. X        p += GOOP2LEN;
  430. X        nleft -= GOOP2LEN;
  431. X    } else                    /* no header */
  432. X        return(0);
  433. X
  434. X    /* skip more space */
  435. X    while (nleft > 0 && (*p == ' ' || *p == '\t')) {
  436. X        p++;
  437. X        nleft--;
  438. X    }
  439. X
  440. X    if (nleft == 0 || *p++ != '\n')        /* didn't end properly */
  441. X        return(0);
  442. X
  443. X    return(p - bufp);
  444. X}
  445. X
  446. X/*
  447. X - unprivileged - drop setuidness if configuration is overridden
  448. X */
  449. Xvoid
  450. Xunprivileged()
  451. X{
  452. X    setgid(getgid());
  453. X    setuid(getuid());
  454. X}
  455. !
  456. echo 'input/Makefile':
  457. sed 's/^X//' >'input/Makefile' <<'!'
  458. X# You get your choice of rnews.immed or rnews.batch; rnews.immed tries
  459. X# to start processing immediately, while rnews.batch waits for somebody
  460. X# else (cron) to do it.  Running rnews.immed might, perhaps, be reasonable
  461. X# if your news load is light and you are wildly impatient about processing
  462. X# incoming news.  Otherwise, leave this alone.
  463. XRNEWS = rnews.batch
  464. X
  465. XDEFINES =
  466. XCOPTS = -O
  467. XCFLAGS = $(COPTS) $(DEFINES) -I../include
  468. XLINTFLAGS = $(DEFINES) -I../include -ha
  469. XLDFLAGS = $(CFLAGS)
  470. XLIBS= ../libcnews.a
  471. XBATCH = ../batch
  472. XTHEMBIN = newsrun newsrunning c7decode bdecode recenews recpnews rnews
  473. XTHEM = newsspool $(THEMBIN)
  474. XRBIN = /bin
  475. X# =()<NEWSARTS = @<NEWSARTS>@>()=
  476. XNEWSARTS = /usr/spool/news
  477. X# =()<NEWSBIN = @<NEWSBIN>@>()=
  478. XNEWSBIN = /usr/lib/newsbin
  479. X# workaround for System V make bug
  480. XSHELL = /bin/sh
  481. XDTR = README Makefile newsrun newsrunning newsspool.c c7decode.c rnews.batch \
  482. X    rnews.8 bdecode.c recenews recpnews
  483. X
  484. Xall:    $(THEM) rnews
  485. X
  486. Xbininstall:    all
  487. X    chmod +x $(THEM) rnews
  488. X    -if test ! -d $(NEWSBIN)/input ; then mkdir $(NEWSBIN)/input ; fi
  489. X    rm -f $(NEWSBIN)/input/newsspool
  490. X    cp $(THEM) $(NEWSBIN)/input
  491. X    cp rnews $(RBIN)/rnews
  492. X    cp rnews $(RBIN)/cunbatch
  493. X    : "and newsspool needs to be made setuid-news"
  494. X
  495. Xnewsinstall:
  496. X    : nothing
  497. X
  498. Xnewsspool: newsspool.o $(LIBS)
  499. X    $(CC) $(LDFLAGS) newsspool.o $(LIBS) -o $@
  500. X
  501. Xc7decode: c7decode.o $(LIBS)
  502. X    $(CC) $(LDFLAGS) c7decode.o $(LIBS) -o $@
  503. X
  504. Xbdecode: bdecode.o $(BATCH)/crctab.o $(LIBS)
  505. X    $(CC) $(LDFLAGS) bdecode.o $(BATCH)/crctab.o $(LIBS) -o $@
  506. X
  507. X$(BATCH)/crctab.o:    $(BATCH)/crctab.c
  508. X    ( cd $(BATCH) ; make crctab.o )
  509. X
  510. Xbdecode.o:    bdecode.c $(BATCH)/coder.h
  511. X    $(CC) -c -I$(BATCH) $(CFLAGS) bdecode.c
  512. X
  513. Xlint:    newsspool.c
  514. X    lint $(LINTFLAGS) newsspool.c 2>&1 | tee lint
  515. X
  516. Xtest.1:
  517. X    echo '#! rnews' >$@
  518. X    echo 'here is a phony first batch' >>$@
  519. X
  520. Xtest.2:
  521. X    echo '#! cunbatch' >$@
  522. X    echo '#! rnews' >>$@
  523. X    echo 'here is a phony second batch' >>$@
  524. X
  525. Xtest.3p:
  526. X    echo '#! rnews' >$@
  527. X    echo 'here is a phony third batch' >>$@
  528. X
  529. Xtest.3:    test.3c
  530. X    ( echo '#! cunbatch' ; cat test.3c ) >$@
  531. X
  532. Xtest.3c:    test.3p
  533. X    : compress tends to return silly exit status for tiny inputs
  534. X    -compress -b12 <test.3p >$@
  535. X
  536. Xtest.out:
  537. X    echo '#! rnews' >$@
  538. X    echo 'here is a phony first batch' >>$@
  539. X    echo '#! rnews' >>$@
  540. X    echo 'here is a phony second batch' >>$@
  541. X    echo '#! rnews' >>$@
  542. X    echo 'here is a phony third batch' >>$@
  543. X
  544. Xrnews.immed:    rnews.batch
  545. X    sed '/qqq/s/newsspool/& -i/' rnews.batch >$@
  546. X
  547. Xrnews:    rnews.batch rnews.immed
  548. X    cp $(RNEWS) rnews
  549. X    chmod +x rnews
  550. X
  551. Xsetup:    all
  552. X    chmod +x rnews.batch rnews.immed
  553. X    rm -rf bin
  554. X    mkdir bin
  555. X    cp $(THEM) bin
  556. X    mkdir bin/input
  557. X    cp newsrun bin/input
  558. X    rm -f tmp.1
  559. X    here=`pwd` ; echo "cat >>$$here/tmp.1" >bin/relaynews
  560. X    echo "echo 1" >bin/spacefor
  561. X    echo 'ln $$*' >bin/newslock
  562. X    echo 'echo 10' >bin/sizeof
  563. X    chmod +x bin/* bin/input/*
  564. X    rm -rf in.coming
  565. X    mkdir in.coming
  566. X
  567. Xr:    all test.1 test.2 test.3 test.3c test.out setup
  568. X    chmod +x $(THEM)
  569. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.1
  570. X    cmp in.coming/* test.1
  571. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.2
  572. X    sed 1d test.2 >tmp.2
  573. X    cmp `ls -t in.coming | sed -n '1s;^;in.coming/;p'` tmp.2
  574. X    rm tmp.2
  575. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.3
  576. X    cmp `ls -t in.coming | sed -n '1s;^;in.coming/;p'` test.3c
  577. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./newsrunning off
  578. X    test -r in.coming/stop
  579. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./newsrunning on
  580. X    test ! -r in.coming/stop
  581. X    mkdir in.coming/bad
  582. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./newsrun
  583. X    cmp tmp.1 test.out
  584. X    test " `echo in.coming/*`" = ' in.coming/bad'
  585. X    rm tmp.1
  586. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.1
  587. X    NEWSARTS=`pwd` NEWSCTL=`pwd` ./rnews.batch <test.2
  588. X    NEWSARTS=`pwd` NEWSCTL=`pwd` NEWSBIN=`pwd`/bin ./rnews.immed <test.3
  589. X    cmp tmp.1 test.out
  590. X    test " `echo in.coming/*`" = ' in.coming/bad'
  591. X    rm tmp.1
  592. X    rm -r bin in.coming
  593. X
  594. Xclean:
  595. X    rm -f *.o newsspool c7decode tmp.? test.* dtr lint rnews rnews.immed
  596. X    rm -f bdecode
  597. X    rm -rf in.coming bin
  598. X
  599. Xdtr:    $(DTR)
  600. X    makedtr $(DTR) >dtr
  601. !
  602. echo 'input/README':
  603. sed 's/^X//' >'input/README' <<'!'
  604. XThis is the input processing, which starts at rnews (aka cunbatch).  It
  605. Xinvokes newsspool, which actually puts the stuff where it belongs (peeling
  606. Xoff the silly and unnecessary "#! cunbatch" header, if any, as it goes).
  607. X
  608. XNewsrun should be run regularly; it unspools the stuff and feeds it into
  609. Xthe relay subsystem for processing.  Newsrunning can be used to turn this
  610. Xfunction on and off if you want to avoid news processing during busy hours.
  611. X
  612. XUsing rnews.immed instead of rnews.batch as rnews will arrange for newsrun
  613. Xto be run after each newsspool -- this is expensive but cuts down latency.
  614. XIf you've got a fast machine and a light newsfeed and totally lack patience,
  615. Xlike Geoff :-), this might be a good idea; otherwise, no.
  616. X
  617. X"make r" builds everything and runs a full regression test on most everything.
  618. !
  619. echo 'input/recenews':
  620. sed 's/^X//' >'input/recenews' <<'!'
  621. X#! /bin/sh
  622. X# News reception via mail, bencoded format.
  623. X
  624. X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
  625. X. ${NEWSCONFIG-/usr/lib/news/bin/config}
  626. X
  627. XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
  628. Xumask $NEWSUMASK
  629. X
  630. Xbdecode | rnews
  631. !
  632. echo 'input/newsrun':
  633. sed 's/^X//' >'input/newsrun' <<'!'
  634. X#! /bin/sh
  635. X# Process spooled news.
  636. X
  637. X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
  638. X. ${NEWSCONFIG-/usr/lib/news/bin/config}
  639. X
  640. XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN/relay:$NEWSBIN:$NEWSPATH ; export PATH
  641. Xumask $NEWSUMASK
  642. X
  643. Xhere="$NEWSARTS/in.coming"
  644. Xcd $here
  645. X
  646. X# First, is it worth trying at all?
  647. Xif test -r stop
  648. Xthen
  649. X    exit 0
  650. Xfi
  651. X
  652. X# Lock against others running.
  653. Xlock="$NEWSCTL/LOCKinput"
  654. Xltemp="$NEWSCTL/L.$$"
  655. Xecho $$ >$ltemp
  656. Xtrap "rm -f $ltemp ; exit 0" 0 1 2 15
  657. Xif newslock $ltemp $lock
  658. Xthen
  659. X    trap "rm -f $ltemp $lock ; exit 0" 0 1 2 15
  660. Xelse
  661. X    exit 0
  662. Xfi
  663. X
  664. X# Sort out where we are.
  665. Xif test -r $NEWSCTL/server
  666. Xthen
  667. X    me="`hostname`"
  668. X    server=`cat $NEWSCTL/server`
  669. Xelse
  670. X    me=me            # don't need actual name
  671. X    server="$me"        # no server file --> we're it
  672. Xfi
  673. X
  674. X# Master loop.
  675. Xwhile :                # "while true", but : is faster
  676. Xdo
  677. X    # Find some work.
  678. X    them=`ls | sed '/[^0-9]/d;50q'`
  679. X    if test " $them" = " "
  680. X    then
  681. X        break            # NOTE BREAK OUT
  682. X    fi
  683. X
  684. X    # Check space.  It is *probably* better to stop processing
  685. X    # when things get too full.  (This test is actually a bit
  686. X    # inaccurate since the batches may be compressed, but it's
  687. X    # good enough to catch major space problems.)
  688. X    allsize=`sizeof $them`
  689. X    if test " `spacefor $allsize articles`" -gt 1    # lots of room
  690. X    then
  691. X        muchroom=y
  692. X    else
  693. X        muchroom=
  694. X    fi
  695. X
  696. X    # Do it.
  697. X    rmlist=
  698. X    for f in $them
  699. X    do
  700. X        # Check for request to stop.
  701. X        if test -r stop
  702. X        then
  703. X            rm -f $rmlist
  704. X            exit 0
  705. X        fi
  706. X
  707. X        # Check for empty.
  708. X        if test ! -s $f
  709. X        then
  710. X            rm -f $f
  711. X            continue            # NOTE CONTINUE
  712. X        fi
  713. X
  714. X        # Space check, if we're close.
  715. X        if test " $muchroom" != " y"
  716. X        then
  717. X            batchsize=`sizeof $f`
  718. X            if test " `spacefor $batchsize articles`" -le 0
  719. X            then
  720. X                rm -f $rmlist
  721. X                exit 0
  722. X            fi
  723. X        fi
  724. X
  725. X        # Decompress if necessary.  People who get lots of
  726. X        # uncompressed batches and never use c7 encoding might
  727. X        # want to remove the c7decode attempt to speed things up.
  728. X        text=nruntmp.$$
  729. X        if compress -d <$f >$text 2>/dev/null
  730. X        then
  731. X            rmlist="$rmlist $f $text"
  732. X        elif c7decode <$f 2>/dev/null | compress -d >$text 2>/dev/null
  733. X        then
  734. X            rmlist="$rmlist $f $text"
  735. X        else
  736. X            rm -f $text
  737. X            text=$f
  738. X            rmlist="$rmlist $f"
  739. X        fi
  740. X
  741. X        # Do it.  -r redirects stdout and stderr into logs.  -n makes
  742. X        # history entries for refused articles; this is right for
  743. X        # NNTP-feed sites and doesn't hurt uucp-feed sites unless
  744. X        # they refuse a good fraction of what they get.
  745. X        if test " $server" = " $me"    # if local
  746. X        then
  747. X            relaynews -r -n <$text
  748. X        else
  749. X            # N.B.: rsh always returns exit status 0!
  750. X            rsh $server "PATH=$PATH relaynews -r -n" <$text
  751. X        fi
  752. X        st=$?
  753. X        if test $st -ne 0
  754. X        then
  755. X            # trouble
  756. X            if test ! -d bad
  757. X            then
  758. X                mkdir bad
  759. X            fi
  760. X            bad=bad/$f
  761. X
  762. X            if test -s bad/limit
  763. X            then
  764. X                limit=`sed 1q bad/limit`
  765. X            else
  766. X                limit=50
  767. X            fi
  768. X            nfiles=`ls bad | wc | awk '{print $1}'`
  769. X            if test " $nfiles" -lt " $limit"
  770. X            then
  771. X                mv $f $bad    # Not $text, save the ORIGINAL!
  772. X            fi
  773. X            echo "$server $consumer \`$bad' failed, status $st" |
  774. X                            mail "$NEWSMASTER"
  775. X        fi
  776. X
  777. X    done
  778. X    rm -f $rmlist
  779. Xdone
  780. X
  781. Xexit 0
  782. !
  783. echo 'input/newsrunning':
  784. sed 's/^X//' >'input/newsrunning' <<'!'
  785. X#! /bin/sh
  786. X# newsrunning - turn news processing on and off
  787. X
  788. X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
  789. X. ${NEWSCONFIG-/usr/lib/news/bin/config}
  790. X
  791. XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
  792. Xumask $NEWSUMASK
  793. X
  794. Xstop=$NEWSARTS/in.coming/stop
  795. X
  796. Xcase "$1"
  797. Xin
  798. X    on)
  799. X    rm -f $stop
  800. X    ;;
  801. X
  802. X    off)
  803. X    if test ! -r $stop    # don't update already-existing file
  804. X    then
  805. X        >$stop
  806. X    fi
  807. X    ;;
  808. X
  809. X    *)
  810. X    echo "Usage: $0 on/off" >&2
  811. X    exit 2
  812. X    ;;
  813. Xesac
  814. X
  815. Xexit 0
  816. !
  817. echo 'input/c7decode.c':
  818. sed 's/^X//' >'input/c7decode.c' <<'!'
  819. X#include <stdio.h>
  820. X
  821. X/*
  822. X * This program is the inverse of encode
  823. X *
  824. X * It collects runs of 12 characters, combines pairs of those
  825. X * to form 6 13 bit numbers, extracts the top bit of each of
  826. X * those to make a 13th 6 bit character, and splits each of
  827. X * the remaining 6 12 bit numbers to form 12 6 bit ones.
  828. X *
  829. X * The strings of 6 bit numbers are collected into groups of
  830. X * 4 and converted into 3 8 bit characters.
  831. X *
  832. X * Now all that would be trivial, if we didn't need to worry
  833. X * about ending all this correctly.  About 1/2 of the following
  834. X * program wouldn't be here if the ending didn't matter....
  835. X */
  836. X
  837. X/*
  838. X * the following pair of characters can never occur as a pair
  839. X * in legal input (since (90 * 91 + 90) > 2^13) - they are
  840. X * noticed at the beginning of a 12 char block, and serve to
  841. X * indicate that this block is the terminator.  The character
  842. X * immediately following is the (expanded) terminator length.
  843. X */
  844. X#define    ENDMARK1    ((90*91 + 90) / 91)
  845. X#define    ENDMARK2    ((90*91 + 90) % 91)
  846. X
  847. Xint errcnt = 0;
  848. X
  849. Xmain()
  850. X{
  851. X    register c;
  852. X    register char *p;
  853. X    register i;
  854. X    register first = 1;
  855. X    register cnt = 0;
  856. X    char b12[12];
  857. X    char c12[12];
  858. X
  859. X    p = b12;
  860. X    i = 12;
  861. X
  862. X    while ((c = getchar()) != EOF) {
  863. X        if (c < ' ' || c >= (' ' + 91)) {
  864. X            if (errcnt++ == 0)
  865. X                fprintf(stderr, "c7decode: Bad data\n");
  866. X            continue;
  867. X        }
  868. X        if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
  869. X            cnt = c - ' ';
  870. X            i = 12;
  871. X            p -= 2;
  872. X            continue;
  873. X        }
  874. X        *p++ = c - ' ';
  875. X        if (--i == 0) {
  876. X            if (p == &b12[12]) {
  877. X                if (!first)
  878. X                    pack12(c12, 12, 0);
  879. X                else
  880. X                    first = 0;
  881. X                p = c12;
  882. X            } else {
  883. X                pack12(b12, 12, 0);
  884. X                p = b12;
  885. X            }
  886. X            i = 12;
  887. X        }
  888. X    }
  889. X
  890. X    if (p >= &b12[0] && p < &b12[12]) {
  891. X        if (!first)
  892. X            pack12(c12, 12, i == 12 ? cnt : 0);
  893. X    } else
  894. X        pack12(b12, 12, i == 12 ? cnt : 0);
  895. X
  896. X    if (i != 12) {
  897. X        if (p >= &b12[0] && p < &b12[12])
  898. X            pack12(b12, 12-i, cnt);
  899. X        else
  900. X            pack12(c12, 12-i, cnt);
  901. X    }
  902. X
  903. X    exit((errcnt > 0) ? 1 : 0);
  904. X}
  905. X
  906. Xstatic char b4[4];
  907. Xstatic int cnt = 0;
  908. X
  909. Xpack12(p, n, last)
  910. X    register char *p;
  911. X    register n;
  912. X    int last;
  913. X{
  914. X    register i;
  915. X    register char *q;
  916. X    char b13[13];
  917. X
  918. X    {
  919. X        register c;
  920. X        register c13;
  921. X
  922. X        q = b13;
  923. X        c13 = 0;
  924. X
  925. X        for (i = 0; i < n; i += 2) {
  926. X            c = *p++ * 91;
  927. X            c += *p++;
  928. X            c13 <<= 1;
  929. X            if (c & (1 << 12))
  930. X                c13 |= 1;
  931. X            *q++ = (c >> 6) & 0x3f;
  932. X            *q++ = c & 0x3f;
  933. X        }
  934. X        *q++ = c13;
  935. X        if (last)
  936. X            q = &b13[last];
  937. X    }
  938. X
  939. X    p = b13;
  940. X    n = q - p;
  941. X    i = cnt;
  942. X    q = &b4[cnt];
  943. X
  944. X    while (--n > 0) {
  945. X        *q++ = *p++;
  946. X        if (++i == 4) {
  947. X            char b3[3];
  948. X            register char *b = b4;
  949. X
  950. X            /* inline expansion of pack6bit, to save calls ... */
  951. X
  952. X            q = b3;
  953. X            *q++ = (b[0] << 2) | ((b[1] >> 4) & 0x3);
  954. X            *q++ = (b[1] << 4) | ((b[2] >> 2) & 0xf);
  955. X            *q = (b[2] << 6) | (b[3] & 0x3f);
  956. X
  957. X            q = b3;
  958. X            while (--i > 0)
  959. X                putchar(*q++);
  960. X
  961. X            q = b4;
  962. X        }
  963. X    }
  964. X
  965. X    *q++ = *p++;    /* the last octet */
  966. X    ++i;
  967. X
  968. X    if (last || i == 4) {
  969. X        pack6bit(b4, i, last);
  970. X        i = 0;
  971. X    }
  972. X
  973. X    cnt = i;
  974. X}
  975. X
  976. Xpack6bit(p, n, last)
  977. X    register char *p;
  978. X    register int n;
  979. X    int last;
  980. X{
  981. X    register char *q;
  982. X    register i = 3;
  983. X    char b3[3];
  984. X
  985. X    if (last) {
  986. X        i = p[n-1];
  987. X        if (i >= 3) {
  988. X            fprintf(stderr, "c7decode: Badly encoded file\n");
  989. X            errcnt++;
  990. X            i = 3;        /* do the best we can */
  991. X        }
  992. X    }
  993. X
  994. X    q = b3;
  995. X    *q++ = (p[0] << 2) | ((p[1] >> 4) & 0x3);
  996. X    *q++ = (p[1] << 4) | ((p[2] >> 2) & 0xf);
  997. X    *q = (p[2] << 6) | (p[3] & 0x3f);
  998. X
  999. X    q = b3;
  1000. X
  1001. X    while (--i >= 0)
  1002. X        putchar(*q++);
  1003. X}
  1004. !
  1005. echo 'input/rnews.batch':
  1006. sed 's/^X//' >'input/rnews.batch' <<'!'
  1007. X#! /bin/sh
  1008. X# Incoming-news spooling.
  1009. X# We ignore arguments -- it looks tempting to put "$*" after cat and
  1010. X# newsspool, but there are security problems.
  1011. X
  1012. X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
  1013. X. ${NEWSCONFIG-/usr/lib/news/bin/config}
  1014. X
  1015. XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
  1016. Xumask $NEWSUMASK
  1017. X
  1018. X# check space, assuming a pretty large batch (no cheap way to find real size)
  1019. Xcounter=1
  1020. Xwhile test " `spacefor 250000 incoming`" -le 0
  1021. Xdo
  1022. X    sleep 300
  1023. X    if test " $counter" -gt 1111        # four tries is plenty
  1024. X    then
  1025. X        # oh no! -- nothing we can do, really...
  1026. X        cat >/dev/null
  1027. X        echo incoming news discarded due to space shortage |
  1028. X                            mail "$NEWSMASTER"
  1029. X        exit 1
  1030. X    fi
  1031. X    counter="1$counter"
  1032. Xdone
  1033. X
  1034. Xif newsspool >/tmp/ngripe.$$ 2>&1        # qqq (marker for Makefile)
  1035. Xthen
  1036. X    rm -f /tmp/ngripe.$$
  1037. X    exit 0
  1038. Xelse
  1039. X    # there really isn't any way to save the data if newsspool fails,
  1040. X    # not without causing other problems
  1041. X    (
  1042. X        echo newsspool failed!!!
  1043. X        cat /tmp/ngripe.$$
  1044. X    ) | mail "$NEWSMASTER"
  1045. X    rm -f /tmp/ngripe.$$
  1046. X    exit 1
  1047. Xfi
  1048. !
  1049. echo 'input/recpnews':
  1050. sed 's/^X//' >'input/recpnews' <<'!'
  1051. X#! /bin/sh
  1052. X# News reception via mail, protected format (inferior to bencode).
  1053. X
  1054. X# =()<. ${NEWSCONFIG-@<NEWSCONFIG>@}>()=
  1055. X. ${NEWSCONFIG-/usr/lib/news/bin/config}
  1056. X
  1057. XPATH=$NEWSCTL/bin:$NEWSBIN/input:$NEWSBIN:$NEWSPATH ; export PATH
  1058. Xumask $NEWSUMASK
  1059. X
  1060. Xsed -n '1,/^$/d
  1061. Xs/^N//p' | rnews
  1062. !
  1063. echo 'libbig/active.fast.c':
  1064. sed 's/^X//' >'libbig/active.fast.c' <<'!'
  1065. X/*
  1066. X * active file access functions (big, fast, in-memory version)
  1067. X */
  1068. X
  1069. X#include <stdio.h>
  1070. X#include <sys/types.h>
  1071. X#include <sys/stat.h>
  1072. X#include "libc.h"
  1073. X#include "news.h"
  1074. X#include "config.h"
  1075. X#include "active.h"
  1076. X
  1077. X/* private */
  1078. Xstatic char *active = NULL;    /* cache: points at entire active file */
  1079. Xstatic int actsize;        /* bytes in active: type int fixed by fread */
  1080. Xstatic char **actlnps;        /* point at lines in active file */
  1081. Xstatic unsigned actlines;    /* lines in actlnps actually used */
  1082. X
  1083. X/* imports from active.c */
  1084. Xextern char actrelnm[];
  1085. X
  1086. X/* forwards */
  1087. XFORWARD statust actmkindx();
  1088. X
  1089. Xstatust
  1090. Xactfload(fp)
  1091. XFILE *fp;
  1092. X{
  1093. X    statust status = ST_OKAY;
  1094. X
  1095. X    if (fp != NULL && active == NULL) {
  1096. X        struct stat sb;
  1097. X
  1098. X        errno = 0;
  1099. X        if (fstat(fileno(fp), &sb) < 0)
  1100. X            warning("can't fstat `%s'", ctlfile(actrelnm));
  1101. X        else if (actsize = sb.st_size, /* squeeze into an int */
  1102. X            (unsigned)actsize != sb.st_size)
  1103. X            warning("`%s' won't fit into memory", ctlfile(actrelnm));
  1104. X        else if ((active = malloc((unsigned)actsize+1)) == NULL)
  1105. X            warning("can't allocate memory for `%s'",
  1106. X                ctlfile(actrelnm));
  1107. X        else {
  1108. X            rewind(fp);
  1109. X            /*
  1110. X             * If we read with fgetms, we might be able to avoid
  1111. X             * calling linescan().
  1112. X             */
  1113. X            if (fread(active, 1, actsize, fp) != actsize) {
  1114. X                warning("error reading `%s'", ctlfile(actrelnm));
  1115. X                status |= ST_DROPPED;
  1116. X            } else
  1117. X                status |= actmkindx();
  1118. X        }
  1119. X        if (active == NULL)
  1120. X            status |= ST_DROPPED;    /* give up! */
  1121. X        if (status != ST_OKAY) {
  1122. X            nnfree(&active);
  1123. X            nnafree(&actlnps);
  1124. X        }
  1125. X    }
  1126. X    return status;
  1127. X}
  1128. X
  1129. Xstatic statust
  1130. Xactmkindx()            /* build actlnps index for active */
  1131. X{
  1132. X    register statust status = ST_OKAY;
  1133. X    unsigned lnpsz;
  1134. X    int maxlines;
  1135. X
  1136. X    active[actsize] = '\0';        /* make a proper string */
  1137. X    /* +1 for a possible partial line +1 for a dummy to check overflow */
  1138. X    maxlines = charcount(active, '\n') + 2;
  1139. X    lnpsz = sizeof(char *) * (long) maxlines;
  1140. X    if (lnpsz != sizeof(char *) * (long)maxlines ||
  1141. X        (actlnps = (char **)malloc(lnpsz)) == NULL) {
  1142. X        warning("`%s' index won't fit in memory", ctlfile(actrelnm));
  1143. X            status |= ST_DROPPED;
  1144. X    } else {
  1145. X        actlnps[maxlines - 2] = "";    /* in case no partial line */
  1146. X        actlnps[maxlines - 1] = "";    /* end sentinel */
  1147. X        actlines = linescan(active, actlnps, maxlines);
  1148. X        if (actlines >= maxlines) {
  1149. X            (void) fprintf(stderr,
  1150. X                "%s: too many newsgroups in `%s' (can't happen)\n",
  1151. X                progname, ctlfile(actrelnm));
  1152. X            status |= ST_DROPPED;
  1153. X        }
  1154. X    }
  1155. X    return status;
  1156. X}
  1157. X
  1158. X/*
  1159. X * Store in lnarray the addresses of the starts of lines in s.
  1160. X * Return the number of lines found; if greater than nent,
  1161. X * store only nent and return nent.
  1162. X * Thus lnarray should be one bigger than needed to detect overflow.
  1163. X */
  1164. Xint
  1165. Xlinescan(s, lnarray, nent)
  1166. Xchar *s;
  1167. Xchar **lnarray;
  1168. Xregister int nent;
  1169. X{
  1170. X    register char **lnarrp = lnarray;
  1171. X    register int i = 0;
  1172. X    register char *nlp = s;
  1173. X
  1174. X    if (i < nent)
  1175. X        *lnarrp++ = nlp;
  1176. X    while (++i < nent && (nlp = index(nlp, '\n')) != NULL && *++nlp != '\0')
  1177. X        *lnarrp++ = nlp;
  1178. X    return i;        /* number of addrs stored */
  1179. X}
  1180. X
  1181. Xstatust
  1182. Xactfsync(fp)            /* write to disk, fp is open */
  1183. XFILE *fp;
  1184. X{
  1185. X    statust status = ST_OKAY;
  1186. X
  1187. X    rewind(fp);
  1188. X    if (active != NULL) {
  1189. X        if (fwrite(active, actsize, 1, fp) != 1)
  1190. X            status |= ST_DROPPED;    /* serious loss */
  1191. X        nnfree(&active);
  1192. X        nnafree(&actlnps);
  1193. X    }
  1194. X    return status;
  1195. X}
  1196. X
  1197. X/* ARGSUSED fp */
  1198. Xchar *
  1199. Xactfind(fp, ng, nglen)
  1200. XFILE *fp;
  1201. Xregister char *ng;
  1202. Xregister int nglen;
  1203. X{
  1204. X    register char *pos;
  1205. X    register unsigned line = 0;
  1206. X
  1207. X    while (pos = actlnps[line], line++ < actlines && pos[0] != '\0')
  1208. X        if (STREQN(pos, ng, nglen) && pos[nglen] == ' ')
  1209. X            return pos;
  1210. X    return NULL;
  1211. X}
  1212. X
  1213. X/* ARGSUSED */
  1214. Xstatust
  1215. Xactfwrnum(fp, pos)
  1216. XFILE *fp;
  1217. Xchar *pos;
  1218. X{
  1219. X    return ST_OKAY;
  1220. X}
  1221. !
  1222. echo 'libbig/sys.fast.c':
  1223. sed 's/^X//' >'libbig/sys.fast.c' <<'!'
  1224. X/*
  1225. X * news sys file reading functions (fast, big, in-memory version)
  1226. X */
  1227. X
  1228. X#include <stdio.h>
  1229. X#include <sys/types.h>
  1230. X#include "news.h"
  1231. X#include "system.h"
  1232. X
  1233. X/* imports */
  1234. Xextern struct system *currsys, *firstsys;
  1235. X
  1236. X/* exports */
  1237. Xboolean justone = NO;
  1238. X
  1239. X/* private */
  1240. Xstatic struct system *thissys = NULL;
  1241. X
  1242. X/* ARGSUSED */
  1243. Xvoid
  1244. Xrewsys(fp)
  1245. XFILE *fp;
  1246. X{
  1247. X    currsys = firstsys;
  1248. X}
  1249. X
  1250. Xstruct system *
  1251. Xmysysincache()                /* optimisation */
  1252. X{
  1253. X    return thissys;
  1254. X}
  1255. X
  1256. Xvoid
  1257. Xremmysys(sys)                /* remember this system */
  1258. Xstruct system *sys;
  1259. X{
  1260. X    thissys = sys;
  1261. X}
  1262. X
  1263. Xvoid
  1264. Xfreecurrsys()
  1265. X{
  1266. X    /* never free sys entries */
  1267. X}
  1268. !
  1269. echo 'libbig/Makefile':
  1270. sed 's/^X//' >'libbig/Makefile' <<'!'
  1271. X# libbig makefile
  1272. XINCLUDE=../include
  1273. XDEFINES=-I$(INCLUDE) -I../relay
  1274. XCOPTS= -O # -g -p -pg
  1275. XCFLAGS= $(COPTS) $(DEFINES)
  1276. XLINTFLAGS=-hau $(DEFINES)
  1277. XLIB=libbig.a
  1278. X# RANLIB is ranlib on non-USG systems, echo on USG systems
  1279. XRANLIB=ranlib
  1280. X#RANLIB=:
  1281. XSRCS=active.fast.c sys.fast.c
  1282. XOBJS=active.fast.o sys.fast.o
  1283. X# workaround for System V make bug
  1284. XSHELL = /bin/sh
  1285. X
  1286. Xu:    $(OBJS)
  1287. X    ar ruv ../libcnews.a $(OBJS)
  1288. X
  1289. Xall:    $(OBJS)
  1290. X
  1291. X$(LIB): $(SRCS)
  1292. X    $(CC) $(CFLAGS) -c $?
  1293. X    ar rv $@ *.o
  1294. X    rm *.o
  1295. X    $(RANLIB) $@
  1296. X
  1297. Xlint:
  1298. X    lint $(LINTFLAGS) $(SRCS)
  1299. X
  1300. Xclean:
  1301. X    rm -f *.o
  1302. !
  1303. echo 'libbsd42/clsexec.c':
  1304. sed 's/^X//' >'libbsd42/clsexec.c' <<'!'
  1305. X/*
  1306. X * set close on exec (on Berklix)
  1307. X */
  1308. X
  1309. X#include <stdio.h>
  1310. X#include <sgtty.h>
  1311. X
  1312. Xvoid
  1313. Xfclsexec(fp)
  1314. XFILE *fp;
  1315. X{
  1316. X    (void) ioctl(fileno(fp), FIOCLEX, (char *)NULL);
  1317. X}
  1318. !
  1319. echo 'libbsd42/getcwd.c':
  1320. sed 's/^X//' >'libbsd42/getcwd.c' <<'!'
  1321. X/*
  1322. X * SystemV getcwd simulation on 4.2BSD
  1323. X */
  1324. X
  1325. X#include <stdio.h>
  1326. X#include <sys/param.h>
  1327. X
  1328. X/* imports from libc */
  1329. Xextern char *getwd();
  1330. Xextern char *strncpy();
  1331. X
  1332. Xchar *
  1333. Xgetcwd(path, size)
  1334. Xregister char *path;
  1335. Xint size;
  1336. X{
  1337. X    if (size >= MAXPATHLEN)
  1338. X        return getwd(path);
  1339. X    else {
  1340. X        char wd[MAXPATHLEN];
  1341. X
  1342. X        if (getwd(wd) == 0)
  1343. X            return 0;
  1344. X        else {
  1345. X            (void) strncpy(path, wd, size-1);
  1346. X            path[size-1] = '\0';
  1347. X            return path;
  1348. X        }
  1349. X    }
  1350. X}
  1351. !
  1352. echo 'libbsd42/fopenexcl.c':
  1353. sed 's/^X//' >'libbsd42/fopenexcl.c' <<'!'
  1354. X/*
  1355. X * fopenexcl(name) - fopen(name, "w") with error if name exists (Berklix)
  1356. X */
  1357. X
  1358. X#include <stdio.h>
  1359. X#include <sys/types.h>
  1360. X#include <sys/file.h>        /* 4.2's O_EXCL defn */
  1361. X
  1362. XFILE *
  1363. Xfopenexcl(name)
  1364. Xregister char *name;
  1365. X{
  1366. X    /* This is the cheaper way. */
  1367. X    register int fd = open(name, O_WRONLY|O_CREAT|O_EXCL, 0666);
  1368. X
  1369. X    if (fd < 0)
  1370. X        return NULL;        /* name existed or couldn't be made */
  1371. X    else
  1372. X        return fdopen(fd, "w");
  1373. X}
  1374. !
  1375. echo 'libbsd42/Makefile':
  1376. sed 's/^X//' >'libbsd42/Makefile' <<'!'
  1377. X# C news libbsd42 makefile
  1378. XINCLUDE = ../include
  1379. XDEFINES=-I$(INCLUDE)
  1380. XCOPTS=-O  # -g -p
  1381. XCFLAGS=$(COPTS) $(DEFINES)
  1382. XLINTFLAGS=-hau $(DEFINES)
  1383. X# workaround for System V make bug
  1384. XSHELL = /bin/sh
  1385. X
  1386. XSRCS = clsexec.c fopenexcl.c getcwd.c
  1387. XOBJS = clsexec.o fopenexcl.o getcwd.o
  1388. X
  1389. X# RANLIB is ranlib on non-USG systems, echo on USG systems
  1390. XRANLIB=ranlib
  1391. X
  1392. Xu:    $(OBJS)
  1393. X    ar ruv ../libcnews.a $(OBJS)
  1394. X
  1395. Xall:    $(OBJS)
  1396. X
  1397. Xlibbsd42.a: $(SRCS)
  1398. X    $(CC) $(CFLAGS) -c $?
  1399. X    ar ru $@ *.o
  1400. X    rm *.o
  1401. X    $(RANLIB) $@
  1402. Xlint:
  1403. X    lint $(LINTFLAGS) $(SRCS)
  1404. X
  1405. Xclean:
  1406. X    rm -f *.o
  1407. !
  1408. echo 'libc/Makefile':
  1409. sed 's/^X//' >'libc/Makefile' <<'!'
  1410. X# C news local libc makefile - added by Ian Darwin
  1411. XINCLUDE=../include
  1412. XDEFINES=-I$(INCLUDE)
  1413. XCOPTS=-O # -g -p
  1414. XCFLAGS=$(COPTS) $(DEFINES)
  1415. XLINTFLAGS=-hau $(DEFINES)
  1416. X# workaround for System V make bug
  1417. XSHELL = /bin/sh
  1418. X
  1419. XSRCS=closeall.c efopen.c error.c fgetmfs.c \
  1420. X    nfclose.c \
  1421. X    standard.c stdfdopen.c warning.c emalloc.c
  1422. XOBJS = closeall.o efopen.o error.o fgetmfs.o getdate.o nfclose.o \
  1423. X    standard.o stdfdopen.o warning.o emalloc.o
  1424. X
  1425. X# RANLIB is ranlib on non-USG systems, echo on USG systems
  1426. XRANLIB=ranlib
  1427. X#RANLIB=echo
  1428. X
  1429. Xu:    $(OBJS)
  1430. X    ar ruv ../libcnews.a $(OBJS)
  1431. X
  1432. Xall:    $(OBJS)
  1433. X
  1434. Xlibc.a:    $(SRCS)
  1435. X    $(CC) $(CFLAGS) -c $?
  1436. X    ar ru $@ *.o
  1437. X    rm *.o
  1438. X    $(RANLIB) $@
  1439. Xlint:
  1440. X    lint $(LINTFLAGS) $(SRCS)
  1441. X
  1442. Xclean:
  1443. X    rm -f *.o *.a getdate.c y.*.h y.*.c
  1444. !
  1445. echo 'libc/emalloc.c':
  1446. sed 's/^X//' >'libc/emalloc.c' <<'!'
  1447. X/*
  1448. X * emalloc - malloc with error() called when out of space
  1449. X */
  1450. X
  1451. X#include <stdio.h>
  1452. X#include <sys/types.h>
  1453. X#include "libc.h"
  1454. X
  1455. Xextern void error();
  1456. X
  1457. Xchar *
  1458. Xemalloc(amount)
  1459. Xunsigned amount;
  1460. X{
  1461. X    register char *it;
  1462. X    char camount[25];        /* Enough to sprintf an unsigned. */
  1463. X
  1464. X    it = malloc(amount);
  1465. X    if (it == NULL) {
  1466. X        sprintf(camount, "%u", amount);
  1467. X        error("malloc(%s) failed", camount);
  1468. X    }    
  1469. X
  1470. X    return(it);
  1471. X}
  1472. !
  1473. echo 'libc/fgetmfs.3':
  1474. sed 's/^X//' >'libc/fgetmfs.3' <<'!'
  1475. X.TH FGETMFS 3 local
  1476. X.DA 23 May 1989
  1477. X.SH NAME
  1478. Xfgetmfs \- read an arbitrarily long, possibly continued line
  1479. X.SH SYNOPSIS
  1480. X.B "#include <stdio.h>
  1481. X.br
  1482. X.B "#include <fgetmfs.h>
  1483. X.PP
  1484. X.B "char *fgetmfs(stream, limit, cont)"
  1485. X.br
  1486. X.B "FILE *stream;"
  1487. X.br
  1488. X.B "int limit, cont;"
  1489. X.PP
  1490. X.B "char *fgetms(stream)
  1491. X.br
  1492. X.B "FILE *stream;"
  1493. X.PP
  1494. X.B "char *cfgetms(stream)
  1495. X.br
  1496. X.B "FILE *stream;"
  1497. X.SH DESCRIPTION
  1498. X.I Fgetmfs
  1499. Xreads an arbitrarily long line from
  1500. X.IR stream ,
  1501. Xallocating memory via
  1502. X.IR malloc (3)
  1503. Xas needed.
  1504. XIf
  1505. X.I limit
  1506. Xis non-negative,
  1507. X.I fgetmfs
  1508. Xwill read no more than
  1509. X.I limit
  1510. Xbytes from
  1511. X.IR stream .
  1512. XFor efficiency,
  1513. Xif
  1514. X.I cont
  1515. Xis not
  1516. X.IR CONT_NO ,
  1517. Xsuch as
  1518. X.I CONT_NOSPC
  1519. Xor
  1520. X.IR CONT_SPC ,
  1521. Xoccurrences of a backslash and a newline together
  1522. Xand in that order
  1523. Xwill be deleted from the input stream;
  1524. Xif
  1525. X.I cont
  1526. Xis
  1527. X.IR CONT_NOSPC ,
  1528. Xany whitespace after the newline
  1529. Xin the input stream will also be deleted from it.
  1530. X.PP
  1531. XThe macros
  1532. X.I fgetms
  1533. X(to read without continuations)
  1534. Xand
  1535. X.I cfgetms
  1536. X(to read with continuations and remove leading whitespace)
  1537. Xshould be used instead when the
  1538. X.I limit
  1539. Xis not needed.
  1540. X.PP
  1541. X.I Fgetmfs
  1542. Xis intended to provide a reliable mechanism for reading
  1543. Xinput containing lines of arbitrary length,
  1544. Xrather than trusting that no line with be longer than some
  1545. Xarbitrary tolerance.
  1546. X.PP
  1547. XThe memory returned by
  1548. X.I fgetmfs
  1549. Xshould be returned when no longer needed via
  1550. X.IR free (3).
  1551. X.\" .SH FILES
  1552. X.SH SEE ALSO
  1553. X.IR malloc (3),
  1554. X.IR fgets (3)
  1555. X.SH DIAGNOSTICS
  1556. XReturns NULL (0) if memory cannot be allocated or upon reading end-of-file;
  1557. Xuse
  1558. X.I feof(stream)
  1559. Xto distinguish.
  1560. X.SH HISTORY
  1561. XWritten by Geoff Collyer
  1562. Xat the University of Toronto
  1563. Xas part of the C news project.
  1564. X.SH BUGS
  1565. XIt's too slow.
  1566. X.br
  1567. XThe meaning of the
  1568. X.I cont
  1569. Xflag is ugly,
  1570. Xbut layering this form of continuation on top is even slower.
  1571. !
  1572. echo 'libc/fgetmfs.c':
  1573. sed 's/^X//' >'libc/fgetmfs.c' <<'!'
  1574. X/*
  1575. X * fgetmfs - read an arbitrarily long, possibly continued line;
  1576. X * return a pointer to it, in malloced memory.
  1577. X */
  1578. X
  1579. X#include <stdio.h>
  1580. X#include <ctype.h>
  1581. X#include <sys/types.h>
  1582. X#include <fgetmfs.h>
  1583. X#include "libc.h"
  1584. X
  1585. X#define max(a,b) ((a) > (b)? (a): (b))
  1586. X#define min(a,b) ((a) < (b)? (a): (b))
  1587. X
  1588. X/* One could make these arguments, with defaults. */
  1589. X#define INITLN 90        /* initial allocation per line */
  1590. X#define GROWLN 200        /* additional allocation size */
  1591. X
  1592. X/* getseg returns */
  1593. X#define FAILED 0
  1594. X#define HITLIMIT 1
  1595. X#define OKAY 2
  1596. X
  1597. Xstatic unsigned sz;        /* bytes currently allocated (in line) */
  1598. Xstatic int incr;        /* for sz */
  1599. Xstatic char *line;        /* current allocation */
  1600. Xstatic char *segment;        /* start of line segment in "line" */
  1601. Xstatic char *morep;        /* last byte possibly containing input */
  1602. X
  1603. X/*
  1604. X * `fget malloced, flagged string' with continuations and limit on bytes.
  1605. X * The limit is like fgets's; limit-1 bytes can be read.  -1 means "no limit".
  1606. X */
  1607. Xchar *
  1608. Xfgetmfs(fp, limit, cont)
  1609. XFILE *fp;
  1610. Xregister int limit, cont;        /* honour \ continuations? */
  1611. X{
  1612. X    /* allocate room for an initial segment of a line */
  1613. X    sz = INITLN;
  1614. X    incr = GROWLN;
  1615. X    if (limit >= 0 && sz > limit)
  1616. X        sz = limit;
  1617. X    line = malloc(sz);
  1618. X    if (line == NULL)
  1619. X        return NULL;        /* no memory, can't go on */
  1620. X    segment = line;
  1621. X    morep = line + sz - 2;
  1622. X
  1623. X    /* read all lines, including continuations */
  1624. X    do {
  1625. X        /* read the first segment of a line */
  1626. X        *morep = '\0';            /* mark end of segment */
  1627. X        if (fgets(segment, (int)sz-(segment-line), fp) == NULL) {
  1628. X            free(line);        /* EOF: give up */
  1629. X            return NULL;
  1630. X        }
  1631. X
  1632. X        /* read more of this line, if it didn't fit */
  1633. X        while (*morep != '\0' && *morep != '\n') {
  1634. X            register int code = getseg(fp, limit);
  1635. X
  1636. X            if (code == FAILED)
  1637. X                return NULL;
  1638. X            else if (code == HITLIMIT)
  1639. X                break;
  1640. X        }
  1641. X    } while (cont && ismore(fp, cont));
  1642. X    return realloc(line, (unsigned)(strlen(line)+1));    /* save space */
  1643. X}
  1644. X
  1645. Xstatic int
  1646. Xgetseg(fp, limit)
  1647. XFILE *fp;
  1648. Xregister int limit;
  1649. X{
  1650. X    register int oldsz = sz;
  1651. X
  1652. X    /* extend the allocation, within limit */
  1653. X    incr = GROWLN;
  1654. X    sz += incr;
  1655. X    if (limit >= 0 && sz > limit) {
  1656. X        sz = limit;
  1657. X        incr = sz - oldsz;
  1658. X    }
  1659. X    if (incr <= 0)            /* hit the limit? */
  1660. X        return HITLIMIT;
  1661. X    line = realloc(line, sz);
  1662. X    if (line == NULL)
  1663. X        return FAILED;        /* no memory, can't go on */
  1664. X    /* -1 starts on the terminating NUL of the prev. segment */
  1665. X    segment = line + oldsz - 1;
  1666. X    morep = line + sz - 2;        /* recompute for new line, sz */
  1667. X
  1668. X    /* read the next segment */
  1669. X    *morep = '\0';
  1670. X    /* +1 because segment includes terminating NUL of the prev. segment */
  1671. X    if (fgets(segment, incr+1, fp) == NULL) {
  1672. X        free(line);        /* EOF: give up */
  1673. X        return FAILED;
  1674. X    }
  1675. X    return OKAY;
  1676. X}
  1677. X
  1678. Xstatic int
  1679. Xismore(fp, cont)
  1680. Xregister FILE *fp;
  1681. Xint cont;
  1682. X{
  1683. X    register char *nlp;
  1684. X
  1685. X    /* got a whole line: is it to be continued? */
  1686. X    if (incr > 0 && cont && (nlp = rindex(line, '\n')) != NULL &&
  1687. X        nlp > line && *--nlp == '\\') {
  1688. X        *nlp = '\0';            /* delete "\\\n" */
  1689. X        segment = nlp;
  1690. X            if (cont == CONT_NOSPC) {
  1691. X            register int c;
  1692. X
  1693. X            /* discard leading whitespace */
  1694. X            while ((c = getc(fp)) != EOF && c != '\n' &&
  1695. X               isascii(c) && isspace(c))
  1696. X                ;
  1697. X            if (c != EOF)
  1698. X                (void) ungetc(c, fp);
  1699. X            }
  1700. X        return 1;            /* read next line */
  1701. X    } else
  1702. X        return 0;
  1703. X}
  1704. !
  1705. echo 'libc/standard.c':
  1706. sed 's/^X//' >'libc/standard.c' <<'!'
  1707. X#define    NULL    0
  1708. X
  1709. Xextern void closeall();
  1710. Xextern char    **environ;
  1711. X
  1712. Xstatic char    *stdenv[] = {
  1713. X/* =()<    "PATH=@<NEWSPATH>@",>()=    */
  1714. X    "PATH=/bin:/usr/bin",
  1715. X    "IFS= \t\n",
  1716. X    NULL
  1717. X};
  1718. X
  1719. Xvoid
  1720. Xstandard()
  1721. X{
  1722. X    environ = stdenv;
  1723. X    closeall(1);
  1724. X}
  1725. X
  1726. Xvoid
  1727. Xsafe()
  1728. X{
  1729. X    setgid(getgid());
  1730. X    setuid(getuid());
  1731. X    closeall(1);
  1732. X}
  1733. !
  1734. echo 'libc/stdfdopen.c':
  1735. sed 's/^X//' >'libc/stdfdopen.c' <<'!'
  1736. X/*
  1737. X * stdfdopen - ensure that the standard i/o descriptors are open,
  1738. X *    to avoid mayhem.
  1739. X */
  1740. X
  1741. X#include <stdio.h>
  1742. X#include <errno.h>
  1743. X#include <sys/types.h>
  1744. X#include <sys/stat.h>
  1745. X
  1746. X#ifndef NSYSFILE
  1747. X#define NSYSFILE 3                    /* hmm, not on V8 */
  1748. X#endif
  1749. X
  1750. Xextern int errno;
  1751. X
  1752. Xvoid
  1753. Xstdfdopen()            /* ensure standard descriptors are open */
  1754. X{
  1755. X    register int fd;
  1756. X    struct stat stbuf;
  1757. X
  1758. X    for (fd = 0; fd < NSYSFILE; fd++)
  1759. X        if (fstat(fd, &stbuf) < 0 && errno == EBADF)
  1760. X            if (open("/dev/null", 2) != fd)    /* open read/write */
  1761. X                exit(1);        /* bad news */
  1762. X}
  1763. !
  1764. echo 'libc/error.3':
  1765. sed 's/^X//' >'libc/error.3' <<'!'
  1766. X.TH ERROR 3 local
  1767. X.DA 8 May 1984
  1768. X.SH NAME
  1769. Xerror, warning \- print error messages
  1770. X.SH SYNOPSIS
  1771. X.nf
  1772. X.B error(s1, s2)
  1773. X.B char *s1;
  1774. X.B char *s2;
  1775. X
  1776. X.B warning(s1, s2)
  1777. X.B char *s1;
  1778. X.B char *s2;
  1779. X
  1780. X.B extern char *progname;
  1781. X.B extern int errno;
  1782. X
  1783. X.B progname = argv[0];
  1784. X.SH DESCRIPTION
  1785. X.I Warning
  1786. Xprints an error message, with suitable embellishments,
  1787. Xand clears
  1788. X.IR errno .
  1789. X.I Error
  1790. Xdoes likewise and then exits.
  1791. XThe
  1792. X.I s1
  1793. Xargument should be a
  1794. X.I printf
  1795. Xformat string (without a trailing newline), with
  1796. X.I s2
  1797. Xavailable as an argument.
  1798. X.PP
  1799. XIf there is an environment variable
  1800. X.BR CMDNAME
  1801. Xwith non-null value,
  1802. Xits contents are printed first, followed by a colon.
  1803. XFollowing this,
  1804. Xany non-null value of
  1805. X.I progname
  1806. Xis printed, followed by a colon and a space.
  1807. XFollowing this,
  1808. X.IR fprintf (3)
  1809. Xis invoked with
  1810. X.I s1
  1811. Xas the format string and
  1812. X.I s2
  1813. Xas the argument.
  1814. XIf the value of
  1815. X.I errno
  1816. Xis within the normal range,
  1817. Xa standard elaborating message is printed (see
  1818. X.IR intro (2)).
  1819. X.PP
  1820. X.B CMDNAME
  1821. Xshould be set by shellfiles that expect subordinate programs to
  1822. Xissue error message in the shellfile's name.
  1823. X.I Progname
  1824. Xshould be set by all programs;
  1825. X.I argv[0]
  1826. Xis usually a suitable thing to set it to.
  1827. X.I Errno
  1828. Xis set by system calls and various other routines,
  1829. Xalthough its use is not universal;
  1830. Xnote that it is not reset by successful system calls following an
  1831. Xunsuccessful one.
  1832. X.SH SEE ALSO
  1833. Xintro(2), intro(3), printf(3), exit(2), getopt(3)
  1834. X.SH DIAGNOSTICS
  1835. X.IR Error 's
  1836. Xexit status is 1.
  1837. X.SH HISTORY
  1838. XLocal products, modelled on the
  1839. X.I error
  1840. Xin Kernighan&Pike.
  1841. X.SH BUGS
  1842. XBe nice if they could take a full
  1843. X.IR printf -style
  1844. Xargument list.
  1845. !
  1846. echo 'libc/error.c':
  1847. sed 's/^X//' >'libc/error.c' <<'!'
  1848. X/*
  1849. X * error - print best error message possible and exit
  1850. X */
  1851. X
  1852. X#include <stdio.h>
  1853. X
  1854. Xextern void warning();
  1855. X
  1856. Xvoid
  1857. Xerror(s1, s2)
  1858. Xchar *s1;
  1859. Xchar *s2;
  1860. X{
  1861. X    warning(s1, s2);
  1862. X    exit(1);
  1863. X}
  1864. !
  1865. echo 'libc/warning.c':
  1866. sed 's/^X//' >'libc/warning.c' <<'!'
  1867. X/*
  1868. X * warning - print best error message possible and clear errno
  1869. X */
  1870. X
  1871. X#include <stdio.h>
  1872. X
  1873. Xvoid
  1874. Xwarning(s1, s2)
  1875. Xchar *s1;
  1876. Xchar *s2;
  1877. X{
  1878. X    char *cmdname;
  1879. X    extern int errno, sys_nerr;
  1880. X    extern char *sys_errlist[];
  1881. X    extern char *progname;
  1882. X    extern char *getenv();
  1883. X
  1884. X    (void) fflush(stdout);                /* hack */
  1885. X    cmdname = getenv("CMDNAME");
  1886. X    if (cmdname != NULL && *cmdname != '\0')
  1887. X        fprintf(stderr, "%s:", cmdname);    /* No space after :. */
  1888. X    if (progname != NULL)
  1889. X        fprintf(stderr, "%s: ", progname);
  1890. X    fprintf(stderr, s1, s2);
  1891. X    if (errno > 0 && errno < sys_nerr)
  1892. X        fprintf(stderr, " (%s)", sys_errlist[errno]);
  1893. X    fprintf(stderr, "\n");
  1894. X    errno = 0;
  1895. X}
  1896. !
  1897. echo 'libc/standard.3':
  1898. sed 's/^X//' >'libc/standard.3' <<'!'
  1899. X.TH STANDARD 3 local
  1900. X.DA 9 Feb 1982
  1901. X.SH NAME
  1902. Xstandard, safe \- standardize conditions in preparation for exec
  1903. X.SH SYNOPSIS
  1904. X.B standard()
  1905. X.PP
  1906. X.B safe()
  1907. X.SH DESCRIPTION
  1908. X.I Standard
  1909. Xalters a process's environment to make it relatively safe to do
  1910. X.IR execvp ,
  1911. X.IR system ,
  1912. X.IR popen ,
  1913. Xetc.
  1914. XIt closes all descriptors except
  1915. Xthe standard ones and supplies a standard set of environment variables
  1916. Xthat ensure a standard interpretation of shell commands and a
  1917. Xstandard search path for programs.
  1918. X.PP
  1919. X.I Safe
  1920. Xis similar, but is intended for use in shell escapes and suchlike.
  1921. XIt leaves the environment variables untouched but turns off
  1922. Xsetuid and setgid permissions.
  1923. X.PP
  1924. XUse of either one permits a setuid/setgid program to
  1925. Xrun other programs without inadvertently bestowing special powers
  1926. Xon nonstandard programs.
  1927. XCare must still be exercised as to what the standard descriptors
  1928. Xrefer to,
  1929. Xand it is still possible for
  1930. Xprograms executed after use of
  1931. X.I standard
  1932. X(as opposed to
  1933. X.IR safe )
  1934. Xto give away special powers through
  1935. X.I their
  1936. Xcarelessness.
  1937. X.SH SEE ALSO
  1938. Xenviron(3), closeall(3)
  1939. X.SH HISTORY
  1940. XLocal products.
  1941. X.SH BUGS
  1942. X.I Standard
  1943. Xmust necessarily supply standard values for some environment variables,
  1944. Xbut it is not clear whether it should pass other variables
  1945. Xthrough or eliminate them.
  1946. XThe current implementation eliminates them, which is safer but sometimes
  1947. Xinconvenient.
  1948. X.PP
  1949. XOne can construct elaborate scenarios in which a setuid
  1950. Xprogram employing
  1951. X.I safe
  1952. Xcould be duped into
  1953. Xexecuting a user-supplied program in a current directory
  1954. Xthe user ordinarily could not have reached.
  1955. X.PP
  1956. XPossibly
  1957. Xone or both should standardize the
  1958. X.I umask
  1959. Xsetting.
  1960. !
  1961. echo 'libc/closeall.3':
  1962. sed 's/^X//' >'libc/closeall.3' <<'!'
  1963. X.TH CLOSEALL 3 local
  1964. X.DA 9 Feb 1982
  1965. X.SH NAME
  1966. Xcloseall \- close all files
  1967. X.SH SYNOPSIS
  1968. X.ft B
  1969. Xcloseall(leavestd)
  1970. X.br
  1971. Xint leavestd;
  1972. X.ft R
  1973. X.SH DESCRIPTION
  1974. X.I Closeall
  1975. Xcloses all currently-open file descriptors.
  1976. XIf
  1977. X.I leavestd
  1978. Xis non-zero,
  1979. Xthe standard input, output, and diagnostic descriptors are left open;
  1980. Xotherwise they are closed too.
  1981. X.SH SEE ALSO
  1982. Xclose(2), standard(3)
  1983. X.SH HISTORY
  1984. XLocal invention.
  1985. X.SH BUGS
  1986. XNothing wrong with
  1987. X.IR closeall ,
  1988. Xbut there ought to be an
  1989. X.IR fcloseall .
  1990. !
  1991. echo 'libc/closeall.c':
  1992. sed 's/^X//' >'libc/closeall.c' <<'!'
  1993. X#include <sys/param.h>
  1994. X
  1995. Xvoid
  1996. Xcloseall(leavestd)
  1997. Xint leavestd;
  1998. X{
  1999. X    register int i;
  2000. X
  2001. X    for (i = (leavestd? 3: 0); i < NOFILE; i++)
  2002. X        close(i);
  2003. X}
  2004. !
  2005. echo 'libc/README':
  2006. sed 's/^X//' >'libc/README' <<'!'
  2007. XThese should, ideally, be inserted into your C library if they aren't
  2008. Xthere already.  If they can't be put into your C library nor -llocal,
  2009. Xjust put the ones not in your C library into libc.a in this directory.
  2010. X
  2011. XThey were all written by either Henry Spencer, Geoff Collyer or Brian
  2012. XKernighan & Rob Pike.
  2013. !
  2014. echo 'libc/efopen.3':
  2015. sed 's/^X//' >'libc/efopen.3' <<'!'
  2016. X.TH EFOPEN 3 local
  2017. X.DA 24 April 1984
  2018. X.SH NAME
  2019. Xefopen \- open a stream, checking for errors
  2020. X.SH SYNOPSIS
  2021. X.nf
  2022. X.B FILE *
  2023. X.B efopen(file, mode)
  2024. X.B char *file;
  2025. X.B char *mode;
  2026. X.SH DESCRIPTION
  2027. X.I Efopen
  2028. Xinvokes
  2029. X.IR fopen (3)
  2030. Xand checks the result for errors.
  2031. XIn the absence of errors, it returns the stream pointer;
  2032. Xin the presence of errors, it prints a message and exits.
  2033. X.SH SEE ALSO
  2034. Xfopen(3), error(3)
  2035. X.SH DIAGNOSTICS
  2036. XExit status, in the event of error, is 1.
  2037. X.SH HISTORY
  2038. XLocal product, roughly following the one in Kernighan&Pike.
  2039. !
  2040. echo 'libc/efopen.c':
  2041. sed 's/^X//' >'libc/efopen.c' <<'!'
  2042. X/*
  2043. X * efopen - fopen file, exit with message if impossible
  2044. X */
  2045. X
  2046. X#include <stdio.h>
  2047. X
  2048. X/* imports from libc */
  2049. Xextern char *strcpy(), *strncat();
  2050. Xextern void error();
  2051. X
  2052. Xstatic char message[] = "can't open file \"%s\" mode ";
  2053. X
  2054. XFILE *
  2055. Xefopen(file, mode)
  2056. Xchar *file;
  2057. Xchar *mode;
  2058. X{
  2059. X    FILE *fp;
  2060. X    char fullmsg[sizeof(message)+10];
  2061. X    extern int errno;
  2062. X
  2063. X    errno = 0;        /* Wipe out residue of earlier errors. */
  2064. X    fp = fopen(file, mode);
  2065. X    if (fp == NULL) {
  2066. X        (void) strcpy(fullmsg, message);
  2067. X        (void) strncat(fullmsg, mode, 10);
  2068. X        error(fullmsg, file);
  2069. X        /* NOTREACHED */
  2070. X    }
  2071. X    return(fp);
  2072. X}
  2073. !
  2074. echo done
  2075.  
  2076.  
  2077.