home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / smail / part2 < prev    next >
Encoding:
Internet Message Format  |  1986-11-30  |  64.1 KB

  1. Subject:  v07i010:  Domain mailer and rmail replacement, Part02/02
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: Mark Horton <mark@cbosgd.ATT.COM>
  6. Mod.sources: Volume 7, Issue 10
  7. Archive-name: smail/Part02
  8.  
  9.  
  10. # To unpack the enclosed files, please use this file as input to the
  11. # Bourne (sh) shell.  This can be most easily done by the command;
  12. #     sh < thisfilename
  13.  
  14. # This archive contains;
  15. #  Makefile         binmail.c           defs.h              deliver.c           
  16. #  getopt.c         main.c              resolve.c           sendmail.att
  17. #  sendmail.leaf    smail.cf.fix        smail.cf.form       smail.cf.sh
  18. #  smail.prompt     sysexits.h          u.Path.local        u.Path.top.1
  19. #  u.Path.uucp.1
  20.  
  21.  
  22. # ---------- file Makefile ----------
  23.  
  24. filename="Makefile"
  25.  
  26. if [ -f $filename ]
  27. then
  28.   echo File \"$filename\" already exists\!  Skipping...
  29.   filename=/dev/null        # throw it away
  30. else
  31.   echo extracting file Makefile...
  32. fi
  33.  
  34. cat << 'END-OF-FILE' > $filename
  35. # Makefile for smail (not a installation makefile)
  36.  
  37. # @(#)Makefile    1.6   (UUCP-Project/CS)   6/27/86
  38.  
  39. # If you have compressed files in this dir, uncompress them
  40. # and point UUMAP at the directory with uncompressed files,
  41. # or fiddle with zcat.
  42. UUMAP=/usr/spool/news/maps/mod.map
  43.  
  44. PATHS    =    /usr/lib/uucp/paths
  45.  
  46. CFLAGS    =    -O -DPATHS=\"$(PATHS)\"
  47.  
  48. OBJECTS =    main.o resolve.o deliver.o getopt.o
  49.  
  50. all: smail binmail
  51.  
  52. smail:        ${OBJECTS}
  53.         cc ${CFLAGS} ${OBJECTS} -o smail
  54.  
  55. ${OBJECTS}:    defs.h
  56.  
  57. binmail:
  58.  
  59. install: all
  60.     @echo read INFO.INSTALL
  61.  
  62. paths:
  63.     pathalias u.Path.* $(UUMAP)/u.* | sort -f > path.out
  64.     cp path.out $(PATHS)
  65.  
  66. clean:
  67.     rm -f *.o a.out core
  68.  
  69. clobber: clean
  70.     rm -f smail rmail binmail
  71. END-OF-FILE
  72.  
  73. if [ "$filename" != "/dev/null" ]
  74. then
  75.   size=`wc -c < $filename`
  76.  
  77.   if [ $size != 691 ]
  78.   then
  79.     echo $filename changed - should be 691 bytes, not $size bytes
  80.   fi
  81.  
  82.   chmod 644 $filename
  83. fi
  84.  
  85. # ---------- file binmail.c ----------
  86.  
  87. filename="binmail.c"
  88.  
  89. if [ -f $filename ]
  90. then
  91.   echo File \"$filename\" already exists\!  Skipping...
  92.   filename=/dev/null        # throw it away
  93. else
  94.   echo extracting file binmail.c...
  95. fi
  96.  
  97. cat << 'END-OF-FILE' > $filename
  98. /* */
  99. /* This program will be used in place of /bin/mail on SVR2 sites.
  100. /* It looks at the arguments and decides whether to call
  101. /* SENDER for sending mail, or READER for reading mail.
  102. /*
  103. /* before installing as /bin/mail, move the stock /bin/mail to /bin/lmail
  104. /*
  105. /*  */
  106.  
  107. #include <stdio.h>
  108. #include "defs.h"
  109.  
  110. #ifdef SENDMAIL
  111. #define    SENDER    "/usr/lib/sendmail"
  112. #else
  113. #define    SENDER    "/bin/rmail"
  114. #endif
  115.  
  116. #define    READER    "/bin/lmail"
  117.  
  118. #define TRUE 1
  119. #define FALSE 0
  120.  
  121. char prog[128];
  122.  
  123. void    perror(), exit(), usage();
  124. char    *strcpy();
  125.  
  126. main(argc, argv)
  127. int argc;
  128. char *argv[];
  129. {
  130.     extern int optind;
  131.     extern char *optarg;
  132.  
  133.     int i, j, c;
  134.     int reading, sending;
  135.  
  136.     reading = sending = FALSE;
  137.  
  138.     (void) strcpy(prog, argv[0]);
  139.  
  140.     if(argc == 1) {
  141.         reading = TRUE;
  142.     } else {
  143.         while((c = getopt(argc, argv, "epqrtf:")) != EOF) {
  144.             switch(c) {
  145.             case 'e':
  146.             case 'p':
  147.             case 'q':
  148.             case 'r':
  149.             case 'f':
  150.                 reading = TRUE;
  151.                 break;
  152.             case 't':
  153.                 sending = TRUE;
  154.                 break;
  155.             default:
  156.                 usage();
  157.                 return(1);
  158.             }
  159.         }
  160.     }
  161.  
  162.     /* any arguments left over -> sending */
  163.     if(argc > optind) {
  164.         sending = TRUE;
  165.     }
  166.  
  167.     if((reading == TRUE) && (sending == TRUE)) {
  168.         usage();
  169.         return(1);
  170.     }
  171.  
  172.     if(sending == TRUE) {
  173.         argv[0] = SENDER;
  174.         for(i = 1, j = optind; i < argc; i++, j++) {
  175.             argv[i] = argv[j];
  176.         }
  177.         argv[i] = NULL;
  178.     } else {
  179.         argv[0] = READER;
  180.     }
  181.  
  182.     (void) execvp(argv[0], argv);
  183.     (void) fprintf(stderr, "%s: execvp(\"%s\", argv) failed: ",
  184.         prog, argv[0]);
  185.     perror("");
  186.     return(1);
  187. }
  188.  
  189. void
  190. usage()
  191. {
  192.     (void) fprintf(stderr, "usage:\t%s [ -epqr ] [ -f file ]\n", prog);
  193.     (void) fprintf(stderr, "\t%s [ -t ] persons\n", prog);
  194. }
  195. END-OF-FILE
  196.  
  197. if [ "$filename" != "/dev/null" ]
  198. then
  199.   size=`wc -c < $filename`
  200.  
  201.   if [ $size != 1630 ]
  202.   then
  203.     echo $filename changed - should be 1630 bytes, not $size bytes
  204.   fi
  205.  
  206.   chmod 644 $filename
  207. fi
  208.  
  209. # ---------- file defs.h ----------
  210.  
  211. filename="defs.h"
  212.  
  213. if [ -f $filename ]
  214. then
  215.   echo File \"$filename\" already exists\!  Skipping...
  216.   filename=/dev/null        # throw it away
  217. else
  218.   echo extracting file defs.h...
  219. fi
  220.  
  221. cat << 'END-OF-FILE' > $filename
  222. /*
  223. **
  224. **  Defs.h:  header file for rmail/smail.
  225. **
  226. **  Configuration options for rmail/smail.  As distributed, these are
  227. **  your options:
  228. **     use gethostname() to determine hostname.
  229. **    full domain name is 'hostname.uucp'.
  230. **    path file is /usr/lib/uucp/paths.
  231. **    no log, no record, no dbm, use sendmail.
  232. ** 
  233. **  You can change these in the next few blocks.
  234. **
  235. */
  236.  
  237. /*
  238. **    @(#)defs.h    1.12   (UUCP-Project/CS)   6/29/86
  239. */
  240.  
  241. /*
  242. **  If you select SENDMAIL below, you needn't worry about hostdomain here,
  243. **  as rmail does no domain routing with a SNOOPY sendmail, and sendmail
  244. **  itself sets hostdomain for smail.
  245. **
  246. **  Determining hostname:
  247. **    To use gethostname(), define GETHOSTNAME.
  248. **    To use uname(), define UNAME.
  249. **    To use a literal string, define HOSTNAME "host"
  250. **
  251. **  Determining hostdomain:
  252. **    To use hostname.mydomain, define MYDOM "mydomain"
  253. **    To use a literal string, define HOSTDOMAIN "host.domain"
  254. **    Otherwise, it will be "hostname" (not advised).
  255. **
  256. **  THE TOP LEVEL OF YOUR DOMAIN NAME IS IMPLICIT IN THE PATHALIAS DATABASE
  257. */
  258.  
  259. # define BSD                /* if system is a Berkeley system */
  260. # define SENDMAIL 1            /* Turn off to use /bin/(l)mail only */
  261.  
  262. # ifdef BSD
  263. # define GETHOSTNAME            /* use gethostname() */
  264. # else
  265. # define UNAME                 /* use uname() */
  266. # endif
  267. /* # define HOSTNAME   "host"        /* literal name */
  268.  
  269. /*
  270.  * .UUCP here is just for testing, GET REGISTERED in COM, EDU, etc.
  271.  * See INFO.REGISTRY for details.
  272.  */
  273. # define MYDOM        ".UUCP"        /* literal domain suffix */
  274.  
  275. /* # define HOSTDOMAIN "host.dom"    /* replacement for HOSTNAME.MYDOM */
  276.  
  277. /*
  278. **  Locations of files:
  279. **    PATHS is where the pathalias output is.  This is mandatory.
  280. **    Define LOG if you want a log of mail.  This can be handy for
  281. **    debugging and traffic analysis.
  282. **    Define RECORD for a copy of all mail.  This uses much time and
  283. **    space and is only used for extreme debugging cases.
  284. */
  285.  
  286. #ifndef PATHS
  287. # define PATHS    "/usr/lib/uucp/paths"    /* where the path database is */
  288. #endif
  289.  
  290. /*# define LOG     "/usr/spool/uucp/mail.log"    /* log of uucp mail */
  291. /*# define RECORD    "/tmp/mail.log"        /* record of uucp mail */
  292.  
  293. /*
  294. **  Mailer options:
  295. **    RMAIL is the command to invoke rmail on machine sys.
  296. **    RARG is how to insulate metacharacters from RMAIL. 
  297. **    LMAIL is the command to invoke the local mail transfer agent.
  298. **    LARG is how to insulate metacharacters from LMAIL. 
  299. **    RLARG is LARG with host! on the front - to pass a uux addr to sendmail.
  300. **    SENDMAIL selects one of two sets of defines below for either
  301. **    using sendmail or /bin/lmail.
  302. */    
  303.  
  304.                 /* add -r for queueing */
  305. # define RMAIL(from,sys)    "/usr/bin/uux - -r %s!rmail",sys
  306. # define RARG(user)        " '(%s)'",user
  307. # define RFROM(frm,now,host)     "From %s  %.24s remote from %s\n",frm,now,host
  308.  
  309. #ifdef SENDMAIL
  310. # define HANDLE    JUSTUUCP    /* see HANDLE definition below */
  311. # define ROUTING JUSTDOMAIN    /* see ROUTING definition below */
  312. /* # define ROUTING REROUTE    /* reroute everything (sets -R flag) */
  313. # define LMAIL(frm,sys)     "/usr/lib/sendmail -em -f%s",frm
  314. # define LARG(user)        " '%s'",user
  315. # define RLARG(sys,frm) " '%s!%s'",sys,frm
  316. # define LFROM(frm,now,host)     ""
  317. #else
  318. # define HANDLE    ALL
  319. # define ROUTING JUSTDOMAIN    /* */
  320. /* # define ROUTING REROUTE    /* reroute everything (sets -R flag) */
  321. #ifdef BSD
  322. # define LMAIL(frm,sys)        "/bin/mail"    /* BSD local delivery agent */
  323. #else
  324. # define LMAIL(frm,sys)        "/bin/lmail"    /* SV  local delivery agent */
  325. #endif
  326. # define LARG(user)        " '%s'",user
  327. # define RLARG(sys,frm) " '%s!%s'",sys,frm
  328. # define LFROM(frm,now,host)    "From %s %.24s\n",frm,now
  329. #endif SENDMAIL
  330.  
  331. /*
  332. ** DON'T TOUCH THE REST
  333. */
  334.  
  335. # define SMLBUF        512    /* small buffer (handle one item) */
  336. # define BIGBUF        4096    /* handle lots of items */
  337.  
  338. # define MAXPATH    32    /* number of elements in ! path */
  339. # define MAXDOMS    16    /* number of subdomains in . domain */
  340. # define MAXARGS    32    /* number of arguments */
  341.  
  342. #ifndef NULL
  343. # define NULL    0
  344. #endif
  345.  
  346. # define DEBUG             if (debug==YES) (void) printf
  347. # define ADVISE         if (debug!=NO) (void) printf
  348. # define error(stat,msg,a)    { (void) fprintf(stderr, msg, a); exit(stat); }
  349. # define lower(c)         ( isupper(c) ? c-'A'+'a' : c )
  350.  
  351.  
  352. enum eform {    /* format of addresses */
  353.     ERROR,         /* bad or invalidated format */
  354.     LOCAL,         /* just a local name */
  355.     DOMAIN,     /* user@domain */
  356.     UUCP,        /* host!address */
  357.     ROUTE };    /* intermediate form - to be routed */
  358.  
  359. enum ehandle {     /* what addresses can we handle? (don't kick to LMAIL) */
  360.     ALL,        /* UUCP and DOMAIN addresses */
  361.     JUSTUUCP,    /* UUCP only; set by -l  */
  362.     NONE };        /* all mail is LOCAL; set by -L */
  363.  
  364. enum erouting {    /* when to route A!B!C!D */
  365.     JUSTDOMAIN,    /* route A if A is a domain */
  366.     ALWAYS,        /* route A always; set by -r */
  367.     REROUTE };    /* route C, B, or A (whichever works); set by -R */
  368.  
  369. enum edebug {    /* debug modes */
  370.     NO,        /* normal deliver */
  371.     VERBOSE,    /* talk alot */
  372.     YES };        /* talk and don't deliver */
  373.  
  374. # ifdef BSD
  375.  
  376. # include    <sysexits.h>
  377. # include    <strings.h>
  378.  
  379. # else
  380.  
  381. # include    "sysexits.h"
  382. # include    <string.h>
  383. # define    index    strchr
  384. # define    rindex    strrchr
  385.  
  386. # endif
  387. extern void exit(), perror();
  388. extern unsigned sleep();
  389. END-OF-FILE
  390.  
  391. if [ "$filename" != "/dev/null" ]
  392. then
  393.   size=`wc -c < $filename`
  394.  
  395.   if [ $size != 5060 ]
  396.   then
  397.     echo $filename changed - should be 5060 bytes, not $size bytes
  398.   fi
  399.  
  400.   chmod 444 $filename
  401. fi
  402.  
  403. # ---------- file deliver.c ----------
  404.  
  405. filename="deliver.c"
  406.  
  407. if [ -f $filename ]
  408. then
  409.   echo File \"$filename\" already exists\!  Skipping...
  410.   filename=/dev/null        # throw it away
  411. else
  412.   echo extracting file deliver.c...
  413. fi
  414.  
  415. cat << 'END-OF-FILE' > $filename
  416. /*
  417. **  Deliver.c
  418. **
  419. **  Routines to effect delivery of mail for rmail/smail. 
  420. **
  421. */
  422.  
  423. #ifndef lint
  424. static char     *sccsid="@(#)deliver.c    1.13   (UUCP-Project/CS)   7/6/86";
  425. #endif
  426.  
  427. # include    <sys/types.h>
  428. # include    <stdio.h>
  429. # include    <pwd.h>
  430. # include    "defs.h"
  431.  
  432. extern int exitstat;        /* set if a forked mailer fails */
  433. extern enum edebug debug;    /* how verbose we are         */ 
  434. extern char hostname[];        /* our uucp hostname         */
  435. extern enum ehandle handle;    /* what we handle        */
  436.  
  437.  
  438. /*
  439. **
  440. **  deliver():  hand the letter to the proper mail programs.
  441. **
  442. **  Copies stdin to a temp file, if more than one mailer 
  443. **  will be invoked.  Issues one command for each different 
  444. **  host of <hostv>, constructing the proper command for
  445. **  LOCAL or UUCP mail.  Note that LOCAL mail has blank
  446. **  host names.  The <userv> names for each host are arguments 
  447. **  to the command.  Reads the "From_" and ">From_" lines 
  448. **  of the letter to build a <from> argument.  Finally, 
  449. **  prepends a "From" line to the letter just before going 
  450. **  out, with a "remote from <hostname>" if it is a UUCP letter.
  451. **
  452. */
  453.  
  454. deliver( argc, hostv, userv, formv )
  455. int argc;                /* number of addresses        */
  456. char *hostv[];                /* host names            */
  457. char *userv[];                /* user names            */
  458. enum eform formv[];            /* form for each address    */
  459. {
  460.     FILE *file;            /* source (stdin or temp file)    */
  461.     FILE *out;            /* pipe to mailer        */
  462.     FILE *popen();            /* to fork a mailer         */
  463. #ifdef RECORD
  464.     FILE *record();            /* snoopy mailer        */
  465. #endif
  466.     char *tmpf = "/tmp/rmXXXXXX";    /* temp file name        */
  467.     char lcommand[SMLBUF];        /* local command issued     */
  468.     char rcommand[SMLBUF];        /* remote command issued    */
  469.     char *command;            /* actual command        */
  470.     char from[SMLBUF];        /* accumulated from argument     */
  471.     char line[SMLBUF];        /* one line of the letter     */
  472.     int plural = 0;            /* more than one mailer?     */
  473.     enum eform form;        /* holds form[i] for speed     */
  474.     long size;            /* number of bytes of message     */
  475.     time_t now, time();        /* the time             */
  476.     char *nows;            /* the time in a string        */
  477.     int i, j, stat;
  478.     char *c, *ctime();
  479.     int failcount = 0;
  480.  
  481.     (void) strcpy( from, "" );
  482.     (void) time( &now );        /* set the time */
  483.     nows = ctime( &now );
  484.  
  485. /*
  486. **  Decide if we should copy the letter to a temp file.  We do this if we
  487. **  are sending to more than one mailer or if we are making a record.  We
  488. **  check to see if there is more than one different host in hostv.
  489. */
  490.  
  491. # ifdef RECORD
  492.     plural++;
  493. # else
  494.     for( i = 1; i < argc; i++ )
  495.         if( strcmp( hostv[0], hostv[i] ) && ++plural )
  496.             break;        /* shouldn't be case sensitive */
  497. # endif
  498.  
  499. /*
  500. **  If plural (more than one copy), copy stdin to a file.  Otherwise, just
  501. **  set file pointer to stdin.  This way, we avoid an extra copy of the
  502. **  file for the 99% of the cases with only one destination.  We also assume
  503. **  that if we must return a failure to the sender, that stdin is a file
  504. **  we can rewind and seek on, which is true of uuxqt.
  505. */
  506.     if( plural ) 
  507.     {
  508.         char *mktemp();
  509.  
  510.         ( void ) mktemp( tmpf );
  511.         if( ( file = fopen( tmpf, "w+" ) ) == NULL )
  512.             error( EX_CANTCREAT, "can't create %s.\n", tmpf );
  513.         while( fgets( line, SMLBUF, stdin ) != NULL )
  514.             (void) fputs( line, file );
  515.     } else {
  516.         file = stdin;
  517.     } 
  518. /*
  519. **  We pass through the list of addresses.
  520. */
  521.     for( i = 0; i < argc; i++ )
  522.     {
  523. /*
  524. **  If form == ERROR, either the address was bad or it has been sent on a
  525. **  previous pass.  So we break out.
  526. */
  527.         form = formv[i];
  528.         if ( form == ERROR )
  529.             continue;
  530. /*
  531. **  Rewind the input file for multiple copies (won't be stdin).  Call
  532. **  rline() to read the first few lines to collapse a From argument
  533. **  from the From_ and >From_ lines.  Rline() leaves the first unused
  534. **  line in line.
  535. */
  536.         if ( plural )
  537.             rewind( file );
  538.         rline( file, line, from );
  539. /*
  540. **  Build the command name based on whether this is local mail or
  541. **  uucp mail.  Someday, this will use a form->mailer table.
  542. */
  543.         (void) sprintf( lcommand, LMAIL( from, hostv[i] ) );
  544.         (void) sprintf( rcommand, RMAIL( from, hostv[i] ) );
  545. /*
  546. **  For each address with the same host name and form, append the user
  547. **  name to the command line, and set form = ERROR so we skip this address
  548. **  on later passes. 
  549. */
  550.         for ( j = argc - 1; j >= i; j-- ) {
  551.             if ( formv[j] != form || strcmp( hostv[i], hostv[j] ) )
  552.                 continue;
  553.             c = lcommand + strlen( lcommand );
  554.             if (form == LOCAL)
  555.                 (void) sprintf( c, LARG( userv[j] ) );
  556.             else
  557.                 (void) sprintf( c, RLARG(hostv[i], userv[j]) );
  558.             c = rcommand + strlen( rcommand );
  559.             (void) sprintf( c, RARG( userv[j] ) );
  560.             formv[j] = ERROR;
  561.         }
  562. retry:
  563.         if (form == LOCAL)
  564.             command = lcommand;
  565.         else
  566.             command = rcommand;
  567.         ADVISE( "COMMAND: %s\n", command );
  568. /*
  569. ** Fork the mailer and set it up for writing so we can send the mail to it,
  570. ** or for debugging divert the output to stdout.
  571. */
  572.         if ( debug == YES )
  573.             out = stdout;
  574.         else {
  575.             failcount = 0;
  576.             do {
  577.                 out = popen( command, "w" );
  578.                 if (out) break;
  579.                 /*
  580.                  * Fork failed.  System probably overloaded.
  581.                  * Wait awhile and try again 10 times.
  582.                  * If it keeps failing, probably some
  583.                  * other problem, like no uux or sendmail.
  584.                  */
  585.                 (void) sleep(60);
  586.             } while (++failcount < 10);
  587.         }
  588.         if( out == NULL )
  589.         {
  590.             exitstat = EX_UNAVAILABLE;
  591.             (void) printf( "couldn't execute %s.\n", command );
  592.             continue;
  593.         }
  594. /*
  595. **  Output our From_ line.
  596. */
  597.     if ( form == LOCAL ) {
  598. #ifdef SENDMAIL
  599.         (void) fprintf( out, LFROM( from, nows, hostname ) );
  600. #else
  601.         char *p;
  602.         if((p=index(from, '!')) == NULL) {
  603.             (void) fprintf( out, LFROM( from, nows, hostname ) );
  604.         } else {
  605.             *p = NULL;
  606.             (void) fprintf(out, RFROM( p+1, nows, from));
  607.             *p = '!';
  608.         }
  609. #endif
  610.     } else {
  611.         (void) fprintf( out, RFROM( from, nows, hostname ) );
  612.     }
  613. /*
  614. **  Copy input.  Remember that line from rline().
  615. */
  616.         size = 0;
  617.         do {
  618.             (void) fputs( line, out );
  619.             size += strlen( line );
  620.         } while( fgets( line, SMLBUF, file ) != NULL );
  621.  
  622. /*
  623. **  Get exit status and if non-zero, set global exitstat so when we exit
  624. **  we can indicate an error.
  625. */
  626.         if ( debug != YES ) {
  627.             if ( stat = pclose( out ) )
  628.                 exitstat = stat >> 8;
  629.             /*
  630.              * handle==ALL means we're smail, else we're rmail.
  631.              * The check here prevents a smail<=>sendmail loop.
  632.              * The form check prevents an internal smail loop.
  633.              */
  634.             if (handle != ALL && form != LOCAL && exitstat != 0) {
  635.                 /*
  636.                  * RMAIL failed, probably because the host
  637.                  * being uux'ed isn't in L.sys.  Try again
  638.                  * using sendmail.  If there is no sendmail,
  639.                  * we should include code ala the old rmail
  640.                  * which mails it back to the sender.
  641.                  */
  642.                 rewind(file);    /* assume uuxqt file */
  643.                 rline( file, line, from );
  644.                 form = LOCAL;
  645.                 exitstat = 0;    /* don't bother uuxqt */
  646.                 ADVISE("uux failed %d, trying sendmail\n", exitstat);
  647.                 goto retry;
  648.             }
  649.         }
  650.     }
  651. /*
  652. **  Update logs and records.  Blech.
  653. */
  654.  
  655. # ifdef LOG
  656.     log( command, from, size ); /* */
  657. # endif
  658. # ifdef RECORD
  659.     rewind( file );
  660.     out = record( command, from, size );
  661.     if(out != NULL) {
  662.         while( fgets( line, SMLBUF, file ) != NULL ) {
  663.             (void) fputs( line, out );
  664.         }
  665.         (void) fclose( out );
  666.     }
  667. # endif
  668.  
  669. /*
  670. **  Close and unlink temp file if we made one.
  671. */
  672.     if ( plural )
  673.     {
  674.         (void) fclose( file );
  675.         (void) unlink( tmpf );
  676.     }
  677. }
  678.  
  679.  
  680. /*
  681. **
  682. **  rline(): collapse From_ and >From_ lines.
  683. **
  684. **  Same idea as the old rmail, but also turns user@domain to domain!user. 
  685. **  Leaves the first line of the letter in "line".
  686. **
  687. */
  688.  
  689. rline( file, line, from )
  690. FILE *file;                /* source file            */
  691. char *line;                /* return first unused line    */
  692. char *from;                /* return accumulated from arg     */
  693. {
  694.     int parts;            /* for cracking From_ lines ... */
  695.     char *partv[16];        /* ... apart using ssplit()     */
  696.     char user[SMLBUF];        /* for rewriting user@host    */
  697.     char domain[SMLBUF];        /* "   "         "              */
  698.     char addr[SMLBUF];        /* "   "         "              */
  699.     enum eform form, parse();    /* "   "         "              */
  700.     extern build();            /* "   "         "              */
  701.     struct passwd *pwent, *getpwuid();        /* to get default user        */
  702.     char *c;
  703.  
  704.     (void) strcpy( from, "" );
  705.     (void) strcpy( addr, "" );
  706.     (void) strcpy( line, "" );
  707. /*
  708. **  Read each line until we hit EOF or a line not beginning with "From "
  709. **  or ">From " (called From_ lines), accumulating the new path in from
  710. **  and stuffing the actual sending user (the user name on the last From_ 
  711. **  line) in addr.
  712. */
  713.     for( ;; )
  714.     {
  715.         if ( fgets( line, SMLBUF, file )==NULL )
  716.             break;
  717.         if ( strncmp( "From ", line, 5 ) 
  718.             && strncmp( ">From ", line, 6 ) )
  719.             break;
  720. /*
  721. **  Crack the line apart using ssplit.
  722. */
  723.         if( c = index( line, '\n' ) );
  724.             *c = '\0';
  725.         parts = ssplit( line, ' ', partv );
  726. /*
  727. **  Tack host! onto the from argument if "remote from host" is present.
  728. */
  729.  
  730.         if ( parts > 3 
  731.             && !strncmp( "remote from ", partv[parts-3], 12 ) )
  732.         {
  733.             (void) strcat( from, partv[parts-1] );
  734.             (void) strcat( from, "!" );
  735.         } 
  736. /*
  737. **  Stuff user name into addr, overwriting the user name from previous 
  738. **  From_ lines, since only the last one counts.  Then rewrite user@host 
  739. **  into host!user, since @'s don't belong in the From_ argument.
  740. */
  741.         (void) strncpy( addr, partv[1], partv[2]-partv[1]-1 ); 
  742.         addr[partv[2]-partv[1]-1] = '\0';    /* ugh */
  743.  
  744.         (void) parse( addr, domain, user );
  745.         if(*domain == '\0') {
  746.             form = LOCAL;
  747.         } else {
  748.             form = UUCP;
  749.         }
  750.  
  751.         build( domain, user, form, addr );
  752.     }
  753. /*
  754. **  Now tack the user name onto the from argument.
  755. */
  756.     (void) strcat( from, addr );
  757. /*
  758. **  If we still have no from argument, we have junk headers, but we try
  759. **  to get the user's name using /etc/passwd.
  760. */
  761.     if ( !*from )
  762.         if ( ( pwent = getpwuid( getuid() ) ) == NULL )
  763.             (void) strcpy( from, "nowhere" );    /* bad news */
  764.         else
  765.             (void) strcpy( from, pwent->pw_name );
  766. }
  767.  
  768.  
  769. # ifdef LOG
  770. log(command, from, size)
  771. char *command, *from;
  772. long size;
  773. {
  774.     FILE *fd;
  775.     char *logtime, *ctime();
  776.     time_t t;
  777.     int cmask;
  778.  
  779.     ( void ) time( &t );
  780.     logtime = ctime( &t );
  781.     logtime[16] = 0;
  782.     logtime += 4;
  783.  
  784.     cmask = umask(0);
  785.     fd = fopen( LOG, "a" );
  786.     (void) umask(cmask);
  787.  
  788.     if ( fd != NULL ) {
  789.         (void) fprintf( fd, "%s: %s, from %s, %ld bytes\n", 
  790.             logtime, command, from, size);
  791.         (void) fclose( fd );
  792.     }
  793. }
  794. # endif
  795.  
  796. # ifdef RECORD
  797. FILE *
  798. record( command, from, size)
  799. char *command, *from;
  800. long size;
  801. {
  802.     FILE *fd;
  803.     char *logtime, *ctime();
  804.     long t;
  805.     int cmask;
  806.  
  807.     ( void ) time( &t );
  808.     logtime = ctime( &t );
  809.     logtime[16] = 0;
  810.     logtime += 4;
  811.  
  812.     cmask = umask(0);
  813.     fd = fopen( RECORD, "a" );
  814.     (void) umask(cmask);
  815.  
  816.     if ( fd != NULL ) {
  817.         (void) fprintf( fd, "%s: %s, from %s, %ld bytes\n", 
  818.             logtime, command, from, size);
  819.     }
  820.     return(fd);
  821. }
  822. # endif
  823. END-OF-FILE
  824.  
  825. if [ "$filename" != "/dev/null" ]
  826. then
  827.   size=`wc -c < $filename`
  828.  
  829.   if [ $size != 10558 ]
  830.   then
  831.     echo $filename changed - should be 10558 bytes, not $size bytes
  832.   fi
  833.  
  834.   chmod 644 $filename
  835. fi
  836.  
  837. # ---------- file getopt.c ----------
  838.  
  839. filename="getopt.c"
  840.  
  841. if [ -f $filename ]
  842. then
  843.   echo File \"$filename\" already exists\!  Skipping...
  844.   filename=/dev/null        # throw it away
  845. else
  846.   echo extracting file getopt.c...
  847. fi
  848.  
  849. cat << 'END-OF-FILE' > $filename
  850. /*
  851.  * Here's something you've all been waiting for:  the AT&T public domain
  852.  * source for getopt(3).  It is the code which was given out at the 1985
  853.  * UNIFORUM conference in Dallas.  I obtained it by electronic mail
  854.  * directly from AT&T.  The people there assure me that it is indeed
  855.  * in the public domain.
  856.  * 
  857.  * There is no manual page.  That is because the one they gave out at
  858.  * UNIFORUM was slightly different from the current System V Release 2
  859.  * manual page.  The difference apparently involved a note about the
  860.  * famous rules 5 and 6, recommending using white space between an option
  861.  * and its first argument, and not grouping options that have arguments.
  862.  * Getopt itself is currently lenient about both of these things White
  863.  * space is allowed, but not mandatory, and the last option in a group can
  864.  * have an argument.  That particular version of the man page evidently
  865.  * has no official existence, and my source at AT&T did not send a copy.
  866.  * The current SVR2 man page reflects the actual behavor of this getopt.
  867.  * However, I am not about to post a copy of anything licensed by AT&T.
  868.  */
  869.  
  870. /* This include is needed only to get "index" defined as "strchr" on Sys V. */
  871. #include "defs.h"
  872.  
  873. /*LINTLIBRARY*/
  874. #define NULL    0
  875. #define EOF    (-1)
  876. #define ERR(s, c)    if(opterr){\
  877.     extern int strlen(), write();\
  878.     char errbuf[2];\
  879.     errbuf[0] = c; errbuf[1] = '\n';\
  880.     (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  881.     (void) write(2, s, (unsigned)strlen(s));\
  882.     (void) write(2, errbuf, 2);}
  883.  
  884. extern int strcmp();
  885. extern char *index();
  886.  
  887. int    opterr = 1;
  888. int    optind = 1;
  889. int    optopt;
  890. char    *optarg;
  891.  
  892. int
  893. getopt(argc, argv, opts)
  894. int    argc;
  895. char    **argv, *opts;
  896. {
  897.     static int sp = 1;
  898.     register int c;
  899.     register char *cp;
  900.  
  901.     if(sp == 1)
  902.         if(optind >= argc ||
  903.            argv[optind][0] != '-' || argv[optind][1] == '\0')
  904.             return(EOF);
  905.         else if(strcmp(argv[optind], "--") == NULL) {
  906.             optind++;
  907.             return(EOF);
  908.         }
  909.     optopt = c = argv[optind][sp];
  910.     if(c == ':' || (cp=index(opts, c)) == NULL) {
  911.         ERR(": illegal option -- ", c);
  912.         if(argv[optind][++sp] == '\0') {
  913.             optind++;
  914.             sp = 1;
  915.         }
  916.         return('?');
  917.     }
  918.     if(*++cp == ':') {
  919.         if(argv[optind][sp+1] != '\0')
  920.             optarg = &argv[optind++][sp+1];
  921.         else if(++optind >= argc) {
  922.             ERR(": option requires an argument -- ", c);
  923.             sp = 1;
  924.             return('?');
  925.         } else
  926.             optarg = argv[optind++];
  927.         sp = 1;
  928.     } else {
  929.         if(argv[optind][++sp] == '\0') {
  930.             sp = 1;
  931.             optind++;
  932.         }
  933.         optarg = NULL;
  934.     }
  935.     return(c);
  936. }
  937. END-OF-FILE
  938.  
  939. if [ "$filename" != "/dev/null" ]
  940. then
  941.   size=`wc -c < $filename`
  942.  
  943.   if [ $size != 2456 ]
  944.   then
  945.     echo $filename changed - should be 2456 bytes, not $size bytes
  946.   fi
  947.  
  948.   chmod 644 $filename
  949. fi
  950.  
  951. # ---------- file main.c ----------
  952.  
  953. filename="main.c"
  954.  
  955. if [ -f $filename ]
  956. then
  957.   echo File \"$filename\" already exists\!  Skipping...
  958.   filename=/dev/null        # throw it away
  959. else
  960.   echo extracting file main.c...
  961. fi
  962.  
  963. cat << 'END-OF-FILE' > $filename
  964. /*
  965. **
  966. **  Rmail/Smail - UUCP mailer with automatic routing.
  967. **
  968. **  Christopher Seiwald        /+\
  969. **  cbosgd!chris        +\
  970. **  January, 1985        \+/
  971. **
  972. */
  973.  
  974. #ifndef lint
  975. static char     *sccsid="@(#)main.c    1.5  (UUCP-Project/CS)  6/9/86";
  976. #endif
  977.  
  978. /*
  979. **
  980. **  usage:      rmail [options] address...
  981. **        smail [options] address...
  982. **  options:
  983. **        -d     debug - verbose and don't invoke mailers.
  984. **        -v    verbose - just verbose.
  985. **        -h hostname    set hostname (default GETHOSTNAME,
  986. **                UNAME, or HOSTNAME)
  987. **        -H hostdomain    set hostdomain (default hostname.MYDOM)
  988. **        -p pathfile    path database filename
  989. **        (without both -r and -R, only user@domain gets routed)
  990. **        -r    force routing of host!address
  991. **        -R    reroute even explicit path!user
  992. **        (without both -l and -L, only local mail goes local)
  993. **        -l    user@domain goes to local mailer
  994. **        -L    all mail goes local
  995. **
  996. **  -r, -R, -l, and -L can be preset in defs.h  Smail clears -l and -L.
  997. **
  998. */
  999.  
  1000. #include    <stdio.h>
  1001. #include    <ctype.h>
  1002. #include    "defs.h"
  1003.  
  1004. #ifdef UNAME
  1005. #include    <sys/utsname.h>
  1006. #endif
  1007.  
  1008.  
  1009. int exitstat = 0;        /* exit status, set by resolve, deliver    */
  1010. enum edebug debug = NO;        /* set by -d or -v option        */
  1011. enum ehandle handle = HANDLE;    /* which mail we can handle, see defs.h    */
  1012. enum erouting routing = ROUTING;/* to route or not to route, see defs.h */
  1013. char hostname[SMLBUF] = "";    /* set by -h, defaults in defs.h     */
  1014. char hostdomain[SMLBUF] = "";    /* set by -H, defaults in defs.h     */
  1015. char *pathfile = PATHS;        /* or set by -p             */
  1016.  
  1017.  
  1018. /*
  1019. **
  1020. **  Rmail/Smail: mail stdin letter to argv addresses.
  1021. **
  1022. **  After processing command line options and finding our host and domain 
  1023. **  names, we map addresses into <host,user,form> triples.  Then we deliver.
  1024. **
  1025. */
  1026.  
  1027. main( argc, argv )
  1028. int argc;
  1029. char **argv;
  1030. {
  1031.     char *hostv[MAXARGS];        /* UUCP neighbor         */
  1032.     char *userv[MAXARGS];        /* address given to host     */
  1033.     enum eform formv[MAXARGS];    /* invalid, local, or uucp     */
  1034.     char *p;
  1035.     int c;
  1036.  
  1037.     char *optstr = "dvrRlLH:h:p:";
  1038.     extern char *optarg;
  1039.     extern int optind;
  1040.  
  1041. /*
  1042. **  see if we aren't invoked as rmail
  1043. */
  1044.     if((p = rindex(argv[0], '/')) == NULL) {
  1045.         p = argv[0];
  1046.     } else {
  1047.         p++;
  1048.     }
  1049.  
  1050.     if(*p != 'r' ) {
  1051.         handle = ALL;
  1052.     }
  1053.  
  1054. /*
  1055. **  Process command line arguments ( maybe getopt()? ).
  1056. */
  1057.     while ((c = getopt(argc, argv, optstr)) != EOF) {
  1058.         switch ( c ) {
  1059.         case 'd': debug = YES;             break;
  1060.         case 'v': debug = VERBOSE;         break; 
  1061.         case 'r': routing = ALWAYS;        break;
  1062.         case 'R': routing = REROUTE;        break;
  1063.         case 'l': handle = JUSTUUCP;        break;
  1064.         case 'L': handle = NONE;        break;
  1065.         case 'H': (void) strcpy( hostdomain, optarg );    break;
  1066.         case 'h': (void) strcpy( hostname, optarg );     break;
  1067.         case 'p': pathfile = optarg;         break;
  1068.         default:
  1069.             error( EX_USAGE, "valid flags are %s\n", optstr);
  1070.         }
  1071.     }
  1072.     if ( argc <= optind ) {
  1073.         error( EX_USAGE, "usage: %s [flags] address...\n", argv[0] );
  1074.     }
  1075.  
  1076. /*
  1077. **  Get our default hostname and hostdomain.
  1078. */
  1079.     getmynames();
  1080. /*
  1081. **  Map argv addresses to <host, user, form>.
  1082. */
  1083.     map( (argc - optind), &argv[optind], hostv, userv, formv );
  1084. /*
  1085. **  Deliver.
  1086. */
  1087.     deliver( (argc - optind), hostv, userv, formv );
  1088. /*
  1089. **  Exitstat was set if any resolve or deliver failed, otherwise 0.
  1090. */
  1091.     exit( exitstat );
  1092. }
  1093.  
  1094.  
  1095. /*
  1096. **
  1097. **  map(): map addresses into <host, user, form> triples.
  1098. **
  1099. **  Calls resolve() for each address of argv.  The result is hostv and 
  1100. **  userv arrays (pointing into buffers userz and hostz), and formv array.
  1101. **
  1102. */
  1103.  
  1104. map( argc, argv, hostv, userv, formv )
  1105. int argc;                /* address count         */
  1106. char **argv;                /* address vector         */
  1107. char *hostv[];                /* remote host vector         */
  1108. char *userv[];                /* user name vector         */
  1109. enum eform formv[];            /* address format vector     */
  1110. {
  1111.     int i;
  1112.     enum eform resolve();
  1113.     char *c, *malloc();
  1114.     char *userz = malloc( BIGBUF );
  1115.     char *hostz = malloc( BIGBUF );
  1116.  
  1117.     for( i=0; i<argc; i++ )
  1118.     {
  1119.         userv[i] = userz;        /* put results here */
  1120.         hostv[i] = hostz;
  1121.         if ( **argv == '(' )        /* strip () */
  1122.         {
  1123.             ++*argv;
  1124.             c = index( *argv, ')' );
  1125.             if (c)
  1126.                 *c = '\0';
  1127.         }
  1128.                         /* here it comes! */
  1129.         formv[i] = resolve( *argv++, hostz, userz );
  1130.         userz += strlen( userz ) + 1;    /* skip past \0 */
  1131.         hostz += strlen( hostz ) + 1;
  1132.     }
  1133. }
  1134.  
  1135.  
  1136. /*
  1137. **
  1138. **  getmynames(): what is my host name and host domain?
  1139. **
  1140. **  Hostname set by -h, failing that by #define HOSTNAME, failing
  1141. **  that by gethostname() or uname().
  1142. **  
  1143. **  Hostdomain set by -h, failing that by #define HOSTDOMAIN,
  1144. **  failing that as hostname.MYDOM, or as just hostname.
  1145. **
  1146. **  See defs.h for the inside story.
  1147. **
  1148. */
  1149.  
  1150. getmynames()
  1151. {
  1152. #ifdef HOSTNAME
  1153.     if ( !*hostname )
  1154.         (void) strcpy( hostname, HOSTNAME );
  1155. #endif
  1156. #ifdef GETHOSTNAME
  1157.     if ( !*hostname )
  1158.         gethostname( hostname, sizeof( hostname ) - 1 );
  1159. #endif
  1160. #ifdef UNAME
  1161.     if ( !*hostname ) {
  1162.         struct utsname site;
  1163.  
  1164.         if ( uname( &site ) < 0 )
  1165.             error( EX_SOFTWARE, "uname() call failed", 0 );
  1166.         (void) strcpy( hostname, site.nodename );
  1167.     }
  1168. #endif
  1169.     if ( !*hostname )
  1170.         error( EX_SOFTWARE, "can't determine hostname.\n", 0 );
  1171. #ifdef HOSTDOMAIN
  1172.     if ( !*hostdomain )
  1173.         (void) strcpy( hostdomain, HOSTDOMAIN );
  1174. #endif
  1175. #ifdef MYDOM
  1176.     if ( !*hostdomain )
  1177.         (void) strcat( strcpy( hostdomain, hostname ), MYDOM );
  1178. #endif
  1179.     if ( !*hostdomain )
  1180.         (void) strcpy( hostdomain, hostname );
  1181.  
  1182. }
  1183.  
  1184.  
  1185. /*
  1186. **  ssplit(): split a line into array pointers.
  1187. **
  1188. **  Each pointer wordv[i] points to the first character after the i'th 
  1189. **  occurence of c in buf.  Note that each wordv[i] includes wordv[i+1].
  1190. **
  1191. */
  1192.  
  1193. ssplit( buf, c, ptr )
  1194. register char *buf;        /* line to split up         */
  1195. char c;                /* character to split on    */
  1196. char **ptr;            /* the resultant vector        */
  1197. {
  1198.         int count = 0;
  1199.         int wasword = 0;
  1200.  
  1201.         for( ; *buf; buf++ )
  1202.         {
  1203.         if ( !wasword )
  1204.             count++, *ptr++ = buf;
  1205.         wasword = ( c != *buf );
  1206.         }
  1207.     if ( !wasword )
  1208.         count++, *ptr++ = buf;
  1209.         *ptr = NULL;
  1210.         return( count );
  1211. }
  1212. END-OF-FILE
  1213.  
  1214. if [ "$filename" != "/dev/null" ]
  1215. then
  1216.   size=`wc -c < $filename`
  1217.  
  1218.   if [ $size != 5792 ]
  1219.   then
  1220.     echo $filename changed - should be 5792 bytes, not $size bytes
  1221.   fi
  1222.  
  1223.   chmod 644 $filename
  1224. fi
  1225.  
  1226. # ---------- file resolve.c ----------
  1227.  
  1228. filename="resolve.c"
  1229.  
  1230. if [ -f $filename ]
  1231. then
  1232.   echo File \"$filename\" already exists\!  Skipping...
  1233.   filename=/dev/null        # throw it away
  1234. else
  1235.   echo extracting file resolve.c...
  1236. fi
  1237.  
  1238. cat << 'END-OF-FILE' > $filename
  1239. /*
  1240. **
  1241. **  Resolve.c
  1242. **
  1243. **  Routes then resolves addresses into UUCP or LOCAL.
  1244. **
  1245. */
  1246. #ifndef lint
  1247. static char     *sccsid="@(#)resolve.c    1.9   (UUCP-Project/CS)   6/27/86";
  1248. #endif
  1249.  
  1250. #include    <ctype.h>
  1251. #include    <stdio.h>
  1252. #include    "defs.h"
  1253.  
  1254. extern int exitstat;        /* set if address doesn't resolve     */
  1255. extern enum ehandle handle;    /* what mail we can handle        */
  1256. extern enum edebug debug;    /* verbose and debug modes        */
  1257. extern enum erouting routing;    /* when to route addresses        */
  1258. extern char hostdomain[];    /* for qualifying abbreviated addr's    */
  1259. extern char *pathfile;        /* location of path database        */
  1260.  
  1261.  
  1262. /*
  1263. **
  1264. **  rsvp(): how to resolve addresses.
  1265. **
  1266. **  After parsing an address into <form>, the resolved form will be
  1267. **  rsvp( form ).  If == ROUTE, we route the parsed address and parse again.
  1268. **
  1269. */
  1270.  
  1271. # define rsvp(a) table[(int)a][(int)handle]
  1272.  
  1273. enum eform table[5][3] = {
  1274. /*    all        uucponly    none */
  1275. {    ERROR,         ERROR,         ERROR },     /* error */
  1276. {    LOCAL,         LOCAL,         LOCAL },     /* local */
  1277. {    ROUTE,         LOCAL,         LOCAL },     /* domain */
  1278. {    UUCP,         UUCP,         LOCAL },     /* uucp */
  1279. {    ERROR,         ERROR,         ERROR }};    /* route */
  1280.  
  1281.  
  1282. /*
  1283. **  NOTE: in this module <domainv> replaces <hostv>. <domainv> contains 
  1284. **  the domain part of each address, though by the time it leaves here it 
  1285. **  can only be a host name.
  1286. */
  1287.  
  1288.  
  1289. /*
  1290. **
  1291. **  resolve(): resolve addresses to <host, user, form>.
  1292. **
  1293. **  This is a gnarly piece of code, but it does it all.  Each section 
  1294. **  is documented.
  1295. **
  1296. */
  1297.  
  1298. enum eform resolve( address, domain, user )
  1299. char *address;                /* the input address     */
  1300. char *domain;                /* the returned domain     */
  1301. char *user;                /* the returned user     */
  1302. {
  1303.     enum eform form;        /* the returned form    */ 
  1304.     enum eform parse();        /* to crack addresses    */
  1305.     int parts;            /* to ssplit addresses    */
  1306.     char *partv[MAXPATH];        /* "  "      "        */
  1307.     char temp[SMLBUF];        /* "  "      "        */
  1308.     int i;
  1309.         
  1310.  
  1311. /*
  1312. **  If we set REROUTE and are prepared to deliver UUCP mail, we split the 
  1313. **  address apart at !'s and try to resolve successively larger righthand 
  1314. **  substrings until we succeed.  Regularly, we just resolve the whole thing 
  1315. **  once.
  1316. */
  1317.     if ( routing == REROUTE && rsvp( UUCP ) == UUCP )
  1318.         parts = ssplit( address, '!', partv );
  1319.     else
  1320.         parts = 1, partv[0] = address;
  1321. /*
  1322. **  This for( i ) loop selects successively larger righthand substrings 
  1323. **  for BULLYing, see above. 
  1324. */
  1325.     for( i = parts - 1; i >= 0; i-- )
  1326.     {
  1327. /*
  1328. **  Parse the address.  If we are BULLYing and our substring parses to 
  1329. **  the LOCAL address, we skip to the next larger.
  1330. */
  1331.         (void) strcpy( temp, partv[i] );
  1332.         form = parse( temp, domain, user );
  1333.     DEBUG("parse address '%s' = %s @ %s (%d)\n",temp,user,domain,form);
  1334.         if ( i && form==LOCAL )
  1335.             continue;
  1336. /*
  1337. **  Routing is next step, so we break out if we don't have a UUCP form (if 
  1338. **  we are set to route ALWAYS or REROUTE) or a ROUTE form.
  1339. */
  1340.         if ( rsvp( form ) != ROUTE && 
  1341.             ( rsvp( form ) != UUCP || routing == JUSTDOMAIN ) )
  1342.             break;
  1343. /*
  1344. **  Apply router.  If BULLYing and routing failed, try next larger substring.
  1345. */
  1346.         if ( route( form, domain, user, temp ) )
  1347.             continue;
  1348. /*
  1349. **  After routing, reparse and resolve.
  1350. */
  1351.         form = parse( temp, domain, user );
  1352.     DEBUG("parse route '%s' = %s @ %s (%d)\n",temp,user,domain,form);
  1353.         break;
  1354.     }
  1355. /*
  1356. **  For LOCAL mail in non-local format, we rewrite the full address into 
  1357. **  <user> and leave <domain> blank.
  1358. */
  1359.     if ( rsvp( form ) == LOCAL && form != LOCAL )
  1360.     {
  1361.         build( domain, user, form, temp );
  1362.         (void) strcpy( user, temp );
  1363.         (void) strcpy( domain, "" );
  1364.         form = LOCAL;
  1365.     }
  1366. /*
  1367. **  If we were supposed to route and address but failed (form == ERROR), 
  1368. **  or after routing once we are left with an address that still needs to
  1369. **  be routed (rsvp( form ) == ROUTE), complain.  It is possible that we 
  1370. **  may want to resolve this address more than once (if the routing tables
  1371. **  return a domain-style address), but most likely this address partially 
  1372. **  resolved to this host.
  1373. */
  1374.     if ( form == ERROR || rsvp( form ) == ROUTE )
  1375.     {
  1376.         exitstat = EX_NOHOST;
  1377.         (void) printf( "%s...couldn't resolve %s.\n", address, domain );
  1378.         form = ERROR;
  1379.     }
  1380.     ADVISE("resolve '%s' = %s @ %s (%d)\n",address,user,domain,form);
  1381.     return ( form );
  1382. }
  1383.  
  1384.  
  1385. /*
  1386. **
  1387. ** parse(): parse <address> into <domain, user, form>.
  1388. **
  1389. **     input        form
  1390. **    -----        ----
  1391. **    user        LOCAL
  1392. **    domain!user    DOMAIN
  1393. **    user@domain    DOMAIN
  1394. **    @domain,address    LOCAL    (just for sendmail)
  1395. **    host!address    UUCP
  1396. **
  1397. */
  1398.  
  1399. enum eform parse( address, domain, user )
  1400. char *address;        /* input address     */
  1401. char *domain;        /* output domain     */
  1402. char *user;        /* output user         */
  1403. {
  1404.     int parts;
  1405.     char *partv[MAXPATH];                /* to crack address */
  1406.  
  1407. /*
  1408. **  If this is route address form @hosta,@hostb:user@hostd, break for
  1409. **  LOCAL since only sendmail would want to eat it.
  1410. */
  1411.     if ( *address == '@' )
  1412.         goto local;
  1413. /*
  1414. **  Try splitting at !. If it works, see if the piece before the ! has
  1415. **  a . in it (domain!user, form DOMAIN) or not (host!user, form UUCP).
  1416. */
  1417.     if ( ssplit( address, '!', partv ) > 1 )
  1418.     {
  1419.         (void) strcpy( user, partv[1] );
  1420.         (void) strncpy( domain, partv[0], partv[1]-partv[0]-1 );
  1421.         domain[partv[1]-partv[0]-1] = '\0';
  1422.         if( ( parts = ssplit( domain, '.', partv ) ) < 2 )
  1423.             return( UUCP );
  1424.         if( partv[parts-1][0] == '\0' )    
  1425.             partv[parts-1][-1] = '\0'; /* strip trailing . */
  1426.         return ( DOMAIN );
  1427.     }
  1428. /*
  1429. **  Try splitting at @.  If it work, this is user@domain, form DOMAIN.
  1430. **  Prefer the righthand @ in a@b@c.
  1431. */
  1432.     if ( ( parts = ssplit( address, '@', partv ) ) >= 2 )
  1433.     {
  1434.         (void) strcpy( domain, partv[parts-1] );
  1435.         (void) strncpy( user, partv[0], partv[parts-1]-partv[0]-1 );
  1436.         user[partv[parts-1]-partv[0]-1] = '\0';
  1437.         return ( DOMAIN );
  1438.     } 
  1439. /* 
  1440. **  Done trying.  This must be just a user name, form LOCAL.
  1441. */
  1442. local:
  1443.     (void) strcpy( user, address );
  1444.     (void) strcpy( domain, "" );
  1445.     return( LOCAL );                /* user */
  1446. }
  1447.  
  1448.  
  1449. /*
  1450. **
  1451. **  route(): route domain, plug in user.
  1452. **
  1453. **  Less complicated than it looks.  Each section is documented.
  1454. **
  1455. */
  1456.  
  1457. route( form, domain, user, result )
  1458. enum eform form;        /* domain is UUCP host? */
  1459. char *domain;            /* domain or host name     */
  1460. char *user;            /* user name         */
  1461. char *result;            /* output route     */
  1462. {
  1463.     int    domains, step;            /* to split domain    */
  1464.     char    *domainv[MAXDOMS];        /* "  "     "        */
  1465.     char    temp[SMLBUF], path[SMLBUF];
  1466.  
  1467. /*
  1468. **  Fully qualify the domain, and then strip the last (top level domain) 
  1469. **  component off, so that we look it up separately.
  1470. */
  1471.     (void) strcpy( temp, ".");
  1472.     (void) strcat( temp, domain );
  1473.  
  1474.     domains = ssplit( temp+1, '.', domainv );
  1475.     /* If the domain ends in .UUCP, trim that off. */
  1476.     if ( domains && isuucp(domainv[domains-1]))
  1477.         domainv[domains-1][-1] = '\0';
  1478. /*
  1479. **  Try to get the path for successive components of the domain.  
  1480. **  Example for osgd.cb.att.uucp:
  1481. **    osgd.cb.att
  1482. **    cb.att
  1483. **    att
  1484. **    uucp ( remember stripping top level? )
  1485. **  Returns with error if we find no path.
  1486. */
  1487.     step = 0;
  1488.     while ( step<domains && getpath( domainv[step]-1, path )  /* w/dot */
  1489.                  && getpath( domainv[step]  , path ) )/* no dot */
  1490.         step++;
  1491.     if ( step == domains )
  1492.     {
  1493.         DEBUG( "getpath '%s' failed\n", domain );
  1494.         return( EX_NOHOST );
  1495.     }
  1496.     DEBUG("getpath '%s' (%s) = %s\n",domain,domainv[step],path);
  1497.  
  1498. /*
  1499. **  If we matched on the entire domain name, this address is fully resolved, 
  1500. **  and we plug <user> into it.  If we matched on only part of the domain 
  1501. **  name, we plug <domain>!<user> in.  
  1502. */
  1503.     build( domain, user, step ? UUCP:LOCAL, temp+1 );
  1504.     (void) sprintf( result, path, temp+1 );
  1505.     return( EX_OK );
  1506. }
  1507.  
  1508. /*
  1509.  * Return 1 iff the string is "UUCP" (ignore case).
  1510.  */
  1511. isuucp(str)
  1512. char *str;
  1513. {
  1514.     if (lower(*str) != 'u') return 0;
  1515.     ++str;
  1516.     if (lower(*str) != 'u') return 0;
  1517.     ++str;
  1518.     if (lower(*str) != 'c') return 0;
  1519.     ++str;
  1520.     if (lower(*str) != 'p') return 0;
  1521.     ++str;
  1522.     if (*str != '\0') return 0;
  1523.     return 1;
  1524. }
  1525.  
  1526. /*
  1527. **
  1528. ** qualifydomain(): turn domain into full domain name.
  1529. **
  1530. ** Best explained by examples, if hostdomain = a.b.c.UUCP
  1531. **    host.domain.UUCP -> host.domain.UUCP
  1532. **    host.b -> host.b.c.UUCP
  1533. **    host.x -> host.x.UUCP
  1534. **
  1535. */
  1536.  
  1537. /* qualifydomain():
  1538.  * Taken out 3/21/86 by MRH - if hostdomain is, say. a.b.c.COM,
  1539.  * and domain is x.UUCP, it turns it into x.UUCP.COM and then
  1540.  * barfs on it.  I don't see a way to handle PQN's this easily.
  1541.  */
  1542.  
  1543. build( domain, user, form, result )
  1544. char *domain;
  1545. char *user;
  1546. enum eform form;
  1547. char *result;
  1548. {
  1549.     switch( form )
  1550.     {
  1551.     case LOCAL:
  1552.         (void) sprintf( result, "%s", user ); 
  1553.         break;
  1554.     case UUCP:
  1555.         (void) sprintf( result, "%s!%s", domain, user );
  1556.         break;
  1557.     case DOMAIN:
  1558.         (void) sprintf( result, "%s@%s", user, domain );
  1559.         break;
  1560.     }
  1561. }
  1562.  
  1563.  
  1564.  
  1565. /*
  1566. **
  1567. ** getpath(): look up key in ascii sorted path database.
  1568. **
  1569. ** Binary searches a la look(1).  Sort -f to fold cases.
  1570. **
  1571. */
  1572.  
  1573. getpath( key, path )
  1574. char *key;        /* what we are looking for */
  1575. char *path;        /* where the results go */
  1576. {
  1577.     long pos, middle, hi, lo;
  1578.     static long pathlength = 0;
  1579.     register char *s;
  1580.     int c;
  1581.     static FILE *file;
  1582.     int flag;
  1583.  
  1584.     if( !pathlength )    /* open file on first use */
  1585.     {
  1586.         if( ( file=fopen( pathfile, "r" ) ) == NULL )
  1587.         {
  1588.             (void) printf( "can't access %s.\n", pathfile );
  1589.             pathlength = -1;
  1590.         } else {
  1591.             (void) fseek( file, 0L, 2 );        /* find length */
  1592.             pathlength = ftell( file );
  1593.         }
  1594.     }
  1595.     if( pathlength == -1 )
  1596.         return( EX_OSFILE );
  1597.  
  1598.     lo = 0;
  1599.     hi = pathlength;
  1600.     (void) strcpy( path, key );
  1601.     (void) strcat( path, "\t" );
  1602. /*
  1603. ** "Binary search routines are never written right the first time around."
  1604. ** - Robert G. Sheldon.
  1605. */
  1606.     for( ;; ) 
  1607.     {
  1608.         pos = middle = ( hi+lo+1 )/2;
  1609.         (void) fseek( file, pos, 0 );    /* find midpoint */
  1610.         if ( pos )        /* to beginning of next line */
  1611.             while( ( c=getc( file ) ) != EOF && c != '\n' );
  1612.         for( flag = 0, s = path; !flag; s++ ) /* match??? */
  1613.         {
  1614.             if ( *s == '\0' )
  1615.                 goto solved;
  1616.             c = getc( file );
  1617.             flag = lower( c ) - lower( *s );
  1618.         } 
  1619.         if ( lo>=middle )        /* failure? */
  1620.             return( EX_NOHOST );
  1621.         if ( c != EOF && flag < 0 )    /* close window */
  1622.             lo = middle;
  1623.         else 
  1624.             hi = middle - 1;
  1625.     } 
  1626. /* 
  1627. ** Now just copy the result.
  1628. */
  1629. solved:
  1630.     while( ( c=getc( file ) ) != EOF && c != '\n' )
  1631.         *path++ = c;
  1632.     *path = '\0';
  1633.     return ( EX_OK );
  1634. }
  1635. END-OF-FILE
  1636.  
  1637. if [ "$filename" != "/dev/null" ]
  1638. then
  1639.   size=`wc -c < $filename`
  1640.  
  1641.   if [ $size != 10038 ]
  1642.   then
  1643.     echo $filename changed - should be 10038 bytes, not $size bytes
  1644.   fi
  1645.  
  1646.   chmod 644 $filename
  1647. fi
  1648.  
  1649. # ---------- file sendmail.att ----------
  1650.  
  1651. filename="sendmail.att"
  1652.  
  1653. if [ -f $filename ]
  1654. then
  1655.   echo File \"$filename\" already exists\!  Skipping...
  1656.   filename=/dev/null        # throw it away
  1657. else
  1658.   echo extracting file sendmail.att...
  1659. fi
  1660.  
  1661. cat << 'END-OF-FILE' > $filename
  1662. This is a diff between the distributed sendmail.cf file in this
  1663. directory and the actual sendmail.cf run on cbosgd.  The only
  1664. changes are filling in ATT.COM in place of orgname.COM, and
  1665. our local convention for CEM.  Other AT&T sites may wish to
  1666. support the CEM syntax by handing off to ihnp4 (as this does)
  1667. or otherwise.  This doesn't apply to non-AT&T sites, which should
  1668. only fill in orgname.
  1669.  
  1670. The sendmail.cf file here makes the host a gateway into and out of
  1671. the organization.  This is probably appropriate for the first machine
  1672. to bring up smail, but for less well-known machines you may prefer
  1673. the sendmail.leaf file or a simpler locally developed sendmail.cf.
  1674.  
  1675. *** sendmail.cf    Mon Jun  9 16:14:53 1986
  1676. --- /usr/lib/sendmail.cf    Mon Jun  9 16:16:50 1986
  1677. ***************
  1678. *** 29,37
  1679.   # Until you register you can use orgname.UUCP for testing.
  1680.   
  1681.   #Dwhost
  1682. ! DDorgname.COM
  1683. ! DAorgname.UUCP
  1684. ! CDUUCP orgname
  1685.   
  1686.   # Preemptive ether and UUCP connections.  We prefer these connections 
  1687.   # over both designated transport mechanisms and the general depository.
  1688.  
  1689. --- 29,37 -----
  1690.   # Until you register you can use orgname.UUCP for testing.
  1691.   
  1692.   #Dwhost
  1693. ! DDATT.COM
  1694. ! DAATT.UUCP
  1695. ! CDUUCP ATT
  1696.   
  1697.   # Preemptive ether and UUCP connections.  We prefer these connections 
  1698.   # over both designated transport mechanisms and the general depository.
  1699. ***************
  1700. *** 280,285
  1701.   #R$*<@$*>$*        $#uux$@$R$:$1@$2$3        hand to uucp relay
  1702.   #R$*<@$*>$*        $#ether$@$R$:$1@$2$3        hand to ether relay
  1703.   #R$*<$*>$*        $#error$:unkown address $1$2$3    don't hand anywhere
  1704.   
  1705.   # local delivery
  1706.   R$+            $#local$:$1            user
  1707.  
  1708. --- 280,288 -----
  1709.   #R$*<@$*>$*        $#uux$@$R$:$1@$2$3        hand to uucp relay
  1710.   #R$*<@$*>$*        $#ether$@$R$:$1@$2$3        hand to ether relay
  1711.   #R$*<$*>$*        $#error$:unkown address $1$2$3    don't hand anywhere
  1712. + # AT&T CEM f.m.last /CBOSGD
  1713. + R$-.$+            $#uux$@ihnp4$:$1.$2        AT&T CEM f.m.last
  1714.   
  1715.   # local delivery
  1716.   R$+            $#local$:$1            user
  1717. END-OF-FILE
  1718.  
  1719. if [ "$filename" != "/dev/null" ]
  1720. then
  1721.   size=`wc -c < $filename`
  1722.  
  1723.   if [ $size != 1919 ]
  1724.   then
  1725.     echo $filename changed - should be 1919 bytes, not $size bytes
  1726.   fi
  1727.  
  1728.   chmod 644 $filename
  1729. fi
  1730.  
  1731. # ---------- file sendmail.leaf ----------
  1732.  
  1733. filename="sendmail.leaf"
  1734.  
  1735. if [ -f $filename ]
  1736. then
  1737.   echo File \"$filename\" already exists\!  Skipping...
  1738.   filename=/dev/null        # throw it away
  1739. else
  1740.   echo extracting file sendmail.leaf...
  1741. fi
  1742.  
  1743. sed 's/^X//' << 'END-OF-FILE' > $filename
  1744. XDate: Thu, 29 May 86 14:28:47 edt
  1745. XFrom: avolio@decuac.DEC.COM (Frederick M. Avolio)
  1746. X
  1747. XThese changes are useful for a simple UUCP site with only one neighbor,
  1748. Xwhich does not run smail but does run sendmail.  It passes all mail to
  1749. Xthe neighbor, which must run smail.
  1750. X
  1751. X----------
  1752. X*** ORIGsendmail.cf    Sat Feb 15 23:27:33 1986
  1753. X--- sendmail.cf    Thu May 29 14:20:06 1986
  1754. X  ###############################
  1755. X  ###   Message precedences   ###
  1756. X***************
  1757. X*** 304,309
  1758. X  # if you just want general disposition.
  1759. X  
  1760. X  #R$+<@$-.UUX>        $#smail$@$:$2!$1        any uucp via smail
  1761. X  R$*<@$+.ETHER>$*    $#ether$@$2$:$1$3        etherhost
  1762. X  
  1763. X  # Send all foreign mail to general disposition now, and everything else
  1764. X
  1765. X--- 304,311 -----
  1766. X  # if you just want general disposition.
  1767. X  
  1768. X  #R$+<@$-.UUX>        $#smail$@$:$2!$1        any uucp via smail
  1769. X+ R$+<@$=U.UUX>    $#uux$@$2$:$1            any uucp via uux
  1770. X+ R$+<@$-.UUX>        $#uux$@$R$:$2!$1
  1771. X  R$*<@$+.ETHER>$*    $#ether$@$2$:$1$3        etherhost
  1772. X  
  1773. X  # Send all foreign mail to general disposition now, and everything else
  1774. X***************
  1775. X*** 322,327
  1776. X  
  1777. X  R$+            $#smail$@$:$1            hand to smail
  1778. X  #R$+            $#smail$@$:$R!$1        hand to uucp relay
  1779. X  #R$+            $#ether$@$R$:$1            hand to ether relay
  1780. X  #R$+            $#error$:unknown address $1    don't hand anywhere
  1781. X  
  1782. X
  1783. X--- 324,331 -----
  1784. X  
  1785. X  R$+            $#smail$@$:$1            hand to smail
  1786. X  #R$+            $#smail$@$:$R!$1        hand to uucp relay
  1787. X+ R$*@$*        $#uux$@$R$:$2!$1
  1788. X+ R$+            $#uux$@$R$:$1            hand to uucp relay
  1789. X  #R$+            $#ether$@$R$:$1            hand to ether relay
  1790. X  #R$+            $#error$:unknown address $1    don't hand anywhere
  1791. END-OF-FILE
  1792.  
  1793. if [ "$filename" != "/dev/null" ]
  1794. then
  1795.   size=`wc -c < $filename`
  1796.  
  1797.   if [ $size != 1509 ]
  1798.   then
  1799.     echo $filename changed - should be 1509 bytes, not $size bytes
  1800.   fi
  1801.  
  1802.   chmod 644 $filename
  1803. fi
  1804.  
  1805. # ---------- file smail.cf.fix ----------
  1806.  
  1807. filename="smail.cf.fix"
  1808.  
  1809. if [ -f $filename ]
  1810. then
  1811.   echo File \"$filename\" already exists\!  Skipping...
  1812.   filename=/dev/null        # throw it away
  1813. else
  1814.   echo extracting file smail.cf.fix...
  1815. fi
  1816.  
  1817. cat << 'END-OF-FILE' > $filename
  1818. Here is a note regarding the changes made at randvax to help handle
  1819. 822 domain issues.  I don't claim this is a 100% solution, but it should
  1820. be worth some study.  This is supposed to be a fix to the problem that
  1821. vanilla 4.2 and 4.3BSD sendmails add their name and a ! to a legal RFC822
  1822. address, turning it into an illegal 822 address.
  1823.  
  1824. -----
  1825. -----
  1826.  
  1827. [terry%owl]
  1828.  
  1829. Here's the change I made:
  1830.  
  1831. S13
  1832. R$+            $:$>5$1                convert to old style
  1833. R$+<@$=w>        $:$1                strip @localhost (trw)
  1834. R$+@$=w            $:$1                strip @localhost (trw)
  1835. R$+@$=w.arpa        $:$1                strip @localhost (trw)
  1836. # trw: don't append our hostname to addresses with @s,
  1837. #  or to uucp addresses we don't talk to--class X
  1838. #  contains a list of sites we talk to.
  1839. R$+@$+            $@$1@$2                stop evaluation
  1840. R$=U!$+            $2                strip local name
  1841. R$=X!$+            $@$U!$1!$2            stick on our host name
  1842. R$+!$+            $@$1!$2                don't prepend our host
  1843. R$+            $:$U!$1                stick on our host name
  1844. END-OF-FILE
  1845.  
  1846. if [ "$filename" != "/dev/null" ]
  1847. then
  1848.   size=`wc -c < $filename`
  1849.  
  1850.   if [ $size != 902 ]
  1851.   then
  1852.     echo $filename changed - should be 902 bytes, not $size bytes
  1853.   fi
  1854.  
  1855.   chmod 644 $filename
  1856. fi
  1857.  
  1858. # ---------- file smail.cf.form ----------
  1859.  
  1860. filename="smail.cf.form"
  1861.  
  1862. if [ -f $filename ]
  1863. then
  1864.   echo File \"$filename\" already exists\!  Skipping...
  1865.   filename=/dev/null        # throw it away
  1866. else
  1867.   echo extracting file smail.cf.form...
  1868. fi
  1869.  
  1870. cat << 'END-OF-FILE' > $filename
  1871. ############################################################
  1872. ############################################################
  1873. #####
  1874. #####        SENDMAIL CONFIGURATION FILE
  1875. #####
  1876. #####    UUCP project prototype: supports domain style 
  1877. #####   addressing over UUCP and ethernet links.
  1878. #####
  1879. #####   A product of the UUCP Project.
  1880. #####
  1881. #####        @(#)smail.cf.form    1.11   (UUCP-Project/CS)   7/13/86
  1882. #####
  1883. ############################################################
  1884. ############################################################
  1885.  
  1886.  
  1887. ############################################################
  1888. ###
  1889. ###  Local configuration options - HINTS
  1890. ###
  1891.  
  1892. # Host name and domain name macros.  Dw set $w, DD sets $D, and
  1893. # CD sets $=D.  Most sendmails set $w to `hostname`, so you can 
  1894. # probably leave out Dw.  $D and $=D lists all domains in which this 
  1895. # host sits, and $D goes into outbound addresses, i.e. "user@$w.$D".
  1896. # $A is another domain for which this host is authoratative, which
  1897. # will be turned into $D.
  1898.  
  1899. CF_HOST
  1900. CF_DOMAIN
  1901. CF_AUTHORITY
  1902. CF_DCLASS
  1903.  
  1904. # Preemptive ether and UUCP connections.  We prefer these connections 
  1905. # over both designated transport mechanisms and the general depository.
  1906. # You can add more classes (here and in S0).
  1907.  
  1908. # /etc/hosts.smtp might be a link to /etc/hosts
  1909. CF_SMTP
  1910. FU/dev/null %s
  1911.  
  1912. # Mock top-level domain names.  These name designate a transport mechanism
  1913. # and appear internally only, set in S3, used in S0, and removed in S4 and
  1914. # (possibly) the ruleset for the particular mailer.  
  1915.  
  1916. CTETHER UUX
  1917.  
  1918. # Relay host.  Used at the end of S0 as the general depository for 
  1919. # addresses which didn't resolve locally.  
  1920.  
  1921. DRrelay
  1922.  
  1923. ###
  1924. ###  End Local configuration options
  1925. ###
  1926. ############################################################
  1927.  
  1928. ############################################################
  1929. #
  1930. #    General configuration information
  1931. #
  1932. #    This information is basically just "boiler-plate"; it must be
  1933. #    there, but is essentially constant.
  1934. #
  1935. #    Information in this file should be independent of location --
  1936. #    i.e., although there are some policy decisions made, they are
  1937. #    not specific to Berkeley per se.
  1938. #
  1939. #        @(#)base.m4    4.3        8/30/83
  1940. #
  1941. ############################################################
  1942.  
  1943. DVUUCP-Project/rel-1.0/CF_DATE
  1944.  
  1945. ##########################
  1946. ###   Special macros   ###
  1947. ##########################
  1948.  
  1949. # official hostname
  1950. Dj$w.$D
  1951. # my name
  1952. DnMAILER-DAEMON
  1953. # UNIX header format
  1954. DlFrom $g  $d
  1955. # delimiter (operator) characters
  1956. Do.:%@!^=/[]
  1957. # format of a total name
  1958. Dq$g$?x ($x)$.
  1959. # SMTP login message
  1960. De$j Sendmail $v/$V ready at $b
  1961.  
  1962.  
  1963. ###################
  1964. ###   Options   ###
  1965. ###################
  1966.  
  1967. # location of alias file
  1968. OA/usr/lib/aliases
  1969. # default delivery mode (deliver in background)
  1970. Odbackground
  1971. # (don't) connect to "expensive" mailers
  1972. #Oc
  1973. # temporary file mode
  1974. OF0644
  1975. # default GID
  1976. Og1
  1977. # location of help file
  1978. OH/usr/lib/sendmail.hf
  1979. # log level
  1980. OL9
  1981. # default messages to old style
  1982. Oo
  1983. # queue directory
  1984. OQ/usr/spool/mqueue
  1985. # read timeout -- violates protocols
  1986. Or2h
  1987. # status file
  1988. OS/usr/lib/sendmail.st
  1989. # queue up everything before starting transmission
  1990. Os
  1991. # default timeout interval
  1992. OT3d
  1993. # time zone names (V6 only)
  1994. OtPST,PDT
  1995. # default UID
  1996. Ou1
  1997. # wizard's password
  1998. OWtZWoIRijHq0EQ
  1999.  
  2000. ###############################
  2001. ###   Message precedences   ###
  2002. ###############################
  2003.  
  2004. Pfirst-class=0
  2005. Pspecial-delivery=100
  2006. Pjunk=-100
  2007.  
  2008. #########################
  2009. ###   Trusted users   ###
  2010. #########################
  2011.  
  2012. Troot
  2013. Tdaemon
  2014. Tuucp
  2015. Tnetwork
  2016.  
  2017. #############################
  2018. ###   Format of headers   ###
  2019. #############################
  2020.  
  2021. #H?P?Return-Path: <$g>
  2022. HReceived: $?sfrom $s 
  2023.     $.by $j ($v/$V)
  2024.     id $i; $b
  2025. H?D?Resent-Date: $a
  2026. H?D?Date: $a
  2027. H?F?Resent-From: $q
  2028. H?F?From: $q
  2029. H?x?Full-Name: $x
  2030. HSubject:
  2031. # HPosted-Date: $a
  2032. # H?l?Received-Date: $b
  2033. H?M?Resent-Message-Id: <$t.$i@$j>
  2034. H?M?Message-Id: <$t.$i@$j>
  2035.  
  2036. ############################################################
  2037. ############################################################
  2038. #####
  2039. #####        REWRITING RULES
  2040. #####
  2041.  
  2042.  
  2043. ###########################
  2044. #  Name Canonicalization  #
  2045. ###########################
  2046. S3
  2047.  
  2048. # basic textual canonicalization
  2049. R<>            $@@                turn into magic token
  2050. R$*<$+>$*        $2                basic RFC821/822 parsing
  2051. R$+ at $+        $1@$2                "at" -> "@" for RFC 822
  2052. R$*<$*>$*        $1$2$3                in case recursive
  2053.  
  2054. # handle route-addr <@a,@b,@c:user@d> 
  2055. R@$+,$+            @$1:$2                change all "," to ":"
  2056. R@$+:$+            $@<@$1>:$2            handle <route-addr>
  2057. R$+:$*;@$+        $@$1:$2;@$3            list syntax
  2058.  
  2059. # Rewrite address into a domain-based address.  Any special mock domain names 
  2060. # (like UUX) should be defined on the CT line and removed (if necessary) 
  2061. # in S4.  You can use them in S0 for designated transport mechanisms.
  2062.  
  2063. # Delimiters with precendence over @.  Add yours here.
  2064.  
  2065. # The @ delimiter.  Leave this alone.
  2066. R$+@$+            $:$1<@$2>            focus on domain
  2067. R$+<$+@$+>        $1$2<@$3>            move gaze right
  2068. R$+<@$+>        $@$1<@$2>            already canonical
  2069.  
  2070. # Delimiters with precendece below @.  Add yours here.
  2071. R$+^$+            $1!$2                convert ^ to !
  2072. R$+!$-.$+!$+        $:$2.$3!$4            prefer domain /CBOSGD
  2073. R$-!$+            $@$2<@$1.UUX>            resolve uucp names
  2074. R$+.!$+            $@$2<@$1>            domain.!host
  2075. R$+!$+            $@$2<@$1>            domain!host
  2076.  
  2077. # % is a low precedence @.
  2078. R$*%$*            $@$>3$1@$2            %->@ and retry
  2079.  
  2080. ############################################################
  2081. ############################################################
  2082. #####
  2083. #####        RULESET ZERO PREAMBLE
  2084. #####
  2085. #####        UUCP Project 11/01/85
  2086. #####
  2087. ############################################################
  2088. ############################################################
  2089.  
  2090. S0
  2091.  
  2092. # first make canonical
  2093. R$*<$*>$*        $1$2$3                defocus
  2094. R$+            $:$>3$1                make canonical
  2095.  
  2096. # handle special cases.....
  2097. R@            $#local$:MAILER-DAEMON        handle <> form
  2098. R$*<@[$+]>$*        $#tcp$@[$2]$:$1@[$2]$3        numeric internet spec
  2099.  
  2100. # strip local stuff
  2101. R$*<$*$w.$D>$*        $1<$2>$3            thishost.mydom
  2102. CF_GATEWAYR$*<$*$D>$*        $1<$2>$3            mydom
  2103. R$*<$*$w.$=D>$*        $1<$2>$4            thishost.anydom
  2104. R$*<$*$w.$A>$*        $1<$2>$3            thishost.anotherdom
  2105. R$*<$*$A>$*        $1<$2>$3            anotherdom
  2106. R$*<$*$w.$=T>$*        $1<$2>$4            thishost.mockdom
  2107. CF_GATEWAYR$*<$*$w>$*        $1<$2>$3            thishost
  2108. R$*<$*.>$*        $1<$2>$3            drop trailing dot
  2109. R<@>:$+            $@$>0$1                strip null route, retry
  2110. R$+<@>            $@$>0$1                strip null addr, retry
  2111.  
  2112.  
  2113. ###############################################
  2114. ###  Machine dependent part of rulset zero  ###
  2115. ###############################################
  2116.  
  2117. # Preemption: for a host on a known link turn the domain spec into a
  2118. # mock domain indicating the link.  One set of these rules for each of 
  2119. # the F classes listed in the local configuration options.
  2120.  
  2121. R$*<$*$=U.$D>$*            $:$1<$2$3.UUX>$4    uuxhost.mydomain
  2122. R$*<$*$=U.$=D>$*        $:$1<$2$3.UUX>$5    uuxhost.anydomain
  2123. R$*<$*$=U.$A>$*            $:$1<$2$3.UUX>$4    uuxhost.anotherdomain
  2124. R$*<$*$=U.$=T>$*        $:$1<$2$3.UUX>$5    uuxhost.mock-domain
  2125. R$*<$*$=U>$*            $:$1<$2$3.UUX>$4    uuxhost
  2126.  
  2127. R$*<$*$=E.$D>$*            $:$1<$2$3.ETHER>$4    etherhost.mydomain
  2128. R$*<$*$=E.$=D>$*        $:$1<$2$3.ETHER>$5    etherhost.anydomain
  2129. R$*<$*$=E.$A>$*            $:$1<$2$3.ETHER>$4    etherhost.anotherdomain
  2130. R$*<$*$=E.$=T>$*        $:$1<$2$3.ETHER>$5    etherhost.mock-domain
  2131. R$*<$*$=E>$*            $:$1<$2$3.ETHER>$4    etherhost
  2132.  
  2133. # Designated delivery: use the indicated transport mechanism.  One of
  2134. # these rules for each of the mock domains defined in $=T.  You can
  2135. # remove these if you just want general disposition.  HINTS.
  2136.  
  2137. # Designated delivery:
  2138. R$*<@$=U.UUX>$*        $#uux$@$2$:$1$3            known uucphost
  2139. R$*<@$+.ETHER>$*    $#ether$@$2$:$1@$2$3        etherhost
  2140.  
  2141. # throw out mock domain name now
  2142. R$*<$*.$=T>$*        $1<$2>$4
  2143.  
  2144. # General disposition of remote mail (comment out all but one).  You
  2145. # might add to this list, if you have other "smarter" mailers.  HINTS.
  2146.  
  2147. R$*<@$*>$*        $#uux$@$2$:$1$3            hand to uucp
  2148. #R$*<@$*>$*        $#uux$@$R$:$1@$2$3        hand to uucp relay
  2149. #R$*<@$*>$*        $#ether$@$R$:$1@$2$3        hand to ether relay
  2150. #R$*<$*>$*        $#error$:unkown address $1$2$3    don't hand anywhere
  2151.  
  2152. # local delivery
  2153. R$+            $#local$:$1            user
  2154.  
  2155. ############################################################
  2156. ############################################################
  2157. #####
  2158. #####        Local and Program Mailer specification
  2159. #####
  2160. #####        @(#)localm.m4    4.1        7/25/83
  2161. #####
  2162. ############################################################
  2163. ############################################################
  2164.  
  2165. CF_SVMAILMlocal, P=CF_LOCALMAIL, F=lsDFMhumSU, S=10, R=20, A=rmail $u
  2166. CF_BSMAILMlocal, P=CF_LOCALMAIL, F=rlsDFMmn, S=10, R=20, A=mail -d $u
  2167. Mprog,    P=/bin/sh,   F=lsDFMe,   S=10, R=20, A=sh -c $u
  2168.  
  2169. S10
  2170. R@            MAILER-DAEMON            errors to mailer-daemon
  2171.  
  2172. ############################################################
  2173. ############################################################
  2174. #####
  2175. #####        UUCP Mailer specification
  2176. #####
  2177. #####        UUCP Project 11/01/85
  2178. #####
  2179. ############################################################
  2180. ############################################################
  2181.  
  2182.  
  2183. # Top two lines use uux, bottom two use smail.  For UUCP to handle domain 
  2184. # style addressing, you must use smail.  HINTS.
  2185.  
  2186. #Muux,    P=/usr/bin/uux, F=sDFMuU, S=13, R=23, M=65535,
  2187. #    A=uux - $h!rmail ($u)
  2188. Muux,    P=/bin/smail, F=sDFMhum, S=14, R=24, M=100000,
  2189.     A=smail -r -vH$j $h!$u
  2190.  
  2191. # S13 rewrites return addresses for uux as smail would: turn "user" into 
  2192. # "host!user" and "user@domain" to "host!domain!user".  Unfortunately,
  2193. # this also affects the From: line (which is wrong).
  2194.  
  2195. S13
  2196. R$+<@$w.UUX>        $@$1<@$w.UUX>            intercept 2nd pass
  2197. R$+            $:$>4$1                externalize
  2198. R$*@$*            $2!$1                a@b -> b!a
  2199. R$+            $@$1<@$w.UUX>            tack on our name
  2200.  
  2201. S14
  2202. R$+<@$=E>        $1            u@cbpavo->u/CBOSGD
  2203. R$*<@$+>$*        $@$1<@$2>$3        already ok
  2204. #R$+            $@$1<@$w>        tack on our hostname
  2205. R$+            $@$1<@$j>        tack on our full address
  2206.  
  2207. ############################################################
  2208. ############################################################
  2209. #####
  2210. #####        SMTP ethernet mailer
  2211. #####
  2212. #####        UUCP Project 11/01/85
  2213. #####
  2214. ############################################################
  2215. ############################################################
  2216.  
  2217. Mether,    P=[IPC], F=msDFMuCXP, S=11, R=21, A=IPC $h
  2218.  
  2219. S11
  2220. R$*<@$+>$*        $@$1<@$2>$3        already ok
  2221. R$+            $@$1<@$w>        tack on our hostname
  2222. #R$+            $@$1<@$j>        tack on our full address
  2223.  
  2224.  
  2225. #################################
  2226. #  Final Output Post-rewriting  #
  2227. #################################
  2228.  
  2229. # This rewrites the internal $=T mock domains into their external form.
  2230. # The default is to replace the mock domain name with $D.  The last
  2231. # two lines are stock.
  2232.  
  2233. S4
  2234. R@            $@                handle <> error addr
  2235. R$+<@$-.UUX>        $2!$1                u@host.UUX => host!u
  2236. R$*<$*$=T>$*        $:$1<$2$D>$4            change local info
  2237. R$*<$+>$*        $1$2$3                defocus
  2238. R@$+:$+:$+        $@@$1,$2:$3            <route-addr> canonical
  2239. END-OF-FILE
  2240.  
  2241. if [ "$filename" != "/dev/null" ]
  2242. then
  2243.   size=`wc -c < $filename`
  2244.  
  2245.   if [ $size != 10487 ]
  2246.   then
  2247.     echo $filename changed - should be 10487 bytes, not $size bytes
  2248.   fi
  2249.  
  2250.   chmod 644 $filename
  2251. fi
  2252.  
  2253. # ---------- file smail.cf.sh ----------
  2254.  
  2255. filename="smail.cf.sh"
  2256.  
  2257. if [ -f $filename ]
  2258. then
  2259.   echo File \"$filename\" already exists\!  Skipping...
  2260.   filename=/dev/null        # throw it away
  2261. else
  2262.   echo extracting file smail.cf.sh...
  2263. fi
  2264.  
  2265. cat << 'END-OF-FILE' > $filename
  2266. cat <<!EOM!
  2267. This script will prompt you for the automatically configurable parameters
  2268. in the stock version of the sendmail configuration file.  Naturally, any
  2269. local extensions will have to be added manually.
  2270.  
  2271. Below is a trace of the session that
  2272. configured the sendmail.cf on clyde.ATT.COM.
  2273. This is a System V machine with sendmail.
  2274. ===
  2275.  
  2276. !EOM!
  2277.  
  2278. echo "press return to continue"; read foo
  2279.  
  2280. cat <<!EOM!
  2281. Enter Date (MM-DD-YY):
  2282. 06-24-86
  2283. Enter This Host's Name:
  2284. clyde
  2285. Enter This Host's Official Domain:
  2286. ATT.COM
  2287. Enter Any Equivalent Domain Classes:
  2288. ATT
  2289. Enter Any Domains For Which This Host Is An Authority:
  2290. ATT.UUCP
  2291. Does This Host Have SMTP Connections (y/n)?
  2292. no
  2293. Enter Full Path to Executable That Will Provide Local Mail Delivery:
  2294. /bin/lmail
  2295. Is /bin/lmail A Berkeley Mailer [i.e., use -r to specify sender] (y/n)?
  2296. no
  2297. Will This Host Act As A Gateway Between Domains (y/n)?
  2298. yes
  2299. ===
  2300. !EOM!
  2301. # get date of configuration
  2302. CF_DATE=`/bin/sh ./smail.prompt string "Enter Date (MM-DD-YY):"`
  2303.  
  2304. # get host name
  2305. CF_HOST=`/bin/sh ./smail.prompt string "Enter This Host's Name:"`
  2306.  
  2307. # get host domain
  2308. CF_DOMAIN=`/bin/sh ./smail.prompt string "Enter This Host's Official Domain:"`
  2309.  
  2310. # get domain classes
  2311. CF_DCLASS=`/bin/sh ./smail.prompt string "Enter Any Equivalent Domain Classes:"`
  2312.  
  2313. # get domain authority
  2314. CF_AUTHORITY=`/bin/sh ./smail.prompt string "Enter Any Domains For Which This Host Is An Authority:"`
  2315.  
  2316. CF_SMTP=`/bin/sh ./smail.prompt yesno "Does This Host Have SMTP Connections (y/n)?"`
  2317. if test "$CF_SMTP" = "yes"
  2318. then
  2319.  
  2320. #get list of local SMTP connections
  2321.     CF_SMTP=`/bin/sh ./smail.prompt file "Enter Full Path to File that Contains List of SMTP Connections:"`
  2322.  
  2323.     CF_SMTP="FE$CF_SMTP %s"
  2324. else
  2325.     CF_SMTP=""
  2326. fi
  2327.  
  2328. # get path to local delivery agent
  2329. CF_LOCALMAIL=`/bin/sh ./smail.prompt file "Enter Full Path to Executable That Will Provide Local Mail Delivery:"`
  2330.  
  2331. CF_SYSTEM=`/bin/sh ./smail.prompt yesno "Is $CF_LOCALMAIL A Berkeley Mailer [i.e., use -r to specify sender] (y/n)?"`
  2332. if test "$CF_SYSTEM" = "yes"
  2333. then
  2334.     CF_SVMAIL="#"
  2335.     CF_BSMAIL=""
  2336. else
  2337.     CF_SVMAIL=""
  2338.     CF_BSMAIL="#"
  2339. fi
  2340.  
  2341. CF_GATEWAY=`/bin/sh ./smail.prompt yesno "Will This Host Act As A Gateway Between Domains(y/n)?"`
  2342. if test "$CF_GATEWAY" = "yes"
  2343. then
  2344.     CF_GATEWAY=""
  2345. else
  2346.     CF_GATEWAY="#"
  2347. fi
  2348.  
  2349. sed     \
  2350.     -e "s/CF_HOST/Dw$CF_HOST/" \
  2351.     -e "s/CF_DOMAIN/DD$CF_DOMAIN/" \
  2352.     -e "s/CF_AUTHORITY/DA$CF_AUTHORITY/" \
  2353.     -e "s/CF_DCLASS/CDUUCP $CF_DCLASS/" \
  2354.     -e "s;CF_SMTP;$CF_SMTP;" \
  2355.     -e "s;CF_DATE;$CF_DATE;" \
  2356.     -e "s;CF_LOCALMAIL;$CF_LOCALMAIL;" \
  2357.     -e "s;CF_BSMAIL;$CF_BSMAIL;" \
  2358.     -e "s;CF_SVMAIL;$CF_SVMAIL;" \
  2359.     -e "s;CF_GATEWAY;$CF_GATEWAY;" \
  2360.     smail.cf.form > sendmail.cf
  2361. END-OF-FILE
  2362.  
  2363. if [ "$filename" != "/dev/null" ]
  2364. then
  2365.   size=`wc -c < $filename`
  2366.  
  2367.   if [ $size != 2604 ]
  2368.   then
  2369.     echo $filename changed - should be 2604 bytes, not $size bytes
  2370.   fi
  2371.  
  2372.   chmod 644 $filename
  2373. fi
  2374.  
  2375. # ---------- file smail.prompt ----------
  2376.  
  2377. filename="smail.prompt"
  2378.  
  2379. if [ -f $filename ]
  2380. then
  2381.   echo File \"$filename\" already exists\!  Skipping...
  2382.   filename=/dev/null        # throw it away
  2383. else
  2384.   echo extracting file smail.prompt...
  2385. fi
  2386.  
  2387. cat << 'END-OF-FILE' > $filename
  2388. loop=true
  2389. while test $loop = true
  2390. do 
  2391.     case "$1" in
  2392.     string)
  2393.         echo "$2" 1>&2
  2394.         read ans
  2395.         if test ! -z "$ans"
  2396.         then
  2397.             echo $ans
  2398.             loop=false;
  2399.         fi
  2400.     ;;
  2401.     file)
  2402.         echo "$2" 1>&2
  2403.         read ans
  2404.         case "$ans" in
  2405.         /*)
  2406.             if test -f "$ans"
  2407.             then
  2408.                 echo $ans
  2409.                 loop=false;
  2410.             else
  2411.                 echo "file '$ans' not found" 1>&2
  2412.             fi
  2413.         ;;
  2414.         *)
  2415.             echo "must give FULL PATH to file" 1>&2
  2416.         ;;
  2417.         esac
  2418.     ;;
  2419.     yesno)
  2420.         echo "$2" 1>&2
  2421.         read ans
  2422.         case "$ans" in
  2423.         y|Y|yes|Yes|YES)
  2424.             echo "yes"
  2425.             loop=false
  2426.         ;;
  2427.         n|N|no|No|NO)
  2428.             echo "no"
  2429.             loop=false
  2430.         ;;
  2431.         *)
  2432.             echo "Please enter yes or no" 1>&2
  2433.         ;;
  2434.         esac
  2435.     ;;
  2436.     *)
  2437.  
  2438.         echo "usage: $0 string|yesno prompt_message" 1>&2
  2439.         echo BOGUS_PROMPT_STRING
  2440.         loop=false
  2441.     ;;
  2442.     esac
  2443. done
  2444. END-OF-FILE
  2445.  
  2446. if [ "$filename" != "/dev/null" ]
  2447. then
  2448.   size=`wc -c < $filename`
  2449.  
  2450.   if [ $size != 717 ]
  2451.   then
  2452.     echo $filename changed - should be 717 bytes, not $size bytes
  2453.   fi
  2454.  
  2455.   chmod 644 $filename
  2456. fi
  2457.  
  2458. # ---------- file sysexits.h ----------
  2459.  
  2460. filename="sysexits.h"
  2461.  
  2462. if [ -f $filename ]
  2463. then
  2464.   echo File \"$filename\" already exists\!  Skipping...
  2465.   filename=/dev/null        # throw it away
  2466. else
  2467.   echo extracting file sysexits.h...
  2468. fi
  2469.  
  2470. cat << 'END-OF-FILE' > $filename
  2471. # define EX_OK        0    /* successful termination */
  2472. # define EX_USAGE    64    /* command line usage error */
  2473. # define EX_NOHOST    68    /* host name unknown */
  2474. # define EX_UNAVAILABLE    69    /* service unavailable */
  2475. # define EX_SOFTWARE    70    /* internal software error */
  2476. # define EX_OSFILE    72    /* critical OS file missing */
  2477. # define EX_CANTCREAT    73    /* can't create (user) output file */
  2478. END-OF-FILE
  2479.  
  2480. if [ "$filename" != "/dev/null" ]
  2481. then
  2482.   size=`wc -c < $filename`
  2483.  
  2484.   if [ $size != 368 ]
  2485.   then
  2486.     echo $filename changed - should be 368 bytes, not $size bytes
  2487.   fi
  2488.  
  2489.   chmod 644 $filename
  2490. fi
  2491.  
  2492. # ---------- file u.Path.local ----------
  2493.  
  2494. filename="u.Path.local"
  2495.  
  2496. if [ -f $filename ]
  2497. then
  2498.   echo File \"$filename\" already exists\!  Skipping...
  2499.   filename=/dev/null        # throw it away
  2500. else
  2501.   echo extracting file u.Path.local...
  2502. fi
  2503.  
  2504. cat << 'END-OF-FILE' > $filename
  2505. # Put local aliases in this file that you don't want to bother
  2506. # the whole world with (e.g. pc's) or that you want to keep secret.
  2507. # Change the name of the file to u.Path.`hostname`
  2508. myname    topsecret(DIRECT), 4urisonly(LOCAL), mypc(LOCAL)
  2509. END-OF-FILE
  2510.  
  2511. if [ "$filename" != "/dev/null" ]
  2512. then
  2513.   size=`wc -c < $filename`
  2514.  
  2515.   if [ $size != 238 ]
  2516.   then
  2517.     echo $filename changed - should be 238 bytes, not $size bytes
  2518.   fi
  2519.  
  2520.   chmod 644 $filename
  2521. fi
  2522.  
  2523. # ---------- file u.Path.top.1 ----------
  2524.  
  2525. filename="u.Path.top.1"
  2526.  
  2527. if [ -f $filename ]
  2528. then
  2529.   echo File \"$filename\" already exists\!  Skipping...
  2530.   filename=/dev/null        # throw it away
  2531. else
  2532.   echo extracting file u.Path.top.1...
  2533. fi
  2534.  
  2535. cat << 'END-OF-FILE' > $filename
  2536. #
  2537. # DOMAIN GATEWAY LIST FOR UUCP AND OTHER TOP-LEVEL DOMAINS
  2538. # This file is pathalias input for UUCP domain addressing.
  2539. #
  2540. # All gateway hosts (those in this file) must understand domain!user.
  2541. # Note that most lines are still commented out, because many hosts don't 
  2542. # recognise domain!user.
  2543. #
  2544. # Problems and changes to domains@registry.UUCP
  2545. #         9/20/85
  2546.  
  2547. # TOP LEVEL DOMAINS AND THEIR GATEWAYS
  2548.  
  2549. # UUCP top level domain
  2550. cbosgd    .uucp
  2551. ihnp4    .uucp
  2552. seismo    .uucp
  2553. ucbvax    .uucp
  2554. harvard    .uucp
  2555. mcvax    .uucp
  2556. decuac    .uucp
  2557.  
  2558. # ARPANET and related domains
  2559. seismo    .arpa, .com, .gov, .edu, .org, .net, .us
  2560. ucbvax    .arpa, .com, .gov, .edu, .org, .net, .us
  2561. harvard    .arpa, .com, .gov, .edu, .org, .net, .us
  2562. talcott    .arpa, .com, .gov, .edu, .org, .net, .us
  2563.  
  2564. # CSNET
  2565. harvard    .csnet
  2566. talcott    .csnet
  2567.  
  2568. # MAILNET
  2569. harvard    .mailnet
  2570. talcott    .mailnet
  2571.  
  2572. # BITNET
  2573. psuvax1    .bitnet
  2574. talcott    .bitnet
  2575.  
  2576. # United Kingdom/Great Britain
  2577. ucl-cs    .uk, .gb
  2578. ukc    .uk, .gb
  2579.  
  2580. # Israel
  2581. humus    .il, .israel
  2582.  
  2583. # Korea
  2584. kaist    .kr, .korea
  2585.  
  2586. # Australia
  2587. munnari    .au, .oz, .oz.au
  2588. mulga    .au, .oz, .oz.au
  2589.  
  2590. # Canada
  2591. ubc-vision    .ca, .cdn, .canada
  2592. watmath        .ca, .cdn, .canada
  2593. garvield    .ca, .cdn, .canada
  2594.  
  2595. # Japan
  2596. kddlab        .jp, .junet, .jpn
  2597. END-OF-FILE
  2598.  
  2599. if [ "$filename" != "/dev/null" ]
  2600. then
  2601.   size=`wc -c < $filename`
  2602.  
  2603.   if [ $size != 1168 ]
  2604.   then
  2605.     echo $filename changed - should be 1168 bytes, not $size bytes
  2606.   fi
  2607.  
  2608.   chmod 644 $filename
  2609. fi
  2610.  
  2611. # ---------- file u.Path.uucp.1 ----------
  2612.  
  2613. filename="u.Path.uucp.1"
  2614.  
  2615. if [ -f $filename ]
  2616. then
  2617.   echo File \"$filename\" already exists\!  Skipping...
  2618.   filename=/dev/null        # throw it away
  2619. else
  2620.   echo extracting file u.Path.uucp.1...
  2621. fi
  2622.  
  2623. cat << 'END-OF-FILE' > $filename
  2624. #
  2625. # DOMAIN GATEWAY LIST FOR UUCP AND OTHER TOP-LEVEL DOMAINS
  2626. # This file is pathalias input for UUCP domain addressing.
  2627. #
  2628. # All gateway hosts (those in this file) must understand domain!user.
  2629. #
  2630. # Problems and changes to domains@registry.UUCP
  2631. #         9/20/85
  2632.  
  2633. # TOP LEVEL REGISTRY ALIAS (.UUCP implied)
  2634.  
  2635. cbosgd        =    registry
  2636.  
  2637. # UUCP 2nd level domains and their gateways.
  2638.  
  2639. #O    AT&T
  2640. cbosgd    .att.com, .att
  2641. # will include ihnp4 as soon as ihnp4 handles subdom.mach.att.com
  2642.  
  2643. #O    BellCore - Bell Communications Research
  2644. bellcore    .bellcore.com
  2645. mouton        .bellcore.com
  2646.  
  2647. #O    Digital Equipment Corp
  2648. decuac    .dec.com, .dec
  2649. decwrl    .dec.com, .dec
  2650.  
  2651. #O    Concurrent Computer Corporation
  2652. peora    .ccur.uucp
  2653. END-OF-FILE
  2654.  
  2655. if [ "$filename" != "/dev/null" ]
  2656. then
  2657.   size=`wc -c < $filename`
  2658.  
  2659.   if [ $size != 674 ]
  2660.   then
  2661.     echo $filename changed - should be 674 bytes, not $size bytes
  2662.   fi
  2663.  
  2664.   chmod 644 $filename
  2665. fi
  2666.  
  2667. echo done
  2668.  
  2669. exit 0
  2670.