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

  1. From: csu@alembic.acs.com (Dave Mack)
  2. Newsgroups: alt.sources
  3. Subject: Anonymous Contact Service software v1.1, Part03/08
  4. Message-ID: <1990Jul15.170632.6897@alembic.acs.com>
  5. Date: 15 Jul 90 17:06:32 GMT
  6.  
  7. This is the second distribution of the Anonymous Contact Service
  8. software. The distribution consists of 8 shar files. This will
  9. (hopefully) be the last full distribution of the system - all
  10. future versions will be distributed as patches. The patchlevel of
  11. this version is 1.
  12.  
  13. The ACS software provides a mechanism for posting anonymous articles,
  14. for receiving replies to those articles which are also anonymous, and
  15. permits prolonged anonymous conversations in which neither writer knows
  16. the other's actual e-mail address.
  17.  
  18. This software is currently being used to provide an anonymous personals
  19. service in alt.personals.
  20.  
  21. Dave Mack
  22. csu@alembic.ACS.COM
  23.  
  24. #! /bin/sh
  25. # This is a shell archive.  Remove anything before this line, then unpack
  26. # it by saving it into a file and typing "sh file".  To overwrite existing
  27. # files, type "sh file -c".  You can also feed this as standard input via
  28. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  29. # will see the following message at the end:
  30. #        "End of archive 3 (of 8)."
  31. # Contents:  mailer/aliases.8 mailer/main.c mailer/misc.c mailer/nptx.c
  32. #   mailer/pw.c
  33. # Wrapped by csu@alembic on Sun Jul 15 12:46:45 1990
  34. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  35. if test -f 'mailer/aliases.8' -a "${1}" != "-c" ; then 
  36.   echo shar: Will not clobber existing file \"'mailer/aliases.8'\"
  37. else
  38. echo shar: Extracting \"'mailer/aliases.8'\" \(4447 characters\)
  39. sed "s/^X//" >'mailer/aliases.8' <<'END_OF_FILE'
  40. X.TH ALIASES 8
  41. X.tr ~
  42. X.SH NAME
  43. Xaliases \- alias file for smail
  44. X.SH DESCRIPTION
  45. XThis file is used by
  46. X.I smail
  47. Xonly if
  48. X.I SENDMAIL
  49. Xis
  50. X.I not defined.
  51. XIf
  52. X.I SENDMAIL
  53. Xis defined, then
  54. X.I sendmail
  55. Xdoes all of the aliasing for the host.
  56. X.PP
  57. XThis file contains a list of aliases for
  58. Xlocal users or mailing lists.
  59. XThe format of each alias is
  60. X.sp
  61. X.ce
  62. Xalias_name~recip_name1~recip_name2~...
  63. X.sp
  64. XAn attempt has been made to remain compatible with
  65. X.I sendmail
  66. Xalias file format, though the syntax is much more format free than
  67. X.I sendmail.
  68. XAs distributed,
  69. X.I case differences are ignored
  70. Xwhen comparing names to aliases.
  71. XOnly alias names which resolve to the local host are recognized, and are
  72. Xstored in their local form.
  73. XLines which start with a white~space are continuation lines.
  74. XParenthesised strings are taken as comments (no nesting),
  75. Xas is anything after a '#' (as in
  76. X.IR /bin/sh ).
  77. XHere are some examples:
  78. X.sp
  79. X.nf
  80. X# this whole line is a comment
  81. X#
  82. X# These are equivalent definitions
  83. X
  84. Xalias_name      recip1 recip2 recip3
  85. X
  86. Xalias_name:     recip1, recip2 , recip3
  87. X
  88. Xalias_name      recip1 recip2
  89. X                recip3
  90. X
  91. Xalias_name      recip1  # Recip1's name
  92. X                recip2  # Recip2's name
  93. X                recip3  # Recip3's name
  94. X
  95. Xalias_name      recip1 (Recp1's name) recip2 (Recp2's name)
  96. X                recip3 (Recp3's name)
  97. X
  98. Xalias_name@thishost     recip1 recip2 recip3
  99. X
  100. Xalias_name@thisdomain   recip1 recip2 recip3
  101. X
  102. Xthishost!alias_name     recip1 recip2 recip3
  103. X
  104. Xthisdomain!alias_name   recip1 recip2 recip3
  105. X.fi
  106. X.PP
  107. XMailing lists are easily handled by two forms of file inclusion.
  108. XThe first form is the same as is supported by
  109. X.I sendmail
  110. X.sp
  111. X.ce
  112. Xmylist    :include:/usr/lib/ml/mylist
  113. X.sp
  114. XIn this example, each entry in
  115. X.I /usr/lib/ml/mylist
  116. Xwould be added to the alias for
  117. X.I mylist.
  118. XThe second form is unique to
  119. X.I smail.
  120. XIt allows the
  121. X.I aliases
  122. Xfile to include other
  123. X.I aliases
  124. Xfiles.
  125. X.sp
  126. X.ce
  127. X:include:/usr/lib/ml/more-aliases
  128. X.sp
  129. XThis would include the file
  130. X.I /usr/lib/ml/more-aliases
  131. Xas a regular alias file.
  132. XThis makes it easier to maintain groups of aliases that
  133. Xchange frequently, such as the list of netnews moderators.
  134. X.PP
  135. XAll aliases are recursive, so care
  136. Xmust be taken in their definition.
  137. X.I smail
  138. Xaliasing attempts to prevent infinite loops, and to
  139. Xdo what was intended by the user.  For example, the alias:
  140. X.sp
  141. X.ce
  142. Xmylogin~mypc!mylogin~mylogin
  143. X.sp
  144. XExpands to
  145. X.sp
  146. X.ce
  147. Xmypc!mylogin mylogin
  148. X.sp
  149. Xeven though the second occurrence of
  150. X.I mylogin
  151. Xmatches the alias name.
  152. X.sp
  153. XBoth forms of file inclusion are recursive, too,
  154. Xso watch out for nesting include files.  They
  155. Xmay lead to infinite loops.
  156. X.PP
  157. XWhile the cost of parsing an alias file is usually negligible,
  158. Xit's wise to take savings anywhere savings
  159. Xcan be found.  Therefore, it's worth mentioning
  160. X.IR smail 's
  161. Xparsing strategy.
  162. X.I smail
  163. Xwill try to get by with doing as little work
  164. Xas possible when aliasing.  If on a particular
  165. Xinvocation of
  166. X.I smail,
  167. Xnone of the recipent addresses are local,
  168. X(i.e., not potential aliases)
  169. Xthen the
  170. X.I aliases
  171. Xfile won't even be read.  Similarly,
  172. Xwhen an
  173. X.I aliases
  174. Xfile is read, it does not expand any of the :include: files
  175. Xuntil they are referenced.  Thus, in the alias (above) for
  176. X.I mylist,
  177. Xthe file
  178. X.I :include:/usr/lib/ml/mylist
  179. Xwould not be opened and read (parsed) unless
  180. Xmail was sent to
  181. X.I mylist.
  182. XWise use of :include: files can greatly
  183. Xincrease the efficiency of the alias utility.
  184. XIt's not clear exactly where the
  185. X.I break-even
  186. Xpoint is when deciding to use an  :include: file in an alias,
  187. Xversus having all of the recipents listed on the line;
  188. Xbut if a mailing list is large (whatever that means)
  189. Xit is wise to use the :include: feature to save on
  190. Xparsing costs.  Note that this discussion only applies to the
  191. Xfirst form of file inclusion, since reading an
  192. X.I aliases
  193. Xfile constitutes a reference to :include: files of the second form.
  194. X.PP
  195. XThere is another form of aliasing which works with the alias capability.
  196. XThis is called
  197. X.I per user forwarding.
  198. XFor a given user name, if there is no alias for the user
  199. Xthen, if the file
  200. X.I ~user/.forward
  201. Xexists, then its contents will be treated as an alias for
  202. Xthe user.  The syntax is the same as that of the
  203. Xrecipient lists in the alias file described above.
  204. X.PP
  205. XOne difference between
  206. X.I smail
  207. Xand
  208. X.I sendmail
  209. Xis that
  210. X.I smail
  211. Xdoesn't handle stuff like mail to files
  212. Xor command execution.
  213. X.SH SEE ALSO
  214. Xsmail(8), paths(8), pathproc(8)
  215. X.SH VERSION
  216. X@(#)aliases.8    2.5 (smail) 9/15/87
  217. END_OF_FILE
  218. if test 4447 -ne `wc -c <'mailer/aliases.8'`; then
  219.     echo shar: \"'mailer/aliases.8'\" unpacked with wrong size!
  220. fi
  221. # end of 'mailer/aliases.8'
  222. fi
  223. if test -f 'mailer/main.c' -a "${1}" != "-c" ; then 
  224.   echo shar: Will not clobber existing file \"'mailer/main.c'\"
  225. else
  226. echo shar: Extracting \"'mailer/main.c'\" \(5194 characters\)
  227. sed "s/^X//" >'mailer/main.c' <<'END_OF_FILE'
  228. X/*
  229. X**
  230. X**  rmail/smail - UUCP mailer with automatic routing.
  231. X**
  232. X**  Christopher Seiwald        /+\
  233. X**  chris@cbosgd.att.com    +\
  234. X**  January, 1985        \+/
  235. X**
  236. X*/
  237. X
  238. X#ifndef lint
  239. Xstatic char     *sccsid="@(#)main.c    2.5 (smail) 9/15/87";
  240. X#endif
  241. X
  242. X/*
  243. X**
  244. X**  usage:      rmail [options] address...
  245. X**        smail [options] address...
  246. X**  options:
  247. X**        -d         debug - verbose and don't invoke mailers.
  248. X**        -v        verbose - just verbose.
  249. X**        -A        print mapped addresses.  don't invoke mailers.
  250. X**        -h hostname    set hostname 
  251. X**        -H hostdomain    set hostdomain (default hostname.MYDOM)
  252. X**        -p pathfile    path database filename
  253. X**        -r        force routing of host!address
  254. X**        -R        reroute even explicit path!user
  255. X**        -l        user@domain goes to local mailer
  256. X**        -L        all mail goes local
  257. X**        -q number    mail queueing cost threshold
  258. X**        -m number    limit on number of uux_noqueue jobs
  259. X**        -u string    string of flags for uux
  260. X**              -F address      name to substitute in From: line
  261. X**        -a aliasfile    aliases filename (not used with SENDMAIL)
  262. X**        -n namelist    list of full names for simple aliases
  263. X*/
  264. X
  265. X#include    <stdio.h>
  266. X#include    <ctype.h>
  267. X#include    "defs.h"
  268. X
  269. Xint exitstat = 0;        /* exit status, set by resolve, deliver    */
  270. X
  271. Xenum edebug debug     = NO;    /* set by -d or -v option        */
  272. Xenum ehandle handle   = HANDLE;    /* which mail we can handle, see defs.h    */
  273. Xenum erouting routing = ROUTING;/* to route or not to route, see defs.h */
  274. X
  275. Xchar hostname[SMLBUF]   = "";    /* set by -h, defaults in defs.h     */
  276. Xchar hostdomain[SMLBUF] = "";    /* set by -H, defaults in defs.h     */
  277. Xchar hostuucp[SMLBUF] = "";    /* built with hostname+".UUCP"         */
  278. X
  279. Xchar *pathfile  = PATHS;    /* or set by -p             */
  280. Xchar *uuxargs   = NULL;        /* or set by -u                */
  281. X
  282. Xchar *aliasfile =
  283. X#ifdef ALIAS
  284. X        ALIAS;        /* or set by -a                */
  285. X#else
  286. X        NULL;
  287. X#endif
  288. X
  289. Xchar *fnlist    =
  290. X#ifdef FULLNAME
  291. X        FULLNAME;    /* or set by -n                */
  292. X#else
  293. X        NULL;
  294. X#endif
  295. X
  296. Xint  queuecost  = QUEUECOST;    /* or set by -q                */
  297. Xchar *from_addr = NULL;        /* or set by -F                */
  298. Xint  maxnoqueue = MAXNOQUEUE;    /* or set by -m                         */
  299. X
  300. Xint  getcost    = 
  301. X#ifdef GETCOST
  302. X        1;    /* get cost of path even if not routing */
  303. X#else
  304. X        0;
  305. X#endif
  306. X
  307. Xchar *spoolfile = NULL;        /* name of the file containing letter   */
  308. XFILE *spoolfp;            /* file pointer to spoolfile        */
  309. Xint  spoolmaster = 0;        /* indicates 'control' of spoolfile     */
  310. X
  311. Xvoid spool();
  312. X
  313. X
  314. X/*
  315. X**
  316. X**  rmail/smail: mail stdin letter to argv addresses.
  317. X**
  318. X**  After processing command line options and finding our host and domain 
  319. X**  names, we map addresses into <host,user,form,cost> sets.  Then we deliver.
  320. X**
  321. X*/
  322. X
  323. Xmain(argc, argv)
  324. Xint argc;
  325. Xchar *argv[];
  326. X{
  327. X    char *hostv[MAXARGS];        /* UUCP neighbor         */
  328. X    char *userv[MAXARGS];        /* address given to host     */
  329. X    int  costv[MAXARGS];        /* cost of resolved route    */
  330. X    enum eform formv[MAXARGS];    /* invalid, local, or uucp     */
  331. X    char *p;
  332. X    int c;
  333. X    int  printaddr  = 0;        /* or set by -A            */
  334. X    int nargc;
  335. X    char **nargv, **alias();
  336. X
  337. X    char *optstr = "cdvArRlLH:h:p:u:q:a:n:m:f:F:";
  338. X    extern char *optarg;
  339. X    extern int optind;
  340. X
  341. X/*
  342. X**  see if we aren't invoked as rmail
  343. X*/
  344. X    if((p = rindex(argv[0], '/')) == NULL) {
  345. X        p = argv[0];
  346. X    } else {
  347. X        p++;
  348. X    }
  349. X
  350. X    if(*p != 'r' ) {
  351. X        handle = ALL;
  352. X    }
  353. X
  354. X/*
  355. X**  Process command line arguments
  356. X*/
  357. X    while ((c = getopt(argc, argv, optstr)) != EOF) {
  358. X        switch ( c ) {
  359. X        case 'd': debug      = YES;         break;
  360. X        case 'v': debug      = VERBOSE;     break; 
  361. X        case 'A': printaddr  = 1;         break; 
  362. X        case 'F': from_addr  = optarg;        break;
  363. X        case 'r': routing    = ALWAYS;        break;
  364. X        case 'R': routing    = REROUTE;        break;
  365. X        case 'l': handle     = JUSTUUCP;    break;
  366. X        case 'L': handle     = NONE;        break;
  367. X        case 'f': spoolfile  = optarg;        break;
  368. X        case 'p': pathfile   = optarg;         break;
  369. X        case 'u': uuxargs    = optarg;         break;
  370. X        case 'a': aliasfile  = optarg;         break;
  371. X        case 'n': fnlist     = optarg;         break;
  372. X        case 'H': (void) strcpy(hostdomain, optarg);    break;
  373. X        case 'h': (void) strcpy(hostname, optarg);     break;
  374. X        case 'm': if(isdigit(*optarg)) {
  375. X                  maxnoqueue = atoi(optarg);
  376. X              }
  377. X              break;
  378. X        case 'c': getcost     = 1;        break;
  379. X        case 'q': if(isdigit(*optarg)) {
  380. X                  queuecost = atoi(optarg);
  381. X              }
  382. X              break;
  383. X        default:
  384. X            error( EX_USAGE, "valid flags are %s\n", optstr);
  385. X        }
  386. X    }
  387. X    if ( argc <= optind ) {
  388. X        error( EX_USAGE, "usage: %s [flags] address...\n", argv[0] );
  389. X    }
  390. X
  391. X/*
  392. X**  Get our default hostname and hostdomain.
  393. X*/
  394. X    getmynames();
  395. X
  396. X/*
  397. X**  Spool the letter in a temporary file.
  398. X*/
  399. X    nargc = argc - optind;
  400. X    if(printaddr == 0) {
  401. X        spool(nargc, &argv[optind]);
  402. X    }
  403. X
  404. X/*
  405. X** Do aliasing and fullname resolution
  406. X*/
  407. X    nargv = alias(&nargc, &argv[optind]);
  408. X
  409. X/*
  410. X**  Map argv addresses to <host, user, form, cost>.
  411. X*/
  412. X    map(nargc, nargv, hostv, userv, formv, costv);
  413. X/*
  414. X**  If all we want it mapped addresses, print them and exit.
  415. X*/
  416. X    if(printaddr) {
  417. X        int i;
  418. X        char abuf[SMLBUF];
  419. X        for(i=nargc-1; i >= 0; i--) {
  420. X            if(formv[i] == ERROR) {
  421. X                (void) strcpy(abuf, nargv[i]);
  422. X            } else {
  423. X                build(hostv[i], userv[i], formv[i], abuf);
  424. X            }
  425. X            (void) fputs(abuf, stdout);
  426. X            if(i != 0) (void) putchar(' ');
  427. X        }
  428. X        (void) putchar('\n');
  429. X        exit(0);
  430. X    }
  431. X/*
  432. X**  Deliver.
  433. X*/
  434. X    deliver(nargc, hostv, userv, formv, costv);
  435. X/*
  436. X**  Exitstat was set if any resolve or deliver failed, otherwise 0.
  437. X*/
  438. X    return( exitstat );
  439. X}
  440. END_OF_FILE
  441. if test 5194 -ne `wc -c <'mailer/main.c'`; then
  442.     echo shar: \"'mailer/main.c'\" unpacked with wrong size!
  443. fi
  444. # end of 'mailer/main.c'
  445. fi
  446. if test -f 'mailer/misc.c' -a "${1}" != "-c" ; then 
  447.   echo shar: Will not clobber existing file \"'mailer/misc.c'\"
  448. else
  449. echo shar: Extracting \"'mailer/misc.c'\" \(6551 characters\)
  450. sed "s/^X//" >'mailer/misc.c' <<'END_OF_FILE'
  451. X
  452. X/*
  453. X**  Miscellaneous support functions for smail/rmail
  454. X*/
  455. X
  456. X#ifndef lint
  457. Xstatic char     *sccsid="@(#)misc.c    2.5 (smail) 9/15/87";
  458. X#endif
  459. X
  460. X# include    <stdio.h>
  461. X# include    <sys/types.h>
  462. X# include    <ctype.h>
  463. X# include    "defs.h"
  464. X#ifdef BSD
  465. X# include    <sys/time.h>
  466. X# include    <sys/timeb.h>
  467. X#else
  468. X# include    <time.h>
  469. X# include    <sys/utsname.h>
  470. X#endif
  471. X
  472. Xextern int  exitstat;        /* set if a forked mailer fails */
  473. Xextern enum edebug debug;    /* how verbose we are         */ 
  474. Xextern enum ehandle handle;    /* what we handle        */
  475. Xextern char *uuxargs;        /* arguments given to uux       */
  476. Xextern int  queuecost;        /* threshold for queueing mail  */
  477. Xextern int  maxnoqueue;        /* max number of uucico's       */
  478. Xextern enum erouting routing;    /* when to route addresses    */
  479. Xextern char hostdomain[];    /* */
  480. Xextern char hostname[];        /* */
  481. Xextern char hostuucp[];        /* */
  482. Xextern char *pathfile;        /* location of path database    */
  483. Xextern char *spoolfile;        /* file name of spooled message */
  484. Xextern FILE *spoolfp;        /* file ptr  to spooled message */
  485. Xextern int spoolmaster;        /* set if creator of spoolfile  */
  486. X
  487. Xextern struct tm *localtime();
  488. X
  489. Xstruct tm *gmt, *loc;        /* GMT and local time structure    */
  490. Xtime_t now;            /* current system time        */
  491. Xchar nows[50];            /* time in ctime format        */
  492. Xchar arpanows[50];        /* time in arpa format        */
  493. X
  494. X# ifdef LOG
  495. Xvoid
  496. Xlog(command, from, size)
  497. Xchar *command, *from;
  498. Xlong size;
  499. X{
  500. X    FILE *fd;
  501. X    char *logtime, tbuf[50];
  502. X    int cmask;
  503. X
  504. X    logtime = strcpy(tbuf, nows);
  505. X    logtime[16] = '\0';
  506. X    logtime += 4;
  507. X
  508. X    cmask = umask(0);
  509. X    fd = fopen(LOG, "a");
  510. X    (void) umask(cmask);
  511. X
  512. X    if (fd != NULL) {
  513. X        (void) fprintf(fd, "%s\t%ld\t%s\t%s\n",
  514. X            logtime, size, from, command);
  515. X        (void) fclose(fd);
  516. X    }
  517. X}
  518. X# endif
  519. X
  520. X# ifdef RECORD
  521. XFILE *
  522. Xrecord(command, from, size)
  523. Xchar *command, *from;
  524. Xlong size;
  525. X{
  526. X    FILE *fd;
  527. X    char *logtime, buf[SMLBUF];
  528. X    int cmask;
  529. X
  530. X    logtime = strcpy(buf, nows);
  531. X    logtime[16] = 0;
  532. X    logtime += 4;
  533. X
  534. X    cmask = umask(0);
  535. X    fd = fopen(RECORD, "a");
  536. X    (void) umask(cmask);
  537. X
  538. X    if (fd != NULL) {
  539. X        (void) fprintf(fd, "%s: %s, from %s, %ld bytes\n", 
  540. X            logtime, command, from, size);
  541. X    }
  542. X    while(fgets(buf, sizeof(buf), spoolfp) != NULL) {
  543. X        (void) fputs(buf, fd);
  544. X    }
  545. X    (void) fclose(fd);
  546. X}
  547. X# endif
  548. X
  549. X
  550. Xsetdates()
  551. X{
  552. X    time_t time();
  553. X    struct tm *gmtime();
  554. X    char *ctime(), *arpadate();
  555. X
  556. X    (void) time(&now);
  557. X    (void) strcpy(nows, ctime(&now));
  558. X    gmt = gmtime(&now);
  559. X    loc = localtime(&now);
  560. X    (void) strcpy(arpanows, arpadate(nows));
  561. X}
  562. X
  563. X/*
  564. X**  Note: This routine was taken from sendmail
  565. X**
  566. X**  ARPADATE -- Create date in ARPANET format
  567. X**
  568. X**    Parameters:
  569. X**        ud -- unix style date string.  if NULL, one is created.
  570. X**
  571. X**    Returns:
  572. X**        pointer to an ARPANET date field
  573. X**
  574. X**    Side Effects:
  575. X**        none
  576. X**
  577. X**    WARNING:
  578. X**        date is stored in a local buffer -- subsequent
  579. X**        calls will overwrite.
  580. X**
  581. X**    Bugs:
  582. X**        Timezone is computed from local time, rather than
  583. X**        from whereever (and whenever) the message was sent.
  584. X**        To do better is very hard.
  585. X**
  586. X**        Some sites are now inserting the timezone into the
  587. X**        local date.  This routine should figure out what
  588. X**        the format is and work appropriately.
  589. X*/
  590. X
  591. Xchar *
  592. Xarpadate(ud)
  593. X    register char *ud;
  594. X{
  595. X    register char *p;
  596. X    register char *q;
  597. X    static char b[40];
  598. X    extern char *ctime();
  599. X    register int i;
  600. X#ifndef BSD
  601. X    extern char *tzname[];
  602. X    time_t t, time();
  603. X#else
  604. X    /* V7 and 4BSD */
  605. X    struct timeb t;
  606. X    extern struct timeb *ftime();
  607. X    extern char *timezone();
  608. X#endif
  609. X
  610. X    /*
  611. X    **  Get current time.
  612. X    **    This will be used if a null argument is passed and
  613. X    **    to resolve the timezone.
  614. X    */
  615. X
  616. X#ifndef BSD
  617. X    (void) time(&t);
  618. X    if (ud == NULL)
  619. X        ud = ctime(&t);
  620. X#else
  621. X    /* V7 or 4BSD */
  622. X    ftime(&t);
  623. X    if (ud == NULL)
  624. X        ud = ctime(&t.time);
  625. X#endif
  626. X
  627. X    /*
  628. X    **  Crack the UNIX date line in a singularly unoriginal way.
  629. X    */
  630. X
  631. X    q = b;
  632. X
  633. X    p = &ud[8];        /* 16 */
  634. X    if (*p == ' ')
  635. X        p++;
  636. X    else
  637. X        *q++ = *p++;
  638. X    *q++ = *p++;
  639. X    *q++ = ' ';
  640. X
  641. X    p = &ud[4];        /* Sep */
  642. X    *q++ = *p++;
  643. X    *q++ = *p++;
  644. X    *q++ = *p++;
  645. X    *q++ = ' ';
  646. X
  647. X    p = &ud[22];        /* 1979 */
  648. X    *q++ = *p++;
  649. X    *q++ = *p++;
  650. X    *q++ = ' ';
  651. X
  652. X    p = &ud[11];        /* 01:03:52 */
  653. X    for (i = 8; i > 0; i--)
  654. X        *q++ = *p++;
  655. X
  656. X                /* -PST or -PDT */
  657. X#ifndef BSD
  658. X    p = tzname[localtime(&t)->tm_isdst];
  659. X#else
  660. X    p = timezone(t.timezone, localtime(&t.time)->tm_isdst);
  661. X#endif
  662. X    if (p[3] != '\0')
  663. X    {
  664. X        /* hours from GMT */
  665. X        p += 3;
  666. X        *q++ = *p++;
  667. X        if (p[1] == ':')
  668. X            *q++ = '0';
  669. X        else
  670. X            *q++ = *p++;
  671. X        *q++ = *p++;
  672. X        p++;        /* skip ``:'' */
  673. X        *q++ = *p++;
  674. X        *q++ = *p++;
  675. X    }
  676. X    else
  677. X    {
  678. X        *q++ = ' ';
  679. X        *q++ = *p++;
  680. X        *q++ = *p++;
  681. X        *q++ = *p++;
  682. X    }
  683. X
  684. X    p = &ud[0];        /* Mon */
  685. X    *q++ = ' ';
  686. X    *q++ = '(';
  687. X    *q++ = *p++;
  688. X    *q++ = *p++;
  689. X    *q++ = *p++;
  690. X    *q++ = ')';
  691. X
  692. X    *q = '\0';
  693. X    return (b);
  694. X}
  695. X
  696. X/*
  697. X *    The user name "postmaster" must be accepted regardless of what
  698. X *    combination of upper and lower case is used.  This function is
  699. X *    used to convert all case variants of "postmaster" to all lower
  700. X *    case.  If the user name passed in is not "postmaster", it is
  701. X *    returned unchanged.
  702. X */
  703. Xchar *
  704. Xpostmaster(user)
  705. Xchar *user;
  706. X{
  707. X    static char *pm = "postmaster";
  708. X
  709. X    if(strcmpic(user, pm) == 0) {
  710. X        return(pm);
  711. X    } else {
  712. X        return(user);
  713. X    }
  714. X}
  715. X
  716. X/*
  717. X * Return 1 iff the string is "UUCP" (ignore case).
  718. X */
  719. Xisuucp(str)
  720. Xchar *str;
  721. X{
  722. X    if(strcmpic(str, "UUCP") == 0) {
  723. X        return(1);
  724. X    } else {
  725. X        return(0);
  726. X    }
  727. X}
  728. X
  729. X/*
  730. X** sform(form) returns a pointer to a string that tells what 'form' means
  731. X*/
  732. X
  733. Xchar *
  734. Xsform(form)
  735. Xenum eform form;
  736. X{
  737. X    if(form == ERROR)  return("ERROR");
  738. X    if(form == LOCAL)  return("LOCAL");
  739. X    if(form == DOMAIN) return("DOMAIN");
  740. X    if(form == UUCP)   return("UUCP");
  741. X    if(form == ROUTE)  return("ROUTE");
  742. X    return("UNKNOWN");
  743. X}
  744. X
  745. X/*
  746. X**
  747. X**  getmynames(): what is my host name and host domain?
  748. X**
  749. X**  Hostname set by -h, failing that by #define HOSTNAME, failing
  750. X**  that by gethostname() or uname().
  751. X**  
  752. X**  Hostdomain set by -h, failing that by #define HOSTDOMAIN,
  753. X**  failing that as hostname.MYDOM, or as just hostname.
  754. X**
  755. X**  See defs.h for the inside story.
  756. X**
  757. X*/
  758. X
  759. Xgetmynames()
  760. X{
  761. X#ifdef HOSTNAME
  762. X    if (!*hostname)
  763. X        (void) strcpy(hostname, HOSTNAME);
  764. X#endif
  765. X#ifdef GETHOSTNAME
  766. X    if (!*hostname)
  767. X        gethostname(hostname, SMLBUF - 1);
  768. X#endif
  769. X#ifdef UNAME
  770. X    if (!*hostname) {
  771. X        struct utsname site;
  772. X
  773. X        if (uname(&site) < 0)
  774. X            error(EX_SOFTWARE, "uname() call failed", 0);
  775. X        (void) strcpy(hostname, site.nodename);
  776. X    }
  777. X#endif
  778. X    if (!*hostname)
  779. X        error(EX_SOFTWARE, "can't determine hostname.\n", 0);
  780. X#ifdef HOSTDOMAIN
  781. X    if (!*hostdomain)
  782. X        (void) strcpy(hostdomain, HOSTDOMAIN);
  783. X#endif
  784. X#ifdef MYDOM
  785. X    if (!*hostdomain)
  786. X        (void) strcat(strcpy(hostdomain, hostname), MYDOM);
  787. X#endif
  788. X    if (!*hostdomain)
  789. X        (void) strcpy(hostdomain, hostname);
  790. X
  791. X    (void) strcat(strcpy(hostuucp, hostname), ".UUCP");
  792. X}
  793. END_OF_FILE
  794. if test 6551 -ne `wc -c <'mailer/misc.c'`; then
  795.     echo shar: \"'mailer/misc.c'\" unpacked with wrong size!
  796. fi
  797. # end of 'mailer/misc.c'
  798. fi
  799. if test -f 'mailer/nptx.c' -a "${1}" != "-c" ; then 
  800.   echo shar: Will not clobber existing file \"'mailer/nptx.c'\"
  801. else
  802. echo shar: Extracting \"'mailer/nptx.c'\" \(3534 characters\)
  803. sed "s/^X//" >'mailer/nptx.c' <<'END_OF_FILE'
  804. X#ifndef lint
  805. Xstatic char *sccsid = "@(#)nptx.c    2.5 (smail) 9/15/87";
  806. X#endif
  807. X
  808. X#include <stdio.h>
  809. X#include <sys/types.h>
  810. X#include <sys/stat.h>
  811. X#include <pwd.h>
  812. X#include "defs.h"
  813. X#include <ctype.h>
  814. X
  815. Xchar *malloc(), *index(), *fullname();
  816. Xvoid nptx(), free(), dotspace();
  817. X
  818. Xenum edebug debug;    /* not used by nptx */
  819. Xchar *fnlist = NULL;    /* not used by nptx */
  820. X
  821. Xmain()
  822. X{
  823. X    int i;
  824. X    char buf[SMLBUF], *p, *name, *last, *nick, *ctmp;
  825. X
  826. X    while(gets(buf) != NULL) {
  827. X        /*  line should be in form
  828. X        **
  829. X        **  login    First Last
  830. X        ** or
  831. X        **  login    First Last(Nickname)
  832. X        **
  833. X        */
  834. X        if((p = index(buf, '\t')) == NULL) {
  835. X            (void) fprintf(stderr, "format error: %s\n", buf);
  836. X            continue;
  837. X        }
  838. X
  839. X        *p++ = '\0';
  840. X        name = fullname(p);
  841. X        dotspace(name);
  842. X
  843. X        if (last = rindex(name, '.')) {
  844. X            last++;
  845. X        } else {
  846. X            last = NULL;
  847. X        }
  848. X
  849. X        if ((nick = index(p, '(')) != NULL) {
  850. X            nick++;
  851. X            if ((ctmp = index(nick, ')')) == NULL) {
  852. X                nick = NULL;
  853. X            } else {
  854. X                *ctmp = '\0';
  855. X            }
  856. X        }
  857. X
  858. X        nptx(buf, name);
  859. X
  860. X        if((last != NULL) && (nick != NULL)) {
  861. X            i=strlen(nick) + strlen(last) + 2;
  862. X            if((name = malloc(i)) != NULL) {
  863. X                (void) strcpy(name, nick);
  864. X                (void) strcat(name, ".");
  865. X                (void) strcat(name, last);
  866. X                dotspace(name);
  867. X                nptx(buf, name);
  868. X                free(name);
  869. X            }
  870. X        }
  871. X    }
  872. X    return(0);
  873. X}
  874. X
  875. Xvoid
  876. Xdotspace(s)
  877. Xchar *s;
  878. X{
  879. X    register char *p, *t;
  880. X
  881. X    /* turn whitespace to '.' */
  882. X    for(p = s; *p != '\0'; p++) {
  883. X        if((*p == ' ') || (*p == '\t')) {
  884. X            *p = '.';
  885. X        }
  886. X    }
  887. X
  888. X    /* elide leading '.'s */
  889. X    for(p = s; *p == '.' ; p++)
  890. X        ;
  891. X
  892. X    /* elide mulitple '.'s and all "'"s */
  893. X    for(t = s; *p != '\0'; p++, t++) {
  894. X        *t = *p;
  895. X
  896. X        if(*t == '\'') {
  897. X            t--;
  898. X            continue;
  899. X        }
  900. X
  901. X        if(*p == '.') {
  902. X            while(*(++p) == '.')
  903. X                ;
  904. X            p--;
  905. X        }
  906. X    }
  907. X    *t = '\0';
  908. X
  909. X    /* elide trailing '.' */
  910. X    if((t > s) && (*(--t) == '.')) *t = '\0';
  911. X}
  912. X
  913. Xvoid
  914. Xnptx(login, name)
  915. Xchar *login, *name;
  916. X{
  917. X    int i,j,k,N,lim,mask;
  918. X    int ii,ji,ki,Ni,limi,maski;
  919. X    char nl[11][100], il[11][100];
  920. X    char *pi, *p, *rindex();
  921. X    char buf[100];
  922. X    char bufi[100];
  923. X
  924. X    if((name == NULL) || (*name == '\0')) {
  925. X        return;
  926. X    }
  927. X
  928. X    for(i=0; i < 10; i++) {
  929. X        if((p = rindex(name, '.')) == NULL) break;
  930. X        (void) strcpy(nl[i], p+1);
  931. X        *p = NULL;
  932. X    }
  933. X    (void) strcpy(nl[i], name);
  934. X
  935. X    while((strcmpic(nl[i], "Mr"  ) == 0)
  936. X     ||   (strcmpic(nl[i], "Dr"  ) == 0)
  937. X     ||   (strcmpic(nl[i], "Mrs" ) == 0)
  938. X     ||   (strcmpic(nl[i], "Miss") == 0)
  939. X     ||   (strcmpic(nl[i], "Ms"  ) == 0)) {
  940. X        i--;
  941. X    }
  942. X
  943. X    while((strcmpic(nl[0], "Jr") == 0)
  944. X     ||   (strcmpic(nl[0], "Sr") == 0)) {
  945. X        for(j=0; j < i; j++) {
  946. X            (void) strcpy(nl[j], nl[j+1]);
  947. X        }
  948. X        i--;
  949. X    }
  950. X
  951. X    N = i;
  952. X    lim = 1 << (N+1);
  953. X    for(mask = 1 << N ; mask < lim ; mask++) {
  954. X        buf[0] = '\0';
  955. X        for(j = 1, k = N; j < lim; j <<=1, k--) {
  956. X            if(j & mask) {
  957. X                (void) strcat(buf, nl[k]);
  958. X                (void) strcat(buf, ".");
  959. X            }
  960. X        }
  961. X        if((p = rindex(buf, '.')) != NULL) {
  962. X            *p = '\0';
  963. X        }
  964. X
  965. X        for(ii=0; ii < 10; ii++) {
  966. X            if((pi = rindex(buf, '.')) == NULL) break;
  967. X            (void) strcpy(il[ii], pi+1);
  968. X            *pi = NULL;
  969. X        }
  970. X        (void) strcpy(il[ii], buf);
  971. X        Ni = ii;
  972. X        limi = 1 << (Ni+1);
  973. X        for(maski = 1 << Ni /* 0 */ ; maski < limi ; maski++) {
  974. X            bufi[0] = '\0';
  975. X            for(ji = 1, ki = Ni; ji < limi; ji <<=1, ki--) {
  976. X                if(ji & maski) {
  977. X                    (void) strcat(bufi, il[ki]);
  978. X                } else {
  979. X                    char init[3];
  980. X                    init[0] = il[ki][0];
  981. X                    init[1] = '\0';
  982. X                    (void) strcat(bufi, init);
  983. X                }
  984. X                (void) strcat(bufi, ".");
  985. X            }
  986. X            if((pi = rindex(bufi, '.')) != NULL) {
  987. X                *pi = '\0';
  988. X            }
  989. X#ifdef DOT_REQD
  990. X            if(index(bufi, '.') == NULL) {
  991. X                continue;
  992. X            }
  993. X#endif /* DOT_REQD */
  994. X            (void) printf("%s\t%s\n",bufi, login); /* */
  995. X        }
  996. X    }
  997. X}
  998. END_OF_FILE
  999. if test 3534 -ne `wc -c <'mailer/nptx.c'`; then
  1000.     echo shar: \"'mailer/nptx.c'\" unpacked with wrong size!
  1001. fi
  1002. # end of 'mailer/nptx.c'
  1003. fi
  1004. if test -f 'mailer/pw.c' -a "${1}" != "-c" ; then 
  1005.   echo shar: Will not clobber existing file \"'mailer/pw.c'\"
  1006. else
  1007. echo shar: Extracting \"'mailer/pw.c'\" \(4604 characters\)
  1008. sed "s/^X//" >'mailer/pw.c' <<'END_OF_FILE'
  1009. X#ifndef lint
  1010. Xstatic char *sccsid = "@(#)pw.c    2.5 (smail) 9/15/87";
  1011. X#endif
  1012. X
  1013. X#include <stdio.h>
  1014. X#include <sys/types.h>
  1015. X#include <sys/stat.h>
  1016. X#include <pwd.h>
  1017. X#include "defs.h"
  1018. X#include <ctype.h>
  1019. X
  1020. Xchar *malloc();
  1021. Xvoid free();
  1022. X
  1023. Xtypedef struct pw_node pwlist;
  1024. X
  1025. Xstruct pw_node {
  1026. X    char *lname;            /* login name */
  1027. X    char *fname;            /* full name  */
  1028. X    int  uid;            /* user-id    */
  1029. X    char *home;            /* login name */
  1030. X    pwlist *vlink;            /* link to next item */
  1031. X};
  1032. X
  1033. Xpwlist *pwhead;        /* head of linked list */
  1034. Xpwlist *pwparse();    /* head of linked list */
  1035. X
  1036. X#define PNULL    ((pwlist *) 0)
  1037. X
  1038. Xchar *
  1039. Xpwfnam(user)
  1040. Xchar *user;
  1041. X{
  1042. X    pwlist *f;
  1043. X
  1044. X    /*
  1045. X    ** check for previously cached user
  1046. X    */
  1047. X
  1048. X    for(f=pwhead; f != NULL; f=f->vlink) {
  1049. X        if(strcmp(user, f->lname) == 0) {
  1050. X            return(f->fname);
  1051. X        }
  1052. X    }
  1053. X    /*
  1054. X    ** not found parse the password file
  1055. X    */
  1056. X
  1057. X    while((f=pwparse()) != PNULL) {
  1058. X        if(strcmp(user, f->lname) == 0) {
  1059. X            return(f->fname);
  1060. X        }
  1061. X    }
  1062. X    return(NULL);
  1063. X}
  1064. X
  1065. Xchar *
  1066. Xpwuid(uid)
  1067. Xint uid;
  1068. X{
  1069. X    pwlist *f;
  1070. X
  1071. X    /*
  1072. X    ** check for previously cached user
  1073. X    */
  1074. X
  1075. X    for(f=pwhead; f != NULL; f=f->vlink) {
  1076. X        if(uid == f->uid) {
  1077. X            return(f->lname);
  1078. X        }
  1079. X    }
  1080. X    /*
  1081. X    ** not found parse the password file
  1082. X    */
  1083. X
  1084. X    while((f=pwparse()) != PNULL) {
  1085. X        if(uid == f->uid) {
  1086. X            return(f->lname);
  1087. X        }
  1088. X    }
  1089. X    return(NULL);
  1090. X}
  1091. X
  1092. X#ifndef SENDMAIL
  1093. Xchar *
  1094. Xtilde(user)
  1095. Xchar *user;
  1096. X{
  1097. X    pwlist *f;
  1098. X
  1099. X    /*
  1100. X    ** check for previously cached user
  1101. X    */
  1102. X
  1103. X    for(f=pwhead; f != NULL; f=f->vlink) {
  1104. X        if(strcmp(user, f->lname) == 0) {
  1105. X            return(f->home);
  1106. X        }
  1107. X    }
  1108. X    /*
  1109. X    ** not found parse the password file
  1110. X    */
  1111. X
  1112. X    while((f=pwparse()) != PNULL) {
  1113. X        if(strcmp(user, f->lname) == 0) {
  1114. X            return(f->home);
  1115. X        }
  1116. X    }
  1117. X    return(NULL);
  1118. X}
  1119. X#endif /* not SENDMAIL */
  1120. X
  1121. Xchar *
  1122. Xfullname(gecos)
  1123. Xchar *gecos;
  1124. X{
  1125. X    static char fname[SMLBUF];
  1126. X    register char *cend;
  1127. X
  1128. X    (void) strcpy(fname, gecos);
  1129. X    if (cend = index(fname, ','))
  1130. X        *cend = '\0';
  1131. X    if (cend = index(fname, '('))
  1132. X        *cend = '\0';
  1133. X    /*
  1134. X    ** Skip USG-style 0000-Name nonsense if necessary.
  1135. X    */
  1136. X    if (isdigit(*(cend = fname))) {
  1137. X        if ((cend = index(fname, '-')) != NULL)
  1138. X            cend++;
  1139. X        else
  1140. X            /*
  1141. X            ** There was no `-' following digits.
  1142. X            */
  1143. X            cend = fname;
  1144. X    }
  1145. X    return (cend);
  1146. X}
  1147. X
  1148. Xpwlist *
  1149. Xpwparse()
  1150. X{
  1151. X    pwlist *f;
  1152. X    char *p, *name;
  1153. X    struct passwd *pwent, *getpwent();
  1154. X    unsigned int i;
  1155. X    static int pw_eof = 0;
  1156. X
  1157. X    if((pw_eof == 1)
  1158. X    || ((pwent = getpwent()) == (struct passwd *) NULL)) {
  1159. X        pw_eof = 1;
  1160. X        return(PNULL);
  1161. X    }
  1162. X    /*
  1163. X    ** Get an entry from the password file.
  1164. X    ** Parse relevant strings.
  1165. X    */
  1166. X    f = (pwlist *) malloc(sizeof(pwlist));
  1167. X    if(f == PNULL) return(PNULL);
  1168. X
  1169. X    f->vlink = pwhead;
  1170. X    pwhead   = f;
  1171. X    f->uid   = pwent->pw_uid;
  1172. X
  1173. X    i=strlen(pwent->pw_name)+1;
  1174. X    p = malloc(i);
  1175. X    if(p == NULL) return(PNULL);
  1176. X    f->lname = strcpy(p, pwent->pw_name);
  1177. X
  1178. X    i=strlen(pwent->pw_dir)+1;
  1179. X    p = malloc(i);
  1180. X    if(p == NULL) return(PNULL);
  1181. X    f->home  = strcpy(p, pwent->pw_dir);
  1182. X
  1183. X    name = fullname(pwent->pw_gecos);
  1184. X    i=strlen(name)+1;
  1185. X    p = malloc(i);
  1186. X    if(p == NULL) return(PNULL);
  1187. X    f->fname = strcpy(p, name);
  1188. X    return(f);
  1189. X}
  1190. X
  1191. X#ifdef FULLNAME
  1192. X/*
  1193. X** Resolve a full name to a login name.
  1194. X** Not too much smarts here.
  1195. X*/
  1196. X
  1197. Xchar *
  1198. Xres_fname(user)
  1199. Xregister char *user;
  1200. X{
  1201. X    long pos, middle, hi, lo;
  1202. X    static long pathlength = 0;
  1203. X    register char *s;
  1204. X    int c;
  1205. X    static FILE *file;
  1206. X    int flag;
  1207. X    char namebuf[SMLBUF], *path;
  1208. X    extern enum edebug debug;
  1209. X    extern char *fnlist;
  1210. X
  1211. X
  1212. X
  1213. XDEBUG("res_fname: looking for '%s'\n", user);
  1214. X
  1215. X    if(pathlength == 0) {    /* open file on first use */
  1216. X        if((file=fopen(fnlist, "r")) == NULL) {
  1217. X            DEBUG( "can't access %s.\n", fnlist);
  1218. X            pathlength = -1;
  1219. X        } else {
  1220. X            (void) fseek(file, 0L, 2);     /* find length */
  1221. X            pathlength = ftell(file);
  1222. X        }
  1223. X    }
  1224. X
  1225. X    if(pathlength == -1 ) return(NULL);
  1226. X
  1227. X    lo = 0;
  1228. X    hi = pathlength;
  1229. X    path = namebuf;
  1230. X
  1231. X    (void) strcpy( path, user );
  1232. X    (void) strcat( path, "\t" );
  1233. X
  1234. X    for( ;; ) {
  1235. X        pos = middle = ( hi+lo+1 )/2;
  1236. X        (void) fseek( file, pos, 0 );    /* find midpoint */
  1237. X        if (pos != 0)        /* to beginning of next line */
  1238. X            while( ( c=getc( file ) ) != EOF && c != '\n' );
  1239. X        for( flag = 0, s = path; flag == 0; s++ ) { /* match??? */
  1240. X            if ( *s == '\0' ) {
  1241. X                goto solved;
  1242. X            }
  1243. X            c = getc( file );
  1244. X            flag = lower( c ) - lower( *s );
  1245. X        } 
  1246. X        if (lo >= middle)        /* failure? */
  1247. X            return(NULL);
  1248. X
  1249. X        if(c != EOF && flag < 0)    /* close window */
  1250. X            lo = middle;
  1251. X        else 
  1252. X            hi = middle - 1;
  1253. X    }
  1254. X/* 
  1255. X** Now just copy the result.
  1256. X*/
  1257. Xsolved:
  1258. X    while(((c  = getc(file)) != EOF) && (c != '\t') && (c != '\n')) {
  1259. X        *path++ = c;
  1260. X    }
  1261. X
  1262. X    if(path == namebuf) {    /* NULL alias field */
  1263. X        return(NULL);
  1264. X    }
  1265. X
  1266. X    *path = '\0';
  1267. X    if((path = malloc((unsigned) strlen(namebuf)+1)) == NULL) {
  1268. X        return(NULL);    /* sorry, no memory */
  1269. X    }
  1270. X
  1271. X    (void) strcpy(path, namebuf);
  1272. X    return(path);
  1273. X
  1274. X}
  1275. X#endif    /* FULLNAME */
  1276. END_OF_FILE
  1277. if test 4604 -ne `wc -c <'mailer/pw.c'`; then
  1278.     echo shar: \"'mailer/pw.c'\" unpacked with wrong size!
  1279. fi
  1280. # end of 'mailer/pw.c'
  1281. fi
  1282. echo shar: End of archive 3 \(of 8\).
  1283. cp /dev/null ark3isdone
  1284. MISSING=""
  1285. for I in 1 2 3 4 5 6 7 8 ; do
  1286.     if test ! -f ark${I}isdone ; then
  1287.     MISSING="${MISSING} ${I}"
  1288.     fi
  1289. done
  1290. if test "${MISSING}" = "" ; then
  1291.     echo You have unpacked all 8 archives.
  1292.     rm -f ark[1-9]isdone
  1293. else
  1294.     echo You still need to unpack the following archives:
  1295.     echo "        " ${MISSING}
  1296. fi
  1297. ##  End of shell archive.
  1298. exit 0
  1299.