home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2031 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  45.4 KB

  1. From: vixie@wrl.dec.com (Paul Vixie)
  2. Newsgroups: comp.lang.perl,alt.sources
  3. Subject: Re: uucp map browser in perl?
  4. Message-ID: <1990Nov6.081214.14486@wrl.dec.com>
  5. Date: 6 Nov 90 08:12:14 GMT
  6.  
  7. # Before someone goes and reinvents another wheel...  does anyone have
  8. # any perl scripts for searching or browsing the Uucp maps?
  9. # -- 
  10. # Richard Foulk        richard@pegasus.com
  11.  
  12. Here's what we use here.  Complete but not documented.  Includes the
  13. "unpackmaps" unpacker, the IDA "dbm" command, the smail "lcasep" command,
  14. and probably other junk from other sources.  Only the index-builder and
  15. browser are currently mine.
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of shell archive."
  24. # Contents:  INFO.costs Makefile README.unpackmaps dbm.c get.pl
  25. #   lcasep.c list.pl mailpath.sh makefile.libd.src mkall.pl
  26. #   mkmap.pl.src mkone.pl unpackmaps.sh uuhost.sh uupath.sh uupaths.sh
  27. #   wrl-uumap.pl.src
  28. # Wrapped by vixie@jove.pa.dec.com on Tue Nov  6 00:09:01 1990
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'INFO.costs' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'INFO.costs'\"
  32. else
  33. echo shar: Extracting \"'INFO.costs'\" \(401 characters\)
  34. sed "s/^X//" >'INFO.costs' <<'END_OF_FILE'
  35. X          LOCAL       25   (local-area network connection)
  36. X          DEDICATED   95   (high speed dedicated link)
  37. X          DIRECT     200   (toll-free call)
  38. X          DEMAND     300   (long-distance call)
  39. X          HOURLY     500   (hourly poll)
  40. X          EVENING   1800   (time restricted call)
  41. X          DAILY     5000   (daily poll, also called POLLED)
  42. X          WEEKLY   30000   (irregular poll)
  43. END_OF_FILE
  44. if test 401 -ne `wc -c <'INFO.costs'`; then
  45.     echo shar: \"'INFO.costs'\" unpacked with wrong size!
  46. fi
  47. # end of 'INFO.costs'
  48. fi
  49. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  50.   echo shar: Will not clobber existing file \"'Makefile'\"
  51. else
  52. echo shar: Extracting \"'Makefile'\" \(3058 characters\)
  53. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  54. X# Makefile for uucp map maintainance utilities
  55. X# originally from  @(#)Makefile    1.1 6/15/87 jbuck@epimass.epi.com
  56. X#
  57. X# vixie@decwrl.dec.com: BSD-ified, added other utilities from uucpmap package
  58. X#    21Sep88
  59. X
  60. NEWSUSR        =news
  61. LIBD        =/wrl/gen/lib/uumap
  62. MAPD        =$(LIBD)/maps
  63. BIND        =/usr/local/bin
  64. GENBIND        =/wrl/gen/bin
  65. MANL        =1
  66. MAND        =/usr/local/man/man$(MANL)
  67. PERLLIB        =/usr/local/lib/perl
  68. NEWSSPOOL    =/usr/spool/news
  69. BATCH        =/usr/spool/news/out.special/maps
  70. X
  71. X# pick the empty one if your ndbm routines are in your /lib/libc.a
  72. X#NDBM=
  73. X# pick this one if you have a libndbm.a file in /usr/lib or /usr/local/lib
  74. NDBM= -lndbm
  75. X
  76. CFLAGS        = -O
  77. INFO        = INFO.costs
  78. BIN_TARGETS    = lcasep dbm
  79. OTHER_TARGETS    = uuhost uupath uupaths makefile.libd mailpath unpackmaps \
  80. X            get list mkall mkone wrl-uumap.pl mkmap.pl
  81. TARGETS        = $(BIN_TARGETS) $(OTHER_TARGETS)
  82. X
  83. all:        $(TARGETS)
  84. X
  85. clean:;        rm -f $(TARGETS) *.o *.BAK *.CKP *~ .emacs*
  86. X
  87. lcasep:        lcasep.o
  88. X        cc -o lcasep lcasep.o
  89. X
  90. dbm:        dbm.o
  91. X        cc -o dbm dbm.o $(NDBM)
  92. X
  93. uupath:        uupath.sh Makefile
  94. X        sed -e 's?>BIND<?$(BIND)?g' -e 's?>LIBD<?$(LIBD)?g' $@.sh > $@
  95. X        chmod +x uupath
  96. X
  97. uupaths:    uupaths.sh Makefile
  98. X        sed -e 's?>LIBD<?$(LIBD)?g' $@.sh > $@
  99. X        chmod +x uupaths
  100. X
  101. mailpath:    mailpath.sh Makefile
  102. X        sed    <$@.sh >$@ \
  103. X            -e 's?>LIBD<?$(LIBD)?g' \
  104. X            -e 's?>BIND<?$(BIND)?g'
  105. X        chmod +x mailpath
  106. X
  107. unpackmaps:    unpackmaps.sh Makefile
  108. X        sed    <$@.sh >$@ \
  109. X            -e 's?>BATCH<?$(BATCH)?g' \
  110. X            -e 's?>NEWSSPOOL<?$(NEWSSPOOL)?g' \
  111. X            -e 's?>MAPDIR<?$(MAPD)?g'
  112. X        chmod +x unpackmaps
  113. X
  114. uuhost:        uuhost.sh Makefile
  115. X        sed    <$@.sh >$@ \
  116. X            -e 's?>LIBD<?$(LIBD)?g'
  117. X        chmod +x uuhost
  118. X
  119. get:        get.pl
  120. X        cp get.pl get
  121. X        chmod +x get
  122. X
  123. list:        list.pl
  124. X        cp list.pl list
  125. X        chmod +x list
  126. X
  127. mkall:        mkall.pl
  128. X        cp mkall.pl mkall
  129. X        chmod +x mkall
  130. X
  131. mkone:        mkone.pl
  132. X        cp mkone.pl mkone
  133. X        chmod +x mkone
  134. X
  135. mkmap.pl:    mkmap.pl.src
  136. X        cp mkmap.pl.src mkmap.pl
  137. X
  138. makefile.libd:    makefile.libd.src Makefile
  139. X        sed    <$@.src >$@ \
  140. X            -e 's?>MAPD<?$(MAPD)?g' \
  141. X            -e 's?>LIBD<?$(LIBD)?g' \
  142. X            -e 's?>BIND<?$(BIND)?g' \
  143. X            -e 's?>MAPS<?$(MAPS)?g'
  144. X
  145. wrl-uumap.pl:    wrl-uumap.pl.src Makefile
  146. X        sed    <$@.src >$@ \
  147. X            -e 's?>CODE<?$(LIBD)?g' \
  148. X            -e 's?>DATA<?$(LIBD)?g' \
  149. X            -e 's?>MAPS<?$(MAPD)?g'
  150. X
  151. install:    $(TARGETS) $(INFO)
  152. X        test -d $(LIBD) ||    mkdir $(LIBD); \
  153. X                    /etc/chown $(NEWSUSR) $(LIBD); \
  154. X                    /bin/chgrp $(NEWSUSR) $(LIBD); \
  155. X                    /bin/chmod 775 $(LIBD)
  156. X        test -d $(BIND) ||    mkdir $(BIND)
  157. X        -test -d $(MAND) ||    mkdir $(MAND)
  158. X        install -c -s -m 555 lcasep   $(BIND)/
  159. X        install -c -s -m 555 dbm      $(BIND)/
  160. X        install -c    -m 555 uuhost   $(GENBIND)/
  161. X        install -c    -m 555 uupath   $(GENBIND)/
  162. X        install -c    -m 555 uupaths  $(GENBIND)/
  163. X        install -c    -m 555 mailpath $(GENBIND)/
  164. X        install -c    -m 444 wrl-uumap.pl $(PERLLIB)/
  165. X        install -c    -m 444 mkmap.pl $(LIBD)/
  166. X        install -c    -m 555 get      $(LIBD)/
  167. X        install -c    -m 555 list     $(LIBD)/
  168. X        install -c    -m 555 mkall    $(LIBD)/
  169. X        install -c    -m 555 mkone    $(LIBD)/
  170. X        install -c    -m 555 unpackmaps $(LIBD)/
  171. X        install -c    -m 444 makefile.libd $(LIBD)/makefile
  172. X        install -c    -m 444 INFO.costs $(LIBD)/
  173. END_OF_FILE
  174. if test 3058 -ne `wc -c <'Makefile'`; then
  175.     echo shar: \"'Makefile'\" unpacked with wrong size!
  176. fi
  177. # end of 'Makefile'
  178. fi
  179. if test -f 'README.unpackmaps' -a "${1}" != "-c" ; then 
  180.   echo shar: Will not clobber existing file \"'README.unpackmaps'\"
  181. else
  182. echo shar: Extracting \"'README.unpackmaps'\" \(7475 characters\)
  183. sed "s/^X//" >'README.unpackmaps' <<'END_OF_FILE'
  184. X            UNPACKMAPS V3.0
  185. X              May 14 1990
  186. X              Chris Lewis
  187. X
  188. X    This README, unpackmaps and uuwhere are Copyright 1990 Chris Lewis,
  189. X    All Rights Reserved.
  190. X
  191. X    You can do anything you want with it, provided that this copyright
  192. X    notice remains intact, you don't claim you wrote it yourself, and you 
  193. X    don't make money selling it directly.  You may redistribute this as
  194. X    you wish, but if you modify it, you should clearly indicate in this
  195. X    README file that it has been modified, by whom, and describe what
  196. X    has been changed.  Reasonable copying charges are okay.
  197. X
  198. X    Though I have taken pains to ensure that this program is reasonably 
  199. X    reliable and secure, I cannot make any warrantee as to the reliability 
  200. X    or security of this software when used on any computer.  It is up to
  201. X    the user of this software to determine its suitability for their
  202. X    purposes and take responsibility for its operation.
  203. X
  204. This is source for a simple, *secure*, map unpacking facility.
  205. X
  206. It is much simpler than uuhosts, has roughly the same functionality,
  207. is easier to install, probably faster and more efficient (at least
  208. the versions I've seen w.r.t. compression), and is considerably less 
  209. vulnerable to trojan maps than most map unpackers that other people use.
  210. X(It has fewer vulnerabilities than uuhosts)
  211. X
  212. The intent is that any UNIX/XENIX/BSD system that can run news will
  213. be able to run this too, so I'm attempting to keep to greatest-common-
  214. denominator except for pathalias and things that I implement myself.
  215. X
  216. This release includes:
  217. X
  218. X    - map unpacking
  219. X    - pathalias operation plus hooks for path customization.
  220. X    - a mechanism for viewing map entries for arbitrary sites.
  221. X      ("uuwhere")
  222. X    - automatic map article deletion if desired.
  223. X
  224. This had been posted to comp.sources.misc about a year ago.  The
  225. prime differences here are that compress is run as a pipeline as stdin to
  226. pathalias, so you don't need to modify pathalias anymore, and the
  227. new "uuwhere" tool.  There is still no makefile because it wouldn't
  228. do anything useful.
  229. X
  230. Regarding security: as many may remember, there's been a fair bit of
  231. discussion on security of map unpacking on the net.  Rather than play
  232. around with trying to make a secure *true* unshar, which probably noone would
  233. trust because it would be so big, I simply made a few simplifying assumptions
  234. about the map format and use an awk script to unpack a map article into
  235. a map file.  It checks for and refuses to unpack articles which have
  236. slashes in their names.  I sent off some mail to Mel asking whether the
  237. assumptions I've made about map format are true, but never got any
  238. response.  I believe that this is *pretty* secure, in that it doesn't
  239. have to be run as root, doesn't use the Bourne shell for unpacking, and 
  240. is careful about the file names it creates.  Please let me know if there 
  241. are any holes I didn't think of.
  242. X
  243. General operation:
  244. X    - your news is modified to batch incoming map article file names
  245. X      to a specific batch file (analogous to normal news batching).  
  246. X      C-news users take note: you may have to utter magic incantations 
  247. X      (hint "classes" in C-news Alpha) to get sendbatches to avoid 
  248. X      trying to uux these...  Another way is to use an explicit batch 
  249. X      file name in the sys file that isn't under the usual "out.going"
  250. X      directories and point unpackmaps at it.
  251. X    - unpackmaps wakes up, usually once per day, and extracts the
  252. X      maps specified (if any) in the batch file into the map directory.
  253. X      Maps are extracted using a secure awk script without resort
  254. X      to setuid root or other wierdnesses.  If you want the uuwhere
  255. X      facility, unpackmaps will extract site->map file correspondences.
  256. X    - If any maps were extracted, pathalias is fired off, and the 
  257. X      resultant file put in the place specified.
  258. X    - If you've specified uuwhere, the where database will be regenerated.
  259. X    - if anything was done, unpackmaps sends you mail telling you
  260. X      what happened.
  261. X
  262. Installation:
  263. X    - If you want to compress the stored map files, set the COMPRESS
  264. X      variable to point your compress program.  You should be using
  265. X      compress versions 3 or 4.  A copy will have come with your
  266. X      news software.
  267. X
  268. X    - I STRONGLY recommend that you build a special version of compress
  269. X      with 12 bit compression instead of 16 for this.  When this
  270. X      is done, compress is considerably smaller (eg: bss of 32K instead
  271. X      of 400K+).  The reason for this is obvious - pathalias is enormous
  272. X      when it's running, and so is a 16 bit compress.  God help you if
  273. X      it starts to swap.
  274. X
  275. X      Advantages:
  276. X        - the whole thing runs considerably faster
  277. X        - much less swap/paging
  278. X        - on our machine, 16 bit compress practically hangs
  279. X          everyone else when run at the same time as pathalias.
  280. X
  281. X      Disadvantages:
  282. X        - the map directory is 10% (really!  only 10%!) bigger.
  283. X
  284. X      What I did was the following:
  285. X        - go to the source directory for compress
  286. X        - remove the binary if it is there.
  287. X        - say:
  288. X            make compress CFLAGS=-DUSERMEM=0
  289. X        - rename this to something like /usr/bin/compress12
  290. X        - make sure that uuwhere and unpackmaps shell scripts
  291. X          have the same name.  Eg: /usr/bin/compress12
  292. X
  293. X    - edit unpackmaps to set the variables at the beginning of
  294. X      the shell script.  Note especially the batch file name
  295. X      (see below)
  296. X    - make the directory for the map files, owned by news.
  297. X    - put unpackmaps in a suitable place.  Eg: /usr/lib/news
  298. X    - put uuwhere in a suitable place.  Eg: /usr/local/bin.
  299. X    - unpackmaps should be run from the userid that owns and runs news.
  300. X    - su to the news userid, and run:
  301. X        unpackmaps -i
  302. X      This will build the initial path file.
  303. X    - insert into your crontab something like:
  304. X        30 3 * * * /bin/su news -c "<path to unpackmaps>/unpackmaps > /dev/null"
  305. X    - insert into your news sys file something like:
  306. X
  307. X        (C-news)
  308. X
  309. X        maps:comp.mail.maps/all:f:/usr/spool/news/out.special/maps
  310. X
  311. X        (B-news)
  312. X
  313. X        maps:world,comp.mail.maps:F:/usr/spool/batch/maps
  314. X
  315. X    - copy uuwhere to an accessible bin directory after modifying
  316. X      the configuration section at the beginning.
  317. X    
  318. uuwhere "sitename" will give you the map name and line numbers where
  319. the site is defined (with #N comments).  Adding a -v option will
  320. invoke compress (if necessary) and show you the map entry itself.
  321. The uuwhere mechanism *only* works using the "#N" entries, and will
  322. not search for macro reassignments and other namings.  One other drawback
  323. is that uuwhere won't display whole map files directly, but that was
  324. never particularly useful anyways.
  325. X
  326. unpackmaps -i: will extract all map articles into the map spool area - useful
  327. for the first time you use it.
  328. X
  329. unpackmaps -p: runs pathalias even if no map articles were extracted.
  330. X
  331. In order to push the paths file into /usr/lib/uucp, I created a file called
  332. paths in /usr/lib/uucp, with 644 permissions, owned by the userid that runs
  333. unpackmaps.
  334. X
  335. The package will send mail to who you specify indicating which maps were
  336. unpacked, and any error returns from pathalias.
  337. X
  338. The uuwhere database is built from the maps as they are unpacked.  After
  339. installation, it may take a while for the where database to be complete.
  340. X(same as for path files themselves too).  I have implemented a binary
  341. search routine to make uuwhere go faster, but frankly, the sed's fast
  342. enough on all but the slowest machine.
  343. X
  344. Let me know of any changes you needed to make to get this to work.
  345. I'm also open to suggestions for new features....
  346. X----------
  347. Chris Lewis, Markham, Ontario, Canada
  348. X{uunet!attcan,utgpu,yunexus,utzoo}!lsuc!{ecicrl|eci386}!clewis
  349. END_OF_FILE
  350. if test 7475 -ne `wc -c <'README.unpackmaps'`; then
  351.     echo shar: \"'README.unpackmaps'\" unpacked with wrong size!
  352. fi
  353. # end of 'README.unpackmaps'
  354. fi
  355. if test -f 'dbm.c' -a "${1}" != "-c" ; then 
  356.   echo shar: Will not clobber existing file \"'dbm.c'\"
  357. else
  358. echo shar: Extracting \"'dbm.c'\" \(10914 characters\)
  359. sed "s/^X//" >'dbm.c' <<'END_OF_FILE'
  360. X/*
  361. X**  DBM -- General dbm management tool.
  362. X**  Copyright (c) 1987 Lennart Lovstrand
  363. X**  CIS Dept, Univ of Linkoping, Sweden
  364. X**
  365. X**  Use it, abuse it, but don't sell it.
  366. X*/
  367. X
  368. X#include <stdio.h>
  369. X#include <ctype.h>
  370. X#include <sys/file.h>
  371. X#ifdef MDBM
  372. X# include "mdbm_compat.h"
  373. X#else MDBM
  374. X# include <ndbm.h>
  375. X# define DBMFILE DBM
  376. X#endif MDBM
  377. X
  378. X#ifndef lint
  379. static char    SccsId[] = "@(#)dbm.c 2.0 (lel@ida.liu.se) 4/20/87";
  380. X#endif !lint
  381. X
  382. X#define TRUE 1
  383. X#define FALSE 0
  384. typedef int bool;
  385. X
  386. X#define    SAMECASE    0
  387. X#define LOWERCASE    1
  388. X#define UPPERCASE    2
  389. X
  390. X#define COMMENTCHAR    '#'
  391. X
  392. X#define streq(s, t)    (strcmp(s, t) == 0)
  393. X#define MAKEDATUM(d, s)    {(d).dptr = s; (d).dsize = strlen(s) + 1;}
  394. X
  395. void do_clear(), do_delete(), do_dump(), do_fetch(), do_load(), do_make(),
  396. X    do_parse(), do_store();
  397. X
  398. struct comtab {
  399. X    char *c_name;
  400. X    void (*c_func)();
  401. X} CommandTable[] = {
  402. X    {"clear",    do_clear},
  403. X    {"delete",    do_delete},
  404. X    {"dump",    do_dump},
  405. X    {"fetch",    do_fetch},
  406. X    {"load",    do_load},
  407. X    {"make",    do_make},
  408. X    {"parse",    do_parse},
  409. X    {"store",    do_store}
  410. X};
  411. X    
  412. X/* global arguments */
  413. int    Argc;
  414. char    **Argv;
  415. X
  416. X/* options */
  417. int    Appending = FALSE;
  418. int    Casing = SAMECASE;
  419. bool    Debug = FALSE;
  420. char    *Outfile = NULL;
  421. int    Mode = 0644;
  422. char    *Progname;
  423. bool    Senteniel = FALSE;
  424. int    Storeflag = DBM_INSERT;
  425. bool    Storewarn = TRUE;
  426. X
  427. X/* Dbm globals */
  428. DBMFILE    *Dbm;
  429. char    *Dbmfile = NULL;
  430. int    Dbmaccess;
  431. datum    key, val;
  432. X
  433. main(argc, argv)
  434. X     int argc;
  435. X     char **argv;
  436. X{
  437. X    extern int optind;
  438. X    extern char *optarg;
  439. X    char *scantoken();
  440. X    struct comtab *cmd;
  441. X    int c;
  442. X
  443. X    Argc = argc;
  444. X    Argv = argv;
  445. X
  446. X    Progname = Argv[0];
  447. X
  448. X    while ((c = getopt(Argc, Argv, "ADILRSUd:m:o:")) != EOF)
  449. X    switch (c) {
  450. X      case 'A':
  451. X        Appending = TRUE;
  452. X        break;
  453. X      case 'D':
  454. X        Debug = TRUE;
  455. X        break;
  456. X      case 'I':
  457. X        Storeflag = DBM_INSERT;
  458. X        Storewarn = FALSE;
  459. X        break;
  460. X      case 'L':
  461. X        Casing = LOWERCASE;
  462. X        break;
  463. X      case 'R':
  464. X        Storeflag = DBM_REPLACE;
  465. X        break;
  466. X      case 'S':
  467. X        Senteniel = TRUE;
  468. X        break;
  469. X      case 'U':
  470. X        Casing = UPPERCASE;
  471. X        break;
  472. X      case 'd':
  473. X        Dbmfile = optarg;
  474. X        break;
  475. X      case 'm':
  476. X        if (optarg[0] == '0')
  477. X        (void) sscanf(optarg, "%o", &Mode);
  478. X        else {
  479. X        (void) sscanf(optarg, "%d", &Mode);
  480. X        if (Mode == 0) {
  481. X            (void) fprintf(stderr, "%s: non-numeric mode: %s\n",
  482. X                   Progname, optarg);
  483. X            exit(1);
  484. X        }
  485. X        }
  486. X        break;
  487. X      case 'o':
  488. X        Outfile = optarg;
  489. X        break;
  490. X      default:
  491. X        (void) fprintf(stderr,
  492. X               "usage: %s [-ADILNRSU] [-d dbm_file] [-m mode] %s", 
  493. X               Progname, "[-o output_file] command [args]\n");
  494. X        exit(1);
  495. X    }
  496. X
  497. X    Argc -= optind;
  498. X    Argv += optind;
  499. X
  500. X    if (Argc > 0) {
  501. X    for (cmd = CommandTable; cmd < &CommandTable[sizeof(CommandTable) /
  502. X                             sizeof(*CommandTable)];
  503. X         cmd++)
  504. X        if (streq(*Argv, cmd->c_name)) {
  505. X        (*cmd->c_func)();
  506. X        exit(0);
  507. X        }
  508. X    (void) fprintf(stderr, "%s: unknown dbm command %s", Progname, *Argv);
  509. X    } else
  510. X    (void) fprintf(stderr, "%s: missing dbm command", Progname);
  511. X    (void) fprintf(stderr, ", use one of the following:\n");
  512. X    for (cmd = CommandTable; cmd < &CommandTable[sizeof(CommandTable) /
  513. X                         sizeof(*CommandTable)]; cmd++)
  514. X    (void) fprintf(stderr, "%s%s", cmd == CommandTable ? "" : "\t",
  515. X               cmd->c_name);
  516. X    (void) fprintf(stderr, "\n");
  517. X    exit(3);
  518. X}
  519. X
  520. opendbm(access)
  521. X     int access;
  522. X{
  523. X    if (Dbmfile == NULL) {
  524. X    if (Argc > 1) {
  525. X        /* use last argument */
  526. X        Dbmfile = Argv[Argc-1];
  527. X        Argc--;
  528. X    } else {
  529. X        (void) fprintf(stderr, "%s: dbm file not specified\n", Progname);
  530. X        exit(3);
  531. X    }
  532. X    }
  533. X    Dbm = dbm_open(Dbmfile, access, Mode);
  534. X    if (Dbm == NULL) {
  535. X    perror(Dbmfile);
  536. X    exit(4);
  537. X    }
  538. X    Dbmaccess = access;
  539. X}
  540. X
  541. closedbm()
  542. X{
  543. X    if ((Dbmaccess & O_RDONLY) == 0 && Senteniel) {
  544. X    MAKEDATUM(key, "@@@");
  545. X    if (dbm_store(Dbm, key, key, DBM_REPLACE) != NULL) {
  546. X        (void) fprintf(stderr, "%s: could not store senteniel \"@@@\"\n",
  547. X               Progname);
  548. X        perror(Progname);
  549. X        exit(5);
  550. X    }
  551. X    }
  552. X    
  553. X    dbm_close(Dbm);
  554. X}
  555. X
  556. XFILE *
  557. openfile(filename, access)
  558. X     char *filename;
  559. X     char *access;
  560. X{
  561. X    FILE *f;
  562. X
  563. X    if (streq(filename, "-"))
  564. X    if (streq(access, "r"))
  565. X        return stdin;
  566. X    else
  567. X        return stdout;
  568. X    else {
  569. X    f = fopen(filename, access);
  570. X    if (f == NULL) {
  571. X        perror(filename);
  572. X        exit(4);
  573. X    }
  574. X    return f;
  575. X    }
  576. X}
  577. X
  578. void
  579. closefile(f)
  580. X     FILE *f;
  581. X{
  582. X    if (f != stdin && f != stdout)
  583. X    (void) fclose(f);
  584. X}
  585. X /*
  586. X**    DO_CLEAR -- Clear out database leaving it emtpy.
  587. X*/
  588. X
  589. void
  590. do_clear()
  591. X{
  592. X    if (Dbmfile != NULL) {
  593. X    opendbm(O_RDWR | O_CREAT | O_TRUNC);
  594. X    closedbm();
  595. X    }
  596. X    while (Argc > 1) {
  597. X    opendbm(O_RDWR | O_CREAT | O_TRUNC);
  598. X    closedbm();
  599. X    }
  600. X}
  601. X
  602. X   
  603. X /*
  604. X**    DO_DELETE -- Delete individual entries from the database.
  605. X*/
  606. X
  607. void
  608. do_delete()
  609. X{
  610. X    opendbm(O_RDWR | O_CREAT);
  611. X
  612. X    for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
  613. X    casify(*Argv, Casing);
  614. X    MAKEDATUM(key, *Argv);
  615. X    if (dbm_delete(Dbm, key) != NULL) {
  616. X        perror(*Argv);
  617. X        exit(5);
  618. X    }
  619. X    }
  620. X
  621. X    closedbm();
  622. X}
  623. X
  624. X /*
  625. X**    DO_DUMP -- List all entries in the database.
  626. X*/
  627. void
  628. do_dump()
  629. X{
  630. X    FILE *output;
  631. X    
  632. X    opendbm(O_RDONLY);
  633. X
  634. X    if (Outfile == NULL)
  635. X    output = stdout;
  636. X    else
  637. X    output = openfile(Outfile, "w");
  638. X
  639. X#ifdef MDBM
  640. X    for (key = dbm_firstkey(Dbm); key.dptr != NULL; key = dbm_nextkey(Dbm, key)) {
  641. X#else MDBM
  642. X    for (key = dbm_firstkey(Dbm); key.dptr != NULL; key = dbm_nextkey(Dbm)) {
  643. X#endif MDBM
  644. X    val = dbm_fetch(Dbm, key);
  645. X    if (val.dptr == NULL)
  646. X        perror(key.dptr);
  647. X    else
  648. X        (void) fprintf(output, "%s\t%s\n", key.dptr, val.dptr);
  649. X    }
  650. X}
  651. X /*
  652. X**    DO_FETCH -- Lookup individual keys in the database.
  653. X*/
  654. void
  655. do_fetch()
  656. X{
  657. X    opendbm(O_RDONLY);
  658. X
  659. X    for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
  660. X    casify(*Argv, Casing);
  661. X    MAKEDATUM(key, *Argv);
  662. X    val = dbm_fetch(Dbm, key);
  663. X    if (val.dptr == NULL)
  664. X        (void) printf("%s\t[NOT FOUND]\n", *Argv);
  665. X    else
  666. X        (void) printf("%s\t%s\n", *Argv, val.dptr);
  667. X    }
  668. X
  669. X    closedbm();
  670. X}
  671. X
  672. X /*
  673. X**    DO_STORE -- Insert individual entries into the database.
  674. X*/
  675. X
  676. void
  677. do_store()
  678. X{
  679. X    /* barf if # of args - 1 is even and no dbm file has been specified */
  680. X    if (Argc & 1 == 1 && Dbmfile == NULL) {
  681. X    (void) fprintf(stderr, "%s: no dbm file specified\n", Progname);
  682. X    exit(3);
  683. X    }
  684. X
  685. X    opendbm(O_RDWR | O_CREAT);
  686. X
  687. X    for (Argc--, Argv++; Argc > 1; Argc -= 2, Argv += 2) {
  688. X    casify(Argv[0], Casing);
  689. X    MAKEDATUM(key, Argv[0]);
  690. X    MAKEDATUM(val, Argv[1]);
  691. X    if (dbm_store(Dbm, key, val, Storeflag) != NULL) {
  692. X        extern int errno;
  693. X
  694. X        if (errno != 0) {
  695. X        perror(Argv[0]);
  696. X        exit(5);
  697. X        } else if (Storewarn)
  698. X        (void) fprintf(stderr,
  699. X                   "%s: duplicate key \"%s\" => \"%s\" ignored\n",
  700. X                   Progname, Argv[0], Argv[1]);
  701. X    }
  702. X    }
  703. X    if (Argc > 0)
  704. X    (void) fprintf(stderr, "%s: no value for last key \"%s\"--ignored\n",
  705. X               Progname, Argv[0]);
  706. X
  707. X    closedbm();
  708. X}
  709. X
  710. X /*
  711. X**    DO_PARSE -- Parse a textual database file and produce key-value
  712. X**        pairs separated by a tab (suitable for input to the ``load''
  713. X**        function).
  714. X*/
  715. X
  716. void
  717. do_parse()
  718. X{
  719. X    FILE *input, *output;
  720. X    
  721. X    if (Outfile == NULL)
  722. X    output = stdout;
  723. X    else
  724. X    output = openfile(Outfile, "w");
  725. X
  726. X    if (Argc == 1)
  727. X    parsefile(stdin, output);
  728. X    else
  729. X    for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
  730. X        input = openfile(*Argv, "r");
  731. X        parsefile(input, output);
  732. X        closefile(input);
  733. X    }
  734. X}
  735. X
  736. X /*
  737. X**    DO_MAKE -- Parse the textual input and load the result into
  738. X**        the database.
  739. X*/
  740. X
  741. void
  742. do_make()
  743. X{
  744. X    FILE *input, *pipin, *pipout;
  745. X    int pipes[2];
  746. X
  747. X    opendbm(O_RDWR | O_CREAT | (Appending ? 0 : O_TRUNC));
  748. X
  749. X    if (pipe(pipes) != NULL) {
  750. X    perror("pipe");
  751. X    exit(9);
  752. X    }
  753. X    pipin = fdopen(pipes[0], "r");
  754. X    pipout = fdopen(pipes[1], "w");
  755. X
  756. X    if (fork() == 0) {
  757. X    /* child process */
  758. X    (void) fclose(pipout);
  759. X
  760. X    loadfile(pipin);
  761. X    } else {
  762. X    /* parent process */
  763. X    (void) fclose(pipin);
  764. X
  765. X    if (Argc == 1)
  766. X        parsefile(stdin, pipout);
  767. X    else
  768. X        for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
  769. X        input = openfile(*Argv, "r");
  770. X        parsefile(input, pipout);
  771. X        closefile(input);
  772. X        }
  773. X    }
  774. X    closedbm();
  775. X}
  776. X
  777. X /*
  778. X**    DO_LOAD -- Load the dbm database from a text file.  The input should
  779. X**        be key-value pairs separated by a tab, each on a single line.
  780. X*/
  781. X
  782. void
  783. do_load()
  784. X{
  785. X    FILE *input;
  786. X
  787. X    opendbm(O_RDWR | O_CREAT | (Appending ? 0 : O_TRUNC));
  788. X
  789. X    if (Argc == 1)
  790. X    loadfile(stdin);
  791. X    else
  792. X    for (Argc--, Argv++; Argc > 0; Argc--, Argv++) {
  793. X        input = openfile(*Argv, "r");
  794. X        loadfile(input);
  795. X        closefile(input);
  796. X    }
  797. X    closedbm();
  798. X}    
  799. X
  800. X /*
  801. X**    PARSEFILE, LOADFILE
  802. X*/ 
  803. X
  804. parsefile(input, output)
  805. X     FILE *input, *output;
  806. X{
  807. X    extern char *index();
  808. X    char buf[BUFSIZ], *key, *val = NULL;
  809. X    register char *p;
  810. X
  811. X    while (fgets(buf, sizeof(buf), input) != NULL) {
  812. X    if (buf[0] == COMMENTCHAR || buf[0] == '\n' || buf[0] == '\0')
  813. X        continue;
  814. X    if (!isspace(buf[0])) {
  815. X        /* extract value */
  816. X        p = scantoken(buf);
  817. X        if (val != NULL)
  818. X        free(val);
  819. X        val = (char *) malloc(p - buf + 1);
  820. X        (void) strncpy(val, buf, p - buf);
  821. X        val[p - buf] = '\0';
  822. X    }
  823. X    casify(buf, Casing);
  824. X    for (p = buf; *p != '\0';) {
  825. X        while (*p != '\0' && isspace(*p)) p++;
  826. X        if (*p == '\0' || *p == COMMENTCHAR)
  827. X        break;
  828. X        key = p;
  829. X        p = scantoken(p);
  830. X        if (*p == COMMENTCHAR)
  831. X        *p = '\0';
  832. X        else if (*p != '\0')
  833. X        *p++ = '\0';
  834. X        (void) fprintf(output, "%s\t%s\n", key, val);
  835. X    }
  836. X    }
  837. X}
  838. X
  839. loadfile(input)
  840. X     FILE *input;
  841. X{
  842. X    char buf[BUFSIZ];
  843. X    register char *tab, *nl;
  844. X    extern char *index();
  845. X
  846. X    while (fgets(buf, sizeof(buf), input) != NULL) {
  847. X    nl = index(buf, '\n');
  848. X    if (nl != NULL)
  849. X        *nl = '\0';
  850. X
  851. X    tab = index(buf, '\t');
  852. X    if (tab == NULL) {
  853. X        (void) fprintf(stderr, "%s: missing tab in \"%s\"--ignored\n",
  854. X               Progname, buf);
  855. X        continue;
  856. X    }
  857. X    *tab++ = '\0';
  858. X    casify(buf, Casing);
  859. X    MAKEDATUM(key, buf);
  860. X    MAKEDATUM(val, tab);
  861. X    if (dbm_store(Dbm, key, val, Storeflag) != NULL && Storewarn) {
  862. X        extern int errno;
  863. X
  864. X        if (errno != 0) {
  865. X        perror(buf);
  866. X        exit(5);
  867. X        } else if (Storewarn)
  868. X        (void) fprintf(stderr,
  869. X                   "%s: duplicate key \"%s\" => \"%s\" ignored\n",
  870. X                   Progname, buf, tab);
  871. X    }
  872. X    }
  873. X}
  874. X
  875. char *
  876. scantoken(p)
  877. X     register char *p;
  878. X{
  879. X  register bool quotedchar = FALSE, insidestring = FALSE, insideroute = FALSE;
  880. X
  881. X  /* hidious address scanner */
  882. X  while (*p != '\0' && (quotedchar || insidestring || insideroute || 
  883. X            (*p != COMMENTCHAR && !isspace(*p)))) {
  884. X    /* special quote character handling */
  885. X    if (quotedchar)
  886. X      quotedchar = FALSE;
  887. X    else {
  888. X      quotedchar = (*p == '\\');
  889. X      if (!insidestring)
  890. X    if (*p == '<')
  891. X      insideroute = TRUE;
  892. X    else if (*p == '>')
  893. X      insideroute = FALSE;
  894. X      if (*p == '"')
  895. X    insidestring = !insidestring;
  896. X    }
  897. X    p++;
  898. X  }
  899. X
  900. X  return p;
  901. X}
  902. X
  903. casify(p, c)
  904. X     register char *p;
  905. X     int c;
  906. X{
  907. X    switch (c) {
  908. X      case LOWERCASE:
  909. X    for (; *p != '\0'; p++)
  910. X        if (isupper(*p))
  911. X        *p = tolower(*p);
  912. X    break;
  913. X      case UPPERCASE:
  914. X    for (; *p != '\0'; p++)
  915. X        if (islower(*p))
  916. X        *p = toupper(*p);
  917. X    break;
  918. X    }
  919. X}
  920. END_OF_FILE
  921. if test 10914 -ne `wc -c <'dbm.c'`; then
  922.     echo shar: \"'dbm.c'\" unpacked with wrong size!
  923. fi
  924. # end of 'dbm.c'
  925. fi
  926. if test -f 'get.pl' -a "${1}" != "-c" ; then 
  927.   echo shar: Will not clobber existing file \"'get.pl'\"
  928. else
  929. echo shar: Extracting \"'get.pl'\" \(943 characters\)
  930. sed "s/^X//" >'get.pl' <<'END_OF_FILE'
  931. X#! /usr/local/bin/perl
  932. X
  933. do "wrl-uumap.pl" || die "can't do wrl-uumap.pl";
  934. package main;
  935. X
  936. dbmopen(mapdb, "$uumap'data/mapdb", 0666) || die "can't open mapdb: $!";
  937. X
  938. chdir "$uumap'maps" || die "can't chdir: $!";
  939. X
  940. foreach $name (@ARGV) {
  941. X
  942. X    undef %trail;
  943. X    while ($cname = $mapdb{$name,"alias"}) {
  944. X        if ($trail{$cname}) {
  945. X            print "alias loop for ${cname}\n";
  946. X            last;
  947. X        }
  948. X        $trail{$name} = 1;
  949. X        $name = $cname;
  950. X    }
  951. X
  952. X    ($map,$pos) = split('@', $mapdb{$name,"map"});
  953. X    if ($map eq "") {
  954. X        printf("%s: no map\n", $name);
  955. X        next;
  956. X    }
  957. X
  958. X    @aliases = split('@', $mapdb{$name,"aliases"});
  959. X
  960. X    printf("=== %s ===", $name);
  961. X    if ($#aliases >= $[) {
  962. X        printf(" (also: %s)", join(' ',@aliases));
  963. X    }
  964. X    printf("\n");
  965. X
  966. X    if (!open(map, $map)) {
  967. X        warn "can't open $map: $!";
  968. X        next;
  969. X    }
  970. X    seek(map, $pos, 0) || warn "can't seek to $pos in $map: $!";
  971. X    $n = 0;
  972. X    while (<map>) {
  973. X        if (/^#[Nn]/) {
  974. X            last if (++$n > 1);
  975. X        }
  976. X        print;
  977. X    }
  978. X    close(map);
  979. X}
  980. X
  981. dbmclose(mapdb);
  982. X
  983. exit 0;
  984. END_OF_FILE
  985. if test 943 -ne `wc -c <'get.pl'`; then
  986.     echo shar: \"'get.pl'\" unpacked with wrong size!
  987. fi
  988. # end of 'get.pl'
  989. fi
  990. if test -f 'lcasep.c' -a "${1}" != "-c" ; then 
  991.   echo shar: Will not clobber existing file \"'lcasep.c'\"
  992. else
  993. echo shar: Extracting \"'lcasep.c'\" \(1163 characters\)
  994. sed "s/^X//" >'lcasep.c' <<'END_OF_FILE'
  995. X/*
  996. X** convert the host name on a pathalias line to lower case
  997. X*/
  998. X
  999. X#ifndef lint
  1000. static char     *sccsid="@(#)lcasep.c    2.5 (smail) 9/15/87";
  1001. X#endif
  1002. X
  1003. X#include <stdio.h>
  1004. X#include <ctype.h>
  1005. X
  1006. X# define lower(c)         ( isupper(c) ? c-'A'+'a' : c )
  1007. X
  1008. void exit(), perror();
  1009. X
  1010. main(argc, argv)
  1011. int argc;
  1012. char *argv[];
  1013. X{
  1014. X    FILE *ifp, *ofp;
  1015. X    char buf[BUFSIZ];
  1016. X    register char *p;
  1017. X    int c;
  1018. X
  1019. X    extern int optind;
  1020. X    extern char *optarg;
  1021. X
  1022. X    ifp = stdin;
  1023. X    ofp = stdout;
  1024. X
  1025. X    while((c = getopt(argc, argv, "f:o:")) != EOF) {
  1026. X        switch(c) {
  1027. X        case 'f':
  1028. X            if((ifp = fopen(optarg, "r")) == NULL) {
  1029. X                (void) fprintf(stderr, "%s: can't open %s: ",
  1030. X                    argv[0], optarg);
  1031. X                perror("");
  1032. X                exit(1);
  1033. X            }
  1034. X            break;
  1035. X        case 'o':
  1036. X            if((ofp = fopen(optarg, "w")) == NULL) {
  1037. X                (void) fprintf(stderr, "%s: can't open %s: ",
  1038. X                    argv[0], optarg);
  1039. X                perror("");
  1040. X                exit(1);
  1041. X            }
  1042. X            break;
  1043. X        default:
  1044. X            (void) fprintf(stderr,
  1045. X                "usage: %s [-f file] [-o outfile]\n", argv[0]);
  1046. X            exit(1);
  1047. X            /* NOTREACHED */
  1048. X            break;
  1049. X        }
  1050. X    }
  1051. X
  1052. X    while(fgets(buf, sizeof(buf), ifp) != NULL) {
  1053. X        for(p = buf; *p != '\t' && *p != '\0' ; p++) {
  1054. X            (void) fputc(lower(*p), ofp);
  1055. X        }
  1056. X        (void) fputs(p, ofp);
  1057. X    }
  1058. X    return(0);
  1059. X}
  1060. END_OF_FILE
  1061. if test 1163 -ne `wc -c <'lcasep.c'`; then
  1062.     echo shar: \"'lcasep.c'\" unpacked with wrong size!
  1063. fi
  1064. # end of 'lcasep.c'
  1065. fi
  1066. if test -f 'list.pl' -a "${1}" != "-c" ; then 
  1067.   echo shar: Will not clobber existing file \"'list.pl'\"
  1068. else
  1069. echo shar: Extracting \"'list.pl'\" \(282 characters\)
  1070. sed "s/^X//" >'list.pl' <<'END_OF_FILE'
  1071. X#! /usr/local/bin/perl
  1072. X
  1073. do "wrl-uumap.pl" || die "can't do wrl-uumap.pl";
  1074. X
  1075. dbmopen(mapdb, "$uumap'data/mapdb", 0666) || die "can't open mapdb: $!";
  1076. X
  1077. while (($key,$val) = each(mapdb)) {
  1078. X    ($name,$dtype) = split($;, $key);
  1079. X    printf("%-30s %-8s (%s)\n", $name, $dtype, $val);
  1080. X}
  1081. X
  1082. exit 1;
  1083. END_OF_FILE
  1084. if test 282 -ne `wc -c <'list.pl'`; then
  1085.     echo shar: \"'list.pl'\" unpacked with wrong size!
  1086. fi
  1087. # end of 'list.pl'
  1088. fi
  1089. if test -f 'mailpath.sh' -a "${1}" != "-c" ; then 
  1090.   echo shar: Will not clobber existing file \"'mailpath.sh'\"
  1091. else
  1092. echo shar: Extracting \"'mailpath.sh'\" \(396 characters\)
  1093. sed "s/^X//" >'mailpath.sh' <<'END_OF_FILE'
  1094. X#! /bin/sh
  1095. X
  1096. X[ $# -eq 1 ] || {
  1097. X    echo "usage:    $0 person"
  1098. X    echo "   or:    $0 person@place"
  1099. X    exit 1
  1100. X}
  1101. X
  1102. eval `echo $1 | awk -F@ '
  1103. X    { if (NF==1) print "place=" $1 "; person=PERSON"
  1104. X      else print "place=" $2 "; person=" $1
  1105. X    }
  1106. X' `
  1107. X
  1108. set `>BIND</dbm fetch $place >LIBD</paths`
  1109. X[ "$2" = "[NOT" ] && {
  1110. X    echo mail path to $place not found
  1111. X    exit 1
  1112. X}
  1113. X
  1114. echo $person $2 | awk '{ printf($2,$1); print ""; }'
  1115. X
  1116. exit 0
  1117. END_OF_FILE
  1118. if test 396 -ne `wc -c <'mailpath.sh'`; then
  1119.     echo shar: \"'mailpath.sh'\" unpacked with wrong size!
  1120. fi
  1121. # end of 'mailpath.sh'
  1122. fi
  1123. if test -f 'makefile.libd.src' -a "${1}" != "-c" ; then 
  1124.   echo shar: Will not clobber existing file \"'makefile.libd.src'\"
  1125. else
  1126. echo shar: Extracting \"'makefile.libd.src'\" \(1199 characters\)
  1127. sed "s/^X//" >'makefile.libd.src' <<'END_OF_FILE'
  1128. X# Makefile - for paths &whatnot
  1129. X# vix 30may90 [got rid of lots of complexity, converted to unpackmaps]
  1130. X# vix 30nov87 [written]
  1131. X#
  1132. X# This should be modified only in the source directory, probably something
  1133. X# like   .../uucpmap/makefile.libd.   If you change the non-source copy, be
  1134. X# prepared to have your changes blown away by an unthinking machine...
  1135. X
  1136. NEWSUSR        =    >NEWSUSR<
  1137. X
  1138. PATHALIAS    =    >BIND</pathalias
  1139. LCASEP        =    >BIND</lcasep
  1140. DBM        =    >BIND</dbm
  1141. MAPD        =    >MAPD<
  1142. X
  1143. STAMP        =    $(MAPD)/.update_stamp
  1144. MAPFILES    =    [du].*
  1145. X
  1146. PATHS        =    >LIBD</paths
  1147. UUMAP        =    >LIBD</uumap
  1148. LOCAL        =    >LIBD</path.local >LIBD</glue.local
  1149. X
  1150. all        :;    @echo "targets are unbatch, paths, and uumap"
  1151. X
  1152. unbatch        :;    ->LIBD</unpackmaps
  1153. X
  1154. paths        :    $(PATHS).pag
  1155. X
  1156. uumap        :    $(UUMAP).pag
  1157. X
  1158. X$(PATHS).pag    :    $(PATHS)
  1159. X            $(DBM) clear newpaths; \
  1160. X            $(DBM) -I load $(PATHS) newpaths; \
  1161. X            rm -f $(PATHS).dir $(PATHS).pag; \
  1162. X            mv newpaths.dir $(PATHS).dir; \
  1163. X            mv newpaths.pag $(PATHS).pag
  1164. X
  1165. X$(PATHS)    :    $(LOCAL) $(STAMP)
  1166. X            cd $(MAPD); \
  1167. X            $(PATHALIAS) $(LOCAL) $(MAPFILES) \
  1168. X                | $(LCASEP) \
  1169. X                | sort > >LIBD</newpaths; \
  1170. X            mv >LIBD</newpaths $(PATHS)
  1171. X
  1172. X$(UUMAP).pag    :    $(STAMP)
  1173. X            cd >LIBD<; ./mkall
  1174. X
  1175. X$(STAMP)    :;    touch $(STAMP); chown $(NEWSUSR) $(STAMP)
  1176. END_OF_FILE
  1177. if test 1199 -ne `wc -c <'makefile.libd.src'`; then
  1178.     echo shar: \"'makefile.libd.src'\" unpacked with wrong size!
  1179. fi
  1180. # end of 'makefile.libd.src'
  1181. fi
  1182. if test -f 'mkall.pl' -a "${1}" != "-c" ; then 
  1183.   echo shar: Will not clobber existing file \"'mkall.pl'\"
  1184. else
  1185. echo shar: Extracting \"'mkall.pl'\" \(399 characters\)
  1186. sed "s/^X//" >'mkall.pl' <<'END_OF_FILE'
  1187. X#! /usr/local/bin/perl
  1188. X
  1189. do "wrl-uumap.pl" || die "can't do wrl-uumap.pl: $!";
  1190. X
  1191. X$| = 1;
  1192. X
  1193. do "mkmap.pl" || die "can't do mkmap, probably a syntax error in it: $!";
  1194. X
  1195. unlink "$uumap'data/mapdb.dir", "$uumap'data/mapdb.pag";
  1196. X
  1197. chop($cwd = `pwd`);
  1198. X
  1199. chdir "$uumap'maps" || die "can't chdir: $!";
  1200. X@maps = <[du].*>;
  1201. chdir $cwd;
  1202. X
  1203. foreach $map (@maps) {
  1204. X    print "$map...";
  1205. X    &mkmap($map);
  1206. X    print "\n";
  1207. X}
  1208. X
  1209. exit 0;
  1210. END_OF_FILE
  1211. if test 399 -ne `wc -c <'mkall.pl'`; then
  1212.     echo shar: \"'mkall.pl'\" unpacked with wrong size!
  1213. fi
  1214. # end of 'mkall.pl'
  1215. fi
  1216. if test -f 'mkmap.pl.src' -a "${1}" != "-c" ; then 
  1217.   echo shar: Will not clobber existing file \"'mkmap.pl.src'\"
  1218. else
  1219. echo shar: Extracting \"'mkmap.pl.src'\" \(2720 characters\)
  1220. sed "s/^X//" >'mkmap.pl.src' <<'END_OF_FILE'
  1221. X#
  1222. X# $Header:$
  1223. X#
  1224. X
  1225. package mkmap;
  1226. X
  1227. X($between, $within) = (0, 1);
  1228. X
  1229. sub main'mkmap {
  1230. X
  1231. local($map) = @_;
  1232. X
  1233. dbmopen(mapdb, "$uumap'data/mapdb", 0666) || die "can't open unames database";
  1234. if (!open(map,"$uumap'maps/$map")) {
  1235. X    warn "mkmap: can't open $map: $!";
  1236. X    return;
  1237. X}
  1238. X
  1239. X$input_state = $between;
  1240. line: while (<map>) {
  1241. X    #
  1242. X    # we're looking for a \n\n#N[ \t], which starts a new map entry
  1243. X    #
  1244. X    if ($input_state == $between) {
  1245. X        if (! /^#[Nn]/) {
  1246. X            next;
  1247. X        }
  1248. X        #
  1249. X        # found one.  init the things we'll later store in the
  1250. X        # database; change input state; parse for names; continue.
  1251. X        #
  1252. X        $map_position = tell - length($_);
  1253. X        $input_state = $within;
  1254. X        chop;
  1255. X        s/^#N[A-Za-z]*//;
  1256. X        s/[ \t]+//g;
  1257. X        s/['"]//g;
  1258. X        @names = split(/,/);
  1259. X
  1260. X        #
  1261. X        # find the canonical name (the first one without any dots
  1262. X        # will do), defaulting to the first entry on the line.
  1263. X        #
  1264. X        $cname = $names[$[];
  1265. X        foreach $name (@names) {
  1266. X            if ($name !~ /\./) {
  1267. X                $cname = $name;
  1268. X                last;
  1269. X            }
  1270. X        }
  1271. X
  1272. X        #
  1273. X        # another pass through to delete $cname from @names
  1274. X            # (actually we create @aliases from @names but don't
  1275. X            # include the $cname)
  1276. X        #
  1277. X        undef @aliases;
  1278. X        foreach $name (@names) {
  1279. X            if ($name ne $cname) {
  1280. X                push(@aliases, $name);
  1281. X            }
  1282. X        }
  1283. X
  1284. X        #
  1285. X        # store the main data for this map entry
  1286. X        #
  1287. X        $mapdb{$cname,"map"} = join('@', $map, $map_position);
  1288. X
  1289. X        next;
  1290. X    }
  1291. X
  1292. X    if ($input_state == $within) {
  1293. X        if (! /^#[Nn]/) {
  1294. X            chop;
  1295. X            s/[ \t]+//g;
  1296. X            s/['"]//g;
  1297. X            if ((! /^#/) && (/=/) && (! /{/) && (/(\w)=(.*)/)) {
  1298. X                #
  1299. X                # looks like an equate without a {network}
  1300. X                #
  1301. X                ($n, $a) = split(/=/, $_);
  1302. X                if ($n eq $cname) {
  1303. X                    #
  1304. X                    # looks like it belongs here
  1305. X                    #
  1306. X                    foreach $x (split(/,/, $a)) {
  1307. X                        push(@aliases, $x);
  1308. X                    }
  1309. X                }
  1310. X            }
  1311. X            next;
  1312. X        }
  1313. X        #
  1314. X        # end of a map entry
  1315. X        #
  1316. X
  1317. X            # we delayed writing the aliases stuff until now
  1318. X            # because some of the aliases are equates in the
  1319. X            # map entry itself.
  1320. X
  1321. X        &write_aliases();
  1322. X        undef @aliases;
  1323. X
  1324. X        $input_state = $between;
  1325. X        redo line;
  1326. X    }
  1327. X
  1328. X    printf("impossible state found: %d\n", $input_state);
  1329. X    die;
  1330. X}
  1331. X#
  1332. X# test for premature eof
  1333. X#
  1334. if (defined(@aliases)) {
  1335. X    print "(premature EOF)";
  1336. X    &write_aliases();
  1337. X    undef @aliases;
  1338. X}
  1339. dbmclose(mapdb);
  1340. close(map);
  1341. X
  1342. X} #sub mkmap
  1343. X
  1344. sub write_aliases {
  1345. X##    printf("%s: %d@%s (%s)\n",
  1346. X##        $cname, $map_position, $map, join(' ',@aliases));
  1347. X
  1348. X    #
  1349. X    # store an aliases list if there are any aliases
  1350. X    #
  1351. X    if ($#aliases >= $[) {
  1352. X        $mapdb{$cname,"aliases"} = join('@', @aliases);
  1353. X    }
  1354. X
  1355. X    #
  1356. X    # store the aliases.  extra fields are probably worthless
  1357. X    # but let's leave room for future complexity
  1358. X    #
  1359. X    foreach $name (@aliases) {
  1360. X        # only one field (now) but use join anyway
  1361. X        $mapdb{$name,"alias"} = join('@', $cname);
  1362. X    }
  1363. X} #sub write_aliases
  1364. END_OF_FILE
  1365. if test 2720 -ne `wc -c <'mkmap.pl.src'`; then
  1366.     echo shar: \"'mkmap.pl.src'\" unpacked with wrong size!
  1367. fi
  1368. # end of 'mkmap.pl.src'
  1369. fi
  1370. if test -f 'mkone.pl' -a "${1}" != "-c" ; then 
  1371.   echo shar: Will not clobber existing file \"'mkone.pl'\"
  1372. else
  1373. echo shar: Extracting \"'mkone.pl'\" \(213 characters\)
  1374. sed "s/^X//" >'mkone.pl' <<'END_OF_FILE'
  1375. X#! /usr/local/bin/perl
  1376. X
  1377. do "wrl-uumap.pl" || die "can't do wrl-uumap.pl";
  1378. X
  1379. X$| = 1;
  1380. X
  1381. do "mkmap.pl" || die "can't open mkmap.pl: $!";
  1382. X
  1383. foreach $map (@ARGV) {
  1384. X    print "$map...";
  1385. X    &mkmap($map);
  1386. X    print "\n";
  1387. X}
  1388. X
  1389. exit 0;
  1390. END_OF_FILE
  1391. if test 213 -ne `wc -c <'mkone.pl'`; then
  1392.     echo shar: \"'mkone.pl'\" unpacked with wrong size!
  1393. fi
  1394. # end of 'mkone.pl'
  1395. fi
  1396. if test -f 'unpackmaps.sh' -a "${1}" != "-c" ; then 
  1397.   echo shar: Will not clobber existing file \"'unpackmaps.sh'\"
  1398. else
  1399. echo shar: Extracting \"'unpackmaps.sh'\" \(8083 characters\)
  1400. sed "s/^X//" >'unpackmaps.sh' <<'END_OF_FILE'
  1401. X#! /bin/sh
  1402. X
  1403. X#    Unpackmaps Copyright 1990, Chris Lewis, All Rights Reserved
  1404. X
  1405. X# patch 1 (done -> fi) applied
  1406. X#
  1407. X# hacked 30may90 by vixie to not run pathalias at all, just unpack maps;
  1408. X# touches MAPDIR/.update_stamp whenever a map file is updated; is config'd
  1409. X# by the makefile now.
  1410. X
  1411. trap "rm -f /tmp/unp?$$; exit" 0 1 2 3 15
  1412. IFS="     
  1413. X"
  1414. export IFS
  1415. PATH=/usr/ucb:/bin:/usr/bin
  1416. export PATH
  1417. X
  1418. X#    The name of the file that you've caused your news system to
  1419. X#    batch the file names of the map articles.
  1420. X# Eg: C-news
  1421. X#BATCH=/usr/lib/news/batch/b.maps/togo
  1422. X#Modern C-news (directory other than /usr/spool/news/out.going)
  1423. X#BATCH=/usr/spool/news/out.special/maps/togo
  1424. X# Eg: B-news
  1425. X#BATCH=/usr/spool/batch/maps
  1426. BATCH=>BATCH<
  1427. X#    News spool directory
  1428. X#NEWSSPOOL=/usr/spool/news
  1429. NEWSSPOOL=>NEWSSPOOL<
  1430. X#    Where you want the maps to go.
  1431. X#    I like using /usr/spool/maps, but on our system, /usr/spool/news
  1432. X#    is a separate file system, and /usr runs close to the limit...
  1433. X#MAPDIR=/usr/spool/news/maps
  1434. MAPDIR=>MAPDIR<
  1435. X#    Person to send results and error messages to
  1436. X#NOTIFY=clewis
  1437. NOTIFY=usenet
  1438. X#    pathalias binary
  1439. X#PATHALIAS=/usr/lbin/pathalias
  1440. X#    where you want the path files to go:
  1441. X#    A convenient place is /usr/lib/uucp/paths which is the smail
  1442. X#    default.  If you're going to put this in /usr/lib/uucp, I suggest
  1443. X#    (rather than make /usr/lib/uucp writeable by everybody), doing
  1444. X#    the following:
  1445. X#        su root
  1446. X#        cd /usr/lib/uucp
  1447. X#        touch paths
  1448. X#        chown news paths    (or usenet)
  1449. X#        chmod 644 paths
  1450. X#PATHFILE=/usr/lib/uucp/paths
  1451. X#    Auxiliary options to pathalias.  Tune to local tastes....
  1452. X#PATHOPTS="-dwatmath"
  1453. X#    If you have a version[s] of your machine's map entry that is different 
  1454. X#    from what's published, change this variable to point at it/them.
  1455. X#    (Eg: I publish the first entry here, and the second one is local tuning
  1456. X#    and hidden connections)
  1457. X#PATHLOCAL="/usr2/clewis/maps/path.local /usr2/clewis/maps/path.nonpublic"
  1458. X#    If this variable is set to the compress binary, maps will be
  1459. X#    compressed.
  1460. X#COMPRESS=/usr2/clewis/maps/compress12
  1461. X#    1 to strip comments from maps - don't do this if you want to use
  1462. X#    uuwhere.  However, this is a great space saver...
  1463. NOCOMMENTS=0
  1464. X#    Define to the name of a file where you want the where database
  1465. X#    to be kept.  Undef if you don't want uuwhere at all.
  1466. X#WHEREFILE=$MAPDIR/where.db
  1467. X#    Uncomment this if you want the map unpacker to remove the
  1468. X#    News articles after the maps have been extracted from them.
  1469. X#    DO NOT DO THIS IF YOU FORWARD MAP ARTICLES TO OTHER SITES!
  1470. X#    This also relies on your awk returning "exit" codes properly.
  1471. X#    Yours may not...
  1472. X#UNLINK=1
  1473. X#    PS: there is *one* possible edit that you might want to make
  1474. X#    below - the maps used to generate wierd domains, but most of that
  1475. X#    appears to be gone now (don't ask me, I never particularly understood
  1476. X#    it, but since Peter Honeyman recommended it...).  If you object
  1477. X#    to these wierd domains, uncomment the egrep.
  1478. X
  1479. X#    Edit no more....
  1480. X
  1481. umask 022
  1482. X
  1483. if test ! -d $MAPDIR -o ! -w $MAPDIR
  1484. then
  1485. X    echo "$MAPDIR missing, unwritable or not a directory" >&2
  1486. X    exit 1
  1487. fi
  1488. X
  1489. if test $# = 1
  1490. then
  1491. X    case $1 in
  1492. X    -p)
  1493. X        forcepath=true
  1494. X        ;;
  1495. X    -P)
  1496. X        forcepath=false
  1497. X        ;;
  1498. X    -i)
  1499. X        cd /
  1500. X        rm -f $BATCH.work
  1501. X        # using find/sort instead of ls just in case there's lots of
  1502. X        # articles....
  1503. X        find $NEWSSPOOL/comp/mail/maps -type f -print | sort > $BATCH
  1504. X        ;;
  1505. X    *)
  1506. X        echo "usage: unpackmaps [-i] [-p]" >&2
  1507. X        exit 1
  1508. X        ;;
  1509. X    esac
  1510. fi
  1511. X
  1512. cd $MAPDIR
  1513. WHERETMP=/tmp/WHERE$$
  1514. rm -f $WHERETMP
  1515. X        
  1516. while test -f $BATCH -o -f $BATCH.work
  1517. do
  1518. X    # There is no window of vulnerability here as long as noone else is
  1519. X    # creating $BATCH.work.
  1520. X    if test ! -f $BATCH.work
  1521. X    then
  1522. X    mv $BATCH $BATCH.work
  1523. X    fi
  1524. X
  1525. X    while read i stuff
  1526. X    do
  1527. X    #    Using stuff to capture remaining junk on line.
  1528. X    #    Eg: C-news article sizes.
  1529. X
  1530. X    if test -z "$i"
  1531. X    then
  1532. X        break
  1533. X    fi
  1534. X
  1535. X    if test ! -r $i
  1536. X    then
  1537. X        echo "$i apparently superseded or expired"
  1538. X        continue
  1539. X    fi
  1540. X
  1541. X    # This awk script depends on the following map article format:
  1542. X    # <don't cares>
  1543. X    # cat << 'something' > filename
  1544. X    # map body
  1545. X    # something
  1546. X    # <don't cares>
  1547. X    # "something" doesn't have to be enclosed in quotes in the cat line.
  1548. X    # This isn't particularly fast - could be dramatically speeded up
  1549. X    # if written in C, but I was trying to ensure that this is as simple
  1550. X    # and self-evident as possible.
  1551. X
  1552. X    awk '
  1553. X    BEGIN    {
  1554. X        where = "'"$WHEREFILE"'"
  1555. X        }
  1556. X    $1 == "cat" && collecting == 0 {
  1557. X        recno = 1
  1558. X        endtoken=$3;
  1559. X        if (substr(endtoken, 1, 1) == "'"'"'")
  1560. X            endtoken=substr(endtoken, 2, length(endtoken)-2);
  1561. X        collecting = 1;
  1562. X        foundone = 1;
  1563. X        name = $5;
  1564. X        if (index(name, "/") != 0) {
  1565. X            printf("Security violation attempt in %s!\n", "'$i'");
  1566. X            exit 1;
  1567. X        } else
  1568. X            printf("extracting %s from %s\n", name, "'$i'");
  1569. X        next;
  1570. X        }
  1571. X
  1572. X        {
  1573. X        if (!collecting)
  1574. X            next;
  1575. X        if ($1 == endtoken) {
  1576. X            line = "rm -f " name ".Z"
  1577. X            print "" | line
  1578. X            collecting = 0;
  1579. X            next
  1580. X        }
  1581. X        if ($1 ~ /^#N/ && where) {
  1582. X            for (i = 2; i <= NF; i++) {
  1583. X            sname = $i
  1584. X            if (p = index(sname, ","))
  1585. X                sname = substr(sname, 1, p-1)
  1586. X            printf "@%s %s %d\n", sname, name, recno >> \
  1587. X                "'$WHERETMP'";
  1588. X            }
  1589. X        }
  1590. X        if ("'$NOCOMMENTS'" == 1 && $0 ~ /#/)
  1591. X            print substr($0, 1, index($0, "#")) > name
  1592. X        else {
  1593. X            print $0 > name
  1594. X        }
  1595. X        recno++
  1596. X        }
  1597. X        
  1598. X        END {
  1599. X        if (collecting) {
  1600. X            printf("Non-terminated map in %s\n", "'$i'");
  1601. X            exit 1;
  1602. X        }
  1603. X        if (!foundone) {
  1604. X            printf("%s does not contain a properly formed map\n", "'$i'");
  1605. X            exit 1;
  1606. X        }
  1607. X        }' $i
  1608. X
  1609. X    touch $MAPDIR/.update_stamp
  1610. X
  1611. X    if test $? = 0 -a -n "$UNLINK"
  1612. X    then
  1613. X        rm -f $i
  1614. X    fi
  1615. X
  1616. X    done < $BATCH.work
  1617. X    rm $BATCH.work
  1618. done > /tmp/unpA$$ 2>&1
  1619. X
  1620. if test -n "$COMPRESS"
  1621. then
  1622. X    files=`ls ?.* | sed -e '/\.Z$/d'`
  1623. X    if test -n "$files"
  1624. X    then
  1625. X    $COMPRESS -f $files
  1626. X    fi
  1627. fi
  1628. X
  1629. if test -n "$PATHALIAS" -a -f "$PATHALIAS" -a "$forcepath" != false
  1630. then
  1631. X    if test -s /tmp/unpA$$ -o "$forcepath" = true
  1632. X    then
  1633. X    cd $MAPDIR
  1634. X
  1635. X    (
  1636. X    if test -n "$COMPRESS"
  1637. X    then
  1638. X        $COMPRESS -dc [ud].*.Z | cat - $PATHLOCAL
  1639. X    else
  1640. X        cat [ud].* $PATHLOCAL
  1641. X    fi |
  1642. X
  1643. X    $PATHALIAS -f $PATHOPTS |
  1644. X
  1645. X    # format of the pathalias -f output is
  1646. X    # cost    host    route
  1647. X    #
  1648. X    # format of a 'paths' file for smail is
  1649. X    # host    route    first_hop_cost
  1650. X    #
  1651. X    # move cost field to end of line:
  1652. X
  1653. X    sed 's/\(.*\)    \(.*\)    \(.*\)/\2    \3    \1/' |
  1654. X
  1655. X    # convert target domain/host to lower case:
  1656. X
  1657. X    #lcasep |
  1658. X    
  1659. X    # remove some additional wierdnesses (per Peter Honeyman):
  1660. X    # You can leave it in or not.
  1661. X
  1662. X    # egrep -v '(\.(com|edu|mil|gov|net|org|arpa|[a-z][a-z])    .*!.*!)|(.\.(com|edu|mil|gov|net|org|arpa|[a-z][a-z])    )' |
  1663. X
  1664. X    # sort the stream:
  1665. X    
  1666. X    sort > /tmp/paths ) > /tmp/unpB$$ 2>&1
  1667. X
  1668. X    if test ! -s /tmp/paths
  1669. X    then
  1670. X        echo "Pathalias failed no map file created" >> /tmp/unpB$$
  1671. X    else
  1672. X        cat /tmp/paths > $PATHFILE 2>> /tmp/unpB$$
  1673. X        if test $? != 0
  1674. X        then
  1675. X        echo "Copy to $PATHFILE failed" >> /tmp/unpB$$
  1676. X        else
  1677. X        rm /tmp/paths
  1678. X        fi
  1679. X        echo "Map remade" >> /tmp/unpB$$
  1680. X        ls -l $PATHFILE >> /tmp/unpB$$
  1681. X    fi
  1682. X
  1683. X    if test -s /tmp/unpB$$
  1684. X    then
  1685. X        echo "Pathalias output:" >> /tmp/unpA$$
  1686. X        cat /tmp/unpB$$ >> /tmp/unpA$$
  1687. X    fi
  1688. X    fi
  1689. fi
  1690. X
  1691. if test -n "$WHEREFILE" -a -s $WHERETMP
  1692. then
  1693. X    if test ! -f $WHEREFILE
  1694. X    then
  1695. X    touch $WHEREFILE
  1696. X    fi
  1697. X
  1698. X    # First awk: throws away WHERE references in $WHEREFILE that
  1699. X    #    are now in $WHERETMP
  1700. X    # Sort: sort by site name
  1701. X    # Second awk: coalesce references to same site/file to one line.
  1702. X    awk '
  1703. X    BEGIN {
  1704. X        mapseen[""] = 1
  1705. X    }
  1706. X    $1 ~ /^@/ {
  1707. X        printf("%s %s %s\n", substr($1, 2), $2, $3);
  1708. X        mapseen[$2] = 1
  1709. X        next;
  1710. X    }
  1711. X    {
  1712. X        if (mapseen[$2])
  1713. X        next
  1714. X        printf("%s %s %s\n", $1, $2, $3);
  1715. X    }' $WHERETMP $WHEREFILE | 
  1716. X    sort | 
  1717. X    awk '
  1718. X    {
  1719. X        if (site != $1 || map != $2) {
  1720. X        if (site)
  1721. X            printf("\n");
  1722. X        site = $1
  1723. X        map = $2
  1724. X        printf("%s %s %s", $1, $2, $3);
  1725. X        } else
  1726. X        printf(",%s", $3);
  1727. X    }
  1728. X    END {
  1729. X        printf("\n");
  1730. X    }' > /tmp/TMP2
  1731. X    
  1732. X    if test -s /tmp/TMP2
  1733. X    then
  1734. X    cat /tmp/TMP2 > $WHEREFILE
  1735. X    fi
  1736. X    echo "Where database ($WHEREFILE) rebuilt" >> /tmp/unpA$$
  1737. fi
  1738. rm -f /tmp/TMP2 $WHERETMP
  1739. X
  1740. if test -s /tmp/unpA$$
  1741. then
  1742. X    mail $NOTIFY < /tmp/unpA$$
  1743. fi
  1744. END_OF_FILE
  1745. if test 8083 -ne `wc -c <'unpackmaps.sh'`; then
  1746.     echo shar: \"'unpackmaps.sh'\" unpacked with wrong size!
  1747. fi
  1748. # end of 'unpackmaps.sh'
  1749. fi
  1750. if test -f 'uuhost.sh' -a "${1}" != "-c" ; then 
  1751.   echo shar: Will not clobber existing file \"'uuhost.sh'\"
  1752. else
  1753. echo shar: Extracting \"'uuhost.sh'\" \(31 characters\)
  1754. sed "s/^X//" >'uuhost.sh' <<'END_OF_FILE'
  1755. X#! /bin/sh
  1756. X
  1757. exec >LIBD</get $@
  1758. END_OF_FILE
  1759. if test 31 -ne `wc -c <'uuhost.sh'`; then
  1760.     echo shar: \"'uuhost.sh'\" unpacked with wrong size!
  1761. fi
  1762. # end of 'uuhost.sh'
  1763. fi
  1764. if test -f 'uupath.sh' -a "${1}" != "-c" ; then 
  1765.   echo shar: Will not clobber existing file \"'uupath.sh'\"
  1766. else
  1767. echo shar: Extracting \"'uupath.sh'\" \(72 characters\)
  1768. sed "s/^X//" >'uupath.sh' <<'END_OF_FILE'
  1769. X#! /bin/sh
  1770. X
  1771. for host
  1772. do
  1773. X    >BIND</dbm fetch $host >LIBD</paths
  1774. done
  1775. X
  1776. exit
  1777. END_OF_FILE
  1778. if test 72 -ne `wc -c <'uupath.sh'`; then
  1779.     echo shar: \"'uupath.sh'\" unpacked with wrong size!
  1780. fi
  1781. # end of 'uupath.sh'
  1782. fi
  1783. if test -f 'uupaths.sh' -a "${1}" != "-c" ; then 
  1784.   echo shar: Will not clobber existing file \"'uupaths.sh'\"
  1785. else
  1786. echo shar: Extracting \"'uupaths.sh'\" \(63 characters\)
  1787. sed "s/^X//" >'uupaths.sh' <<'END_OF_FILE'
  1788. X#! /bin/sh
  1789. X
  1790. for host
  1791. do
  1792. X    look -f $host >LIBD</paths
  1793. done
  1794. X
  1795. exit
  1796. END_OF_FILE
  1797. if test 63 -ne `wc -c <'uupaths.sh'`; then
  1798.     echo shar: \"'uupaths.sh'\" unpacked with wrong size!
  1799. fi
  1800. # end of 'uupaths.sh'
  1801. fi
  1802. if test -f 'wrl-uumap.pl.src' -a "${1}" != "-c" ; then 
  1803.   echo shar: Will not clobber existing file \"'wrl-uumap.pl.src'\"
  1804. else
  1805. echo shar: Extracting \"'wrl-uumap.pl.src'\" \(148 characters\)
  1806. sed "s/^X//" >'wrl-uumap.pl.src' <<'END_OF_FILE'
  1807. X# configuration constants for uumap
  1808. X
  1809. package uumap;
  1810. X
  1811. X$code = ">CODE<";
  1812. X$data = ">DATA<";
  1813. X$maps = ">MAPS<";
  1814. X
  1815. package main;
  1816. X
  1817. push(@INC, $uumap'code);
  1818. END_OF_FILE
  1819. if test 148 -ne `wc -c <'wrl-uumap.pl.src'`; then
  1820.     echo shar: \"'wrl-uumap.pl.src'\" unpacked with wrong size!
  1821. fi
  1822. # end of 'wrl-uumap.pl.src'
  1823. fi
  1824. echo shar: End of shell archive.
  1825. exit 0
  1826. --
  1827. Paul Vixie
  1828. DEC Western Research Lab    <vixie@wrl.dec.com>
  1829. Palo Alto, California        ...!decwrl!vixie
  1830.