home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume1 / smail < prev    next >
Internet Message Format  |  1986-11-30  |  13KB

  1. From: ihnp4!amdcad!idi!bene!luke!steven
  2. Date: Thu, 6 Jun 85 09:45:43 pdt
  3. Newsgroups: mod.sources
  4. Subject: Smail - a smarter net mailer
  5. Reply-To: steven@luke.UUCP (Steven List)
  6. Organization: Benetics Corp, Mt.View, CA
  7. Keywords: mail USENET news
  8.  
  9. The following shar file contains the man page and source for a smarter
  10. mailer interface for use with networks.  It is based (as the copyright
  11. indicates) on the program nmail by Kim Chr. Madsen (diku!kimcm).  The
  12. program just didn't quite do it as it was.
  13.  
  14. The changes include allowing multiple destinations of various forms
  15. rather than the node and recipient arguments of the original.  Also, I
  16. wrote the man page.
  17.  
  18. This program works fine with Rnmail, Pnews, rn, readnews, and postnews.
  19. That is, it works with recmail!  Any comments would be welcome, since
  20. this is my first posting to the net.  This little goodie has allowed us
  21. here to make full use of the output of pathalias and to feel that we're
  22. becoming a real part of the network.
  23.  
  24. Steven
  25. --
  26.                                /-\  
  27. :-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:
  28. :            Steven List @ Benetics Corporation                         :
  29. :                        (415) 940-6300                                 :
  30. :            {cdp,idi,oliveb,sun,tolerant}!bene!luke!steven             :
  31. :-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:-:
  32.                                \-/                                       
  33.  
  34. ------------------------------ Cut Here ------------------------------
  35. #!/bin/sh
  36. # This is a shell archive, meaning:
  37. # 1. Remove everything above the #!/bin/sh line.
  38. # 2. Save the resulting text in a file.
  39. # 3. Execute the file with /bin/sh (not csh) to create the files:
  40. #    smail.c
  41. #    smail.1
  42. # This archive created: Wed Jun  5 17:34:05 1985
  43. export PATH; PATH=/bin:$PATH
  44. echo shar: extracting "'smail.c'" '(7702 characters)'
  45. if test -f 'smail.c'
  46. then
  47.     echo shar: over-writing existing file "'smail.c'"
  48. fi
  49. sed 's/^X//' << \SHAR_EOF > 'smail.c'
  50. X/*
  51. X * smail -- An interface to mail, made to handle 
  52. X *        mail via the UUCP-network. A network
  53. X *        connection database is kept in:
  54. X *          /usr/lib/uucp/paths
  55. X *        and is maintained with pathalias(1).
  56. X *
  57. X * call --  smail destination...
  58. X *            where destination may be:
  59. X *                recipient
  60. X *                recipient@system
  61. X *                recipient@system.MODE
  62. X *                system![system!...]recipient
  63. X *
  64. X * (c) 1985 by Kim Chr. Madsen
  65. X *           Datalogisk Institut (Institute of Datalogy)
  66. X *           University of Copenhagen.
  67. X *           {decvax,philabs,seismo}!mcvax!diku!kimcm
  68. X * modified by Steven M. List 6/85
  69. X *               Benetics Corporation
  70. X *             Mt. View, CA
  71. X *             {cdp,idi,oliveb,sun,tolerant}!bene!luke!steven
  72. X *
  73. X */
  74. X
  75. X#include <stdio.h>
  76. X
  77. X/* ------------------------------------------------------------ */
  78. X/* some globally useful defines                                 */
  79. X/* ------------------------------------------------------------ */
  80. X
  81. X#define    PATHS    "/usr/lib/uucp/paths"
  82. X#define MAIL    "/bin/mail"
  83. X#define    VERSION    "smail -- version 0.1 preliminary version."
  84. X#define    HOSTSZ    10
  85. X#define    PATHSZ    80
  86. X#define TRUE     1
  87. X#define FALSE     0
  88. X
  89. X/* ------------------------------------------------------------ */
  90. X/* some globals                                                 */
  91. X/* ------------------------------------------------------------ */
  92. X
  93. Xtypedef unsigned char boolean;
  94. X
  95. Xboolean    debug = FALSE;
  96. X
  97. X/* ------------------------------------------------------------ */
  98. X/* place to read path entries into                              */
  99. X/* ------------------------------------------------------------ */
  100. X
  101. Xstruct smail_entry {
  102. X    char    hostname[HOSTSZ+1];
  103. X    char    pathstr[PATHSZ]
  104. X};
  105. X
  106. Xextern char *getenv();
  107. X
  108. X/* ------------------------------------------------------------ */
  109. X/* do it here - NOW!                                            */
  110. X/* ------------------------------------------------------------ */
  111. X
  112. Xmain(argc, argv)
  113. Xint        argc;
  114. Xchar    *argv[];
  115. X{
  116. X    struct smail_entry t1;            /* work space for path entries    */
  117. X    FILE    *pathfile;                /* pathalias produced path file    */
  118. X    char    *paths = PATHS;            /* file name of path database    */
  119. X    char    *mail = MAIL;            /* path name of mailer to use    */
  120. X    char    *tmp;                    /* temporary pointer            */
  121. X    char    *host;                    /* destination host system        */
  122. X    char    *recipient;                /* destination user name        */
  123. X    char    *mailarg[32];            /* args to mail program            */
  124. X    char    narg = 0;                /* number of args to mail pgm    */
  125. X    boolean    found = FALSE;            /* true if node in path db        */
  126. X
  127. X    register char carg;                /* current command arg            */
  128. X    char    buf[BUFSIZ];            /* temporary buffer for dest    */
  129. X
  130. X    char    *calloc ();
  131. X
  132. X    /* ------------------------------------------------------------ */
  133. X    /* MAILER environment variable overrides definition             */
  134. X    /* ------------------------------------------------------------ */
  135. X
  136. X    if ((tmp = getenv("MAILER")) != NULL)
  137. X    {
  138. X        fprintf (stderr,"%s is requested as mail program\n",tmp);
  139. X        mail = tmp;
  140. X    }
  141. X
  142. X    /* ------------------------------------------------------------ */
  143. X    /* process command line options                                 */
  144. X    /* ------------------------------------------------------------ */
  145. X
  146. X    while(argc > 1 && argv[1][0] == '-')
  147. X    {
  148. X        argv++;
  149. X        argc--;
  150. X        switch(argv[0][1])
  151. X        {
  152. X            case 'd':    /* Just type some debugging information */
  153. X                debug = TRUE;
  154. X                break;
  155. X            case 'm':    /* Another mail program requested */
  156. X                argv++;
  157. X                argc--;
  158. X                if (argc > 1)
  159. X                {
  160. X                    mail = argv[0];
  161. X                    if (debug) printf ("Mail program = %s\n",mail);
  162. X                }
  163. X                else
  164. X                {
  165. X                    fprintf (stderr,"Mail program expected\n");
  166. X                    exit(1);
  167. X                }
  168. X                break;
  169. X            case 'p':    /* An alternative path database requested */
  170. X                argv++;
  171. X                argc--;
  172. X                if (argc > 1)
  173. X                {
  174. X                    paths = argv[0];
  175. X                    if (debug) printf ("Database = %s\n",paths);
  176. X                }
  177. X                else
  178. X                {
  179. X                    fprintf(stderr,"Alternate database expected\n");
  180. X                    exit(1);
  181. X                }
  182. X                break;
  183. X            default:
  184. X                fprintf (stderr, "Unknown option: %s\n", *argv);
  185. X        }
  186. X    }
  187. X
  188. X    /* ------------------------------------------------------------ */
  189. X    /* open the path database                                       */
  190. X    /* ------------------------------------------------------------ */
  191. X
  192. X    if (!(pathfile = fopen(paths, "r")))
  193. X    {
  194. X        fprintf (stderr,"cannot open %s\n",paths);
  195. X        exit(1);
  196. X    }
  197. X
  198. X    if (debug) printf ("%s\n", VERSION);
  199. X
  200. X    /* ------------------------------------------------------------ */
  201. X    /* for each destination on the command line,                    */
  202. X    /*   find the host and recipient names and create an arg to     */
  203. X    /*   the mailer                                                 */
  204. X    /* ------------------------------------------------------------ */
  205. X
  206. X    mailarg[narg] = calloc (1, strlen (mail) + 1);
  207. X    strcpy (mailarg[narg++], mail);
  208. X
  209. X    for (carg = 1; carg < argc; carg++)
  210. X    {
  211. X        fprintf (stderr, "checking arg #%d <%s>\n", carg, argv[carg]);
  212. X        if (argv[carg][0] == '\0' || argv[carg][0] == ' ') continue;
  213. X        strcpy (buf, argv[carg]);
  214. X        crackrecip (buf, &recipient, &host);
  215. X
  216. X        found = FALSE;
  217. X        while(!found &&
  218. X                fscanf(pathfile,"%s\t%[^\n]",t1.hostname,t1.pathstr)==2)
  219. X        {
  220. X            if (strncmp(t1.hostname, host, HOSTSZ) == 0)
  221. X            {
  222. X                mailarg[narg] = calloc (1, strlen (t1.pathstr) + 
  223. X                                    strlen (recipient) + 2);
  224. X                sprintf (mailarg[narg++], t1.pathstr, recipient);
  225. X                found = TRUE;
  226. X            }
  227. X        }
  228. X
  229. X        if (!found)
  230. X        {
  231. X            fprintf(stderr, "Sorry, no information about %s\n",host);
  232. X            mailarg[narg] = calloc (1, strlen (argv[carg]) + 1);
  233. X            strcpy (mailarg[narg++], argv[carg]);
  234. X        }
  235. X        fprintf (stderr, "Sending mail to %s\n",mailarg[narg-1]);
  236. X        rewind (pathfile);
  237. X    }
  238. X    (void) fclose(pathfile);
  239. X
  240. X    fprintf (stderr, "Sending mail to a total of %d destinations\n", narg-1);
  241. X
  242. X    if (narg <= 1)
  243. X    {
  244. X        fprintf(stderr, "Sorry, no destinations\n");
  245. X        if (debug)
  246. X        {
  247. X            printf("what?\n");
  248. X        }
  249. X    }
  250. X    else
  251. X    {
  252. X    /* ------------------------------------------------------------ */
  253. X    /* if debugging, log the command that WOULD be executed         */
  254. X    /* ------------------------------------------------------------ */
  255. X
  256. X        if (debug)
  257. X        {
  258. X            printf ("Mailcmd = %s",mail);
  259. X            for (carg = 0; carg < narg; carg++)
  260. X                printf (" %s", mailarg[carg]);
  261. X            printf ("\n");
  262. X        }
  263. X    /* ------------------------------------------------------------ */
  264. X    /* otherwise, do it right here and now                          */
  265. X    /* ------------------------------------------------------------ */
  266. X
  267. X        else
  268. X        {
  269. X            execv (mail, mailarg);
  270. X            perror ("returned from execv");
  271. X            fprintf (stderr, "Cannot execv %s\n",mail);
  272. X            exit(1);
  273. X        }
  274. X    }
  275. X}
  276. Xcrackrecip (buf, recip, host)
  277. Xregister char *buf;
  278. Xregister char **recip;
  279. Xregister char **host;
  280. X{
  281. X#    include    <sys/utsname.h>
  282. X
  283. X    register char *sp;
  284. X    register char *ep;
  285. X
  286. X    static struct utsname name;
  287. X
  288. X    char    *strrchr ();
  289. X
  290. X    if (debug)
  291. X    {
  292. X        printf ("Cracking %s for host and recip\n", buf);
  293. X    }
  294. X
  295. X    if (sp = strrchr (buf, '@'))    /* internet style                */
  296. X    {
  297. X        sp++;                        /* start of node name            */
  298. X        if (ep = strrchr (sp, '.'))    /* path type (should be UUCP    */
  299. X        {
  300. X            *ep = '\0';
  301. X        }
  302. X        *host = sp;
  303. X
  304. X        *(sp-1) = '\0';
  305. X
  306. X        if (sp = strrchr (buf, '!'))    /* multiple nodes            */
  307. X        {
  308. X            *recip = sp + 1;
  309. X        }
  310. X        else
  311. X        {
  312. X            *recip = buf;
  313. X        }
  314. X        if (debug)
  315. X        {
  316. X            printf ("INTERNET style: r = %s  h = %s\n",
  317. X                *recip, *host);
  318. X        }
  319. X    }
  320. X    else if (sp = strrchr (buf, '!'))    /* uucp style                */
  321. X    {
  322. X        *recip = sp + 1;
  323. X        *sp = '\0';
  324. X            
  325. X        if (sp = strrchr (buf, '!'))    /* multiple nodes            */
  326. X        {
  327. X            *host = sp + 1;
  328. X        }
  329. X        else
  330. X        {
  331. X            *host = buf;
  332. X        }
  333. X        if (debug)
  334. X        {
  335. X            printf ("UUCP style: r = %s  h = %s\n",
  336. X                *recip, *host);
  337. X        }
  338. X    }
  339. X    else                                /* assume local - no host    */
  340. X    {
  341. X        *recip = buf;
  342. X        if (uname (&name) == -1)
  343. X        {
  344. X            perror ("uname failure");
  345. X            exit (99);
  346. X        }
  347. X        *host = name.nodename;
  348. X        if (debug)
  349. X        {
  350. X            printf ("UNKNOWN style: r = %s  h = %s\n",
  351. X                *recip, *host);
  352. X        }
  353. X    }
  354. X
  355. X    return;
  356. X}
  357. SHAR_EOF
  358. if test 7702 -ne "`wc -c 'smail.c'`"
  359. then
  360.     echo shar: error transmitting "'smail.c'" '(should have been 7702 characters)'
  361. fi
  362. echo shar: extracting "'smail.1'" '(1981 characters)'
  363. if test -f 'smail.1'
  364. then
  365.     echo shar: over-writing existing file "'smail.1'"
  366. fi
  367. sed 's/^X//' << \SHAR_EOF > 'smail.1'
  368. X.TH "smail" "1" "Benetics Local"
  369. X.fi
  370. X.ad b
  371. X.SH NAME
  372. Xsmail - send mail using various addressing schemes
  373. X.SH SYNOPSIS
  374. Xsmail [ -d ] [ -m \fIaltmailer\fR ] [ -p \fIaltpathdb\fR ]
  375. X.br
  376. X      \fIdestination\fR...
  377. X.SH DESCRIPTION
  378. XSmail is a veneer over the standard /bin/mail program found in UNIX
  379. XSystem III systems.  It accepts destination specifications in several
  380. Xdifferent formats, allowing its use between various mail packages and
  381. Xthe mailer.
  382. X.SS Options
  383. X.IP "-d" 16
  384. XThe -d option turns on the limited debugging facility built into the
  385. Xmailer.  In debug mode, the mailer does not actually mail anything, but
  386. Xtells you what it would do if it did do it.
  387. X.IP "-m \fIaltmailer\fR" 16
  388. XThe -m option specifies an optional mailer to use.  This supersedes the
  389. Xdefault mailer in the program ("/bin/mail") and the
  390. Xenvironment variable MAILER.  The environment variable MAILER may be
  391. Xused to define an alternate mailer in the absence of the -m option.
  392. X.IP "" 16
  393. XThis option also provides some means of debugging.  The mailer may be
  394. Xdefined to be /bin/echo or some other program or shell script.
  395. X.IP "-p \fIaltpathdb\fR" 16
  396. XThe -p option allows the specification of an alternate path file.  The
  397. Xdefault path file is "/usr/lib/uucp/paths".  The path file is the output
  398. Xof program pathalias (produced by Peter Honeyman), and contains one
  399. Xentry for each known node on the network.
  400. X.SS Arguments
  401. X.IP \fIdestination\fR 16
  402. XThe destination(s) specified may take one of the following forms:
  403. X.RS 22
  404. X.P
  405. Xperson
  406. X.P
  407. Xnode![node!...]person
  408. X.P
  409. Xperson@node
  410. X.P
  411. Xnode![node!...]person@node
  412. X.P
  413. Xperson@node.NET
  414. X.P
  415. Xnode![node!...]person@node.NET
  416. X.RE
  417. X.IP "" 16
  418. Xwhere node is a system node name on the network and person is the login
  419. Xname of the addressee.  256 destinations may be specified.
  420. XThe mail program will be invoked only once for all destinations
  421. Xspecified.
  422. X.SH FILES
  423. X.IP "/usr/lib/uucp/paths" 20
  424. XPath file produced by pathalias.
  425. X.SH "SEE ALSO"
  426. Xpathalias(1), Pnews(1), Rnmail(1), rn(1), postnews(1), readnews(1)
  427. SHAR_EOF
  428. if test 1981 -ne "`wc -c 'smail.1'`"
  429. then
  430.     echo shar: error transmitting "'smail.1'" '(should have been 1981 characters)'
  431. fi
  432. #    End of shell archive
  433. exit 0
  434.  
  435.  
  436.  
  437.