home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume30 / mserv-3.0 / part01 next >
Encoding:
Text File  |  1992-06-19  |  55.9 KB  |  1,996 lines

  1. Newsgroups: comp.sources.misc
  2. From: jv@mh.nl (Johan Vromans)
  3. Subject:  v30i046:  mserv-3.0 - Squirrel Mail Server Software, Part01/04
  4. Message-ID: <csm-v30i046=mserv-3.0.195346@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: f77c278186bdd737dbd360d5cccc0bd0
  6. Date: Sun, 14 Jun 1992 00:58:29 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: jv@mh.nl (Johan Vromans)
  10. Posting-number: Volume 30, Issue 46
  11. Archive-name: mserv-3.0/part01
  12. Environment: Perl
  13.  
  14. The Squirrel Mail Server is a mail response program. You can send
  15. email to it, and it will try to react sensible to your message.
  16.  
  17. Main purpose of the mail server is to obtain files from an archive,
  18. but other functions can be added easily.
  19.  
  20. Version 3 is a complete rework of Version 1 (a.k.a. Multihouse-1),
  21. that has been in production on a number of sites ever since its
  22. release in 1988.  Both the popular csdserv (by Dave Shaver) and the
  23. UTRECHT mail server (by Piet van Oostrum) have been dereived from
  24. Multihouse-1.
  25.  
  26. The Squirrel Mail Server software is distributed under the terms of
  27. the GNU Public Licence.
  28.  
  29. A brief survey of old and new features:
  30.  
  31.   - All written in perl, hence portable and easily maintainable.
  32.   - Easy to install.
  33.   - Archives can be split over a number of directories or file systems.
  34.   - Requests are queued and processed by a separate daemon process
  35.     (e.g. from cron). This cuts down on the system load. Moreover, you
  36.     can control when the queue is being run.
  37.   - Requests can be honoured `as is' (name the file and you'll get
  38.     it), but the server can also perform directory searches and index
  39.     file lookup.
  40.     You need GNU find and locate for the index lookup feature.
  41.   - While looking for files, the server knows about commonly handled
  42.     filenames (e.g. ".tar.Z" in "foo.tar.Z") and pseudo-standard
  43.     version numbering (e.g. "gcc-2.1.tar.Z"). It is quite well
  44.     possible that a simple request for "emacs" will actually transmit the
  45.     file "gnu/emacs-18.58/dist/emacs-18.58.tar.Z".
  46.   - Requests can be encoded using a number of encoding schemes, e.g.
  47.     uuencode, xxencode, Dumas' uue and btoa.
  48.   - Requests that are too large to send in one piece are automatically
  49.     split and transferred in parts. The server provides a smart
  50.     unpacking program on request,
  51.   - Parts of requests can be re-transmitted in case of failure.
  52.   - Requests can designate a directory. In this case the whole
  53.     directory tree is packed using some popular packing programs
  54.     (compressed tar, zoo or zip).
  55.   - Requests can be sent by email, or via uucp.
  56.   - The server can be asked to return a list of archive entries that
  57.     match a given request, thus obsoleting the need to transfer huge
  58.     "ls-lR" type index files to find out whatsitcalled.
  59.   - All transfers can be logged. Maintenance procedures include a
  60.     reporting tool.
  61.  
  62. Probable future directions:
  63.  
  64.   - Anonymous FTP interface.
  65.   - Automatic (and transparent) downloading of unknown archive entries
  66.     from other archive servers.
  67.   - Notifier services (you'll be notified if archive entries are
  68.     added).
  69.   - Remote maintenance.
  70.  
  71. Requirements:
  72.  
  73.   - Perl 4.0 patchlevel 19 or later.
  74.   - GNU find 3.5 or later (only if you want to exploit the index
  75.     features).
  76.   - A decent mail system that can deliver mail to a process (sendmail,
  77.     smail3, or smail2.5 w/ mods).
  78.  
  79. For more information:
  80.  
  81.     <jv@mh.nl>
  82.     Johan Vromans
  83.     Multihouse Research
  84. --------------------------------------------------------------
  85. #! /bin/sh
  86. # This is a shell archive.  Remove anything before this line, then feed it
  87. # into a shell via "sh file" or similar.  To overwrite existing files,
  88. # type "sh file -c".
  89. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  90. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  91. # Contents:  README ChangeLog HELP mlistener.pl process.pl
  92. # Wrapped by kent@sparky on Sat Jun 13 19:46:21 1992
  93. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  94. echo If this archive is complete, you will see the following message:
  95. echo '          "shar: End of archive 1 (of 4)."'
  96. if test -f 'README' -a "${1}" != "-c" ; then 
  97.   echo shar: Will not clobber existing file \"'README'\"
  98. else
  99.   echo shar: Extracting \"'README'\" \(4368 characters\)
  100.   sed "s/^X//" >'README' <<'END_OF_FILE'
  101. X@(#)@ README    3.4 - README
  102. X
  103. XSquirrel Mail Server
  104. X====================
  105. X
  106. XThe Squirrel Mail Server is a mail response program. You can send
  107. Xemail to it, and it will try to react sensible to your message.
  108. X
  109. XMain purpose of the mail server is to obtain files from an archive,
  110. Xbut other functions can be added easily.
  111. X
  112. XThe Squirrel Mail Server software is 
  113. X
  114. X    Copyright 1988,1992 Johan Vromans
  115. X
  116. Xand distributed under the terms of the GNU Public Licence. It is
  117. Xwritten in Perl.
  118. X
  119. XDistribution
  120. X============
  121. X
  122. XThis package contains the following files.
  123. X
  124. X    README        This document.
  125. X    ChangeLog        A log of changes.
  126. X    INSTALL        The documentation on how to install the package.
  127. X    mserv_common.pl    Common information for the mail server constituents.
  128. X    mserv_config.pl    Configuration file.
  129. X    process.pl        Perl script to parse mail messages, and to
  130. X            enqueue the requests.
  131. X    pr_*.pl        Demand loadable modules for process.pl
  132. X    rfc822.pl        A package to process rfc822 based messages.
  133. X    dorequest.pl    Perl script to encode and split the files, and sent
  134. X            them to the requester.
  135. X    dr_*.pl        Demand loadable modules for dorequest.pl
  136. X    ms_lock.pl        Portable file locking package
  137. X    unpack.pl        Perl script to unpack a concatenated series of parts.
  138. X    HELP        The HELP file.
  139. X    mlistener.pl    Generator for a simple wrapper around "process.pl"
  140. X            to enable setuid processing.
  141. X    makeindex.pl    A simple script to aid in maintaining an index
  142. X                of archive entries.
  143. X    chkconfig.pl    A tool to feed back on the configuration file.
  144. X    testlock.pl        A tool to test the locking package.
  145. X    report.pl        A tool to generate usage and error reports.
  146. X    do_report.pl    A script to use report.pl
  147. X    do_runq.sh        A shell script to run the mail server queue from cron.
  148. X    CRONTAB.sample    A sample cron tab for the mail server.
  149. X    mserv.notes
  150. X    mserv.hints        Sample files.
  151. X    ixlookup.patch    Patch to GNU find 3.5 'locate.c' for create
  152. X                the index lookup program.
  153. X    Makefile        To install the package.
  154. X
  155. X
  156. XPrinciple of operation
  157. X======================
  158. X
  159. XWhen a mail is sent to the appropriate designation, generally a mail
  160. Xalias, it is piped into program "listener". This program effectivily
  161. Xchanges user to the mail server user, and passes control to the perl
  162. Xscript "process".  This program reads the input, extracts the return
  163. Xaddress to be used from the mail headers, and parses the commands in
  164. Xthe message body.  See "HELP.txt" for a detailed description of the
  165. Xcommands.  "process" tries to locate the requested files in the
  166. Xarchive libraries, using default extensions to filenames as described
  167. Xbelow.  Requests are then put in the mail server queue.
  168. X
  169. XA separate daemon process ("dorequest", usually invoked by cron) can
  170. Xbe used to process the queue. This program encodes the file, splits it
  171. Xinto parts, and passes each part to the mail program for delivery.
  172. X
  173. XWhen all parts of a specific delivery are concatenated in the correct
  174. Xorder (e.g. using a mail program), the original file can be unpacked
  175. Xusing the perl program "unpack".
  176. X
  177. XStructure of the archives
  178. X=========================
  179. X
  180. XThe mail server can handle a list of directories, each of which
  181. Xcontains zero or more archive entries. By default the following
  182. Xconventions in the naming of archive entries are used:
  183. X
  184. X   XXXX         Plain file (ascii text)
  185. X   XXXX.shar    Shell Archive
  186. X   XXXX.shar.Z  Compressed Shell Archive
  187. X   XXXX.Z       Compressed file
  188. X   XXXX.tar     Unix tar format
  189. X   XXXX.tar.Z   Compressed tar
  190. X   XXXX.TZ      Compressed tar
  191. X   XXXX.zoo     Zoo archive format
  192. X   XXXX.zip    Zip archive format
  193. X
  194. XWhen someone requests for item XXXX, all of these possibilities are
  195. Xtried in locating the desired archive item.
  196. X
  197. XIt is also possible to configure the server to locate entries using a
  198. Xnormalized version encoding scheme. In this case, it will also find
  199. Xfiles of the form XXXX-YYYZZZ (with ZZZ one of the above extensions).
  200. XAlso, if a suitable file appears to be a directory, the search is
  201. Xcontinued in this directory.
  202. X
  203. XFinally, it is possible to have the server lookup entries in an index
  204. Xfile. 
  205. X
  206. XAbout the software
  207. X==================
  208. X
  209. XVersion 3 is a complete rework of Version 1 (a.k.a. Multihouse-1),
  210. Xthat has been in production on a number of sites ever since its
  211. Xrelease in 1988.  Both the popular csdserv (by Dave Shaver) and the
  212. XUTRECHT mail server (by Piet van Oostrum) have been dereived from
  213. XMultihouse-1.
  214. X
  215. END_OF_FILE
  216.   if test 4368 -ne `wc -c <'README'`; then
  217.     echo shar: \"'README'\" unpacked with wrong size!
  218.   fi
  219.   # end of 'README'
  220. fi
  221. if test -f 'ChangeLog' -a "${1}" != "-c" ; then 
  222.   echo shar: Will not clobber existing file \"'ChangeLog'\"
  223. else
  224.   echo shar: Extracting \"'ChangeLog'\" \(109 characters\)
  225.   sed "s/^X//" >'ChangeLog' <<'END_OF_FILE'
  226. XWed Jun 10 11:57:44 1992  Johan Vromans  (jv at largo)
  227. X
  228. X    * ================ Released V3.00 ================
  229. X
  230. END_OF_FILE
  231.   if test 109 -ne `wc -c <'ChangeLog'`; then
  232.     echo shar: \"'ChangeLog'\" unpacked with wrong size!
  233.   fi
  234.   # end of 'ChangeLog'
  235. fi
  236. if test -f 'HELP' -a "${1}" != "-c" ; then 
  237.   echo shar: Will not clobber existing file \"'HELP'\"
  238. else
  239.   echo shar: Extracting \"'HELP'\" \(15640 characters\)
  240.   sed "s/^X//" >'HELP' <<'END_OF_FILE'
  241. XThe Mail Server
  242. X===============
  243. X
  244. XThe mail server is a mail response program. This means that you can
  245. Xsend it an email message, and the program will read this message,
  246. Xextracts commands from it, and execute these commands if no errors
  247. Xwere encountered.
  248. X
  249. XThe main purpose of the mail server is to handle requests for files in
  250. Xarchives. By sending a request for a file, the mail server will look
  251. Xit up and send the requested file to the originator of the request,
  252. Xeither via email or via UUCP.
  253. X
  254. XWhen files are transferred via email, binary files (e.g. compressed
  255. Xarchives) are encoded using one of several popular encoding schemes.
  256. XBig files are split into pieces to avoid mailer limits.
  257. X
  258. XBasic Use
  259. X=========
  260. X
  261. XTo request a file from the server send an email message with the
  262. Xfollowing command:
  263. X
  264. X   SEND filename
  265. X
  266. XThis will have the requested file send via email to the originator of
  267. Xthe mail message. Encoding, if needed, will be performed with the
  268. X'btoa' program. BEGIN and END can be used to protect the request
  269. Xfrom anything else in the mail message, e.g. a signature:
  270. X
  271. X   BEGIN
  272. X   SEND filename
  273. X   END
  274. X   .signature follows.....
  275. X
  276. XTo receive a file via UUCP, use the following commands:
  277. X
  278. X   UUCP host!path user
  279. X   SEND filename
  280. X
  281. XThis will have all requested files transferred via UUCP to the
  282. Xdesignated host!path. It is equivalent to the Unix command:
  283. X
  284. X   uucp -drnuser host!path/filename 
  285. X
  286. XIt is your own responsibility that the supplied path is accessible to
  287. Xyour UUCP system!
  288. X
  289. XThe Server's Archives
  290. X=====================
  291. X
  292. XFiles are stored in the archives in one of the following formats:
  293. X
  294. XPlain: normal ASCII text.
  295. X
  296. XShell Archive: ASCII files which can be unloaded using the
  297. X    Unix sh(1) program.
  298. X    Shell Archives have names ending in ".shar".
  299. X
  300. XCompressed: 16-bit compression using the compress(1) utility.
  301. X    Compressed files have names ending in ".Z".
  302. X
  303. XTar: standard UNIX tar(1) format.
  304. X    Tar archives have names ending in ".tar".
  305. X
  306. XCompressed Tar: compressed tar archive.
  307. X    Compressed tar archives have names ending in ".tar.Z" or ".TZ".
  308. X
  309. XZoo: standard "zoo" format.
  310. X    These files have names ending in ".zoo".
  311. X
  312. XWhen requesting a file you do not have to specify the format-specific
  313. Xextension. A request for a file "foo" will automatically be changed to
  314. X"foo", "foo.tar", "foo.shar", "foo.Z", "foo.TZ" or "foo.zoo" whichever is
  315. Xavailable.
  316. X
  317. XAdditional formats may be added.
  318. X
  319. XCommand Syntax
  320. X==============
  321. X
  322. XA command consists of a keyword (verb), followed by zero or more
  323. Xarguments, depending on the command. Command verbs may be specified in
  324. Xall uppercase letters, lowercase or whatever mixed case. In other
  325. Xwords: case is not significant in command verbs. Case *IS* significant
  326. Xin command arguments.
  327. XEmpty lines are ignored.
  328. X
  329. XThe following commands are understood by the server. The order of
  330. Xcommand classes is important.
  331. X
  332. X 1. Destination selection. One or more of the following commands must
  333. X    be issued before any request command.
  334. X
  335. X    REPLY <address>
  336. X    ---------------
  337. X      The return address used by the server is set to the indicated
  338. X      <address>. This must be a valid address by which you can be
  339. X      reached. It should contain a domain-based address.
  340. X      Use this command if you are not sure that the return addresses
  341. X      generated by your mail system are reliable.
  342. X      The address specified with this command will be used by the
  343. X      server to confirm receipt.
  344. X
  345. X    UUCP <host>!<path> <user>
  346. X    -------------------------
  347. X      The mail server will transfer requests to the indicated host
  348. X      using UUCP. The host must be known to the server system.
  349. X      Requests will be transferred to the indicated <path>. UUCP
  350. X      notification messages will be send to <user>.
  351. X
  352. X    MAIL <address>
  353. X    --------------
  354. X      The mail server will transfer requests to the indicated address
  355. X      using e-mail. This is the default transfer method for the
  356. X      server. You must specify a valid (preferable domain-based)
  357. X      address by which you can be reached.
  358. X      If no UUCP nor MAIL commands have been issued, requests will be
  359. X      send to the recipient as specified by a REPLY command, or
  360. X      dereived from the mail headers.
  361. X
  362. X 2. Transfer parameters. These parameters may be set as often as
  363. X    needed. Setting transfers parameters affects only requests that
  364. X    follow these commands.
  365. X
  366. X    LIMIT <number>
  367. X    --------------
  368. X      Specify the maximum number of Kbytes which may be sent in a single
  369. X      transfer. Requests that exceed this amount will be split
  370. X      before sending.
  371. X      The amount may be specified with a trailing K, e.g. "30K".
  372. X      The default value is 64K.
  373. X      NOTE: due to overhead, it is possible that the size of the
  374. X      mail which reaches you will (slightly) exceed this limit.
  375. X
  376. X    UUENCODE
  377. X    --------
  378. X    XXENCODE
  379. X    --------
  380. X    UUE
  381. X    ---
  382. X    BTOA
  383. X    ----
  384. X      The requested files will be encoded using the indicated encoding
  385. X      method. 
  386. X      Not all methods need to be available in the server installation.
  387. X
  388. X    CWD [<path>]
  389. X    ------------
  390. X      Sets (or cancels) the current working directory for subsequent
  391. X      commands. CWD commands do not nest, e.g. after "CWD foo; CWD bar"
  392. X      the current directory will be "bar", not "foo/bar".
  393. X
  394. X 3. Request commands. 
  395. X
  396. X    INDEX [<item>]
  397. X    --------------
  398. X      The specified <item> is looked up in the server archives. If
  399. X      found, a list of all items that match the request is returned.
  400. X      For example, "INDEX gcc" will return a list of every item in the
  401. X      server archives that has "gcc" in its name or path.
  402. X      "INDEX" without arguments will request for a file INDEX in the
  403. X      archives, if present.
  404. X      Since index requests can return a huge amount of information,
  405. X      the number of lines returned is limited to (usually) a few
  406. X      houndred lines. 
  407. X
  408. X    SEARCH <item>
  409. X    -------------
  410. X      The specified <item> is looked up in the server archives. If
  411. X      found, a list of all items that match the request is returned.
  412. X      SEARCH is more limited that INDEX. It returns only archive
  413. X      entries that are eligible to be found by a SEND command.
  414. X      This can be used to find out which versions of a specific package
  415. X      can be found on the server, and where.
  416. X      For example, "SEARCH gcc" will return a list of every item in the
  417. X      server archives that has a name that starts with "gcc", followed
  418. X      by something that looks like a version number, and ends with
  419. X      ".tar.Z" or some other predefined extension.
  420. X
  421. X    SEND <item> [<item>...]
  422. X    -----------------------
  423. X      The specified <item>s are looked up in the server archives. If
  424. X      found, they will be sent to you. Multiple items may be
  425. X      specified with one SEND command.
  426. X      If a SEARCH request for the named item returns multiple
  427. X      possibilities, the SEND request will be treated as a SEARCH, 
  428. X      i.e. a list of possibilities is returned.
  429. X      NOTE: the names of the <item>s are case sentive!
  430. X
  431. X    RESEND <item> <part> [<part>...]
  432. X    --------------------------------
  433. X      Re-send the indicated <part>s of this item. This is useful if not
  434. X      all parts of a multi-parts transmission did arrive correctly.
  435. X      When re-transmitting, the encoding and limit used must be
  436. X      identical to those of the original transmission.
  437. X
  438. X    PACK <method>
  439. X    -----------
  440. X      Subsequent SEND requests must select directies. This directory
  441. X      will be packed into a file using the indicated method, and
  442. X      transferred.  <method> may be "tar", "zoo" or "zip".  If
  443. X      <method> is "off", subsequent request are treated normally.
  444. X      NOTE: <method> "tar" means "compressed tar".  A limit (usually
  445. X      2Mb) is imposed on the total size of the files in the
  446. X      directories.
  447. X
  448. X 4. Misc. commands
  449. X
  450. X    HELP
  451. X    ----
  452. X      This command gives a brief list of server commands.
  453. X      Note that this is NOT the same as the "SEND HELP" command.
  454. X      The latter command will send this document.
  455. X
  456. X    TEST
  457. X    ----
  458. X      This command is for testing. No files will be sent if you use
  459. X      this, but a confirmation message will be sent to the return path as
  460. X      determined from the mail headers or the REPLY command.  You may
  461. X      use this to find out if your address is valid, and to check the
  462. X      status of your request.
  463. X
  464. X    BEGIN
  465. X    -----
  466. X      Ignore anything above this line, and start looking for commands.
  467. X      This command can be used to discard incorrect responses, errors
  468. X      etc. that may result from input that was not directed to the mail
  469. X      server itself.
  470. X
  471. X    END or EXIT
  472. X    -----------
  473. X      The remainder of the message is ignored. This can be useful if a
  474. X      .signature is appended to the message.
  475. X
  476. X
  477. XSample Mail Server Report (email transfer)
  478. X==========================================
  479. X
  480. XSending:
  481. X
  482. X    mail jv@mh.nl
  483. X    btoa
  484. X        index bio
  485. X    search bio
  486. X    send bio
  487. X    resend zoo 2 3 4
  488. X    send foo
  489. X    end
  490. X
  491. Xwill generate the following report:
  492. X
  493. X    From: Mail Server <mserv@mh.nl>
  494. X[1]    To: jv@mhres.mh.nl
  495. X    Subject: Request by jv
  496. X    Date: Sun, 1 Oct 92 18:25:39 MET (+0100)
  497. X
  498. X    Processing mail headers ...
  499. X[2]    Default return address: "jv@mhres.mh.nl"
  500. X
  501. X    Processing message contents...
  502. X
  503. X    Command: mail jv@mh.nl
  504. X[3]    => Transfer via email to "jv@mh.nl"
  505. X
  506. X    Command: btoa
  507. X    => Encoding = btoa
  508. X
  509. X    Command: index bio
  510. X    => Index: bio
  511. X
  512. X    Command: search bio
  513. X    => Search: bio
  514. X
  515. X    Command: send bio HELP
  516. X    => Return address: "jv"
  517. X    => Send: bio
  518. X    => Send: HELP
  519. X
  520. X    Command: resend zoo 2 3 4
  521. X    => Resend: zoo, parts 2,3,4
  522. X
  523. X    Command: send foo
  524. X    => Send: foo
  525. X
  526. X    Command: end
  527. X    => Okay
  528. X
  529. X    Your message has been processed.
  530. X
  531. X[4]    Index results:
  532. X
  533. X            Date     Size   Index: bio
  534. X      --------  -----   ---------------------------------
  535. X      91/07/10     2K   bio-2.4/Makefile
  536. X      91/07/06     3K   bio-2.4/README
  537. X      91/07/09    14K   bio-2.4/bio.diffs
  538. X      91/07/09    36K   bio-2.4/bio.tar.Z
  539. X      91/07/09    36K   bio-2.4/bio-2.4.tar.Z
  540. X      89/12/16     4K   fastio/stubio.c
  541. X
  542. X[5]    Search results:
  543. X
  544. X        Date     Size   Search: bio
  545. X      --------  -----   ---------------------------------
  546. X      91/07/09    36K   bio-2.4/bio.tar.Z
  547. X      91/07/09    36K   bio-2.4/bio-2.4.tar.Z
  548. X
  549. X[6]    Request "bio" is ambiguous:
  550. X
  551. X        Date     Size   Search: bio
  552. X      --------  -----   ---------------------------------
  553. X      91/07/09    36K   bio-2.4/bio.tar.Z
  554. X      91/07/09    36K   bio-2.4/bio-2.4.tar.Z
  555. X
  556. X[7]    Requests:
  557. X
  558. X      Request                       Size Enc Limit Status
  559. X      ---------------------------- ----- --- ----- -------
  560. X      bio                                          Ambiguous
  561. X      HELP                 11K  B    64K Queued
  562. X      zoo-2.1/zoo.TZ                171K  B    64K Queued (parts 2 3 4 only)
  563. X      foo                                          Unknown
  564. X
  565. X    The requests with status "Queued" will be sent as soon as the load of
  566. X    the server system permits, usually within 24 hours.
  567. X
  568. X    Mail Server finished.
  569. X
  570. XAs you can see, the return mail is sent to the address [1] extracted
  571. Xfrom the mail headers [2]. A REPLY command could have been used to
  572. Xsupply a different address.
  573. X
  574. XThe MAIL command [3] instructs the server to send the requests via
  575. Xemail to the given address. If the MAIL command had not been issued,
  576. Xthe address from the message header [2] would have been used.
  577. X
  578. XThe result from the INDEX command [4] returns info for every file in
  579. Xthe archives that have "bio" in its name or path.
  580. X
  581. XThe result from the SEARCH command [5] returns info for every file in
  582. Xthe archives that that is likely to be a selectable archive item.
  583. X
  584. XSince more than one file matches the request for "bio", it is turned
  585. Xinto a SEARCH command [6].
  586. X
  587. XIn the list of requests [7] the size and encoding of the files are
  588. Xshown. Note that the size is the size *before* encoding!
  589. XRequest "foo" could not be found and is skipped.
  590. X
  591. XSome time later the following mails will arrive:
  592. X
  593. X    From               Size      Subject
  594. X    --------------   ---------   ----------------------------------
  595. X    Mail Server      298/10175   "HELP (complete) ascii"
  596. X    Mail Server      829/65453   "zoo.TZ (part 2 of 4) btoa encoded"
  597. X    Mail Server      829/65453   "zoo.TZ (part 3 of 4) btoa encoded"
  598. X    Mail Server      325/25578   "zoo.TZ (part 4 of 4) btoa encoded"
  599. X
  600. XFiles which are sent in parts have all pieces clearly marked as such:
  601. X
  602. X    ------ begin of zoo.TZ -- btoa encoded -- part 2 of 4 ------
  603. X    #(_0M#C)R-&3BEIu9#I[oEFn;50r5kb6%CJq%=NMgE3in`tMpnX0rOEYPWNM...
  604. X    =69S\PiSodA"*lArTZ.-(g6DL2A6_5>DMuFV/&S7H/]XEgLe(l@e;-Rqr:iZ...
  605. X    ...
  606. X    ...
  607. X    $`eP&iGea"a#e[F!oeo1r@U/FP;::i"V)j_EW+.(U*&IrTJ+u'9=$MY7s*CC...
  608. X    uI=a5*Wj^#1LD,&>MZKY@H1_a9QE$$4[+?[ePhh"h2Ub"/a,(ES*ZH"nK"6d...
  609. X    ------ end of zoo.TZ -- btoa encoded -- part 2 of 4 ------
  610. X
  611. XSample Mail Server Report (uucp transfer)
  612. X=========================================
  613. X
  614. XSending:
  615. X
  616. X    uucp mhres!/usr/spool/uucppublic/receive/jv jv
  617. X    btoa
  618. X    limit 64K
  619. X    send bio-2.4
  620. X    resend zoo 2 3 4
  621. X    send foo
  622. X    end
  623. X
  624. Xwill generate the following report:
  625. X
  626. X    From: Mail Server <mserv@mh.nl>
  627. X[1]    To: jv@mhres.mh.nl
  628. X    Subject: Request by jv
  629. X    Date: Sun, 1 Oct 92 18:41:39 MET (+0100)
  630. X
  631. X    Mail Server V3.0 [process 3.21]
  632. X
  633. X    Processing mail headers ...
  634. X[2]    Default return address: "jv@mhres.mh.nl"
  635. X
  636. X    Processing message contents...
  637. X
  638. X    Command: uucp mhres!/usr/spool/uucppublic/receive/jv/server jv
  639. X[3]    => Transfer via UUCP to "mhres!/usr/spool/uucppublic/receive/jv/server"
  640. X    => (UUCP notification to: "jv")
  641. X
  642. X    Command: btoa
  643. X    => Encoding = btoa
  644. X
  645. X    Command: limit 64K
  646. X    => Limit = 64K
  647. X
  648. X    Command: send bio HELP
  649. X    => Return address: "jv"
  650. X    => Send: bio
  651. X    => Send: HELP
  652. X
  653. X    Command: resend zoo 2 3 4
  654. X    => Resend: zoo, parts 2,3,4
  655. X
  656. X    Command: send foo
  657. X    => Send: foo
  658. X
  659. X    Command: end
  660. X    => Okay
  661. X
  662. X    Your message has been processed.
  663. X
  664. X[4]    Requests:
  665. X
  666. X      Request                       Size Limit Remarks
  667. X      ---------------------------- ----- ----- -------
  668. X      bio-2.4/bio-2.4.tar.Z          36K   64K Queued
  669. X      HELP                 11K   64K Queued
  670. X      zoo-2.1/zoo.TZ                171K   64K Queued (parts 2 3 4 only)
  671. X      foo                                      Unknown
  672. X
  673. X    The requests with status "Queued" will be sent as soon as the load of
  674. X    the server system permits, usually within 24 hours.
  675. X
  676. X    Mail Server finished.
  677. X
  678. XAs you can see, the return mail is sent to the address [1] extracted
  679. Xfrom the mail headers [2]. A REPLY command could have been used to
  680. Xsupply a different address.
  681. X
  682. XThe UUCP command [3] instructs the server to send the requests via
  683. Xuucp to the given system.
  684. X
  685. XIn the list of requests [4] the size of the files is
  686. Xshown.
  687. XRequest "foo" could not be found and is skipped.
  688. X
  689. XSome time later the following files will arrive:
  690. X
  691. X    /usr/spool/uucppublic/receive/jv/server/bio.tar.Z
  692. X    /usr/spool/uucppublic/receive/jv/server/HELP
  693. X    /usr/spool/uucppublic/receive/jv/server/zoo.TZ/part02of04
  694. X    /usr/spool/uucppublic/receive/jv/server/zoo.TZ/part03of04
  695. X    /usr/spool/uucppublic/receive/jv/server/zoo.TZ/part04of04
  696. X
  697. XHistory
  698. X=======
  699. X
  700. XThis mail server has been developed by Johan Vromans at Multihouse
  701. XResearch. It is all written in Perl, except for one small C-wrapper
  702. Xprogram. 
  703. XThis software is Copyright 1988, 1992 by Johan Vromans, and may be
  704. Xdistributed according to the GNU Public Licence.
  705. X
  706. XVersion 1 was released in 1988 and has helped to develop Perl-2.
  707. XIt has been in full production at a number of sites ever since.
  708. XVersion 2 has never been released. 
  709. XThis is version 3, completely reworked, and requires Perl 4.019 or
  710. Xlater. 
  711. X
  712. XFor questions, information and remarks:
  713. X
  714. X    Johan Vromans
  715. X--
  716. XJohan Vromans                       jv@mh.nl via internet backbones
  717. XMultihouse Automatisering bv               uucp: ..!{uunet,hp4nl}!mh.nl!jv
  718. XDoesburgweg 7, 2803 PL Gouda, The Netherlands  phone/fax: +31 1820 62944/62500
  719. X------------------------ "Arms are made for hugging" -------------------------
  720. X
  721. XSCCS Info: @(#)@ HELP    3.9 - HELP
  722. END_OF_FILE
  723.   if test 15640 -ne `wc -c <'HELP'`; then
  724.     echo shar: \"'HELP'\" unpacked with wrong size!
  725.   fi
  726.   # end of 'HELP'
  727. fi
  728. if test -f 'mlistener.pl' -a "${1}" != "-c" ; then 
  729.   echo shar: Will not clobber existing file \"'mlistener.pl'\"
  730. else
  731.   echo shar: Extracting \"'mlistener.pl'\" \(4502 characters\)
  732.   sed "s/^X//" >'mlistener.pl' <<'END_OF_FILE'
  733. X#!/usr/local/bin/perl
  734. X# mlistener.pl -- make listener.c
  735. X# SCCS Status     : @(#)@ mlistener.pl    1.3
  736. X# Author          : Johan Vromans
  737. X# Created On      : Sun May 31 14:22:56 1992
  738. X# Last Modified By: Johan Vromans
  739. X# Last Modified On: Tue Jun  2 12:55:46 1992
  740. X# Update Count    : 18
  741. X# Status          : Unknown, Use with caution!
  742. X
  743. X$my_name = "mlistener.pl";
  744. X$my_version = "1.3";
  745. X#
  746. X################ Common stuff ################
  747. X
  748. X$libdir = $ENV{"MSERVLIB"} || "/usr/local/lib/mserv";
  749. Xrequire "./mserv_common.pl";    # USE CURRENT DIR, NOT LIBDIR!
  750. X
  751. X################ Options handling ################
  752. X
  753. X$opt_verbose = $opt_ident = $opt_help = 0;
  754. X$opt_setruid = $opt_setenv = $opt_uid = 0;
  755. X$opt_nosetruid = $opt_nosetenv = $opt_nouid = 0;
  756. X&options if @ARGV > 0 && $ARGV[0] =~ /^-+[^-]+/;
  757. Xprint STDERR ($my_package, " [", $my_name, " ", $my_version, "]\n")
  758. X    if $opt_ident || $opt_verbose;
  759. X
  760. X################ Main ################
  761. X
  762. X$mserv_uid = (getpwnam ($mserv_owner))[2];
  763. Xdie ("Cannot get UID for user $mserv_owner\n") unless defined $mserv_uid;
  764. X
  765. Xif ( $opt_verbose ) {
  766. X    print STDERR ("Using ", $have_setruid ? "setruid system call" :
  767. X          "'su' program", ".\n");
  768. X    print STDERR ("Using setenv library call.\n")
  769. X    if $have_setruid && $have_setenv;
  770. X    print STDERR ("Change to UID $mserv_uid.\n")
  771. X    if $have_setruid && $use_uid;
  772. X}
  773. X
  774. X$have_setruid |= $opt_setruid;
  775. X$have_setruid = 0 if $opt_nosetruid;
  776. X$have_setenv |= $opt_setenv;
  777. X$have_setenv = 0 if $opt_nosetenv || !$have_setruid;
  778. X$use_uid |= $opt_uid;
  779. X$use_uid = 0 if $opt_nouid || !$have_setruid;
  780. X
  781. Xrequire "ctime.pl";
  782. Xchop ($ctime = &ctime(time));
  783. X$uid = $use_uid ? ", uid = $mserv_uid" : "";
  784. X$opt = "";
  785. X$opt .= " setruid" if $have_setruid;
  786. X$opt .= " setenv" if $have_setenv;
  787. X$opt .= " useuid" if $use_uid;
  788. X
  789. Xprint <<EOD;
  790. X/* listener - receives mails and passes them to the mail server */
  791. X
  792. Xstatic char *SCCS_id[] = 
  793. X    {"@(#)@ Generated by mlistener.pl 1.3 on $ctime",
  794. X     "@(#)@ Configuration:",
  795. X     "@(#)@     Server  = $mserv_owner$uid",
  796. X     "@(#)@     Process = $libdir/process",
  797. X     "@(#)@     Options =$opt"};
  798. X
  799. X#include <stdio.h>
  800. XEOD
  801. Xprint <<EOD if $have_setruid && !$use_uid;
  802. X#include <pwd.h>
  803. XEOD
  804. Xprint <<EOD if $have_setruid;
  805. Xint setruid();
  806. XEOD
  807. Xprint <<EOD if $have_setruid && !$use_uid;
  808. Xint setrgid();
  809. XEOD
  810. Xprint <<EOD if $have_setenv;
  811. Xint setenv();
  812. XEOD
  813. Xprint <<EOD;
  814. X
  815. X/* In an attempt to leave some useful tracks upon failure, 
  816. X * we're gonna exit with special values.
  817. X */
  818. X#define abend(i)    exit(88+(i))
  819. X
  820. Xint chdir();
  821. X
  822. Xmain (argc, argv)
  823. Xint argc;
  824. Xchar *argv[];
  825. X{
  826. XEOD
  827. X
  828. Xif ( $have_setruid && $use_uid ) {
  829. X    print <<EOD;
  830. X    /* Change identity. */
  831. X    if (setruid ($mserv_uid) < 0) abend (1);
  832. XEOD
  833. X    print <<EOD if $have_setenv;
  834. X    setenv ("USER", "$mserv_owner", 1);
  835. X    setenv ("LOGNAME", "$mserv_owner", 1);
  836. X    setenv ("HOME", "/tmp", 1);
  837. XEOD
  838. X    print <<EOD;
  839. X    if (chdir ("/tmp") < 0) abend (3);
  840. X
  841. X    /* Execute the real listener */
  842. X    return execl ("$libdir/process", "process", (char*)0);
  843. X    abend (4);
  844. XEOD
  845. X}
  846. Xelsif ( $have_setruid ) {
  847. X    print <<EOD;
  848. X    struct passwd *pw;
  849. X
  850. X    /* Get info from system */
  851. X    pw = getpwnam ("$mserv_owner");
  852. X    if ( pw == NULL ) {
  853. X      perror ("getpwnam");
  854. X      exit (70);            /* Internal software error */
  855. X    }
  856. X
  857. X    /* Change identity. */
  858. X    if (setruid (pw->pw_uid) < 0) abend (1);
  859. X    if (setrgid (pw->pw_gid) < 0) abend (2);
  860. XEOD
  861. X    print <<EOD if $have_setenv;
  862. X    setenv ("USER", pw->pw_name, 1);
  863. X    setenv ("LOGNAME", pw->pw_name, 1);
  864. X    setenv ("HOME", pw->pw_dir, 1);
  865. XEOD
  866. X    print <<EOD;
  867. X    if (chdir (pw->pw_dir) < 0) abend (3);
  868. X
  869. X    /* Execute the real listener */
  870. X    return execl ("$libdir/process", "process", (char*)0);
  871. X    abend (4);
  872. XEOD
  873. X}
  874. Xelse {
  875. X    print <<EOD;
  876. X    /* Become root so we can so "su" w/o asking */
  877. X    if (setuid (0) < 0) abend (10);
  878. X    chdir ("/tmp");
  879. X
  880. X    /* Execute the real listener via "su" */
  881. X    return execl ("/bin/su", "su", "$mserv_owner", "-c", 
  882. X              "$libdir/process", (char*)0);
  883. X    abend (11);
  884. XEOD
  885. X}
  886. Xprint "}\n";
  887. X
  888. X################ Subroutines ################
  889. X
  890. Xsub options {
  891. X    require "newgetopt.pl";
  892. X    if ( !&NGetOpt ("setenv", "setruid", "nosetenv", "nosetruid",
  893. X            "uid", "nouid",
  894. X            "verbose", "ident", "help")
  895. X    || $opt_help
  896. X    || (@ARGV > 0)) {
  897. X    &usage;
  898. X    }
  899. X}
  900. X
  901. Xsub usage {
  902. X    print STDERR <<EndOfUsage;
  903. X$my_package [$my_name $my_version]
  904. X
  905. XUsage: $my_name [-help] [-ident]
  906. X
  907. XOptions:
  908. X    -[no]setruid  use (do not use) setruid system call
  909. X    -[no]setenv      use (do not use) setenv library call
  910. X    -help      this message
  911. X    -ident      print identification
  912. X    -verbose      supply verbose information
  913. XEndOfUsage
  914. X    exit (1);
  915. X}
  916. END_OF_FILE
  917.   if test 4502 -ne `wc -c <'mlistener.pl'`; then
  918.     echo shar: \"'mlistener.pl'\" unpacked with wrong size!
  919.   fi
  920.   # end of 'mlistener.pl'
  921. fi
  922. if test -f 'process.pl' -a "${1}" != "-c" ; then 
  923.   echo shar: Will not clobber existing file \"'process.pl'\"
  924. else
  925.   echo shar: Extracting \"'process.pl'\" \(24561 characters\)
  926.   sed "s/^X//" >'process.pl' <<'END_OF_FILE'
  927. X#!/usr/local/bin/perl
  928. X# process.pl -- 
  929. X# SCCS Status     : @(#)@ process    3.32
  930. X# Author          : Johan Vromans
  931. X# Created On      : ***
  932. X# Last Modified By: Johan Vromans
  933. X# Last Modified On: Tue Jun  9 11:45:48 1992
  934. X# Update Count    : 358
  935. X# Status          : Going steady.
  936. X
  937. X# This program processes mail messages, and enqueues requests for
  938. X# the mail server.
  939. X#
  940. X# For options and calling, see subroutine 'usage'.
  941. X#
  942. X$my_name = "process";
  943. X$my_version = "3.32";
  944. X#
  945. X################ Common stuff ################
  946. X
  947. X$libdir = $ENV{"MSERVLIB"} || "/usr/local/lib/mserv";
  948. Xunshift (@INC, $libdir);
  949. Xrequire "mserv_common.pl";
  950. X
  951. X################ Options handling ################
  952. X
  953. X&options if @ARGV > 0 && $ARGV[0] =~ /^-+[^-]+/;
  954. X@ARGV = ("-") unless @ARGV > 0;
  955. X
  956. X################ Setting up ################
  957. X
  958. X# All output goes to STDOUT, and will be mailed to the requestor.
  959. X# Create a temp file to catch all.
  960. X$tmpfile = "/usr/tmp/mserv$$";
  961. Xopen (STDOUT, ">" . $tmpfile) unless $opt_debug;
  962. X
  963. X# Motd.
  964. X&include ($notesfile);
  965. X
  966. X$errflag = 0;
  967. X$didhelp = 0;
  968. X$needhelp = 0;
  969. X
  970. X# Turn extensions into pattern.
  971. X($extpat = "(" . join("|", @exts) . ")") =~ s/\./\\./g;
  972. X
  973. X# Search strategy.
  974. X$dofilesearch = 1 unless $dodirsearch || $doindexsearch;
  975. X
  976. Xrequire "$libdir/rfc822.pl";
  977. X
  978. X&start_read (shift(@ARGV)) ||
  979. X    &die ("Cannot read input [$!]\n");
  980. X
  981. X# Flush "From_" line...
  982. Xif ( defined $rfc822'line_in_cache && $rfc822'line_in_cache =~ /^From / ) {
  983. X    undef $rfc822'line_in_cache;
  984. X}
  985. X
  986. Xprint STDOUT ("Processing mail headers...\n");
  987. X
  988. X$h_from = "";
  989. X$h_reply = "";
  990. X
  991. Xwhile ( $res = &read_header ) {
  992. X    last if $res == $rfc822'EMPTY_LINE;
  993. X    next unless $res == $rfc822'VALID_HEADER;
  994. X    $rfc822'header =~ tr/[A-Z]/[a-z]/;
  995. X    $h_from = $rfc822'contents if $rfc822'header eq "from";
  996. X    $h_reply = $rfc822'contents if $rfc822'header eq "reply-to";
  997. X}
  998. X
  999. X# Preset sender info.
  1000. X$h_from = $h_reply if $h_reply;
  1001. X$v_sender = $h_from;
  1002. X&parse_addresses ($h_from);
  1003. Xif ( @rfc822'addresses == 1 ) {        #'){
  1004. X    $h_from = $rfc822'addresses[0];    #';
  1005. X    $v_sender = $rfc822'addr_comments{$h_from} || $h_from;    #';
  1006. X}
  1007. X
  1008. X# Setup defaults.
  1009. X&reset;
  1010. Xprint STDOUT ("Default return address: \"$sender\"\n");
  1011. X
  1012. X# Since comments in programs need to be useful, it is not allowed to
  1013. X# place the comment "Command loop" here.
  1014. Xprint STDOUT ("\nProcessing message contents...\n\n");
  1015. X&command_loop;
  1016. Xprint STDOUT ("Your message has been processed.\n");
  1017. Xclose (STDIN);
  1018. X
  1019. Xif ( $commands == 0 ) {
  1020. X    print STDOUT ("No commands were found.\n");
  1021. X    &help;
  1022. X}
  1023. Xelsif ( $errflag ) {
  1024. X    print STDOUT ("Number of errors detected = $errflag.\n",
  1025. X          "NO WORK WILL BE DONE.\n");
  1026. X    &help unless $didhelp;
  1027. X}
  1028. Xelse {
  1029. X    print STDOUT ("\n");
  1030. X    require "$libdir/pr_doindex.pl", &index_loop if @indexq > 0;
  1031. X    &search_loop if @searchq > 0;
  1032. X    require "$libdir/pr_dowork.pl", &work_loop if @workq > 0;
  1033. X    &help if $needhelp && !$didhelp;
  1034. X}
  1035. X
  1036. X&include ($hintsfile) 
  1037. X    unless $didhelp || $opt_debug || $opt_nomail;
  1038. X
  1039. Xprint STDOUT ("\nMail Server finished.\n");
  1040. X
  1041. X# Send confirmation message to recipient.
  1042. X&confirm;
  1043. X
  1044. X# Startup the queue run in the background.
  1045. X&background_run ("$libdir/dorequest" . ($opt_trace ? " -trace": "")) 
  1046. X    if $auto_runrequest && !$opt_debug;
  1047. X
  1048. Xexit (0);
  1049. X
  1050. X################ Subroutines ################
  1051. X
  1052. Xsub search {
  1053. X    local ($request, $wantall) = @_;
  1054. X
  1055. X    # This function returns an array of strings, each describing one
  1056. X    # possibility. Each description is a NUL-joined string with fields:
  1057. X    #   - the basename (used for sorting)
  1058. X    #   - the size
  1059. X    #   - the last modification date
  1060. X    #   - the name of the library (LIB)
  1061. X    #   - the part between library and basename
  1062. X    #
  1063. X    # If $wantall == TRUE, all possibilities are returned.
  1064. X    # If $wantall == FALSE, one possibility is returned if the filesearch
  1065. X    # (failing that, the directory search) locates exactly one file.
  1066. X    # Otherwise, all possibilities are returned.
  1067. X
  1068. X    local (@ret) = ();
  1069. X
  1070. X    if ( $dofilesearch ) {
  1071. X    foreach $lib ( @libdirs ) {
  1072. X        push (@ret, &filesearch ($lib, $request));
  1073. X    }
  1074. X    }
  1075. X
  1076. X    if ( $dodirsearch && ($wantall || @ret != 1)) {
  1077. X    require "$libdir/pr_dsearch.pl";
  1078. X    foreach $lib ( @libdirs ) {
  1079. X        push (@ret, &dirsearch ($lib, $request));
  1080. X    }
  1081. X    }
  1082. X
  1083. X    if ( $doindexsearch && ($wantall || @ret != 1)) {
  1084. X    require "$libdir/pr_isearch.pl";
  1085. X    if ( $indexfile =~ m|^/| ) {
  1086. X        local ($lib) = defined $indexlib ? $indexlib 
  1087. X        : (&fnsplit($indexfile))[0];
  1088. X        push (@ret, &indexsearch ($indexfile, $lib, $request));
  1089. X    }
  1090. X    else {
  1091. X        foreach $lib ( @libdirs ) {
  1092. X        push (@ret, &indexsearch ("$lib/$indexfile", $lib, $request));
  1093. X        }
  1094. X    }
  1095. X    }
  1096. X
  1097. X    if ( $opt_debug || $opt_trace ) {
  1098. X    @ret = reverse ( sort (@ret));
  1099. X    print STDOUT ("=> Search queue:\n");
  1100. X    local ($i) = 1;
  1101. X    foreach $entry ( @ret ) {
  1102. X        local (@a) = &zu ($entry);
  1103. X        printf STDOUT ("  %3d: %s %s %s %s:%s:%s\n", $i, 
  1104. X               $a[0], $a[1], $a[2], $a[3], $a[4], $a[0]);
  1105. X        $i++;
  1106. X    }
  1107. X    @ret;
  1108. X    }
  1109. X    else {
  1110. X    reverse ( sort (@ret));
  1111. X    }
  1112. X}
  1113. X
  1114. Xsub filesearch {
  1115. X
  1116. X    local ($libdir, $request) = @_;
  1117. X
  1118. X    # Locate an archive item $request in library $libdir.
  1119. X    # Eligible items are in the format XXX or
  1120. X    # XXX.EXT, where EXT is one of the known extensions.
  1121. X    #
  1122. X    # See "sub search" for a description of the return values.
  1123. X
  1124. X    local (@retval);        # return value
  1125. X    local (@a);            # to hold stat() result
  1126. X
  1127. X    # Normalize the request. 
  1128. X    # $tryfile will be the basename of the request.
  1129. X    # $subdir holds the part between $libdir and $tryfile.
  1130. X    local ($subdir, $tryfile) = &fnsplit ($request);
  1131. X    $subdir .= "/" if $subdir && $subdir !~ m|/$|;
  1132. X    $libdir .= "/" if $libdir && $libdir !~ m|/$|;
  1133. X
  1134. X    print STDOUT ("Try file $libdir$subdir$tryfile...\n") if $opt_debug;
  1135. X
  1136. X    # First attempt: see if the given file exists 'as is', with possible 
  1137. X    # extensions
  1138. X
  1139. X    foreach $ext ( "", @exts) {
  1140. X    if ( -f $libdir.$subdir.$tryfile.$ext && -r _ ) {
  1141. X        @a = stat (_);
  1142. X        print STDOUT ("File $libdir$subdir$tryfile$ext (found)\n")
  1143. X        if $opt_debug;
  1144. X        push (@retval, 
  1145. X          &zp ($tryfile.$ext, $a[7], $a[9], $libdir, $subdir));
  1146. X    }
  1147. X    }
  1148. X
  1149. X    return @retval;
  1150. X}
  1151. X
  1152. Xsub confirm {
  1153. X
  1154. X    # Send the contents of the temp file to the requestor.
  1155. X
  1156. X    # Close it, and reopen.
  1157. X    close (STDOUT);
  1158. X    open (MESSAGE, $tmpfile);
  1159. X
  1160. X    if ( $opt_debug || $opt_nomail ) {
  1161. X    open (MAILER, ">&STDERR");
  1162. X    }
  1163. X    else {
  1164. X    open (MAILER, "|$sendmail '$recipient' $mserv_bcc");
  1165. X    }
  1166. X
  1167. X    print MAILER ("To: $recipient\n",
  1168. X          "Subject: Request by $v_sender\n");
  1169. X
  1170. X    if ( defined @x_headers ) {
  1171. X    foreach $hdr ( @x_headers ) {
  1172. X        print MAILER ($hdr, "\n");
  1173. X    }
  1174. X    }
  1175. X    print MAILER ("\n");
  1176. X
  1177. X    while ( <MESSAGE> ) {
  1178. X    # Suppress unrecognized stuff.
  1179. X    if ( $reset > 1 ) {
  1180. X        $reset-- if /^=> Resetting/;
  1181. X        if ( $reset > 1 ) {
  1182. X        print MAILER $' if /^Command: /;
  1183. X        }
  1184. X        else {
  1185. X        print MAILER $_;
  1186. X        }
  1187. X    }
  1188. X    else {
  1189. X        print MAILER $_;
  1190. X    }
  1191. X    }
  1192. X    close (MAILER);
  1193. X    close (MESSAGE);
  1194. X
  1195. X    # This aids in debugging...
  1196. X    rename ($tmpfile, "/usr/tmp/mserv.last");
  1197. X    unlink ($tmpfile);
  1198. X}
  1199. X
  1200. Xsub enqueue {
  1201. X
  1202. X    # Add a request to the queue.
  1203. X
  1204. X    local (@work) = @_;
  1205. X
  1206. X    if ( grep (/\s/, @work) ) {
  1207. X    return "Refused";
  1208. X    }
  1209. X
  1210. X    if (open (BATCH, ">>$queue")) {
  1211. X    if ( &locking (*BATCH, 1) == 1 ) {
  1212. X        seek (BATCH, 0, 2);
  1213. X        print BATCH (join (" ", @work), "\n");
  1214. X        close (BATCH);
  1215. X        $entries++;
  1216. X        if ( defined $plist && $plist =~ /\S/ ) {
  1217. X        local ($remarks) = "Queued (part";
  1218. X        $remarks .= "s" if $plist =~ /,/;
  1219. X        $remarks .= " ${plist} only)";
  1220. X        return $remarks;
  1221. X        }
  1222. X        else {
  1223. X        "Queued";
  1224. X        }
  1225. X
  1226. X    }
  1227. X    else {
  1228. X        "Queue error";
  1229. X    }
  1230. X    }
  1231. X    else {
  1232. X    "Cannot queue";
  1233. X    }
  1234. X}
  1235. X
  1236. Xsub dolist {
  1237. X    local ($list_type, $query, *found) = (@_);
  1238. X    local ($entries) = 0;
  1239. X    local ($name, $size, $date, $lib, $subdir); # elements of @found
  1240. X    local ($prev);        # to suppress duplicates
  1241. X    local (@tm);        # for time conversions
  1242. X
  1243. X    $~ = "list_header";
  1244. X    write;
  1245. X    $~ = "list_format";
  1246. X    $: = " /";        # break filenames at logical places
  1247. X    $= = 99999;
  1248. X
  1249. X    # have we found something?
  1250. X    unless ( @found > 0 ) {
  1251. X    $size = $date = "";
  1252. X    $name = "***not found***";
  1253. X    write;
  1254. X    next;
  1255. X    }
  1256. X
  1257. X    $prev = "";
  1258. X    foreach $found ( @found ) {
  1259. X
  1260. X    ($name, $size, $date, $lib, $subdir) = &zu ($found);
  1261. X
  1262. X    # Avoid duplicates.
  1263. X    next if $lib.$subdir.$name eq $prev;
  1264. X    $prev = $lib.$subdir.$name;
  1265. X
  1266. X    # Normalize size and date, if needed.
  1267. X    $size = int(($size+1023)/1024) . "K" unless $size =~ /K$/;
  1268. X    if ( $date =~ /^T/ ) {
  1269. X        $date = $';
  1270. X    }
  1271. X    else {
  1272. X        @tm = localtime ($date);
  1273. X        $date = sprintf("%02d/%02d/%02d", 
  1274. X                1900+$tm[5], $tm[4]+1, $tm[3]);
  1275. X    }
  1276. X
  1277. X    $name = $subdir.$name;
  1278. X    write;
  1279. X    }
  1280. X}
  1281. X
  1282. Xsub search_loop {
  1283. X
  1284. X    print STDOUT ("Search results:\n");
  1285. X
  1286. X    foreach $query ( @searchq ) {
  1287. X
  1288. X    local (@found);        # return from search
  1289. X
  1290. X    # Locate them.
  1291. X    @found = &search ($query, 1);
  1292. X
  1293. X    # Print report.
  1294. X    &dolist ("Search", $query, *found);
  1295. X
  1296. X    }
  1297. X
  1298. X    print STDOUT ("\n");
  1299. X}
  1300. X
  1301. Xsub reset {
  1302. X    # Set defaults.
  1303. X    @workq = ();
  1304. X    @searchq = ();
  1305. X    @indexq = ();
  1306. X    $commands = 0;
  1307. X    $errflag = 0;
  1308. X    $method = "";
  1309. X    @limits = @email_limits;    # assume mail
  1310. X
  1311. X    # Who sent this mail?
  1312. X    $sender = $h_from ? $h_from : "?";
  1313. X
  1314. X    # Who gets the replies?
  1315. X    $recipient = $sender;
  1316. X
  1317. X    # Destination for email transfers.
  1318. X    $destination = "";
  1319. X
  1320. X    # Destination for UUCP transfers.
  1321. X    $uupath = $uunote = "";
  1322. X
  1323. X    # Tally.
  1324. X    $reset++;
  1325. X}
  1326. X
  1327. Xsub errmsg {
  1328. X  local ($msg) = shift (@_);
  1329. X  print STDOUT ">>>>>>>> $msg\n";
  1330. X  $errflag++;
  1331. X}
  1332. X
  1333. Xsub include {
  1334. X    local ($file) = @_;
  1335. X    if ( open (NOTES, $file) ) {
  1336. X    while ( <NOTES> ) {
  1337. X        print STDOUT;
  1338. X    }
  1339. X    close (NOTES);
  1340. X    }
  1341. X}
  1342. X
  1343. Xsub fnsplit {
  1344. X    local ($file) = @_;
  1345. X    # Normalize $file -> ($dir, $basename)
  1346. X    local (@path) = split (m|/+|, $file);
  1347. X    (join ("/", @path[0..$#path-1]), $path[$#path]);
  1348. X}
  1349. X
  1350. X# Pseudo-record pack/unpack
  1351. Xsub zp { join ("\0", @_); }
  1352. Xsub zu { split (/\0/, $_[0]); }
  1353. X
  1354. Xsub command_loop {
  1355. X
  1356. X    local ($res, $cmd, @cmd);
  1357. X    local ($curdir) = "";
  1358. X
  1359. X    while ( $res = &read_body ) {
  1360. X
  1361. X    next if $res != $rfc822'DATA_LINE;    #';
  1362. X
  1363. X    if ( $rfc822'line =~ /\s*;\s*/ ) {        #'){
  1364. X        $rfc822'line_in_cache = "$'\n";
  1365. X        $rfc822'line = $`;
  1366. X    }
  1367. X
  1368. X    $commands++;
  1369. X    print STDOUT "Command: $rfc822'line\n";
  1370. X    @cmd = split (/[\t ,:=]+/, $rfc822'line);    #');
  1371. X    @cmd = grep ( $_ ne "", @cmd);
  1372. X
  1373. X    # get command verb, shifting leading "set" verb
  1374. X    do {
  1375. X        $cmd = shift (@cmd);
  1376. X        last unless $cmd;
  1377. X        $cmd  =~ tr/[a-z]/[A-Z]/;
  1378. X    } while ( $cmd eq "SET" );
  1379. X
  1380. X    ################ exit | end ################
  1381. X
  1382. X    if (( $cmd eq "EXIT" ) | ( $cmd eq "END" )) {
  1383. X        print STDOUT "=> Okay\n";
  1384. X        last;
  1385. X    }
  1386. X
  1387. X    ################ begin ################
  1388. X
  1389. X    if (( $cmd eq "BEGIN" )) {
  1390. X        print STDOUT "=> Resetting\n";
  1391. X        &reset;
  1392. X    }
  1393. X
  1394. X    ################ reply <address> ################
  1395. X
  1396. X    elsif ( $cmd eq "PATH" || $cmd eq "REPLY" ) {
  1397. X        if ( @workq + @searchq + @indexq ) {
  1398. X        &errmsg ("$cmd command must precede all other commands");
  1399. X        next;
  1400. X        }
  1401. X
  1402. X        shift (@cmd) if $cmd[0] =~ /to/i;
  1403. X
  1404. X        if ( @cmd == 1 ) {
  1405. X        &parse_addresses ($cmd[0]);
  1406. X        if ( @rfc822'addresses != 1 ) {    #'){
  1407. X            &errmsg ("Invalid return address: \"$cmd[0]\"");
  1408. X            next;
  1409. X        }
  1410. X        $recipient = shift (@rfc822'addresses);    #');
  1411. X        push (@workq, &zp ("M", $recipient));
  1412. X        print STDOUT "=> Return address: \"$recipient\"\n";
  1413. X        }
  1414. X        else {
  1415. X        &errmsg ("Usage: $cmd email-address");
  1416. X        }
  1417. X    }
  1418. X
  1419. X    ################ mail <address> ################
  1420. X
  1421. X    elsif ( $cmd eq "MAIL" ) {
  1422. X
  1423. X        if ( $method ne "" ) {
  1424. X        &errmsg ("$cmd command must precede other commands");
  1425. X        next;
  1426. X        }
  1427. X
  1428. X        shift (@cmd) if $cmd[0] =~ /to/i;
  1429. X
  1430. X        if ( @cmd == 1 ) {
  1431. X        &parse_addresses ($cmd[0]);
  1432. X        if ( @rfc822'addresses != 1 ) {    #'){
  1433. X            &errmsg ("Invalid return address: \"$sender\"");
  1434. X            next;
  1435. X        }
  1436. X        $method = "M";
  1437. X        $destination = $rfc822'addresses[0];    #';
  1438. X        push (@workq, &zp ("M", $destination));
  1439. X        print STDOUT ("=> Transfer via email to \"$destination\"\n");
  1440. X        @limits = @email_limits;
  1441. X        }
  1442. X        else {
  1443. X        &errmsg ("Usage: $cmd email-address");
  1444. X        }
  1445. X    }
  1446. X
  1447. X    ################ uucp <path> ################
  1448. X
  1449. X    elsif ( $cmd eq "UUCP" && defined $uucp ) {
  1450. X
  1451. X        if ( $method  ne "" ) {
  1452. X        &errmsg ("$cmd command must precede other commands");
  1453. X        next;
  1454. X        }
  1455. X
  1456. X        local ($msg) = "Usage: $cmd host!path user";
  1457. X
  1458. X        shift (@cmd) if $cmd[0] =~ /to/i;
  1459. X
  1460. X        if ( @cmd == 2 ) {
  1461. X        ($uupath, $uunote) = @cmd;
  1462. X
  1463. X        if ( $uupath =~ /!/ ) {
  1464. X            local ($host, $path) = ($`, $');
  1465. X            local ($ok);
  1466. X            ($ok = &check_uucp_name ($host)) ||
  1467. X            &errmsg ("Unknown UUCP system name: \"$host\"");
  1468. X            ($ok += &check_uucp_path ($path)) ||
  1469. X            &errmsg ("Invalid UUCP path name: \"$path\"");
  1470. X            if ( $ok == 2 ) {
  1471. X            $method = "U";
  1472. X            push (@workq, &zp ("U", $uupath, $uunote));
  1473. X            print STDOUT ("=> Transfer via UUCP to \"$uupath\"\n");
  1474. X            print STDOUT ("=> (UUCP notification to \"$uunote\")\n");
  1475. X            @limits = @uucp_limits;
  1476. X            }
  1477. X        }
  1478. X        else {
  1479. X            &errmsg ($msg);
  1480. X            next;
  1481. X        }
  1482. X        }
  1483. X        else {
  1484. X        &errmsg ($msg);
  1485. X        }
  1486. X    }
  1487. X
  1488. X    ################ limit [ <number>[K] ] ################
  1489. X
  1490. X    elsif ( $cmd eq "LIMIT" ) {
  1491. X
  1492. X        if ( @cmd == 0 ) {
  1493. X        push (@workq, &zp ("L", $limits[1]));
  1494. X        print STDOUT "=> Limit = $limits[1]K (default)\n";
  1495. X        }
  1496. X        elsif ( $cmd[0] =~ /^(\d+)K?$/i ) {
  1497. X        local ($new) = $1;
  1498. X        local ($msg) = "Warning: LIMIT must be between ".
  1499. X            "$limits[0]K and $limits[2]K";
  1500. X
  1501. X        if ( $new < $limits[0] ) {
  1502. X            $new = $limits[0];
  1503. X            &errmsg ($msg);
  1504. X            $errflag--;
  1505. X        }
  1506. X        elsif ( $new > $limits[2] ) {
  1507. X            $new = $limits[2];
  1508. X            &errmsg ($msg);
  1509. X            $errflag--;
  1510. X        }
  1511. X        push (@workq, &zp ("L", $new));
  1512. X        print STDOUT "=> Limit = ${new}K\n";
  1513. X        }
  1514. X        else {
  1515. X        &errmsg ("Usage: $cmd [ number[K] ]");
  1516. X
  1517. X        }
  1518. X    }
  1519. X
  1520. X    ################ various encoders ################
  1521. X
  1522. X    elsif ( $cmd eq "UUENCODE" || $cmd eq "UUDECODE" || $cmd eq "UU" ) {
  1523. X        &setencoding ("uuencoding", $uuencode, "U");
  1524. X    }
  1525. X    elsif ( $cmd eq "XXENCODE" || $cmd eq "XXDECODE" || $cmd eq "XX" ) {
  1526. X        &setencoding ("xxencoding", $xxencode, "X");
  1527. X    }
  1528. X    elsif ( $cmd eq "UUD" || $cmd eq "UUE" ) {
  1529. X        &setencoding ("uue", $uue, "D");
  1530. X    }
  1531. X    elsif ( $cmd eq "BTOA" || $cmd eq "ATOB") {
  1532. X        &setencoding ("btoa", $btoa, "B");
  1533. X    }
  1534. X
  1535. X    ################ send <item> [ <item>...] ################
  1536. X
  1537. X    elsif ( $cmd eq "SEND" || $cmd eq "TOPIC" || $cmd eq "GET" ) {
  1538. X
  1539. X        if ( @cmd > 0 ) {
  1540. X        foreach $item ( @cmd ) {
  1541. X            if ( $item =~ m:(^\.|/\.): ) {
  1542. X            &errmsg ("Illegal request");
  1543. X            }
  1544. X            else {
  1545. X            &setdefaults;
  1546. X            push (@workq, &zp ("S", $curdir.$item)); 
  1547. X            print STDOUT "=> Send: $curdir$item\n";
  1548. X            }
  1549. X        }
  1550. X        }
  1551. X        else {
  1552. X        &errmsg ("Usage: $cmd item [ item ... ]");
  1553. X        }
  1554. X    }
  1555. X
  1556. X    ################ resend <item> <number> [ <number>...] ################
  1557. X
  1558. X    elsif ( $cmd eq "RESEND" ) {
  1559. X
  1560. X        local ($msg) = "Usage: $cmd item part# [ part# ... ]";
  1561. X
  1562. X        if ( @cmd > 1 ) {
  1563. X        local ($item) = shift (@cmd);
  1564. X        local ($plist) = "";
  1565. X        if ( $item =~ m:(^\.|/\.): ) {
  1566. X            &errmsg ("Illegal request");
  1567. X            next;
  1568. X        }
  1569. X        foreach $num (@cmd) {
  1570. X            if ( $num =~ /^\d+$/ ) {
  1571. X            $plist .= 0+$num . ",";
  1572. X            }
  1573. X            else {
  1574. X            &errmsg ($msg);
  1575. X            last;
  1576. X            }
  1577. X        }
  1578. X        &setdefaults;
  1579. X        chop ($plist);
  1580. X        push (@workq, &zp ("S", $curdir.$item, $plist));
  1581. X        print STDOUT ("=> Resend: $curdir$item, part",
  1582. X                  (@plist > 0) ? "s " : " ",
  1583. X                  $plist, "\n");
  1584. X        }
  1585. X        else {
  1586. X        &errmsg ($msg);
  1587. X        }
  1588. X    }
  1589. X    
  1590. X    ################ pack ################
  1591. X
  1592. X    elsif ( $cmd eq "PACK" && defined $packing_limit && $packing_limit ) {
  1593. X
  1594. X        if ( @cmd == 1 ) {
  1595. X        local ($packing);
  1596. X
  1597. X        ($packing = $cmd[0]) =~ tr/[A-Z]/[a-z]/;
  1598. X        if ( ($packing eq "tar" && (-x $tar || -x $pdtar)) ||
  1599. X             ($packing eq "zip" && -x $zip) ||
  1600. X             ($packing eq "zoo" && -x $zoo) ) {
  1601. X            push (@workq, &zp ("P", $packing));
  1602. X            print STDOUT ("=> Subsequent directories will be ",
  1603. X                  "packed using $packing\n");
  1604. X        } 
  1605. X        elsif ( $packing eq "off" ) {
  1606. X            push (@workq, &zp ("P"));
  1607. X            print STDOUT "=> No more packing\n";
  1608. X        }
  1609. X        else {
  1610. X            &errmsg ("Wrong argument for PACK");
  1611. X        }
  1612. X        }
  1613. X        else {
  1614. X        &errmsg ("Usage: $cmd { ".
  1615. X             (-x $tar ? "tar | " : "").
  1616. X             (-x $zip ? "zip | " : "").
  1617. X             (-x $zoo ? "zoo | " : "").
  1618. X             "off }");
  1619. X        }
  1620. X    }
  1621. X
  1622. X    ################ search <item> [ <item>...] ################
  1623. X
  1624. X    elsif ( $cmd eq "SEARCH" ) {
  1625. X
  1626. X        if ( @cmd > 0 ) {
  1627. X        foreach $item ( @cmd ) {
  1628. X            if ( $item =~ m:(^\.|/\.): ) {
  1629. X            &errmsg ("Illegal request");
  1630. X            }
  1631. X            else {
  1632. X            push (@searchq, $curdir.$item);
  1633. X            print STDOUT "=> Search: $curdir$item\n";
  1634. X            }
  1635. X        }
  1636. X        }
  1637. X        else {
  1638. X        &errmsg ("Usage: $cmd item [ item ... ]");
  1639. X        }
  1640. X    }
  1641. X
  1642. X    ################ index ################
  1643. X    
  1644. X    elsif ( $cmd eq "INDEX" && ( @cmd == 0 || defined $indexfile ) ) {
  1645. X
  1646. X        if ( @cmd == 0 ) {
  1647. X        &setdefaults;
  1648. X        push (@workq, &zp ("S", $curdir."INDEX")); 
  1649. X        print STDOUT "=> Send: ${curdir}INDEX\n";
  1650. X        }
  1651. X        elsif ( @cmd > 0 ) {
  1652. X        foreach $item ( @cmd ) {
  1653. X            if ( $item =~ m:(^\.|/\.): ) {
  1654. X            &errmsg ("Illegal request");
  1655. X            }
  1656. X            else {
  1657. X            push (@indexq, $curdir.$item);
  1658. X            print STDOUT "=> Index: $curdir$item\n";
  1659. X            }
  1660. X        }
  1661. X        }
  1662. X        else {
  1663. X        &errmsg ("Usage: $cmd item [ item ... ]");
  1664. X        }
  1665. X    }
  1666. X
  1667. X    ################ help ################
  1668. X
  1669. X    elsif ( $cmd eq "HELP" ) {
  1670. X
  1671. X        if ( @cmd == 0 ) {
  1672. X        print STDOUT ("=> Okay, I'll append some help ".
  1673. X                  "at the end of this message\n");
  1674. X        $needhelp = 1;
  1675. X        }
  1676. X        else {
  1677. X        &errmsg ("HELP does not take any arguments ".
  1678. X             "(but you'll get help anyway)");
  1679. X        }
  1680. X    }
  1681. X
  1682. X    ################ test ################
  1683. X
  1684. X    elsif ( $cmd eq "TEST" ) {
  1685. X
  1686. X        if ( @cmd == 0 ) {
  1687. X        $opt_noqueue = 1;
  1688. X        print STDOUT "=> Okay\n";
  1689. X        }
  1690. X        else {
  1691. X        &errmsg ("Command $cmd unknown");
  1692. X        }
  1693. X    }
  1694. X
  1695. X    ################ cwd ################
  1696. X
  1697. X    elsif ( $cmd eq "CWD" || $cmd eq "REQUEST" ) {
  1698. X
  1699. X        if ( @cmd == 0 ) {
  1700. X        print STDOUT ("=> No current directory\n");
  1701. X        $curdir = "";
  1702. X        }
  1703. X        elsif ( @cmd == 1 ) {
  1704. X        if ( $cmd[0] =~ m:(^\.|/\.): ) {
  1705. X            &errmsg ("Illegal directory");
  1706. X        }
  1707. X        else {
  1708. X            $curdir = $cmd[0];
  1709. X            print STDOUT ("=> Current directory = $curdir\n");
  1710. X            $curdir .= "/" unless $curdir =~ m|/$|;
  1711. X        }
  1712. X        }
  1713. X        else {
  1714. X        &errmsg ("Usage: $cmd [ path ]");
  1715. X        }
  1716. X    }
  1717. X
  1718. X    ################ UNKNOWN ################
  1719. X
  1720. X    else {
  1721. X        &errmsg ("Command $cmd unknown");
  1722. X    }
  1723. X
  1724. X    ################ End of Commands ################
  1725. X
  1726. X    print STDOUT "\n";
  1727. X    }
  1728. X}
  1729. X
  1730. Xsub setdefaults {
  1731. X
  1732. X    unless ( $recipient ) {
  1733. X    $recipient = $sender;
  1734. X    print STDOUT ("=> Return address: \"$recipient\"\n");
  1735. X    }
  1736. X
  1737. X    unless ( $method ) {
  1738. X    $method = "M";
  1739. X    $destination = $recipient unless $destination ne "";
  1740. X    push (@workq, &zp ("M", $destination));
  1741. X    print STDOUT ("=> Transfer via email to \"$destination\"\n");
  1742. X    @limits = @email_limits;
  1743. X    }
  1744. X}
  1745. X
  1746. Xsub setencoding {
  1747. X    local ($tag, $encoder, $encoding) = @_;
  1748. X    if ( @cmd == 0 ) {
  1749. X    if ( -x $encoder ) {
  1750. X        push (@workq, &zp ("E", $encoding));
  1751. X        print STDOUT "=> Encoding = $encoding ($tag)\n";
  1752. X    }
  1753. X    else {
  1754. X        print STDOUT "=> Encoding '$tag' not available\n";
  1755. X    }
  1756. X    }
  1757. X    else {
  1758. X    $tag =~ tr/a-z/A-Z/;
  1759. X    &errmsg ("$tag does not take any arguments");
  1760. X    }
  1761. X}
  1762. X
  1763. Xsub die {
  1764. X    local ($msg) = "@_";
  1765. X    print STDOUT ($msg, "\n");
  1766. X    $sender = $sender || $mserv_owner || $mserv_bcc || "postmaster";
  1767. X    $mserv_bcc = $mserv_owner;
  1768. X    &confirm;
  1769. X    exit (1);
  1770. X}
  1771. X
  1772. Xsub background_run {
  1773. X    local ($cmd) = @_;
  1774. X
  1775. X    # Run $cmd in the background.
  1776. X
  1777. X    local ($pid);
  1778. X
  1779. X    if ( ($pid = fork) == 0 ) {
  1780. X
  1781. X    # Child process. Disable signals.
  1782. X    foreach $sig ( "HUP", "INT", "QUIT" ) {
  1783. X        $SIG{$sig} = "IGNORE";
  1784. X    }
  1785. X
  1786. X    # Fork another child to do the job.
  1787. X    if ( fork == 0 ) {
  1788. X        # Execute command. No way to signal failure.
  1789. X        exec $cmd;
  1790. X        exit (0);
  1791. X    }
  1792. X
  1793. X    }
  1794. X
  1795. X    # Wait for first child to complete. 
  1796. X    # This assures that the signals are armed before the parent can do
  1797. X    # harmful things.
  1798. X    waitpid ($pid, 0);
  1799. X}
  1800. X
  1801. Xsub check_uucp_name {
  1802. X    return 1 unless $uuname ne "";
  1803. X    local ($host) = @_;
  1804. X    open ( UUNAME, $uuname . "|" );
  1805. X    local (@hosts) = <UUNAME>;
  1806. X    close (UUNAME);
  1807. X    @found = grep ( /^$host$/, @hosts );
  1808. X    return @found == 1;
  1809. X}
  1810. X
  1811. Xsub check_uucp_path {
  1812. X    local ($path) = @_;
  1813. X    # $path should start with slash or tilde.
  1814. X    $path =~ /^[\/~]/;
  1815. X}
  1816. X
  1817. Xsub options {
  1818. X    require "newgetopt.pl";
  1819. X    $opt_debug = $opt_trace = $opt_nomail = $opt_noqueue = $opt_help = 0;
  1820. X    if ( !&NGetOpt ("debug", "trace", "noqueue", "nomail", "help")
  1821. X    || $opt_help
  1822. X    || (@ARGV > 0 && !($opt_debug || $opt_trace || $opt_nomail))) {
  1823. X    &usage;
  1824. X    }
  1825. X}
  1826. X
  1827. Xsub usage {
  1828. X    print STDERR <<EndOfUsage;
  1829. X$my_package [$my_name $my_version]
  1830. X
  1831. XUsage: $my_name [-help] [-noqueue] [-debug] < mail-message
  1832. X
  1833. XOptions:
  1834. X    -help    this message
  1835. X    -noqueue    process message, but do not enter request
  1836. X    -nomail    do not reply by email (testing only)
  1837. X    -debug    for debugging
  1838. X    -trace    for debugging
  1839. X
  1840. X'mail-message' should be RFC-822 conformant.
  1841. XEndOfUsage
  1842. X    exit (1);
  1843. X}
  1844. X
  1845. Xformat M_header =
  1846. X
  1847. X  Request                                        Size  Enc  Limit  Status
  1848. X  --------------------------------------------  -----  ---  -----  ------
  1849. X.
  1850. Xformat M_list =
  1851. X  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@>>>>>>  @||  @>>>>  @<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1852. X$name, $size, $coding, $limit, $remarks
  1853. X~~  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1854. X$name
  1855. X.
  1856. Xformat U_header =
  1857. X
  1858. X  Request                                        Size  Limit  Status
  1859. X  --------------------------------------------  -----  -----  ------
  1860. X.
  1861. Xformat U_list =
  1862. X  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<@>>>>>>  @>>>>  @<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1863. X$name, $size, $limit, $remarks
  1864. X~~  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1865. X$name
  1866. X.
  1867. Xformat list_header =
  1868. X
  1869. X     Date       Size  @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1870. X$list_type . ": " . $query
  1871. X  ----------  ------  ----------------------------
  1872. X.
  1873. Xformat list_format =
  1874. X  @<<<<<<<<< @>>>>>>  ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1875. X$date, $size, $name
  1876. X~~                      ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  1877. X$name
  1878. X.
  1879. X
  1880. X# WARNING: ugly layout ahead!
  1881. X
  1882. Xsub help {
  1883. X# Auto-configuring help message.
  1884. Xprint STDOUT <<SquirrelTail;
  1885. XValid server commands are:
  1886. X
  1887. XBEGIN
  1888. X    Discard anything above this line, and start processing commands.
  1889. XREPLY <address>
  1890. X    Specify return address for replies. Use this if you are not sure that
  1891. X    your mail system generates correct return addresses.
  1892. XMAIL <address>
  1893. X    Requests will be sent via email to <address>. This is the default.
  1894. XSquirrelTail
  1895. X
  1896. Xprint STDOUT <<SquirrelTail if defined $uucp;
  1897. XUUCP <host>!<path> <user>
  1898. X    Requests will be sent via uucp to <host>!<path>. The <user> on
  1899. X    <host> will be notified. <path> must be writable by the UUCP
  1900. X    system on <host>.
  1901. XSquirrelTail
  1902. X
  1903. Xlocal ($l) = "";
  1904. X$l = " and $uucp_limits[1]K bytes for UUCP" if defined $uucp;
  1905. Xprint STDOUT <<SquirrelTail;
  1906. XLIMIT <number>
  1907. X    Maximum number of Kbytes to be sent per transfer.
  1908. X    Default is $email_limits[1]K bytes for email$l.
  1909. X    The limit applies to subsequent "send" commands.
  1910. XSquirrelTail
  1911. X
  1912. Xprint ("BTOA\n")    if -x $btoa;
  1913. Xprint ("UUE\n")        if -x $uue;
  1914. Xprint ("XXENCODE\n")    if -x $xxencode;
  1915. Xprint STDOUT <<SquirrelTail;
  1916. XUUENCODE
  1917. X    Specify encoding to be used. Default is UUENCODE.
  1918. X    The encoding applies to subsequent "send" commands.
  1919. XSquirrelTail
  1920. X
  1921. Xprint STDOUT <<SquirrelTail;
  1922. XCWD [<path>]
  1923. X    Sets or cancels the current working directory for subsequent commands.
  1924. XSquirrelTail
  1925. X
  1926. Xprint STDOUT <<SquirrelTail if defined $indexfile;
  1927. XINDEX [<item>...]
  1928. X    Look up everything in the archives that matches the <item>s.
  1929. X    If no <item>s are specified, requests for a file named "INDEX".
  1930. XSquirrelTail
  1931. X
  1932. Xprint STDOUT <<SquirrelTail;
  1933. XSEARCH <item> [<item>...]
  1934. X    Look up the indicated archive entries, and return a list of 
  1935. X    files found.
  1936. XSEND <item> [<item>...]
  1937. X    Specify the items to be sent.
  1938. XRESEND <item> <part> [<part>...]
  1939. X    Re-sends the indicated <parts> from the specified <item>.
  1940. X    The encoding and limit must be identical to those used in the
  1941. X    original request.
  1942. XSquirrelTail
  1943. X
  1944. Xif ( defined $packing_limit ) {
  1945. X    print STDOUT "PACK {";
  1946. X    print STDOUT " TAR |" if -x $tar || -x $pdtar;
  1947. X    print STDOUT " ZOO |" if -x $zoo;
  1948. X    print STDOUT " ZIP |" if -x $zip;
  1949. Xprint STDOUT <<SquirrelTail;
  1950. X OFF }
  1951. X    Subsequent requests must specify directories, which will be
  1952. X    packed using the indicated method and transferred.
  1953. X    "PACK OFF" cancels packing.
  1954. XSquirrelTail
  1955. X}
  1956. X
  1957. Xprint STDOUT <<SquirrelTail;
  1958. XHELP
  1959. X    This message.
  1960. X    Use "send HELP" for a more detailed description on how to use
  1961. X    the archive server.
  1962. XEND
  1963. XEXIT
  1964. X    Terminate command processing. The remainder of
  1965. X    the input will be ignored.
  1966. X
  1967. XCase is insignificant in the command verbs, but it is
  1968. Xsignificant in the <path> and <item> specifications.
  1969. X
  1970. XSquirrelTail
  1971. X$didhelp = 1;
  1972. X}
  1973. END_OF_FILE
  1974.   if test 24561 -ne `wc -c <'process.pl'`; then
  1975.     echo shar: \"'process.pl'\" unpacked with wrong size!
  1976.   fi
  1977.   # end of 'process.pl'
  1978. fi
  1979. echo shar: End of archive 1 \(of 4\).
  1980. cp /dev/null ark1isdone
  1981. MISSING=""
  1982. for I in 1 2 3 4 ; do
  1983.     if test ! -f ark${I}isdone ; then
  1984.     MISSING="${MISSING} ${I}"
  1985.     fi
  1986. done
  1987. if test "${MISSING}" = "" ; then
  1988.     echo You have unpacked all 4 archives.
  1989.     rm -f ark[1-9]isdone
  1990. else
  1991.     echo You still must unpack the following archives:
  1992.     echo "        " ${MISSING}
  1993. fi
  1994. exit 0
  1995. exit 0 # Just in case...
  1996.