home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / ftpmail / part02 < prev    next >
Encoding:
Text File  |  1993-05-15  |  50.3 KB  |  1,912 lines

  1. Newsgroups: comp.sources.misc
  2. From: lmjm@doc.ic.ac.uk (Lee M J McLoughlin)
  3. Subject: v37i052:  ftpmail - Automatic Email to FTP Gateway, v1.13, Part02/02
  4. Message-ID: <1993May11.193144.22713@sparky.imd.sterling.com>
  5. X-Md4-Signature: 28cfc2033e24e811711c75d0d5f81a9f
  6. Date: Tue, 11 May 1993 19:31:44 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: lmjm@doc.ic.ac.uk (Lee M J McLoughlin)
  10. Posting-number: Volume 37, Issue 52
  11. Archive-name: ftpmail/part02
  12. Environment: UNIX, Perl, Sun, Dec, INET
  13.  
  14. #! /bin/sh
  15. # This is a shell archive.  Remove anything before this line, then feed it
  16. # into a shell via "sh file" or similar.  To overwrite existing files,
  17. # type "sh file -c".
  18. # Contents:  auth chat2.pl config.pl crontab dq.pl inst.pl
  19. #   mmdf_maildelivery pp_mailfilter sendmail_forward socket.ph
  20. #   support.pl
  21. # Wrapped by kent@sparky on Tue May 11 12:58:18 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 2 (of 2)."'
  25. if test -f 'auth' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'auth'\"
  27. else
  28.   echo shar: Extracting \"'auth'\" \(65 characters\)
  29.   sed "s/^X//" >'auth' <<'END_OF_FILE'
  30. X# Patterns for who is authorised to use ftpmail
  31. X#
  32. X# anyone
  33. X.*@.*
  34. END_OF_FILE
  35.   if test 65 -ne `wc -c <'auth'`; then
  36.     echo shar: \"'auth'\" unpacked with wrong size!
  37.   fi
  38.   # end of 'auth'
  39. fi
  40. if test -f 'chat2.pl' -a "${1}" != "-c" ; then 
  41.   echo shar: Will not clobber existing file \"'chat2.pl'\"
  42. else
  43.   echo shar: Extracting \"'chat2.pl'\" \(9620 characters\)
  44.   sed "s/^X//" >'chat2.pl' <<'END_OF_FILE'
  45. X# chat.pl: chat with a server
  46. X# Based on: V2.01.alpha.7 91/06/16
  47. X# Randal L. Schwartz (was <merlyn@iwarp.intel.com>)
  48. X# multihome additions by A.Macpherson@bnr.co.uk
  49. X# allow for /dev/pts based systems by Joe Doupnik <JRD@CC.USU.EDU>
  50. X
  51. Xpackage chat;
  52. X
  53. Xif( defined( &main'PF_INET ) ){
  54. X    $pf_inet = &main'PF_INET;
  55. X    $sock_stream = &main'SOCK_STREAM;
  56. X    local($name, $aliases, $proto) = getprotobyname( 'tcp' );
  57. X    $tcp_proto = $proto;
  58. X}
  59. Xelse {
  60. X    # XXX hardwired $PF_INET, $SOCK_STREAM, 'tcp'
  61. X    # but who the heck would change these anyway? (:-)
  62. X    $pf_inet = 2;
  63. X    $sock_stream = 1;
  64. X    $tcp_proto = 6;
  65. X}
  66. X
  67. X
  68. X$sockaddr = 'S n a4 x8';
  69. Xchop($thishost = `hostname`);
  70. X
  71. X# *S = symbol for current I/O, gets assigned *chatsymbol....
  72. X$next = "chatsymbol000000"; # next one
  73. X$nextpat = "^chatsymbol"; # patterns that match next++, ++, ++, ++
  74. X
  75. X
  76. X## $handle = &chat'open_port("server.address",$port_number);
  77. X## opens a named or numbered TCP server
  78. X
  79. Xsub open_port { ## public
  80. X    local($server, $port) = @_;
  81. X
  82. X    local($serveraddr,$serverproc);
  83. X
  84. X    # We may be multi-homed, start with 0, fixup once connexion is made
  85. X    $thisaddr = "\0\0\0\0" ;
  86. X    $thisproc = pack($sockaddr, 2, 0, $thisaddr);
  87. X
  88. X    *S = ++$next;
  89. X    if ($server =~ /^(\d+)+\.(\d+)\.(\d+)\.(\d+)$/) {
  90. X        $serveraddr = pack('C4', $1, $2, $3, $4);
  91. X    } else {
  92. X        local(@x) = gethostbyname($server);
  93. X        return undef unless @x;
  94. X        $serveraddr = $x[4];
  95. X    }
  96. X    $serverproc = pack($sockaddr, 2, $port, $serveraddr);
  97. X    unless (socket(S, $pf_inet, $sock_stream, $tcp_proto)) {
  98. X        ($!) = ($!, close(S)); # close S while saving $!
  99. X        return undef;
  100. X    }
  101. X    unless (bind(S, $thisproc)) {
  102. X        ($!) = ($!, close(S)); # close S while saving $!
  103. X        return undef;
  104. X    }
  105. X    unless (connect(S, $serverproc)) {
  106. X        ($!) = ($!, close(S)); # close S while saving $!
  107. X        return undef;
  108. X    }
  109. X# We opened with the local address set to ANY, at this stage we know
  110. X# which interface we are using.  This is critical if our machine is
  111. X# multi-homed, with IP forwarding off, so fix-up.
  112. X    local($fam,$lport);
  113. X    ($fam,$lport,$thisaddr) = unpack($sockaddr, getsockname(S));
  114. X    $thisproc = pack($sockaddr, 2, 0, $thisaddr);
  115. X# end of post-connect fixup
  116. X    select((select(S), $| = 1)[0]);
  117. X    $next; # return symbol for switcharound
  118. X}
  119. X
  120. X## ($host, $port, $handle) = &chat'open_listen([$port_number]);
  121. X## opens a TCP port on the current machine, ready to be listened to
  122. X## if $port_number is absent or zero, pick a default port number
  123. X## process must be uid 0 to listen to a low port number
  124. X
  125. Xsub open_listen { ## public
  126. X
  127. X    *S = ++$next;
  128. X    local($thisport) = shift || 0;
  129. X    local($thisproc_local) = pack($sockaddr, 2, $thisport, $thisaddr);
  130. X    local(*NS) = "__" . time;
  131. X    unless (socket(NS, $pf_inet, $sock_stream, $tcp_proto)) {
  132. X        ($!) = ($!, close(NS));
  133. X        return undef;
  134. X    }
  135. X    unless (bind(NS, $thisproc_local)) {
  136. X        ($!) = ($!, close(NS));
  137. X        return undef;
  138. X    }
  139. X    unless (listen(NS, 1)) {
  140. X        ($!) = ($!, close(NS));
  141. X        return undef;
  142. X    }
  143. X    select((select(NS), $| = 1)[0]);
  144. X    local($family, $port, @myaddr) =
  145. X        unpack("S n C C C C x8", getsockname(NS));
  146. X    $S{"needs_accept"} = *NS; # so expect will open it
  147. X    (@myaddr, $port, $next); # returning this
  148. X}
  149. X
  150. X## $handle = &chat'open_proc("command","arg1","arg2",...);
  151. X## opens a /bin/sh on a pseudo-tty
  152. X
  153. Xsub open_proc { ## public
  154. X    local(@cmd) = @_;
  155. X
  156. X    *S = ++$next;
  157. X    local(*TTY) = "__TTY" . time;
  158. X    local($pty,$tty) = &_getpty(S,TTY);
  159. X    die "Cannot find a new pty" unless defined $pty;
  160. X    $pid = fork;
  161. X    die "Cannot fork: $!" unless defined $pid;
  162. X    unless ($pid) {
  163. X        close STDIN; close STDOUT; close STDERR;
  164. X        setpgrp(0,$$);
  165. X        if (open(DEVTTY, "/dev/tty")) {
  166. X            ioctl(DEVTTY,0x20007471,0);        # XXX s/b &TIOCNOTTY
  167. X            close DEVTTY;
  168. X        }
  169. X        open(STDIN,"<&TTY");
  170. X        open(STDOUT,">&TTY");
  171. X        open(STDERR,">&STDOUT");
  172. X        die "Oops" unless fileno(STDERR) == 2;    # sanity
  173. X        close(S);
  174. X        exec @cmd;
  175. X        die "Cannot exec @cmd: $!";
  176. X    }
  177. X    close(TTY);
  178. X    $next; # return symbol for switcharound
  179. X}
  180. X
  181. X# $S is the read-ahead buffer
  182. X
  183. X## $return = &chat'expect([$handle,] $timeout_time,
  184. X##     $pat1, $body1, $pat2, $body2, ... )
  185. X## $handle is from previous &chat'open_*().
  186. X## $timeout_time is the time (either relative to the current time, or
  187. X## absolute, ala time(2)) at which a timeout event occurs.
  188. X## $pat1, $pat2, and so on are regexs which are matched against the input
  189. X## stream.  If a match is found, the entire matched string is consumed,
  190. X## and the corresponding body eval string is evaled.
  191. X##
  192. X## Each pat is a regular-expression (probably enclosed in single-quotes
  193. X## in the invocation).  ^ and $ will work, respecting the current value of $*.
  194. X## If pat is 'TIMEOUT', the body is executed if the timeout is exceeded.
  195. X## If pat is 'EOF', the body is executed if the process exits before
  196. X## the other patterns are seen.
  197. X##
  198. X## Pats are scanned in the order given, so later pats can contain
  199. X## general defaults that won't be examined unless the earlier pats
  200. X## have failed.
  201. X##
  202. X## The result of eval'ing body is returned as the result of
  203. X## the invocation.  Recursive invocations are not thought
  204. X## through, and may work only accidentally. :-)
  205. X##
  206. X## undef is returned if either a timeout or an eof occurs and no
  207. X## corresponding body has been defined.
  208. X## I/O errors of any sort are treated as eof.
  209. X
  210. X$nextsubname = "expectloop000000"; # used for subroutines
  211. X
  212. Xsub expect { ## public
  213. X    if ($_[0] =~ /$nextpat/) {
  214. X        *S = shift;
  215. X    }
  216. X    local($endtime) = shift;
  217. X
  218. X    local($timeout,$eof) = (1,1);
  219. X    local($caller) = caller;
  220. X    local($rmask, $nfound, $timeleft, $thisbuf);
  221. X    local($cases, $pattern, $action, $subname);
  222. X    $endtime += time if $endtime < 600_000_000;
  223. X
  224. X    if (defined $S{"needs_accept"}) { # is it a listen socket?
  225. X        local(*NS) = $S{"needs_accept"};
  226. X        delete $S{"needs_accept"};
  227. X        $S{"needs_close"} = *NS;
  228. X        unless(accept(S,NS)) {
  229. X            ($!) = ($!, close(S), close(NS));
  230. X            return undef;
  231. X        }
  232. X        select((select(S), $| = 1)[0]);
  233. X    }
  234. X
  235. X    # now see whether we need to create a new sub:
  236. X
  237. X    unless ($subname = $expect_subname{$caller,@_}) {
  238. X        # nope.  make a new one:
  239. X        $expect_subname{$caller,@_} = $subname = $nextsubname++;
  240. X
  241. X        $cases .= <<"EDQ"; # header is funny to make everything elsif's
  242. Xsub $subname {
  243. X    LOOP: {
  244. X        if (0) { ; }
  245. XEDQ
  246. X        while (@_) {
  247. X            ($pattern,$action) = splice(@_,0,2);
  248. X            if ($pattern =~ /^eof$/i) {
  249. X                $cases .= <<"EDQ";
  250. X        elsif (\$eof) {
  251. X             package $caller;
  252. X            $action;
  253. X        }
  254. XEDQ
  255. X                $eof = 0;
  256. X            } elsif ($pattern =~ /^timeout$/i) {
  257. X            $cases .= <<"EDQ";
  258. X        elsif (\$timeout) {
  259. X             package $caller;
  260. X            $action;
  261. X        }
  262. XEDQ
  263. X                $timeout = 0;
  264. X            } else {
  265. X                $pattern =~ s#/#\\/#g;
  266. X            $cases .= <<"EDQ";
  267. X        elsif (\$S =~ /$pattern/) {
  268. X            \$S = \$';
  269. X             package $caller;
  270. X            $action;
  271. X        }
  272. XEDQ
  273. X            }
  274. X        }
  275. X        $cases .= <<"EDQ" if $eof;
  276. X        elsif (\$eof) {
  277. X            undef;
  278. X        }
  279. XEDQ
  280. X        $cases .= <<"EDQ" if $timeout;
  281. X        elsif (\$timeout) {
  282. X            undef;
  283. X        }
  284. XEDQ
  285. X        $cases .= <<'ESQ';
  286. X        else {
  287. X            $rmask = "";
  288. X            vec($rmask,fileno(S),1) = 1;
  289. X            ($nfound, $rmask) =
  290. X                 select($rmask, undef, undef, $endtime - time);
  291. X            if ($nfound) {
  292. X                $nread = sysread(S, $thisbuf, 1024);
  293. X                if ($nread > 0) {
  294. X                    $S .= $thisbuf;
  295. X                } else {
  296. X                    $eof++, redo LOOP; # any error is also eof
  297. X                }
  298. X            } else {
  299. X                $timeout++, redo LOOP; # timeout
  300. X            }
  301. X            redo LOOP;
  302. X        }
  303. X    }
  304. X}
  305. XESQ
  306. X        eval $cases; die "$cases:\n$@" if $@;
  307. X    }
  308. X    $eof = $timeout = 0;
  309. X    do $subname();
  310. X}
  311. X
  312. X## &chat'print([$handle,] @data)
  313. X## $handle is from previous &chat'open().
  314. X## like print $handle @data
  315. X
  316. Xsub print { ## public
  317. X    if ($_[0] =~ /$nextpat/) {
  318. X        *S = shift;
  319. X    }
  320. X    print S @_;
  321. X    if( $chat'debug ){
  322. X        print STDERR "printed:";
  323. X        print STDERR @_;
  324. X    }
  325. X}
  326. X
  327. X## &chat'close([$handle,])
  328. X## $handle is from previous &chat'open().
  329. X## like close $handle
  330. X
  331. Xsub close { ## public
  332. X    if ($_[0] =~ /$nextpat/) {
  333. X         *S = shift;
  334. X    }
  335. X    close(S);
  336. X    if (defined $S{"needs_close"}) { # is it a listen socket?
  337. X        local(*NS) = $S{"needs_close"};
  338. X        delete $S{"needs_close"};
  339. X        close(NS);
  340. X    }
  341. X}
  342. X
  343. X## @ready_handles = &chat'select($timeout, @handles)
  344. X## select()'s the handles with a timeout value of $timeout seconds.
  345. X## Returns an array of handles that are ready for I/O.
  346. X## Both user handles and chat handles are supported (but beware of
  347. X## stdio's buffering for user handles).
  348. X
  349. Xsub select { ## public
  350. X    local($timeout) = shift;
  351. X    local(@handles) = @_;
  352. X    local(%handlename) = ();
  353. X    local(%ready) = ();
  354. X    local($caller) = caller;
  355. X    local($rmask) = "";
  356. X    for (@handles) {
  357. X        if (/$nextpat/o) { # one of ours... see if ready
  358. X            local(*SYM) = $_;
  359. X            if (length($SYM)) {
  360. X                $timeout = 0; # we have a winner
  361. X                $ready{$_}++;
  362. X            }
  363. X            $handlename{fileno($_)} = $_;
  364. X        } else {
  365. X            $handlename{fileno(/'/ ? $_ : "$caller\'$_")} = $_;
  366. X        }
  367. X    }
  368. X    for (sort keys %handlename) {
  369. X        vec($rmask, $_, 1) = 1;
  370. X    }
  371. X    select($rmask, undef, undef, $timeout);
  372. X    for (sort keys %handlename) {
  373. X        $ready{$handlename{$_}}++ if vec($rmask,$_,1);
  374. X    }
  375. X    sort keys %ready;
  376. X}
  377. X
  378. X# ($pty,$tty) = $chat'_getpty(PTY,TTY):
  379. X# internal procedure to get the next available pty.
  380. X# opens pty on handle PTY, and matching tty on handle TTY.
  381. X# returns undef if can't find a pty.
  382. X# Modify "/dev/pty" to "/dev/pts" for Dell Unix v2.2 (aka SVR4.04). Joe Doupnik.
  383. X
  384. Xsub _getpty { ## private
  385. X    local($_PTY,$_TTY) = @_;
  386. X    $_PTY =~ s/^([^']+)$/(caller)[$[]."'".$1/e;
  387. X    $_TTY =~ s/^([^']+)$/(caller)[$[]."'".$1/e;
  388. X    local($pty, $tty, $kind);
  389. X    if( -e "/dev/pts000" ){        ## mods by Joe Doupnik Dec 1992
  390. X        $kind = "pts";        ## SVR4 Streams
  391. X    } else {
  392. X        $kind = "pty";        ## BSD Clist stuff
  393. X    }
  394. X    for $bank (112..127) {
  395. X        next unless -e sprintf("/dev/$kind%c0", $bank);
  396. X        for $unit (48..57) {
  397. X            $pty = sprintf("/dev/$kind%c%c", $bank, $unit);
  398. X            open($_PTY,"+>$pty") || next;
  399. X            select((select($_PTY), $| = 1)[0]);
  400. X            ($tty = $pty) =~ s/pty/tty/;
  401. X            open($_TTY,"+>$tty") || next;
  402. X            select((select($_TTY), $| = 1)[0]);
  403. X            system "stty nl>$tty";
  404. X            return ($pty,$tty);
  405. X        }
  406. X    }
  407. X    undef;
  408. X}
  409. X
  410. X1;
  411. END_OF_FILE
  412.   if test 9620 -ne `wc -c <'chat2.pl'`; then
  413.     echo shar: \"'chat2.pl'\" unpacked with wrong size!
  414.   fi
  415.   # end of 'chat2.pl'
  416. fi
  417. if test -f 'config.pl' -a "${1}" != "-c" ; then 
  418.   echo shar: Will not clobber existing file \"'config.pl'\"
  419. else
  420.   echo shar: Extracting \"'config.pl'\" \(7225 characters\)
  421.   sed "s/^X//" >'config.pl' <<'END_OF_FILE'
  422. X# Local configuration details for ftpmail.
  423. X#
  424. X# $Header: /a/swan/home/swan/staff/csg/lmjm/src/perl/mirror/ftpmail/RCS/config.pl,v 1.10 1993/04/25 20:27:48 lmjm Exp lmjm $
  425. X# $Log: config.pl,v $
  426. X# Revision 1.10  1993/04/25  20:27:48  lmjm
  427. X# Added mail_overhead.
  428. X#
  429. X# Revision 1.9  1993/04/25  14:14:58  lmjm
  430. X# Allow for multiple help files (one per language).
  431. X#
  432. X# Revision 1.8  1993/04/23  23:27:03  lmjm
  433. X# Massive renaming for sys5.
  434. X#
  435. X# Revision 1.7  1993/04/23  17:23:37  lmjm
  436. X# Renamed ftpmail-local-config.pl to ftpmail-config.pl
  437. X# Made pathnames relative to $ftpmail_dir
  438. X#
  439. X# Revision 1.6  1993/04/20  20:15:37  lmjm
  440. X# Don't attempt to reply to mail from ftpmail!
  441. X# Allow for a message of the day file.
  442. X#
  443. X# Revision 1.5  1993/04/15  14:17:44  lmjm
  444. X# Typos fixed.
  445. X# Ignore system and admin mail on advice from Christophe
  446. X#
  447. X# Revision 1.4  1993/04/13  10:34:37  lmjm
  448. X# Added more variables to tailor help messages.
  449. X# Dont recommend using ftpmail-request
  450. X# Changed job pausing.
  451. X#
  452. X# Revision 1.3  1993/03/30  20:32:21  lmjm
  453. X# By default use sendmail.
  454. X# By default use immediate.
  455. X# Max user settable limit to 100 K.
  456. X#
  457. X# Revision 1.2  1993/03/23  21:40:13  lmjm
  458. X# Now ftpmail_dir is ftpmail's home directory
  459. X# Added sendmail, mime and batched processing
  460. X#  based on work by Christophe.Wolfhugel@grasp.insa-lyon.fr.
  461. X#
  462. X
  463. X#-- Needs tailoring ----------------------------------------------------------
  464. X
  465. X# Parent directory of the system
  466. X# This is now the home direcory of the ftpmail account.
  467. X# $ftpmail_dir = "/src.doc.ic.ac.uk/public/ic.doc/ftpmail";
  468. X
  469. X# Default site to connect to
  470. X$default_site = 'src.doc.ic.ac.uk';
  471. X
  472. X# My hostname for Mime multipart message ids and help messages
  473. X$hostname = 'src.doc.ic.ac.uk';
  474. X
  475. X# ftpmail's full email address in help messages
  476. X$ftpmail_email = "ftpmail@$hostname";
  477. X
  478. X# Managers email address in help messages
  479. X$managers_email = "ukuug-soft@$hostname";
  480. X
  481. X# How to send mail - has "-s 'subj'" and the reply-to name appended
  482. X# Or use sendmail - this is a much better option.  Also the mime support
  483. X# is only available under sendmail.
  484. X#  If you give the -f ftpmail-request then all mail will appear to be
  485. X# sent by ftpmail-request.  This means that it will require a mailbox or
  486. X# alias.  Also beware that a *LOT* of users submit requests to ftpmail by
  487. X# replying to older messages to you will have to look out for this.  Using
  488. X# -f is therefor NOT recommended.
  489. X#$mail_cmd = "/usr/lib/sendmail -t -odi -f ftpmail-request";
  490. X$mail_cmd = "/usr/lib/sendmail -t -odi";
  491. X# $mail_cmd = "/usr/ucb/mail -v ";
  492. X
  493. X# A dumber mailer is one which thinks:
  494. X# mail 'Lee McLoughlin <lmjm@doc>' is a message to 3 accounts 'Lee', 'McLoughlin'
  495. X# and '<lmjm@doc>.  Most mailers these days are NOT dumb so leave this set to
  496. X# 0.
  497. X$dumb_mailer = 0;
  498. X
  499. X# ftpmail can process jobs in one of two ways
  500. X# immediate: after each get/dir/ls mail the result back to the user
  501. X# non-immedaite:  keep all the files received by get/dir/ls till the
  502. X#            entire jobs is done then mail the results back.  This may
  503. X#         use a lot of space.
  504. X$immediate = 0;
  505. X
  506. X# Cleanup input copies once queued.  If this is set to 0 then
  507. X# copies of all input will be left lying around - so cron will have
  508. X# to clean it.
  509. X$cleanup = 1;
  510. X
  511. X# If this file exists exit before the next parse of the queue.
  512. X$ftpmail_scan_end = "scan-end";
  513. X
  514. X# If set to 1 limit to just login=anonymous, passwd=-ftpmail/$replyto
  515. X$restricted = 0;
  516. X
  517. X# TODO:
  518. X# If set is the name of a file containing restrictions on when to
  519. X# attempt to connect to certain sites.  This can be used to allow only
  520. X# traffic to the local archive during busy times but allow connections
  521. X# everywhere the rest of the time.
  522. X#  Each line in the file is either a comment '#.*' or
  523. X# day of week: mon|tue|wed|thur|fri|say|sun, an hour range and a site pattern
  524. X# eg:  mon|tue|wed|thru|fri 9-18 src.doc.ic.ac.uk
  525. X#   only try jobs to the local site during working hours.
  526. X$time_restrictions = "restrictions";
  527. X
  528. X# TODO:
  529. X# Only allow ftp sessions to these sites - default is to all
  530. X# it is a regexp matching the sites
  531. X# $ftp_permitted = '^.*\.doc\.ic\.ac\.uk$';
  532. X
  533. X#-- needs checking -----------------------------------------------------------
  534. X
  535. X# Paths for various commands
  536. X$btoa = '/usr/local/bin/btoa';
  537. X$uuencode = '/usr/local/bin/uuencode';
  538. X$compress = '/usr/ucb/compress';
  539. X
  540. X# -1 because the higher settings take a lot more time for only 
  541. X# a little improvement.
  542. X$gzip = '/usr/local/bin/gzip -1';
  543. X
  544. X# Mime stuff
  545. X$mime_version = '1.0';
  546. X$mmencode = '/usr/local/mailcap/mmencode';
  547. X
  548. X# Any reply-to name matching this pattern should not be replied to
  549. X$dont_reply_to = 'ftpmail|postmaster|mmdf|mailer-daemon|system|admin';
  550. X
  551. X#-- may tweek ---------------------------------------------------------------
  552. X
  553. X# How long to pause between parses of the queue
  554. X$between_runs_pause = 60; # seconds
  555. X
  556. X# Max no of commands in a job
  557. X$max_cmds = 100;
  558. X
  559. X# If a job fails how long to pause before retrying
  560. X$retry_pause = 6 * (60 * 60);  # 6 hours
  561. X
  562. X# Never try a job more than this many times.
  563. X$max_tries = 3;
  564. X
  565. X# Pause for this much after each mail sent to avoid flooding the email
  566. X# system.  Only set to 0 if using mail does NOT submit in background -
  567. X# so sendmail should have mail_pause set to 0.
  568. X$mail_pause = 0; # seconds
  569. X
  570. X# Files bigger than this are split up - can be reset by 'size num' in job
  571. X$def_max_size = 60 * 1024;
  572. X
  573. X# Upper limit on what the user can ask for in a size command
  574. X$max_size = 100 * 1024;
  575. X
  576. X# Asking to split up files smaller than this is ignored
  577. X$min_size = 10 * 1024;
  578. X
  579. X# This is the size, in bytes, of the extra bits that your mailer adds
  580. X# to messages.  It usuall the size of the mail headers (From:..,Date:...)
  581. X# Be careful is you have an X.400 mailer as the overheads may be larger.
  582. X$mail_overhead = 2048;
  583. X
  584. X# Files bigger than this are aborted - to avoid overflowing the
  585. X# mail system
  586. X$max_processing_size = 10 * 1024 * 1024;
  587. X
  588. X# When trying to connect to the ftp daemon
  589. X$ftp_port = 21;
  590. X$retry_call = 1;    # Do retry
  591. X$retry_attempts = 1;    #  but only ONCE
  592. X
  593. X
  594. X#-- probably OK ------------------------------------------------------------
  595. X
  596. X# All file/directory names are relative to ftpmail_dir
  597. X
  598. X# Where temp files are stored (including files being pulled back from
  599. X# remote sites).
  600. X$tmpdir = "tmp";
  601. X
  602. X# Where the ftpmail queue is stored.
  603. X$quedir = "queue";
  604. X
  605. X# Where copies of the input are kept (you have to remove these manually
  606. X# or via a cron job).
  607. X$incopydir = "tmp";
  608. X
  609. X# Where the authorisation file resides
  610. X$authfile = "auth";
  611. X
  612. X# Where to keep track of goings on!
  613. X$logfile = "log";
  614. X
  615. X# Directory containing help files.  helpdir/help is the
  616. X# default one returned.  I have this as a symlink to english.
  617. X$helpdir = "help";
  618. X
  619. X# Message of the day file.  If present then it is emailed back at
  620. X# the start of any email response.
  621. X$motdfile = "motd";
  622. X
  623. X# This file is used to lock processing by dq
  624. X# Not releative to $ftpmail_dir.  Keep it in /tmp so it gets wiped automatically
  625. X# on a system crash.
  626. X$lock = "/tmp/ftpmail.lock";
  627. X
  628. X# Used to log an ftp session (this is email back to the user)
  629. X$xferlog = "$tmpdir/xferlog";
  630. X
  631. X# Temp file where get's and dir's copy into before being emailed
  632. X$incoming = "$tmpdir/infile";
  633. X
  634. X#-- leave at very end-----------------------------------------------------
  635. X
  636. X# Make sure this package returns TRUE
  637. X1;
  638. END_OF_FILE
  639.   if test 7225 -ne `wc -c <'config.pl'`; then
  640.     echo shar: \"'config.pl'\" unpacked with wrong size!
  641.   fi
  642.   # end of 'config.pl'
  643. fi
  644. if test -f 'crontab' -a "${1}" != "-c" ; then 
  645.   echo shar: Will not clobber existing file \"'crontab'\"
  646. else
  647.   echo shar: Extracting \"'crontab'\" \(60 characters\)
  648.   sed "s/^X//" >'crontab' <<'END_OF_FILE'
  649. X15,45 * * * * /src.doc.ic.ac.uk/public/ic.doc/ftpmail/dq.pl
  650. END_OF_FILE
  651.   if test 60 -ne `wc -c <'crontab'`; then
  652.     echo shar: \"'crontab'\" unpacked with wrong size!
  653.   fi
  654.   # end of 'crontab'
  655. fi
  656. if test -f 'dq.pl' -a "${1}" != "-c" ; then 
  657.   echo shar: Will not clobber existing file \"'dq.pl'\"
  658. else
  659.   echo shar: Extracting \"'dq.pl'\" \(19116 characters\)
  660.   sed "s/^X//" >'dq.pl' <<'END_OF_FILE'
  661. X#!/usr/bin/perl -s
  662. X# Very simple ftpmail system
  663. X# De-Queue a transfer and do it
  664. X# By Lee McLoughlin <lmjm@doc.ic.ac.uk>
  665. X#  You can do what you like with this except claim that you wrote it or
  666. X#  give copies with changes not approved by Lee.  Neither Lee nor any other
  667. X#  organisation can be held liable for any problems caused by the use or
  668. X#  storage of this package.
  669. X#
  670. X# $Header: /a/swan/home/swan/staff/csg/lmjm/src/perl/mirror/ftpmail/RCS/dq.pl,v 1.16 1993/04/28 18:19:19 lmjm Exp lmjm $
  671. X# $Log: dq.pl,v $
  672. X# Revision 1.16  1993/04/28  18:19:19  lmjm
  673. X# From chris, corrected filename in mime message.
  674. X#
  675. X# Revision 1.15  1993/04/25  20:27:49  lmjm
  676. X# Use own split routine to implement size paramater.
  677. X#
  678. X# Revision 1.14  1993/04/25  14:38:52  lmjm
  679. X# Dont requeue jobs that have been tried too many times.
  680. X#
  681. X# Revision 1.13  1993/04/25  14:14:59  lmjm
  682. X# Conform to mime rules on filenames.
  683. X#
  684. X# Revision 1.12  1993/04/25  13:18:01  lmjm
  685. X# Moved signal handling into ftp'pl.
  686. X#
  687. X# Revision 1.11  1993/04/23  23:27:04  lmjm
  688. X# Massive renaming for sys5.
  689. X#
  690. X# Revision 1.10  1993/04/23  20:03:16  lmjm
  691. X# Don't use STDIN, STDOUT or STDERR.
  692. X# Use own verion of library routines before any others.
  693. X# Log the pid when sleeping to make it easier to kill.
  694. X#
  695. X# Revision 1.9  1993/04/23  17:23:37  lmjm
  696. X# Renamed ftpmail-local-config.pl to ftpmail-config.pl
  697. X# Made pathnames relative to $ftpmail_dir.
  698. X# Moved the check_tries handle to the start of the job.
  699. X#
  700. X# Revision 1.8  1993/04/21  10:58:38  lmjm
  701. X# Added jobid to response.
  702. X#
  703. X# Revision 1.7  1993/04/20  20:15:37  lmjm
  704. X# Turned printing job to mail into a library routine.
  705. X#
  706. X# Revision 1.6  1993/04/15  18:07:14  lmjm
  707. X# Scan queue in perl not by calling ls.
  708. X# Added more logging.
  709. X# Done inplace change the comms variable.
  710. X# Dump stdout onto stderr when playing with fd's before mailing.
  711. X# Don't send a completed message if job was zapped.
  712. X#
  713. X# Revision 1.5  1993/04/15  14:17:43  lmjm
  714. X# log when quitting.
  715. X# Something is adding spaces to the start of job lines - zap them for now.
  716. X# Don't requeue overtried jobs.
  717. X# Added some patches from  Christophe.
  718. X#
  719. X# Revision 1.4  1993/04/13  10:34:36  lmjm
  720. X# Lots of little cleanups in logging and response messages
  721. X#
  722. X# Revision 1.3  1993/03/30  20:32:19  lmjm
  723. X# Must have an ftpmail account whose home directory everything is in.
  724. X# New -test option that uses /tmp/ftpmail-test
  725. X# Simplified the parsing of the jobs.
  726. X# ftpmail-dq keeps running till shutdown
  727. X# Changed the mime code, now handles force better.
  728. X# Moved the close( STDOUT ) to where it doesn't cause mail to fail!
  729. X#
  730. X# Revision 1.2  1993/03/23  21:40:10  lmjm
  731. X# Fixed all those little internal problems.
  732. X# Rewrote the setup routines.
  733. X# Added gzip and btoa support
  734. X# Added mime, multipart and all sorts of other good things based on work by
  735. X#  Christophe.Wolfhugel@grasp.insa-lyon.fr
  736. X#
  737. X
  738. X$ftpmail = 'ftpmail';
  739. X
  740. Xif( $test ){
  741. X    $ftpmail_dir = '/tmp/ftpmail-test';
  742. X}
  743. Xelse {
  744. X    # The ftpmail_dir is the home directory of ftpmail.
  745. X    $ftpmail_dir = (getpwnam( $ftpmail ))[ 7 ];
  746. X}
  747. X
  748. Xif( ! $ftpmail_dir ){
  749. X    die "No home directory for ftpmail\n";
  750. X}
  751. X
  752. Xif( ! -d $ftpmail_dir ){
  753. X    die "no such directory as $ftpmail_dir\n";
  754. X}
  755. X
  756. Xchdir( $ftpmail_dir ) || die "cannot chdir to $ftpmail_dir\n";
  757. X
  758. X# All the auxillary scripts come from ftpmail's home dir.
  759. Xunshift( @INC, '.' );
  760. X
  761. Xrequire 'config.pl';
  762. Xrequire 'support.pl';
  763. Xrequire 'ftp.pl';
  764. Xrequire 'chat2.pl';
  765. X
  766. X# Don't leave files around writable
  767. Xumask( 077 );
  768. X
  769. Xsub handler {
  770. X    local( $sig ) = @_;
  771. X    local( $msg ) = "Caught a SIG$sig shutting down";
  772. X    warn $msg;
  773. X    &log( $msg );
  774. X    exit( 0 );
  775. X}
  776. X$SIG{ 'PIPE' } = 'handler';
  777. X# Only allow jobs to be updated.  (In case q.pl has deleted it.)
  778. X$updating_only = 1;
  779. X
  780. X# Mime types
  781. X$partial = 1;
  782. X$octets = 2;
  783. X$text = 3;
  784. X
  785. X# Counters for Mime multiparts;
  786. X$partno = 0;
  787. X$nparts = 0;
  788. X# part id
  789. X$id = '';
  790. X
  791. X&trap_signals();
  792. X&lock();
  793. X&ftp'set_timeout( 60 );        # Use long timeouts
  794. X&ftp'set_signals( "main'log" );    # Beware of SIGPIPES
  795. X&ftp'debug( 1 );
  796. Xwhile( ! -f $ftpmail_scan_end ){
  797. X    &scan_q();
  798. X    &process_qfiles();
  799. X    if( $between_runs_pause ){
  800. X        &log( "nothing to do - sleeping pid=$$" );
  801. X        sleep( $between_runs_pause );
  802. X    }
  803. X}
  804. X&log( "found $ftpmail_scan_end so quiting" );
  805. X&unlock();
  806. Xexit( 0 );
  807. X
  808. X# Scan the Q directory
  809. Xsub scan_q
  810. X{
  811. X    &log( "scanning queue" );
  812. X    
  813. X    @qfiles = ();
  814. X    opendir( dir, $quedir ) || die "Cannot open directory: $quedir";
  815. X    local( @dir ) = readdir( dir );
  816. X    closedir( dir );
  817. X
  818. X    foreach $_ ( @dir ){
  819. X        if( /^\d+\.\d+$/ ){
  820. X            push( @qfiles, $_ );
  821. X        }
  822. X    }
  823. X    @qfiles = sort @qfiles;
  824. X}
  825. X
  826. X
  827. Xsub process_qfiles
  828. X{
  829. X    local( $qf );
  830. X    foreach $qf ( @qfiles ){
  831. X        if( -f $ftpmail_scan_end ){
  832. X            last;
  833. X        }
  834. X        $qfile = "$quedir/$qf";
  835. X        &process_qfile();
  836. X    }
  837. X}
  838. X
  839. Xsub process_qfile
  840. X{
  841. X    if( ! open( qf, $qfile ) ){
  842. X        # File was probably deleted by the user
  843. X        return;
  844. X    }
  845. X
  846. X    # Only give up if a serious error occurs - otherwise retry.
  847. X    $give_up = 0;
  848. X
  849. X    # Force encoding?
  850. X    $force = 0;
  851. X
  852. X    # filters
  853. X    $compress_it = 0;
  854. X    $gzip_it = 0;
  855. X    $uuencode_it = 0;
  856. X    $atob_it = 0;
  857. X    $mime_it = 0;
  858. X
  859. X    # Set the max file size from the local config file.
  860. X    $max_file_size = $def_max_size;
  861. X
  862. X    # When running in non-interactive mode this is the
  863. X    # jobs to do.
  864. X    @mailback = ();    # an elem is true if @comms elem needs to be mailed
  865. X    @filename = ();    # filename to report in messages
  866. X    @filters = ();    # filters to apply to file.
  867. X
  868. X    # input lines
  869. X    # Strip out the informational lines and stick the rest into @comms
  870. X    @comms = ();
  871. X    while( <qf> ){
  872. X        chop;
  873. X        # This s/.. is to get around an old bug - shouldn't be needed now
  874. X        s/^\s*//;
  875. X        if( /^reply-to (.+)$/ ){
  876. X            $reply_to = $1;
  877. X            next;
  878. X        }
  879. X        elsif( /^tries (\d+)( (\d+))?$/ ){
  880. X            $tries = $1;
  881. X            $whenretry = $2;
  882. X            next;
  883. X        }
  884. X        push( @comms, $_ );
  885. X    }
  886. X    close( qf );
  887. X    
  888. X    if( ! &check_tries() ){
  889. X        # Too many - job has been dequeued
  890. X        return;
  891. X    }
  892. X    
  893. X    if( $whenretry > time() ){
  894. X        &log( "too early to process $qfile" ) if $test;
  895. X        return;
  896. X    }
  897. X
  898. X    &log( "starting job: $qfile" );
  899. X    
  900. X    $tries++;
  901. X    # On failure don't retry the job for progressively
  902. X    # longer times.
  903. X    $whenretry = time() + $retry_pause;
  904. X    &write_entry();
  905. X    
  906. X    # Send all ftp errors into xferlog
  907. X    open( out, ">$xferlog" ) || &fatal( "Cannot create $xferlog" );
  908. X    $ftp'showfd = "main'out";
  909. X    
  910. X    $mailing_back = $immediate;
  911. X    
  912. X    &ftp_to_site();
  913. X    close( out );
  914. X
  915. X    if( ! $immediate ){
  916. X        # mail out all the completed get/dir/ls
  917. X        $mailing_back = 1;
  918. X        for( $cmdno = 0; $cmdno <= $#comms; $cmdno++ ){
  919. X            if( $mailback[ $cmdno ] ){
  920. X                &mail_back();
  921. X            }
  922. X        }
  923. X    }
  924. X    &finish_entry();
  925. X    
  926. X    unlink( $xferlog );
  927. X}
  928. X
  929. Xsub ftp_to_site
  930. X{
  931. X    local( $mode ) = undef;
  932. X    local( $open ) = undef;
  933. X    
  934. X    # All done?
  935. X    $job_done = 0;
  936. X
  937. X    # Make sure connection is shut down.
  938. X    &chat'close();
  939. X
  940. X    &log( "$qfile: tries=$tries [$max_tries] reply_to=$reply_to" );
  941. X    # process commands
  942. X    $site = $user = $pass = '';
  943. X    for( $cmdno = 0; $cmdno <= $#comms; $cmdno++ ){
  944. X        $_ = $comm = $comms[ $cmdno ];
  945. X        if( /^DONE|FAILED/ ){
  946. X            &log( "skipping: $_" );
  947. X        }
  948. X        elsif( /^open (.+)$/i ){
  949. X            $site = $1;
  950. X        }
  951. X        elsif( /^user (.+)$/i ){
  952. X            $user = $1;
  953. X        }
  954. X        elsif( /^pass (.+)$/i ){
  955. X            $pass = $1;
  956. X            
  957. X            &log( "connecting to $site" );
  958. X            $res = &ftp'open( $site, $ftp_port, $retry_call, $retry_attempts );
  959. X            if( $res != 1 ){
  960. X                &pralog( "Failed to connect" );
  961. X                last;
  962. X            }
  963. X            &log( "logging in as $user $pass" );
  964. X            if( ! &ftp'login( $user, $pass ) ){
  965. X                &pralog( "Failed to login" );
  966. X                &ftp'close();
  967. X                last;
  968. X            }
  969. X            $pwd = &ftp'pwd();
  970. X            &log( "pwd=$pwd" );
  971. X            
  972. X            # Default type is binary
  973. X            if( ! defined( $mode ) ){
  974. X                $mode = 'I';
  975. X            }
  976. X            if( ! &ftp'type( $mode ) ){
  977. X                &pralog( "Failed to set type to binary" );
  978. X            }
  979. X        }
  980. X        elsif( /^mode (.+)$/i ){
  981. X            $mode = $1 eq 'binary' ? 'I' : 'A';
  982. X            if( defined( $open ) ){
  983. X                if( ! &ftp'type( $mode ) ){
  984. X                    &pralog( "Failed to set type to $1" );
  985. X                }
  986. X            }
  987. X        }
  988. X        elsif( /^cd (.+)$/i ){
  989. X            $dir = $1;
  990. X            &log( "cwd $dir" );
  991. X            if( ! &ftp'cwd( $dir ) ){
  992. X                &pralog( "Failed to change to remote directory: $dir" );
  993. X                $give_up = 1;
  994. X                last;
  995. X            }
  996. X            $pwd = &ftp'pwd();
  997. X            &log( "pwd=$pwd" );
  998. X        }
  999. X        elsif( /^(compress|gzip)( no)?$/i ){
  1000. X            eval "\$$1_it = 1";
  1001. X            &log( "$1_it set" ) if $test;
  1002. X        }
  1003. X        elsif( /^(force )?(compress|gzip|uuencode|btoa|mime)( no)?$/i ){
  1004. X            $force = $1 eq 'force ';
  1005. X            &log( "force set" ) if $force && $test;
  1006. X            eval "\$$2_it = 1";
  1007. X            &log( "$2_it set" ) if $test;
  1008. X        }
  1009. X        elsif( /^size (\d+)/i ){
  1010. X            $max_file_size = $1;
  1011. X        }
  1012. X        elsif( /^(ls|dir) (.*)/i ){
  1013. X            $path = $2;
  1014. X            local( $old_mode );
  1015. X            
  1016. X            &log( $comm );
  1017. X            if( $mode ne 'A' ){
  1018. X                if( &ftp'type( 'A' ) ){
  1019. X                    $old_mode = $mode;
  1020. X                }
  1021. X                else {
  1022. X                    &pralog( "Cannot set type to ascii for dir listing, trying to carry on" );
  1023. X                }
  1024. X            }
  1025. X            
  1026. X            if( ! &ftp'dir_open( $path ) ){
  1027. X                &pralog( "Cannot get remote directory listing because: $ftp'response" );
  1028. X                $give_up = 1;
  1029. X            }
  1030. X            
  1031. X            local( $in ) = "$incoming.$cmdno";
  1032. X            open( IN, ">$in" ) || &fail( "cannot create $in" );
  1033. X
  1034. X            # Suck back dir listing output into a temp file
  1035. X            while( ($len = &ftp'read()) > 0 ){
  1036. X                $bytes += $len;
  1037. X                if( $mode eq 'A' ){
  1038. X                    $ftp'buf =~ s/\r//g;
  1039. X                }
  1040. X                print IN $ftp'buf;
  1041. X            }
  1042. X            close( IN );
  1043. X
  1044. X            &ftp'dir_close();
  1045. X            if( defined( $old_mode ) && ! &ftp'type( $old_mode ) ){
  1046. X                &pralog( "Cannot reset type after dir" );
  1047. X            }
  1048. X
  1049. X            if( $len < 0 ){
  1050. X                &pralog( "\nTimed out reading data" );
  1051. X                last;
  1052. X            }
  1053. X
  1054. X            $filename = "directory-listing";
  1055. X            &mail_back();
  1056. X        }
  1057. X        elsif( /^get (.+)/i ){
  1058. X            local( $in ) = "$incoming.$cmdno";
  1059. X            
  1060. X            $filename = $1;
  1061. X
  1062. X            &log( $comm );
  1063. X            if( ! &ftp'get( $filename, $in, 0 ) ){
  1064. X                $comms[ $cmdno ] = "FAILED $comms[ $cmdno ]";
  1065. X                &pralog( "failed to get $filename" );
  1066. X            }
  1067. X            else {
  1068. X                &mail_back();
  1069. X            }
  1070. X        }
  1071. X        else {
  1072. X            &log( "Internal error: found command: $_" );
  1073. X        }
  1074. X        
  1075. X        if( $cmdno == $#comms ){
  1076. X            $job_done = 1;
  1077. X        }
  1078. X    }
  1079. X    
  1080. X    &log( "job done" );
  1081. X    &ftp'quit();
  1082. X}
  1083. X
  1084. X# Check out the tries counter.  If too many then dequeue job.
  1085. X# Return 1 if ok.
  1086. Xsub check_tries
  1087. X{
  1088. X    if( $tries <= $max_tries ){
  1089. X        return 1;
  1090. X    }
  1091. X    
  1092. X    unlink( $qfile );
  1093. X    &log( "Job $qfile failed and dequeued" );
  1094. X    &respond( "failed", "Your job failed to be fully processed after too may tries ($tries)" );
  1095. X    $job_done = 1;
  1096. X    return 0;
  1097. X}
  1098. X
  1099. X
  1100. X# This should check error status
  1101. Xsub mail_back
  1102. X{
  1103. X    if( ! $mailing_back ){
  1104. X        # Not mailing stuff back yet, just remember it.
  1105. X        $mailback[ $cmdno ] = 1;
  1106. X        $filename[ $cmdno ] = $filename;
  1107. X        $pwd[ $cmdno ] = $pwd;
  1108. X        local( $f ) = '';
  1109. X        $f .= 'c' if $compress_it;
  1110. X        $f .= 'g' if $gzip_it;
  1111. X        $f .= 'a' if $atob_it;
  1112. X        $f .= 'u' if $uuencode_it;
  1113. X        $f .= 'm' if $mime_it;
  1114. X        $f .= 'F' if $force;
  1115. X        $filters[ $cmdno ] = $f;
  1116. X        &log( "delayed mail back: $pwd $filename $f" ) if $test;
  1117. X        return;
  1118. X    }
  1119. X
  1120. X    local( $note, $suff, $infile, $command );
  1121. X    
  1122. X    $infile = "$incoming.$cmdno";
  1123. X    if( ! $immediate ){
  1124. X        $command = $comms[ $cmdno ];
  1125. X        $filename = $filename[ $cmdno ];
  1126. X        $pwd = $pwd[ $cmdno ];
  1127. X        local( $f ) = $filters[ $cmdno ];
  1128. X        $compress_it = ($f =~ /c/);
  1129. X        $gzip_it = ($f =~ /g/);
  1130. X        $atob_it = ($f =~ /a/);
  1131. X        $uuencode_it = ($f =~ /u/);
  1132. X        $mime_it = ($f =~ /m/);
  1133. X        $force_it = ($f =~ /F/);
  1134. X        &log( "NOW mailing back: $pwd $filename $f" ) if $test;
  1135. X    }
  1136. X    
  1137. X    $partno = 0;
  1138. X    $nparts = 0;
  1139. X    $id = '';
  1140. X    $cte = '';
  1141. X    
  1142. X    # I use single quotes when running system commands so prevent extra ones
  1143. X    $command =~ s/'//g;
  1144. X    
  1145. X    local( $report ) = "$site:$pwd";
  1146. X    if( $command =~ /get/ ){
  1147. X        $report .= "/$filename";
  1148. X    }
  1149. X    
  1150. X    if( $compress_it ){
  1151. X        &log( "compressing $infile" );
  1152. X        system( "$compress '$infile'" );
  1153. X        if( -r "$infile.Z" ){
  1154. X            $note = ' compressed';
  1155. X            $infile .= '.Z';
  1156. X            $suff = '.Z';
  1157. X        }
  1158. X    }
  1159. X    elsif( $gzip_it ){
  1160. X        &log( "gzip $infile" );
  1161. X        system( "$gzip '$infile'" );
  1162. X        if( -r "$infile.z" ){
  1163. X            $note = ' gzipped';
  1164. X            $infile .= '.z';
  1165. X            $suff = '.z';
  1166. X        }
  1167. X    }
  1168. X    
  1169. X    $is_text = (-T $infile);
  1170. X    if( $force || $mime_it || ! $is_text ){
  1171. X        if( !$mime_it && !$uuencode_it && !$btoa_it ){
  1172. X            &log( "non text but no method, using uuencode" );
  1173. X            $uuencode_it = 1;
  1174. X        }
  1175. X        # Convert binary file using given filter
  1176. X        # (Execpt mime, only encode if you have to)
  1177. X        if( $mime_it && ($force || !$is_text) ){
  1178. X            &log( "mmencoding $infile" );
  1179. X            system( "$mmencode < '$infile' > '$infile.mm'" );
  1180. X            unlink( $infile );
  1181. X            $note .= ' mmencoded';
  1182. X            $infile .= '.mm';
  1183. X            $cte = 'base64';
  1184. X        }
  1185. X        elsif( $uuencode_it ){
  1186. X            &log( "uuencoding $infile" );
  1187. X            system( "$uuencode '$filename$suff' < '$infile' > '$infile.uu'" );
  1188. X            unlink( $infile );
  1189. X            $note .= ' uuencoded';
  1190. X            $infile .= '.uu';
  1191. X        }
  1192. X        elsif( $btoa_it ){
  1193. X            &log( "btoa-ing $infile" );
  1194. X            system( "$btoa < '$infile' > '$infile.btoa'" );
  1195. X            unlink( $infile );
  1196. X            $note .= ' btoa';
  1197. X            $infile .= '.btoa';
  1198. X        }
  1199. X    }
  1200. X
  1201. X    $report .= $note . " ($command)";
  1202. X    
  1203. X    if( $mime_it ){
  1204. X        $nparts = 0;
  1205. X        $partno = 0;
  1206. X        $id = "ftpmail-" . time . "-$$@$hostname";
  1207. X    }
  1208. X
  1209. X    local( $file_size ) = &size( $infile );
  1210. X    if( $file_size > $max_processing_size ){
  1211. X        local( $msg ) = "file size exceeded max. processing size ($max_processing_size), canceling job";
  1212. X        &log( $msg );
  1213. X        &log( $report );
  1214. X    
  1215. X        &mailit( 'aborting job: too big', $msg );
  1216. X    }
  1217. X    elsif( $file_size >= $max_file_size ){
  1218. X        # Split the file up and mail back the parts
  1219. X        # Allow for mail headers.  If you have to pay
  1220. X        # by size then it is important not to accidentally go over
  1221. X        # limit.
  1222. X        $nparts = &tsplit( $infile, $max_file_size - $mail_overhead );
  1223. X&log( "tsplit $infile $max_file_size into $nparts" );
  1224. X        
  1225. X        for( $partno = 1; $partno <= $nparts; $partno++ ){
  1226. X            local( $file ) = "$tmpdir/part$partno";
  1227. X            local( $reppart ) = "[$partno of $nparts]";
  1228. X            
  1229. X            &mailit( "$reppart $report", $file, 1 );
  1230. X
  1231. X            unlink( $file );
  1232. X        }
  1233. X    }
  1234. X    else {
  1235. X        &mailit( $report, $infile, 1 );
  1236. X    }
  1237. X    unlink( $infile );
  1238. X    
  1239. X    $comms[ $cmdno ] = "DONE $comms[ $cmdno ]";
  1240. X    &write_entry();
  1241. X}
  1242. X
  1243. Xsub mime_header
  1244. X{
  1245. X    local( $kind, $file  ) = @_;
  1246. X    print MAIL "Mime-Version: $mime_version\n";
  1247. X    if( $kind == $text ){
  1248. X        print MAIL "Content-Type: text/plain; charset=US-ASCII\n";
  1249. X    }
  1250. X    elsif( $kind == $partial ){
  1251. X        print MAIL "Content-Type: message/partial;\n";
  1252. X        print MAIL " id=\"$id\"; number=$partno; total=$nparts\n";
  1253. X    }
  1254. X    elsif( $kind == $octets ){
  1255. X        print MAIL "Content-Type: application/octet-stream;\n";
  1256. X        print MAIL "  name=\"$filename$suff\"\n";
  1257. X    }
  1258. X    if( $cte ){
  1259. X        print MAIL "Content-Transfer-Encoding: $cte\n";
  1260. X    }
  1261. X}
  1262. X
  1263. X# A Mime message has extra header fields
  1264. X# and if the message is a (mime) split up message then whole
  1265. X# mime message is chopped up and sent as a series of message/partial messages
  1266. Xsub mailit
  1267. X{
  1268. X    local( $subject, $file, $isfile ) = @_;
  1269. X    
  1270. X    &log( "mailit $reply_to $subject" );
  1271. X    
  1272. X    if( $mail_cmd =~ /sendmail/ ){
  1273. X        open( MAIL, "| $mail_cmd" ) || &fail( "Can't start $mail_cmd" );
  1274. X        print MAIL "To: $reply_to\n";
  1275. X        print MAIL "Subject: $subject\n";
  1276. X        if( $mime_it ){
  1277. X            # cte is set if this file was encoded
  1278. X            local( $kind ) = $cte ? $octets : $text;
  1279. X            if( $nparts != 0 ){
  1280. X                # Don't output the cte except in the
  1281. X                # inner message.
  1282. X                local( $real_cte ) = $cte;
  1283. X                $cte = '';
  1284. X                &mime_header( $partial, $file );
  1285. X                $cte = $real_cte;
  1286. X                if( $partno == 1 ){
  1287. X                    # Output the header for the
  1288. X                    # inner message.
  1289. X                    print MAIL "\n";
  1290. X                    &mime_header( $kind, $file );
  1291. X                }
  1292. X            }
  1293. X            else {
  1294. X                &mime_header( $kind, $file );
  1295. X            }
  1296. X        }
  1297. X        print MAIL "\n";
  1298. X    }
  1299. X    else {
  1300. X        open( MAIL, "| $mail_cmd -s '$subject' '$reply_to' >/dev/null 2>&1" ) ||
  1301. X             &fail( "Can't start $mail_cmd" );
  1302. X    }
  1303. X    
  1304. X    if( ! $isfile ){
  1305. X        # $file is the string to send
  1306. X        print MAIL $file;
  1307. X    }
  1308. X    else {
  1309. X        open( IN, $file ) || &fail( "Can't reopen $file" );
  1310. X        while( <IN> ){
  1311. X            print MAIL;
  1312. X        }
  1313. X        close( IN );
  1314. X    }
  1315. X    close( MAIL );
  1316. X    
  1317. X    sleep( $mail_pause ) if $mail_pause;
  1318. X}
  1319. X
  1320. Xsub size
  1321. X{
  1322. X    local( $file ) = @_;
  1323. X    
  1324. X    local( $dev,$ino,$fmode,$nlink,$uid,$gid,$rdev,$ssize,
  1325. X          $atime,$mtime,$ctime,$blksize,$blocks ) =
  1326. X              stat( $file );
  1327. X    return( $ssize );
  1328. X}
  1329. X
  1330. X# Output a standard lump of messages
  1331. Xsub respond
  1332. X{
  1333. X    local( $status, $msg ) = @_;
  1334. X    local( $c );
  1335. X    local( $subject ) = "ftpmail job $status";
  1336. X    
  1337. X    &log( "respond $reply_to $subject" );
  1338. X    
  1339. X    if( $mail_cmd =~ /sendmail/ ){
  1340. X        open( MAIL, "| $mail_cmd" ) || &fail( "Can't start $mail_cmd" );
  1341. X        print MAIL "To: $reply_to\n";
  1342. X        print MAIL "Subject: $subject\n\n";
  1343. X    }
  1344. X    else {
  1345. X        open( MAIL, "| $mail_cmd -s '$subject' '$reply_to' >/dev/null 2>&1" ) ||
  1346. X             &fail( "Can't start $mail_cmd" );
  1347. X    }
  1348. X    print MAIL "$ftpmail_response\n";
  1349. X    print MAIL "$msg\nYour job was (lines begining DONE show completed transfers):\n";
  1350. X    &mail_comms();
  1351. X    print MAIL "\nThe ftp log contains:\n";
  1352. X    open( LOG, $xferlog ) || &fail( "cannot reopen $xferlog" );
  1353. X    local( @log ) = <LOG>;
  1354. X    close( LOG );
  1355. X    print MAIL join( "\n", "@log" );
  1356. X    print MAIL "\n";
  1357. X    close MAIL;
  1358. X    
  1359. X    sleep( $mail_pause ) if $mail_pause;
  1360. X}
  1361. X
  1362. Xsub finish_entry
  1363. X{
  1364. X    if( $job_done ){
  1365. X        if( -f $qfile ){
  1366. X        # The job is done and hasn't been deleted due to too many tries
  1367. X            unlink( $qfile );
  1368. X            &log( "deleting $qfile" );
  1369. X            &respond( "completed", "" );
  1370. X        }
  1371. X    }
  1372. X    elsif( $give_up ){
  1373. X        unlink( $qfile );
  1374. X        &log( "Job $qfile failed when a serious error occured" );
  1375. X        &respond( "failed", "An unrecoverable error occured so your job was aborted" );
  1376. X    }
  1377. X    else {
  1378. X        if( ! &check_tries() ){
  1379. X            return;
  1380. X        }
  1381. X        &log( "Requeing job: $qfile" );
  1382. X        &respond( "queueing for retry $qfile", "" );
  1383. X        &write_entry();
  1384. X    }
  1385. X}
  1386. X
  1387. X
  1388. Xsub lock
  1389. X{
  1390. X    if( -r $lock ){
  1391. X        open( lock, "<$lock" ) || &fatal( "Cannot open lockfile $lock" );
  1392. X        local( $pid ) = <lock>;
  1393. X        chop( $pid );
  1394. X        close( lock );
  1395. X        # Check that the locking process is still around
  1396. X        if( kill( 0, $pid ) == 1 ){
  1397. X            # Still locked
  1398. X            &log( "queue already locked by $pid" );
  1399. X            exit( 0 );
  1400. X        }
  1401. X        else {
  1402. X            # No process so zap lock
  1403. X            unlink $lock;
  1404. X        }
  1405. X    }
  1406. X    open( lock, ">$lock" ) || &fatal( "Cannot create lockfile $lock" );
  1407. X    print lock "$$\n";
  1408. X    close lock;
  1409. X}
  1410. X
  1411. Xsub unlock
  1412. X{
  1413. X    unlink( $lock );
  1414. X}
  1415. X
  1416. Xsub shutdown
  1417. X{
  1418. X    &log( "Received HUP so shutting down" );
  1419. X    exit( 0 );
  1420. X}
  1421. X
  1422. Xsub trap_signals
  1423. X{
  1424. X    $SIG{ 'HUP' } = "main\'shutdown";
  1425. X}
  1426. X
  1427. X# print to out and log it.
  1428. Xsub pralog
  1429. X{
  1430. X    local( $msg ) = @_;
  1431. X    print out "$msg\n";
  1432. X    &log( $msg );
  1433. X}
  1434. X
  1435. X# Split the file up into chunks size big, remove the
  1436. X# original and return the number of parts
  1437. Xsub tsplit
  1438. X{
  1439. X    local( $file, $size ) = @_;
  1440. X    local( $buffer, $in, $sofar );
  1441. X    local( $index ) = 0;
  1442. X    local( $part );
  1443. X
  1444. X    open( f, $file ) || &fatal( "Cannot open $file to split" );
  1445. X    $sofar = $size;
  1446. X    while( <f> ){
  1447. X        $in = length( $_ );
  1448. X        if( $sofar >= $size ){
  1449. X            if( $part ){
  1450. X                close( part );
  1451. X            }
  1452. X            $index++;
  1453. X            $part = "$tmpdir/part$index";
  1454. X            unlink( $part );
  1455. X            open( part, ">$part" ) || &fatal( "cannot create $part" );
  1456. X            $sofar = 0;
  1457. X        }
  1458. X        print part;
  1459. X        $sofar += $in;
  1460. X    }
  1461. X    close( part );
  1462. X    close( f );
  1463. X
  1464. X    return $index;
  1465. X}
  1466. X
  1467. X# Split the file up into chunks size big, remove the
  1468. X# original and return the number of parts
  1469. Xsub binsplit
  1470. X{
  1471. X    local( $file, $size ) = @_;
  1472. X    local( $bufsiz ) = 512;
  1473. X    local( $buffer, $in, $sofar );
  1474. X    local( $index ) = 0;
  1475. X    local( $part );
  1476. X
  1477. X    open( f, $file ) || &fatal( "Cannot open $file to split" );
  1478. X    $sofar = $size; # Force a new file
  1479. X    while( ($in = sysread( f, $buffer, $bufsiz )) > 0 ){
  1480. X        if( $sofar >= $size ){
  1481. X            if( $part ){
  1482. X                close( part );
  1483. X            }
  1484. X            $index++;
  1485. X            $part = "$tmpdir/part$index";
  1486. X            unlink( $part );
  1487. X            open( part, ">$part" ) || &fatal( "cannot create $part" );
  1488. X            $sofar = 0;
  1489. X        }
  1490. X        if( ($out = syswrite( part, $buffer, $in )) != $in ){
  1491. X            &fatal( "Failed to write data to $part" );
  1492. X        }
  1493. X        $sofar += $in;
  1494. X    }
  1495. X    close( part );
  1496. X    close( f );
  1497. X
  1498. X    return $index;
  1499. X}
  1500. END_OF_FILE
  1501.   if test 19116 -ne `wc -c <'dq.pl'`; then
  1502.     echo shar: \"'dq.pl'\" unpacked with wrong size!
  1503.   fi
  1504.   chmod +x 'dq.pl'
  1505.   # end of 'dq.pl'
  1506. fi
  1507. if test -f 'inst.pl' -a "${1}" != "-c" ; then 
  1508.   echo shar: Will not clobber existing file \"'inst.pl'\"
  1509. else
  1510.   echo shar: Extracting \"'inst.pl'\" \(2620 characters\)
  1511.   sed "s/^X//" >'inst.pl' <<'END_OF_FILE'
  1512. X#!/usr/bin/perl -s
  1513. X# Create the directories needed for ftpmail to work
  1514. X# By Lee McLoughlin <lmjm@doc.ic.ac.uk>
  1515. X#  You can do what you like with this except claim that you wrote it or
  1516. X#  give copies with changes not approved by Lee.  Neither Lee nor any other
  1517. X#  organisation can be held liable for any problems caused by the use or
  1518. X#  storage of this package.
  1519. X#
  1520. X# $Header: /a/swan/home/swan/staff/csg/lmjm/src/perl/mirror/ftpmail/RCS/inst.pl,v 1.7 1993/04/25 14:15:10 lmjm Exp lmjm $
  1521. X# $Log: inst.pl,v $
  1522. X# Revision 1.7  1993/04/25  14:15:10  lmjm
  1523. X# Allow for multiple help files (one per language).
  1524. X#
  1525. X# Revision 1.6  1993/04/23  23:27:05  lmjm
  1526. X# Massive renaming for sys5.
  1527. X#
  1528. X# Revision 1.5  1993/04/23  20:03:17  lmjm
  1529. X# Use own version of library routines before others.
  1530. X#
  1531. X# Revision 1.4  1993/04/23  17:23:39  lmjm
  1532. X# Renamed ftpmail-local-config.pl to ftpmail-config.pl
  1533. X# Made pathnames relative to $ftpmail_dir.
  1534. X#
  1535. X# Revision 1.3  1993/03/30  20:32:20  lmjm
  1536. X# Now requires an ftpmail account whose home directory everything is in
  1537. X# changed the -test option to use /tmp/ftpmail-test
  1538. X#
  1539. X# Revision 1.2  1993/03/23  21:40:12  lmjm
  1540. X# Cleaned up to use ftpmail's home and droped the .sh from the install.
  1541. X#
  1542. X
  1543. X$ftpmail = 'ftpmail';
  1544. X
  1545. Xif( $test ){
  1546. X    $ftpmail_dir = '/tmp/ftpmail-test';
  1547. X}
  1548. Xelse {
  1549. X    # The ftpmail_dir is the home directory of ftpmail.
  1550. X    $ftpmail_dir = (getpwnam( $ftpmail ))[ 7 ];
  1551. X    $do_chown = 1;
  1552. X}
  1553. X
  1554. X
  1555. Xmkdir( $ftpmail_dir, 0755 );
  1556. Xprint "mkdir $ftpmail_dir\n";
  1557. X
  1558. Xif( ! $ftpmail_dir ){
  1559. X    die "No home directory for ftpmail\n";
  1560. X}
  1561. X
  1562. Xif( ! -d $ftpmail_dir ){
  1563. X    die "no such directory as $ftpmail_dir\n";
  1564. X}
  1565. X
  1566. Xchop( $here = `pwd` );
  1567. X
  1568. Xchdir( $ftpmail_dir ) || die "cannot chdir to $ftpmail_dir\n";
  1569. X
  1570. Xunshift( @INC, $here );
  1571. X
  1572. Xrequire 'config.pl';
  1573. X
  1574. X@dirs = ( $tmpdir, $quedir, $helpdir );
  1575. X@files = (
  1576. X    'q.pl',
  1577. X    'dq.pl',
  1578. X    'support.pl',
  1579. X    'config.pl',
  1580. X    'ftp.pl',
  1581. X    'chat2.pl',
  1582. X    'socket.ph',
  1583. X    $authfile );
  1584. X# All the help files are help_language
  1585. X@helpfiles = (
  1586. X    'help_english' );
  1587. X
  1588. Xforeach $dir ( @dirs ){
  1589. X    if( ! -d $dir ){
  1590. X        print "mkdir $dir\n";
  1591. X        if( ! mkdir( $dir, 0755 ) ){
  1592. X            die "Failed to create $dir";
  1593. X        }
  1594. X    }
  1595. X}
  1596. X
  1597. X# Copy in the rest of the files
  1598. Xprint "Installing files\n";
  1599. Xforeach $file ( @files ){
  1600. X    print "copying $file\n";
  1601. X    system( "cp $here/$file ." );
  1602. X}
  1603. Xforeach $file ( @helpfiles ){
  1604. X    print "copying $file\n";
  1605. X    $f = $file;
  1606. X    # change help_english -> english
  1607. X    $f =~ s,help_,,;
  1608. X    system( "cp $here/$file $helpdir/$f" );
  1609. X}
  1610. Xlink( "$helpdir/english", "$helpdir/help" );
  1611. Xsystem( "chmod 755 q.pl dq.pl" );
  1612. Xif( $do_chown ){
  1613. X    $uid = (getpwnam( $ftpmail ))[ 2 ];
  1614. X    chown $uid, 0, @files;
  1615. X    chown $uid, 0, @dirs;
  1616. X    chown $uid, 0, $ftpmail_dir;
  1617. X}
  1618. END_OF_FILE
  1619.   if test 2620 -ne `wc -c <'inst.pl'`; then
  1620.     echo shar: \"'inst.pl'\" unpacked with wrong size!
  1621.   fi
  1622.   chmod +x 'inst.pl'
  1623.   # end of 'inst.pl'
  1624. fi
  1625. if test -f 'mmdf_maildelivery' -a "${1}" != "-c" ; then 
  1626.   echo shar: Will not clobber existing file \"'mmdf_maildelivery'\"
  1627. else
  1628.   echo shar: Extracting \"'mmdf_maildelivery'\" \(64 characters\)
  1629.   sed "s/^X//" >'mmdf_maildelivery' <<'END_OF_FILE'
  1630. Xdefault * pipe A "/src.doc.ic.ac.uk/public/ic.doc/ftpmail/q.pl"
  1631. END_OF_FILE
  1632.   if test 64 -ne `wc -c <'mmdf_maildelivery'`; then
  1633.     echo shar: \"'mmdf_maildelivery'\" unpacked with wrong size!
  1634.   fi
  1635.   # end of 'mmdf_maildelivery'
  1636. fi
  1637. if test -f 'pp_mailfilter' -a "${1}" != "-c" ; then 
  1638.   echo shar: Will not clobber existing file \"'pp_mailfilter'\"
  1639. else
  1640.   echo shar: Extracting \"'pp_mailfilter'\" \(246 characters\)
  1641.   sed "s/^X//" >'pp_mailfilter' <<'END_OF_FILE'
  1642. X# Default path is only /vol/pp/bin
  1643. X# Under MMDF path contained $HOME, hence /homes/info-server
  1644. XPATH="/vol/pp/bin:/homes/info-server:/usr/local/bin:/usr/ucb/bin:/usr/bin";
  1645. X
  1646. Xif( !delivered ){
  1647. X    pipe "/src.doc.ic.ac.uk/public/ic.doc/ftpmail/q.pl";
  1648. X}
  1649. END_OF_FILE
  1650.   if test 246 -ne `wc -c <'pp_mailfilter'`; then
  1651.     echo shar: \"'pp_mailfilter'\" unpacked with wrong size!
  1652.   fi
  1653.   # end of 'pp_mailfilter'
  1654. fi
  1655. if test -f 'sendmail_forward' -a "${1}" != "-c" ; then 
  1656.   echo shar: Will not clobber existing file \"'sendmail_forward'\"
  1657. else
  1658.   echo shar: Extracting \"'sendmail_forward'\" \(48 characters\)
  1659.   sed "s/^X//" >'sendmail_forward' <<'END_OF_FILE'
  1660. X"|/src.doc.ic.ac.uk/public/ic.doc/ftpmail/q.pl"
  1661. END_OF_FILE
  1662.   if test 48 -ne `wc -c <'sendmail_forward'`; then
  1663.     echo shar: \"'sendmail_forward'\" unpacked with wrong size!
  1664.   fi
  1665.   # end of 'sendmail_forward'
  1666. fi
  1667. if test -f 'socket.ph' -a "${1}" != "-c" ; then 
  1668.   echo shar: Will not clobber existing file \"'socket.ph'\"
  1669. else
  1670.   echo shar: Extracting \"'socket.ph'\" \(2752 characters\)
  1671.   sed "s/^X//" >'socket.ph' <<'END_OF_FILE'
  1672. Xif (!defined &_sys_socket_h) {
  1673. X    eval 'sub _sys_socket_h {1;}';
  1674. X    eval 'sub SOCK_STREAM {1;}';
  1675. X    eval 'sub SOCK_DGRAM {2;}';
  1676. X    eval 'sub SOCK_RAW {3;}';
  1677. X    eval 'sub SOCK_RDM {4;}';
  1678. X    eval 'sub SOCK_SEQPACKET {5;}';
  1679. X    eval 'sub SO_DEBUG {0x0001;}';
  1680. X    eval 'sub SO_ACCEPTCONN {0x0002;}';
  1681. X    eval 'sub SO_REUSEADDR {0x0004;}';
  1682. X    eval 'sub SO_KEEPALIVE {0x0008;}';
  1683. X    eval 'sub SO_DONTROUTE {0x0010;}';
  1684. X    eval 'sub SO_BROADCAST {0x0020;}';
  1685. X    eval 'sub SO_USELOOPBACK {0x0040;}';
  1686. X    eval 'sub SO_LINGER {0x0080;}';
  1687. X    eval 'sub SO_OOBINLINE {0x0100;}';
  1688. X    eval 'sub SO_DONTLINGER {(~ &SO_LINGER);}';
  1689. X    eval 'sub SO_SNDBUF {0x1001;}';
  1690. X    eval 'sub SO_RCVBUF {0x1002;}';
  1691. X    eval 'sub SO_SNDLOWAT {0x1003;}';
  1692. X    eval 'sub SO_RCVLOWAT {0x1004;}';
  1693. X    eval 'sub SO_SNDTIMEO {0x1005;}';
  1694. X    eval 'sub SO_RCVTIMEO {0x1006;}';
  1695. X    eval 'sub SO_ERROR {0x1007;}';
  1696. X    eval 'sub SO_TYPE {0x1008;}';
  1697. X    eval 'sub SOL_SOCKET {0xffff;}';
  1698. X    eval 'sub AF_UNSPEC {0;}';
  1699. X    eval 'sub AF_UNIX {1;}';
  1700. X    eval 'sub AF_INET {2;}';
  1701. X    eval 'sub AF_IMPLINK {3;}';
  1702. X    eval 'sub AF_PUP {4;}';
  1703. X    eval 'sub AF_CHAOS {5;}';
  1704. X    eval 'sub AF_NS {6;}';
  1705. X    eval 'sub AF_NBS {7;}';
  1706. X    eval 'sub AF_ECMA {8;}';
  1707. X    eval 'sub AF_DATAKIT {9;}';
  1708. X    eval 'sub AF_CCITT {10;}';
  1709. X    eval 'sub AF_SNA {11;}';
  1710. X    eval 'sub AF_DECnet {12;}';
  1711. X    eval 'sub AF_DLI {13;}';
  1712. X    eval 'sub AF_LAT {14;}';
  1713. X    eval 'sub AF_HYLINK {15;}';
  1714. X    eval 'sub AF_APPLETALK {16;}';
  1715. X    eval 'sub AF_NIT {17;}';
  1716. X    eval 'sub AF_802 {18;}';
  1717. X    eval 'sub AF_OSI {19;}';
  1718. X    eval 'sub AF_X25 {20;}';
  1719. X    eval 'sub AF_OSINET {21;}';
  1720. X    eval 'sub AF_GOSIP {22;}';
  1721. X    eval 'sub AF_MAX {21;}';
  1722. X    eval 'sub PF_UNSPEC { &AF_UNSPEC;}';
  1723. X    eval 'sub PF_UNIX { &AF_UNIX;}';
  1724. X    eval 'sub PF_INET { &AF_INET;}';
  1725. X    eval 'sub PF_IMPLINK { &AF_IMPLINK;}';
  1726. X    eval 'sub PF_PUP { &AF_PUP;}';
  1727. X    eval 'sub PF_CHAOS { &AF_CHAOS;}';
  1728. X    eval 'sub PF_NS { &AF_NS;}';
  1729. X    eval 'sub PF_NBS { &AF_NBS;}';
  1730. X    eval 'sub PF_ECMA { &AF_ECMA;}';
  1731. X    eval 'sub PF_DATAKIT { &AF_DATAKIT;}';
  1732. X    eval 'sub PF_CCITT { &AF_CCITT;}';
  1733. X    eval 'sub PF_SNA { &AF_SNA;}';
  1734. X    eval 'sub PF_DECnet { &AF_DECnet;}';
  1735. X    eval 'sub PF_DLI { &AF_DLI;}';
  1736. X    eval 'sub PF_LAT { &AF_LAT;}';
  1737. X    eval 'sub PF_HYLINK { &AF_HYLINK;}';
  1738. X    eval 'sub PF_APPLETALK { &AF_APPLETALK;}';
  1739. X    eval 'sub PF_NIT { &AF_NIT;}';
  1740. X    eval 'sub PF_802 { &AF_802;}';
  1741. X    eval 'sub PF_OSI { &AF_OSI;}';
  1742. X    eval 'sub PF_X25 { &AF_X25;}';
  1743. X    eval 'sub PF_OSINET { &AF_OSINET;}';
  1744. X    eval 'sub PF_GOSIP { &AF_GOSIP;}';
  1745. X    eval 'sub PF_MAX { &AF_MAX;}';
  1746. X    eval 'sub SOMAXCONN {5;}';
  1747. X    eval 'sub MSG_OOB {0x1;}';
  1748. X    eval 'sub MSG_PEEK {0x2;}';
  1749. X    eval 'sub MSG_DONTROUTE {0x4;}';
  1750. X    eval 'sub MSG_MAXIOVLEN {16;}';
  1751. X}
  1752. X1;
  1753. END_OF_FILE
  1754.   if test 2752 -ne `wc -c <'socket.ph'`; then
  1755.     echo shar: \"'socket.ph'\" unpacked with wrong size!
  1756.   fi
  1757.   # end of 'socket.ph'
  1758. fi
  1759. if test -f 'support.pl' -a "${1}" != "-c" ; then 
  1760.   echo shar: Will not clobber existing file \"'support.pl'\"
  1761. else
  1762.   echo shar: Extracting \"'support.pl'\" \(2450 characters\)
  1763.   sed "s/^X//" >'support.pl' <<'END_OF_FILE'
  1764. X# support for the ftpmail system
  1765. X# By Lee McLoughlin <lmjm@doc.ic.ac.uk>
  1766. X#  You can do what you like with this except claim that you wrote it or
  1767. X#  give copies with changes not approved by Lee.  Neither Lee nor any other
  1768. X#  organisation can be held liable for any problems caused by the use or
  1769. X#  storage of this package.
  1770. X#
  1771. X
  1772. X# Don't change this unless you are really clever.
  1773. X$ftpmail_response = '<FTP EMAIL> response';
  1774. X
  1775. X
  1776. X# Expects globals $qfile, $reply_to, $tries, and @comms
  1777. X# If updating_only is set then the file will not be recreated only updated.
  1778. Xsub write_entry
  1779. X{
  1780. X    local( $c );
  1781. X
  1782. X    if( $updating_only && ! -f $qfile ){
  1783. X        # Job must have been deleted
  1784. X        return;
  1785. X    }
  1786. X    open( qfile, "> $qfile" ) || die "Cannot create queue entry";;
  1787. X    local( $to ) = $reply_to;
  1788. X    $to =~ s/\\@/@/;
  1789. X    print qfile "reply-to $to\n";
  1790. X    print qfile "tries $tries $whenretry\n";
  1791. X    foreach $c ( @comms ){
  1792. X        print qfile "$c\n";
  1793. X    }
  1794. X    close( qfile );
  1795. X}
  1796. X
  1797. X# returns the number of items in the queue
  1798. Xsub queuelen
  1799. X{
  1800. X    local( @qfiles );
  1801. X    local( $qlen ) = 0;
  1802. X
  1803. X    @qfiles = ();
  1804. X    opendir( dir, $quedir ) || die "Cannot open directory $quedir ";
  1805. X    local( @dir ) = readdir( dir );
  1806. X    closedir( dir );
  1807. X
  1808. X    foreach $_ ( @dir ){
  1809. X        if( /^\d+\.\d+$/ ){
  1810. X            $qlen++;
  1811. X        }
  1812. X    }
  1813. X    return $qlen;
  1814. X}
  1815. X
  1816. X# Pretty print the contents of the comms array to MAIL
  1817. Xsub mail_comms
  1818. X{
  1819. X    local( $c );
  1820. X    local( $site, $user, $pass );
  1821. X    local( $show_open ) = 1;
  1822. X
  1823. X    print MAIL "      reply-to $reply_to\n";
  1824. X    foreach $_ ( @comms ){
  1825. X        if( /^open (.+)$/i ){
  1826. X            $site = $1;
  1827. X            next;
  1828. X        }
  1829. X        elsif( /^user (.+)$/i ){
  1830. X            $user = $1;
  1831. X            next;
  1832. X        }
  1833. X        elsif( /^pass (.+)$/i ){
  1834. X            $pass = $1;
  1835. X            next;
  1836. X        }
  1837. X        if( $show_open ){
  1838. X            print MAIL "      open $site $user $pass\n";
  1839. X            $show_open = 0;
  1840. X        }
  1841. X        local( $l ) = $_;
  1842. X        if( $l !~ /DONE/ ){
  1843. X            $l =~ s/^/     /;
  1844. X        }
  1845. X        print MAIL " $l\n";
  1846. X    }
  1847. X}
  1848. X
  1849. X# print the MAIL any contents of the ftpmail message of the day file
  1850. Xsub mail_motd
  1851. X{
  1852. X    if( open( motd, $motdfile ) ){
  1853. X        while( <motd> ){
  1854. X            print MAIL;
  1855. X        }
  1856. X        close( motd );
  1857. X    }
  1858. X}
  1859. X
  1860. Xsub fatal
  1861. X{
  1862. X    local( $fatal_error ) = @_;
  1863. X
  1864. X    &log( "Fatal error $fatal_error" );
  1865. X    exit( 0 );
  1866. X}
  1867. X
  1868. Xsub log
  1869. X{
  1870. X    local( $msg ) = @_;
  1871. X
  1872. X    &gettime();
  1873. X
  1874. X    open( LOG, ">>$logfile" ) || die "All is lost!\n";
  1875. X    print LOG "$time $msg\n";
  1876. X    close( LOG );
  1877. X}
  1878. X
  1879. Xsub gettime
  1880. X{
  1881. X    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
  1882. X                        localtime(time);
  1883. X    $time = sprintf( "%02d/%02d/%02d %02d:%02d:%02d",
  1884. X            $year, $mon+1, $mday, $hour, $min, $sec );
  1885. X}
  1886. X
  1887. X#  Make sure this package returns TRUE
  1888. X1;
  1889. END_OF_FILE
  1890.   if test 2450 -ne `wc -c <'support.pl'`; then
  1891.     echo shar: \"'support.pl'\" unpacked with wrong size!
  1892.   fi
  1893.   # end of 'support.pl'
  1894. fi
  1895. echo shar: End of archive 2 \(of 2\).
  1896. cp /dev/null ark2isdone
  1897. MISSING=""
  1898. for I in 1 2 ; do
  1899.     if test ! -f ark${I}isdone ; then
  1900.     MISSING="${MISSING} ${I}"
  1901.     fi
  1902. done
  1903. if test "${MISSING}" = "" ; then
  1904.     echo You have unpacked both archives.
  1905.     rm -f ark[1-9]isdone
  1906. else
  1907.     echo You still must unpack the following archives:
  1908.     echo "        " ${MISSING}
  1909. fi
  1910. exit 0
  1911. exit 0 # Just in case...
  1912.