home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume34 / unpckmps / part01 < prev    next >
Encoding:
Text File  |  1992-11-28  |  56.9 KB  |  2,192 lines

  1. Newsgroups: comp.sources.misc
  2. From: clewis@ferret.ocunix.on.ca (Chris Lewis)
  3. Subject:  v34i001:  unpackmaps - A secure comp.mail.maps unpacker, Part01/02
  4. Message-ID: <csm-v34i001=unpackmaps.142040@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: 420621ca02d2f9c1c4906e02c8ed6801
  6. Date: Sun, 29 Nov 1992 20:21:22 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: clewis@ferret.ocunix.on.ca (Chris Lewis)
  10. Posting-number: Volume 34, Issue 1
  11. Archive-name: unpackmaps/part01
  12. Environment: Pathalias, Cnews, UNIX
  13. Supersedes: unpackmaps: Volume 22, Issue 69
  14.  
  15.             UNPACKMAPS V4.1 
  16.                  92/11/28
  17.               Chris Lewis
  18.             clewis@ferret.ocunix.on.ca
  19.  
  20. Unpackmaps: a simple, fast and secure UUCP map (as in comp.mail.maps)
  21. unpacker written in C.  It can also be used to unpack Brian Reid's
  22. PostScript network maps.  A flexible map query program is also included.
  23. This is intended to be a complete uuhosts replacement, but runs much
  24. faster and more reliably.
  25.  
  26. See the README for more information.
  27. ---
  28. #! /bin/sh
  29. # This is a shell archive.  Remove anything before this line, then feed it
  30. # into a shell via "sh file" or similar.  To overwrite existing files,
  31. # type "sh file -c".
  32. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  33. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  34. # Contents:  README MANIFEST config.proto runpath.c sortwdb.c uncomp.c
  35. #   unpack.c unpacker.c unpackmaps.M uuwhere.c
  36. # Wrapped by clewis@ecicrl on Sat Nov 28 02:12:32 1992
  37. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  38. echo If this archive is complete, you will see the following message:
  39. echo '          "shar: End of archive 1 (of 2)."'
  40. if test -f 'README' -a "${1}" != "-c" ; then 
  41.   echo shar: Will not clobber existing file \"'README'\"
  42. else
  43.   echo shar: Extracting \"'README'\" \(1935 characters\)
  44.   sed "s/^X//" >'README' <<'END_OF_FILE'
  45. X            UNPACKMAPS V4.1 (comp.sources.misc release)
  46. X                 92/11/28
  47. X              Chris Lewis
  48. X            clewis@ferret.ocunix.on.ca
  49. X
  50. XUnpackmaps: a simple, fast and secure UUCP map (as in comp.mail.maps)
  51. Xunpacker written in C.  It can also be used to unpack Brian Reid's
  52. XPostScript network maps.  A flexible map query program is also included.
  53. XThis is intended to be a complete uuhosts replacement, but runs much
  54. Xfaster and more reliably.
  55. X
  56. X    This software is Copyright 1992 Chris Lewis, All Rights Reserved.
  57. X    Except as otherwise noted in individual source files, the following
  58. X    applies:
  59. X
  60. X    You can do anything you want with it, provided that this copyright
  61. X    notice remains intact, you don't claim you wrote it yourself, and you 
  62. X    don't make money selling it directly.  You may redistribute this as
  63. X    you wish.  But I reserve the right to make derivitive works.  In
  64. X    other words, you may not distribute modified versions of this software
  65. X    without my permission.  This is mostly to help protect against
  66. X    maliciously modified copies being distributed, and is more a
  67. X    protection for you than me.
  68. X
  69. X    Though I have taken pains to ensure that this program is reasonably 
  70. X    reliable and secure, I cannot make any warrantee as to the reliability 
  71. X    or security of this software when used on any computer.  It is up to
  72. X    the user of this software to determine its suitability for their
  73. X    purposes and take responsibility for its operation.
  74. X
  75. X    If you have to make any changes to files other than the Makefile
  76. X    and config.h to make this program work on your machine, please
  77. X    contact me and tell me where I goofed.
  78. X    
  79. XWith that bilge out of the way...
  80. X
  81. XInstructions on how to use:
  82. X    1) copy config.proto to config.h, and edit as appropriate.
  83. X    2) copy Make.proto to Makefile, and edit as appropriate.
  84. X    3) type "make".
  85. X    4) su root and type "make install"
  86. X    5) read the unpackmaps manual page on how to use this software.
  87. END_OF_FILE
  88.   if test 1935 -ne `wc -c <'README'`; then
  89.     echo shar: \"'README'\" unpacked with wrong size!
  90.   fi
  91.   # end of 'README'
  92. fi
  93. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  94.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  95. else
  96.   echo shar: Extracting \"'MANIFEST'\" \(1290 characters\)
  97.   sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  98. X   File Name        Archive #    Description
  99. X----------------------------------------------------------
  100. X README                     1    
  101. X MANIFEST                   1    This shipping list
  102. X Make.proto                 2    prototype Makefile
  103. X config.proto               1    prototype config.h
  104. X deletelist                 2    sample delete list
  105. X display.c                  2    displays map entries/files
  106. X docomp.c                   2    file compression
  107. X dointer.c                  2    domain optimizer
  108. X dopath                     2    sample unpackmaps script
  109. X fatal.c                    2    error handler
  110. X fileinit.c                 2    file name initializer
  111. X getmaps.c                  2    spool directory scan
  112. X getpath.c                  2    binary path file search
  113. X lock.c                     2    lock file handler
  114. X runpath.c                  1    check for and run pathalias/uuwhere.db
  115. X savestr.c                  2    string save
  116. X sortwdb.c                  1    sort the where database
  117. X uncomp.c                   1    inline file uncompression
  118. X unpack.c                   1    map unpacking code
  119. X unpack.h                   2    main header
  120. X unpacker.c                 1    mainline
  121. X unpackmaps.M               1    manual page for unpackmaps
  122. X uuwhere.M                  2    manual page for uuwhere
  123. X uuwhere.c                  1    mainline for uuwhere
  124. END_OF_FILE
  125.   if test 1290 -ne `wc -c <'MANIFEST'`; then
  126.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  127.   fi
  128.   # end of 'MANIFEST'
  129. fi
  130. if test -f 'config.proto' -a "${1}" != "-c" ; then 
  131.   echo shar: Will not clobber existing file \"'config.proto'\"
  132. else
  133.   echo shar: Extracting \"'config.proto'\" \(3963 characters\)
  134.   sed "s/^X//" >'config.proto' <<'END_OF_FILE'
  135. X/* Copyright 1992, Chris Lewis.  All Rights Reserved
  136. X   Please see the README for the terms of the copyright.
  137. X   1.5 92/08/14
  138. X */
  139. X
  140. X#undef BSD        /* define if you're a BSD or V7 system */
  141. X#define USG        /* define if you're a System V or Xenix system */
  142. X#define NEEDTYPES_H    /* define if your sys/stat.h needs types.h,
  143. X               but doesn't already include it. */
  144. X
  145. X#define MAPDIR        "/usr/spool/maps"
  146. X
  147. X/*    Default pathalias invocation line.
  148. X    Should have -i to lower case everything.
  149. X    If you're running smail 2.5, which likes to see the cost
  150. X    of the first hop, supply a -f option.
  151. X */
  152. X#define PATHALIAS    "/usr/bin/pathalias -i -f"
  153. X
  154. X#define SPOOLDIR    "/usr/spool/news"
  155. X#define PATHFILE    "/usr/lib/uucp/paths"
  156. X
  157. X/*    undef COMPFLAG if you want COMPRESS's default compress ratio.
  158. X    -b16 uses up about 450K.
  159. X    -b12 uses up about 60K. */
  160. X
  161. X#define COMPFLAG    "-b12"
  162. X#define COMPRESS    "/usr/bin/compress"
  163. X
  164. X#define NEWSID        "news"    /* *must* be same as news system owner. */
  165. X
  166. X#define MALLRET        char *    /* what malloc() and realloc() return
  167. X                   sometimes "void *" */
  168. X
  169. X
  170. X/*    Where you're likely to have the most space.  If you have several
  171. X    smallish partitions, it would make sense to have these different.
  172. X    Eg: /tmp and /usr/tmp.  unpackmaps attempts to balance between
  173. X    the two.  In fact, if these are on different spindles, this
  174. X    may improve performance somewhat as well.
  175. X */
  176. X#define TMPDIR        "/tmp"
  177. X#define TMPDIR2        "/tmp"
  178. X
  179. X/*    Bnews doesn't need to lock batch files.  Cnews *does*.
  180. X    If you're not running Cnews, undefine LOCKBATCH.
  181. X    If you are running Cnews, make sure that LOCKBATCH
  182. X    is set to the lock file name.  Usually /usr/lib/news/LOCK.
  183. X */
  184. X#define    LOCKBATCH    "/usr/lib/news/LOCK"
  185. X
  186. X/*    If you have SVR[34] or Posix-compliant directory routines,
  187. X    define "USGDIR". If you have Berkeley directory routines
  188. X    (usually older systems) define BERKDIR. If you have
  189. X    neither, or are unsure, leave both undefined, and my
  190. X    ugly and slow "ls" kludge will work.
  191. X */
  192. X#define USGDIR
  193. X#undef BERKDIR
  194. X
  195. X/*    Turn this off if you're running smail 3, or smail 2.5 with the
  196. X    "dotteddomain" bug fixed
  197. X */
  198. X
  199. X#define    NODOTDOMAIN
  200. X
  201. X/*    Unpackmaps will insert "file" directives into the beginning of
  202. X    each map when stuffing it into pathalias so any error messages
  203. X    will have the right file name and line number.  If OLDPATHALIAS
  204. X    is defined, unpackmaps will not do this.  Older versions of
  205. X    pathalias (9 and previous) don't grok the "file {name}" directive.
  206. X    Rutgers has just recently started sending maps with the file 
  207. X    directive in them - so, theoretically, as long as you have the
  208. X    new pathalias, you could define this to disable this feature.
  209. X    But, it doesn't hurt, and makes sure that the file directive is
  210. X    inserted even on local maps where you may have forgotten to insert
  211. X    the file directive.
  212. X
  213. X    Defining this doesn't cause unpackmaps to strip already-existing
  214. X    "file" directives from the maps - so you can't use this to
  215. X    adapt the new maps to old pathalias.  It's far more important
  216. X    to upgrade to the new pathalias (10 or better).  Older pathalias
  217. X    tends to go into infinite loops in some obscure situations.
  218. X */
  219. X
  220. X#undef    OLDPATHALIAS
  221. X
  222. X/*    Some systems have a maximum file length of 14.  Ie: System V
  223. X    on the System-V file system type (as opposed to the Berkeley
  224. X    Fast File System for instance.)  Occasionally, Rutgers will
  225. X    goof and send out maps with file names longer than 12 (which
  226. X    will cause a problem on System V systems when you try to
  227. X    compress - compress adds 2 characters for the .Z).  Rutgers
  228. X    then usually resends the map with a new length of 12.
  229. X
  230. X    If FILELENGTH is set to:
  231. X
  232. X        0        unpackmaps will refuse to unpack anything longer
  233. X            than 12.
  234. X        1        unpackmaps will unpack files with length of 13 or 14,
  235. X            but not compress them.
  236. X        nn        unpackmaps will unpack as long as the file name
  237. X            length is <= nn, and compress if <= nn-2.
  238. X
  239. X    I strongly recommend a setting of 0, and whenever unpackmaps tells
  240. X    you that a map is longer than 12, send a complaint off to
  241. X    uucpmap@rutgers.
  242. X */
  243. X
  244. X#define FILELENGTH    0
  245. END_OF_FILE
  246.   if test 3963 -ne `wc -c <'config.proto'`; then
  247.     echo shar: \"'config.proto'\" unpacked with wrong size!
  248.   fi
  249.   # end of 'config.proto'
  250. fi
  251. if test -f 'runpath.c' -a "${1}" != "-c" ; then 
  252.   echo shar: Will not clobber existing file \"'runpath.c'\"
  253. else
  254.   echo shar: Extracting \"'runpath.c'\" \(8059 characters\)
  255.   sed "s/^X//" >'runpath.c' <<'END_OF_FILE'
  256. X/* Copyright 1992, Chris Lewis.  All Rights Reserved
  257. X   Please see the README for the terms of the copyright.
  258. X   1.4 92/07/12
  259. X */
  260. X
  261. X#ifndef lint
  262. Xstatic char SCCSid[] = "@(#)runpath.c 1.4 92/07/12 16:43:27";
  263. X#endif
  264. X#define    UNPACKMAPS
  265. X#include "unpack.h"
  266. X
  267. Xint stunlinked = 0;
  268. Xint stprocessed = 0;
  269. X
  270. Xdorunpath() {
  271. X    extern char *zfgets();
  272. X    extern FILE *zfopen();
  273. X    struct stat stb;
  274. X    register char *p;
  275. X    register int recno;
  276. X    FILE *list, *mapf, *path, *whfp;
  277. X    char buf[BUFSIZ];
  278. X    long pathtime = 0;
  279. X    char **mapptr, **locptr;
  280. X
  281. X    fatal(chdir(unpackdir), "Can't change to unpacking directory");
  282. X
  283. X    (void) umask(022);
  284. X
  285. X    (void) unlink(pathtmp);
  286. X    (void) unlink(pathtmp2);
  287. X    (void) unlink(wheretmp);
  288. X
  289. X    /* awwww, do we really have to run it?
  290. X       these tests are to confirm that we have to run pathalias
  291. X       (if forcepath = 0)
  292. X     */
  293. X
  294. X    if (!forcepath) {
  295. X    if (stat(wheredb, &stb))
  296. X        forcepath = 1;        /* no where file, run it. */
  297. X    else
  298. X        pathtime = stb.st_mtime;
  299. X    if (!whereonly) {
  300. X        if (stat(pathfile, &stb))
  301. X        forcepath = 1;        /* no path file, run it. */
  302. X        else /* minimum time is trigger */
  303. X        pathtime = stb.st_mtime < pathtime ? stb.st_mtime: pathtime;
  304. X    }
  305. X    }
  306. X
  307. X    if (debug)
  308. X    (void) fprintf(stderr, "in dorunpath: pathtime: %ld, force: %d\n",
  309. X        pathtime, forcepath);
  310. X
  311. X    getmaps(&mapfiles, 1);
  312. X    for (mapptr = mapfiles.list; mapptr && *mapptr; mapptr++)
  313. X    if (stat(*mapptr, &stb))
  314. X        (void) fprintf(stderr, "Can't stat %s\n", *mapptr);
  315. X    else {
  316. X        if (pathtime < stb.st_mtime)    /* map file newer, run it */
  317. X        forcepath = 1;
  318. X        if (debug)
  319. X        (void) fprintf(stderr, "check %s, t: %ld, force: %d\n", buf,
  320. X            stb.st_mtime, forcepath);
  321. X    }
  322. X
  323. X    /* then, collect the map file mentioned in the command line */
  324. X    recno = mapfiles.curptr - mapfiles.list;
  325. X
  326. X    for (mapptr = localmaps.list; mapptr && *mapptr; mapptr++)
  327. X    if (stat(*mapptr, &stb))
  328. X        (void) fprintf(stderr, "Can't stat %s\n", *mapptr);
  329. X    else {
  330. X        if (pathtime < stb.st_mtime)    /* local map newer, run it */
  331. X        forcepath = 1;
  332. X        savestr(&mapfiles, *mapptr);
  333. X    }
  334. X
  335. X    /* pointers >= locptr are command line maps */
  336. X    locptr = mapfiles.list + recno;
  337. X
  338. X    if (debug) {
  339. X    (void) fprintf(stderr, "finish: forcepath: %d\n", forcepath);
  340. X    for (mapptr = mapfiles.list; mapptr && *mapptr; mapptr++)
  341. X        (void) fprintf(stderr, "map %s%s\n", *mapptr,
  342. X        mapptr >= locptr? "*": "");
  343. X    }
  344. X
  345. X
  346. X    if (!forcepath)
  347. X    return;
  348. X
  349. X    /* only doing it one step at a time.  If we make the popen
  350. X       multistage (sed reorder + sort), then we lose the ability
  351. X       to replace the sed with something faster, *and* the ability
  352. X       to check for errors in each step.
  353. X
  354. X       This should really be forked, with output to pathalias
  355. X       on one side, and input from pathalias and output to
  356. X       sort on the other.  Then we don't have to have *two*
  357. X       path temporaries.  Next time...
  358. X     */
  359. X
  360. X    if (whereonly)
  361. X    path = (FILE *) NULL;
  362. X    else {
  363. X    (void) sprintf(tempbuf, "%s > %s", pathalias, pathtmp);
  364. X    fatal(!(path = popen(tempbuf, "w")), "Can't popen pathalias");
  365. X    (void) fprintf(stderr, "Starting pathalias\n");
  366. X    }
  367. X
  368. X    fatal(!(whfp = fopen(wheretmp, "w")), "Can't open where.tmp");
  369. X
  370. X    /* Here we GOOOOOOOO!!!! */
  371. X
  372. X    (void) fflush(stderr);
  373. X
  374. X    for (mapptr = mapfiles.list; mapptr && *mapptr; mapptr++) {
  375. X    int writing = 1;    /* set to false if not pumping to pathalias */
  376. X    int skipmap;
  377. X    char *((*rdfcn)());
  378. X    int compressed = 0;
  379. X
  380. X    (void) strcpy(tempbuf, *mapptr);
  381. X
  382. X    p = *mapptr + strlen(*mapptr) - 2;
  383. X
  384. X    if (*p == '.' && *(p+1) == 'Z') {
  385. X        compressed = 1;
  386. X        tempbuf[p - *mapptr] = '\0';
  387. X    }
  388. X
  389. X    skipmap = (mapptr < locptr) && search(lmapfiles.list, tempbuf);
  390. X    if (!path || skipmap)
  391. X        writing = 0;
  392. X    
  393. X    if (unlinkskip && skipmap && **mapptr == 'u') {
  394. X        if (verbose)
  395. X        (void) fprintf(stderr, "Unlinking %s\n", tempbuf);
  396. X        stunlinked++;
  397. X        (void) unlink(*mapptr);
  398. X        continue;
  399. X    }
  400. X
  401. X    if (debug)
  402. X        (void) fprintf(stderr, "opening %s, .Z=: %d, writing: %d, skip: %d\n", *mapptr,
  403. X        compressed, writing, skipmap);
  404. X
  405. X    if (compressed) {
  406. X        fatal(!(mapf = zfopen(*mapptr, "r")), "Can't zfopen map file");
  407. X        rdfcn = zfgets;
  408. X    } else {
  409. X        fatal(!(mapf = fopen(*mapptr, "r")), "Can't fopen map file");
  410. X        rdfcn = fgets;
  411. X    }
  412. X    stprocessed++;
  413. X
  414. X#ifndef    OLDPATHALIAS
  415. X    if (writing && path)
  416. X        (void) fprintf(path, "file {%s}\n", *mapptr);
  417. X#endif
  418. X    recno = 0;
  419. X
  420. X    while(rdfcn(buf, sizeof(buf), mapf)) {
  421. X        recno++;
  422. X
  423. X        /* optimization: delete comments from pathalias input. */
  424. X        if (buf[0] == '#') {
  425. X        if (writing)
  426. X            (void) putc('\n', path);
  427. X
  428. X        /* If a #N[ame] record, save information */
  429. X        if (buf[1] == 'N') {
  430. X
  431. X            /* #N[ame][ \t]+site[, ]+site[, ]+,site */
  432. X            for (p = buf + 2; *p && !isspace(*p); p++)
  433. X            continue;
  434. X            while(*p && isspace(*p)) p++;
  435. X            while(*p && *p != '\n') {
  436. X
  437. X            while(*p && *p != ',' && !isspace(*p)) {
  438. X                (void) putc(*p, whfp);
  439. X                p++;    /* ya never know */
  440. X            }
  441. X
  442. X            (void) fprintf(whfp, "\t%s\t%d\n", tempbuf, recno);
  443. X
  444. X            while(*p && (*p == ',' || isspace(*p)))
  445. X                p++;
  446. X            }
  447. X        }
  448. X        } else {
  449. X        p = strchr(buf, '#');
  450. X        if (p) {
  451. X            for (p--; p >= buf && (*p == ' ' || *p == '\t'); p--)
  452. X            continue;
  453. X            if (p < buf) {
  454. X            *++p = ' ';    /* wierd but true - pathalias */
  455. X            *++p = '#';    /* needs it sometimes */
  456. X            }
  457. X            *++p = '\n';
  458. X            *++p = '\0';
  459. X        }
  460. X        if (writing)
  461. X            (void) fputs(buf, path);
  462. X        }
  463. X    }
  464. X
  465. X    if (compressed)
  466. X        (void) zfclose(mapf);
  467. X    else
  468. X        (void) fclose(mapf);
  469. X    if (skipmap && unlinkskip && **mapptr == 'u') {
  470. X        (void) fprintf(stderr, "Unlinking %s\n", *mapptr);
  471. X        (void) unlink(*mapptr);
  472. X    }
  473. X#ifndef    OLDPATHALIAS
  474. X    if (writing && path)
  475. X        (void) fprintf(path, "private {}\n");
  476. X#endif
  477. X    }
  478. X
  479. X    if (stunlinked)
  480. X    (void) fprintf(stderr, "%d map files discarded by discard list\n",
  481. X        stunlinked);
  482. X    (void) fprintf(stderr, "%d map files processed\n", stprocessed);
  483. X
  484. X    (void) zfiofree();
  485. X
  486. X    (void) fclose(whfp);
  487. X
  488. X    (void) fflush(stderr);
  489. X    if (path && pclose(path)) {
  490. X    (void) unlink(pathtmp);
  491. X    fatal(1, "pathalias failed");
  492. X    }
  493. X
  494. X    if (!whereonly)
  495. X    (void) fprintf(stderr, "Pathalias completed: okay\n");
  496. X
  497. X    sortwdb();
  498. X
  499. X    (void) fprintf(stderr, "%s completed: okay\n", wheredb);
  500. X    if (whereonly)
  501. X    return;
  502. X
  503. X    (void) fprintf(stderr, "Sorting pathalias output\n");
  504. X    fatal(!(whfp = fopen(pathtmp, "r")), "reopen path temp");
  505. X    (void) sprintf(tempbuf, "sort -u > %s", pathtmp2);
  506. X
  507. X    fatal(!(path = popen(tempbuf, "w")), "popen sort");
  508. X    (void) unlink(pathtmp);        /* we don't have to do cleanup later */
  509. X
  510. X    /* swap fields around */
  511. X    while(fgets(buf, sizeof(buf), whfp)) {
  512. X    char *site, *route, *t;
  513. X
  514. X    site = strchr(buf, '\t');
  515. X    *site++ = '\0';
  516. X    if (route = strchr(site, '\t'))
  517. X        *route++ = '\0';
  518. X    else
  519. X        {
  520. X            route = site;
  521. X            site = buf;
  522. X        }
  523. X    t = strchr(route, '\n');
  524. X    *t = '\0';
  525. X
  526. X#ifdef    NODOTDOMAIN
  527. X    if (*site == '.')
  528. X        continue;
  529. X#endif
  530. X
  531. X    /* lcasep's job */
  532. X    for (t = site; *t; t++)
  533. X        if (isupper(*t))
  534. X        *t = tolower(*t);
  535. X
  536. X    if (internet)
  537. X        dointernet(site, &route);
  538. X
  539. X    (void) fputs(site, path);
  540. X    (void) putc('\t', path);
  541. X    (void) fputs(route, path);
  542. X    if (site != buf)
  543. X    {
  544. X        (void) putc('\t', path);
  545. X        (void) fputs(buf, path);
  546. X    }
  547. X    (void) putc('\n', path);
  548. X    }
  549. X
  550. X    (void) fclose(whfp);
  551. X    (void) unlink(pathtmp);
  552. X    if (pclose(path)) {
  553. X    (void) unlink(pathtmp2);
  554. X    fatal(1, "sort failed");
  555. X    }
  556. X    (void) fprintf(stderr, "Sorting pathalias output completed: okay\n");
  557. X
  558. X    fatal(!(whfp = fopen(pathtmp2, "r")), "Open of pathtmp2 for copy failed");
  559. X    fatal(!(path = fopen(pathfile, "w")), "Open of path output file failed");
  560. X    while((recno = fread(tempbuf, sizeof(char), BUFSIZ, whfp)) > 0)
  561. X    fatal(recno != fwrite(tempbuf, sizeof(char), recno, path),
  562. X        "write failed");
  563. X    (void) fclose(whfp);
  564. X    (void) fclose(path);
  565. X    (void) fprintf(stderr, "Creation of %s completed: okay\n", pathfile);
  566. X
  567. X}
  568. X
  569. Xsearch(list, item)
  570. Xregister char **list, *item; {
  571. X    if (debug)
  572. X    (void) fprintf(stderr, "find %s\n", item);
  573. X    if (!list)
  574. X    return(0);
  575. X    while(*list)
  576. X    if (strcmp(*list++, item) == 0)
  577. X        return(1);
  578. X    return(0);
  579. X}
  580. END_OF_FILE
  581.   if test 8059 -ne `wc -c <'runpath.c'`; then
  582.     echo shar: \"'runpath.c'\" unpacked with wrong size!
  583.   fi
  584.   # end of 'runpath.c'
  585. fi
  586. if test -f 'sortwdb.c' -a "${1}" != "-c" ; then 
  587.   echo shar: Will not clobber existing file \"'sortwdb.c'\"
  588. else
  589.   echo shar: Extracting \"'sortwdb.c'\" \(1630 characters\)
  590.   sed "s/^X//" >'sortwdb.c' <<'END_OF_FILE'
  591. X/* Copyright 1992, Chris Lewis.  All Rights Reserved
  592. X   Please see the README for the terms of the copyright.
  593. X   1.1 92/06/10
  594. X */
  595. X
  596. X#ifndef lint
  597. Xstatic char SCCSid[] = "@(#)sortwdb.c 1.1 92/06/10 01:16:23";
  598. X#endif
  599. X#define    UNPACKMAPS
  600. X#include "unpack.h"
  601. Xsortwdb() {
  602. X    char buf[BUFSIZ];
  603. X    char lastsite[BUFSIZ], lastfile[BUFSIZ], lastrecord[BUFSIZ];
  604. X    register char *site, *file, *record, *t;
  605. X    FILE *in, *out;
  606. X
  607. X    (void) sprintf(tempbuf, "sort -u %s", wheretmp);
  608. X    fatal(!(in = popen(tempbuf, "r")), "Can't popen sort of wheretmp");
  609. X    (void) unlink(wheredb);
  610. X    if (debug)
  611. X    (void) fprintf(stderr, "wheredb: %s\n", wheredb);
  612. X    fatal(!(out = fopen(wheredb, "w")), "Can't open where.db");
  613. X
  614. X    lastsite[0] = lastfile[0] = lastrecord[0] = '\0';
  615. X
  616. X    while(fgets(buf, sizeof(buf), in)) {
  617. X    site = buf;
  618. X    file = strchr(site, '\t');
  619. X    *file++ = '\0';
  620. X    record = strchr(file, '\t');
  621. X    *record++ = '\0';
  622. X    t = strchr(record, '\n');
  623. X    *t = '\0';
  624. X
  625. X    if (strcmp(site, lastsite)) {
  626. X        if (lastsite[0])
  627. X        (void) putc('\n', out);
  628. X        (void) fprintf(out, "%s\t%s,%s", site, file, record);
  629. X        (void) strcpy(lastsite, site);
  630. X        (void) strcpy(lastfile, file);
  631. X        (void) strcpy(lastrecord, record);
  632. X    } else if (strcmp(file, lastfile)) {
  633. X        (void) fprintf(out, ":%s,%s", file, record);
  634. X        (void) strcpy(lastfile, file);
  635. X        (void) strcpy(lastrecord, record);
  636. X    } else if (strcmp(record, lastrecord)) {
  637. X        (void) fprintf(out, ",%s", record);
  638. X        (void) strcpy(lastrecord, record);
  639. X    }
  640. X
  641. X    }
  642. X    (void) putc('\n', out);
  643. X
  644. X    (void) fclose(out);
  645. X    fatal(pclose(in), "Popen'd where.db sort failed");
  646. X    (void) unlink(wheretmp);
  647. X}
  648. END_OF_FILE
  649.   if test 1630 -ne `wc -c <'sortwdb.c'`; then
  650.     echo shar: \"'sortwdb.c'\" unpacked with wrong size!
  651.   fi
  652.   # end of 'sortwdb.c'
  653. fi
  654. if test -f 'uncomp.c' -a "${1}" != "-c" ; then 
  655.   echo shar: Will not clobber existing file \"'uncomp.c'\"
  656. else
  657.   echo shar: Extracting \"'uncomp.c'\" \(3519 characters\)
  658.   sed "s/^X//" >'uncomp.c' <<'END_OF_FILE'
  659. X/*    Derived from "unshark", by James A. Woods.  Permission
  660. X    pending.
  661. X */
  662. X
  663. X#ifndef lint
  664. Xstatic char SCCSid[] = "@(#)uncomp.c 1.1 92/06/10 01:16:25";
  665. X#endif
  666. X
  667. X#include "unpack.h"
  668. X
  669. Xstatic long    M, N, c, f, m, o, r, s, w;
  670. Xstatic long    O, S, e, i, k, n, q;
  671. Xstatic long    *t;
  672. Xstatic char    *D, *h;
  673. Xstatic FILE    *infile;
  674. Xstatic int    savestate;
  675. X
  676. Xlong
  677. Xarsize(bits)
  678. Xint bits; {
  679. X    switch(bits) {
  680. X    case 16: return(69001L);
  681. X    case 15: return(35053L);
  682. X    case 14: return(18013L);
  683. X    case 13: return(9001L);
  684. X    default: return(5003L);
  685. X    }
  686. X}
  687. X
  688. Xzfiofree() {
  689. X    if (t)
  690. X    free((char*) t);
  691. X    if (D)
  692. X    free(D);
  693. X    if (h)
  694. X    free(h);
  695. X    D = h = (char *) NULL;
  696. X    t = (long *) NULL;
  697. X}
  698. X
  699. Xcheckarray(bits)
  700. Xint bits; {
  701. X    static int curbits = 0;
  702. X    long asize;
  703. X
  704. X    if (debug)
  705. X    (void) fprintf(stderr, "Need %d bits\n", bits);
  706. X
  707. X    if (bits <= curbits)
  708. X    return(0);
  709. X
  710. X    asize = arsize(bits);
  711. X
  712. X    zfiofree();
  713. X    
  714. X    if (!(t = (long *) malloc(asize * sizeof(long))) ||
  715. X    !(D = (char *) malloc(asize * sizeof(char))) ||
  716. X    !(h = (char *) malloc(asize * sizeof(char)))) {
  717. X
  718. X    zfiofree();
  719. X
  720. X    curbits = 0;
  721. X    return(1);
  722. X    }
  723. X    curbits = bits;
  724. X    return(0);
  725. X}
  726. X
  727. X
  728. Xlong
  729. Xg()
  730. X{
  731. X    char    *p;
  732. X
  733. X    /* Was "m < f & n < k" Should it be && ?*/
  734. X    if ((m < f) & (n < k) && (m = (1l << ++n) - 1) || O >= S) {
  735. X        O = 0;
  736. X        S = fread(D, 1, n, infile) * 8;
  737. X        if (S < 8)
  738. X            return(-1);
  739. X        S -= n - 1;
  740. X    }
  741. X    p = D + O / 8;
  742. X    q = O & 7;
  743. X    O += n;
  744. X    return (1 << 8 - q) - 1 & *p >> q | m & ((15 < n + q) * p[2] * 256 | p[1] & 255) << 8 - q;
  745. X}
  746. X
  747. Xstatic char *p, *bp;
  748. X
  749. X#define    zputc(c,s) *bp++ = c; if (*(bp-1) == '\n') {*state = s; *bp = '\0'; return(0);}
  750. X
  751. Xint
  752. Xzgetc(file)
  753. XFILE *file; {
  754. X    int ch = getc(file);
  755. X    return(ch);
  756. X}
  757. X
  758. Xa(state)
  759. Xint *state; {
  760. X    switch(*state) {
  761. X        case 0:
  762. X        break;
  763. X        case 1:
  764. X        goto state1;
  765. X        case 2:
  766. X        goto state2;
  767. X        case 3:
  768. X        goto state3;
  769. X    }
  770. X
  771. X    if (0x1f != zgetc(infile))
  772. X        return(1);
  773. X    if (0x9d != zgetc(infile))
  774. X        return(1);
  775. X    k = zgetc(infile);
  776. X    e = k >> 7 & 1;
  777. X    k &= 31;
  778. X    if (checkarray(k)) {
  779. X        (void) fprintf(stderr,
  780. X        "%s: Cannot allocate enough memory for %d bit decompression\n",
  781. X        progname, k);
  782. X        return(1);
  783. X    }
  784. X
  785. X    p = D + 256;
  786. X    M = N = c = m = r = s = 0;
  787. X    O = S = q = 0;
  788. X
  789. X    if (k > 16)
  790. X        return 1;
  791. X    w = 256;
  792. X    while (w--) 
  793. X        t[w] = 0, h[w] = w;
  794. X    n = 8;
  795. X    f = 256 + e;
  796. X    i = o = (w = g());
  797. X    if (o < 0)
  798. X        return 1;
  799. X    zputc(i, 1);
  800. X    state1:
  801. X    while ((w = g()) + 1) {
  802. X        ;
  803. X        if ((w == 256) & e) {
  804. X            w = 256;
  805. X            while (w--) 
  806. X                t[w] = 0;
  807. X            m = n = 8;
  808. X            f = 256;
  809. X            if ((w = g()) < 0)
  810. X                return 0;
  811. X        }
  812. X        c = w;
  813. X        if (w >= f)
  814. X            *p++ = i, w = o;
  815. X        while (w >= 256)
  816. X            *p++ = h[w], w = t[w];
  817. X        zputc(i = h[w], 2);
  818. X    state2:
  819. X        while (p > D + 256) {
  820. X            zputc(*--p, 3);
  821. X    state3:             ;
  822. X        }
  823. X        if ((w = f) < 1l << k)
  824. X            t[w] = o, h[f++] = i;
  825. X        o = c;
  826. X    }
  827. X    return 0;
  828. X}
  829. X
  830. Xstatic char *savename;
  831. X
  832. XFILE
  833. X*zfopen(file, mode)
  834. Xchar *file, *mode; {
  835. X    savestate = 0;
  836. X    savename = file;
  837. X    return(fopen(file, mode));
  838. X}
  839. X
  840. X/* Must follow fgets calling sequence. */
  841. X/* ARGSUSED */
  842. Xchar *
  843. Xzfgets(buf, len, file)
  844. Xchar *buf; int len; FILE *file; {
  845. X    bp = buf;
  846. X    infile = file;
  847. X    if (a(&savestate)) {
  848. X    (void) fprintf(stderr, "%s: Error uncompressing %s\n", progname, savename);
  849. X    return((char *) NULL);
  850. X    }
  851. X    if (bp == buf)
  852. X    return((char *) NULL);
  853. X    else
  854. X    return(buf);
  855. X}
  856. X
  857. Xzfclose(file)
  858. XFILE *file; {
  859. X    return(fclose(file));
  860. X}
  861. X
  862. X#ifdef    NEVER
  863. Xmain(argc, argv)
  864. Xint argc;
  865. Xchar *argv; {
  866. X    char buf[512];
  867. X    FILE *f = zfopen("shark.dist.Z", "r");
  868. X    while(zfgets(buf, sizeof(buf), f)) {
  869. X    (void) fputs(buf, stdout);
  870. X    }
  871. X    (void) zfclose(f);
  872. X}
  873. X#endif
  874. END_OF_FILE
  875.   if test 3519 -ne `wc -c <'uncomp.c'`; then
  876.     echo shar: \"'uncomp.c'\" unpacked with wrong size!
  877.   fi
  878.   # end of 'uncomp.c'
  879. fi
  880. if test -f 'unpack.c' -a "${1}" != "-c" ; then 
  881.   echo shar: Will not clobber existing file \"'unpack.c'\"
  882. else
  883.   echo shar: Extracting \"'unpack.c'\" \(7122 characters\)
  884.   sed "s/^X//" >'unpack.c' <<'END_OF_FILE'
  885. X/* Copyright 1992, Chris Lewis.  All Rights Reserved
  886. X   Please see the README for the terms of the copyright.
  887. X   1.3 92/08/14
  888. X */
  889. X
  890. X#ifndef lint
  891. Xstatic char SCCSid[] = "@(#)unpack.c 1.3 92/08/14 20:48:41";
  892. X#endif
  893. X#define    UNPACKMAPS
  894. X#include "unpack.h"
  895. X
  896. X/*
  897. X    This code depends on the following map article format:
  898. X        <don't cares>
  899. X        cat << 'something' > filename
  900. X            map body
  901. X            something
  902. X            <don't cares>
  903. X
  904. X        "something" doesn't have to be enclosed in quotes in the
  905. X        cat line.
  906. X */
  907. X
  908. Xint stunpacked = 0;
  909. Xint stdiscarded = 0;
  910. X
  911. Xunpack() {
  912. X    FILE *work, *artfp, *outfp;
  913. X    char article[BUFSIZ],
  914. X     buf[BUFSIZ],
  915. X     outfile[BUFSIZ],
  916. X     endmarker[BUFSIZ];
  917. X    int discarding, collecting, foundone, endmlen;
  918. X    register char *f, *t;
  919. X
  920. X    (void) umask(022);
  921. X
  922. X    (void) unlink(tempfile);
  923. X
  924. X    fatal(chdir(unpackdir), "Can't change to unpacking directory");
  925. X    fatal(access(".", W_OK|R_OK),
  926. X     "Incorrect permissions on unpacking directory");
  927. X
  928. X    if (initialize) {
  929. X    (void) sprintf(tempbuf, "find %s/comp/mail/maps -type f -print >> togo",
  930. X        spooldir);
  931. X    fatal(system(tempbuf), "Find in spooldir/comp/mail/maps failed");
  932. X    }
  933. X
  934. X    while(access(togofile, R_OK) == 0 ||
  935. X      access(workfile, R_OK) == 0) {
  936. X
  937. X    if (access(workfile, F_OK) != 0) {
  938. X        setbatch(1);
  939. X        fatal(link(togofile, workfile), "link from togo to work");
  940. X        fatal(unlink(togofile), "unlink of togo");
  941. X        setbatch(0);
  942. X    }
  943. X
  944. X    fatal(!(work = fopen(workfile, "r")), "open of work file");
  945. X
  946. X    while(fgets(buf, sizeof(buf), work)) {
  947. X
  948. X        for (f = buf, t = article; *f && !isspace(*f); )
  949. X        *t++ = *f++;
  950. X        *t = '\0';
  951. X
  952. X        if (access(article, R_OK) != 0) {
  953. X        (void) sprintf(buf, "%s/%s", spooldir, article);
  954. X        if (access(buf, R_OK) != 0) {
  955. X            (void) fprintf(stderr, "%s apparently superseded or expired\n",
  956. X            article);
  957. X            continue;
  958. X        }
  959. X        (void) strcpy(article, buf);
  960. X        }
  961. X
  962. X        if (debug)
  963. X        (void) fprintf(stderr, "AE: %s\n", article);
  964. X
  965. X        if (!(artfp = fopen(article, "r"))) {
  966. X        (void) fprintf(stderr, "cannot open %s\n", article);
  967. X        continue;
  968. X        }
  969. X
  970. X        collecting = foundone = 0;
  971. X
  972. X
  973. X        while(fgets(buf, sizeof(buf), artfp)) {
  974. X
  975. X        if (!collecting && strncmp("cat ", buf, 4) == 0) {
  976. X            struct stat stb;
  977. X
  978. X            if (!catheader(buf, endmarker, outfile, article))
  979. X            break;
  980. X
  981. X            endmlen = strlen(endmarker);
  982. X
  983. X
  984. X            discarding = unlinkskip && search(lmapfiles.list, outfile);
  985. X
  986. X            if (discarding)
  987. X            unlink(outfile);
  988. X
  989. X            if (!(outfp = fopen(tempfile, "w"))) {
  990. X            (void) fprintf(stderr, "Couldn't open %s file - skipping\n",
  991. X                tempfile);
  992. X            break;
  993. X            } else if (verbose)
  994. X            (void) fprintf(stderr, "%s %s from %s\n",
  995. X                discarding ? "Discarding": "Extracting",
  996. X                outfile, article);
  997. X
  998. X            foundone = collecting = 1;
  999. X            continue;
  1000. X        }
  1001. X
  1002. X        if (!collecting)
  1003. X            continue;
  1004. X
  1005. X        if (strncmp(buf, endmarker, endmlen) == 0 &&
  1006. X            buf[endmlen] == '\n') {
  1007. X
  1008. X            collecting = 0;
  1009. X            (void) fclose(outfp);
  1010. X
  1011. X            (void) unlink(outfile);
  1012. X
  1013. X            if (!discarding)
  1014. X            fatal(link(tempfile, outfile), "link temp to output file");
  1015. X
  1016. X            if (discarding)
  1017. X            stdiscarded++;
  1018. X            else
  1019. X            stunpacked++;
  1020. X
  1021. X            fatal(unlink(tempfile), "unlink temp file");
  1022. X
  1023. X            chmod(outfile, 0644);
  1024. X
  1025. X            if (!discarding)
  1026. X            docompress(outfile);
  1027. X
  1028. X            continue;
  1029. X        }
  1030. X
  1031. X        (void) fputs(buf, outfp);
  1032. X
  1033. X        }
  1034. X
  1035. X        fclose(artfp);
  1036. X
  1037. X        if (collecting) {
  1038. X        (void) fprintf(stderr, "Non-terminated map in %s\n", article);
  1039. X        (void) fclose(outfp);
  1040. X        (void) unlink(tempfile);
  1041. X        continue;
  1042. X        }
  1043. X
  1044. X        if (!foundone) {
  1045. X        (void) fprintf(stderr, "%s does not contain a properly formed map\n",
  1046. X            article);
  1047. X        continue;
  1048. X        } else
  1049. X        anyunpacked = 1;
  1050. X
  1051. X        if (unlinkflag)
  1052. X        (void) unlink(article);
  1053. X    }
  1054. X    (void) fclose(work);
  1055. X    (void) unlink(workfile);
  1056. X    }
  1057. X
  1058. X    if (stdiscarded)
  1059. X    (void) fprintf(stderr, "%d maps discarded\n", stdiscarded);
  1060. X    if (stunpacked)
  1061. X    (void) fprintf(stderr, "%d maps unpacked\n", stunpacked);
  1062. X
  1063. X    if (debug)
  1064. X    (void) fprintf(stderr, "End of %s file\n", workfile);
  1065. X    docompress((char *) NULL);
  1066. X}
  1067. X
  1068. X/*
  1069. X    Parse the "cat << 'something' > filename" line.
  1070. X
  1071. X    Strip off any quotes, and check the filename for security
  1072. X    breaches.
  1073. X
  1074. X    Since we know that buf is limited to 512 bytes, we
  1075. X    don't have to check endmarker and outfile overflow.
  1076. X */
  1077. X
  1078. Xcatheader(buf, endmarker, outfile, article)
  1079. Xchar *buf, *endmarker, *outfile, *article; {
  1080. X    register char *p = buf+4, *p2;
  1081. X    register int i;
  1082. X
  1083. X    p2 = strchr(buf, '\n');    /* chop(inbuf) ;-) */
  1084. X    if (p2)
  1085. X    *p2 = '\0';
  1086. X
  1087. X    while(*p && *p == ' ') p++;    /* skip whitespace after cat */
  1088. X
  1089. X    if (!*p || *p != '<') {
  1090. X    (void) fprintf(stderr, "%s: malformed cat line: %s\n", article, buf);
  1091. X    return(0);
  1092. X    }
  1093. X
  1094. X    while(*p && *p != ' ') p++;        /* skip to begin of white space */
  1095. X    while(*p && *p == ' ') p++;        /* skip to begin of end marker */
  1096. X
  1097. X    for (p2 = endmarker; *p && *p != ' '; )    /* copy over endmarker */
  1098. X    *p2++ = *p++;
  1099. X
  1100. X    *p2 = '\0';
  1101. X    if (endmarker[0] == '\'') {
  1102. X    *(p2-1) = '\0';
  1103. X    /* should work ;-) */
  1104. X    (void) strcpy(endmarker, &endmarker[1]);
  1105. X    }
  1106. X
  1107. X    while(*p && *p == ' ') p++;
  1108. X    if (!*p || *p != '>') {
  1109. X    (void) fprintf(stderr, "%s: malformed cat line: %s\n", article, buf);
  1110. X    return(0);
  1111. X    }
  1112. X    while(*p && *p != ' ') p++;        /* skip over > */
  1113. X    while(*p && *p == ' ') p++;        /* skip over whitespace */
  1114. X
  1115. X    if (!*p) {
  1116. X    (void) fprintf(stderr, "%s: malformed cat line: %s\n", article, buf);
  1117. X    return(0);
  1118. X    }
  1119. X
  1120. X    for (p2 = outfile; *p && *p != ' '; )
  1121. X    *p2++ = *p++;
  1122. X    *p2 = '\0';
  1123. X
  1124. X    if (strlen(outfile) < 1) {
  1125. X    (void) fprintf(stderr, "%s: missing filename: %s\n",
  1126. X        article, buf);
  1127. X    return(0);
  1128. X    }
  1129. X
  1130. X#if    (FILELENGTH == 0)
  1131. X# define MAXUNPLEN 12
  1132. X#else
  1133. X# if    (FILELENGTH == 1)
  1134. X#  define MAXUNPLEN 14
  1135. X# else
  1136. X#  define MAXUNPLEN (FILELENGTH - 2)
  1137. X# endif
  1138. X#endif
  1139. X    
  1140. X    if (strlen(outfile) > MAXUNPLEN) {
  1141. X    (void) fprintf(stderr, "%s: output filename too long (> %d): %s\n",
  1142. X        article, MAXUNPLEN, outfile);
  1143. X    return(0);
  1144. X    }
  1145. X
  1146. X    /* security checks */
  1147. X    for (p = outfile; *p; p++)
  1148. X    if (isalpha(*p) ||
  1149. X        isdigit(*p) ||
  1150. X        *p == '.')
  1151. X
  1152. X        continue;
  1153. X    else {
  1154. X        (void) fprintf(stderr, 
  1155. X        "%s: Security violation attempt: bad character[s]: %s\n%s%s\n",
  1156. X        article, outfile, "  in cat line: ", buf);
  1157. X        return(0);
  1158. X    }
  1159. X
  1160. X    if (*outfile == '.' ||
  1161. X    strncmp(outfile, "togo", 4) == 0 ||
  1162. X    strncmp(outfile, "path.", 5) == 0 ||
  1163. X    strcmp(outfile, "where.db") == 0 ||
  1164. X    strcmp(outfile, "_temp_") == 0) {
  1165. X
  1166. X    (void) fprintf(stderr,
  1167. X        "%s: Security violation attempt: attempts to write on %s\n%s%s\n",
  1168. X        article, outfile, "  in cat line: ", buf);
  1169. X    return(0);
  1170. X    }
  1171. X    return(1);
  1172. X}
  1173. X
  1174. X#ifdef    TESTCAT
  1175. Xdoone(buf)
  1176. Xchar *buf; {
  1177. X    char endmarker[512];
  1178. X    char outfile[512];
  1179. X
  1180. X    if (catheader(buf, endmarker, outfile, "/////123"))
  1181. X    printf("Good: %s -> endmarker: %s, outfile: %s\n",
  1182. X        buf, endmarker, outfile);
  1183. X    else
  1184. X    printf("bad: %s\n", buf);
  1185. X}
  1186. X
  1187. Xmain() {
  1188. X    doone("cat << foo > blat\n");
  1189. X    doone("cat << foo > 'blat'\n");
  1190. X    doone("cat << foo > \n");
  1191. X    doone("cat \n");
  1192. X    doone("cat << 'foo' > foo\n");
  1193. X    doone("cat << 'foo' > .foo\n");
  1194. X    doone("cat << 'foo' > README\n");
  1195. X    doone("cat << 'foo' > u.can.on.1\n");
  1196. X    doone("cat << 'foo' > u.can.on.1frammisframmis\n");
  1197. X}
  1198. X#endif
  1199. END_OF_FILE
  1200.   if test 7122 -ne `wc -c <'unpack.c'`; then
  1201.     echo shar: \"'unpack.c'\" unpacked with wrong size!
  1202.   fi
  1203.   # end of 'unpack.c'
  1204. fi
  1205. if test -f 'unpacker.c' -a "${1}" != "-c" ; then 
  1206.   echo shar: Will not clobber existing file \"'unpacker.c'\"
  1207. else
  1208.   echo shar: Extracting \"'unpacker.c'\" \(5196 characters\)
  1209.   sed "s/^X//" >'unpacker.c' <<'END_OF_FILE'
  1210. X/* Copyright 1992, Chris Lewis.  All Rights Reserved
  1211. X   Please see the README for the terms of the copyright.
  1212. X   1.3 92/07/12
  1213. X */
  1214. X
  1215. X#ifndef lint
  1216. Xstatic char SCCSid[] = "@(#)unpacker.c 1.3 92/07/12 16:33:55";
  1217. X#endif
  1218. X#define    UNPACKMAPS
  1219. X#define    INIT(x)    = x
  1220. X#include "unpack.h"
  1221. X
  1222. X#include <signal.h>
  1223. X
  1224. Xquit() {
  1225. X    fatal(1, "Interrupted");
  1226. X}
  1227. X
  1228. Xchar *
  1229. Xcheckabs(value)
  1230. Xchar *value; {
  1231. X    static char pwd[512];
  1232. X    static char buf[512];
  1233. X    if (*value != '/') {
  1234. X    if (!*pwd) {
  1235. X        FILE *p;
  1236. X        char *bp;
  1237. X        p = popen("pwd", "r");
  1238. X        if (!p) {
  1239. X        fprintf(stderr, "%s: can't popen pwd!\n", progname);
  1240. X        exit(1);
  1241. X        }
  1242. X        fgets(pwd, sizeof(pwd), p);
  1243. X        pclose(p);
  1244. X        bp = strchr(pwd, '\n');
  1245. X        if (bp)
  1246. X        *bp = '\0';
  1247. X    }
  1248. X    strcpy(buf, pwd);
  1249. X    strcat(buf, "/");
  1250. X    strcat(buf, value);
  1251. X    return(buf);
  1252. X    } else
  1253. X    return(value);
  1254. X}
  1255. X
  1256. X
  1257. Xmain(argc, argv)
  1258. Xint argc;
  1259. Xchar **argv; {
  1260. X    extern int optind;
  1261. X    extern char *optarg;
  1262. X    int c;
  1263. X
  1264. X    progname = strrchr(argv[0], '/');
  1265. X    if (progname)
  1266. X    progname++;
  1267. X    else
  1268. X    progname = argv[0];
  1269. X    
  1270. X    
  1271. X    while((c = getopt(argc, argv, "vM:tn:VI:cf:s:d:uXpPm:iwWl:U")) != EOF)
  1272. X    switch(c) {
  1273. X        case 'V':
  1274. X        (void) printf("%s\n", VERSION);
  1275. X        exit(0);
  1276. X        case 'v':
  1277. X        verbose = 1;
  1278. X        break;
  1279. X        case 't':
  1280. X        dontunpack = 1;
  1281. X        break;
  1282. X        case 'I':
  1283. X        internet = optarg;
  1284. X        break;
  1285. X        case 'l':
  1286. X        (void) strcpy(tempbuf, optarg);
  1287. X        break;
  1288. X        case 'U':
  1289. X        unlinkskip = 1;
  1290. X        break;
  1291. X        case 'W':
  1292. X        forcepath = 1;
  1293. X        /*fallthru*/
  1294. X        case 'w':
  1295. X        whereonly = runpath = 1;
  1296. X        break;
  1297. X        case 'c':
  1298. X        compflag = 1;
  1299. X        break;
  1300. X        case 'i':
  1301. X        initialize = 1;
  1302. X        break;
  1303. X        case 'f':
  1304. X        savestr(&localmaps, checkabs(optarg));
  1305. X        break;
  1306. X        case 'X':
  1307. X        debug = 1;
  1308. X        break;
  1309. X        case 's':
  1310. X        (void) strcpy(spooldir, checkabs(optarg));
  1311. X        break;
  1312. X        case 'd':
  1313. X        (void) strcpy(unpackdir, checkabs(optarg));
  1314. X        break;
  1315. X        case 'P':
  1316. X        forcepath = runpath = 1;
  1317. X        break;
  1318. X        case 'M':
  1319. X        pathalias = optarg;
  1320. X        runpath = 1;
  1321. X        break;
  1322. X        case 'm':
  1323. X        (void) strcpy(pathfile, checkabs(optarg));
  1324. X        case 'p':
  1325. X        runpath = 1;
  1326. X        break;
  1327. X        case 'u':
  1328. X        unlinkflag = 1;
  1329. X        break;
  1330. X        case 'n':
  1331. X        notify = optarg;
  1332. X        break;
  1333. X        case '?':
  1334. X        usage = 1;
  1335. X        break;
  1336. X    }
  1337. X
  1338. X    if (usage) {
  1339. X    static char *puse[] = {
  1340. X        "usage: unpacker <options>",
  1341. X        "  options: -f <local map files>",
  1342. X        "           -i   (initialize from comp.mail.maps group)",
  1343. X        "           -X   (debug)",
  1344. X        "           -c   (compress maps)",
  1345. X        "           -s <spooldir>",
  1346. X        "           -d <map/unpackdir>",
  1347. X        "           -m <output map> (implies -p)",
  1348. X        "           -M <pathalias pipeline) (implies -p)",
  1349. X        "           -p   (run pathalias if paths out of date)",
  1350. X        "           -P   (run pathalias unconditionally)",
  1351. X        "           -u   (unlink maps after processing)",
  1352. X        "           -V   (print unpackmaps version)",
  1353. X        "           -v   (verbose diagnostics)",
  1354. X        "           -w   (do where file only if out of date)",
  1355. X        "           -W   (do where file unconditionally)",
  1356. X        "           -U   (unlink maps mentioned in ignorefile)",
  1357. X        "           -l <ignorefile>",
  1358. X        "           -n <mail command to send output>",
  1359. X        "           -t   (don't unpack - ignore newsgroup)",
  1360. X        NULL
  1361. X    };
  1362. X    register char **p;
  1363. X
  1364. X    for (p = puse; *p; p++)
  1365. X        (void) fprintf(stderr, "%s\n", *p);
  1366. X
  1367. X    exit(1);
  1368. X    }
  1369. X
  1370. X    if (!dontunpack)
  1371. X    (void) checkids();
  1372. X
  1373. X    if (SIG_DFL == signal(SIGINT, SIG_IGN))
  1374. X    signal(SIGINT, quit);
  1375. X    (void) signal(SIGTERM, quit);
  1376. X
  1377. X    togofile = makepath(unpackdir, "togo");
  1378. X    workfile = makepath(unpackdir, "togo.work");
  1379. X    wheredb = makepath(unpackdir, "where.db");
  1380. X
  1381. X
  1382. X    /* gets linked, so must be in unpackdir */
  1383. X    tempfile = makepath(unpackdir, "_temp_");
  1384. X
  1385. X    if (notify) {
  1386. X
  1387. X    /* Normally these should be created ala mktemp, but we have
  1388. X       to make sure that we clobber on subsequent runs.
  1389. X       Otherwise, there goes your disk if something *really*
  1390. X       wierd goes wrong and they don't get deleted for some reason. */
  1391. X
  1392. X    wheretmp = makepath(TMPDIR2, "UNPAwhere");
  1393. X    pathtmp = makepath(TMPDIR, "UNPApathtmp1");
  1394. X    pathtmp2 = makepath(TMPDIR2, "UNPApathtmp2");
  1395. X    } else {
  1396. X    wheretmp = makepath(TMPDIR2, ".where");
  1397. X    pathtmp = makepath(TMPDIR, ".pathtmp1");
  1398. X    pathtmp2 = makepath(TMPDIR2, ".pathtmp2");
  1399. X    }
  1400. X
  1401. X    unlink(tempfile);
  1402. X    unlink(wheretmp);
  1403. X    unlink(pathtmp);
  1404. X    unlink(pathtmp2);
  1405. X
  1406. X    if (tempbuf[0])
  1407. X    (void) keeplist(tempbuf);
  1408. X
  1409. X    if (notify)
  1410. X    (void) startlog();
  1411. X    
  1412. X    if (!dontunpack)
  1413. X    (void) unpack();
  1414. X
  1415. X    if (runpath)
  1416. X    (void) dorunpath();
  1417. X
  1418. X    myexit(0);
  1419. X    /* NOTREACHED */
  1420. X}
  1421. X
  1422. Xkeeplist(file)
  1423. Xchar *file; {
  1424. X    FILE *f;
  1425. X    register char *p;
  1426. X    fatal(!(f = fopen(file, "r")), "Can't open keeplist");
  1427. X
  1428. X    while(fgets(tempbuf, sizeof(tempbuf), f)) {
  1429. X
  1430. X    p = strchr(tempbuf, '\n');
  1431. X
  1432. X    if (p)
  1433. X        *p = '\0';
  1434. X
  1435. X    p = strrchr(tempbuf, '.');
  1436. X    if (p && 0 == strcmp(p, ".Z"))
  1437. X        *p = '\0';
  1438. X
  1439. X    if (tempbuf[0])
  1440. X        savestr(&lmapfiles, tempbuf);
  1441. X    }
  1442. X    (void) fclose(f);
  1443. X}
  1444. X
  1445. X#include <pwd.h>
  1446. Xcheckids() {
  1447. X    struct passwd *p;
  1448. X    extern struct passwd *getpwnam();
  1449. X
  1450. X    fatal(!(p = getpwnam(NEWSID)), "Can't getpwnam(NEWSID)");
  1451. X    if (geteuid() == 0)
  1452. X    (void) setuid(p->pw_uid);
  1453. X    fatal(p->pw_uid != geteuid() || p->pw_uid != getuid(),
  1454. X    "Must be run as NEWSID");
  1455. X}
  1456. END_OF_FILE
  1457.   if test 5196 -ne `wc -c <'unpacker.c'`; then
  1458.     echo shar: \"'unpacker.c'\" unpacked with wrong size!
  1459.   fi
  1460.   # end of 'unpacker.c'
  1461. fi
  1462. if test -f 'unpackmaps.M' -a "${1}" != "-c" ; then 
  1463.   echo shar: Will not clobber existing file \"'unpackmaps.M'\"
  1464. else
  1465.   echo shar: Extracting \"'unpackmaps.M'\" \(14161 characters\)
  1466.   sed "s/^X//" >'unpackmaps.M' <<'END_OF_FILE'
  1467. X.\"Copyright 1992 by Chris Lewis 1.5 92/11/28
  1468. X.TH UNPACKMAPS 1 "Chris Lewis"
  1469. Xunpackmaps \- USENET UUCP map unpacker
  1470. X.SH SYNOPSIS
  1471. X.B unpackmaps
  1472. X.BI [ options ]
  1473. X.SH DESCRIPTION
  1474. X.B Unpackmaps
  1475. Xis a specially optimized hack program for retrieving and
  1476. Xsafely unpacking the UUCP maps produced by the UUCP Mapping Project.
  1477. XIt can be instructed to run pathalias to generate the UUCP routing
  1478. Xtable that various other mailers need (ie: smail 2.5, IDA Sendmail).
  1479. XIt will also create a special database that
  1480. X.BR uuwhere (1)
  1481. Xuses to display the map entries for individual sites.
  1482. X.P
  1483. X.B Unpackmaps
  1484. Xcan also be used to unpack other USENET postings, such as Brian
  1485. XReid's maps of USENET sites (news.lists.ps-maps), provided that the
  1486. Xshar format used conforms to the UUCP Map postings.
  1487. X.P
  1488. XOne of the difficulties inherent in most posted map unpackers is
  1489. Xthat they use a ``real'' unshar to unpack map articles.
  1490. XSince a ``real'' unshar is just invoking the shell on a portion
  1491. Xof an article, this can easily be seen to be an
  1492. X.BR "extreme security hole" .
  1493. XWhich bears repeating, using an insecure (usually home grown) unpacker
  1494. Xis just asking for your machine to be
  1495. X.BR destroyed .
  1496. X.P
  1497. XThe ``SECURITY ISSUES'' section of this manual page analyses
  1498. Xsome of the potential vulnerabilities, and discusses how
  1499. X.B unpackmaps
  1500. Xdeals with them.
  1501. X.P
  1502. XThe term ``hack'' was used in the first paragraph.
  1503. X.B Unpackmaps
  1504. Xis not a ``tool'' in the UNIX sense.
  1505. XThe reason for this is simple: the maps are huge, and some machines
  1506. Xare quite small.
  1507. X.B Unpackmaps
  1508. Xis designed to use as little time, memory and disk space as possible.
  1509. XIn fact,
  1510. X.B Unpackmaps
  1511. Xwill allow you to compress the maps and run pathalias even on 16 bit machines,
  1512. Xprovided that you instruct it to use a sufficiently small subset of the maps
  1513. Xthat
  1514. X.B pathalias
  1515. Xdoesn't run out of memory.
  1516. X.P
  1517. XThe highest load that 
  1518. X.B unpackmaps
  1519. Ximposes is during the map decompression
  1520. Xand pathalias phase.
  1521. X.B Unpackmaps
  1522. Xcontains its own decompression function that dynamically sizes itself
  1523. Xto the requirements of the compressed files.
  1524. XIf the maps are compressed with 16 bit compression (a build option),
  1525. X.B unpackmaps
  1526. Xwill grow to around 500K.
  1527. XProcessing the complete UUCP maps currently (March 1992) causes
  1528. X.B pathalias
  1529. Xto grow to about 2Mb.
  1530. X.B Unpackmaps
  1531. Xwill not page or swap provided that you have enough memory to fit it
  1532. Xand
  1533. X.BR pathalias .
  1534. XIt is suggested that you consider reducing the compression factor in
  1535. Xconfig.h to prevent things from swapping to disk.
  1536. X.SH "BASIC FUNCTIONALITY"
  1537. X.B Unpackmaps
  1538. Xdoes all of its work in a directory set aside for the purpose.
  1539. XIt should be created and it's ownership should be set to the
  1540. Xuserid that owns your news system.
  1541. XThis is the ``map directory''.
  1542. XThere should be a different map directory for each different
  1543. Xtype of article you wish to unpack.
  1544. XThe sys file for your news system is instructed to write
  1545. Xthe file names of each incoming article in the desired
  1546. Xgroups into a
  1547. X.I togo
  1548. Xfile in the appropriate directory.
  1549. X.P
  1550. X.B Unpackmaps
  1551. Xis run from a cron job, as ``news'', and will read through
  1552. Xthe 
  1553. X.I togo
  1554. Xfile and unpack the map articles into the directory.
  1555. X.P
  1556. XIf instructed,
  1557. X.B unpackmaps
  1558. Xwill invoke pathalias on the maps and generate a paths
  1559. Xdatabase and
  1560. X.B uuwhere
  1561. Xdatabase.
  1562. XThis can be either unconditional, or based on whether any
  1563. Xarticles were unpacked.
  1564. X.P
  1565. XOptionally, the unpacked articles can be compressed,
  1566. Xand the original articles removed from the spool area
  1567. Xas they are being extracted.
  1568. X.SH OPTIONS
  1569. X.P
  1570. XUnpacking options:
  1571. X.TP .5i
  1572. X.B \-V
  1573. XPrint unpackmaps version.
  1574. X.TP .5i
  1575. X.B \-v
  1576. XPrint file names of maps and map names as they're unpacked, discarded
  1577. Xor unlinked.
  1578. X.TP .5i
  1579. X.B \-t
  1580. XSkip unpacking step.
  1581. XAlso prevents unpackmaps from insisting on running as the NEWSID.
  1582. XWhich permits invocation as an arbitrary user, but care needs to be
  1583. Xtaken that you specify map files in places that are writable by
  1584. Xyou.
  1585. X.TP .5i
  1586. X.BI \-n notify
  1587. XSpecifies a mail pipeline to do notification of completion.
  1588. XIf not specified, all output is on stderr.
  1589. X.TP .5i
  1590. X.BI \-d directory
  1591. XDirectory to do the unpacking in.
  1592. XDefault:
  1593. X.IR /usr/spool/maps .
  1594. X.TP .5i
  1595. X.B \-u
  1596. XDelete the articles from the news system after they're unpacked.
  1597. XDo not do this unless you don't pass these articles on to your neighbors,
  1598. Xie: you are a leaf site.
  1599. X.TP .5i
  1600. X.B \-c
  1601. XCompress the files after they're created.
  1602. X.B Compress
  1603. Xis invoked with groups of 10 files apiece.
  1604. X.TP .5i
  1605. X.B \-i
  1606. XInitialize - this is a short cut for starting up
  1607. X.B unpackmaps
  1608. Xwhen you have an empty map directory, and a news spool directory
  1609. Xfull of articles.
  1610. XIt merely creates a
  1611. X.I togo
  1612. Xfile from the contents of
  1613. X.BI <spooldir> /comp/mail/maps.
  1614. XThis can easily be done via a manual
  1615. X.in +.5i
  1616. X.nf
  1617. X.sp
  1618. Xls <full path to a directory>/* >> <mapdir>/togo
  1619. X.sp
  1620. X.fi
  1621. X.in -.5i
  1622. X.TP .5i
  1623. X.BI \-s directory
  1624. XSet the news spool directory.
  1625. XDefault:
  1626. X.IR /usr/spool/news .
  1627. XThis is required for proper unpacking if your system does not use
  1628. X.I /usr/spool/news
  1629. Xfor the news spool directory, or your news system doesn't write
  1630. Xfull paths into the togo files (ie: new versions of C news).
  1631. X.P
  1632. XPathalias invocation options:
  1633. X.TP .5i
  1634. X.B \-P
  1635. XRun pathalias.
  1636. X.TP .5i
  1637. X.B \-p
  1638. XRun pathalias if any of the maps are newer than the last UUCP map created.
  1639. X.TP .5i
  1640. X.BI \-M pipeline
  1641. XAlternate pathalias pipeline.
  1642. XImplies \-p.
  1643. XThis should really be placed in a shell script.
  1644. XStandard input is the maps themselves (comments are stripped out
  1645. Xat this point), and standard output is the
  1646. Xpathalias file.
  1647. XFor example, something like this could be used:
  1648. X.P
  1649. X.in +.5i
  1650. X.nf
  1651. X/usr/local/bin/pathalias -fi | sed -e 's/foo!bang/bang!foo/'
  1652. X.fi
  1653. X.in -.5i
  1654. X.P
  1655. XDefault specified in compile.
  1656. XWith the -f option, pathalias will be emitting the paths in this form:
  1657. X.P
  1658. X.nf
  1659. Xcost   site   route
  1660. X.fi
  1661. X.P
  1662. X.TP .5i
  1663. X.BI \-m file
  1664. XSpecifies where the resultant UUCP map should be written.
  1665. XImplies
  1666. X.BR \-p .
  1667. XDefault:
  1668. X.I /usr/lib/uucp/paths
  1669. X(Smail 2.5 default)
  1670. X.TP .5i
  1671. X.BI \-f file
  1672. XAppend
  1673. X.I file
  1674. Xonto the list of map directory files to be processed through pathalias.
  1675. XThis is how you specify local map files.
  1676. XThis option can be used more than once.
  1677. XThe file names should be full paths, unless you keep the file in the
  1678. Xmap directory.
  1679. XIn which case, they should all be named ``path.<something>'' (see
  1680. X``SECURITY ISSUES'' section).
  1681. X.TP .5i
  1682. X.B \-W
  1683. XJust create the
  1684. X.B uuwhere
  1685. Xdatabase
  1686. X.RI ( where.db ),
  1687. Xand don't run
  1688. X.BR pathalias .
  1689. X.TP .5i
  1690. X.BI \-w
  1691. XSame as \-W, except don't create the where database unless any
  1692. Xof the maps are newer than when it was last created.
  1693. X.TP .5i
  1694. X.B \-U
  1695. XUnlink any ``u.''-prefixed map file mentioned in the
  1696. X.BR ignorefile .
  1697. X.TP .5i
  1698. X.BI \-l file
  1699. XSpecify the
  1700. X.BR ignorefile .
  1701. XA file listing, one per line, the map files that should not be
  1702. Xpiped into
  1703. X.BR pathalias .
  1704. XIf
  1705. X.B \-l
  1706. Xis used without
  1707. X.BR \-U ,
  1708. X.B unpackmaps
  1709. Xwill not pass the files mentioned in the ignorefile through to
  1710. X.BR pathalias ,
  1711. Xhowever, all files will be cross-referenced in the
  1712. X.B uuwhere
  1713. Xdatabase.
  1714. XThis is convenient for keeping a database of all sites in the map, but
  1715. Xonly constructing a
  1716. X.B paths
  1717. Xfile for a subset of the net.
  1718. X(See the OPERATIONS section for an example).
  1719. X.IP "" .5i
  1720. XIf \-U is also specified, any file listed in the
  1721. X.B ignorefile
  1722. Xwill be deleted (only if it has a ``u.'' prefix), and not cross-referenced in the
  1723. X.B where
  1724. Xdatabase.
  1725. X.TP .5i
  1726. X.BI \-I route
  1727. XIf you have a nearby friendly
  1728. Xsite with good routing software, you can specify a route here.
  1729. XThis will replace any path entries for sites with domain names with
  1730. Xa route to that site followed by the domain site.
  1731. XFor example,
  1732. X.BI \-I foo!uunet.ca
  1733. Xwill cause
  1734. X.B unpackmaps
  1735. Xto replace all routes to domain-named sites with
  1736. X.IR "foo!uunet.ca!<domain-named site>!<user>" .
  1737. XThis is only done if the
  1738. X.BR pathalias -created
  1739. Xrouting has two more hops than the specified
  1740. X.IR route .
  1741. XFurther,
  1742. Xall ``.domain'' routes
  1743. Xthat are longer than the \fIroute\fP
  1744. Xwill be shortened to 
  1745. X.IR "route!<domain>!<user>" .
  1746. XAnd finally, if there are domainized sites in a route, the path
  1747. Xto the last domainized site will be replaced with
  1748. X.IR route .
  1749. XIe: ``a!b!c!d.edu!e.edu!d'' will be transformed to
  1750. X.IR route "!e.edu!d".
  1751. X.IP "" .5i
  1752. XThis should be done with extreme care, with the permission of all of the
  1753. Xsites involved in the specified
  1754. X.IR route .
  1755. XFurther, the designated forwarder site \fBMUST\fP support full domain
  1756. Xaddressing - hopefully it is running full DNS/BIND on the Internet.
  1757. XHowever, properly managed pathalias sites (such as ones running
  1758. X.B unpackmaps
  1759. X;-) should be capable of being your internet forwarder.
  1760. XThis is primarily intended for situations where you're directly connected
  1761. Xto a commercial Internet service, such as
  1762. X.BR uunet .
  1763. XThis is roughly analogous to
  1764. X.B pathalias
  1765. X.I smart-host
  1766. Xin that domain-named sites are automatically sent to a specific Internet
  1767. Xsite, instead of all mail to sites not listed in the maps.
  1768. XNote, however, that you don't need to make your internet route be
  1769. Xthe same as your smart-host.
  1770. X.SH "SETUP AND OPERATION"
  1771. X.P
  1772. XFirst of all, you should create a directory for each set of articles
  1773. Xyou wish to unpack.
  1774. XWe'll assume the use of /usr/spool/maps for UUCP maps.
  1775. XThis directory should be owned by the same userid that runs news.
  1776. XWe'll assume ``news''.
  1777. X.P
  1778. XYou will usually need to create the file that
  1779. X.B unpackmaps
  1780. Xwill write the UUCP paths file into, and change its
  1781. Xownership to news.
  1782. XIe:
  1783. X.P
  1784. X.in +.5i
  1785. X.nf
  1786. Xsu root
  1787. Xtouch /usr/lib/uucp/paths
  1788. Xchown news /usr/lib/uucp/paths
  1789. Xchmod 644 /usr/lib/uucp/paths
  1790. X.fi
  1791. X.in -.5i
  1792. X.P
  1793. XThen you should insert the following into your news
  1794. X.I sys
  1795. Xfile:
  1796. X.P
  1797. XFor Cnews:
  1798. X.P
  1799. Xmaps:comp.mail.maps/all:f:/usr/spool/maps/togo
  1800. X.P
  1801. XFor Bnews:
  1802. X.P
  1803. Xmaps:world,comp.mail.maps:F:/usr/spool/maps/togo
  1804. X.P
  1805. XThen, you install a cron entry to invoke unpackmaps.
  1806. XIt should be invoked by the userid that owns news.
  1807. XIf you have the 
  1808. X.IR /usr/lib/crontab -style
  1809. Xcron you will want to insert this into
  1810. X.IR /usr/lib/crontab :
  1811. X.in +.5i
  1812. X.nf
  1813. X.sp
  1814. Xm h * * * su news -c "<unpackmaps invocation>"
  1815. X.sp
  1816. X.fi
  1817. X.in -.5i
  1818. XWhere
  1819. X.B m
  1820. Xand
  1821. X.B h
  1822. Xare the minute and hour you want the program to run.
  1823. X.P
  1824. XIf you have a
  1825. X.BR crontab -style
  1826. Xversion of cron, you would enter the same thing into the
  1827. Xnews cron entry, but the "su news -c" and double quotes aren't
  1828. Xnecessary.
  1829. X.P
  1830. XThe best approach is to have the crontab entry invoke a shell
  1831. Xscript that has the
  1832. X.B unpackmaps
  1833. Xinvocation line.
  1834. X.P
  1835. XThe "unpackmaps invocation" would normally be something like this
  1836. X.in +.5i
  1837. X.nf
  1838. X.sp
  1839. X<path to unpackmaps>/unpackmaps -cpn'mail news'
  1840. X.sp
  1841. X.fi
  1842. X.in -.5i
  1843. X.P
  1844. XWhich simply means compress any incoming maps and run
  1845. X.BR pathalias .
  1846. XThe
  1847. X.B uuwhere
  1848. Xdatabase will be created as well.
  1849. XThe results of the run will be mailed to the news userid.
  1850. X.P
  1851. XIt's usually common for a system administrator to
  1852. Xhave a local copy of his site map entry and/or a
  1853. Xmap entry that is used to customize/"fix" routing
  1854. Xelsewhere.
  1855. XSupply these as \-f options to
  1856. X.BR unpackmaps .
  1857. XI use
  1858. X.B path.local
  1859. Xto keep the most up-to-date copy of my map entry,
  1860. Xand
  1861. X.B path.hacks
  1862. Xto keep local customizations (eg: ``dead'' links etc.)
  1863. X.P
  1864. XSystems that are really short of space may want to run
  1865. X.B unpackmaps
  1866. Xmore often.
  1867. XOne suggested approach would be to run the first
  1868. X.B unpackmaps
  1869. Xentry several times a day,
  1870. Xand the second one once per day:
  1871. X.sp
  1872. X.nf
  1873. Xunpackmaps -cuUwl keepfile -n '/bin/mail somebody'
  1874. Xunpackmaps -cuUpl keepfile -n '/bin/mail somebody'
  1875. X.fi
  1876. X.P
  1877. XIf you wish to unpack Brian Reid's network maps, try the following
  1878. Xapproach:
  1879. X.P
  1880. XFirst, create /usr/spool/ps-maps, owner news.
  1881. X.P
  1882. XModify the sys file thusly:
  1883. X.P
  1884. XFor Cnews:
  1885. X.P
  1886. Xps-maps:news.lists.ps-maps/all:f:/usr/spool/ps-maps/togo
  1887. X.P
  1888. XFor Bnews:
  1889. X.P
  1890. Xps-maps:world,news.lists.ps-maps:F:/usr/spool/ps-maps/togo
  1891. X.P
  1892. XThen run the following as news from your cron:
  1893. X.P
  1894. Xunpackmaps -cud /usr/spool/ps-maps
  1895. X.SH "SECURITY ISSUES"
  1896. X.P
  1897. XIt is trivially easy to forge a posting in the map newsgroups.
  1898. XMany map unpackers more-or-less ram the article straight through
  1899. Xthe shell expecting it to be a well-behaved shar file.
  1900. XOn the other hand, the forger could include a ``rm -fr /''
  1901. Xor something even more damaging in the article instead.
  1902. X.P
  1903. X.B Uuhosts
  1904. Xtakes the approach of isolating the unpacking area
  1905. Xunder a ``chroot(2)''.
  1906. XThis is a little awkward, because you have to duplicate
  1907. Xmany things into the chroot'd area, and you have to run the
  1908. Xunpacker as root.
  1909. X.P
  1910. X.B Unpackmaps
  1911. Xtakes an entirely different approach.
  1912. XThe UUCP mapping project (and Brian Reid's ps-maps) uses a
  1913. Xvery simple format for encapsulating maps:
  1914. X.P
  1915. X.nf
  1916. X<stuff>
  1917. Xcat << endtoken > file
  1918. X<body of map>
  1919. Xendtoken
  1920. X.fi
  1921. X.P
  1922. X.B Unpackmaps
  1923. Xscans the file looking for the ``cat'' lines and parses it
  1924. Xin C, coming up with the file name and endtoken.
  1925. XThus, it is impossible for a forger to do anything other than
  1926. Xcreate a file.
  1927. X.P
  1928. X.B Unpackmaps
  1929. Xthen checks the specified filename for oddities:
  1930. Xa prefix of "../" would specify writing a file outside of the
  1931. Xmap directory.
  1932. XOther possibilities are shell metacharacters (which might cause
  1933. Xthe unpacker to foul up), or insertion of shell scripts to snare
  1934. Xthe unwary system administrator with ``.'' first in their PATH.
  1935. X.P
  1936. X.B Unpackmaps
  1937. Xscans the file name and will reject a file with:
  1938. Xa leading ``.'', or that contains any character that is not
  1939. Xalphabetic (lower and upper case), a digit (0..9) or a period.
  1940. XIt also rejects names that are longer than 14 characters.
  1941. X.P
  1942. XSince
  1943. X.B unpackmaps
  1944. Xalso puts other files into the map directory, it also checks
  1945. Xfor and rejects attempts to write to ``togo*'', ``where.db''
  1946. Xor ``path.*'' (the latter for SA's to install their
  1947. Xown map entries via \-f).
  1948. X.P
  1949. XAnd finally, all files are created mode 644, so they can't
  1950. Xbe executed by accident.
  1951. X.P
  1952. X.B Uuhosts
  1953. Xspends a fair amount of time verifying article headers.
  1954. XGiven the ease of forgery, this seems rather pointless.
  1955. XThis checking also makes it difficult to make any changes
  1956. Xto the map headers - such as cross-posting to other groups.
  1957. X.SH FILES
  1958. X.br
  1959. X.if t .ta 2.5i
  1960. X.if n .ta 3.5i
  1961. X/usr/spool/maps    Default map directory
  1962. X"/where.db    Where database
  1963. X"/maps    Where the unpacked maps are kept
  1964. X/usr/lib/uucp/paths    Default paths file
  1965. X.SH AUTHOR
  1966. X.B Unpackmaps
  1967. Xwas written by Chris Lewis.
  1968. XThe built-in decompress routine was written by James A. Wood
  1969. Xand appeared in the 1990 (?) Obfuscated C Contest.
  1970. X(Though was somewhat de-obfuscated and modified for use in
  1971. X.BR unpackmaps )
  1972. END_OF_FILE
  1973.   if test 14161 -ne `wc -c <'unpackmaps.M'`; then
  1974.     echo shar: \"'unpackmaps.M'\" unpacked with wrong size!
  1975.   fi
  1976.   # end of 'unpackmaps.M'
  1977. fi
  1978. if test -f 'uuwhere.c' -a "${1}" != "-c" ; then 
  1979.   echo shar: Will not clobber existing file \"'uuwhere.c'\"
  1980. else
  1981.   echo shar: Extracting \"'uuwhere.c'\" \(3512 characters\)
  1982.   sed "s/^X//" >'uuwhere.c' <<'END_OF_FILE'
  1983. X/* Copyright 1992, Chris Lewis.  All Rights Reserved
  1984. X   Please see the README for the terms of the copyright.
  1985. X   1.2 92/08/14
  1986. X */
  1987. X
  1988. X#ifndef lint
  1989. Xstatic char SCCSid[] = "@(#)uuwhere.c 1.2 92/08/14 20:48:55";
  1990. X#endif
  1991. X#define    INIT(x)    = x
  1992. X#include "unpack.h"
  1993. X
  1994. Xint verbose;
  1995. Xint lflag;
  1996. Xint emitmap;
  1997. X
  1998. Xint rc = 0;
  1999. X
  2000. Xmain(argc, argv)
  2001. Xint argc;
  2002. Xchar **argv; {
  2003. X    int cost;
  2004. X    register int i;
  2005. X    char buf[BUFSIZ];
  2006. X    char smarthost[BUFSIZ];
  2007. X    int smarthosted;
  2008. X    int c;
  2009. X    char *region = NULL;
  2010. X    register char **p, *rp;
  2011. X    extern char *optarg, *gpathdata;
  2012. X    extern int optind;
  2013. X    extern long pathlength;
  2014. X
  2015. X    progname = argv[0];
  2016. X
  2017. X    while((c = getopt(argc, argv, "Xd:m:evr:l")) != EOF)
  2018. X    switch(c) {
  2019. X        case 'd':
  2020. X        (void) strcpy(unpackdir, optarg);
  2021. X        break;
  2022. X        case 'm':
  2023. X        (void) strcpy(pathfile, optarg);
  2024. X        break;
  2025. X        case 'v':
  2026. X        verbose = 1;
  2027. X        break;
  2028. X        case 'e':
  2029. X        emitmap = 1;
  2030. X        break;
  2031. X        case 'l':
  2032. X        lflag = 1;
  2033. X        break;
  2034. X        case 'r':
  2035. X        region = optarg;
  2036. X        break;
  2037. X        case 'X':
  2038. X        debug = 1;
  2039. X        break;
  2040. X        case '?':
  2041. X        usage = 1;
  2042. X        break;
  2043. X    }
  2044. X
  2045. X    if (usage) {
  2046. X    static char *uuse[] = {
  2047. X        "usage: uuwhere <options>",
  2048. X        "  options: -d mapdir      map directory",
  2049. X        "           -m pathfile    pathalias map file",
  2050. X        "           -e             display map entry)",
  2051. X        "           -v             display interesting path information",
  2052. X        "           -l             display map file names",
  2053. X        "           -r region      display map (region) file",
  2054. X        NULL
  2055. X    };
  2056. X
  2057. X    for (p = uuse; *p; p++)
  2058. X        (void) fprintf(stderr, "%s\n", *p);
  2059. X
  2060. X    exit(1);
  2061. X    }
  2062. X
  2063. X
  2064. X    if (chdir(unpackdir)) {
  2065. X    (void) fprintf(stderr, "%s: Can't change to %s\n", progname, unpackdir);
  2066. X    exit(1);
  2067. X    }
  2068. X
  2069. X    wheredb = makepath(unpackdir, "where.db");
  2070. X    if (debug)
  2071. X    (void) fprintf(stderr, "wheredb: %s\n", wheredb);
  2072. X
  2073. X    if (lflag)
  2074. X    exit(dolist());
  2075. X
  2076. X    if (region) {
  2077. X    int list[2];
  2078. X    list[0] = 1;
  2079. X    list[1] = 0;
  2080. X    exit(dumpfile(region, list, 0));
  2081. X    }
  2082. X
  2083. X    gpathdata = pathfile;
  2084. X    pathlength = 0;
  2085. X
  2086. X    if (getpath("smart-host", smarthost, &cost))
  2087. X    smarthost[0] = '\0';
  2088. X    
  2089. X    for (i = optind; i < argc; i++) {
  2090. X    buf[0] = 0;
  2091. X    smarthosted = 0;
  2092. X    if (emitmap)
  2093. X        pathlength = 0;
  2094. X    if (getpath(argv[i], buf, &cost)) {
  2095. X        if (smarthost[0]) {
  2096. X        (void) sprintf(buf, smarthost, argv[i]);
  2097. X        smarthosted = 1;
  2098. X        rc |= 2;
  2099. X        } else {
  2100. X        buf[0] = '\0';
  2101. X        rc |= 4;
  2102. X        }
  2103. X    } else {
  2104. X        rp = strrchr(buf, '!');
  2105. X        if (rp)
  2106. X        *rp = '\0';
  2107. X        else
  2108. X        (void) strcpy(buf, argv[i]);
  2109. X    }
  2110. X
  2111. X    if (verbose) {
  2112. X        (void) printf("route %s: %s!<user>", argv[i], buf[0]? buf: "<noroute>");
  2113. X        if (smarthosted)
  2114. X        (void) printf(" (smarthosted)");
  2115. X        (void) putchar('\n');
  2116. X    } else
  2117. X        if (buf[0])
  2118. X        (void) printf("%s\n", buf);
  2119. X    if (emitmap)
  2120. X        (void) dumpmap(argv[i]);
  2121. X    }
  2122. X    exit(rc);
  2123. X    /* NOTREACHED */
  2124. X}
  2125. X
  2126. Xstruct stringlist sl;
  2127. Xdolist() {
  2128. X    register char *p, *q;
  2129. X    char **mapptr;
  2130. X    struct stat stb;
  2131. X    extern char *ctime();
  2132. X
  2133. X    getmaps(&sl, 0);
  2134. X    for (mapptr = sl.list; *mapptr; mapptr++)
  2135. X    if (verbose) {
  2136. X        if (stat(*mapptr, &stb))
  2137. X        (void) fprintf(stderr, "%s: can't stat %s\n", progname, *mapptr);
  2138. X        else {
  2139. X        p = ctime(&stb.st_mtime);
  2140. X        q = strchr(p, '\n');
  2141. X        if (q)
  2142. X            *q = '\0';
  2143. X        (void) printf("%-14s %6ld %s\n", *mapptr, stb.st_size, p);
  2144. X        }
  2145. X    } else {
  2146. X        q = strrchr(*mapptr, '.');
  2147. X        if (q && strcmp(q, ".Z") == 0)
  2148. X        *q = '\0';
  2149. X        (void) printf("%s\n", *mapptr);
  2150. X    }
  2151. X    return(0);
  2152. X}
  2153. X
  2154. Xfatal(e, str)
  2155. Xint e;
  2156. Xchar *str; {
  2157. X    if (e) {
  2158. X    (void) fprintf(stderr, "%s: %s\n", progname, str);
  2159. X    exit(e);
  2160. X    }
  2161. X}
  2162. END_OF_FILE
  2163.   if test 3512 -ne `wc -c <'uuwhere.c'`; then
  2164.     echo shar: \"'uuwhere.c'\" unpacked with wrong size!
  2165.   fi
  2166.   # end of 'uuwhere.c'
  2167. fi
  2168. echo shar: End of archive 1 \(of 2\).
  2169. cp /dev/null ark1isdone
  2170. MISSING=""
  2171. for I in 1 2 ; do
  2172.     if test ! -f ark${I}isdone ; then
  2173.     MISSING="${MISSING} ${I}"
  2174.     fi
  2175. done
  2176. if test "${MISSING}" = "" ; then
  2177.     echo You have unpacked both archives.
  2178.     rm -f ark[1-9]isdone
  2179. else
  2180.     echo You still must unpack the following archives:
  2181.     echo "        " ${MISSING}
  2182. fi
  2183. exit 0
  2184.  
  2185. -- 
  2186. Chris Lewis; clewis@ferret.ocunix.on.ca; Phone: Canada 613 832-0541
  2187. Psroff 3.0 info: psroff-request@ferret.ocunix.on.ca
  2188. Ferret list: ferret-request@ferret.ocunix.on.ca
  2189.  
  2190. exit 0 # Just in case...
  2191.