home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume9 / elm2 / part15 < prev    next >
Encoding:
Internet Message Format  |  1987-03-10  |  50.9 KB

  1. Subject:  v09i015:  ELM Mail System, Part15/19
  2. Newsgroups: mod.sources
  3. Approved: rs@mirror.TMC.COM
  4.  
  5. Submitted by: Dave Taylor <hplabs!taylor>
  6. Mod.sources: Volume 9, Issue 15
  7. Archive-name: elm2/Part15
  8.  
  9. #! /bin/sh
  10. # This is a shell archive.  Remove anything before this line,
  11. # then unpack it by saving it in a file and typing "sh file".
  12. # If this archive is complete, you will see the message:
  13. #        "End of archive 15 (of 19)."
  14. # Contents:  doc/Alias.guide doc/Config.guide src/addr_utils.c
  15. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  16. echo shar: Extracting \"doc/Alias.guide\" \(16382 characters\)
  17. if test -f doc/Alias.guide ; then 
  18.   echo shar: Will not over-write existing file \"doc/Alias.guide\"
  19. else
  20. sed "s/^X//" >doc/Alias.guide <<'END_OF_doc/Alias.guide'
  21. X.PH ""
  22. X\"
  23. X\"  A guide to the ELM alias system and so on.
  24. X\"  format with 'troff -mm Config.guide > Config.format'
  25. X\"  or something similar.
  26. X\"  (C) Copyright 1986 Dave Taylor
  27. X\"
  28. X\"  Last modification: January 19th, 1987
  29. X\"
  30. X.SA 1
  31. X.nr Hy 1
  32. X.nr Pt 1
  33. X.nr Pi 8
  34. X.lg
  35. X.HM 1 1
  36. X.rs
  37. X.ds HF 3  3  
  38. X.ds HP 12 12 10 10 10
  39. X.PF ""
  40. X.ce 99
  41. X.sp 5
  42. X.ps 20
  43. X\fBELM Alias Users Guide\fR
  44. X.sp 4
  45. X.ps 12
  46. X\fIWhat aliases are and how to use them
  47. Xin the \fBElm\fP mail system\fR
  48. X.sp 2
  49. XDave Taylor
  50. X.sp
  51. XHewlett-Packard Laboratories
  52. X1501 Page Mill Road
  53. XPalo Alto CA
  54. X94304
  55. X.sp 
  56. Xemail: taylor@hplabs.HPL.HP.COM or hplabs!taylor
  57. X.sp 7
  58. X.ps 18
  59. X\fB\(co\fR\s12 Copyright 1986, 1987 by Dave Taylor
  60. X.ps 10
  61. X.SK
  62. X.sp 5
  63. X.ps 14
  64. X\fBElm Alias Users Guide\fR
  65. X.PH "'Alias Users Guide''version 1.5'
  66. X.PF "''Page \\\\nP''"
  67. X.nr P 1
  68. X.sp
  69. X.ps 10
  70. X(version 1.5)
  71. X.sp 2
  72. XDave Taylor
  73. X.sp
  74. XHewlett-Packard Laboratories
  75. X1501 Page Mill Road
  76. XPalo Alto CA
  77. X94304
  78. X.sp 
  79. Xemail: taylor@hplabs.HPL.HP.COM or hplabs!taylor
  80. X.sp 2
  81. X\*(DT
  82. X.ce 0
  83. X.sp 3
  84. X.P
  85. XThis document is intended as a supplement to the \fIElm Users Guide\fR
  86. Xand is only of interest to those users desiring more knowledge
  87. Xabout how aliases work and how to create strange and exciting
  88. Xaliases for their systems (alright, so it's not \fIthat\fR exciting!)
  89. X.sp
  90. X.P
  91. XThis document is broken up into the following sections;
  92. Xuser aliases,
  93. Xgroup aliases,
  94. Xsystem aliases,
  95. Xediting and installing new aliases,
  96. Xthe machine routing database,
  97. Xthe domain routing database,
  98. Xand general warnings and other chitchat.
  99. X.sp
  100. X.H 1 "User Aliases"
  101. XThe most simple sort of aliases in the \fBElm\fR system are individual
  102. Xuser aliases.  These are made up of three parts;
  103. X.nf
  104. X
  105. X    \fIaliasname list\fR : \fIusername\fR : \fIaddress\fR
  106. X
  107. X.fi
  108. XWhere the \fIaliasname list\fR is either a single aliasname\*F
  109. X.FS
  110. XPlease see the appendix for a full definition of what exactly an
  111. Xaliasname consists of.
  112. X.FE
  113. Xor a list of aliasnames separated by commas.
  114. X.P
  115. X\fIUsername\fR is used to indicate the full "real name" of the user.  
  116. XFor example, if you had an alias for "dat" to get to me, the 
  117. X\fIusername\fR field would contain "Dave Taylor" or perhaps "Dave Taylor at HP"
  118. Xor some other permutation.  Versions 1.2a and later of the \fBElm\fR
  119. Xsystem use this information to add to the addresses of outbound mail
  120. Xin the interest of more readable addresses.  It is recommended that this
  121. Xfield contain peoples names only.
  122. X.P
  123. X\fIAddress\fR is either the users full electronic mail address or, if
  124. Xthe machine routing database is installed, the minimum address needed
  125. Xto specify the destination.  For example, say our routing database
  126. Xcontained information on how to get to machine "hp-sdd" and I wanted
  127. Xto have an address for my friend Ken there - I could have his address
  128. Xspecified as simply "ken@hp-sdd" (or alternatively "hp-sdd!ken" since
  129. Xthe two are functionally equivalent).
  130. X.sp
  131. X.P 0
  132. XLet's get on to some examples, shall we?
  133. X.sp
  134. XConsider this excerpt from my own \fI.alias_text\fR file;
  135. X.nf
  136. X
  137. Xwunder,walter : Walter Underwood: wunder@hpcea
  138. Xlaubach       : Mark Laubach    : laubach@hpcea
  139. Xmary          : Mary Hsia-Coron : hsia@hpindla
  140. Xdecot         : Dave Decot      : decot@hpda
  141. X     
  142. Xjeff          : Jeff Wu         : hpcnoe!j_wu
  143. Xdave          : Dave Barrett    : hpcnof!d_barrett
  144. X
  145. X.fi
  146. XNote that the alias for Walter Underwood has two \fIaliasnames\fR associated
  147. Xwith it, \fIwunder\fR and \fIwalterf\R.  Also notice that the first four aliases
  148. Xuse the Internet style naming convention (\fIuser@machine\fR) but the last two
  149. Xuse the UUCP style convention (\fImachine!user\fR).  In this context it is
  150. Xindependent.
  151. X.P
  152. XThe only time when it \fIdoes\fR make a difference which notation you
  153. Xuse is if you have to specify more than the machine that the user is
  154. Xreceiving mail on.  That is, say we have a friend who receives mail at
  155. Xa machine called \fBtwinkie\fR and our best connection is through Georgia
  156. XInstitute of Technology (``gatech'')...Our alias for them could be;
  157. X.nf
  158. X
  159. X  buddy         : Our friend      : gatech!twinkie!buddy
  160. X
  161. Xor
  162. X
  163. X  buddy2        : Our friend      : gatech!buddy@twinkie
  164. X
  165. X.fi
  166. Xbut not;
  167. X.nf
  168. X
  169. X  buddy         : Our friend      : buddy@twinkie@gatech
  170. X
  171. X.fi
  172. X(however, buddy%twinkie@gatech \fIwill\fR also work, but that's far
  173. Xtoo bizarre a notation to be recommended!!) (besides there's no
  174. Xguarantee that "gatech" will like it, nor the "buddy2" alias above!)
  175. X.P
  176. XAnyway, suffice to say that if you must specify any sort of route
  177. Xthat you should use the uucp notation as much as possible to ensure
  178. Xthat the system expands the correct machine name.
  179. X.sp
  180. X.H 1 "Group Aliases"
  181. XAfter the confusion of user aliases, group aliases are even more 
  182. Xfun!  For the most part the notation is very similar;
  183. X.nf
  184. X
  185. X    \fIaliasname list\fR : \fIgroupname\fR : \fIlist of people\fR
  186. X
  187. X.fi
  188. XWhere \fIaliasname list\fR and \fIgroupname\fR are exactly equivalent
  189. Xto the corresponding fields in user aliases.
  190. X.P
  191. XThe interesting part is the \fIlist of people\fR field!  This
  192. Xfield is actually in the same notation as the aliasname list,
  193. Xso it's not quite as strange as I've lead you to believe.
  194. XIt's best to illustrate by example;
  195. X.nf
  196. X
  197. Xfriends, mypals, gang : The Gang of Six : joe, larry, mary, joanna,
  198. X                      nancy, michael
  199. X
  200. X.fi
  201. X(Notice that you can continue onto as many lines as you'd like so
  202. Xlong as each additional line start with either a \s8SPACE\s10 or a \s8TAB\s10
  203. Xcharacter)
  204. X.P
  205. XThe significant limitation with group aliases is that each of the
  206. Xpeople in the list must be a \fIpreviously defined aliasname in either the
  207. Xexisting alias file or the system alias file\fR or a valid destination
  208. Xon the current machine.
  209. X.P
  210. XWhat does this mean?  This means that the following excerpt from an
  211. Xalias file;
  212. X.nf
  213. X
  214. Xhawaii : The Hawaiian Twins : joe@\s8RIT-CS.ARPA\s10, maoa
  215. Xmaoa   : Maoa Lichtenski Jr : maoa@Hawaii.cs.uh.\s8ARPA\s10
  216. X
  217. X.fi
  218. Xwill fail for two reasons - not only does the group \fIlist of people\fR
  219. Xcontain a complex address, but it also contains an aliasname that is 
  220. Xdefined \fIlater\fR in the \fI.alias_text\fR file!  \fB** \s8BEWARE\s10!!! **\fR
  221. X.P
  222. XThe correct way to have the previous alias in the file is to have it like;  
  223. X.nf
  224. X
  225. Xjoe    : Joe Lichtenski     : joe@\s8RIT-CS\s10
  226. Xmaoa   : Maoa Lichtenski Jr : maoa@Hawaii
  227. Xhawaii : The Hawaiian Twins : joe, maoa
  228. X
  229. X.fi
  230. Xwhich will then work correctly.
  231. X.P 0
  232. XThis isn't too hard now, is it?
  233. X.sp
  234. XFortunately, while this seems pretty tough, when you run \fInewalias\fR
  235. Xto install the new aliases, it will give you relevent and meaningful
  236. Xerror messages that will help you fix the list up correctly!
  237. X.sp
  238. X.H 1 "System Aliases"
  239. XSystem aliases are functionally equivalent to the individual \fBElm\fR 
  240. Xalias lists each \fBElm\fR user has (both user aliases and group aliases) 
  241. Xbut are "read only" for everyone but the \fBElm\fR administrator.  The 
  242. Xformat of the file is identical to the users file, and the only difference is
  243. Xthat this file is expected to be located in the directory that contains
  244. Xthe \fIsystem_hash_file\fR and \fIsystem_data_file\fR files (see the
  245. X\fIElm Configuration Guide\fR for more details on these variables).
  246. X.P
  247. XSimply create a \fI.alias_text\fR file in the specific directory
  248. Xas you would a normal file, and install it the same way (see the
  249. Xfollowing section for more details on that).  
  250. X.P
  251. XVoila!!
  252. X.sp
  253. X.H 1 "Editing and Installing New Aliases"
  254. XTo install new aliases, you need merely to create, or modify,
  255. Xyour \fI.alias_text\fR file in your home directory until you're
  256. Xsatisfied with it and it meets the requirements stated above.
  257. XYou can then try to install it with the command;
  258. X.nf
  259. X
  260. X    $ \fBnewalias\fR
  261. X
  262. X.fi
  263. Xwhich will either report back the number of aliases installed into 
  264. Xthe system or will report errors indicative of the changes that
  265. Xthe program expects before it can accept the alias list.
  266. X.P
  267. XNote that blank lines are no problem and that comments are not only
  268. Xallowed but actually encouraged, and must have `\fB#\fR' as the first
  269. Xcharacter of each comment line.
  270. X.sp
  271. XFinally, if you find that you're hitting the ``Too many aliases'' error, 
  272. Xthen you'll need to reconfigure the entire \fBElm\fR system (again,
  273. Xsee the \fIElm Configuration Guide\fR).
  274. X.sp
  275. X.H 1 "The Hostname Routing Database"
  276. XFloating about on the various networks is a rather nifty program by
  277. Xa number of people, including Peter Honeyman and Steve Bellovin, 
  278. Xcalled \fIpathalias\fR.  What this incredibly handy program does is 
  279. Xtake the strange postings in netnews groups like "news.map" and massage
  280. Xthem into a file of the form;
  281. X.nf
  282. X
  283. X  \fIhostname\fR    <tab>    \fIaddress\fR
  284. X
  285. X.fi
  286. Xwhich is then sorted alphabetically and stored in the file
  287. Xpointed to by \fIpathfile\fR (guess where to look for more information!)
  288. Xfor \fBElm\fR to use.
  289. X.P
  290. XIf you don't have the program, or don't want to use it, you can 
  291. Xsimulate this file by listing machines in the same format.  The
  292. Xexact format expected is;
  293. X.nf
  294. X
  295. X  \fIhostname\fR<tab>\fImachine-address\fR
  296. X
  297. X.fi
  298. Xwhere \fIhostname\fR is a limited identifier (no special characters) and
  299. Xmachine-address MUST contain the sequence `%s' (and consequently
  300. Xany other percent signs that appear in the address must be paired)
  301. Xso that the call in the program ``sprintf(buffer, machine-address, username)''
  302. Xwill generate a valid return address.
  303. X.P 0
  304. XBy way of example, here are a few entries from my own file;
  305. X.nf
  306. X
  307. X \s8HPL\s10    hplabs!%s
  308. X \s8PARC\s10   hplabs!%s@Xerox.\s8PA.COM\s10
  309. X amc-hq     hplabs!%s@\s8AMC-HQ.ARPA\s10
  310. X imsss        hplabs!%s%%\s8IMSSS@SU-AI.ARPA\s10
  311. X infopro    hpfcla!ihnp4!astrovax!infopro!%s
  312. X interleaf  hpfcdc!hpda!sun!interleaf!%s
  313. X jpl-vax    hplabs!%s@jpl-vax
  314. X
  315. X.fi
  316. XAs you can see, the addresses can get pretty complicated!!  In fact
  317. Xit's due purely to the complication that a database file of this
  318. Xsort can be so wonderful!!
  319. X.sp
  320. XIf you'd like further information on the pathalias program, try
  321. Xkeeping track of the entries in the netnews group \fImod.sources\fR - 
  322. Xit's posted about once a year or so...
  323. X.sp
  324. X.H 1 "The Domain Routing Database"
  325. XOne of the more interesting features of the 3.2 and above
  326. X\fBElm\fR mailer is the domain routing database.  This is
  327. Xthe same database (in the same strange format) as used by
  328. Xthe most recent version of the \fIuumail\fR program.
  329. X.P
  330. XIn a nutshell, the file contains information of the form;
  331. X.nf
  332. X
  333. X   \fIdomain\fR   \fIpathtogateway\fR  \fIrewrite-template\fR
  334. X
  335. X.fi
  336. XThe \fIdomain\fR field must begin with a leading `.' and
  337. Xshould be ordered in the same notation as the standard
  338. Xdomain information (that is, "\s8.HP.COM\s10" not "\s8.COM.HP\s10").
  339. X.P
  340. X\fIPathtogateway\fR is routing information on how to get
  341. Xto the particular gateway that this domain expects, and
  342. Xalways is a machine/host name (to be found in the pathalias
  343. Xdatabase, see the previous section) preceeded by a `>' 
  344. Xcharacter.
  345. X.P
  346. X\fIRewrite-template\fR is the most interesting of the
  347. Xthree, and is akin to a printf string for C.  The 
  348. Xchanges are that instead of `%s' `%d' and so on, the
  349. Xactual "percent" values represent various parts of 
  350. Xthe address, namely;
  351. X.nf
  352. X
  353. X    Symbol        Represents
  354. X    ------          ----------
  355. X      %U        The username in the To: address
  356. X      %N        The remote machine name
  357. X      %D        %N + domain information 
  358. X      %R        path to %N from pathalias
  359. X      %P        \fIpathtogateway\fR entry
  360. X      %S        Obsolete!
  361. X      %%        The `%' character
  362. X
  363. X.fi
  364. Xwith this very intuitive setup, let's look at a few entries 
  365. Xfrom the domains database and see how they work;
  366. X.nf
  367. X
  368. X.ps 8
  369. X  .EUR.UUCP,,,%R!%U
  370. X  .ATT.UUCP,>\s10ihnp4\s8,,%P!%D!%U
  371. X  .HP.COM,,,%R!%U
  372. X  .UUCP,,,%R!%U
  373. X  .COM,>\s10hplabs\s8,,%P!%U@%D
  374. X  .CSNET,>\s10hplabs\s8,,%P!%U%%%D@CSNET-RELAY.ARPA
  375. X  .ARPA,>\s10hplabs\s8,,%P!%U@%D
  376. X.ps 10
  377. X
  378. X.fi
  379. X(Note the presence of a third field that is always null.  This is
  380. Xfor compatability with the "uumail" program, but this field is
  381. Xnow always \fI\s8NULL\s10\fR)
  382. X.P
  383. XTo see how it all works, let's suppose that we want to send a message
  384. Xto "jad@Purdue.\s8ARPA\s10".  This would break down into the following fields:
  385. X.nf
  386. X
  387. X    %U = jad
  388. X    %N = Purdue
  389. X    %D = Purdue.\s8ARPA\s10
  390. X      
  391. X.fi
  392. XWhen the \fBelm\fR program matches the ".\s8ARPA\s10" entry
  393. X.nf
  394. X
  395. X  .\s8ARPA\s10,>hplabs,,%P!%U@%D
  396. X
  397. X.fi
  398. Xthe other fields instantiated would be:
  399. X.nf
  400. X
  401. X    %P = <path to hplabs>
  402. X  template = %P!%U@%D
  403. X
  404. X.fi
  405. XAs is hopefully obvious, if our path to hplabs was "hpcnoe!hplabs" then
  406. Xthe fully expanded address would be;
  407. X.nf
  408. X
  409. X    hpcnoe!hplabs!jad@Purdue.\s8ARPA\s10
  410. X
  411. X.fi
  412. XAnd so on.  
  413. X.sp
  414. X.P
  415. XWhat does this mean to the average user?  It means that you can
  416. Xfor the most part send mail to people on different gateways by
  417. Xsimply using their full domain information, so that mail to 
  418. Xaddresses like "Jack@\s8MIT.MIT.EDU\s10" will work, and mail 
  419. Xto "SueAnn@\s8BBN.MAILNET\s10"
  420. Xwill work and so on!!
  421. X.sp
  422. X.H 1 "Other Stuff not Covered Yet"
  423. XProbably the biggest question you have in your mind right now is
  424. X"But how the heck does this relate to the 'ole \fIBerkeley Mail\fR
  425. Xaliases and the snazzo \fIsendmail\fR alias system??"  Well,
  426. Xrest assured, \fIsendmail\fR fans, that if you \fIreally\fR want to have
  427. Xyour aliases down in the transport you can.  No problem.  All you'll
  428. Xneed to do is to turn off the address validation routine in \fBElm\fR
  429. X(I'm not even going to bother to tell you where to look for this one!!).
  430. X.P
  431. XFor those \fIBerkeley Mail\fR fanatics out there, you can translate your 
  432. Xaliases into the format that \fBElm\fR wants by running them
  433. Xthrough the \fIawk\fR script listed in Appendix Two.
  434. X.sp
  435. X.P
  436. XFinally, if you have any problems or questions, try looking in 
  437. Xthe \fInewalias\fR manual entry, or dropping me a line at the
  438. X"usual" email address (ask your administrator!).
  439. X.SK
  440. X.ce 99
  441. XAppendix One
  442. X
  443. XA BNF of the Alias File Grammar
  444. X.ce 0
  445. X.sp 2
  446. XIn this listing, items in <> brackets are non-terminals, items in {}
  447. Xare optional, and items in \fBbold face\fR are terminals.
  448. X.sp 2
  449. X.nf
  450. X
  451. X<alias_file>  ::=  <line> { <alias_file> }
  452. X
  453. X<line>          ::=  <comment> | <empty> | <alias>
  454. X
  455. X<comment>     ::=  .. any sequence of characters starting with '#' ..
  456. X
  457. X<empty>          ::=  .. an empty line ..
  458. X
  459. X<alias>          ::=  <user alias> | <group alias>
  460. X
  461. X<user alias>  ::=  <aliaslist> \fB:\fR { <comment> \fB:\fR } 
  462. X           {<whitespace>} <address>
  463. X
  464. X<group alias> ::=  <aliaslist> \fB:\fR { <comment> \fB:\fR } 
  465. X           {<whitespace>} <list of addresses>
  466. X
  467. X<aliaslist>   ::=  <aliasname> { \fB,\fR <aliaslist> }
  468. X
  469. X<aliasname>   ::=  <alpha-char> { <sequence-of-chars> }
  470. X
  471. X<comment>     ::=  .. anything other than ":" ..
  472. X
  473. X<address>     ::=  <username> | <arpa-address> | <uucp-address> | 
  474. X           <complex-address>
  475. X
  476. X<list-of-addresses> ::= <aliasname> { \fB,\fR <whitespace> } 
  477. X            { <list-of-addresses> }
  478. X
  479. X<username>    ::=  .. any valid mailbox name on the system ..
  480. X
  481. X<arpa-address> ::= <username> ( \fB@\fR <hostname> | <postfix> )
  482. X
  483. X<hostname>    ::=  .. any legal host machine name ..
  484. X
  485. X<uucp-address> ::= <hostname> \fB!\fR <username>
  486. X
  487. X<complex-address> ::= <prefix> ( <uucp-address> | <arpa-address> )
  488. X
  489. X<prefix>      ::= <hostname> \fB!\fR { <prefix> }
  490. X
  491. X<postfix>     ::= \fB%\fR <hostname> { <postfix> } \fB@\fR 
  492. X          <hostname>
  493. X
  494. X<sequence-of-chars> ::= .. any characters other than space, tab, 
  495. X                   return, or colon ..
  496. X
  497. X<whitespace> ::= .. space, tab or newline followed by space or tab ..
  498. X
  499. X.fi
  500. X.SK
  501. X.ce 99
  502. XAppendix Two
  503. X
  504. XAn AWK Script for 
  505. XTranslating Aliases from a \fIBerkeley Mail\fR
  506. X".mailrc" File to an \fIElm\fR ".alias_text" File
  507. X.ce 0
  508. X.sp 2
  509. X.nf
  510. X.ce
  511. X-------------------------------------------------------------------
  512. X
  513. XBEGIN { print "# ELM alias_text file, from a .mailrc file..." 
  514. X    print ""
  515. X      }
  516. X
  517. Xnext_line == 1 { 
  518. X    next_line = 0;
  519. X        group = ""
  520. X    for (i = 1; i <= NF; i++) {
  521. X      if (i == NF && $i == "\\\\") sep = ""
  522. X      else                       sep = ", "
  523. X      if ($i == "\\\\") {
  524. X        group = sprintf("%s,", group)
  525. X        next_line = 1;
  526. X      }
  527. X      else if (length(group) > 0)
  528. X        group = sprintf("%s%s%s", group, sep, $i);
  529. X      else
  530. X        group = $i;
  531. X      }
  532. X      print "\\t" group
  533. X    }
  534. X$1 ~ /[Aa]lias|[Gg]roup/ { 
  535. X    if ( NF == 3)
  536. X      print $2 " : user alias : " $3;
  537. X    else {
  538. X      group = ""
  539. X      for (i = 3; i <= NF; i++) {
  540. X        if (i == NF && $i == "\\\\") sep = ""
  541. X        else        sep = ", "
  542. X    
  543. X        if ($i == "\\\\") {
  544. X           group = sprintf("%s,", group)
  545. X           next_line = 1;
  546. X        }
  547. X        else if (length(group) > 0) 
  548. X           group = sprintf("%s%s%s", group, sep, $i);
  549. X        else
  550. X           group = $i;
  551. X        }
  552. X        print $2 " : group alias : " group;
  553. X      }
  554. X     }
  555. X
  556. X.ce
  557. X-------------------------------------------------------------------
  558. X.fi
  559. X.P
  560. XNote: this script is contained in the release under the name 
  561. X"mailrc.awk" in the utilities directory "utils".
  562. END_OF_doc/Alias.guide
  563. if test 16382 -ne `wc -c <doc/Alias.guide`; then
  564.     echo shar: \"doc/Alias.guide\" unpacked with wrong size!?
  565. fi
  566. # end of overwriting check
  567. fi
  568. echo shar: Extracting \"doc/Config.guide\" \(15488 characters\)
  569. if test -f doc/Config.guide ; then 
  570.   echo shar: Will not over-write existing file \"doc/Config.guide\"
  571. else
  572. sed "s/^X//" >doc/Config.guide <<'END_OF_doc/Config.guide'
  573. X.PH ""
  574. X\"
  575. X\"  A guide to the configuration of the Elm mail system
  576. X\"  format with 'troff -mm Config.guide > Config.format'
  577. X\"  or something similar.
  578. X\"  (C) Copyright 1986 Dave Taylor
  579. X\"
  580. X\"  Last modification: January 19th, 1987
  581. X\"
  582. X.SA 1
  583. X.nr Hy 1
  584. X.nr Pt 1
  585. X.nr Pi 8
  586. X.lg
  587. X.HM 1 1
  588. X.rs
  589. X.ds HF 3  3
  590. X.ds HP 12 12 10 10 10
  591. X.PF ""
  592. X.ce 99
  593. X.sp 13
  594. X.ps 20
  595. X\fBElm Configuration Guide\fR
  596. X.sp 4
  597. X.ps 12
  598. X\fIHow to install and customize the Elm mail system\fR
  599. X.sp 2
  600. XDave Taylor
  601. X.sp
  602. XHewlett-Packard Laboratories
  603. X1501 Page Mill Road
  604. XPalo Alto CA
  605. X94304
  606. X.sp 
  607. Xemail: taylor@hplabs.HPL.HP.COM or hplabs!taylor
  608. X.sp 7
  609. X.ps 18
  610. X\fB\(co\fR\s12 Copyright 1986,1987 by Dave Taylor
  611. X.ps 10
  612. X.SK
  613. X.sp 5
  614. X.ps 14
  615. X\fBElm Configuration Guide\fR
  616. X.PH "'Elm Configuration Guide''version 1.5'
  617. X.PF "''Page \\\\nP''"
  618. X.nr P 1
  619. X.sp
  620. X.ps 10
  621. X(version 1.5)
  622. X.sp 2
  623. XDave Taylor
  624. X.sp
  625. XHewlett-Packard Laboratories
  626. X1501 Page Mill Road
  627. XPalo Alto CA
  628. X94304
  629. X.sp 
  630. Xemail: taylor@hplabs.HPL.HP.COM or hplabs!taylor
  631. X.sp 2
  632. X\*(DT
  633. X.ce 0
  634. X.sp 3
  635. X.P
  636. XThis document is intended as a supplement to the \fIElm Users Guide\fR
  637. Xand is only of interest to those people at a site either installing
  638. Xor maintaining the source code to the \fBElm\fR mail system.
  639. X.sp 2
  640. X.P
  641. XIt's \fIhighly\fR recommended that installation be done by using the
  642. X\fIConfigure.sh\fR script supplied with the system.  Please see the
  643. Xfile \fIInstructions\fR for further information.
  644. X.sp 2
  645. XThe remainder of this document will discuss the 
  646. Xoptions available via direct editing of various files and
  647. Xparameters.  As indicated above, 99.9% of the sites that install
  648. X\fBElm\fR should find the \fIConfigure.sh\fR script sufficient.
  649. X.sp 2
  650. X.P
  651. XThe first thing that needs to be decided when you're ready to install
  652. Xthe program is what sort of operating system you're running on...
  653. Xcurrently the choices are;
  654. X.VL 14 3
  655. X.LI "System V"
  656. XThis is the default configuration, and should work on all Bell 
  657. XSystem V Unix
  658. X.FS ' '
  659. X.br
  660. XUnix is a Trademark of AT&T Bell Laboratories.
  661. X.br
  662. XHP-UX and Spectrum are Trademarks of Hewlett-Packard Company.
  663. X.br
  664. XUTS is a Trademark of Amdahl Corporation.
  665. X.FE
  666. Xsystems, including HP-UX (and the \fISpectrum\fR series!) or 
  667. Xsimulations thereof.
  668. X.LI "BSD"
  669. XThis is for the Berkeley breed of Unix.
  670. X.LI "UTS"
  671. XThis is for the Amdahl version of Unix.
  672. X.LI "SUN"
  673. XThis is for the Sun workstations (This is a superset of the BSD
  674. Xdefinition as the Sun appears to have some major crises when it
  675. Xis asked to perform string functions and handed \fInull\fR addresses,
  676. Xas opposed to a \fIpointer\fR to a \fInull\fR...)
  677. X.LI "PYRAMID"
  678. XThis is for the Pyramid 90x machines (This is the same as the
  679. XBSD definition)
  680. X.LE
  681. X.sp
  682. XOnce you've decided which is appropriate, edit the Makefile file
  683. Xin the top level directory and alter the "DEFINE" there (about
  684. Xline 33 or so) accordingly.  (Note: also use the associated
  685. X"LIB2" define that's associated with each of the systems to ensure
  686. Xthat the program uses the correct libraries when linking together!)
  687. X.sp
  688. XAn analogous change should be made in the Makefile in 'src' and 'utils'
  689. Xtoo if you're planning on actually working on the programs rather than
  690. Xjust installing them...
  691. X.sp
  692. XWhile you're at it, if you happen to be running \fIACSNET\fR, then
  693. Xyou need to add the relevent define in the main Makefile and the
  694. XMakefile in directory `src' too!
  695. X.sp 2
  696. XOnce that's done, all of the other installation dependent definitions
  697. Xare contained in the file \fIhdrs/sysdefs.h\fR and are;
  698. X.sp
  699. X.VL 15 0
  700. X.LI "USE_EMBEDDED_ADDRESSES"
  701. XThis controls the mailers response to messages that contain 
  702. X"Reply-To:" or "From:" lines that actually contain a return
  703. Xaddress.  If it's defined, the mailer will attempt to use
  704. Xthe address specified (overriding the return address built from the path that
  705. Xthe mail took).  It will look the address up in the pathalias
  706. Xdatabase (see the documentation on the alias system) for 
  707. Xincomplete paths, but it is still recommended that this be left
  708. Xundefined.  
  709. X.P
  710. XThis will, of course, make the mailer not be a standard 'RFC-822' 
  711. Xmailer, since the mail system is defined to use the reply-to
  712. Xif included rather than the return address, but, at least for
  713. Xaddresses on the Internet, it ain't going to work a lot of the time!
  714. X.LI "FIND_DELTA"
  715. XThis is the delta that the binary search of the pathalias database
  716. Xwill use to determine when it's slicing up a single line, rather than
  717. Xa multitude of lines.   Ideally, this should be set to 1 byte less
  718. Xthan the shortest line in the file...the default is 10 bytes.
  719. X.LI MAX_SALIASES        
  720. XThe number of system aliases allowed.  (It is recommended that
  721. Xthis be a prime number to improve the performance of the 
  722. Xhashing function (it's a complicated proof!))
  723. X.LI MAX_UALIASES
  724. XThe number of user aliases allowed.  (should be a prime number -
  725. Xsee the comment above)
  726. X.LI MAX_IN_WEEDLIST 
  727. XThe maximum number of headers that can be specified in the weedout
  728. Xlist of the .elmrc file.  A suggested alternative approach if this
  729. Xnumber is too small is to specify initial substrings in the file
  730. Xrather than increasing the number.  For example, say you want to 
  731. Xweedout the headers "Latitude:" and "Latitudinal-Coords:", you
  732. Xcould simply specify "Latitud" and match them both!  Furthermore
  733. Xyou could also specify headers like "X-" and remove all the user
  734. Xdefined headers!
  735. X.LI MAX_HOPS
  736. XWhen replying to a G)roup, this is the maximum number of hops that
  737. Xa message can have taken.  This is used to try to optimize the 
  738. Xreturn address (remove cyclic loops and so on) and regular use
  739. Xshould show that the default of 35 is plenty more than you'll
  740. Xever need!
  741. X.LI MAX_ATTEMPTS
  742. XWhen reading in the default mailbox (\fI/usr/mail/$username\fR) the mailer
  743. Xcreates a file called \fI/usr/mail/$username.lock\fR to ensure that no
  744. Xmail is added to the file while it's being either read, or replaced
  745. X(ie written to).  Occasionally, this lock file will already be in
  746. Xplace since someone is currently sending you mail.  If this occurs,
  747. Xthe mailer will wait a few seconds and try to create the lock file
  748. Xagain.  This parameter defines the number of tries the mailer should
  749. Xtake before giving up.
  750. X.LI REMOVE_AT_LAST
  751. XWhen it does decide to give up after trying to create the lock file,
  752. X(see MAX_ATTEMPTS, above) this will define how to act.  If it's 
  753. Xdefined, the mailer will attempt to remove the lock file after the
  754. XMAX_ATTEMPTS timeout.  On the other hand, if it's not defined (the
  755. Xrecommended state) it'll simply quit the mailer, telling the user
  756. Xto try again in a few minutes.
  757. X.LI DEFAULT_BATCH_SUBJECT
  758. XWhat the subject should be on messages that are from redirected input
  759. Xbut don't have a subject specified...
  760. X.LI NOCHECK_VALIDNAME
  761. XThis disables the checking of validnames on the existing machine.
  762. XOn machines that run a system such as \fIsendmail\fR and use the
  763. Xsendmail alias feature, this should be defined.  On other systems
  764. Xthis should be left as the default (not defined) to avoid users
  765. Xgenerating \fIdead.letter\fR files...
  766. X.LI NO_VM
  767. XThis disables the calls to "vfork()" and replaces them will calls
  768. Xto "fork()".  On machines where vfork() is available, this should
  769. Xbe left undefined, as the virtual call is considerably faster (and
  770. Xis only used when the spawned process doesn't need ALL the stuff
  771. Xfrom the calling process!)
  772. X.LI ALLOW_BCC
  773. XIf you are running a mail transport agent that can properly deal 
  774. Xwith the "Bcc" header in messages, you should define this variable.
  775. XOtherwise you'll end up with strange stuff like people \fIknowing\fR
  776. Xwho got "bcc"s of their mail...
  777. X.LI LOOK_CLOSE_AFTER_SEARCH
  778. XSome systems are set up in such a way as to have direct connections
  779. Xto machines, but to have multi-machine hops be preferable for
  780. Xrouting messages to/through that machine (an example is a connection
  781. Xto "nbires" for the monthly mod.map information, but only connected
  782. Xto once a month!).  If this option is defined, then the system will
  783. Xtry to find a suitable path to the machine \fIbefore\fR it checks
  784. Xagainst the \fIL.sys/uuname\fR list of systems that it can connect to.
  785. X.LI USE_UUNAME
  786. XThe mailer tries to get the list of machines that's its connected
  787. Xto by looking in the \fIL.sys\fR file.  If it fails usually, it will
  788. Xthen try to do a \fIuuname\fR command and then read the output of
  789. Xthat command.  If this is defined, however, it will skip the \fIL.sys\fR
  790. Xreading and immediately try the \fIuuname\fR call.
  791. X.LI DONT_OPTIMIZE_RETURN
  792. XWhen saving the return address of a current message, the program will
  793. Xattempt to store the minimum possible path.  Oftentimes, however, this
  794. Xisn't the ideal behaviour.  If you don't want the program to do this,
  795. Xthen you should define this.
  796. X.LI DONT_TOUCH_ADDRESSES
  797. XWith the slow entrance of various delivery agents that can dynamically
  798. Xroute things it becomes important that the mailer \fInot\fR touch 
  799. Xaddresses as entered by the user.  If this is the case at your
  800. Xsite (for example, if you're running \fIsmail\fR and \fIsendmail\fR as
  801. Xa package) then you need to define this.
  802. X.LI AUTO_BACKGROUND
  803. XIf this is defined then the \fInewmail\fR program automatically puts 
  804. Xitself into background as soon as it's invoked.  Otherwise, the
  805. Xuser needs to have a trailing ampersand (as in \fBnewmail &\fR) to
  806. Xget the same functionality.  (it seems reasonable to assume that
  807. Xno-one would ever run the utility as a \fIforeground\fR process!!!)
  808. X.LI DONT_ADD_FROM
  809. XSome mail systems (like my own) add From: lines that are
  810. Xactually different than the "default".  That is, the machine
  811. XI send mail from is "hpldat" so my From: line would normally
  812. Xbe "hpldat!taylor" but it should actually be "taylor@hplabs".
  813. XMy sendmail will add this correctly, so this allows \fBElm\fR
  814. Xto defer the addition until then.  This should only be used
  815. Xif your system is running sendmail in such a way that it will
  816. Xadd this header as needed ONLY!
  817. X.LI INTERNET_ADDRESS_FORMAT
  818. XFor systems that prefer the Internet addressing notation in the 
  819. XFrom: line, defining this will force that.  The default is
  820. Xto use Usenet notation (\fIhostname!username\fR) - this will change
  821. Xit to Internet notation (\fIusername@hostname\fR).
  822. X.LI PREFER_UUCP
  823. XOn some mail systems, the local host automatically appends their
  824. Xidentification \fIin Internet format\fR to the addresses you
  825. Xreceive (e.g. ``ihnp4!snsvax!joe@hplabs.HP.COM'' is an address
  826. Xform I see, being directly connection to HPLABS, all too often).
  827. XThis will simple ensure that when displaying the return address 
  828. Xof the message it will ignore the Internet part if there's also 
  829. Xa UUCP part.  (This is a kludge.  One should never have to 
  830. Xdeal with this in a mail system... *sigh*)
  831. X.LI BOGUS_INTERNET
  832. XAfter some serious thought, I came to the conclusion that the
  833. Xeasiest way to deal with the dumb configuration here is to 
  834. Xsimply strip off the local address part entirely whenever 
  835. Xpossible.  Hence, this field defines the local address that
  836. Xis added to the message addresses needlessly.  This is probably
  837. Xthe single worst solution imaginable, but it works...
  838. X.LI USE_DOMAIN
  839. XDefine if you want to have the \fIDOMAIN\fR field added to the
  840. X\fIhostname\fR in the From: field on outbound mail (note that this
  841. Xonly makes sense on Internet mail...)
  842. X.LI DOMAIN
  843. XIf you choose to have the USE_DOMAIN define set, you
  844. X\fIMUST DEFINE THIS ACCORDINGLY!!!\fR
  845. XA typical entry would be;
  846. X.DS
  847. X#define DOMAINS        ".HP.COM"
  848. X.DE
  849. X.LI SAVE_GROUP_MAILBOX_ID
  850. XIf you're running the mailer set group id (usually "setgid mail") then
  851. Xthis'll ensure that the users mailbox, when altered, will always retain
  852. Xits group id (obtained by the "getegid()" call, for those gurus out
  853. Xthere who care).  
  854. X.LI ENABLE_CALENDAR"
  855. XIf you want to have users able to scan their mail for calendar entries
  856. X(see the \fIElm Reference Guide\fR) then define this and the following
  857. Xtoo.  (There is no reason not to have this, but power corrupts, right?)
  858. X.LI "dflt_calendar_file"
  859. XThe name of the default "calendar" file if the user doesn't specify
  860. Xone in their \fI.elmrc\fR file.
  861. X.LI NOTES_HEADER
  862. XThis defines the first "word" of the line that a \fInotes\fR file entry
  863. Xwould contain.
  864. X.LI NOTES_FOOTER
  865. XThis defines the footer line (in it's entirety).
  866. X.LI system_hash_file
  867. XThis is the file that contains the hashed version of the system 
  868. Xaliases.  It is also used in the \fInewalias\fR command.  (note that
  869. Xit is defined differently if you're running on a Berkeley system)
  870. X.LI system_data_file
  871. XThis is the other file the \fInewalias\fR command installs in the system
  872. Xalias area.  (Note this is defined differently if you're runnnig
  873. Xa bsd system)
  874. X.LI pathfile
  875. XThis defines the location of the pathalias datafile.  This file is in
  876. Xthe format that \fIpathalias\fR generates, that is;
  877. X.nf
  878. X   
  879. X    machine <tab> address
  880. X
  881. X.fi
  882. XFor further information, please see the \fIElm Alias System\fR documentation.
  883. X.LI domains
  884. XThis defines the location of the the domains database file.  The format
  885. Xfor this file and so on are fully discussed in the \fIElm Alias System\fR
  886. Xdocument.
  887. X.LI Lsys
  888. XThis defines where the system \fIL.sys\fR file is kept.  This is used for the
  889. Xmailer to quickly know what machines the current machine can talk to
  890. Xdirectly (to avoid trying to search the pathalias database to route mail
  891. Xto these machines).  
  892. X.LI DEBUG
  893. XThe name of the file to put in the users home directory if they choose to
  894. Xuse the `-d' debug option. 
  895. X.LI temp_file
  896. XTemporary file for sending outbound messages.
  897. X.LI temp_mbox
  898. XPlace to keep copy of incoming mailbox to avoid collisions with newer
  899. Xmail.
  900. X.LI temp_print 
  901. XFile to use when creating a printout of a message.
  902. X.LI mailtime_file
  903. XFile to compare date to to determine if a given message is New
  904. Xsince the last time the mail was read or not.
  905. X.LI readmsg_file
  906. XFile to use when communicating with the \fIreadmsg\fR program (see
  907. Xthat program for more information)
  908. X.LI signature_file
  909. XThe name of the file to search for in the users home directory
  910. Xif they have \fIsignature\fR enabled in their \fI.elmrc\fR file.
  911. X.LI default_editor
  912. XIf no editor is specified in the users .elmrc file, this is which
  913. Xeditor to use.  \s12 Ensure it is a valid editor on this machine!!\s10
  914. X(Note that the default home for \fIvi\fR is different on BSD machines)
  915. X.LI mailhome
  916. XWhere all the incoming mailboxes are, and also where the 'lock'
  917. Xfiles have to be put for the mailer to know not to add new
  918. Xmail while we're reading/writing the mailfile.
  919. X(note that mail is kept in a different directory on Berkeley 
  920. Xsystems)
  921. X.LI default_pager
  922. XThis is the standard pager to use for reading messages.
  923. X.LI sendmail
  924. XDefines where \fIsendmail\fR is (if you have it on your system).
  925. X.LI smflags 
  926. XDefines the flags to hand to \fIsendmail\fR if and when the program
  927. Xchooses to use it.
  928. X.LI mailer
  929. XIf you don't have \fIsendmail\fR, this is the mailer that'll be used.
  930. X.LI mailx
  931. XIf all else fails, this mailer can be used in a rather dumb way.
  932. X.LI helphome
  933. XWhere the help file is kept (soon to be help files!)
  934. X.LI helpfile
  935. XThe name of the main helpfile (kept in \fIhelphome\fR).
  936. X.LI elmrcfile
  937. XThe name of the automatic control file (currently \fI.elmrc\fR)
  938. X.LI mailheaders 
  939. XThe name of the optional file that users may have that will be
  940. Xincluded in the headers of each outbound message.
  941. X.LI unedited_mail
  942. XIn the strange case when the mailer suddenly finds all the directories
  943. Xit uses shut off (like \fI/usr/mail\fR and \fI/tmp\fR) 
  944. Xthen it'll put the current
  945. Xmailbox into this file in the users home directory.
  946. X.LI newalias
  947. XHow to install new aliases..(note: you MUST have the '-q' flag!)
  948. X.LI remove
  949. XHow to remove a file.
  950. X.LI cat
  951. XHow to display a file to stdout.
  952. X.LI uuname
  953. XHow to get a \fIuuname\fR listing (ie a listing of the machines that this
  954. Xmachine connects to)
  955. X.LE
  956. END_OF_doc/Config.guide
  957. if test 15488 -ne `wc -c <doc/Config.guide`; then
  958.     echo shar: \"doc/Config.guide\" unpacked with wrong size!?
  959. fi
  960. # end of overwriting check
  961. fi
  962. echo shar: Extracting \"src/addr_utils.c\" \(16530 characters\)
  963. if test -f src/addr_utils.c ; then 
  964.   echo shar: Will not over-write existing file \"src/addr_utils.c\"
  965. else
  966. sed "s/^X//" >src/addr_utils.c <<'END_OF_src/addr_utils.c'
  967. X/**            addr_utils.c            **/
  968. X
  969. X/** This file contains addressing utilities 
  970. X
  971. X    (C) Copyright 1986 Dave Taylor 
  972. X**/
  973. X
  974. X#include "headers.h"
  975. X
  976. X#include <sys/types.h>
  977. X#include <sys/stat.h>
  978. X#include <ctype.h>
  979. X
  980. X#ifdef BSD
  981. X#undef tolower
  982. X#endif
  983. X
  984. Xchar *shift_lower(), *get_alias_address(), *get_token(), *strtok(),
  985. X     *strchr(), *strcpy(), *strcat(), *strncpy();
  986. X
  987. Xint
  988. Xtalk_to(sitename)
  989. Xchar *sitename;
  990. X{
  991. X    /** If we talk to the specified site, return true, else
  992. X        we're going to have to expand this baby out, so 
  993. X        return false! **/
  994. X
  995. X    struct lsys_rec  *sysname;
  996. X
  997. X    sysname = talk_to_sys;
  998. X
  999. X    if (sysname == NULL) {
  1000. X     dprint0(2,
  1001. X        "Warning - talk_to_sys is currently set to NULL! (talk_to)\n");
  1002. X     return(0);
  1003. X    }
  1004. X
  1005. X    while (sysname != NULL) {
  1006. X      if (strcmp(sysname->name, sitename) == 0)
  1007. X        return(1);
  1008. X      else
  1009. X        sysname = sysname->next;
  1010. X    }
  1011. X
  1012. X    return(0);
  1013. X}
  1014. X
  1015. Xremove_domains(host)
  1016. Xchar *host;
  1017. X{
  1018. X    /** Remove all entries following the first '.' to ensure that
  1019. X        entries like "MIT.ARPA" will match "MIT" in the database
  1020. X    **/
  1021. X
  1022. X    register int loc = 0;
  1023. X
  1024. X    while (host[loc] != '.' && host[loc] != '\0')
  1025. X      loc++;
  1026. X
  1027. X    if (host[loc] == '.') host[loc] = '\0';
  1028. X}
  1029. X
  1030. Xadd_site(buffer, site, lastsite)
  1031. Xchar *buffer, *site, *lastsite;
  1032. X{
  1033. X    /** add site to buffer, unless site is 'uucp', current machine, or
  1034. X            site is the same as lastsite.   If not, set lastsite to
  1035. X            site.
  1036. X    **/
  1037. X
  1038. X    char local_buffer[LONG_SLEN];
  1039. X    char *strip_parens();
  1040. X
  1041. X    if (strcmp(site, "uucp") != 0)
  1042. X      if (strcmp(site, lastsite) != 0) 
  1043. X        if (strcmp(site, hostname) != 0) {
  1044. X          if (buffer[0] == '\0')
  1045. X            strcpy(buffer, strip_parens(site));         /* first in list! */
  1046. X          else {
  1047. X            sprintf(local_buffer,"%s!%s", buffer, strip_parens(site));
  1048. X            strcpy(buffer, local_buffer);
  1049. X          }
  1050. X          strcpy(lastsite, strip_parens(site)); /* don't want THIS twice! */
  1051. X        }
  1052. X}
  1053. X
  1054. X#ifdef USE_EMBEDDED_ADDRESSES
  1055. X
  1056. Xget_address_from(prefix, line, buffer)
  1057. Xchar *prefix, *line, *buffer;
  1058. X{
  1059. X    /** This routine extracts the address from either a 'From:' line
  1060. X        or a 'Reply-To:' line...the algorithm is quite simple, too:
  1061. X        increment 'line' past header, then check last character of 
  1062. X        line.  If it's a '>' then the address is contained within '<>'
  1063. X        and if it's a ')' then the address is in the 'clear'... **/
  1064. X
  1065. X    register int i, j = 0;
  1066. X    
  1067. X    no_ret(line);
  1068. X
  1069. X    line = (char *) (line + strlen(prefix) + 1);
  1070. X
  1071. X    if (line[strlen(line)-1] == '>') {
  1072. X      for (i=strlen(line)-2; i > -1 && line[i] != '<'; i--)
  1073. X        buffer[j++] = line[i];
  1074. X      buffer[j] = 0;
  1075. X      reverse(buffer);
  1076. X    }
  1077. X    else {    /* either ')' or address in the clear... */
  1078. X      for (i=0; i < strlen(line) && line[i] != '('; i++)
  1079. X        buffer[j++] = line[i];
  1080. X      if (buffer[j-1] == '(') j--;
  1081. X      buffer[j] = 0;
  1082. X    }
  1083. X}
  1084. X
  1085. X#endif
  1086. X
  1087. Xtranslate_return(addr, ret_addr)
  1088. Xchar *addr, *ret_addr;
  1089. X{
  1090. X    /** Return ret_addr to be the same as addr, but with the login 
  1091. X            of the person sending the message replaced by '%s' for 
  1092. X            future processing... 
  1093. X        Fixed to make "%xx" "%%xx" (dumb 'C' system!) 
  1094. X    **/
  1095. X
  1096. X    register int loc, loc2, index = 0;
  1097. X    
  1098. X    loc2 = chloc(addr,'@');
  1099. X    if ((loc = chloc(addr, '%')) < loc2)
  1100. X      loc2 = loc;
  1101. X
  1102. X    if (loc2 != -1) {    /* ARPA address. */
  1103. X      /* algorithm is to get to '@' sign and move backwards until
  1104. X         we've hit the beginning of the word or another metachar.
  1105. X      */
  1106. X      for (loc = loc2 - 1; loc > -1 && addr[loc] != '!'; loc--)
  1107. X         ;
  1108. X    }
  1109. X    else {            /* usenet address */
  1110. X      /* simple algorithm - find last '!' */
  1111. X
  1112. X      loc2 = strlen(addr);    /* need it anyway! */
  1113. X
  1114. X      for (loc = loc2; loc > -1 && addr[loc] != '!'; loc--)
  1115. X          ;
  1116. X    }
  1117. X    
  1118. X    /** now copy up to 'loc' into destination... **/
  1119. X
  1120. X    while (index <= loc) {
  1121. X      ret_addr[index] = addr[index];
  1122. X      index++;
  1123. X    }
  1124. X
  1125. X    /** now append the '%s'... **/
  1126. X
  1127. X    ret_addr[index++] = '%';
  1128. X    ret_addr[index++] = 's';
  1129. X
  1130. X    /** and, finally, if anything left, add that **/
  1131. X
  1132. X    while (loc2 < strlen(addr)) {
  1133. X      ret_addr[index++] = addr[loc2++];
  1134. X      if (addr[loc2-1] == '%')    /* tweak for "printf" */
  1135. X        ret_addr[index++] = '%';
  1136. X    }
  1137. X    
  1138. X    ret_addr[index] = '\0';
  1139. X}
  1140. X
  1141. Xbuild_address(to, full_to)
  1142. Xchar *to, *full_to;
  1143. X{
  1144. X    /** loop on all words in 'to' line...append to full_to as
  1145. X        we go along, until done or length > len.  Modified to
  1146. X        know that stuff in parens are comments... 
  1147. X    **/
  1148. X
  1149. X    register int i, changed = 0, in_parens = 0;
  1150. X    char word[SLEN], *ptr, buffer[SLEN];
  1151. X    char new_to_list[LONG_SLEN];
  1152. X    char *strpbrk(), *expand_system(), *strcat();
  1153. X
  1154. X    new_to_list[0] = '\0';
  1155. X
  1156. X    i = get_word(to, 0, word);
  1157. X
  1158. X    full_to[0] = '\0';
  1159. X
  1160. X    while (i > 0) {
  1161. X
  1162. X      if (word[0] == '(' || in_parens) {
  1163. X        in_parens = (word[strlen(word-1)] != ')');
  1164. X        strcat(full_to, " ");
  1165. X        strcat(full_to, word);
  1166. X      }
  1167. X      else if (strpbrk(word,"!@:") != NULL)
  1168. X#ifdef DONT_TOUCH_ADDRESS
  1169. X        sprintf(full_to, "%s%s%s", full_to,
  1170. X                    full_to[0] != '\0'? ", " : "", word);
  1171. X#else
  1172. X        sprintf(full_to, "%s%s%s", full_to,
  1173. X                    full_to[0] != '\0'? ", " : "", expand_system(word, 1));
  1174. X#endif
  1175. X      else if ((ptr = get_alias_address(word, 1, 0)) != NULL)
  1176. X        sprintf(full_to, "%s%s%s", full_to, 
  1177. X                    full_to[0] != '\0'? ", " : "", ptr);
  1178. X      else if (strlen(word) > 0) {
  1179. X        if (valid_name(word)) 
  1180. X          sprintf(full_to, "%s%s%s", full_to,
  1181. X                      full_to[0] != '\0'? ", " : "", word);
  1182. X        else if (check_only) {
  1183. X          printf("(alias \"%s\" is unknown)\n\r", word);
  1184. X          changed++;
  1185. X        }
  1186. X        else if (! isatty(fileno(stdin)) ) {    /* batch mode error! */
  1187. X          fprintf(stderr,"Cannot expand alias '%s'!\n\r", word);
  1188. X          fprintf(stderr,"Use \"checkalias\" to find valid addresses!\n\r");
  1189. X          dprint1(1,
  1190. X              "Can't expand alias %s - bailing out! (build_address)\n", 
  1191. X              word);
  1192. X          emergency_exit();
  1193. X        }
  1194. X        else {
  1195. X          dprint1(2,"Entered unknown address %s (build_address)\n", word);
  1196. X          sprintf(buffer, "'%s' is an unknown address.  Replace with: ", 
  1197. X                  word);
  1198. X          word[0] = '\0';
  1199. X
  1200. X          if (mail_only) 
  1201. X            printf(buffer);
  1202. X          else
  1203. X            PutLine0(LINES, 0, buffer);
  1204. X        
  1205. X          (void) optionally_enter(word, LINES, strlen(buffer), FALSE);
  1206. X          if (strlen(word) > 0) {
  1207. X            sprintf(new_to_list, "%s%s%s", new_to_list,
  1208. X            strlen(new_to_list) > 0? " ":"", word);
  1209. X            dprint1(3,"Replaced with %s (build_address)\n", word);
  1210. X          }
  1211. X          else
  1212. X        dprint0(3,"Address removed from to list (build_address)\n");
  1213. X          if (mail_only) printf("\n\r");
  1214. X          changed++;
  1215. X          clear_error();
  1216. X          continue;
  1217. X        }
  1218. X      }
  1219. X
  1220. X      i = get_word(to, i, word);
  1221. X    }
  1222. X
  1223. X    if (changed)
  1224. X      strcpy(to, new_to_list);
  1225. X}
  1226. X
  1227. Xint
  1228. Xreal_from(buffer, entry)
  1229. Xchar *buffer;
  1230. Xstruct header_rec *entry;
  1231. X{
  1232. X    /***** Returns true iff 's' has the seven 'from' fields, (or
  1233. X           8 - some machines include the TIME ZONE!!!)
  1234. X           Initializing the date and from entries in the record 
  1235. X           and also the message received date/time.  *****/
  1236. X
  1237. X    char junk[STRING], timebuff[STRING], holding_from[SLEN];
  1238. X    int  eight_fields = 0;
  1239. X
  1240. X    entry->year[0] = '\0';
  1241. X    junk[0] = '\0';
  1242. X
  1243. X    /* From <user> <day> <month> <day> <hr:min:sec> <year> */
  1244. X
  1245. X    sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %s", timebuff, junk);
  1246. X
  1247. X    if (timebuff[1] != ':' && timebuff[2] != ':') { 
  1248. X      dprint1(3,"real_from returns FAIL [bad time field] on\n-> %s\n", 
  1249. X          buffer);
  1250. X      return(FALSE);
  1251. X    }
  1252. X    if (junk[0] != '\0') {    /* try for 8 field entry */
  1253. X      junk[0] = '\0';
  1254. X      sscanf(buffer, "%*s %*s %*s %*s %*s %s %*s %*s %s", timebuff, junk);
  1255. X      if (junk[0] != '\0') {
  1256. X        dprint1(3,"real_from returns FAIL [too many fields] on\n-> %s\n", 
  1257. X            buffer);
  1258. X        return(FALSE);
  1259. X      }
  1260. X      eight_fields++;
  1261. X    }
  1262. X
  1263. X    /** now get the info out of the record! **/
  1264. X
  1265. X    if (eight_fields) 
  1266. X      sscanf(buffer, "%s %s %s %s %s %s %*s %s",
  1267. X                junk, holding_from, entry->dayname, entry->month, 
  1268. X                    entry->day, entry->time, entry->year);
  1269. X    else
  1270. X      sscanf(buffer, "%s %s %s %s %s %s %s",
  1271. X                junk, holding_from, entry->dayname, entry->month, 
  1272. X                    entry->day, entry->time, entry->year);
  1273. X    
  1274. X    strncpy(entry->from, holding_from, STRING);
  1275. X    resolve_received(entry);
  1276. X    return(entry->year[0] != '\0');
  1277. X}
  1278. X
  1279. Xforwarded(buffer, entry)
  1280. Xchar *buffer;
  1281. Xstruct header_rec *entry;
  1282. X{
  1283. X    /** Change 'from' and date fields to reflect the ORIGINATOR of 
  1284. X        the message by iteratively parsing the >From fields... 
  1285. X        Modified to deal with headers that include the time zone
  1286. X        of the originating machine... **/
  1287. X
  1288. X    char machine[SLEN], buff[SLEN], holding_from[SLEN];
  1289. X
  1290. X    machine[0] = '\0';
  1291. X
  1292. X    sscanf(buffer, "%*s %s %s %s %s %s %s %*s %*s %s",
  1293. X                holding_from, entry->dayname, entry->month, 
  1294. X                    entry->day, entry->time, entry->year, machine);
  1295. X
  1296. X    if (isdigit(entry->month[0])) { /* try for veeger address */
  1297. X      sscanf(buffer, "%*s %s %s%*c %s %s %s %s %*s %*s %s",
  1298. X                holding_from, entry->dayname, entry->day, entry->month, 
  1299. X                    entry->year, entry->time, machine);
  1300. X    }
  1301. X    if (isalpha(entry->year[0])) { /* try for address including tz */
  1302. X      sscanf(buffer, "%*s %s %s %s %s %s %*s %s %*s %*s %s",
  1303. X                holding_from, entry->dayname, entry->month, 
  1304. X                    entry->day, entry->time, entry->year, machine);
  1305. X    }
  1306. X
  1307. X    if (machine[0] == '\0')
  1308. X      sprintf(buff,"anonymous");
  1309. X    else
  1310. X      sprintf(buff,"%s!%s", machine, holding_from);
  1311. X
  1312. X    strncpy(entry->from, buff, STRING);
  1313. X}
  1314. X
  1315. Xparse_arpa_from(buffer, newfrom)
  1316. Xchar *buffer, *newfrom;
  1317. X{
  1318. X    /** try to parse the 'From:' line given... It can be in one of
  1319. X        two formats:
  1320. X        From: Dave Taylor <hplabs!dat>
  1321. X        or  From: hplabs!dat (Dave Taylor)
  1322. X
  1323. X        Added: removes quotes if name is quoted (12/12)
  1324. X        Added: only copies STRING characters...
  1325. X        Added: if no comment part, copy address instead! 
  1326. X    **/
  1327. X
  1328. X    char temp_buffer[SLEN], *temp;
  1329. X    register int i, j = 0;
  1330. X
  1331. X    temp = (char *) temp_buffer;
  1332. X    temp[0] = '\0';
  1333. X
  1334. X    no_ret(buffer);        /* blow away '\n' char! */
  1335. X
  1336. X    if (lastch(buffer) == '>') {
  1337. X      for (i=strlen("From: "); buffer[i] != '\0' && buffer[i] != '<' &&
  1338. X           buffer[i] != '('; i++)
  1339. X        temp[j++] = buffer[i];
  1340. X      temp[j] = '\0';
  1341. X    }
  1342. X    else if (lastch(buffer) == ')') {
  1343. X      for (i=strlen(buffer)-2; buffer[i] != '\0' && buffer[i] != '(' &&
  1344. X           buffer[i] != '<'; i--)
  1345. X        temp[j++] = buffer[i];
  1346. X      temp[j] = '\0';
  1347. X      reverse(temp);
  1348. X    }
  1349. X
  1350. X#ifdef USE_EMBEDDED_ADDRESSES
  1351. X
  1352. X    /** if we have a null string at this point, we must just have a 
  1353. X        From: line that contains an address only.  At this point we
  1354. X        can have one of a few possibilities...
  1355. X
  1356. X        From: address
  1357. X        From: <address>
  1358. X        From: address ()
  1359. X    **/
  1360. X      
  1361. X    if (strlen(temp) == 0) {
  1362. X      if (lastch(buffer) != '>') {       
  1363. X        for (i=strlen("From:");buffer[i] != '\0' && buffer[i] != '('; i++)
  1364. X          temp[j++] = buffer[i];
  1365. X        temp[j] = '\0';
  1366. X      }
  1367. X      else {    /* get outta '<>' pair, please! */
  1368. X        for (i=strlen(buffer)-2;buffer[i] != '<' && buffer[i] != ':';i--)
  1369. X          temp[j++] = buffer[i];
  1370. X        temp[j] = '\0';
  1371. X        reverse(temp);
  1372. X      }
  1373. X    }
  1374. X#endif
  1375. X      
  1376. X    if (strlen(temp) > 0) {        /* mess with buffer... */
  1377. X
  1378. X      /* remove leading spaces and quotes... */
  1379. X
  1380. X      while (whitespace(temp[0]) || quote(temp[0]))
  1381. X        temp = (char *) (temp + 1);        /* increment address! */
  1382. X
  1383. X      /* remove trailing spaces and quotes... */
  1384. X
  1385. X      i = strlen(temp) - 1;
  1386. X
  1387. X      while (whitespace(temp[i]) || quote(temp[i]))
  1388. X       temp[i--] = '\0';
  1389. X
  1390. X      /* if anything is left, let's change 'from' value! */
  1391. X
  1392. X      if (strlen(temp) > 0)
  1393. X        strncpy(newfrom, temp, STRING);
  1394. X    }
  1395. X}
  1396. X
  1397. Xparse_arpa_date(string, entry)
  1398. Xchar *string;
  1399. Xstruct header_rec *entry;
  1400. X{
  1401. X    /** Parse and figure out the given date format... return
  1402. X        the entry fields changed iff it turns out we have a
  1403. X        valid parse of the date!  **/
  1404. X
  1405. X    char word[15][NLEN], buffer[SLEN], *bufptr;
  1406. X    char *aword;
  1407. X    int  words = 0;
  1408. X
  1409. X    strcpy(buffer, string);
  1410. X    bufptr = (char *) buffer;
  1411. X
  1412. X    /** break the line down into words... **/
  1413. X
  1414. X    while ((aword = strtok(bufptr," \t '\"-/(),.")) != NULL) {
  1415. X      strcpy(word[words++], aword);
  1416. X      bufptr = NULL;
  1417. X    }
  1418. X
  1419. X    if (words < 6) {    /* strange format.  We're outta here! */
  1420. X      dprint1(3,"parse_arpa_date failed [less than six fields] on\n-> %s\n",
  1421. X          string);
  1422. X      return;
  1423. X    }
  1424. X
  1425. X    /* There are now five possible combinations that we could have:
  1426. X     
  1427. X        Date: day_number month_name year_number time timezone
  1428. X        Date: day_name day_number month_name year_number ...
  1429. X        Date: day_name month_name day_number time year_number
  1430. X        Date: day_name month_name day_number year_number time
  1431. X        Date: day_number month_name year_number time timezone day_name
  1432. X
  1433. X       Note that they are distinguishable by checking the first
  1434. X       character of the second, third and fourth words... 
  1435. X    */
  1436. X
  1437. X    if (isdigit(word[1][0])) {            /*** type one! ***/
  1438. X      if (! valid_date(word[1], word[2], word[3])) {
  1439. X        dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
  1440. X          word[1], word[2], word[3], string);
  1441. X        return;        /* strange date! */
  1442. X      }
  1443. X      strncpy(entry->day, word[1], 3);
  1444. X      strncpy(entry->month, word[2], 3);
  1445. X      strncpy(entry->year,  word[3], 4);
  1446. X      strncpy(entry->time,  word[4], 10);
  1447. X    }
  1448. X    else if (isdigit(word[2][0])) {                /*** type two! ***/
  1449. X      if (! valid_date(word[2], word[3], word[4])) {
  1450. X        dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
  1451. X          word[2], word[3], word[4], string);
  1452. X        return;        /* strange date! */
  1453. X      }
  1454. X      strncpy(entry->day, word[2], 3);
  1455. X      strncpy(entry->month, word[3], 3);
  1456. X      strncpy(entry->year,  word[4], 4);
  1457. X      strncpy(entry->time,  word[5], 10);
  1458. X    }
  1459. X    else if (isdigit(word[3][0])) {        
  1460. X      if (word[4][1] == ':' || 
  1461. X              word[4][2] == ':') {                   /*** type three! ***/
  1462. X        if (! valid_date(word[3], word[2], word[5])) {
  1463. X         dprint4(3,
  1464. X        "parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
  1465. X            word[3], word[2], word[5], string);
  1466. X          return;        /* strange date! */
  1467. X        }
  1468. X        strncpy(entry->year,  word[5], 4);
  1469. X        strncpy(entry->time,  word[4], 10);
  1470. X      }
  1471. X      else {                       /*** type four!  ***/ 
  1472. X        if (! valid_date(word[3], word[2], word[4])) {
  1473. X         dprint4(3,"parse_arpa_date failed [bad date: %s/%s/%s] on\n-> %s\n",
  1474. X            word[3], word[2], word[4], string);
  1475. X          return;        /* strange date! */
  1476. X        }
  1477. X        strncpy(entry->year,  word[4], 4);
  1478. X        strncpy(entry->time, word[5], 10);
  1479. X      }
  1480. X      strncpy(entry->day, word[3], 3);
  1481. X      strncpy(entry->month, word[2], 3);
  1482. X    }
  1483. X}
  1484. X
  1485. Xfix_arpa_address(address)
  1486. Xchar *address;
  1487. X{
  1488. X    /** Given a pure ARPA address, try to make it reasonable.
  1489. X
  1490. X        This means that if you have something of the form a@b@b make 
  1491. X            it a@b.  If you have something like a%b%c%b@x make it a%b@x...
  1492. X    **/
  1493. X
  1494. X    register int host_count = 0, i;
  1495. X    char     hosts[MAX_HOPS][2*NLEN];    /* array of machine names */
  1496. X    char     *host, *addrptr;
  1497. X
  1498. X    /*  break down into a list of machine names, checking as we go along */
  1499. X    
  1500. X    addrptr = (char *) address;
  1501. X
  1502. X    while ((host = get_token(addrptr, "%@", 2)) != NULL) {
  1503. X      for (i = 0; i < host_count && ! equal(hosts[i], host); i++)
  1504. X          ;
  1505. X
  1506. X      if (i == host_count) {
  1507. X        strcpy(hosts[host_count++], host);
  1508. X        if (host_count == MAX_HOPS) {
  1509. X           dprint0(2,
  1510. X              "Can't build return address - hit MAX_HOPS (fix_arpa_address)\n");
  1511. X           error("Can't build return address - hit MAX_HOPS limit!");
  1512. X           return(1);
  1513. X        }
  1514. X      }
  1515. X      else 
  1516. X        host_count = i + 1;
  1517. X      addrptr = NULL;
  1518. X    }
  1519. X
  1520. X    /** rebuild the address.. **/
  1521. X
  1522. X    address[0] = '\0';
  1523. X
  1524. X    for (i = 0; i < host_count; i++)
  1525. X      sprintf(address, "%s%s%s", address, 
  1526. X              address[0] == '\0'? "" : 
  1527. X             (i == host_count - 1 ? "@" : "%"),
  1528. X              hosts[i]);
  1529. X
  1530. X    return(0);
  1531. X}
  1532. X
  1533. Xfigure_out_addressee(buffer, mail_to)
  1534. Xchar *buffer;
  1535. Xchar *mail_to;
  1536. X{
  1537. X    /** This routine steps through all the addresses in the "To:"
  1538. X        list, initially setting it to the first entry (if mail_to
  1539. X        is NULL) or, if the user is found (eg "alternatives") to
  1540. X        the current "username".
  1541. X
  1542. X        Modified to know how to read quoted names...
  1543. X    **/
  1544. X
  1545. X    char *address, *bufptr;
  1546. X    register int index = 0, index2 = 0;
  1547. X    
  1548. X    if (equal(mail_to, username)) return;    /* can't be better! */
  1549. X
  1550. X    bufptr = (char *) buffer;    /* use the string directly   */
  1551. X
  1552. X    if (strchr(buffer,'"') != NULL) {    /* we have a quoted string */
  1553. X      while (buffer[index] != '"')
  1554. X        index++;
  1555. X      index++;    /* skip the leading quote */
  1556. X      while (buffer[index] != '"' && index < strlen(buffer))
  1557. X        mail_to[index2++] = buffer[index++];
  1558. X      mail_to[index2] = '\0';
  1559. X    }
  1560. X    else while ((address = strtok(bufptr, " ,\t\n\r")) != NULL) {
  1561. X      if (! okay_address(address, "don't match me!")) {
  1562. X        strcpy(mail_to, username);    /* it's to YOU! */
  1563. X        return;
  1564. X      }
  1565. X      else if (strlen(mail_to) == 0)    /* it's SOMEthing! */
  1566. X        get_return_name(address, mail_to, FALSE);
  1567. X
  1568. X      bufptr = (char *) NULL;    /* set to null */
  1569. X    }
  1570. X
  1571. X    return;
  1572. X}
  1573. END_OF_src/addr_utils.c
  1574. if test 16530 -ne `wc -c <src/addr_utils.c`; then
  1575.     echo shar: \"src/addr_utils.c\" unpacked with wrong size!?
  1576. fi
  1577. # end of overwriting check
  1578. fi
  1579. echo shar: End of archive 15 \(of 19\).
  1580. cp /dev/null ark15isdone
  1581. DONE=true
  1582. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; do
  1583.     if test ! -f ark${I}isdone ; then
  1584.     echo shar: You still need to run archive ${I}.
  1585.     DONE=false
  1586.     fi
  1587. done
  1588. if test "$DONE" = "true" ; then
  1589.     echo You have unpacked all 19 archives.
  1590.     echo "See the Instructions file"
  1591.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1592. fi
  1593. ##  End of shell archive.
  1594. exit 0
  1595.