home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume33 / mailagnt / part05 < prev    next >
Encoding:
Text File  |  1992-11-19  |  55.2 KB  |  2,238 lines

  1. Newsgroups: comp.sources.misc
  2. From: ram@eiffel.com (Raphael Manfredi)
  3. Subject:  v33i097:  mailagent - Rule Based Mail Filtering, Part05/17
  4. Message-ID: <1992Nov20.050349.13560@sparky.imd.sterling.com>
  5. X-Md4-Signature: ff4a793c6a28c9a9b13de77c988d283c
  6. Date: Fri, 20 Nov 1992 05:03:49 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: ram@eiffel.com (Raphael Manfredi)
  10. Posting-number: Volume 33, Issue 97
  11. Archive-name: mailagent/part05
  12. Environment: Perl, Sendmail, UNIX
  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:  Configure.b agent/filter/io.c agent/test/cmd/give.t
  19. # Wrapped by kent@sparky on Wed Nov 18 22:42:21 1992
  20. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  21. echo If this archive is complete, you will see the following message:
  22. echo '          "shar: End of archive 5 (of 17)."'
  23. if test -f 'Configure.b' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'Configure.b'\"
  25. else
  26.   echo shar: Extracting \"'Configure.b'\" \(34312 characters\)
  27.   sed "s/^X//" >'Configure.b' <<'END_OF_FILE'
  28. X    rp="Shall I ignore $ans() from now on?"
  29. X    . myread
  30. X    case "$ans" in
  31. X    y*) d_uname="$undef" d_gethname="$undef"; $echo $n "Okay...$c";;
  32. X    esac;;
  33. Xesac
  34. Xcase "$phostname" in
  35. X'') aphostname='';;
  36. X*) case "$aphostname" in
  37. X    /*) ;;
  38. X    *) set X $phostname
  39. X        shift
  40. X        file=$1
  41. X        shift
  42. X        file=`loc $file $file $pth`
  43. X        aphostname=`echo $file $*`
  44. X        ;;
  45. X    esac
  46. X    ;;
  47. Xesac
  48. Xcase "$d_uname$d_gethname" in
  49. X*define*) ;;
  50. X*)
  51. X    case "$phostname" in
  52. X    '') ;;
  53. X    *)
  54. X        $cat <<EOT
  55. X
  56. XThere is no gethostname() or uname() on this system.  You have two
  57. Xpossibilities at this point:
  58. X
  59. X1)  You can have your host name ($hostname) compiled into $package, which
  60. X    lets $package start up faster, but makes your binaries non-portable, or
  61. X2)  you can have $package use a
  62. X    
  63. X    popen("$aphostname","r")
  64. X
  65. X    which will start slower but be more portable.
  66. X
  67. XIf you want option 2 but with a different command, you can edit config.sh at
  68. Xthe end of this shell script.
  69. X
  70. XEOT
  71. X        case "$d_phostname" in
  72. X        "$define") dflt=n;;
  73. X        "$undef")  dflt=y;;
  74. X        '')
  75. X            case "$d_portable" in
  76. X            "$define") dflt=n ;;
  77. X            *) dflt=y ;;
  78. X            esac;;
  79. X        esac
  80. X        rp="Do you want your host name compiled in?"
  81. X        . myread
  82. X        case "$ans" in
  83. X        n*)d_phostname="$define" ;;
  84. X        *) phostname=''; d_phostname="$undef";;
  85. X        esac;;
  86. X    esac
  87. X    case "$phostname" in
  88. X    '')
  89. X        echo 'No hostname function--hardwiring "'$hostname'".';;
  90. X    esac;;
  91. Xesac
  92. X
  93. X: determine where public executables go
  94. Xcase "$bin" in
  95. X'')
  96. X    dflt=`loc . /bin /usr/local/bin /usr/lbin /usr/local /usr/bin`
  97. X    ;;
  98. X*)  dflt="$bin"
  99. X    ;;
  100. Xesac
  101. Xcont=true
  102. Xwhile $test "$cont" ; do
  103. X    echo " "
  104. X    rp="Where do you want to put the public executables? (~name ok)"
  105. X    . myread
  106. X    bin="$ans"
  107. X    bin=`filexp $bin`
  108. X    if test -d $bin; then
  109. X    cont=''
  110. X    else
  111. X    dflt=n
  112. X    rp="Directory $bin doesn't exist.  Use that name anyway?"
  113. X    . myread
  114. X    dflt=''
  115. X    case "$ans" in
  116. X    y*) cont='';;
  117. X    esac
  118. X    fi
  119. Xdone
  120. X
  121. X: determine optimize, if desired, or use for debug flag also
  122. Xcase "$optimize" in
  123. X' ') dflt="none";;
  124. X'') dflt="-O";;
  125. X*) dflt="$optimize";;
  126. Xesac
  127. X$cat <<EOH
  128. X
  129. XSome C compilers have problems with their optimizers, by default, $package
  130. Xcompiles with the -O flag to use the optimizer.  Alternately, you might want to
  131. Xuse the symbolic debugger, which uses the -g flag (on traditional Unix systems).
  132. XEither flag can be specified here. To use neither flag, specify the word "none".
  133. X
  134. XEOH
  135. Xrp="What optimizer/debugger flag should be used?"
  136. X. myread
  137. Xoptimize="$ans"
  138. Xcase "$optimize" in
  139. X'none') optimize=" ";;
  140. Xesac
  141. X
  142. Xcase "$ccflags" in
  143. X'') case "$cc" in
  144. X    *gcc*) dflt='-fpcc-struct-return';;
  145. X    *) dflt='';;
  146. X    esac
  147. X    ;;
  148. X*) dflt="$ccflags"
  149. X    case "$cc" in
  150. X    *gcc*) case "$dflt" in
  151. X        *-fpcc-struct-return*) ;;
  152. X        *) dflt="$dflt -fpcc-struct-return";;
  153. X        esac;;
  154. X    esac;;
  155. Xesac
  156. X
  157. Xcase "$mips_type" in
  158. X*BSD*) ;;
  159. X'') ;;
  160. X*) inclwanted="$inclwanted $usrinc/bsd";;
  161. Xesac
  162. Xfor thisincl in $inclwanted; do
  163. X    if $test -d $thisincl; then
  164. X        if $test x$thisincl != x$usrinc; then
  165. X            case "$dflt" in
  166. X            *$thisincl*);;
  167. X            *) dflt="$dflt -I$thisincl";;
  168. X            esac
  169. X        fi
  170. X    fi
  171. Xdone
  172. X
  173. Xcase "$optimize" in
  174. X-g*)
  175. X    case "$dflt" in
  176. X    *DEBUG*);;
  177. X    *) dflt="$dflt -DDEBUG";;
  178. X    esac
  179. X    ;;
  180. Xesac
  181. Xif $contains 'LANGUAGE_C' $usrinc/signal.h >/dev/null 2>&1; then
  182. X    case "$dflt" in
  183. X    *LANGUAGE_C*);;
  184. X    *) dflt="$dflt -DLANGUAGE_C";;
  185. X    esac
  186. Xelif $contains 'LANGUAGE_C' $usrinc/sys/signal.h >/dev/null 2>&1; then
  187. X    case "$dflt" in
  188. X    *LANGUAGE_C*);;
  189. X    *) dflt="$dflt -DLANGUAGE_C";;
  190. X    esac
  191. Xfi
  192. Xif $contains 'NO_PROTOTYPE' $usrinc/signal.h >/dev/null 2>&1; then
  193. X    case "$dflt" in
  194. X    *NO_PROTOTYPE*);;
  195. X    *) dflt="$dflt -DNO_PROTOTYPE";;
  196. X    esac
  197. Xelif $contains 'NO_PROTOTYPE' $usrinc/sys/signal.h >/dev/null 2>&1; then
  198. X    case "$dflt" in
  199. X    *NO_PROTOTYPE*);;
  200. X    *) dflt="$dflt -DNO_PROTOTYPE";;
  201. X    esac
  202. Xfi
  203. Xif $contains '_NO_PROTO' $usrinc/signal.h >/dev/null 2>&1; then
  204. X    case "$dflt" in
  205. X    *_NO_PROTO*);;
  206. X    *) dflt="$dflt -D_NO_PROTO";;
  207. X    esac
  208. Xelif $contains '_NO_PROTO' $usrinc/sys/signal.h >/dev/null 2>&1; then
  209. X    case "$dflt" in
  210. X    *_NO_PROTO*);;
  211. X    *) dflt="$dflt -D_NO_PROTO";;
  212. X    esac
  213. Xfi
  214. Xcase "$dflt" in
  215. X'') dflt=none;;
  216. Xesac
  217. X$cat <<EOH
  218. X
  219. XYour C compiler may want other flags.  For this question you should include
  220. X-I/whatever and -DWHATEVER flags and any other flags used by the C compiler,
  221. Xbut you should NOT include libraries or ld flags like -lwhatever.  To use no
  222. Xflags, specify the word "none".
  223. X
  224. XEOH
  225. Xset X $dflt
  226. Xshift
  227. Xdflt=${1+"$@"}
  228. Xrp="Any additional cc flags?"
  229. X. myread
  230. Xcase "$ans" in
  231. Xnone) ans='';
  232. Xesac
  233. Xccflags="$ans"
  234. X
  235. X: the following weeds options from ccflags that are of no interest to cpp
  236. Xcppflags="$ccflags"
  237. Xcase "$cc" in
  238. X*gcc*) cppflags="$cppflags -D__GNUC__";;
  239. Xesac
  240. Xcase "$mips_type" in
  241. X'');;
  242. X*BSD*) cppflags="$cppflags -DSYSTYPE_BSD43";;
  243. Xesac
  244. Xcase "$cppflags" in
  245. X'');;
  246. X*)  set X $cppflags
  247. X    cppflags=''
  248. X    for flag
  249. X    do
  250. X        case $flag in
  251. X        -D*|-I*|-traditional|-ansi|-nostdinc) cppflags="$cppflags $flag";;
  252. X        esac
  253. X    done
  254. X    case "$cppflags" in
  255. X    *-*)  echo "(C preprocessor flags: $cppflags)";;
  256. X    esac
  257. X    ;;
  258. Xesac
  259. X
  260. X: flags used in final linking phase
  261. Xcase "$ldflags" in
  262. X'') if venix; then
  263. X        dflt='-i -z'
  264. X    else
  265. X        dflt='none'
  266. X    fi
  267. X    ;;
  268. X*) dflt="$ldflags";;
  269. Xesac
  270. Xecho " "
  271. Xrp="Any additional ld flags (NOT including libraries)?"
  272. X. myread
  273. Xcase "$ans" in
  274. Xnone) ans='';
  275. Xesac
  276. Xldflags="$ans"
  277. Xrmlist="$rmlist pdp11"
  278. X
  279. X: set up the script used to warn in case of inconsistency
  280. Xcat <<'EOSC' >whoa
  281. Xdflt=y
  282. Xecho ' '
  283. Xecho "*** WHOA THERE!!! ***"
  284. Xecho "    The $hint value for \$$var on this machine was \"$was\"!"
  285. Xrp="    Keep the $hint value?"
  286. X. myread
  287. Xcase "$ans" in
  288. Xy) td=$was; tu=$was;;
  289. Xesac
  290. XEOSC
  291. X
  292. X: define an is-in-libc? function
  293. Xinlibc='echo " "; td=$define; tu=$undef;
  294. Xvar=$2; eval "was=\$$2";
  295. Xif $contains "^$1\$" libc.list >/dev/null 2>&1;
  296. Xthen echo "$1() found.";
  297. X    eval "case \"\$$var\" in $undef) . whoa; esac"; eval "$var=\$td";
  298. Xelse echo "$1() not found.";
  299. X    eval "case \"\$$var\" in $define) . whoa; esac"; eval "$var=\$tu"; fi'
  300. X
  301. X: see if bcopy exists
  302. Xcase "$d_bcopy" in
  303. X$define) d_bcopy="$undef";;
  304. X$undef) d_bcopy="$define";;
  305. Xesac
  306. Xset bcopy d_bcopy
  307. Xeval $inlibc
  308. Xcase "$d_bcopy" in
  309. X$define) d_bcopy="$undef";;
  310. X*) d_bcopy="$define";;
  311. Xesac
  312. X
  313. X: function used to set $1 to $val
  314. Xsetvar='var=$1; eval "was=\$$1"; td=$define; tu=$undef;
  315. Xcase "$val$was" in
  316. X$define$undef) . whoa; eval "$var=\$td";;
  317. X$undef$define) . whoa; eval "$var=\$tu";;
  318. X*) eval "$var=$val";;
  319. Xesac'
  320. X
  321. X: see which of string.h or strings.h is needed
  322. Xecho " "
  323. Xstrings=`loc string.h "" $usrinc $inclwanted`
  324. Xval="$undef"
  325. Xif $test -r "$strings"; then
  326. X    echo "Using <string.h> instead of <strings.h>."
  327. X    if bsd; then
  328. X        echo "(Actually, this looks more like it were an USG system)"
  329. X    fi
  330. X    val="$define"
  331. Xelse
  332. X    strings=`loc strings.h "" $usrinc $inclwanted`
  333. X    if $test -r "$strings"; then
  334. X        echo "Using <strings.h> instead of <string.h>."
  335. X        if usg; then
  336. X            echo "(Actually, this looks more like it were a BSD system)"
  337. X        fi
  338. X    else
  339. X        echo "No string header found--You'll surely have problems."
  340. X    fi
  341. Xfi
  342. Xset i_string
  343. Xeval $setvar
  344. X
  345. X: index or strchr
  346. Xecho " "
  347. Xcase "$d_index" in
  348. Xn) dflt=n;;
  349. X*) dflt=y;;
  350. Xesac
  351. Xif $contains '^index$' libc.list >/dev/null 2>&1 ; then
  352. X    if $contains '^strchr$' libc.list >/dev/null 2>&1 ; then
  353. X        if $contains strchr "$strings" >/dev/null 2>&1 ; then
  354. X            if $contains index "$strings" >/dev/null 2>&1 ; then
  355. X                echo "Your system has both index() and strchr()."
  356. X                rp="Shall I use index() rather than strchr()?"
  357. X                . myread
  358. X                case "$ans" in
  359. X                    n*) val="$define" ;;
  360. X                    *)  val="$undef" ;;
  361. X                esac
  362. X            else
  363. X                val="$define"
  364. X                echo "strchr() found."
  365. X            fi
  366. X        else
  367. X            val="$undef"
  368. X            echo "index() found."
  369. X        fi
  370. X    else
  371. X        val="$undef"
  372. X        echo "index() found."
  373. X    fi
  374. Xelse
  375. X    if $contains '^strchr$' libc.list >/dev/null 2>&1 ; then
  376. X        val="$define"
  377. X        echo "strchr() found."
  378. X    else
  379. X        echo "No index() or strchr() found!"
  380. X        val="$undef"
  381. X    fi
  382. Xfi
  383. Xset d_index
  384. Xeval $setvar
  385. X
  386. X: see if rename exists
  387. Xset rename d_rename
  388. Xeval $inlibc
  389. X
  390. X: see if strerror and/or sys_errlist[] exist
  391. Xecho " "
  392. Xif $contains '^strerror$' libc.list >/dev/null 2>&1; then
  393. X    echo 'strerror() found.'
  394. X    d_strerror="$define"
  395. X    d_strerrm="$undef"
  396. X    if $contains 'sys_errlist' libc.tmp >/dev/null 2>&1; then    
  397. X        echo "You also have sys_errlist[]."
  398. X        d_syserrlst="$define"
  399. X    else
  400. X        echo "But you don't have sys_errlist[]."
  401. X        d_syserrlst="$undef"
  402. X    fi
  403. Xelif $contains '#[     ]*define.*strerror' $usrinc/string*.h >/dev/null 2>&1; then
  404. X    echo 'strerror() found in string header.'
  405. X    d_strerror="$define"
  406. X    d_strerrm="$undef"
  407. X    if $contains 'sys_errlist' libc.tmp >/dev/null 2>&1; then    
  408. X        echo "You also have sys_errlist[]."
  409. X        d_syserrlst="$define"
  410. X    else
  411. X        echo "But you don't have sys_errlist[]."
  412. X        d_syserrlst="$undef"
  413. X    fi
  414. Xelif $contains 'sys_errlist' libc.tmp >/dev/null 2>&1; then
  415. X    echo "strerror() not found, but you have sys_errlist[] so we'll use that."
  416. X    d_strerror="$undef"
  417. X    d_syserrlst="$define"
  418. X    d_strerrm="$define"
  419. Xelse
  420. X    echo 'strerror() and sys_errlist[] not found.'
  421. X    d_strerror="$undef"
  422. X    d_syserrlst="$undef"
  423. X    d_strerrm="$undef"
  424. Xfi
  425. Xif $contains 'sys_errnolist' libc.tmp >/dev/null 2>&1; then
  426. X    echo " "
  427. X    echo "Symbolic error codes for errno are kept in sys_errnolist[]."
  428. X    d_sysernlst="$define"
  429. Xelse
  430. X    d_sysernlst="$undef"
  431. Xfi
  432. X
  433. X: see if union wait is available
  434. Xecho " "
  435. Xif $contains 'int.*w_status;' $usrinc/sys/wait.h >/dev/null 2>&1 ; then
  436. X    echo "Looks like we have to use 'union wait' pointer for wait()."
  437. X    val="$define"
  438. Xelse
  439. X    echo "Your wait() should be happy with a plain 'int' pointer."
  440. X    val="$undef"
  441. Xfi
  442. Xset d_uwait
  443. Xeval $setvar
  444. X
  445. X: see if there is a vfork
  446. Xecho " "
  447. Xif $contains '^vfork$' libc.list >/dev/null 2>&1 ; then
  448. X    echo "vfork() found."
  449. X    val="$undef"
  450. Xelse
  451. X    echo "No vfork() found--will use fork() instead."
  452. X    val="$define"
  453. Xfi
  454. Xset d_vfork
  455. Xeval $setvar
  456. X
  457. X: now get the host name to advertise as our mailing address
  458. Xcase "$hiddennet" in
  459. X'') dflt=n;;
  460. X*) dflt=y;;
  461. Xesac
  462. X$cat <<EOM
  463. XSome sites are on "hidden" networks, in the sense that the network appears
  464. Xto the outside world as a single machine.  The advertised name of any host
  465. Xon this hidden network is the name of one machine on the local network which
  466. Xknows how to forward mail to any other host on the hidden network.
  467. X
  468. XDo you wish to advertise a different hostname to the world than the one your
  469. Xown host ($hostname$mydomain) has?
  470. X
  471. XEOM
  472. Xrp='Use "hidden" network?'
  473. X. myread
  474. Xcase "$ans" in
  475. Xn*) d_hidnet="$undef" hiddennet='';;
  476. X*)
  477. X    d_hidnet="$define"
  478. X    echo " "
  479. X    case "$hiddennet" in
  480. X    '') dflt=`echo $mydomain | $sed -e 's/^\.//'`;;
  481. X    *) dflt="$hiddennet";;
  482. X    esac
  483. X    rp="What hostname do you wish to advertise?"
  484. X    . myread
  485. X    hiddennet="$ans"
  486. X    ;;
  487. Xesac
  488. X
  489. X: see if this is an fcntl system
  490. Xecho " "
  491. Xif $test -r $usrinc/fcntl.h ; then
  492. X    val="$define"
  493. X    echo "<fcntl.h> found."
  494. Xelse
  495. X    val="$undef"
  496. X    echo "No <fcntl.h> found, but that's ok."
  497. Xfi
  498. Xset i_fcntl
  499. Xeval $setvar
  500. X
  501. X: define an alternate in-header-list? function
  502. Xinhdr='echo " "; td=$define; tu=$undef; yyy=$@;
  503. Xcont=true; xxf="echo \"<\$1> found.\"";
  504. Xcase $# in 2) xxnf="echo \"No <\$1> found.\"";;
  505. X*) xxnf="echo \"No <\$1> found, ...\"";;
  506. Xesac;
  507. Xcase $# in 4) instead=instead;; *) instead="at last";; esac;
  508. Xwhile $test "$cont";
  509. Xdo xxx=`loc $1 x $usrinc /usr/local/include $inclwanted`;
  510. X    var=$2; eval "was=\$$2";
  511. X    if $test -f $xxx;
  512. X    then eval $xxf;
  513. X        eval "case \"\$$var\" in $undef) . whoa; esac"; eval "$var=\$td";
  514. X        cont="";
  515. X    else eval $xxnf;
  516. X        eval "case \"\$$var\" in $define) . whoa; esac"; eval "$var=\$tu"; fi;
  517. X    set $yyy; shift; shift; yyy=$@;
  518. X    case $# in 0) cont="";;
  519. X    2) xxf="echo \"but I found <\$1> $instead.\"";
  520. X        xxnf="echo \"and I did not find <\$1> either.\"";;
  521. X    *) xxf="echo \"but I found <\$1\> instead.\"";
  522. X        xxnf="echo \"there is no <\$1>, ...\"";;
  523. X    esac;
  524. Xdone;
  525. Xwhile $test "$yyy";
  526. Xdo set $yyy; var=$2; eval "was=\$$2";
  527. X    eval "case \"\$$var\" in $define) . whoa; esac"; eval "$var=\$tu";
  528. X    set $yyy; shift; shift; yyy=$@;
  529. Xdone'
  530. X
  531. X: see if this is a sys/file.h system
  532. Xset sys/file.h i_sysfile
  533. Xeval $inhdr
  534. X
  535. X: see if we should include time.h, sys/time.h, or both
  536. Xecho " "
  537. Xecho "Testing to see if we should include <time.h>, <sys/time.h> or both."
  538. X$echo $n "I'm now running the test program...$c"
  539. X$cat >try.c <<'EOCP'
  540. X#include <sys/types.h>
  541. X#ifdef I_TIME
  542. X#include <time.h>
  543. X#endif
  544. X#ifdef I_SYSTIME
  545. X#ifdef SYSTIMEKERNEL
  546. X#define KERNEL
  547. X#endif
  548. X#include <sys/time.h>
  549. X#endif
  550. X#ifdef I_SYSSELECT
  551. X#include <sys/select.h>
  552. X#endif
  553. Xmain()
  554. X{
  555. X    struct tm foo;
  556. X#ifdef S_TIMEVAL
  557. X    struct timeval bar;
  558. X#endif
  559. X#ifdef S_TIMEZONE
  560. X    struct timezone tzp;
  561. X#endif
  562. X    if (foo.tm_sec == foo.tm_sec)
  563. X    exit(0);
  564. X#ifdef S_TIMEVAL
  565. X    if (bar.tv_sec == bar.tv_sec)
  566. X    exit(0);
  567. X#endif
  568. X    exit(1);
  569. X}
  570. XEOCP
  571. Xflags=''
  572. Xfor s_timezone in '-DS_TIMEZONE' ''; do
  573. Xsysselect=''
  574. Xfor s_timeval in '-DS_TIMEVAL' ''; do
  575. Xfor i_systimek in '' '-DSYSTIMEKERNEL'; do
  576. Xfor i_time in '' '-DI_TIME'; do
  577. Xfor i_systime in '-DI_SYSTIME' ''; do
  578. X    case "$flags" in
  579. X    '') $echo $n ".$c"
  580. X        if $cc $ccflags \
  581. X        $i_time $i_systime $i_systimek $sysselect $s_timeval $s_timezone \
  582. X        try.c -o try >/dev/null 2>&1 ; then
  583. X            set X $i_time $i_systime $i_systimek $sysselect $s_timeval
  584. X            shift
  585. X            flags="$*"
  586. X            echo " "
  587. X            $echo $n "Succeeded with $flags$c"
  588. X        fi
  589. X        ;;
  590. X    esac
  591. Xdone
  592. Xdone
  593. Xdone
  594. Xdone
  595. Xdone
  596. Xtimeincl=''
  597. Xecho " "
  598. Xcase "$flags" in
  599. X*SYSTIMEKERNEL*) i_systimek="$define"
  600. X    timeincl="$usrinc/sys/time.h"
  601. X    echo "We'll include <sys/time.h> with KERNEL defined.";;
  602. X*) i_systimek="$undef";;
  603. Xesac
  604. Xcase "$flags" in
  605. X*I_TIME*) i_time="$define"
  606. X    timeincl="$usrinc/time.h $timeincl"
  607. X    echo "We'll include <time.h>.";;
  608. X*) i_time="$undef";;
  609. Xesac
  610. Xcase "$flags" in
  611. X*I_SYSTIME*) i_systime="$define"
  612. X    timeincl="$usrinc/sys/time.h $timeincl"
  613. X    echo "We'll include <sys/time.h>.";;
  614. X*) i_systime="$undef";;
  615. Xesac
  616. X$rm -f try.c try
  617. X
  618. X: see if this is a syswait system
  619. Xset sys/wait.h i_syswait
  620. Xeval $inhdr
  621. X
  622. X: check for length of integer
  623. Xecho " "
  624. Xcase "$intsize" in
  625. X'')
  626. X    echo "Checking to see how big your integers are..."
  627. X    $cat >try.c <<'EOCP'
  628. X#include <stdio.h>
  629. Xmain()
  630. X{
  631. X    printf("%d\n", sizeof(int));
  632. X}
  633. XEOCP
  634. X    if $cc $ccflags try.c -o try >/dev/null 2>&1 ; then
  635. X        dflt=`./try`
  636. X    else
  637. X        dflt='4'
  638. X        echo "(I can't seem to compile the test program.  Guessing...)"
  639. X    fi
  640. X    ;;
  641. X*)
  642. X    dflt="$intsize"
  643. X    ;;
  644. Xesac
  645. Xrp="What is the size of an integer (in bytes)?"
  646. X. myread
  647. Xintsize="$ans"
  648. X$rm -f try.c try
  649. X
  650. X: determine where mail is spooled
  651. Xcase "$maildir" in
  652. X'') dflt=`loc . /usr/spool/mail /usr/spool/mail /usr/mail`;;
  653. X*) dflt="$maildir";;
  654. Xesac
  655. Xcont=true
  656. Xwhile $test "$cont" ; do
  657. X    echo " "
  658. X    rp="Where is yet-to-be-read mail spooled?"
  659. X    . myread
  660. X    maildir=`filexp "$ans"`
  661. X    if $test -d "$maildir"; then
  662. X        cont=''
  663. X    else
  664. X        dflt=n
  665. X        rp="Directory $maildir doesn't exist.  Use that name anyway?"
  666. X        . myread
  667. X        dflt=''
  668. X        case "$ans" in
  669. X        y*) cont='';;
  670. X        esac
  671. X    fi
  672. Xdone
  673. X
  674. X: determine where mail is spooled
  675. Xcase "$mailfile" in
  676. X'')
  677. X    dflt="$maildir"
  678. X    case "$dflt" in
  679. X    '') dflt='%~/mailbox';;
  680. X    *) dflt="$dflt/%L";;
  681. X    esac
  682. X    ;;
  683. X*)  dflt="$mailfile"
  684. X    ;;
  685. Xesac
  686. Xcat <<'EOM'
  687. X
  688. XIn the following question, you may use %~ to represent the user's home
  689. Xdirectory, and %L to represent a users name.
  690. X
  691. XEOM
  692. Xrp="In which file is yet-to-be-read mail spooled?"
  693. X. myread
  694. Xmailfile=`filexp "$ans"`
  695. X
  696. X: determine where manual pages go
  697. X$cat <<EOM
  698. X
  699. X$package has manual pages available in source form.
  700. XEOM
  701. Xcase "$nroff" in
  702. Xnroff)
  703. X    echo "However, you don't have nroff, so they're probably useless to you."
  704. X    case "$mansrc" in
  705. X    '') mansrc="none";;
  706. X    esac;;
  707. Xesac
  708. Xecho "If you don't want the manual sources installed, answer 'none'."
  709. Xcase "$mansrc" in
  710. X'')
  711. X    dflt="$sysman"
  712. X    ;;
  713. X*)  dflt="$mansrc"
  714. X    ;;
  715. Xesac
  716. Xcont=true
  717. Xwhile $test "$cont" ; do
  718. X    echo " "
  719. X    rp="Where do the manual pages (source) go? (~name ok)"
  720. X    . myread
  721. X    case "$ans" in
  722. X    'none') mansrc=''
  723. X        cont='';;
  724. X    *)
  725. X        mansrc=`filexp "$ans"`
  726. X        if test -d "$mansrc"; then
  727. X            cont=''
  728. X        else
  729. X            dflt=n
  730. X            rp="Directory $mansrc doesn't exist.  Use that name anyway?"
  731. X            . myread
  732. X            dflt=''
  733. X            case "$ans" in
  734. X            y*) cont='';;
  735. X            esac
  736. X        fi;;
  737. X    esac
  738. Xdone
  739. Xcase "$mansrc" in
  740. X'') manext='0';;
  741. X*l) manext=l;;
  742. X*n) manext=n;;
  743. X*o) manext=l;;
  744. X*p) manext=n;;
  745. X*C) manext=C;;
  746. X*L) manext=L;;
  747. X*) manext=1;;
  748. Xesac
  749. X
  750. X: find out how to generate dependencies
  751. Xecho " "
  752. Xecho "Checking how to generate makefile dependencies on your machine..."
  753. Xtoplev=`cd ..;pwd`
  754. X$cat >dep.c <<'EOCP'
  755. X#include "dep.h"
  756. XEOCP
  757. X$cat >dep.h <<'EOCP'
  758. X
  759. XEOCP
  760. Xtakeflags='flags=""
  761. Xcase "$@" in
  762. X*--*)
  763. X    for arg
  764. X    do
  765. X        shift
  766. X        case "$arg" in
  767. X        --) break;;
  768. X        *) flags="$flags $arg";;
  769. X        esac
  770. X    done;;
  771. Xesac'
  772. Xcase "$mkdep" in
  773. X'')
  774. X    ;;
  775. X*)
  776. X    if test -x "$mkdep" &&
  777. X        $mkdep dep.c >dep.out 2>/dev/null &&
  778. X        $contains 'dep\.o:.*dep\.h' dep.out >/dev/null 2>&1
  779. X    then
  780. X        echo "$mkdep works."
  781. X    else
  782. X        mkdep=
  783. X    fi
  784. Xesac
  785. X
  786. Xcase "$mkdep" in
  787. X'')
  788. X    $spitshell > ../mkdep <<EOM
  789. X$startsh
  790. X$takeflags
  791. Xfor srcfile
  792. Xdo
  793. X    $cpp -M -I. $cppflags \$flags \$srcfile 2>/dev/null
  794. Xdone
  795. XEOM
  796. X    mkdep=$toplev/mkdep
  797. X    chmod +x $mkdep
  798. X    $eunicefix $mkdep
  799. X    if $mkdep dep.c >dep.out 2>/dev/null &&
  800. X        $contains 'dep\.o:.*dep\.h' dep.out >/dev/null 2>&1
  801. X    then
  802. X        echo "Looks like we can use $cpp -M."
  803. X    else
  804. X        mkdep=
  805. X    fi
  806. X    ;;
  807. Xesac
  808. X
  809. Xcase "$mkdep" in
  810. X'')
  811. X    $spitshell >../mkdep <<EOS
  812. X$startsh
  813. X$takeflags
  814. Xfor srcfile
  815. Xdo
  816. X    case "\$srcfile" in
  817. X    *.c) c='.c';;
  818. X    *.y) c='.y';;
  819. X    *.l) c='.l';;
  820. X    esac
  821. X    filebase=\`basename \$srcfile \$c\`
  822. X    <\$srcfile $cpp $cppminus $cppflags -I. \$flags 2>/dev/null | \\
  823. X    $sed -e '/^# *[0-9]/!d' \\
  824. X        -e 's/^.*"\(.*\)".*\$/'\$filebase'.o: \1/' \\
  825. X        -e 's|: \./|: |' \\
  826. X        -e 's|: *$|: '\$srcfile'|' | \\
  827. X    $grep -v '^#' | $sort | $uniq
  828. Xdone
  829. XEOS
  830. X    mkdep=$toplev/mkdep
  831. X    chmod +x $mkdep
  832. X    $eunicefix $mkdep
  833. X    if $mkdep dep.c >dep.out 2>/dev/null &&
  834. X        $contains 'dep\.o:.*dep\.h' dep.out >/dev/null 2>&1
  835. X    then
  836. X        echo "A shell script using $cpp does the trick."
  837. X    else
  838. X        echo "$cpp doesn't seem to be any use at all."
  839. X        $spitshell >../mkdep <<EOS
  840. X$startsh
  841. X$takeflags
  842. Xfor srcfile
  843. Xdo
  844. X    case "\$srcfile" in
  845. X    *.c) c='.c';;
  846. X    *.y) c='.y';;
  847. X    *.l) c='.l';;
  848. X    esac
  849. X    filebase=\`basename \$srcfile \$c\`
  850. X    echo \$filebase.o: \$srcfile
  851. X    $grep '^#[  ]*include' \$srcfile /dev/null |
  852. X    $sed -e 's/#[   ]*include[  ]*//' \\
  853. X        -e 's,<\(.*\)>,"$usrinc/\1",' \\
  854. X        -e 's/:[^"]*"\([^"]*\)".*/: \1/' \\
  855. X        -e 's/\.c:/\.o:/'
  856. Xdone
  857. XEOS
  858. X        mkdep=$toplev/mkdep
  859. X        chmod +x $mkdep
  860. X        $eunicefix $mkdep
  861. X        if $mkdep dep.c >dep.out 2>/dev/null &&
  862. X            $contains 'dep\.o:.*dep\.h' dep.out >/dev/null 2>&1
  863. X        then
  864. X            cat << EOM
  865. X
  866. XI can use a script with grep instead, but it will make some incorrect
  867. Xdependencies, since it doesn't understand about conditional compilation.
  868. XMoreover, some dependencies may be missing, because scanning won't be
  869. Xa recursive process.
  870. XIf you have a program which generates makefile dependencies, you may want
  871. Xto use it.  If not, you can use the script and edit the Makefile by hand
  872. Xif you need to.
  873. XEOM
  874. X        else
  875. X            mkdep=
  876. X            cat << EOM
  877. X
  878. XI can't seem to generate makefile dependencies at all!  Perhaps you have a
  879. Xprogram that does?  If you don't, you might look at the mkdep script to
  880. Xsee if you can create one which works.
  881. XEOM
  882. X        fi
  883. X    fi
  884. Xesac
  885. Xcont=true
  886. Xdflt="$mkdep"
  887. Xwhile $test "$cont" ; do
  888. X    echo " "
  889. Xrp="Name of program to make makefile dependencies?"
  890. X. myread
  891. Xmkdep="$ans"
  892. Xmkdep=`filexp $mkdep`
  893. Xif test -f "$mkdep"; then
  894. X    cont=''
  895. Xelse
  896. X    dflt=n
  897. X    rp="$mkdep doesn't exist.  Use that name anyway?"
  898. X    . myread
  899. X    dflt=''
  900. X    case "$ans" in
  901. X    y*) cont='';;
  902. X    esac
  903. Xfi
  904. Xdone
  905. X$rm -f dep.c dep.h dep.o dep.out
  906. X
  907. X: get organization name
  908. Xlongshots='/usr/src/new /usr/src/local /usr/local/src'
  909. Xcase "$orgname" in
  910. X'') if xxx=`loc news/src/defs.h x $longshots`; then
  911. X        dflt=`$sed -n 's/^.*MYORG[     ]*"\(.*\)".*$/\1/p' $xxx`
  912. X    else
  913. X        dflt=''
  914. X    fi
  915. X    ;;
  916. X*)  dflt="$orgname";;
  917. Xesac
  918. X$cat << 'EOH'
  919. XPlease type the name of your organization as you want it to appear on the
  920. XOrganization line of outgoing articles.  (It's nice if this also specifies
  921. Xyour location.  Your city name is probably sufficient if well known.)
  922. XFor example:
  923. X
  924. X    University of Southern North Dakota, Hoople
  925. X
  926. XYou may also put the name of a file, as long as it begins with a slash.
  927. XFor example:
  928. X
  929. X    /etc/organization
  930. X
  931. XEOH
  932. Xorgname=""
  933. Xwhile test "X$orgname" = "X"; do
  934. X    rp="Organization:"
  935. X    . myread
  936. X    orgname="$ans"
  937. Xdone
  938. X
  939. X: determine perl absolute location
  940. Xcase "$perlpath" in
  941. X'')
  942. X    if test -f /usr/bin/perl; then
  943. X        dflt=/usr/bin/perl
  944. X    else
  945. X        case "$_perl" in
  946. X        */*) dflt="$_perl";;
  947. X        *) dflt=/usr/bin/perl;;
  948. X        esac
  949. X    fi
  950. X    ;;
  951. X*)  dflt="$perlpath"
  952. X    ;;
  953. Xesac
  954. Xcont=true
  955. Xwhile $test "$cont" ; do
  956. X    echo " "
  957. X    rp="Where is perl located on your system?"
  958. X    . myread
  959. X    perlpath="$ans"
  960. X    case "$ans" in
  961. X    /*) if test -f $ans; then
  962. X        cont=''
  963. X    else
  964. X        dflt=n
  965. X        rp="File $ans doesn't exist.  Use that name anyway?"
  966. X        . myread
  967. X        dflt=''
  968. X        case "$ans" in
  969. X        y*) cont='';;
  970. X        esac
  971. X    fi
  972. X    ;;
  973. X    *) echo "Please use an absolute path name.";;
  974. X    esac
  975. Xdone
  976. X
  977. X: see what type pids are declared as in the kernel
  978. Xcase "$pidtype" in
  979. X'')
  980. X    if $contains 'pid_t;' $usrinc/sys/types.h >/dev/null 2>&1 ; then
  981. X        dflt='pid_t';
  982. X    else
  983. X        dflt="int"
  984. X    fi
  985. X    ;;
  986. X*)  dflt="$pidtype";;
  987. Xesac
  988. Xecho " "
  989. Xrp="What type are process ids on this system declared as?"
  990. X. myread
  991. Xpidtype="$ans"
  992. X
  993. X: determine where private executables go
  994. Xcase "$privlib" in
  995. X'')
  996. X    dflt=/usr/lib/$package
  997. X    test -d /usr/local/lib && dflt=/usr/local/lib/$package
  998. X    ;;
  999. X*)  dflt="$privlib"
  1000. X    ;;
  1001. Xesac
  1002. X$cat <<EOM
  1003. X
  1004. XThe $package package has some auxiliary files that should be put in a library
  1005. Xthat is accessible by everyone.  Where do you want to put these "private" but
  1006. Xaccessible files?
  1007. X
  1008. XEOM
  1009. Xrp="Private library path? (~name ok)"
  1010. X. myread
  1011. Xprivlib="$ans"
  1012. Xcase "$d_portable" in
  1013. X"$undef")
  1014. X    privlib=`filexp $privlib`
  1015. X    ;;
  1016. Xesac
  1017. X
  1018. X: see how we invoke the C preprocessor
  1019. Xecho " "
  1020. Xecho "Now, how can we feed standard input to your C preprocessor..."
  1021. Xcat <<'EOT' >testcpp.c
  1022. X#define ABC abc
  1023. X#define XYZ xyz
  1024. XABC.XYZ
  1025. XEOT
  1026. Xcd ..
  1027. Xecho 'cat >.$$.c; '"$cc"' -E ${1+"$@"} .$$.c; rm .$$.c' >cppstdin
  1028. Xchmod 755 cppstdin
  1029. Xwrapper=`pwd`/cppstdin
  1030. Xcd UU
  1031. Xif test "X$cppstdin" != "X" && \
  1032. X    $cppstdin $cppminus <testcpp.c >testcpp.out 2>&1 && \
  1033. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1034. X    echo "You used to use $cppstdin $cppminus so we'll use that again."
  1035. Xelif test "$cc" = gcc && \
  1036. X    (echo "Using gcc, eh?  We'll try to force gcc -E using a wrapper..."; \
  1037. X    $wrapper <testcpp.c >testcpp.out 2>&1; \
  1038. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1) ; then
  1039. X    echo "Yup, we can."
  1040. X    cppstdin="$wrapper"
  1041. X    cppminus='';
  1042. Xelif echo 'Maybe "'"$cc"' -E" will work...'; \
  1043. X    $cc -E <testcpp.c >testcpp.out 2>&1; \
  1044. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1045. X    echo "Yup, it does."
  1046. X    cppstdin="$cc -E"
  1047. X    cppminus='';
  1048. Xelif echo 'Nope...maybe "'"$cc"' -E -" will work...'; \
  1049. X    $cc -E - <testcpp.c >testcpp.out 2>&1; \
  1050. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1051. X    echo "Yup, it does."
  1052. X    cppstdin="$cc -E"
  1053. X    cppminus='-';
  1054. Xelif echo 'Uh-uh.  Time to get fancy.  Trying a wrapper...'; \
  1055. X    $wrapper <testcpp.c >testcpp.out 2>&1; \
  1056. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1057. X    cppstdin="$wrapper"
  1058. X    cppminus=''
  1059. X    echo "Eureka!"
  1060. Xelif echo 'No such luck, maybe "'$cpp'" will work...'; \
  1061. X    $cpp <testcpp.c >testcpp.out 2>&1; \
  1062. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1063. X    echo "It works!"
  1064. X    cppstdin="$cpp"
  1065. X    cppminus='';
  1066. Xelif echo 'Nixed again...maybe "'$cpp' -" will work...'; \
  1067. X    $cpp - <testcpp.c >testcpp.out 2>&1; \
  1068. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1069. X    echo "Hooray, it works!  I was beginning to wonder."
  1070. X    cppstdin="$cpp"
  1071. X    cppminus='-';
  1072. Xelif echo 'Nope...maybe "'"$cc"' -P" will work...'; \
  1073. X    $cc -P <testcpp.c >testcpp.out 2>&1; \
  1074. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1075. X    echo "Yipee, that works!"
  1076. X    cppstdin="$cc -P"
  1077. X    cppminus='';
  1078. Xelif echo 'Nope...maybe "'"$cc"' -P -" will work...'; \
  1079. X    $cc -P - <testcpp.c >testcpp.out 2>&1; \
  1080. X    $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1081. X    echo "At long last!"
  1082. X    cppstdin="$cc -P"
  1083. X    cppminus='-';
  1084. Xelse
  1085. X    dflt=''
  1086. X    rp="No dice.  I can't find a C preprocessor.  Name one:"
  1087. X    . myread
  1088. X    cppstdin="$ans"
  1089. X    $cppstdin <testcpp.c >testcpp.out 2>&1
  1090. X    if $contains 'abc.*xyz' testcpp.out >/dev/null 2>&1 ; then
  1091. X        echo "OK, that will do."
  1092. X    else
  1093. X        echo "Sorry, I can't get that to work.  Go find one and rerun Configure."
  1094. X        exit 1
  1095. X    fi
  1096. Xfi
  1097. X$rm -f testcpp.c testcpp.out
  1098. X
  1099. X: get C preprocessor symbols handy
  1100. Xecho " "
  1101. Xecho $attrlist | $tr '[ - ]' '[\012-\012]' >Cppsym.know
  1102. X$cat <<EOSS >Cppsym
  1103. X$startsh
  1104. Xcase "\$1" in
  1105. X-l) list=true
  1106. X    shift
  1107. X    ;;
  1108. Xesac
  1109. Xunknown=''
  1110. Xcase "\$list\$#" in
  1111. X1|2)
  1112. X    for sym do
  1113. X    if $contains "^\$1$" Cppsym.true >/dev/null 2>&1; then
  1114. X        exit 0
  1115. X    elif $contains "^\$1$" Cppsym.know >/dev/null 2>&1; then
  1116. X        :
  1117. X    else
  1118. X        unknown="\$unknown \$sym"
  1119. X    fi
  1120. X    done
  1121. X    set X \$unknown
  1122. X    shift
  1123. X    ;;
  1124. Xesac
  1125. Xcase \$# in
  1126. X0) exit 1;;
  1127. Xesac
  1128. Xecho \$* | $tr '[ - ]' '[\012-\012]' | $sed -e 's/\(.*\)/\\
  1129. X#ifdef \1\\
  1130. Xexit 0; _ _ _ _\1\\     \1\\
  1131. X#endif\\
  1132. X/' >Cppsym\$\$
  1133. Xecho exit 1 >>Cppsym\$\$
  1134. X$cppstdin $cppminus <Cppsym\$\$ >Cppsym2\$\$
  1135. Xcase "\$list" in
  1136. Xtrue) $awk 'NF > 5 {print substr(\$6,2,100)}' <Cppsym2\$\$ ;;
  1137. X*)
  1138. X    sh Cppsym2\$\$
  1139. X    status=\$?
  1140. X    ;;
  1141. Xesac
  1142. X$rm -f Cppsym\$\$ Cppsym2\$\$
  1143. Xexit \$status
  1144. XEOSS
  1145. Xchmod +x Cppsym
  1146. X$eunicefix Cppsym
  1147. Xecho "Your C preprocessor defines the following symbols:"
  1148. XCppsym -l $attrlist >Cppsym.true
  1149. X$cat Cppsym.true
  1150. Xrmlist="$rmlist Cppsym Cppsym.know Cppsym.true"
  1151. X
  1152. X: see how many register declarations we want to use
  1153. Xcase "$registers" in
  1154. X'')
  1155. X    if Cppsym vax; then
  1156. X        dflt=6
  1157. X    elif Cppsym sun mc68000 mips; then
  1158. X        dflt=10
  1159. X    elif Cppsym pyr; then
  1160. X        dflt=14
  1161. X    elif Cppsym ns32000 ns16000; then
  1162. X        dflt=5
  1163. X    elif Cppsym $smallmach; then
  1164. X        dflt=3
  1165. X    else
  1166. X        : if you have any other numbers for me, please send them in
  1167. X        dflt=6
  1168. X    fi;;
  1169. X*) dflt=$registers ;;
  1170. Xesac
  1171. Xcat <<EOM
  1172. XDifferent C compilers on different machines pay attention to different numbers
  1173. Xof register declarations.  About how many register declarations in each routine
  1174. Xdoes your C compiler pay attention to?  (OK to guess)
  1175. X
  1176. XEOM
  1177. Xrp="Maximum register declarations?"
  1178. X. myread
  1179. Xregisters=$ans
  1180. Xreg1=''
  1181. X$awk "BEGIN { for (i=1; i<=16; i++) printf \"reg%d=''\n\", i}" </dev/null >.foo
  1182. X. .foo
  1183. X$awk "BEGIN { for (i=1; i<=$registers; i++) printf \"reg%d=register\n\", i}" \
  1184. X    </dev/null >.foo
  1185. X. .foo
  1186. X$rm -f .foo
  1187. X
  1188. X: determine where public executables go
  1189. Xcase "$scriptdir" in
  1190. X'')
  1191. X    dflt="$bin"
  1192. X    : guess some guesses
  1193. X    $test -d /usr/share/scripts && dflt=/usr/share/scripts
  1194. X    $test -d /usr/share/bin && dflt=/usr/share/bin
  1195. X    ;;
  1196. X*)  dflt="$scriptdir"
  1197. X    ;;
  1198. Xesac
  1199. Xcont=true
  1200. X$cat <<EOM
  1201. XSome installations have a separate directory just for executable scripts so
  1202. Xthat they can mount it across multiple architectures but keep the scripts in
  1203. Xone spot.  You might, for example, have a subdirectory of /usr/share for this.
  1204. XOr you might just lump your scripts in with all your other executables.
  1205. XEOM
  1206. Xwhile $test "$cont" ; do
  1207. X    rp="Where do you keep publicly executable scripts? (~name ok)"
  1208. X    . myread
  1209. X    scriptdir="$ans"
  1210. X    scriptdir=`./filexp "$scriptdir"`
  1211. X    if $test -d $scriptdir; then
  1212. X    cont=''
  1213. X    else
  1214. X    case "$fastread" in
  1215. X    yes) dflt=y;;
  1216. X    *) dflt=n;;
  1217. X    esac
  1218. X    rp="Directory $scriptdir doesn't exist.  Use that name anyway?"
  1219. X    . myread
  1220. X    dflt=''
  1221. X    case "$ans" in
  1222. X    y*) cont='';;
  1223. X    esac
  1224. X    fi
  1225. Xdone
  1226. X
  1227. X: see if signal is declared as pointer to function returning int or void
  1228. Xecho " "
  1229. X$cppstdin $cppminus $cppflags < $usrinc/signal.h >$$.tmp
  1230. Xif $contains 'int.*\*[     ]*signal' $$.tmp >/dev/null 2>&1 ; then
  1231. X    echo "You have int (*signal())() instead of void."
  1232. X    val="$undef"
  1233. X    signal_t="int"
  1234. Xelif $contains 'void.*\*[     ]*signal' $$.tmp >/dev/null 2>&1 ; then
  1235. X    echo "You have void (*signal())() instead of int."
  1236. X    val="$define"
  1237. X    signal_t="void"
  1238. Xelif $contains 'extern[     ]*[(\*]*signal' $$.tmp >/dev/null 2>&1 ; then
  1239. X    echo "You have int (*signal())() instead of void."
  1240. X    val="$undef"
  1241. X    signal_t="int"
  1242. Xelse
  1243. X    case "$d_voidsig" in
  1244. X    '') echo "I can't determine whether signal handler returns void or int..."
  1245. X        dflt=void
  1246. X        rp="What type does your signal handler returns?"
  1247. X        . myread
  1248. X        case "$ans" in
  1249. X        void) val="$define"; signal_t="void";;
  1250. X        *) val="$undef"; signal_t="int";;
  1251. X        esac;;
  1252. X    *) echo "As you already told me, signal handler returns $signal_t.";;
  1253. X    esac
  1254. Xfi
  1255. Xset d_voidsig
  1256. Xeval $setvar
  1257. X$rm -f $$.tmp
  1258. X
  1259. X: see if time exists
  1260. Xecho " "
  1261. Xif $contains '^time$' libc.list >/dev/null 2>&1; then
  1262. X    echo 'time() found.'
  1263. X    val="$define"
  1264. X    case "$timetype" in
  1265. X    '')
  1266. X        if $contains 'time_t;' $usrinc/sys/types.h >/dev/null 2>&1 ; then
  1267. X            dflt='time_t';
  1268. X        else
  1269. X            dflt='long';
  1270. X        fi
  1271. X        ;;
  1272. X    *)  dflt="$timetype"
  1273. X        ;;
  1274. X    esac
  1275. X    cont=true
  1276. X    echo " "
  1277. X    rp="What type is returned by time() on this sytem?"
  1278. X    . myread
  1279. X    timetype="$ans"
  1280. Xelse
  1281. X    echo 'time() not found, hope that will do.'
  1282. X    val="$undef"
  1283. X    timetype='int';
  1284. Xfi
  1285. Xset d_time
  1286. Xeval $setvar
  1287. X
  1288. X: see what type uids are declared as in the kernel
  1289. Xcase "$uidtype" in
  1290. X'')
  1291. X    if $contains 'uid_t;' $usrinc/sys/types.h >/dev/null 2>&1 ; then
  1292. X        dflt='uid_t';
  1293. X    else
  1294. X        set `grep '_ruid;' $usrinc/sys/user.h 2>/dev/null` unsigned short
  1295. X        case $1 in
  1296. X        unsigned) dflt="$1 $2" ;;
  1297. X        *) dflt="$1" ;;
  1298. X        esac
  1299. X    fi
  1300. X    ;;
  1301. X*)  dflt="$uidtype";;
  1302. Xesac
  1303. Xecho " "
  1304. Xrp="What type are user ids on this system declared as?"
  1305. X. myread
  1306. Xuidtype="$ans"
  1307. X
  1308. Xecho " "
  1309. Xecho "End of configuration questions."
  1310. Xecho " "
  1311. X
  1312. X: create config.sh file
  1313. Xecho " "
  1314. Xif test -d ../UU; then
  1315. X    cd ..
  1316. Xfi
  1317. Xecho "Creating config.sh..."
  1318. Xxxx=`$date 2>&1`
  1319. Xyyy=`( (logname) 2>/dev/null || whoami) 2>&1`
  1320. X$spitshell <<EOT >config.sh
  1321. X$startsh
  1322. X#
  1323. X# This file was produced by running the Configure script. It holds all the
  1324. X# definitions figured out by Configure. Should you modify one of these values,
  1325. X# do not forget to propagate your changes by running "Configure -d". You may
  1326. X# instead choose to run each of the .SH files by yourself.
  1327. X#
  1328. X
  1329. X# Configuration time: $xxx 
  1330. X# Configured by: $yyy
  1331. X# Target system: $myuname
  1332. X
  1333. Xd_bsd='$d_bsd'
  1334. Xd_eunice='$d_eunice'
  1335. Xd_xenix='$d_xenix'
  1336. Xeunicefix='$eunicefix'
  1337. XMcc='$Mcc'
  1338. Xawk='$awk'
  1339. Xbison='$bison'
  1340. Xcat='$cat'
  1341. Xchgrp='$chgrp'
  1342. Xchmod='$chmod'
  1343. Xchown='$chown'
  1344. Xcompress='$compress'
  1345. Xcp='$cp'
  1346. Xcpio='$cpio'
  1347. Xcpp='$cpp'
  1348. Xcsh='$csh'
  1349. Xdate='$date'
  1350. Xecho='$echo'
  1351. Xegrep='$egrep'
  1352. Xemacs='$emacs'
  1353. Xexpr='$expr'
  1354. Xgrep='$grep'
  1355. Xinews='$inews'
  1356. Xless='$less'
  1357. Xline='$line'
  1358. Xlint='$lint'
  1359. Xln='$ln'
  1360. Xlp='$lp'
  1361. Xlpr='$lpr'
  1362. Xls='$ls'
  1363. Xmail='$mail'
  1364. Xmailx='$mailx'
  1365. Xmake='$make'
  1366. Xmkdir='$mkdir'
  1367. Xmore='$more'
  1368. Xmv='$mv'
  1369. Xnroff='$nroff'
  1370. Xperl='$perl'
  1371. Xpg='$pg'
  1372. Xpmake='$pmake'
  1373. Xpr='$pr'
  1374. Xrm='$rm'
  1375. Xrmail='$rmail'
  1376. Xsed='$sed'
  1377. Xsendmail='$sendmail'
  1378. Xsleep='$sleep'
  1379. Xsmail='$smail'
  1380. Xsort='$sort'
  1381. Xsubmit='$submit'
  1382. Xtail='$tail'
  1383. Xtar='$tar'
  1384. Xtbl='$tbl'
  1385. Xtest='$test'
  1386. Xtouch='$touch'
  1387. Xtr='$tr'
  1388. Xtroff='$troff'
  1389. Xuname='$uname'
  1390. Xuniq='$uniq'
  1391. Xuuname='$uuname'
  1392. Xvi='$vi'
  1393. Xzcat='$zcat'
  1394. Xmyuname='$myuname'
  1395. XAuthor='$Author'
  1396. XDate='$Date'
  1397. XHeader='$Header'
  1398. XId='$Id'
  1399. XLocker='$Locker'
  1400. XLog='$Log'
  1401. XRCSfile='$RCSfile'
  1402. XRevision='$Revision'
  1403. XSource='$Source'
  1404. XState='$State'
  1405. Xbin='$bin'
  1406. Xcc='$cc'
  1407. Xccflags='$ccflags'
  1408. Xcppflags='$cppflags'
  1409. Xldflags='$ldflags'
  1410. Xlkflags='$lkflags'
  1411. Xoptimize='$optimize'
  1412. Xcontains='$contains'
  1413. Xcppminus='$cppminus'
  1414. Xcppstdin='$cppstdin'
  1415. Xd_bcopy='$d_bcopy'
  1416. Xaphostname='$aphostname'
  1417. Xd_gethname='$d_gethname'
  1418. Xd_phostname='$d_phostname'
  1419. Xd_uname='$d_uname'
  1420. Xd_hidnet='$d_hidnet'
  1421. Xhiddennet='$hiddennet'
  1422. Xd_index='$d_index'
  1423. Xd_portable='$d_portable'
  1424. Xd_rename='$d_rename'
  1425. Xd_strerrm='$d_strerrm'
  1426. Xd_strerror='$d_strerror'
  1427. Xd_sysernlst='$d_sysernlst'
  1428. Xd_syserrlst='$d_syserrlst'
  1429. Xd_time='$d_time'
  1430. Xtimetype='$timetype'
  1431. Xd_uwait='$d_uwait'
  1432. Xd_vfork='$d_vfork'
  1433. Xd_voidsig='$d_voidsig'
  1434. Xsignal_t='$signal_t'
  1435. Xhostname='$hostname'
  1436. Xmydomain='$mydomain'
  1437. Xphostname='$phostname'
  1438. Xi_fcntl='$i_fcntl'
  1439. Xi_string='$i_string'
  1440. Xstrings='$strings'
  1441. Xi_sysfile='$i_sysfile'
  1442. Xi_syswait='$i_syswait'
  1443. Xi_systime='$i_systime'
  1444. Xi_systimek='$i_systimek'
  1445. Xi_time='$i_time'
  1446. Xtimeincl='$timeincl'
  1447. Xtimezone='$timezone'
  1448. Xintsize='$intsize'
  1449. Xlibc='$libc'
  1450. Xnm_opt='$nm_opt'
  1451. Xlibpth='$libpth'
  1452. Xplibpth='$plibpth'
  1453. Xlibs='$libs'
  1454. Xmaildir='$maildir'
  1455. Xmailfile='$mailfile'
  1456. Xmanext='$manext'
  1457. Xmansrc='$mansrc'
  1458. Xmkdep='$mkdep'
  1459. Xhuge='$huge'
  1460. Xlarge='$large'
  1461. Xmedium='$medium'
  1462. Xmodels='$models'
  1463. Xsmall='$small'
  1464. Xsplit='$split'
  1465. Xc='$c'
  1466. Xn='$n'
  1467. Xorgname='$orgname'
  1468. Xpackage='$package'
  1469. Xperlpath='$perlpath'
  1470. Xpidtype='$pidtype'
  1471. Xprivlib='$privlib'
  1472. Xreg10='$reg10'
  1473. Xreg11='$reg11'
  1474. Xreg12='$reg12'
  1475. Xreg13='$reg13'
  1476. Xreg14='$reg14'
  1477. Xreg15='$reg15'
  1478. Xreg16='$reg16'
  1479. Xreg1='$reg1'
  1480. Xreg2='$reg2'
  1481. Xreg3='$reg3'
  1482. Xreg4='$reg4'
  1483. Xreg5='$reg5'
  1484. Xreg6='$reg6'
  1485. Xreg7='$reg7'
  1486. Xreg8='$reg8'
  1487. Xreg9='$reg9'
  1488. Xregisters='$registers'
  1489. Xscriptdir='$scriptdir'
  1490. Xsharpbang='$sharpbang'
  1491. Xshsharp='$shsharp'
  1492. Xspitshell='$spitshell'
  1493. Xstartsh='$startsh'
  1494. Xsysman='$sysman'
  1495. Xuidtype='$uidtype'
  1496. Xincpath='$incpath'
  1497. Xmips='$mips'
  1498. Xmips_type='$mips_type'
  1499. Xusrinc='$usrinc'
  1500. XEOT
  1501. X
  1502. X: add special variables
  1503. Xtest -f patchlevel.h && \
  1504. Xawk '/^#define/ {printf "%s=%s\n",$2,$3}' patchlevel.h >>config.sh
  1505. Xecho "CONFIG=true" >>config.sh
  1506. X
  1507. X: propagate old symbols
  1508. Xif test -f UU/config.sh; then
  1509. X    <UU/config.sh sort | uniq >UU/oldconfig.sh
  1510. X    sed -n 's/^\([a-zA-Z_0-9]*\)=.*/\1/p' config.sh config.sh UU/oldconfig.sh |\
  1511. X    sort | uniq -u >UU/oldsyms
  1512. X    set X `cat UU/oldsyms`
  1513. X    shift
  1514. X    case $# in
  1515. X    0) ;;
  1516. X    *)    echo "Hmm...You had some extra variables I don't know about...I'll try to keep 'em..."
  1517. X    for sym in `cat UU/oldsyms`; do
  1518. X        echo "    Propagating $hint variable "'$'"$sym..."
  1519. X        eval 'tmp="$'"${sym}"'"'
  1520. X        echo "$tmp" | \
  1521. X        sed -e "s/'/'\"'\"'/g" -e "s/^/$sym='/" -e "s/$/'/" >>config.sh
  1522. X    done
  1523. X    ;;
  1524. X    esac
  1525. Xfi
  1526. X
  1527. X: Finish up
  1528. XCONFIG=true
  1529. X
  1530. Xecho " "
  1531. Xdflt=''
  1532. Xecho "If you didn't make any mistakes, then just type a carriage return here."
  1533. Xrp="If you need to edit config.sh, do it as a shell escape here:"
  1534. X. UU/myread
  1535. Xcase "$ans" in
  1536. X'') ;;
  1537. X*) : in case they cannot read
  1538. X    eval $ans;;
  1539. Xesac
  1540. X. ./config.sh
  1541. X
  1542. Xecho " "
  1543. Xecho "Doing variable substitutions on .SH files..."
  1544. Xif test -f MANIFEST; then
  1545. X    set x `awk '{print $1}' <MANIFEST | $grep '\.SH'`
  1546. Xelse
  1547. X    set x `find . -name "*.SH" -print`
  1548. Xfi
  1549. Xshift
  1550. Xcase $# in
  1551. X0) set x *.SH; shift;;
  1552. Xesac
  1553. Xif test ! -f $1; then
  1554. X    shift
  1555. Xfi
  1556. Xfor file in $*; do
  1557. X    case "$file" in
  1558. X    */*)
  1559. X    dir=`$expr X$file : 'X\(.*\)/'`
  1560. X    file=`$expr X$file : 'X.*/\(.*\)'`
  1561. X    (cd $dir && . $file)
  1562. X    ;;
  1563. X    *)
  1564. X    . $file
  1565. X    ;;
  1566. X    esac
  1567. Xdone
  1568. Xif test -f config.h.SH; then
  1569. X    if test ! -f config.h; then
  1570. X    : oops, they left it out of MANIFEST, probably, so do it anyway.
  1571. X    . config.h.SH
  1572. X    fi
  1573. Xfi
  1574. X
  1575. Xif $contains '^depend:' Makefile >/dev/null 2>&1; then
  1576. X    dflt=n
  1577. X    $cat <<EOM
  1578. X
  1579. XNow you need to generate make dependencies by running "make depend".
  1580. XYou might prefer to run it in background: "make depend > makedepend.out &"
  1581. XIt can take a while, so you might not want to run it right now.
  1582. X
  1583. XEOM
  1584. X    rp="Run make depend now?"
  1585. X    . UU/myread
  1586. X    case "$ans" in
  1587. X    y*) make depend
  1588. X    echo "Now you must run a make."
  1589. X    ;;
  1590. X    *)  echo "You must run 'make depend' then 'make'."
  1591. X    ;;
  1592. X    esac
  1593. Xelif test -f [Mm]akefile; then
  1594. X    echo " "
  1595. X    echo "Now you must run a make."
  1596. Xelse
  1597. X    echo "Done."
  1598. Xfi
  1599. X
  1600. X$rm -f kit*isdone
  1601. X$rm -rf UU
  1602. X: end of Configure
  1603. END_OF_FILE
  1604.  if test 34312 -ne `wc -c <'Configure.b'`; then
  1605.     echo shar: \"'Configure.b'\" unpacked with wrong size!
  1606.  elif test -f 'Configure.a'; then
  1607.     echo shar: Combining  \"'Configure'\" \(70471 characters\)
  1608.     cat 'Configure.a' 'Configure.b' > 'Configure'
  1609.     if test 70471 -ne `wc -c <'Configure'`; then
  1610.       echo shar: \"'Configure'\" combined with wrong size!
  1611.     else
  1612.       chmod u+x Configure
  1613.       rm Configure.a Configure.b
  1614.     fi
  1615.   fi
  1616.   # end of 'Configure.b'
  1617. fi
  1618. if test -f 'agent/filter/io.c' -a "${1}" != "-c" ; then 
  1619.   echo shar: Will not clobber existing file \"'agent/filter/io.c'\"
  1620. else
  1621.   echo shar: Extracting \"'agent/filter/io.c'\" \(16581 characters\)
  1622.   sed "s/^X//" >'agent/filter/io.c' <<'END_OF_FILE'
  1623. X/*
  1624. X
  1625. X    #     ####            ####
  1626. X    #    #    #          #    #
  1627. X    #    #    #          #
  1628. X    #    #    #   ###    #
  1629. X    #    #    #   ###    #    #
  1630. X    #     ####    ###     ####
  1631. X
  1632. X    I/O routines.
  1633. X*/
  1634. X
  1635. X/*
  1636. X * $Id: io.c,v 2.9 92/07/14 16:48:13 ram Exp $
  1637. X *
  1638. X *  Copyright (c) 1992, Raphael Manfredi
  1639. X *
  1640. X *  You may redistribute only under the terms of the GNU General Public
  1641. X *  Licence as specified in the README file that comes with dist.
  1642. X *
  1643. X * $Log:    io.c,v $
  1644. X * Revision 2.9  92/07/14  16:48:13  ram
  1645. X * 3.0 beta baseline.
  1646. X * 
  1647. X */
  1648. X
  1649. X#include "config.h"
  1650. X#include "portable.h"
  1651. X#include <sys/types.h>
  1652. X#include "hash.h"
  1653. X#include "parser.h"
  1654. X#include "lock.h"
  1655. X#include "logfile.h"
  1656. X#include "environ.h"
  1657. X#include <stdio.h>
  1658. X#include <errno.h>
  1659. X#include <sys/stat.h>
  1660. X
  1661. X#ifdef I_SYSWAIT
  1662. X#include <sys/wait.h>
  1663. X#endif
  1664. X
  1665. X#ifdef I_FCNTL
  1666. X#include <fcntl.h>
  1667. X#else
  1668. X#include <sys/fcntl.h>
  1669. X#endif
  1670. X#ifdef I_SYSFILE
  1671. X#include <sys/file.h>
  1672. X#endif
  1673. X
  1674. X#ifdef I_STRING
  1675. X#include <string.h>
  1676. X#else
  1677. X#include <strings.h>
  1678. X#endif
  1679. X
  1680. X#define BUFSIZE        1024            /* Amount of bytes read in a single call */
  1681. X#define CHUNK        (10 * BUFSIZE)    /* Granularity of pool */
  1682. X#define MAX_STRING    2048            /* Maximum string's length */
  1683. X#define AGENT_WAIT    "agent.wait"    /* File listing out-of-the-queue mails */
  1684. X#define AGENT_LOCK    "perl.lock"        /* Lock file used by mailagent */
  1685. X
  1686. Xprivate void pool_realloc();    /* Extend pool zone */
  1687. Xprivate int get_lock();            /* Attempt to get a lockfile */
  1688. Xprivate void release_agent();    /* Remove mailagent's lock if needed */
  1689. Xprivate int process_mail();        /* Process mail by feeding the mailagent */
  1690. Xprivate void queue_mail();        /* Queue mail for delayed processing */
  1691. Xprivate char *write_file();        /* Write mail on disk */
  1692. Xprivate char *save_file();        /* Emergency saving into a file */
  1693. X
  1694. Xprivate char *mail = (char *) 0;    /* Where mail is stored */
  1695. Xprivate int len;                    /* Mail length in bytes */
  1696. Xprivate int queued = 0;                /* True when mail queued safely */
  1697. X
  1698. Xextern int errno;                /* System call error status */
  1699. Xextern char *malloc();            /* Memory allocation */
  1700. Xextern char *realloc();            /* Re-allocation of memory pool */
  1701. Xextern char *logname();            /* User's login name */
  1702. Xextern int loglvl;                /* Logging level */
  1703. X
  1704. Xprivate void read_stdin()
  1705. X{
  1706. X    /* Read the whole stdandard input into memory and return a pointer to its
  1707. X     * location in memory. Any I/O error is fatal. Set the length of the
  1708. X     * data read into 'len'.
  1709. X     */
  1710. X
  1711. X    int size;                    /* Current size of memory pool */
  1712. X    int amount = 0;                /* Total amount of data read */
  1713. X    int n;                        /* Bytes read by last system call */
  1714. X    char *pool;                    /* Where input is stored */
  1715. X    char buf[BUFSIZE];
  1716. X
  1717. X    size = CHUNK;
  1718. X    pool = malloc(size);
  1719. X    if (pool == (char *) 0)
  1720. X        fatal("out of memory");
  1721. X
  1722. X    add_log(19, "reading mail");
  1723. X
  1724. X    while (n = read(0, buf, BUFSIZE)) {
  1725. X        if (n == -1) {
  1726. X            add_log(1, "SYSERR read: %m (%e)");
  1727. X            fatal("I/O error");
  1728. X        }
  1729. X        if (size - amount < n)                /* Pool not big enough */
  1730. X            pool_realloc(&pool, &size);        /* Resize it or fail */
  1731. X        bcopy(buf, pool + amount, n);        /* Copy read bytes */
  1732. X        amount += n;                        /* Update amount of bytes read */
  1733. X    }
  1734. X
  1735. X    len = amount;                /* Indicate how many bytes where read */
  1736. X
  1737. X    add_log(16, "got mail (%d bytes)", amount);
  1738. X
  1739. X    mail = pool;                /* Where mail is stored */
  1740. X}
  1741. X
  1742. Xpublic void process()
  1743. X{
  1744. X    char *queue;                        /* Location of mailagent's queue */
  1745. X
  1746. X    (void) umask(077);                    /* Files we create are private ones */
  1747. X
  1748. X    queue = ht_value(&symtab, "queue");    /* Fetch queue location */
  1749. X    if (queue == (char *) 0)
  1750. X        fatal("queue directory not defined");
  1751. X
  1752. X    read_stdin();                        /* Read mail */
  1753. X    (void) get_lock();                    /* Get a lock file */
  1754. X    queue_mail(queue);                    /* Process also it locked */
  1755. X    release_lock();                        /* Release lock file if necessary */
  1756. X}
  1757. X
  1758. Xpublic int was_queued()
  1759. X{
  1760. X    return queued;            /* Was mail queued? */
  1761. X}
  1762. X
  1763. Xprivate void pool_realloc(pool, size)
  1764. Xchar **pool;
  1765. Xint *size;
  1766. X{
  1767. X    /* Make more room in pool and update parameters accordingly */
  1768. X
  1769. X    char *cpool = *pool;    /* Current location */
  1770. X    int csize = *size;        /* Current size */
  1771. X
  1772. X    csize += CHUNK;
  1773. X    cpool = realloc(cpool, csize);
  1774. X    if (cpool == (char *) 0)
  1775. X        fatal("out of memory");
  1776. X    *pool = cpool;
  1777. X    *size = csize;
  1778. X}
  1779. X
  1780. Xprivate int get_lock()
  1781. X{
  1782. X    /* Try to get a filter lock in the spool directory. Propagate the return
  1783. X     * status of filter_lock(): 0 for ok, -1 for failure.
  1784. X     */
  1785. X
  1786. X    char *spool;                        /* Location of spool directory */
  1787. X
  1788. X    spool = ht_value(&symtab, "spool");    /* Fetch spool location */
  1789. X    if (spool == (char *) 0)
  1790. X        fatal("spool directory not defined");
  1791. X
  1792. X    return filter_lock(spool);            /* Get a lock in spool directory */
  1793. X}
  1794. X
  1795. Xprivate void release_agent()
  1796. X{
  1797. X    /* In case of abnormal failure, the mailagent may leave its lock file
  1798. X     * in the spool directory. Remove it if necessary.
  1799. X     */
  1800. X
  1801. X    char *spool;                    /* Location of spool directory */
  1802. X    char agentlock[MAX_STRING];        /* Where lock file is held */
  1803. X    struct stat buf;                /* Stat buffer */
  1804. X
  1805. X    spool = ht_value(&symtab, "spool");    /* Fetch spool location */
  1806. X    if (spool == (char *) 0)            /* Should not happen */
  1807. X        return;
  1808. X
  1809. X    sprintf(agentlock, "%s/%s", spool, AGENT_LOCK);
  1810. X    if (-1 == stat(agentlock, &buf))
  1811. X        return;                        /* Assume no lock file left behind */
  1812. X
  1813. X    if (-1 == unlink(agentlock)) {
  1814. X        add_log(1, "SYSERR unlink: %m (%e)");
  1815. X        add_log(2, "ERROR could not remove mailagent's lock");
  1816. X    } else
  1817. X        add_log(5, "NOTICE removed mailagent's lock");
  1818. X}
  1819. X
  1820. Xprivate void queue_mail(queue)
  1821. Xchar *queue;                /* Location of the queue directory */
  1822. X{
  1823. X    char *where;            /* Where mail is stored */
  1824. X    char real[MAX_STRING];    /* Real queue mail */
  1825. X    char *base;                /* Pointer to base name */
  1826. X    struct stat buf;        /* To make sure queued file remains */
  1827. X
  1828. X    where = write_file(queue, "Tm");
  1829. X    if (where == (char *) 0) {
  1830. X        add_log(1, "ERROR unable to queue mail");
  1831. X        fatal("try again later");
  1832. X    }
  1833. X
  1834. X    /* If we have a lock, create a qm* file suitable for mailagent processing.
  1835. X     * Otherwise, create a fm* file and the mailagent will process it
  1836. X     * immediately.
  1837. X     */
  1838. X    if (is_locked())
  1839. X        sprintf(real, "%s/%s%d", queue, "qm", progpid);
  1840. X    else
  1841. X        sprintf(real, "%s/%s%d", queue, "fm", progpid);
  1842. X
  1843. X    if (-1 == rename(where, real)) {
  1844. X        add_log(1, "SYSERR rename: %m (%e)");
  1845. X        add_log(2, "ERROR could not rename %s into %s", where, real);
  1846. X        fatal("try again later");
  1847. X    }
  1848. X
  1849. X    /* Compute base name of queued mail */
  1850. X    base = rindex(real, '/');
  1851. X    if (base++ == (char *) 0)
  1852. X        base = real;
  1853. X
  1854. X    add_log(4, "QUEUED [%s] %d bytes", base, len);
  1855. X    queued = 1;
  1856. X
  1857. X    /* If we got a lock, then no mailagent is running and we may process the
  1858. X     * mail. Otherwise, do nothing. The mail will be processed by the currently
  1859. X     * active mailagent.
  1860. X     */
  1861. X
  1862. X    if (!is_locked())            /* Another mailagent is running */
  1863. X        return;                    /* Leave mail in queue */
  1864. X
  1865. X    if (0 == process_mail(real)) {
  1866. X        /* Mailagent may have simply queued the mail for itself by renaming
  1867. X         * it, so of course we would not be able to remove it. Hence the
  1868. X         * test for ENOENT to avoid error messages when the file does not
  1869. X         * exit any more.
  1870. X         */
  1871. X        if (-1 == unlink(real) && errno != ENOENT) {
  1872. X            add_log(1, "SYSERR unlink: %m (%e)");
  1873. X            add_log(2, "ERROR could not remove queued mail");
  1874. X        }
  1875. X        return;
  1876. X    }
  1877. X    /* Paranoia: make sure the queued mail is still there */
  1878. X    if (-1 == stat(real, &buf)) {
  1879. X        queued = 0;            /* Or emergency_save() would not do anything */
  1880. X        add_log(1, "SYSERR stat: %m (%e)");
  1881. X        add_log(1, "ERROR queue file [%s] vanished", base);
  1882. X        if (-1 == emergency_save())
  1883. X            add_log(1, "ERROR mail probably lost");
  1884. X    } else {
  1885. X        add_log(4, "WARNING mailagent failed, [%s] left in queue", base);
  1886. X        release_agent();    /* Remove mailagent's lock file if needed */
  1887. X    }
  1888. X}
  1889. X
  1890. Xprivate int process_mail(location)
  1891. Xchar *location;
  1892. X{
  1893. X    /* Process mail held in 'location' by invoking the mailagent on it. If the
  1894. X     * command fails, return -1. Otherwise, return 0;
  1895. X     * Note that we will exit if the first fork is not possible, but that is
  1896. X     * harmless, because we know the mail was safely queued, otherwise we would
  1897. X     * not be here trying to make the mailagent process it.
  1898. X     */
  1899. X    
  1900. X    FILE *fp;                /* The file pointer on pipe */
  1901. X    char cmd[MAX_STRING];    /* The built command */
  1902. X    char buf[MAX_STRING];    /* To store output from mailagent */
  1903. X    char **envp;            /* Environment pointer */
  1904. X#ifdef UNION_WAIT
  1905. X    union wait status;        /* Waiting status */
  1906. X#else
  1907. X    int status;                /* Status from command */
  1908. X#endif
  1909. X    int xstat;                /* The exit status value */
  1910. X    int pid;                /* Pid of our children */
  1911. X    int res;                /* Result from wait */
  1912. X
  1913. X    if (loglvl <= 20) {        /* Loggging level higher than 20 is for tests */
  1914. X        pid = fork();
  1915. X        if (pid == -1) {    /* Resources busy, most probably */
  1916. X            release_lock();
  1917. X            add_log(1, "SYSERR fork: %m (%e)");
  1918. X            add_log(6, "NOTICE exiting to save resources");
  1919. X            exit(0);        /* Exiting will also release sendmail process */
  1920. X        } else if (pid != 0)
  1921. X            exit(0);        /* Release waiting sendmail */
  1922. X    }
  1923. X
  1924. X    /* Now hopefully we detached ourselves from sendmail, which thinks the mail
  1925. X     * has been delivered. Not yet, but close. Simply wait a little in case
  1926. X     * more mail is comming. This process is going to remain alive while the
  1927. X     * mailagent is running so as to trap any weird exit status. But the size
  1928. X     * of the perl process (with script compiled) is about 1650K on my MIPS,
  1929. X     * so the more we delay the invocation, the better.
  1930. X     */
  1931. X
  1932. X    if (loglvl < 12)        /* Loggging level 12 and higher is for debugging */
  1933. X        sleep(60);            /* Delay invocation of mailagent */
  1934. X    progpid = getpid();        /* This may be the child (if fork succeded) */
  1935. X    envp = make_env();        /* Build new environment */
  1936. X
  1937. X    pid = vfork();            /* Virtual fork this time... */
  1938. X    if (pid == -1) {
  1939. X        add_log(1, "SYSERR vfork: %m (%e)");
  1940. X        add_log(1, "ERROR cannot run mailagent");
  1941. X        return -1;
  1942. X    }
  1943. X
  1944. X    if (pid == 0) {            /* This is the child */
  1945. X        execle(PERLPATH, "perl", "-S", "mailagent", location, (char *) 0, envp);
  1946. X        exit(1);
  1947. X    } else {                /* Parent process */
  1948. X        while (pid != (res = wait(&status)))
  1949. X            if (res == -1) {
  1950. X                add_log(1, "SYSERR wait: %m (%e)");
  1951. X                return -1;
  1952. X            }
  1953. X
  1954. X#ifdef WEXITSTATUS
  1955. X        if (WIFEXITED(status)) {            /* Exited normally */
  1956. X            xstat = WEXITSTATUS(status);
  1957. X            if (xstat != 0) {
  1958. X                add_log(3, "ERROR mailagent returned status %d", xstat);
  1959. X                return -1;
  1960. X            }
  1961. X        } else if (WIFSIGNALED(status)) {    /* Signal received */
  1962. X            xstat = WTERMSIG(status);
  1963. X            add_log(3, "ERROR mailagent terminated by signal %d", xstat);
  1964. X            return -1;
  1965. X        } else if (WIFSTOPPED(status)) {    /* Process stopped */
  1966. X            xstat = WSTOPSIG(status);
  1967. X            add_log(3, "WARNING mailagent stopped by signal %d", xstat);
  1968. X            add_log(6, "NOTICE terminating mailagent, pid %d", pid);
  1969. X            if (-1 == kill(pid, 15))
  1970. X                add_log(1, "SYSERR kill: %m (%e)");
  1971. X            return -1;
  1972. X        } else
  1973. X            add_log(1, "BUG please report bug 'posix-wait' to author");
  1974. X#else
  1975. X#ifdef UNION_WAIT
  1976. X        xstat = status.w_status;
  1977. X#else
  1978. X        xstat = status;
  1979. X#endif
  1980. X        if ((xstat & 0xff) == 0177) {        /* Process stopped */
  1981. X            xstat >>= 8;
  1982. X            add_log(3, "WARNING mailagent stopped by signal %d", xstat);
  1983. X            add_log(6, "NOTICE terminating mailagent, pid %d", pid);
  1984. X            if (-1 == kill(pid, 15))
  1985. X                add_log(1, "SYSERR kill: %m (%e)");
  1986. X            return -1;
  1987. X        } else if ((xstat & 0xff) != 0) {    /* Signal received */
  1988. X            xstat &= 0xff;
  1989. X            if (xstat & 0200) {                /* Dumped a core ? */
  1990. X                xstat &= 0177;
  1991. X                add_log(3, "ERROR mailagent dumped core on signal %d", xstat);
  1992. X            } else
  1993. X                add_log(3, "ERROR mailagent terminated by signal %d", xstat);
  1994. X            return -1;
  1995. X        } else {
  1996. X            xstat >>= 8;
  1997. X            if (xstat != 0) {
  1998. X                add_log(3, "ERROR mailagent returned status %d", xstat);
  1999. X                return -1;
  2000. X            }
  2001. X        }
  2002. X#endif
  2003. X    }
  2004. X    
  2005. X    add_log(19, "mailagent ok");
  2006. X
  2007. X    return 0;
  2008. X}
  2009. X
  2010. Xpublic int emergency_save()
  2011. X{
  2012. X    /* Save mail in emeregency files and add the path to the agent.wait file,
  2013. X     * so that the mailagent knows where to look when processing its queue.
  2014. X     * Return -1 if the mail was not sucessfully saved, 0 otherwise.
  2015. X     */
  2016. X
  2017. X    char *where;            /* Where file was stored (static data) */
  2018. X    char *home = homedir();    /* Location of the home directory */
  2019. X    char path[MAX_STRING];    /* Location of the AGENT_WAIT file */
  2020. X    char *queue;            /* Location of the queue directory */
  2021. X    char *emergdir;            /* Emergency directory */
  2022. X    int fd;                    /* File descriptor to write in AGENT_WAIT */
  2023. X    int size;                /* Length of 'where' string */
  2024. X
  2025. X    if (mail == (char *) 0)
  2026. X        return -1;            /* Mail not read yet */
  2027. X
  2028. X    if (queued) {
  2029. X        add_log(6, "NOTICE mail was safely queued");
  2030. X        return 0;
  2031. X    }
  2032. X
  2033. X    emergdir = ht_value(&symtab, "emergdir");
  2034. X    if ((emergdir != (char *) 0) && (char *) 0 != (where = save_file(emergdir)))
  2035. X        goto ok;
  2036. X    if ((home != (char *) 0) && (char *) 0 != (where = save_file(home)))
  2037. X        goto ok;
  2038. X    if (where = save_file("/usr/spool/uucppublic"))
  2039. X        goto ok;
  2040. X    if (where = save_file("/var/spool/uucppublic"))
  2041. X        goto ok;
  2042. X    if (where = save_file("/usr/tmp"))
  2043. X        goto ok;
  2044. X    if (where = save_file("/var/tmp"))
  2045. X        goto ok;
  2046. X    if (where = save_file("/tmp"))
  2047. X        goto ok;
  2048. X
  2049. X    return -1;        /* Could not save mail anywhere */
  2050. X
  2051. Xok:
  2052. X    add_log(6, "DUMPED in %s", where);
  2053. X    fprintf(stderr, "%s: DUMPED in %s\n", progname, where);
  2054. X
  2055. X    /* Attempt to write path of saved mail in the AGENT_WAIT file */
  2056. X
  2057. X    queue = ht_value(&symtab, "queue");
  2058. X    if (queue == (char *) 0)
  2059. X        return 0;
  2060. X    sprintf(path, "%s/%s", queue, AGENT_WAIT);
  2061. X    if (-1 == (fd = open(path, O_WRONLY | O_APPEND | O_CREAT, 0600))) {
  2062. X        add_log(1, "SYSERR open: %m (%e)");
  2063. X        add_log(6, "WARNING mailagent ignores where mail was left");
  2064. X        return 0;
  2065. X    }
  2066. X    size = strlen(where);
  2067. X    where[size + 1] = '\0';            /* Make room for trailing new-line */
  2068. X    where[size] = '\n';
  2069. X    if (-1 == write(fd, where, size + 1)) {
  2070. X        add_log(1, "SYSERR write: %m (%e)");
  2071. X        add_log(4, "ERROR could not append to %s", path);
  2072. X        add_log(6, "WARNING mailagent ignores where mail was left");
  2073. X    } else {
  2074. X        where[size] = '\0';
  2075. X        add_log(7, "NOTICE memorized %s", where);
  2076. X        queued = 1;
  2077. X    }
  2078. X    close(fd);
  2079. X
  2080. X    return 0;
  2081. X}
  2082. X
  2083. Xprivate char *save_file(dir)
  2084. Xchar *dir;                /* Where saving should be done (directory) */
  2085. X{
  2086. X    /* Attempt to write mail in directory 'dir' and return a pointer to static
  2087. X     * data holding the path name of the saved file if writing was ok.
  2088. X     * Otherwise, return a null pointer and unlink any already created file.
  2089. X     */
  2090. X
  2091. X    struct stat buf;                /* Stat buffer */
  2092. X
  2093. X    /* Make sure 'dir' entry exists, although we do not make sure it is really
  2094. X     * a directory. If 'dir' is in fact a file, then open() will loudly
  2095. X     * complain. We only want to avoid spurious log messages.
  2096. X     */
  2097. X
  2098. X    if (-1 == stat(dir, &buf))        /* No entry in file system, probably */
  2099. X        return (char *) 0;            /* Saving failed */
  2100. X
  2101. X    return write_file(dir, logname());
  2102. X}
  2103. X
  2104. Xprivate char *write_file(dir, template)
  2105. Xchar *dir;                /* Where saving should be done (directory) */
  2106. Xchar *template;            /* First part of the file name */
  2107. X{
  2108. X    /* Attempt to write mail in directory 'dir' and return a pointer to static
  2109. X     * data holding the path name of the saved file if writing was ok.
  2110. X     * Otherwise, return a null pointer and unlink any already created file.
  2111. X     * The file 'dir/template.$$' is created (where '$$' refers to the pid of
  2112. X     * the current process). As login name <= 8 and pid is <= 5, we are below
  2113. X     * the fatidic 14 chars limit for filenames.
  2114. X     */
  2115. X
  2116. X    static char path[MAX_STRING];    /* Path name of created file */
  2117. X    int fd;                            /* File descriptor */
  2118. X    register4 int n;                /* Result from the write system call */
  2119. X    register1 char *mailptr;        /* Pointer into mail buffer */
  2120. X    register2 int length;            /* Number of bytes already written */
  2121. X    register3 int amount;            /* Amount of bytes written by last call */
  2122. X
  2123. X    sprintf(path, "%s/%s.%d", dir, template, progpid);
  2124. X
  2125. X    if (-1 == (fd = open(path, O_WRONLY | O_CREAT | O_EXCL, 0600))) {
  2126. X        add_log(1, "SYSERR open: %m (%e)");
  2127. X        add_log(2, "ERROR cannot create file %s", path);
  2128. X        return (char *) 0;
  2129. X    }
  2130. X
  2131. X    /* Write the mail on disc. We do not call a single write on the mail buffer
  2132. X     * as in "write(fd, mail, len)" in case the mail length exceeds the maximum
  2133. X     * amount of bytes the system can atomically write.
  2134. X     */
  2135. X    
  2136. X    for (
  2137. X        mailptr = mail, length = 0;
  2138. X        length < len;
  2139. X        mailptr += amount, length += amount
  2140. X    ) {
  2141. X        amount = len - length;
  2142. X        if (amount > BUFSIZ)        /* Do not write more than BUFSIZ */
  2143. X            amount = BUFSIZ;
  2144. X        n = write(fd, mailptr, amount);
  2145. X        if (n == -1 || n != amount) {
  2146. X            if (n == -1)
  2147. X                add_log(1, "SYSERR write: %m (%e)");
  2148. X            add_log(2, "ERROR cannot write to file %s", path);
  2149. X            if (-1 == unlink(path)) {
  2150. X                add_log(1, "SYSERR unlink: %m (%e)");
  2151. X                add_log(4, "WARNING leaving %s around", path);
  2152. X            }
  2153. X            close(fd);
  2154. X            return (char *) 0;
  2155. X        }
  2156. X    }
  2157. X
  2158. X    close(fd);
  2159. X    add_log(19, "mail in %s", path);
  2160. X
  2161. X    return path;            /* Where mail was writen (static data) */
  2162. X}
  2163. X
  2164. X#ifndef RENAME
  2165. Xpublic int rename(from, to)
  2166. Xchar *from;                /* Original name */
  2167. Xchar *to;                /* Target name */
  2168. X{
  2169. X    (void) unlink(to);
  2170. X    if (-1 == link(from, to))
  2171. X        return -1;
  2172. X    if (-1 == unlink(from))
  2173. X        return -1;
  2174. X
  2175. X    return 0;
  2176. X}
  2177. X#endif
  2178. X
  2179. END_OF_FILE
  2180.   if test 16581 -ne `wc -c <'agent/filter/io.c'`; then
  2181.     echo shar: \"'agent/filter/io.c'\" unpacked with wrong size!
  2182.   fi
  2183.   # end of 'agent/filter/io.c'
  2184. fi
  2185. if test -f 'agent/test/cmd/give.t' -a "${1}" != "-c" ; then 
  2186.   echo shar: Will not clobber existing file \"'agent/test/cmd/give.t'\"
  2187. else
  2188.   echo shar: Extracting \"'agent/test/cmd/give.t'\" \(494 characters\)
  2189.   sed "s/^X//" >'agent/test/cmd/give.t' <<'END_OF_FILE'
  2190. X# Test GIVE command
  2191. Xdo '../pl/cmd.pl';
  2192. Xunlink 'output';
  2193. X
  2194. X&add_header('X-Tag: give');
  2195. X`$cmd`;
  2196. X$? == 0 || print "1\n";
  2197. X-f 'output' || print "2\n";        # Where output is created
  2198. Xchop($output = `cat output 2>/dev/null`);
  2199. X@output = split(' ', $output);
  2200. X@valid = (17, 132, 804);        # Output of wc on body
  2201. X$ok = 1;
  2202. Xfor ($i = 0; $i < 3; $i++) {
  2203. X    $ok = 0 if $valid[$i] != $output[$i];
  2204. X}
  2205. X$ok || print "3\n";
  2206. X-f "$user" || print "4\n";        # Default action applies
  2207. X
  2208. Xunlink 'output', 'mail', "$user";
  2209. Xprint "0\n";
  2210. END_OF_FILE
  2211.   if test 494 -ne `wc -c <'agent/test/cmd/give.t'`; then
  2212.     echo shar: \"'agent/test/cmd/give.t'\" unpacked with wrong size!
  2213.   fi
  2214.   # end of 'agent/test/cmd/give.t'
  2215. fi
  2216. echo shar: End of archive 5 \(of 17\).
  2217. cp /dev/null ark5isdone
  2218. MISSING=""
  2219. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ; do
  2220.     if test ! -f ark${I}isdone ; then
  2221.     MISSING="${MISSING} ${I}"
  2222.     fi
  2223. done
  2224. if test "${MISSING}" = "" ; then
  2225.     echo You have unpacked all 17 archives.
  2226.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2227. else
  2228.     echo You still must unpack the following archives:
  2229.     echo "        " ${MISSING}
  2230. fi
  2231. exit 0
  2232. exit 0 # Just in case...
  2233.