home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume41 / mailagnt / part18 < prev    next >
Encoding:
Text File  |  1993-12-03  |  54.9 KB  |  1,768 lines

  1. Newsgroups: comp.sources.misc
  2. From: Raphael Manfredi <ram@acri.fr>
  3. Subject: v41i018:  mailagent - Flexible mail filtering and processing package, v3.0, Part18/26
  4. Message-ID: <1993Dec3.213347.22582@sparky.sterling.com>
  5. X-Md4-Signature: 981913fae13c29c88a6bd99d8a8e420e
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: Advanced Computer Research Institute, Lyon, France.
  8. Date: Fri, 3 Dec 1993 21:33:47 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: Raphael Manfredi <ram@acri.fr>
  12. Posting-number: Volume 41, Issue 18
  13. Archive-name: mailagent/part18
  14. Environment: UNIX, Perl
  15. Supersedes: mailagent: Volume 33, Issue 93-109
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  22. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  23. # Contents:  Artistic Makefile.SH agent/files/Makefile.SH
  24. #   agent/filter/Makefile.SH agent/filter/lock.c
  25. #   agent/filter/logfile.c agent/man/mailhelp.SH agent/pl/emergency.pl
  26. #   agent/pl/eval.pl
  27. # Wrapped by ram@soft208 on Mon Nov 29 16:49:57 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. echo If this archive is complete, you will see the following message:
  30. echo '          "shar: End of archive 18 (of 26)."'
  31. if test -f 'Artistic' -a "${1}" != "-c" ; then 
  32.   echo shar: Will not clobber existing file \"'Artistic'\"
  33. else
  34.   echo shar: Extracting \"'Artistic'\" \(6205 characters\)
  35.   sed "s/^X//" >'Artistic' <<'END_OF_FILE'
  36. X                      The "Artistic License"
  37. X
  38. X                             Preamble
  39. X
  40. XThe intent of this document is to state the conditions under which a
  41. XPackage may be copied, such that the Copyright Holder maintains some
  42. Xsemblance of artistic control over the development of the Package,
  43. Xwhile giving the users of the package the right to use and distribute
  44. Xthe Package in a more-or-less customary fashion, plus the right to make
  45. Xreasonable modifications.
  46. X
  47. XIt also grants you the rights to reuse parts of a Package in your own
  48. Xprograms without transferring this License to those programs, provided
  49. Xthat you meet some reasonable requirements.
  50. X
  51. XDefinitions:
  52. X
  53. X        "Package" refers to the collection of files distributed by the
  54. X        Copyright Holder, and derivatives of that collection of files
  55. X        created through textual modification.
  56. X
  57. X        "Standard Version" refers to such a Package if it has not been
  58. X        modified, or has been modified in accordance with the wishes
  59. X        of the Copyright Holder as specified below.
  60. X
  61. X        "Copyright Holder" is whoever is named in the copyright or
  62. X        copyrights for the package.
  63. X
  64. X        "You" is you, if you're thinking about copying or distributing
  65. X        this Package.
  66. X
  67. X        "Reasonable copying fee" is whatever you can justify on the
  68. X        basis of media cost, duplication charges, time of people involved,
  69. X        and so on.  (You will not be required to justify it to the
  70. X        Copyright Holder, but only to the computing community at large
  71. X        as a market that must bear the fee.)
  72. X
  73. X        "Freely Available" means that no fee is charged for the item
  74. X        itself, though there may be fees involved in handling the item.
  75. X        It also means that recipients of the item may redistribute it
  76. X        under the same conditions they received it.
  77. X
  78. X1. You may make and give away verbatim copies of the source form of the
  79. XStandard Version of this Package without restriction, provided that you
  80. Xduplicate all of the original copyright notices and associated disclaimers.
  81. X
  82. X2. You may apply bug fixes, portability fixes and other modifications
  83. Xderived from the Public Domain or from the Copyright Holder.  A Package
  84. Xmodified in such a way shall still be considered the Standard Version.
  85. X
  86. X3. You may otherwise modify your copy of this Package in any way, provided
  87. Xthat you insert a prominent notice in each changed file stating how and
  88. Xwhen you changed that file, and provided that you do at least ONE of the
  89. Xfollowing:
  90. X
  91. X    a) place your modifications in the Public Domain or otherwise make them
  92. X    Freely Available, such as by posting said modifications to Usenet or
  93. X    an equivalent medium, or placing the modifications on a major archive
  94. X    site such as uunet.uu.net, or by allowing the Copyright Holder to include
  95. X    your modifications in the Standard Version of the Package.
  96. X
  97. X    b) use the modified Package only within your corporation or organization.
  98. X
  99. X    c) rename any non-standard executables so the names do not conflict
  100. X    with standard executables, which must also be provided, and provide
  101. X    a separate manual page for each non-standard executable that clearly
  102. X    documents how it differs from the Standard Version.
  103. X
  104. X    d) make other distribution arrangements with the Copyright Holder.
  105. X
  106. X4. You may distribute the programs of this Package in object code or
  107. Xexecutable form, provided that you do at least ONE of the following:
  108. X
  109. X    a) distribute a Standard Version of the executables and library files,
  110. X    together with instructions (in the manual page or equivalent) on where
  111. X    to get the Standard Version.
  112. X
  113. X    b) accompany the distribution with the machine-readable source of
  114. X    the Package with your modifications.
  115. X
  116. X    c) give non-standard executables non-standard names, and clearly
  117. X    document the differences in manual pages (or equivalent), together
  118. X    with instructions on where to get the Standard Version.
  119. X
  120. X    d) make other distribution arrangements with the Copyright Holder.
  121. X
  122. X5. You may charge a reasonable copying fee for any distribution of this
  123. XPackage.  You may charge any fee you choose for support of this
  124. XPackage.  You may not charge a fee for this Package itself.  However,
  125. Xyou may distribute this Package in aggregate with other (possibly
  126. Xcommercial) programs as part of a larger (possibly commercial) software
  127. Xdistribution provided that you do not advertise this Package as a
  128. Xproduct of your own.
  129. X
  130. X6. The scripts and library files supplied as input to or produced as
  131. Xoutput from the programs of this Package do not automatically fall
  132. Xunder the copyright of this Package, but belong to whomever generated
  133. Xthem, and may be sold commercially, and may be aggregated with this
  134. XPackage.  If such scripts or library files are aggregated with this
  135. XPackage via the so-called "undump" or "unexec" methods of producing a
  136. Xbinary executable image, then distribution of such an image shall
  137. Xneither be construed as a distribution of this Package nor shall it
  138. Xfall under the restrictions of Paragraphs 3 and 4, provided that you do
  139. Xnot represent such an executable image as a Standard Version of this
  140. XPackage.
  141. X
  142. X7. You may reuse parts of this Package in your own programs, provided that
  143. Xyou explicitly state where you got them from, in the source code (and, left
  144. Xto your courtesy, in the documentation), duplicating all the associated
  145. Xcopyright notices and disclaimers. Besides your changes, if any, must be
  146. Xclearly marked as such. Parts reused that way will no longer fall under this
  147. Xlicense if, and only if, the name of your program(s) have no immediate
  148. Xconnection with the name of the Package itself or its associated programs.
  149. XYou may then apply whatever restrictions you wish on the reused parts or
  150. Xchoose to place them in the Public Domain--this will apply only within the
  151. Xcontext of your package.
  152. X
  153. X8. The name of the Copyright Holder may not be used to endorse or promote
  154. Xproducts derived from this software without specific prior written permission.
  155. X
  156. X9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
  157. XIMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  158. XWARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  159. X
  160. X                                The End
  161. END_OF_FILE
  162.   if test 6205 -ne `wc -c <'Artistic'`; then
  163.     echo shar: \"'Artistic'\" unpacked with wrong size!
  164.   fi
  165.   # end of 'Artistic'
  166. fi
  167. if test -f 'Makefile.SH' -a "${1}" != "-c" ; then 
  168.   echo shar: Will not clobber existing file \"'Makefile.SH'\"
  169. else
  170.   echo shar: Extracting \"'Makefile.SH'\" \(5126 characters\)
  171.   sed "s/^X//" >'Makefile.SH' <<'END_OF_FILE'
  172. X: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL14]
  173. X: $X-Id: Jmake.tmpl,v 3.0.1.1 1993/08/20 07:36:36 ram Exp ram $
  174. X
  175. Xcase $CONFIG in
  176. X'')
  177. X    if test -f config.sh; then TOP=.;
  178. X    elif test -f ../config.sh; then TOP=..;
  179. X    elif test -f ../../config.sh; then TOP=../..;
  180. X    elif test -f ../../../config.sh; then TOP=../../..;
  181. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  182. X    else
  183. X        echo "Can't find config.sh."; exit 1
  184. X    fi
  185. X    . $TOP/config.sh
  186. X    ;;
  187. Xesac
  188. Xcase "$0" in
  189. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  190. Xesac
  191. XCURRENT=.
  192. XDIR=`echo $CURRENT/ | sed -e 's/\.\///g'`
  193. Xecho "Extracting ${DIR}Makefile (with variable substitutions)"
  194. XDATE=`date`
  195. X$spitshell >Makefile <<!GROK!THIS!
  196. X########################################################################
  197. X# Makefile generated from Makefile.SH on $DATE
  198. X
  199. XSHELL = /bin/sh
  200. XJMAKE = jmake
  201. XTOP = .
  202. XCURRENT = $CURRENT
  203. XDIR = $DIR
  204. X
  205. X########################################################################
  206. X# Parameters set by Configure -- edit config.sh if changes are needed
  207. X
  208. XCTAGS = ctags
  209. XMAKE = make
  210. XMV = $mv
  211. XRM = $rm -f
  212. X
  213. X########################################################################
  214. X# Automatically generated parameters -- do not edit
  215. X
  216. XSUBDIRS = agent
  217. X
  218. X!GROK!THIS!
  219. X$spitshell >>Makefile <<'!NO!SUBS!'
  220. X########################################################################
  221. X# Jmake rules for building libraries, programs, scripts, and data files
  222. X# $X-Id: Jmake.rules,v 3.0 1993/08/18 12:04:14 ram Exp ram $
  223. X
  224. X########################################################################
  225. X# Start of Jmakefile
  226. X
  227. X# $X-Id: Jmakefile,v 2.9 92/07/14 16:46:57 ram Exp $
  228. X#
  229. X#  Copyright (c) 1990-1993, Raphael Manfredi
  230. X#  
  231. X#  You may redistribute only under the terms of the Artistic License,
  232. X#  as specified in the README file that comes with the distribution.
  233. X#  You may reuse parts of this distribution only within the terms of
  234. X#  that same Artistic License; a copy of which may be found at the root
  235. X#  of the source tree for mailagent 3.0.
  236. X#
  237. X# $X-Log$
  238. X
  239. Xall::
  240. X
  241. Xlocal_clobber::
  242. X    $(RM) install mkdep cppstdin
  243. X
  244. Xdepend::
  245. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  246. X    for i in $(SUBDIRS) ;\
  247. X    do \
  248. X        (cd $$i ; echo "Depending" "in $(DIR)$$i..."; \
  249. X            $(MAKE) $(MFLAGS)  depend); \
  250. X    done
  251. X
  252. X########################################################################
  253. X# Common rules for all Makefiles -- do not edit
  254. X
  255. Xemptyrule::
  256. X
  257. Xclean: sub_clean local_clean
  258. Xrealclean: sub_realclean local_realclean
  259. Xclobber: sub_clobber local_clobber
  260. X
  261. Xlocal_clean::
  262. X    $(RM) core *~ *.o
  263. X
  264. Xlocal_realclean:: local_clean
  265. X    $(RM) -r UU
  266. X
  267. Xlocal_clobber:: local_realclean
  268. X    $(RM) config.sh config.h
  269. X    $(RM) Makefile
  270. X
  271. XMakefile.SH: Jmakefile
  272. X    -@if test -f $(TOP)/.package; then \
  273. X        if test -f Makefile.SH; then \
  274. X            echo "    $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \
  275. X            $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \
  276. X        fi; \
  277. X        echo "    $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \
  278. X        $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \
  279. X    else touch $@; exit 0; fi
  280. X
  281. XMakefile: Makefile.SH
  282. X    /bin/sh Makefile.SH
  283. X
  284. Xtags::
  285. X    $(CTAGS) -w *.[ch]
  286. X    $(CTAGS) -xw *.[ch] > tags
  287. X
  288. Xlocal_clobber::
  289. X    $(RM) tags
  290. X
  291. X########################################################################
  292. X# Rules for building in sub-directories -- do not edit
  293. X
  294. Xsubdirs:
  295. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  296. X    for i in $(SUBDIRS) ;\
  297. X    do \
  298. X        (cd $$i ; echo $(VERB) "in $(DIR)$$i..."; \
  299. X            $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)); \
  300. X    done
  301. X
  302. Xinstall::
  303. X    @$(MAKE) subdirs TARGET=install VERB="Installing" FLAGS=
  304. X
  305. Xdeinstall::
  306. X    @$(MAKE) subdirs TARGET=deinstall VERB="Deinstalling" FLAGS=
  307. X
  308. Xinstall.man::
  309. X    @$(MAKE) subdirs TARGET=install.man VERB="Installing man pages" FLAGS=
  310. X
  311. Xdeinstall.man::
  312. X    @$(MAKE) subdirs TARGET=deinstall.man VERB="Deinstalling man pages" FLAGS=
  313. X
  314. Xsub_clean::
  315. X    @$(MAKE) subdirs TARGET=clean VERB="Cleaning" FLAGS=
  316. X    @echo "Back to $(CURRENT) for "clean...
  317. X
  318. Xsub_realclean::
  319. X    @$(MAKE) subdirs TARGET=realclean VERB="Real cleaning" FLAGS=
  320. X    @echo "Back to $(CURRENT) for "realclean...
  321. X
  322. Xsub_clobber::
  323. X    @$(MAKE) subdirs TARGET=clobber VERB="Clobbering" FLAGS=
  324. X    @echo "Back to $(CURRENT) for "clobber...
  325. X
  326. Xtag::
  327. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  328. X    for i in $(SUBDIRS) ;\
  329. X    do \
  330. X        (cd $$i ; echo "Tagging" "in $(DIR)$$i..."; \
  331. X            $(MAKE) $(MFLAGS)  tag); \
  332. X    done
  333. X
  334. XMakefiles::
  335. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  336. X    for i in $(SUBDIRS);\
  337. X    do \
  338. X        echo "Making "Makefiles" in $(DIR)$$i..."; \
  339. X        (cd $$i || exit 1; \
  340. X        if test ! -f Makefile; then /bin/sh Makefile.SH; fi; \
  341. X        $(MAKE) $(MFLAGS) Makefiles) \
  342. X    done
  343. X
  344. XMakefiles.SH:: Makefile.SH
  345. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  346. X    for i in $(SUBDIRS);\
  347. X    do \
  348. X        case "$(DIR)$$i/" in \
  349. X        */*/*/*/) newtop=../../../..;; \
  350. X        */*/*/) newtop=../../..;; \
  351. X        */*/) newtop=../..;; \
  352. X        */) newtop=..;; \
  353. X        esac; \
  354. X        case "$(TOP)" in \
  355. X        /*) newtop="$(TOP)" ;; \
  356. X        esac; \
  357. X        echo "Making Makefiles.SH in $(DIR)$$i..."; \
  358. X        (cd $$i || exit 1; $(MAKE) $(MFLAGS) -f ../Makefile \
  359. X        Makefile TOP=$$newtop CURRENT=$(DIR)$$i;\
  360. X        $(MAKE) $(MFLAGS) Makefiles.SH) \
  361. X    done
  362. X
  363. Xall::
  364. X    @$(MAKE) subdirs TARGET=all VERB="Making all" FLAGS=
  365. X
  366. X!NO!SUBS!
  367. Xchmod 644 Makefile
  368. X$eunicefix Makefile
  369. X
  370. END_OF_FILE
  371.   if test 5126 -ne `wc -c <'Makefile.SH'`; then
  372.     echo shar: \"'Makefile.SH'\" unpacked with wrong size!
  373.   fi
  374.   # end of 'Makefile.SH'
  375. fi
  376. if test -f 'agent/files/Makefile.SH' -a "${1}" != "-c" ; then 
  377.   echo shar: Will not clobber existing file \"'agent/files/Makefile.SH'\"
  378. else
  379.   echo shar: Extracting \"'agent/files/Makefile.SH'\" \(5457 characters\)
  380.   sed "s/^X//" >'agent/files/Makefile.SH' <<'END_OF_FILE'
  381. X: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL14]
  382. X: $X-Id: Jmake.tmpl,v 3.0.1.1 1993/08/20 07:36:36 ram Exp ram $
  383. X
  384. Xcase $CONFIG in
  385. X'')
  386. X    if test -f config.sh; then TOP=.;
  387. X    elif test -f ../config.sh; then TOP=..;
  388. X    elif test -f ../../config.sh; then TOP=../..;
  389. X    elif test -f ../../../config.sh; then TOP=../../..;
  390. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  391. X    else
  392. X        echo "Can't find config.sh."; exit 1
  393. X    fi
  394. X    . $TOP/config.sh
  395. X    ;;
  396. Xesac
  397. Xcase "$0" in
  398. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  399. Xesac
  400. XCURRENT=agent/files
  401. XDIR=`echo $CURRENT/ | sed -e 's/\.\///g'`
  402. Xecho "Extracting ${DIR}Makefile (with variable substitutions)"
  403. XDATE=`date`
  404. X$spitshell >Makefile <<!GROK!THIS!
  405. X########################################################################
  406. X# Makefile generated from Makefile.SH on $DATE
  407. X
  408. XSHELL = /bin/sh
  409. XJMAKE = jmake
  410. XTOP = ../..
  411. XCURRENT = $CURRENT
  412. XDIR = $DIR
  413. XINSTALL = ../../install
  414. X
  415. X########################################################################
  416. X# Parameters set by Configure -- edit config.sh if changes are needed
  417. X
  418. XCTAGS = ctags
  419. XMAKE = make
  420. XMV = $mv
  421. XPRIVLIB = $installprivlib
  422. XRM = $rm -f
  423. X
  424. X########################################################################
  425. X# Automatically generated parameters -- do not edit
  426. X
  427. XSUBDIRS = help
  428. X
  429. X!GROK!THIS!
  430. X$spitshell >>Makefile <<'!NO!SUBS!'
  431. X########################################################################
  432. X# Jmake rules for building libraries, programs, scripts, and data files
  433. X# $X-Id: Jmake.rules,v 3.0 1993/08/18 12:04:14 ram Exp ram $
  434. X
  435. X########################################################################
  436. X# Start of Jmakefile
  437. X
  438. X# $X-Id: Jmakefile,v 2.9 92/07/14 16:47:32 ram Exp $
  439. X#
  440. X#  Copyright (c) 1990-1993, Raphael Manfredi
  441. X#  
  442. X#  You may redistribute only under the terms of the Artistic License,
  443. X#  as specified in the README file that comes with the distribution.
  444. X#  You may reuse parts of this distribution only within the terms of
  445. X#  that same Artistic License; a copy of which may be found at the root
  446. X#  of the source tree for mailagent 3.0.
  447. X#
  448. X# $X-Log$
  449. X
  450. XFILES = agenthelp commands distribs filter.sh mailagent.cf proglist \
  451. X    chkagent.sh
  452. X
  453. Xall::
  454. X
  455. Xinstall::
  456. X    @for dir in $(PRIVLIB); do \
  457. X        case '${MFLAGS}' in *[i]*) set +e;; esac; \
  458. X        (set -x; $(INSTALL) -d $$dir); \
  459. X    done
  460. X
  461. Xdeinstall::
  462. X    $(RM) -r $(PRIVLIB)
  463. X
  464. Xinstall:: $(FILES)
  465. X    @case '${MFLAGS}' in *[i]*) set +e;; esac; \
  466. X    for i in $(FILES); do \
  467. X        (set -x; $(INSTALL) -c -m 444 $$i $(PRIVLIB)); \
  468. X    done
  469. X
  470. Xdeinstall::
  471. X    @case '${MFLAGS}' in *[i]*) set +e;; esac; \
  472. X    for i in $(FILES); do \
  473. X        (set -x; $(RM) $(PRIVLIB)/$$i); \
  474. X    done
  475. X
  476. X########################################################################
  477. X# Common rules for all Makefiles -- do not edit
  478. X
  479. Xemptyrule::
  480. X
  481. Xclean: sub_clean local_clean
  482. Xrealclean: sub_realclean local_realclean
  483. Xclobber: sub_clobber local_clobber
  484. X
  485. Xlocal_clean::
  486. X    $(RM) core *~ *.o
  487. X
  488. Xlocal_realclean:: local_clean
  489. X
  490. Xlocal_clobber:: local_realclean
  491. X    $(RM) Makefile config.sh
  492. X
  493. XMakefile.SH: Jmakefile
  494. X    -@if test -f $(TOP)/.package; then \
  495. X        if test -f Makefile.SH; then \
  496. X            echo "    $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \
  497. X            $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \
  498. X        fi; \
  499. X        echo "    $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \
  500. X        $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \
  501. X    else touch $@; exit 0; fi
  502. X
  503. XMakefile: Makefile.SH
  504. X    /bin/sh Makefile.SH
  505. X
  506. Xtags::
  507. X    $(CTAGS) -w *.[ch]
  508. X    $(CTAGS) -xw *.[ch] > tags
  509. X
  510. Xlocal_clobber::
  511. X    $(RM) tags
  512. X
  513. X########################################################################
  514. X# Rules for building in sub-directories -- do not edit
  515. X
  516. Xsubdirs:
  517. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  518. X    for i in $(SUBDIRS) ;\
  519. X    do \
  520. X        (cd $$i ; echo $(VERB) "in $(DIR)$$i..."; \
  521. X            $(MAKE) $(MFLAGS) $(FLAGS) $(TARGET)); \
  522. X    done
  523. X
  524. Xinstall::
  525. X    @$(MAKE) subdirs TARGET=install VERB="Installing" FLAGS=
  526. X
  527. Xdeinstall::
  528. X    @$(MAKE) subdirs TARGET=deinstall VERB="Deinstalling" FLAGS=
  529. X
  530. Xinstall.man::
  531. X    @$(MAKE) subdirs TARGET=install.man VERB="Installing man pages" FLAGS=
  532. X
  533. Xdeinstall.man::
  534. X    @$(MAKE) subdirs TARGET=deinstall.man VERB="Deinstalling man pages" FLAGS=
  535. X
  536. Xsub_clean::
  537. X    @$(MAKE) subdirs TARGET=clean VERB="Cleaning" FLAGS=
  538. X    @echo "Back to $(CURRENT) for "clean...
  539. X
  540. Xsub_realclean::
  541. X    @$(MAKE) subdirs TARGET=realclean VERB="Real cleaning" FLAGS=
  542. X    @echo "Back to $(CURRENT) for "realclean...
  543. X
  544. Xsub_clobber::
  545. X    @$(MAKE) subdirs TARGET=clobber VERB="Clobbering" FLAGS=
  546. X    @echo "Back to $(CURRENT) for "clobber...
  547. X
  548. Xtag::
  549. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  550. X    for i in $(SUBDIRS) ;\
  551. X    do \
  552. X        (cd $$i ; echo "Tagging" "in $(DIR)$$i..."; \
  553. X            $(MAKE) $(MFLAGS)  tag); \
  554. X    done
  555. X
  556. XMakefiles::
  557. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  558. X    for i in $(SUBDIRS);\
  559. X    do \
  560. X        echo "Making "Makefiles" in $(DIR)$$i..."; \
  561. X        (cd $$i || exit 1; \
  562. X        if test ! -f Makefile; then /bin/sh Makefile.SH; fi; \
  563. X        $(MAKE) $(MFLAGS) Makefiles) \
  564. X    done
  565. X
  566. XMakefiles.SH:: Makefile.SH
  567. X    @case '${MFLAGS}' in *[ik]*) set +e;; esac; \
  568. X    for i in $(SUBDIRS);\
  569. X    do \
  570. X        case "$(DIR)$$i/" in \
  571. X        */*/*/*/) newtop=../../../..;; \
  572. X        */*/*/) newtop=../../..;; \
  573. X        */*/) newtop=../..;; \
  574. X        */) newtop=..;; \
  575. X        esac; \
  576. X        case "$(TOP)" in \
  577. X        /*) newtop="$(TOP)" ;; \
  578. X        esac; \
  579. X        echo "Making Makefiles.SH in $(DIR)$$i..."; \
  580. X        (cd $$i || exit 1; $(MAKE) $(MFLAGS) -f ../Makefile \
  581. X        Makefile TOP=$$newtop CURRENT=$(DIR)$$i;\
  582. X        $(MAKE) $(MFLAGS) Makefiles.SH) \
  583. X    done
  584. X
  585. Xall::
  586. X    @$(MAKE) subdirs TARGET=all VERB="Making all" FLAGS=
  587. X
  588. X!NO!SUBS!
  589. Xchmod 644 Makefile
  590. X$eunicefix Makefile
  591. X
  592. END_OF_FILE
  593.   if test 5457 -ne `wc -c <'agent/files/Makefile.SH'`; then
  594.     echo shar: \"'agent/files/Makefile.SH'\" unpacked with wrong size!
  595.   fi
  596.   chmod +x 'agent/files/Makefile.SH'
  597.   # end of 'agent/files/Makefile.SH'
  598. fi
  599. if test -f 'agent/filter/Makefile.SH' -a "${1}" != "-c" ; then 
  600.   echo shar: Will not clobber existing file \"'agent/filter/Makefile.SH'\"
  601. else
  602.   echo shar: Extracting \"'agent/filter/Makefile.SH'\" \(5055 characters\)
  603.   sed "s/^X//" >'agent/filter/Makefile.SH' <<'END_OF_FILE'
  604. X: Makefile.SH generated from Jmake.tmpl and Jmakefile [jmake 3.0 PL14]
  605. X: $X-Id: Jmake.tmpl,v 3.0.1.1 1993/08/20 07:36:36 ram Exp ram $
  606. X
  607. Xcase $CONFIG in
  608. X'')
  609. X    if test -f config.sh; then TOP=.;
  610. X    elif test -f ../config.sh; then TOP=..;
  611. X    elif test -f ../../config.sh; then TOP=../..;
  612. X    elif test -f ../../../config.sh; then TOP=../../..;
  613. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  614. X    else
  615. X        echo "Can't find config.sh."; exit 1
  616. X    fi
  617. X    . $TOP/config.sh
  618. X    ;;
  619. Xesac
  620. Xcase "$0" in
  621. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  622. Xesac
  623. XCURRENT=agent/filter
  624. XDIR=`echo $CURRENT/ | sed -e 's/\.\///g'`
  625. Xecho "Extracting ${DIR}Makefile (with variable substitutions)"
  626. XDATE=`date`
  627. X$spitshell >Makefile <<!GROK!THIS!
  628. X########################################################################
  629. X# Makefile generated from Makefile.SH on $DATE
  630. X
  631. XSHELL = /bin/sh
  632. XJMAKE = jmake
  633. XTOP = ../..
  634. XCURRENT = $CURRENT
  635. XDIR = $DIR
  636. XINSTALL = ../../install
  637. X
  638. X########################################################################
  639. X# Parameters set by Configure -- edit config.sh if changes are needed
  640. X
  641. XCC = $cc
  642. XCTAGS = ctags
  643. XJCFLAGS = \$(CFLAGS) $optimize $ccflags $large
  644. XJLDFLAGS = \$(LDFLAGS) $optimize $ldflags
  645. XLIBS = $libs
  646. XMAKE = make
  647. XMKDEP = $mkdep \$(DPFLAGS) --
  648. XMV = $mv
  649. XPRIVLIB = $installprivlib
  650. XRM = $rm -f
  651. XSED = $sed
  652. X
  653. X########################################################################
  654. X# Automatically generated parameters -- do not edit
  655. X
  656. XSOURCES =  \$(SRC)
  657. XOBJECTS =  \$(OBJ)
  658. X
  659. X########################################################################
  660. X# New suffixes and associated building rules -- edit with care
  661. X
  662. X.c.o:
  663. X    \$(CC) -c \$(JCFLAGS) \$<
  664. X
  665. X!GROK!THIS!
  666. X$spitshell >>Makefile <<'!NO!SUBS!'
  667. X########################################################################
  668. X# Jmake rules for building libraries, programs, scripts, and data files
  669. X# $X-Id: Jmake.rules,v 3.0 1993/08/18 12:04:14 ram Exp ram $
  670. X
  671. X########################################################################
  672. X# Force 'make depend' to be performed first -- do not edit
  673. X
  674. X.FORCE_DEPEND::
  675. X
  676. Xall:: .FORCE_DEPEND
  677. X
  678. X########################################################################
  679. X# Start of Jmakefile
  680. X
  681. X# $X-Id: Jmakefile,v 2.9 92/07/14 18:41:10 ram Exp $
  682. X#
  683. X#  Copyright (c) 1990-1993, Raphael Manfredi
  684. X#  
  685. X#  You may redistribute only under the terms of the Artistic License,
  686. X#  as specified in the README file that comes with the distribution.
  687. X#  You may reuse parts of this distribution only within the terms of
  688. X#  that same Artistic License; a copy of which may be found at the root
  689. X#  of the source tree for mailagent 3.0.
  690. X#
  691. X# $X-Log$
  692. X
  693. X# Files used to build the application
  694. XSRC = environ.c hash.c io.c lock.c logfile.c main.c misc.c msg.c parser.c \
  695. X    user.c
  696. X
  697. X# Derived object file names
  698. XOBJ = \
  699. X    environ.o \
  700. X    hash.o \
  701. X    io.o \
  702. X    lock.o \
  703. X    logfile.o \
  704. X    main.o \
  705. X    misc.o \
  706. X    msg.o \
  707. X    parser.o \
  708. X    user.o 
  709. X
  710. X# File config.h is in the top-level directory
  711. XCFLAGS = -I$(TOP)
  712. XDPFLAGS = -I$(TOP)
  713. X
  714. Xdepend:: ../../mkdep
  715. X
  716. X../../mkdep:
  717. X    @echo "You have to run Configure in $(TOP) first."; exit 1
  718. X
  719. Xdepend::
  720. X    ($(SED) '/^# DO NOT DELETE/q' Makefile && \
  721. X    $(MKDEP) $(SOURCES) | \
  722. X    $(SED) 's/: \.\//: /; /\/usr\/include/d' \
  723. X    ) > Makefile.new
  724. X    cp Makefile Makefile.bak
  725. X    cp Makefile.new Makefile
  726. X    $(RM) Makefile.new
  727. X
  728. Xall:: filter
  729. X
  730. Xlocal_realclean::
  731. X    $(RM) filter
  732. X
  733. Xfilter: $(OBJ)
  734. X    $(RM) $@
  735. X    if test -f $@; then $(MV) $@ $@~; else exit 0; fi
  736. X    $(CC) -o $@ $(OBJ) $(JLDFLAGS) $(LIBS)
  737. X
  738. Xinstall:: filter
  739. X    $(INSTALL) -c -s -m 555  filter  $(PRIVLIB)
  740. X
  741. Xdeinstall::
  742. X    $(RM)  $(PRIVLIB)/filter
  743. X
  744. X########################################################################
  745. X# Common rules for all Makefiles -- do not edit
  746. X
  747. Xemptyrule::
  748. X
  749. Xclean: local_clean
  750. Xrealclean: local_realclean
  751. Xclobber: local_clobber
  752. X
  753. Xlocal_clean::
  754. X    $(RM) core *~ *.o
  755. X
  756. Xlocal_realclean:: local_clean
  757. X
  758. Xlocal_clobber:: local_realclean
  759. X    $(RM) Makefile config.sh
  760. X
  761. XMakefile.SH: Jmakefile
  762. X    -@if test -f $(TOP)/.package; then \
  763. X        if test -f Makefile.SH; then \
  764. X            echo "    $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~"; \
  765. X            $(RM) Makefile.SH~; $(MV) Makefile.SH Makefile.SH~; \
  766. X        fi; \
  767. X        echo "    $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT)" ; \
  768. X        $(JMAKE) -DTOPDIR=$(TOP) -DCURDIR=$(CURRENT) ; \
  769. X    else touch $@; exit 0; fi
  770. X
  771. XMakefile: Makefile.SH
  772. X    /bin/sh Makefile.SH
  773. X
  774. Xtags::
  775. X    $(CTAGS) -w *.[ch]
  776. X    $(CTAGS) -xw *.[ch] > tags
  777. X
  778. Xlocal_clobber::
  779. X    $(RM) tags
  780. X
  781. X########################################################################
  782. X# Empty rules for directories with no sub-directories -- do not edit
  783. X
  784. Xinstall::
  785. X    @echo "install in $(CURRENT) done."
  786. X
  787. Xdeinstall::
  788. X    @echo "deinstall in $(CURRENT) done."
  789. X
  790. Xinstall.man::
  791. X    @echo "install.man in $(CURRENT) done."
  792. X
  793. Xdeinstall.man::
  794. X    @echo "deinstall.man in $(CURRENT) done."
  795. X
  796. XMakefiles::
  797. X
  798. XMakefiles.SH::
  799. X
  800. X########################################################################
  801. X# Dependencies generated by make depend
  802. X# DO NOT DELETE THIS LINE -- make depend relies on it
  803. X
  804. X# Put nothing here or make depend will gobble it up
  805. X.FORCE_DEPEND::
  806. X    @echo "You must run 'make depend' in $(TOP) first."; exit 1
  807. X!NO!SUBS!
  808. Xchmod 644 Makefile
  809. X$eunicefix Makefile
  810. X
  811. END_OF_FILE
  812.   if test 5055 -ne `wc -c <'agent/filter/Makefile.SH'`; then
  813.     echo shar: \"'agent/filter/Makefile.SH'\" unpacked with wrong size!
  814.   fi
  815.   # end of 'agent/filter/Makefile.SH'
  816. fi
  817. if test -f 'agent/filter/lock.c' -a "${1}" != "-c" ; then 
  818.   echo shar: Will not clobber existing file \"'agent/filter/lock.c'\"
  819. else
  820.   echo shar: Extracting \"'agent/filter/lock.c'\" \(3106 characters\)
  821.   sed "s/^X//" >'agent/filter/lock.c' <<'END_OF_FILE'
  822. X/*
  823. X
  824. X #        ####    ####   #    #           ####
  825. X #       #    #  #    #  #   #           #    #
  826. X #       #    #  #       ####            #
  827. X #       #    #  #       #  #     ###    #
  828. X #       #    #  #    #  #   #    ###    #    #
  829. X ######   ####    ####   #    #   ###     ####
  830. X
  831. X    Lock file handling.
  832. X*/
  833. X
  834. X/*
  835. X * $Id: lock.c,v 3.0 1993/11/29 13:48:12 ram Exp ram $
  836. X *
  837. X *  Copyright (c) 1990-1993, Raphael Manfredi
  838. X *  
  839. X *  You may redistribute only under the terms of the Artistic License,
  840. X *  as specified in the README file that comes with the distribution.
  841. X *  You may reuse parts of this distribution only within the terms of
  842. X *  that same Artistic License; a copy of which may be found at the root
  843. X *  of the source tree for mailagent 3.0.
  844. X *
  845. X * $Log: lock.c,v $
  846. X * Revision 3.0  1993/11/29  13:48:12  ram
  847. X * Baseline for mailagent 3.0 netwide release.
  848. X *
  849. X */
  850. X
  851. X#include "config.h"
  852. X#include "portable.h"
  853. X#include <errno.h>
  854. X#include <sys/types.h>
  855. X#include <sys/stat.h>
  856. X
  857. X#ifdef I_FCNTL
  858. X#include <fcntl.h>
  859. X#else
  860. X#include <sys/fcntl.h>
  861. X#endif
  862. X#ifdef I_SYS_FILE
  863. X#include <sys/file.h>
  864. X#endif
  865. X#include "confmagic.h"
  866. X
  867. X#define MAX_STRING    2048        /* Max string length */
  868. X#define MAX_TIME    3600        /* One hour */
  869. X
  870. Xprivate char lockfile[MAX_STRING];        /* Location of lock file */
  871. Xprivate int locked = 0;                    /* Did we lock successfully? */
  872. X
  873. Xprivate void check_lock();                /* Make sure lockfile is not too old */
  874. X
  875. Xextern int errno;                        /* System error status */
  876. Xextern Time_t time();                    /* Current time */
  877. X
  878. Xpublic int filter_lock(dir)
  879. Xchar *dir;                        /* Where lockfile should be written */
  880. X{
  881. X    /* Note: this locking is not completly safe w.r.t. race conditions, but the
  882. X     * mailagent will do its own locking checks in a rather safe way.
  883. X     * Return 0 if locking succeeds, -1 otherwise.
  884. X     */
  885. X
  886. X    int fd;
  887. X
  888. X    sprintf(lockfile, "%s/filter.lock", dir);
  889. X    check_lock(lockfile);
  890. X    if (-1 == (fd = open(lockfile, O_CREAT | O_EXCL, 0))) {
  891. X        if (errno != EEXIST)
  892. X            add_log(1, "SYSERR open: %m (%e)");
  893. X        return -1;
  894. X    }
  895. X    locked = 1;                    /* We did lock successfully */
  896. X    close(fd);                    /* Close dummy file descriptor */
  897. X
  898. X    return 0;
  899. X}
  900. X
  901. Xpublic void release_lock()
  902. X{
  903. X    if (locked && -1 == unlink(lockfile)) {
  904. X        add_log(1, "SYSERR unlink: %m (%e)");
  905. X        add_log(4, "WARNING could not remove lockfile %s", lockfile);
  906. X    }
  907. X    locked = 0;
  908. X}
  909. X
  910. Xpublic int is_locked()
  911. X{
  912. X    return locked;            /* Do we have a lock file active or not? */
  913. X}
  914. X
  915. Xprivate void check_lock(file)
  916. Xchar *file;
  917. X{
  918. X    /* Make sure the lock file is not older than MAX_TIME seconds, otherwise
  919. X     * unlink it (something must have gone wrong).
  920. X     */
  921. X
  922. X    struct stat buf;
  923. X
  924. X    if (-1 == stat(file, &buf)) {        /* Stat failed */
  925. X        if (errno == ENOENT)            /* File does not exist */
  926. X            return;
  927. X        add_log(1, "SYSERR stat: %m (%e)");
  928. X        add_log(2, "could not check lockfile %s", file);
  929. X        return;
  930. X    }
  931. X
  932. X    if (time((Time_t *) 0) - buf.st_mtime > MAX_TIME) {
  933. X        if (-1 == unlink(lockfile)) {
  934. X            add_log(1, "SYSERR unlink: %m (%e)");
  935. X            add_log(4, "WARNING could not remove old lock %s", lockfile);
  936. X        } else
  937. X            add_log(6, "UNLOCKED filter (lock older than 1 hour)");
  938. X    } else
  939. X        add_log(16, "lockfile for filter is recent");
  940. X}
  941. X
  942. END_OF_FILE
  943.   if test 3106 -ne `wc -c <'agent/filter/lock.c'`; then
  944.     echo shar: \"'agent/filter/lock.c'\" unpacked with wrong size!
  945.   fi
  946.   # end of 'agent/filter/lock.c'
  947. fi
  948. if test -f 'agent/filter/logfile.c' -a "${1}" != "-c" ; then 
  949.   echo shar: Will not clobber existing file \"'agent/filter/logfile.c'\"
  950. else
  951.   echo shar: Extracting \"'agent/filter/logfile.c'\" \(5979 characters\)
  952.   sed "s/^X//" >'agent/filter/logfile.c' <<'END_OF_FILE'
  953. X/*
  954. X
  955. X #        ####    ####   ######     #    #       ######           ####
  956. X #       #    #  #    #  #          #    #       #               #    #
  957. X #       #    #  #       #####      #    #       #####           #
  958. X #       #    #  #  ###  #          #    #       #        ###    #
  959. X #       #    #  #    #  #          #    #       #        ###    #    #
  960. X ######   ####    ####   #          #    ######  ######   ###     ####
  961. X
  962. X    Handles logging facilities.
  963. X*/
  964. X
  965. X/*
  966. X * $Id: logfile.c,v 3.0 1993/11/29 13:48:14 ram Exp ram $
  967. X *
  968. X *  Copyright (c) 1990-1993, Raphael Manfredi
  969. X *  
  970. X *  You may redistribute only under the terms of the Artistic License,
  971. X *  as specified in the README file that comes with the distribution.
  972. X *  You may reuse parts of this distribution only within the terms of
  973. X *  that same Artistic License; a copy of which may be found at the root
  974. X *  of the source tree for mailagent 3.0.
  975. X *
  976. X * $Log: logfile.c,v $
  977. X * Revision 3.0  1993/11/29  13:48:14  ram
  978. X * Baseline for mailagent 3.0 netwide release.
  979. X *
  980. X */
  981. X
  982. X#include "config.h"
  983. X#include "portable.h"
  984. X#include <stdio.h>
  985. X#include <sys/types.h>
  986. X
  987. X#ifdef I_TIME
  988. X# include <time.h>
  989. X#endif
  990. X#ifdef I_SYS_TIME
  991. X# include <sys/time.h>
  992. X#endif
  993. X#ifdef I_SYS_TIME_KERNEL
  994. X# define KERNEL
  995. X# include <sys/time.h>
  996. X# undef KERNEL
  997. X#endif
  998. X#include "confmagic.h"
  999. X
  1000. X#define MAX_STRING    1024            /* Maximum length for logging string */
  1001. X
  1002. Xprivate FILE *logfile = (FILE *) 0;    /* File pointer used for logging */
  1003. Xshared int loglvl = 20;                /* Logging level */
  1004. Xprivate char *logname;                /* Name of the logfile in use */
  1005. Xprivate void expand();                /* Run the %m %e expansion on the string */
  1006. Xprivate int add_error();            /* Prints description of error in errno */
  1007. Xprivate int add_errcode();            /* Print the symbolic error name */
  1008. X
  1009. Xpublic char *progname = "ram";    /* Program name */
  1010. Xpublic Pid_t progpid = 0;        /* Program PID */
  1011. X
  1012. Xextern Time_t time();            /* Time in seconds since the Epoch */
  1013. Xextern char *malloc();            /* Memory allocation */
  1014. Xextern char *strsave();            /* Save string in memory */
  1015. Xextern int errno;                /* System error report variable */
  1016. X
  1017. X/* VARARGS2 */
  1018. Xpublic void add_log(level, format, arg1, arg2, arg3, arg4, arg5)
  1019. Xint level;
  1020. Xchar *format;
  1021. Xlong arg1, arg2, arg3, arg4, arg5;    /* Use long instead of int for 64 bits */
  1022. X{
  1023. X    /* Add logging informations at specified level. Note that the arguments are
  1024. X     * declared as 'int', but it should work fine, even when we give doubles,
  1025. X     * because they will be pased "as is" to fprintf. Maybe I should use
  1026. X     * vfprintf when it is available--RAM.
  1027. X     * The only magic string substitution which occurs is the '%m', which is
  1028. X     * replaced by the error message, as given by errno and '%e' which gives
  1029. X     * the symbolic name of the error (if available, otherwise the number).
  1030. X     * The log file must have been opened with open_log() before add_log calls.
  1031. X     */
  1032. X
  1033. X    struct tm *ct;                /* Current time (pointer to static data) */
  1034. X    Time_t clock;                /* Number of seconds since the Epoch */
  1035. X    char buffer[MAX_STRING];    /* Buffer which holds the expanded %m string */
  1036. X
  1037. X    if (loglvl < level)            /* Logging level is not high enough */
  1038. X        return;
  1039. X
  1040. X    if (logfile == (FILE *) 0)    /* Logfile not opened for whatever reason */
  1041. X        return;
  1042. X
  1043. X    clock = time((Time_t *) 0);    /* Number of seconds */
  1044. X    ct = localtime(&clock);        /* Get local time from amount of seconds */
  1045. X    expand(format, buffer);        /* Expansion of %m and %e into buffer */
  1046. X
  1047. X    fprintf(logfile, "%d/%.2d/%.2d %.2d:%.2d:%.2d %s[%d]: ",
  1048. X        ct->tm_year, ct->tm_mon + 1, ct->tm_mday,
  1049. X        ct->tm_hour, ct->tm_min, ct->tm_sec,
  1050. X        progname, progpid);
  1051. X
  1052. X    fprintf(logfile, buffer, arg1, arg2, arg3, arg4, arg5);
  1053. X    putc('\n', logfile);
  1054. X    fflush(logfile);
  1055. X}
  1056. X
  1057. Xpublic int open_log(name)
  1058. Xchar *name;
  1059. X{
  1060. X    /* Open log file 'name' for logging. If a previous log file was opened,
  1061. X     * it is closed before. The routine returns -1 in case of error.
  1062. X     */
  1063. X    
  1064. X    if (logfile != (FILE *) 0)
  1065. X        fclose(logfile);
  1066. X    
  1067. X    logfile = fopen(name, "a");        /* Append to existing file */
  1068. X    logname = strsave(name);        /* Save file name */
  1069. X
  1070. X    if (logfile == (FILE *) 0)
  1071. X        return -1;
  1072. X    
  1073. X    return 0;
  1074. X}
  1075. X
  1076. Xpublic void close_log()
  1077. X{
  1078. X    /* Close log file */
  1079. X
  1080. X    if (logfile != (FILE *) 0)
  1081. X        fclose(logfile);
  1082. X
  1083. X    logfile = (FILE *) 0;
  1084. X}
  1085. X
  1086. Xpublic void set_loglvl(level)
  1087. Xint level;
  1088. X{
  1089. X    /* Set logging level to 'level' */
  1090. X
  1091. X    loglvl = level;
  1092. X}
  1093. X
  1094. Xprivate void expand(from, to)
  1095. Xchar *from;
  1096. Xchar *to;
  1097. X{
  1098. X    /* The string held in 'from' is copied into 'to' and every '%m' is expanded
  1099. X     * into the error message deduced from the value of errno.
  1100. X     */
  1101. X
  1102. X    int len;                            /* Length of substituted text */
  1103. X
  1104. X    while (*to++ = *from)
  1105. X        if (*from++ == '%')
  1106. X            switch (*from) {
  1107. X            case 'm':                    /* %m is the English description */
  1108. X                len = add_error(to - 1);
  1109. X                to += len - 1;
  1110. X                from++;
  1111. X                break;
  1112. X            case 'e':                    /* %e is the symbolic error code */
  1113. X                len = add_errcode(to - 1);
  1114. X                to += len - 1;
  1115. X                from++;
  1116. X                break;
  1117. X            }
  1118. X}
  1119. X
  1120. Xprivate int add_error(where)
  1121. Xchar *where;
  1122. X{
  1123. X    /* Prints a description of the error code held in 'errno' into 'where' if
  1124. X     * it is available, otherwise simply print the error code number.
  1125. X     */
  1126. X
  1127. X#ifdef HAS_SYS_ERRLIST
  1128. X    extern int sys_nerr;                    /* Size of sys_errlist[] */
  1129. X    extern char *sys_errlist[];                /* Maps error code to string */
  1130. X#endif
  1131. X
  1132. X#ifdef HAS_STRERROR
  1133. X    sprintf(where, "%s", strerror(errno));
  1134. X#else
  1135. X#ifdef HAS_SYS_ERRLIST
  1136. X    sprintf(where, "%s", strerror(errno));    /* Macro defined by Configure */
  1137. X#else
  1138. X    sprintf(where, "error #%d", errno);
  1139. X#endif
  1140. X#endif
  1141. X
  1142. X    return strlen(where);
  1143. X}
  1144. X
  1145. Xprivate int add_errcode(where)
  1146. Xchar *where;
  1147. X{
  1148. X    /* Prints the symbolic description of the error code heldin in 'errno' into
  1149. X     * 'where' if possible. Otherwise, prints the error number.
  1150. X     */
  1151. X    
  1152. X#ifdef HAS_SYS_ERRNOLIST
  1153. X    extern int sys_nerrno;                    /* Size of sys_errnolist[] */
  1154. X    extern char *sys_errnolist[];            /* Error code to symbolic name */
  1155. X#endif
  1156. X
  1157. X#ifdef HAS_SYS_ERRNOLIST
  1158. X    if (errno < 0 || errno >= sys_nerrno)
  1159. X        sprintf(where, "UNKNOWN");
  1160. X    else
  1161. X        sprintf(where, "%s", sys_errnolist[errno]);
  1162. X#else
  1163. X        sprintf(where, "%d", errno);
  1164. X#endif
  1165. X
  1166. X    return strlen(where);
  1167. X}
  1168. X
  1169. END_OF_FILE
  1170.   if test 5979 -ne `wc -c <'agent/filter/logfile.c'`; then
  1171.     echo shar: \"'agent/filter/logfile.c'\" unpacked with wrong size!
  1172.   fi
  1173.   # end of 'agent/filter/logfile.c'
  1174. fi
  1175. if test -f 'agent/man/mailhelp.SH' -a "${1}" != "-c" ; then 
  1176.   echo shar: Will not clobber existing file \"'agent/man/mailhelp.SH'\"
  1177. else
  1178.   echo shar: Extracting \"'agent/man/mailhelp.SH'\" \(5834 characters\)
  1179.   sed "s/^X//" >'agent/man/mailhelp.SH' <<'END_OF_FILE'
  1180. Xcase $CONFIG in
  1181. X'')
  1182. X    if test -f config.sh; then TOP=.;
  1183. X    elif test -f ../config.sh; then TOP=..;
  1184. X    elif test -f ../../config.sh; then TOP=../..;
  1185. X    elif test -f ../../../config.sh; then TOP=../../..;
  1186. X    elif test -f ../../../../config.sh; then TOP=../../../..;
  1187. X    else
  1188. X        echo "Can't find config.sh."; exit 1
  1189. X    fi
  1190. X    . $TOP/config.sh
  1191. X    ;;
  1192. Xesac
  1193. Xcase "$0" in
  1194. X*/*) cd `expr X$0 : 'X\(.*\)/'` ;;
  1195. Xesac
  1196. Xecho "Extracting agent/man/mailhelp.$manext (with variable substitutions)"
  1197. X$rm -f mailhelp.$manext
  1198. X$spitshell >mailhelp.$manext <<!GROK!THIS!
  1199. X.TH MAILHELP $manext ram
  1200. X''' @(#) Manual page for mailagent's commands -- (c) ram February 1991
  1201. X'''
  1202. X''' $Id: mailhelp.SH,v 3.0 1993/11/29 13:48:29 ram Exp ram $
  1203. X'''
  1204. X'''  Copyright (c) 1990-1993, Raphael Manfredi
  1205. X'''  
  1206. X'''  You may redistribute only under the terms of the Artistic License,
  1207. X'''  as specified in the README file that comes with the distribution.
  1208. X'''  You may reuse parts of this distribution only within the terms of
  1209. X'''  that same Artistic License; a copy of which may be found at the root
  1210. X'''  of the source tree for mailagent 3.0.
  1211. X'''
  1212. X''' $Log: mailhelp.SH,v $
  1213. X''' Revision 3.0  1993/11/29  13:48:29  ram
  1214. X''' Baseline for mailagent 3.0 netwide release.
  1215. X'''
  1216. X.SH NAME
  1217. Xmaildist, mailhelp, maillist, mailpatch \- mailagent's commands
  1218. X.SH SYNOPSIS
  1219. X\fBmaildist\fR \fIaddress\fR \fIsystem\fR [ \fIversion\fR ]
  1220. X.br
  1221. X\fBmailhelp\fR [ \fIaddress\fR ]
  1222. X.br
  1223. X\fBmaillist\fR [ \fIaddress\fR ]
  1224. X.br
  1225. X\fBmailpatch\fR \fIaddress\fR \fIsystem\fR \fIversion\fR \fIpatchlist\fR
  1226. X.SH DESCRIPTION
  1227. XThese commands are not intended to be run directly by a user. They may
  1228. Xappear in any mail whose subject is set to \fICommand\fR. Such a mail
  1229. Xwill be processed by the \fImailagent\fR(1), which will extract all lines
  1230. Xbeginning with \fI@SH\fR, followed by one of the above commands. The
  1231. Xmailagent first sets environment variables that will be used by every
  1232. Xcommands.
  1233. X.PP
  1234. X.I Maildist
  1235. Xis used to mail a whole distribution to the given address. The version
  1236. Xnumber may be ommitted if the system has no version specified !!
  1237. X.I Maildist
  1238. Xlooks for the \fISpool/distribs\fR file to find where the distribution
  1239. Xis located. If it has been archived, the file name extension is used
  1240. Xto guess how the archive will be restored:
  1241. X.sp
  1242. X.PD 0
  1243. X.TP 10
  1244. X.B .cpio
  1245. Xarchive is a \fIcpio\fR archive
  1246. X.TP
  1247. X.B .tar
  1248. Xarchive is in \fItar\fR format
  1249. X.TP
  1250. X.B .cpio.Z
  1251. Xcompressed \fIcpio\fR archive
  1252. X.TP
  1253. X.B .tar.Z
  1254. Xcompressed \fItar\fR archive
  1255. X.PD
  1256. X.PP
  1257. XNote that on file systems with short file names, the final \fB.Z\fR
  1258. Xextension could be dropped. Therefore, compressed archives must be
  1259. Xexplicitely stated in the \fISpool/distribs\fR file.
  1260. X.PP
  1261. XOnce the directory is found (or extracted), \fImaildist\fR looks
  1262. Xfor a \fI.package\fR file. If one is found, then it is assumed this
  1263. Xdistribution is under control of the dist 3.0 package, and the \fImakedist\fR
  1264. Xcommmand is called to actually mirror the source tree (makedist being part of
  1265. Xdist 3.0).
  1266. X.PP
  1267. XOtherwise, it looks
  1268. Xfor a \fIMANIFEST\fR file. If it finds one,
  1269. Xonly the files listed therein will be sent. Otherwise,
  1270. Xall the files will be sent, excepted the binary executables and object
  1271. Xfiles, the RCS sub-directories or RCS files, the private \fIU\fR
  1272. Xsubdirectory and the \fI.package\fR file, any \fIcore\fR file or files
  1273. Xin a \fIbugs\fR subdirectory.
  1274. X.PP
  1275. XThen, the following algorithm is used: if no RCS file is found, the
  1276. Xfile is sent as-is. Otherwise, we look for a defined 'lastpat' symbol.
  1277. XIf it is found, the corresponding revision is checked-out and sent.
  1278. XOtherwise, the last-revision on the default branch is exctracted,
  1279. Xprovided that the corresponding working file is not found.
  1280. X.PP
  1281. XThe \fImaildist\fR command will not work if the system is tagged as
  1282. Xan old one (with an \fIo\fR in the patches column of the \fIdistribs\fR
  1283. Xfile). A message will be sent back to the user, explaining that only
  1284. Xpatches are available.
  1285. X.PP
  1286. X.I Mailhelp
  1287. Xsends help to the address (if ommitted, the return path of the mail
  1288. Xis used). The help text is found in \fISpool/agenthelp\fR. It should
  1289. Xhave been correctly set in the installation procedure, as explained
  1290. Xin the \fImailagent\fR($manext) manual page.
  1291. X.PP
  1292. X.I Maillist
  1293. Xsends the list of available distributions, with current patchlevels
  1294. Xif necessary. The \fISpool/distribs\fR and \fISpool/proglist\fR files
  1295. Xare both used to build the list.
  1296. X.PP
  1297. X.I Mailpatch
  1298. Xsends one or more patches for a maintained distribution. The directory
  1299. Xor the archive is found by scanning \fISpool/distribs\fR. The \fIbugs\fR
  1300. Xsub-directory must then hold the available patches. The patches may
  1301. Xbe stored in compressed form (with the ending \fI.Z\fR), as
  1302. X.I mailpatch
  1303. Xknows about them and will uncompress the patch before sending.
  1304. X.PP
  1305. XPatches for old systems are kept in a separate directory, either in normal
  1306. Xor in compressed form. If the version number of the old system is \fIx.y\fR,
  1307. Xthen the directory must be named \fIbugs-x.y\fR and placed in the root
  1308. Xdirectory of the system, just like \fIbugs\fR is.
  1309. X.PP
  1310. XWhenever the user asks for an old system, \fImailpatch\fR inserts a little
  1311. Xnote giving the latest version number for that system.
  1312. X.SH NOTE
  1313. XFor a more accurate description of these commands (user's point of vue),
  1314. Xyou may want to have a look at the help file or send help to yourself
  1315. Xusing the \fImailhelp\fR command.
  1316. X.SH FILES
  1317. X.PD 0
  1318. X.TP 20
  1319. X~/.mailagent
  1320. Xconfiguration file for mailagent.
  1321. X.TP
  1322. X$privlib
  1323. Xdirectory holding templates and samples.
  1324. X.TP
  1325. XSpool/agenthelp
  1326. Xhelp file
  1327. X.TP
  1328. XSpool/distribs
  1329. Xdistribution list
  1330. X.TP
  1331. XSpool/proglist
  1332. Xcomments for available distributions
  1333. X.TP
  1334. XSpool/plsave
  1335. Xrecords patchlevel of archived distributions
  1336. X.TP
  1337. XLog/agentlog
  1338. Xmailagent's log file
  1339. X.PD
  1340. X.SH BUGS
  1341. XThe \fIproglist\fR file ought to make a distinction between different
  1342. Xversions of a same system.
  1343. X.SH AUTHOR
  1344. XRaphael Manfredi <ram@acri.fr>
  1345. X.SH "SEE ALSO"
  1346. Xmailagent($manext).
  1347. X!GROK!THIS!
  1348. Xchmod 444 mailhelp.$manext
  1349. END_OF_FILE
  1350.   if test 5834 -ne `wc -c <'agent/man/mailhelp.SH'`; then
  1351.     echo shar: \"'agent/man/mailhelp.SH'\" unpacked with wrong size!
  1352.   fi
  1353.   # end of 'agent/man/mailhelp.SH'
  1354. fi
  1355. if test -f 'agent/pl/emergency.pl' -a "${1}" != "-c" ; then 
  1356.   echo shar: Will not clobber existing file \"'agent/pl/emergency.pl'\"
  1357. else
  1358.   echo shar: Extracting \"'agent/pl/emergency.pl'\" \(5547 characters\)
  1359.   sed "s/^X//" >'agent/pl/emergency.pl' <<'END_OF_FILE'
  1360. X;# $Id: emergency.pl,v 3.0 1993/11/29 13:48:41 ram Exp ram $
  1361. X;#
  1362. X;#  Copyright (c) 1990-1993, Raphael Manfredi
  1363. X;#  
  1364. X;#  You may redistribute only under the terms of the Artistic License,
  1365. X;#  as specified in the README file that comes with the distribution.
  1366. X;#  You may reuse parts of this distribution only within the terms of
  1367. X;#  that same Artistic License; a copy of which may be found at the root
  1368. X;#  of the source tree for mailagent 3.0.
  1369. X;#
  1370. X;# $Log: emergency.pl,v $
  1371. X;# Revision 3.0  1993/11/29  13:48:41  ram
  1372. X;# Baseline for mailagent 3.0 netwide release.
  1373. X;#
  1374. X;# 
  1375. X#
  1376. X# Emergency situation routines
  1377. X#
  1378. X
  1379. X# Emergency signal was caught
  1380. Xsub emergency {
  1381. X    local($sig) = @_;            # First argument is signal name
  1382. X    if ($has_option) {            # Mailagent was invoked "manually"
  1383. X        &resync;                # Resynchronize waiting file if necessary
  1384. X        exit 1;
  1385. X    }
  1386. X    &fatal("trapped SIG$sig");
  1387. X}
  1388. X
  1389. X# In case something got wrong
  1390. Xsub fatal {
  1391. X    local($reason) = shift;        # Why did we get here ?
  1392. X    # Make sure the lock file does not last. We don't need any lock now, as
  1393. X    # we are going to die real soon anyway.
  1394. X    unlink $lockfile if $locked;
  1395. X    # Assume the whole message has not been read yet
  1396. X    $fd = STDIN;                # Default input
  1397. X    if ($file_name ne '') {
  1398. X        $Header{'All'} = '';    # We're about to re-read the whole message
  1399. X        open(MSG, $file_name);    # Ignore errors
  1400. X        $fd = MSG;
  1401. X    }
  1402. X    unless (-t $fd) {            # Do not get mail if connected to a tty
  1403. X        while (<$fd>) {
  1404. X            $Header{'All'} .= $_;
  1405. X        }
  1406. X    }
  1407. X    # It can happen that we get here before configuration file was read
  1408. X    if (defined $loglvl) {
  1409. X        &add_log("FATAL $reason") if $loglvl;
  1410. X        -t STDIN && print STDERR "$prog_name: $reason\n";
  1411. X    }
  1412. X    # Try an emergency save, if mail is not empty
  1413. X    if ($Header{'All'} ne '' && 0 == &emergency_save) {
  1414. X        # The stderr should be redirected to some file
  1415. X        $file_name =~ s|.*/(.*)|$1|;    # Keep only basename
  1416. X        $file_name = "<stdin>" if $file_name eq '';
  1417. X        print STDERR "**** $file_name not processed ($reason) ****\n";
  1418. X        print STDERR $Header{'All'};
  1419. X        ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
  1420. X            localtime(time);
  1421. X        $date = sprintf("%.2d/%.2d/%.2d %.2d:%.2d:%.2d",
  1422. X            $year,++$mon,$mday,$hour,$min,$sec);
  1423. X        print STDERR "---- $date ----\n";
  1424. X    }
  1425. X    &resync;            # Resynchronize waiting file if necessary
  1426. X    # Give an error exit status to filter
  1427. X    exit 1;
  1428. X}
  1429. X
  1430. X# Emergency saving of message held in $Header{'All'}. If the 'emergdir'
  1431. X# configuration parameter in ~/.mailagent is set to an existing directory, the
  1432. X# first saving attempt is made there (each mail in a separate file).
  1433. Xsub emergency_save {
  1434. X    return 0 unless (defined $cf'home);    # ~/.mailagent not processed
  1435. X    return 1 if -d "$cf'emergdir" && &dump_mbox("$cf'emergdir/ma$$");
  1436. X    return 1 if &dump_mbox(&mailbox_name);
  1437. X    return 1 if &dump_mbox("$cf'home/mbox.urgent");
  1438. X    return 1 if &dump_mbox("$cf'home/mbox.urg$$");
  1439. X    return 1 if &dump_mbox("/usr/spool/uucppublic/mbox.$cf'user");
  1440. X    return 1 if &dump_mbox("/var/spool/uucppublic/mbox.$cf'user");
  1441. X    return 1 if &dump_mbox("/usr/tmp/mbox.$cf'user");
  1442. X    return 1 if &dump_mbox("/var/tmp/mbox.$cf'user");
  1443. X    return 1 if &dump_mbox("/tmp/mbox.$cf'user");
  1444. X    &add_log("ERROR unable to save mail in any emergency mailbox") if $loglvl;
  1445. X    0;
  1446. X}
  1447. X
  1448. X# Dump $Header{'All'} in emergency mailbox
  1449. Xsub dump_mbox {
  1450. X    local($mbox) = shift(@_);
  1451. X    local($ok) = 0;                        # printing status
  1452. X    local($existed) = 0;                # did the mailbox exist already ?
  1453. X    local($old_size);                    # Size the old mailbox had
  1454. X    local($new_size);                    # Size of the mailbox after saving
  1455. X    local($should);                        # Size it should have if saved properly
  1456. X    $existed = 1 if -f $mbox;
  1457. X    $old_size = $existed ? -s $mbox : 0;
  1458. X    if (open(MBOX, ">>$mbox")) {
  1459. X        (print MBOX $Header{'All'}) && ($ok = 1);
  1460. X        print MBOX "\n";                # allow parsing by other mail tools
  1461. X        close(MBOX) || ($ok = 0);
  1462. X        $new_size = -s $mbox;            # Stat new mbox file, grab its size
  1463. X        $should = $old_size +            # New ideal size is old size plus...
  1464. X            length($Header{'All'}) +    # ... the length of the message saved
  1465. X            1;                            # ... the trailing new-line
  1466. X        if ($should != $new_size) {
  1467. X            &add_log("ERROR $mbox has $new_size bytes (should have $should)")
  1468. X                if $loglvl;
  1469. X            $ok = 0;                    # Saving failed, sorry...
  1470. X        }
  1471. X        if ($ok) {
  1472. X            &add_log("DUMPED in $mbox") if $loglvl > 5;
  1473. X            return 1;
  1474. X        } else {
  1475. X            if ($existed) {
  1476. X                &add_log("WARNING imcomplete mail appended to $mbox")
  1477. X                    if $loglvl > 5;
  1478. X            } else {
  1479. X                unlink "$mbox";            # remove incomplete file
  1480. X            }
  1481. X        }
  1482. X    }
  1483. X    0;
  1484. X}
  1485. X
  1486. X# Resynchronizes the waiting file if necessary (i.e if it exists and %waiting
  1487. X# is not an empty array).
  1488. Xsub resync {
  1489. X    local(@key) = keys %waiting;    # Keys of H table are file names
  1490. X    local($ok) = 1;                    # Assume resync is ok
  1491. X    local($printed) = 0;            # Nothing printed yet
  1492. X    return if $#key < 0 || "$cf'queue" eq '' || ! -f "$cf'queue/$agent_wait";
  1493. X    &add_log("resynchronizing the waiting file") if $loglvl > 11;
  1494. X    if (open(WAITING, ">$cf'queue/$agent_wait~")) {
  1495. X        foreach (@key) {
  1496. X            if ($waiting{$_}) {
  1497. X                print WAITING "$_\n" || ($ok = 0);
  1498. X                $printed = 1;
  1499. X            }
  1500. X        }
  1501. X        close(WAITING) || ($ok = 0);
  1502. X        if ($printed) {
  1503. X            if (!$ok) {
  1504. X                &add_log("ERROR could not update waiting file") if $loglvl;
  1505. X                unlink "$cf'queue/$agent_wait~";
  1506. X            } elsif (rename("$cf'queue/$agent_wait~","$cf'queue/$agent_wait")) {
  1507. X                &add_log("waiting file has been updated") if $loglvl > 18;
  1508. X            } else {
  1509. X                &add_log("ERROR cannot rename waiting file") if $loglvl;
  1510. X            }
  1511. X        } else {
  1512. X            unlink "$cf'queue/$agent_wait";
  1513. X            unlink "$cf'queue/$agent_wait~";
  1514. X            &add_log ("removed waiting file") if $loglvl > 18;
  1515. X        }
  1516. X    } else {
  1517. X        &add_log("ERROR unable to write new waiting file") if $loglvl;
  1518. X    }
  1519. X}
  1520. X
  1521. END_OF_FILE
  1522.   if test 5547 -ne `wc -c <'agent/pl/emergency.pl'`; then
  1523.     echo shar: \"'agent/pl/emergency.pl'\" unpacked with wrong size!
  1524.   fi
  1525.   # end of 'agent/pl/emergency.pl'
  1526. fi
  1527. if test -f 'agent/pl/eval.pl' -a "${1}" != "-c" ; then 
  1528.   echo shar: Will not clobber existing file \"'agent/pl/eval.pl'\"
  1529. else
  1530.   echo shar: Extracting \"'agent/pl/eval.pl'\" \(6419 characters\)
  1531.   sed "s/^X//" >'agent/pl/eval.pl' <<'END_OF_FILE'
  1532. X;# $Id: eval.pl,v 3.0 1993/11/29 13:48:42 ram Exp ram $
  1533. X;#
  1534. X;#  Copyright (c) 1990-1993, Raphael Manfredi
  1535. X;#  
  1536. X;#  You may redistribute only under the terms of the Artistic License,
  1537. X;#  as specified in the README file that comes with the distribution.
  1538. X;#  You may reuse parts of this distribution only within the terms of
  1539. X;#  that same Artistic License; a copy of which may be found at the root
  1540. X;#  of the source tree for mailagent 3.0.
  1541. X;#
  1542. X;# $Log: eval.pl,v $
  1543. X;# Revision 3.0  1993/11/29  13:48:42  ram
  1544. X;# Baseline for mailagent 3.0 netwide release.
  1545. X;#
  1546. X;# 
  1547. X#
  1548. X# The built-in expression interpreter
  1549. X#
  1550. X
  1551. X# Initialize the interpreter
  1552. Xsub init_interpreter {
  1553. X    do set_priorities();    # Fill in %Priority
  1554. X    do set_functions();        # Fill in %Function
  1555. X    $macro_T = "the Epoch";    # Default value for %T macro substitution
  1556. X}
  1557. X
  1558. X# Priorities for operators -- magic numbers :-)
  1559. X# An operator with higher priority will evaluate before another with a lower
  1560. X# one. For instance, given the priorities listed hereinafter, a && b == c
  1561. X# would evaluate as a && (b == c).
  1562. Xsub set_priorities {
  1563. X    $Priority{'&&'} = 4;
  1564. X    $Priority{'||'} = 3;
  1565. X    $Priority{'>='} = 6;
  1566. X    $Priority{'<='} = 6;
  1567. X    $Priority{'<'}  = 6;
  1568. X    $Priority{'>'}  = 6;
  1569. X    $Priority{'=='} = 6;
  1570. X    $Priority{'!='} = 6;
  1571. X    $Priority{'='}  = 6;
  1572. X    $Priority{'/='} = 6;
  1573. X}
  1574. X
  1575. X# Perl functions handling operators
  1576. Xsub set_functions {
  1577. X    $Function{'&&'} = 'f_and';            # Boolean AND
  1578. X    $Function{'||'} = 'f_or';            # Boolean OR
  1579. X    $Function{'>='} = 'f_ge';            # Greater or equal
  1580. X    $Function{'<='} = 'f_le';            # Lesser or equal
  1581. X    $Function{'<'}  = 'f_lt';            # Lesser than
  1582. X    $Function{'>'}  = 'f_gt';            # Greader than
  1583. X    $Function{'=='} = 'f_eq';            # Equality
  1584. X    $Function{'!='} = 'f_ne';            # Difference (not equality)
  1585. X    $Function{'='}  = 'f_match';        # Pattern matching
  1586. X    $Function{'/='} = 'f_nomatch';        # Pattern matching (no match)
  1587. X}
  1588. X
  1589. X# Print error messages -- asssumes $unit and $. correctly set.
  1590. Xsub error {
  1591. X    do add_log("ERROR @_") if $loglvl > 1;
  1592. X}
  1593. X
  1594. X# Add a value on the stack, modified by all the monadic operators.
  1595. X# We use the locals @val and @mono from eval_expr.
  1596. Xsub push_val {
  1597. X    local($val) = shift(@_);
  1598. X    while ($#mono >= 0) {
  1599. X        # Cheat... the only monadic operator is '!'.
  1600. X        pop(@mono);
  1601. X        $val = !$val;
  1602. X    }
  1603. X    push(@val, $val);
  1604. X}
  1605. X
  1606. X# Execute a stacked operation, leave result in stack.
  1607. X# We use the locals @val and @op from eval_expr.
  1608. X# If the value stack holds only one operand, do nothing.
  1609. Xsub execute {
  1610. X    return unless $#val > 0;
  1611. X    local($op) = pop(@op);            # The operator
  1612. X    local($val2) = pop(@val);        # Right value in algebraic notation
  1613. X    local($val1) = pop(@val);        # Left value in algebraic notation
  1614. X    local($func) = $Function{$op};    # Function to be called
  1615. X    do macros_subst(*val1);            # Expand macros
  1616. X    do macros_subst(*val2);
  1617. X    push(@val, eval("do $func($val1, $val2)") ? 1: 0);
  1618. X}
  1619. X
  1620. X# Given an operator, either we add it in the stack @op, because its
  1621. X# priority is lower than the one on top of the stack, or we first execute
  1622. X# the stacked operations until we reach the end of stack or an operand
  1623. X# whose priority is lower than ours.
  1624. X# We use the locals @val and @op from eval_expr.
  1625. Xsub update_stack {
  1626. X    local($op) = shift(@_);        # Operator
  1627. X    if (!$Priority{$op}) {
  1628. X        do error("illegal operator $op");
  1629. X        return;
  1630. X    } else {
  1631. X        if ($#val < 0) {
  1632. X            do error("missing first operand for '$op' (diadic operator)");
  1633. X            return;
  1634. X        }
  1635. X        # Because of a bug in perl 4.0 PL19, I'm using a loop construct
  1636. X        # instead of a while() modifier.
  1637. X        while (
  1638. X            $Priority{$op[$#op]} > $Priority{$op}    # Higher priority op
  1639. X            && $#val > 0                            # At least 2 values
  1640. X        ) {
  1641. X            do execute();    # Execute an higer priority stacked operation
  1642. X        }
  1643. X        push(@op, $op);        # Everything at higher priority has been executed
  1644. X    }
  1645. X}
  1646. X
  1647. X# This is the heart of our little interpreter. Here, we evaluate
  1648. X# a logical expression and return its value.
  1649. Xsub eval_expr {
  1650. X    local(*expr) = shift(@_);    # Expression to parse
  1651. X    local(@val) = ();            # Stack of values
  1652. X    local(@op) = ();            # Stack of diadic operators
  1653. X    local(@mono) =();            # Stack of monadic operators
  1654. X    local($tmp);
  1655. X    $_ = $expr;
  1656. X    while (1) {
  1657. X        s/^\s+//;                # Remove spaces between words
  1658. X        # A perl statement <<command>>
  1659. X        if (s/^<<//) {
  1660. X            if (s/^(.*)>>//) {
  1661. X                do push_val((system
  1662. X                    ('perl','-e', "if ($1) {exit 0;} else {exit 1;}"
  1663. X                    ))? 0 : 1);
  1664. X            } else {
  1665. X                do error("incomplete perl statement");
  1666. X            }
  1667. X        }
  1668. X        # A shell statement <command>
  1669. X        elsif (s/^<//) {
  1670. X            if (s/^(.*)>//) {
  1671. X                do push_val((system
  1672. X                    ("if $1 >/dev/null 2>&1; then exit 0; else exit 1; fi"
  1673. X                    ))? 0 : 1);
  1674. X            } else {
  1675. X                do error("incomplete shell statement");
  1676. X            }
  1677. X        }
  1678. X        # The '(' construct
  1679. X        elsif (s/^\(//) {
  1680. X            do push_val(do eval_expr(*_));
  1681. X            # A final '\' indicates an end of line
  1682. X            do error("missing final parenthesis") if !s/^\\//;
  1683. X        }
  1684. X        # Found a ')' or end of line
  1685. X        elsif (/^\)/ || /^$/) {
  1686. X            s/^\)/\\/;                        # Signals: left parenthesis found
  1687. X            $expr = $_;                        # Remove interpreted stuff
  1688. X            do execute() while $#val > 0;    # Executed stacked operations
  1689. X            while ($#op >= 0) {
  1690. X                $_ = pop(@op);
  1691. X                do error("missing second operand for '$_' (diadic operator)");
  1692. X            }
  1693. X            return $val[0];
  1694. X        }
  1695. X        # Diadic operators
  1696. X        elsif (s/^(\|\||&&|>=|<=|>|<|==|!=|=|\/=)//) {
  1697. X            do update_stack($1);
  1698. X        }
  1699. X        # Unary operator '!'
  1700. X        elsif (s/^!//) {
  1701. X            push(@mono,'!');
  1702. X        }
  1703. X        # Everything else is a value which stands for itself (atom)
  1704. X        elsif (s/^([\w'"%]+)//) {
  1705. X            do push_val($1);
  1706. X        }
  1707. X        # Syntax error
  1708. X        else {
  1709. X            print "Syntax error: remaining is >>>$_<<<\n";
  1710. X            $_ = "";
  1711. X        }
  1712. X    }
  1713. X}
  1714. X
  1715. X# Call eval_expr and check that everything is ok (e.g. the stack must be empty)
  1716. Xsub evaluate {
  1717. X    local($val);                    # Value returned
  1718. X    local(*expr) = shift(@_);        # Expression to be parsed
  1719. X    while ($expr) {
  1720. X        $val = do eval_expr(*expr);        # Expression will be modified
  1721. X        print "extra closing parenthesis ignored.\n" if $expr =~ s/^\\\)*//;
  1722. X        $expr = $val . $expr if $expr ne '';
  1723. X    }
  1724. X    $val;
  1725. X}
  1726. X
  1727. X#
  1728. X# Boolean functions used by the interpreter. They all take two arguments
  1729. X# and return 0 if false and 1 if true.
  1730. X#
  1731. X
  1732. Xsub f_and { $_[0] && $_[1]; }        # Boolean AND
  1733. Xsub f_or { $_[0] || $_[1]; }        # Boolean OR
  1734. Xsub f_ge { $_[0] >= $_[1]; }        # Greater or equal
  1735. Xsub f_le { $_[0] <= $_[1]; }        # Lesser or equal
  1736. Xsub f_lt { $_[0] < $_[1]; }            # Lesser than
  1737. Xsub f_gt { $_[0] > $_[1]; }            # Greater than
  1738. Xsub f_eq { "$_[0]" eq "$_[1]"; }    # Equal
  1739. Xsub f_ne { "$_[0]" ne "$_[1]"; }    # Not equal
  1740. Xsub f_match { $_[0] =~ /$_[1]/; }    # Pattern matches
  1741. Xsub f_nomatch { $_[0] !~ /$_[1]/; }    # Pattern does not match
  1742. X
  1743. END_OF_FILE
  1744.   if test 6419 -ne `wc -c <'agent/pl/eval.pl'`; then
  1745.     echo shar: \"'agent/pl/eval.pl'\" unpacked with wrong size!
  1746.   fi
  1747.   # end of 'agent/pl/eval.pl'
  1748. fi
  1749. echo shar: End of archive 18 \(of 26\).
  1750. cp /dev/null ark18isdone
  1751. MISSING=""
  1752. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ; do
  1753.     if test ! -f ark${I}isdone ; then
  1754.     MISSING="${MISSING} ${I}"
  1755.     fi
  1756. done
  1757. if test "${MISSING}" = "" ; then
  1758.     echo You have unpacked all 26 archives.
  1759.     echo "Now run 'sh PACKNOTES', then read README and type Configure.'"
  1760.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1761. else
  1762.     echo You still must unpack the following archives:
  1763.     echo "        " ${MISSING}
  1764. fi
  1765. exit 0
  1766.  
  1767. exit 0 # Just in case...
  1768.