home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume10 / pcmail2 / part04 < prev    next >
Text File  |  1990-01-24  |  61KB  |  2,138 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v10i036: PC-MAIL release 2, 4/11
  3. from: wswietse@lso.win.tue.nl (Wietse Venema)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 10, Issue 36
  7. Submitted-by: wswietse@lso.win.tue.nl (Wietse Venema)
  8. Archive-name: pcmail2/part04
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 4 (of 11)."
  17. # Contents:  aux/srctoman.sh daemon/DAEMON.ins daemon/Makefile
  18. #   daemon/ms_parse.c main/Implement main/invoke.c main/msd_dir.c
  19. #   main/screen.h main/sendwork.c main/setup.c main/switcher.c
  20. #   main/unalias.c
  21. # Wrapped by wswietse@tuewsa on Mon Jan 22 17:27:16 1990
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f aux/srctoman.sh -a "${1}" != "-c" ; then 
  24.   echo shar: Will not over-write existing file \"aux/srctoman.sh\"
  25. else
  26. echo shar: Extracting \"aux/srctoman.sh\" \(4444 characters\)
  27. sed "s/^X//" >aux/srctoman.sh <<'END_OF_aux/srctoman.sh'
  28. X: srctoman - see comment below
  29. X
  30. X: process arguments
  31. X
  32. Xwhile :
  33. Xdo
  34. X    case $1 in
  35. X [0-9]) SECT=$1;;
  36. X     -) LANG=$1; B='[#:]';;
  37. X  -awk) LANG=$1; B='#';;
  38. X    -c) LANG=$1; B='\/\*';;
  39. X    -f) LANG=$1; B='[Cc]';;
  40. X   -mk) LANG=$1; B='#';;
  41. X -n|-t) LANG=$1; B='\\"';;
  42. X    -p) LANG=$1; B='{';;
  43. X    -r) LANG=$1; B='#';;
  44. X    -C) LANG=$1; B=$2; shift;;
  45. X    -*) ERROR="unknown option: $1"; break;;
  46. X    "") ERROR="missing file argument"; break;;
  47. X     *) break;;
  48. X    esac
  49. X    shift
  50. Xdone
  51. X
  52. X: check error status
  53. X
  54. Xcase $ERROR in
  55. X"") ;;
  56. X *) echo "$0: $ERROR" 1>&2
  57. X    echo "usage: $0 [-|-awk|-c|-f|-mk|-n|-p|-t|-r] [section] file(s)" 1>&2; exit 1;;
  58. Xesac
  59. X
  60. X: set up for file suffix processing
  61. X
  62. Xcase $LANG in
  63. X"") sh='[:#]';    r='#';    rh=$r;    awk='#'; mk='#';
  64. X    c='\/\*';    h=$c;    y=$c;    l=$c;
  65. X    f='[Cc]';    fh=$f;    p='{';    ph=$p;
  66. X    ms='\\"';    nr=$ms;    mn=$ms;    man=$ms;
  67. Xesac
  68. X
  69. X: extract comments
  70. X
  71. Xfor i in $*
  72. Xdo
  73. X    case $LANG in
  74. X    "") eval B\="\$`expr $i : '^.*\.\([^.]*\)$'`"
  75. X    test "$B" || { echo "$0: unknown suffix: $i; assuming c" 1>&2; B=$c; }
  76. X    esac
  77. X    sed '
  78. X    /^'"$B"'++/,/^'"$B"'--/!d
  79. X    /^'"$B"'++/d
  80. X    /^'"$B"'--/d
  81. X    s/[     ]*$//
  82. X    /^'"$B"' \([A-Z]\)/{
  83. X    s//\1/
  84. X    /^NAME/{
  85. X        N
  86. X        s/^.*\n'"$B"'[     ]*//
  87. X        h
  88. X        y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
  89. X        s/^.*$/.TH & '"$SECT"'\
  90. X.ad\
  91. X.fi\
  92. X.SH NAME/
  93. X        p
  94. X        g
  95. X        s/ [0-9]$//
  96. X        a\
  97. X\\-
  98. X        p
  99. X        d
  100. X    }
  101. X    /^SUMMARY/d
  102. X    /^DESCRIPTION/s//.SH &\
  103. X.ad\
  104. X.fi/
  105. X    /^BUGS/s//.SH &\
  106. X.ad\
  107. X.fi/
  108. X    /^DIAGNOSTICS/s//.SH &\
  109. X.ad\
  110. X.fi/
  111. X    /^[A-Z][A-Z][A-Z][^a-z]*$/s//.SH &\
  112. X.na\
  113. X.nf/
  114. X    p
  115. X    d
  116. X    }
  117. X    s/^'"$B"'[     ]*//
  118. X    s/^[     ]*$//
  119. X' $i
  120. Xdone 
  121. X
  122. Xexit
  123. X
  124. X:++
  125. X: NAME
  126. X:    srctoman 1
  127. X: SUMMARY
  128. X:    extract manual page from source file comment
  129. X: PACKAGE
  130. X:    source file maintentance tools
  131. X: SYNOPSIS
  132. X:    srctoman [-|-awk|-c|-f|-mk|-m|-n|-p|-t|-r] [section] file(s)
  133. X: DESCRIPTION
  134. X:    Srctoman converts comments in various programming languages to
  135. X:    UNIX-style manual pages.
  136. X:    The command processes comments in the style of newsource(1);
  137. X:    its standard output is suitable for formatting with nroff(1) or 
  138. X:    troff(1) using the "-man" macro package.  
  139. X:    Typically, srctoman is integrated with make(1) scripts.
  140. X:
  141. X:    Source files are processed in the indicated order; if no
  142. X:    files argument the command produces no output.
  143. X:
  144. X:    The source file language can be specified through a command-line
  145. X:    option, or can be implied by the filename suffix.
  146. X:    The expected start-of-comment symbol is shown in the last column.
  147. X:
  148. X: .nf
  149. X    option    language    comment
  150. X
  151. X    -    shell        [:#]
  152. X    -awk    awk        #
  153. X    -c    c        /*
  154. X    -f    fortran        [Cc]
  155. X    -mk    make        #
  156. X    -n    nroff        \\"
  157. X    -p    pascal        {
  158. X    -t    troff        \\"
  159. X    -r    ratfor        #
  160. X    -C    any language    next argument
  161. X: .fi
  162. X:
  163. X: .nf
  164. X    suffix    language    comment
  165. X
  166. X    .awk    awk        #
  167. X    .c    c        /*
  168. X    .f    fortran        [Cc]
  169. X    .fh    fortran        [Cc]
  170. X    .h    c        /*
  171. X    .l    lex        /*
  172. X    .man    nroff,troff    \\"
  173. X    .mk    make        #
  174. X    .me    nroff,troff    \\"
  175. X    .ms    nroff,troff    \\"
  176. X    .nr    nroff,troff    \\"
  177. X    .p    pascal        {
  178. X    .ph    pascal        {
  179. X    .r    ratfor        #
  180. X    .rh    ratfor        #
  181. X    .sh    shell        [:#]
  182. X    .y    yacc        /*
  183. X: .fi
  184. X:
  185. X:    The required format of comments is discussed below, where SOC
  186. X:    stands for the start-of-comment symbol of the language being used.
  187. X:
  188. X:    1) Start of manual: SOC, followed by `++'.
  189. X:
  190. X:    2) Section heading: SOC, blank, section name in upper case.
  191. X:
  192. X:    3) New paragraph: empty line or line with SOC only.
  193. X:
  194. X:    4) All other text: SOC and subsequent blanks or tabs are removed.
  195. X:    Lines that do not start with SOC are left unchanged (useful for 
  196. X:    inclusion of program text).
  197. X:
  198. X:    5) End of manual: SOC, followed by `--'.
  199. X:    An end-of-comment may follow if the source file language requires this.
  200. X:
  201. X:    The following manual sections receive a special treatment:
  202. X:    NAME and SUMMARY should appear at the beginning and in
  203. X:    this order; DESCRIPTION, DIAGNOSTICS and BUGS will be
  204. X:    right-margin adjusted.
  205. X:    Other sections may be added freely without confusing srctoman.
  206. X: COMMANDS
  207. X:    sh(1), sed(1), expr(1)
  208. X: SEE ALSO
  209. X:    newsource(1), modsource(1), xman(1)
  210. X:    The earlier commands new(1), mod(1), mkman(1) and dssman(1)
  211. X:    by Ruud Zwart and Ben Noordzij (Erasmus University, Rotterdam) 
  212. X: DIAGNOSTICS
  213. X:    The program complains if an unknown language is specified
  214. X:    or if the language cannot be deduced from the file suffix.
  215. X: AUTHOR(S)
  216. X:    W.Z. Venema
  217. X:    Eindhoven University of Technology
  218. X:    Department of Mathematics and Computer Science
  219. X:    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  220. X: CREATION DATE
  221. X:    Fri Jan 17 22:59:27 MET 1986
  222. X: LAST MODIFICATION
  223. X:    Thu Mar 10 20:08:15 MET 1988
  224. X: VERSION/RELEASE
  225. X:    1.20
  226. X:--
  227. X
  228. X
  229. END_OF_aux/srctoman.sh
  230. if test 4444 -ne `wc -c <aux/srctoman.sh`; then
  231.     echo shar: \"aux/srctoman.sh\" unpacked with wrong size!
  232. fi
  233. # end of overwriting check
  234. fi
  235. if test -f daemon/DAEMON.ins -a "${1}" != "-c" ; then 
  236.   echo shar: Will not over-write existing file \"daemon/DAEMON.ins\"
  237. else
  238. echo shar: Extracting \"daemon/DAEMON.ins\" \(4035 characters\)
  239. sed "s/^X//" >daemon/DAEMON.ins <<'END_OF_daemon/DAEMON.ins'
  240. X@(#) DAEMON.ins 1.3 90/01/06 19:47:10
  241. X
  242. XThis document describes how to install the daemon software on the file
  243. Xserver that exports the per-user mail directories, and how to adapt the
  244. Xlocal sendmail.cf file.
  245. X
  246. XOperation
  247. X=========
  248. X
  249. XThe per-user mail directories are mounted from a file server.  The UUCP
  250. Xfile transfer functions of the pc-mail cico program are taken over by
  251. Xthe following two programs that run on the file server:
  252. X
  253. Xpc-mail:    deliver mail to a user's mail directory (the receiving
  254. X        function of the cico program). This program is intended 
  255. X        to be called by sendmail.
  256. X
  257. Xpc-maild:    scan user mail directories for unsent mail, and pipe it 
  258. X        through the UNIX rmail command (the sending function of 
  259. X        the cico program). This program should be started at
  260. X        system boot time.
  261. X
  262. XAll per-user mail directories live below the pc-mail spool directory
  263. X(/var/spool/pc-mail by default).
  264. X
  265. XBoth programs report all problems via the syslog facility. Most error
  266. Xconditions case the programs to retry at a later time.
  267. X
  268. XInstallation on the server
  269. X==========================
  270. X
  271. XBuild the pc-mail and pc-maild programs.  In the Makefile, you should
  272. Xspecify the location of the executable programs and the pc-mail spool
  273. Xdirectory, and how often the daemon program will scan user directories
  274. Xfor unsent mail.  You will probably have to do a `make depend' before
  275. Xyou can `make' the programs.
  276. X
  277. XExecute the following command to create the pc-mail spool directory, and
  278. Xto install the pc-mail and pc-maild programs.  You must be root.
  279. X
  280. X    % make install
  281. X
  282. XThe output from the "make" command will depend on how you specified the
  283. Xpath names in the Makefile:
  284. X
  285. X    mkdir /var/spool/pc-mail
  286. X    chmod 755 /var/spool/pc-mail
  287. X    cp pc-mail pc-maild /usr/local/lib
  288. X    chown root /usr/local/lib/pc-mail
  289. X    chmod u+s /usr/local/lib/pc-mail
  290. X
  291. XExecute the following command if you wish to install the manual pages.
  292. X
  293. X    % make installman
  294. X
  295. XAgain, the output from make will depend on what you specified in the
  296. XMakefile:
  297. X
  298. X    cp pc-mail.8 pc-maild.8 /usr/local/man/man8
  299. X
  300. XAdd a line with the command
  301. X
  302. X    /usr/local/lib/pc-maild
  303. X
  304. Xto the file /etc/rc.local (the exact name of the rc script depends on
  305. Xyour version of unix, and the exact path name of the pc-maild program
  306. Xdepends on where you installed it).
  307. X
  308. XFor now, you will have to start the pc-maild program by hand (unless
  309. Xyou wish to reboot the machine).
  310. X
  311. XAdd to the sendmail.cf file a line that looks like:
  312. X
  313. X    Mpc,    P=/usr/local/lib/pc-mail, F=lsDFMn, S=xxx, R=yyy, A=pc-mail $u
  314. X
  315. XWhere xxx and yyy may be the same rewriting rules as used for the local
  316. Xmailer (usually defined with the "Mlocal" line). The exact path name of
  317. Xthe pc-mail executable depends on what you specified in the Makefile.
  318. X
  319. XIn the file sendmail.cf, at the end of ruleset S0, but just BEFORE the
  320. Xlocal mailer will be invoked (something like "R$* $#local $:$1"), add a
  321. Xline with
  322. X
  323. X    R $=X            $#pc $:$1
  324. X
  325. XUse a different letter if X is already in use.  
  326. X
  327. XThere are two ways to define X as a list of pc-mail users.  The list can
  328. Xbe wired into the sendmail.cf file, e.g.:
  329. X
  330. X    CXjohn marsha
  331. X
  332. XMultiple usernames on a line, and multiple CX lines are allowed.  
  333. X
  334. XA better way is to have sendmail read the list from an external file, by
  335. Xputting the following line into the sendmail.cf file:
  336. X
  337. X    FX/etc/pc-mail-users %s
  338. X
  339. XThe /etc/pc-mail-users file should contain only a single login name per
  340. Xline.
  341. X
  342. XEach time you change the list of pc-mail users (either in sendmail.cf,
  343. Xor in the /etc/pc-mail-users file) you will have to kill the sendmail
  344. Xdaemon and restart it.
  345. X
  346. XNote that the sendmail program ON THE NFS SERVER will never read the
  347. Xpc-mail user's .forward file.  That file will still be useful, however,
  348. Xif the user's home directory is exported to OTHER hosts running
  349. Xsendmail.  In that case you will want to create a .forward file in the
  350. Xuser's home directory containing
  351. X
  352. X    username@fully-qualified-hostname-of-the-server
  353. X
  354. XThe same effect can be achieved, of course, by adding an entry to the
  355. Xnetwork-wide alias data base:
  356. X
  357. X    username:    username@server
  358. END_OF_daemon/DAEMON.ins
  359. if test 4035 -ne `wc -c <daemon/DAEMON.ins`; then
  360.     echo shar: \"daemon/DAEMON.ins\" unpacked with wrong size!
  361. fi
  362. # end of overwriting check
  363. fi
  364. if test -f daemon/Makefile -a "${1}" != "-c" ; then 
  365.   echo shar: Will not over-write existing file \"daemon/Makefile\"
  366. else
  367. echo shar: Extracting \"daemon/Makefile\" \(4614 characters\)
  368. sed "s/^X//" >daemon/Makefile <<'END_OF_daemon/Makefile'
  369. X# @(#) Makefile 1.7 12/29/89 18:08:05
  370. X
  371. X###############################
  372. X# Start of configurable options. You will also have to do a `make depend'.
  373. X
  374. X# Compiler options.
  375. X# -DSYSV is needed for system 5 release 2
  376. X# -DRFC822 if you want the daemon to produce To: and From: header lines
  377. X# -DSYSEXITS if your system has <sysexits.h>
  378. X# -DSYSLOG if your system has a BSD 4.3-like syslog facility
  379. X# -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\" if you don't have BSD4.3-like syslog
  380. X#    You will also have to create that file, with mode 666.
  381. X#
  382. X#BSD4.X: DEFS = -DRFC822 -DSYSEXITS -DSYSLOG
  383. X#SYSVR2: DEFS = -DRFC822 -DSYSV -DSYSLOGFILE=\"/usr/spool/mqueue/syslog\" 
  384. X
  385. XDEFS    = -DRFC822 -DSYSEXITS -DSYSLOG
  386. X
  387. X# Location of pc-mail spool area
  388. X
  389. XMAILDIR    = /var/spool/pc-mail
  390. X
  391. X# How often the daeman will scan the pc-mail spool area for unsent mail.
  392. X# This time interval can also be changed via the command line.
  393. X
  394. XDELAY    = 30
  395. X
  396. X# Some system-5 implementations have a separate library with BSD-compatible
  397. X# directory access routines.
  398. X#
  399. X#LIBS    = -lndir
  400. X
  401. XLIBS    = 
  402. X
  403. X# Location of the pc-mail en pc-maild binaries
  404. X
  405. XEXEDIR    = /usr/local/lib
  406. X
  407. X# If you want to, where to install the manual pages
  408. X
  409. XMANDIR    = /usr/local/man/man8
  410. X
  411. X# End of configurable options
  412. X#############################
  413. X
  414. XSHELL    = /bin/sh
  415. XCFLAGS    = $(DEFS) -DDELAY=$(DELAY) -DMAILDIR=\"$(MAILDIR)\"
  416. XARCHIVE    = sarch
  417. XSOURCES    = README pc-mail.c pc-maild.c Makefile sysexits.h syslog.h \
  418. X    syslog.c util.c util.h mtime.c mtime.h dosunix.c dosunix.h \
  419. X    percentm.h percentm.c  ms_parse.c ms_parse.h DAEMON.ins
  420. X
  421. XPCMOBJ    = pc-mail.o syslog.o percentm.o dosunix.o ms_parse.o
  422. XPCMSRC    = pc-mail.c syslog.c percentm.c dosunix.c ms_parse.c
  423. X
  424. XPCMDOBJ    = pc-maild.o syslog.o percentm.o dosunix.o util.o mtime.o
  425. XPCMDSRC    = pc-maild.c syslog.c percentm.c dosunix.c util.c mtime.c
  426. X
  427. Xall:    pc-mail pc-maild
  428. X
  429. Xinstall: all
  430. X    -mkdir $(MAILDIR)
  431. X    chmod 755 $(MAILDIR)
  432. X    cp pc-mail pc-maild $(EXEDIR)
  433. X    chown root $(EXEDIR)/pc-mail
  434. X    chmod 4755 $(EXEDIR)/pc-mail
  435. X
  436. Xinstallman: 
  437. X    cp pc-mail.8 pc-maild.8 $(MANDIR)
  438. X
  439. Xpc-mail: $(PCMOBJ)
  440. X    $(CC) $(CFLAGS) -o $@ $(PCMOBJ) $(LIBS)
  441. X
  442. Xpc-maild: $(PCMDOBJ)
  443. X    $(CC) $(CFLAGS) -o $@ $(PCMDOBJ) $(LIBS)
  444. X
  445. Xlint:    lint1 lint2
  446. X
  447. Xlint1:    $(PCMSRC)
  448. X    lint $(CFLAGS) $(PCMSRC)
  449. X
  450. Xlint2:    $(PCMDSRC)
  451. X    lint $(CFLAGS) $(PCMDSRC)
  452. X
  453. Xshar:    $(SOURCES) pc-mail.8 pc-maild.8
  454. X    @shar $(SOURCES) pc-mail.8 pc-maild.8
  455. X
  456. Xclean:
  457. X    rm -f *.o core nohup.out
  458. X
  459. Xclobber: clean
  460. X    rm -f pc-maild pc-mail
  461. X
  462. Xarchive: $(SOURCES)
  463. X    $(ARCHIVE) $?;
  464. X    touch archive
  465. X
  466. Xdepend:    
  467. X    (sed '1,/^# do not edit/!d' Makefile; \
  468. X    for i in [a-z][a-z]*.c; do \
  469. X        $(CC) -E $(CFLAGS) $$i | sed -n '/^# *1 *"\([^"]*\)".*/{;s//'`echo $$i|sed 's/c$$/o/'`':    \1/;p;}'; \
  470. X    done)>$$$$ && mv $$$$ Makefile
  471. X
  472. X# do not edit below this line - it was create with `make depend'
  473. Xdosunix.o:    dosunix.c
  474. Xdosunix.o:    /usr/include/stdio.h
  475. Xdosunix.o:    ./dosunix.h
  476. Xms_parse.o:    ms_parse.c
  477. Xms_parse.o:    /usr/include/stdio.h
  478. Xms_parse.o:    /usr/include/ctype.h
  479. Xms_parse.o:    ./dosunix.h
  480. Xms_parse.o:    ./ms_parse.h
  481. Xmtime.o:    mtime.c
  482. Xmtime.o:    /usr/include/syslog.h
  483. Xmtime.o:    ./mtime.h
  484. Xpc-mail.o:    pc-mail.c
  485. Xpc-mail.o:    /usr/include/stdio.h
  486. Xpc-mail.o:    /usr/include/sys/types.h
  487. Xpc-mail.o:    /usr/include/sys/sysmacros.h
  488. Xpc-mail.o:    /usr/include/sys/stat.h
  489. Xpc-mail.o:    /usr/include/pwd.h
  490. Xpc-mail.o:    /usr/include/varargs.h
  491. Xpc-mail.o:    /usr/include/syslog.h
  492. Xpc-mail.o:    /usr/include/sys/dir.h
  493. Xpc-mail.o:    /usr/include/sysexits.h
  494. Xpc-mail.o:    ./dosunix.h
  495. Xpc-mail.o:    ./percentm.h
  496. Xpc-mail.o:    ./ms_parse.h
  497. Xpc-maild.o:    pc-maild.c
  498. Xpc-maild.o:    /usr/include/stdio.h
  499. Xpc-maild.o:    /usr/include/pwd.h
  500. Xpc-maild.o:    /usr/include/time.h
  501. Xpc-maild.o:    /usr/include/signal.h
  502. Xpc-maild.o:    /usr/include/vm/faultcode.h
  503. Xpc-maild.o:    /usr/include/sys/types.h
  504. Xpc-maild.o:    /usr/include/sys/sysmacros.h
  505. Xpc-maild.o:    /usr/include/sys/stat.h
  506. Xpc-maild.o:    /usr/include/syslog.h
  507. Xpc-maild.o:    /usr/include/sys/types.h
  508. Xpc-maild.o:    /usr/include/sys/dir.h
  509. Xpc-maild.o:    /usr/include/sgtty.h
  510. Xpc-maild.o:    /usr/include/sys/ioctl.h
  511. Xpc-maild.o:    /usr/include/sys/ttychars.h
  512. Xpc-maild.o:    /usr/include/sys/ttydev.h
  513. Xpc-maild.o:    /usr/include/sys/ttold.h
  514. Xpc-maild.o:    /usr/include/sys/ioccom.h
  515. Xpc-maild.o:    /usr/include/sys/ttycom.h
  516. Xpc-maild.o:    /usr/include/sys/filio.h
  517. Xpc-maild.o:    /usr/include/sys/ioccom.h
  518. Xpc-maild.o:    /usr/include/sys/sockio.h
  519. Xpc-maild.o:    /usr/include/sys/ioccom.h
  520. Xpc-maild.o:    ./dosunix.h
  521. Xpc-maild.o:    ./util.h
  522. Xpc-maild.o:    ./mtime.h
  523. Xpercentm.o:    percentm.c
  524. Xpercentm.o:    /usr/include/stdio.h
  525. Xpercentm.o:    ./percentm.h
  526. Xsyslog.o:    syslog.c
  527. Xutil.o:    util.c
  528. Xutil.o:    /usr/include/stdio.h
  529. Xutil.o:    /usr/include/pwd.h
  530. Xutil.o:    /usr/include/sys/types.h
  531. Xutil.o:    /usr/include/sys/sysmacros.h
  532. Xutil.o:    /usr/include/sys/dir.h
  533. Xutil.o:    /usr/include/syslog.h
  534. Xutil.o:    ./util.h
  535. END_OF_daemon/Makefile
  536. if test 4614 -ne `wc -c <daemon/Makefile`; then
  537.     echo shar: \"daemon/Makefile\" unpacked with wrong size!
  538. fi
  539. # end of overwriting check
  540. fi
  541. if test -f daemon/ms_parse.c -a "${1}" != "-c" ; then 
  542.   echo shar: Will not over-write existing file \"daemon/ms_parse.c\"
  543. else
  544. echo shar: Extracting \"daemon/ms_parse.c\" \(4182 characters\)
  545. sed "s/^X//" >daemon/ms_parse.c <<'END_OF_daemon/ms_parse.c'
  546. X/*++
  547. X/* NAME
  548. X/*      ms_parse 3
  549. X/* SUMMARY
  550. X/*      message parser
  551. X/* PROJECT
  552. X/*      pc-mail
  553. X/* PACKAGE
  554. X/*    nfs
  555. X/* SYNOPSIS
  556. X/*    #include "ms_parse.h"
  557. X/*
  558. X/*    int ms_parse(context, line)
  559. X/*    int context;
  560. X/*    char *line;
  561. X/*
  562. X/*    int hscanf(line, prefix, format, result)
  563. X/*    char *line;
  564. X/*    char *prefix;
  565. X/*    char *format;
  566. X/*    char *result;
  567. X/* DESCRIPTION
  568. X/*    The routines in this module recognize
  569. X/*    the context in which successive lines of text occur within an
  570. X/*    e-mail message, or extract specific information from header
  571. X/*    lines.
  572. X/*
  573. X/*    The expected format of an e-mail message is: UUCP header lines,
  574. X/*    RFC822-like header lines, message body. Each of these sections
  575. X/*    may be missing from the message. A header line is a line that
  576. X/*    has no blanks before the first colon appearing on that line.
  577. X/*
  578. X/*    ms_parse() determines the context in which a line of text was found:
  579. X/*
  580. X/* .nf
  581. X    MS_UUCP        UUCP-style From_ line
  582. X    MS_HEADER    RFC822-like header line
  583. X    MS_CONT        Continued header line
  584. X    MS_BODY        Line within message body
  585. X/* .fi
  586. X/*
  587. X/*    The context argument should have the value MS_UUCP in the initial
  588. X/*    call of ms_parse(). Upon successive calls the value should be equal
  589. X/*    to the last value returned by ms_parse().
  590. X/*
  591. X/*    hscanf() compares the beginning of a line with the specified prefix
  592. X/*    (ignoring case differences), and if the comparison succeeds, it
  593. X/*    invokes sscanf() on the remainder of that line. A zero return value
  594. X/*    means that no information was extracted with sscanf.
  595. X/* AUTHOR(S)
  596. X/*      W.Z. Venema
  597. X/*      Eindhoven University of Technology
  598. X/*      Department of Mathematics and Computer Science
  599. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  600. X/* CREATION DATE
  601. X/*    Sat Dec  9 18:50:35 MET 1989
  602. X/* LAST MODIFICATION
  603. X/*    1/6/90 19:45:16
  604. X/* VERSION/RELEASE
  605. X/*    1.7
  606. X/*--*/
  607. X
  608. X#include <stdio.h>
  609. X#include <ctype.h>
  610. X
  611. X#include "ms_parse.h"
  612. X
  613. Xextern char *strchr();
  614. X
  615. X/* forward declarations */
  616. X
  617. Xstatic int isheader();
  618. Xstatic int istrncmp();
  619. X
  620. X/* hscanf - match header and extract info from remainder of header line */
  621. X
  622. Xint     hscanf(line, pre, fmt, ptr)
  623. Xchar   *line;
  624. Xchar   *pre;
  625. Xchar   *fmt;
  626. Xchar   *ptr;
  627. X{
  628. X    int     len = strlen(pre);
  629. X
  630. X    return (istrncmp(pre, line, len) == 0 && sscanf(line + len, fmt, ptr) == 1);
  631. X}
  632. X
  633. X/* ms_parse - parse one message line */
  634. X
  635. Xint     ms_parse(context, line)
  636. Xregister int context;
  637. Xregister char *line;
  638. X{
  639. X
  640. X    /*
  641. X     * A message may begin with UUCP header lines ("From blablabla",
  642. X     * sometimes escaped with a ">" character), followed by RFC822-like
  643. X     * header lines (lines that start with a word + colon, or continuation
  644. X     * lines that start with whitespace), followed by the remainder of the
  645. X     * message. Header and body are usually separated by an empty line (on
  646. X     * systems that can handle that) but the we do not require this.
  647. X     */
  648. X
  649. X    switch (context) {
  650. X    case MS_UUCP:
  651. X    if (line[0] == '>' || strncmp(line, "From ", 5) == 0)
  652. X        return (MS_UUCP);
  653. X    if (isspace(line[0]))
  654. X        return (MS_BODY);
  655. X    /* FALLTHROUGH */
  656. X    case MS_HEADER:
  657. X    case MS_CONT:
  658. X    if (isspace(line[0]))
  659. X        return (MS_CONT);
  660. X    if (isheader(line))
  661. X        return (MS_HEADER);
  662. X    /* FALLTHROUGH */
  663. X    case MS_BODY:
  664. X    return (MS_BODY);
  665. X    }
  666. X    /* NOTREACHED */
  667. X}
  668. X
  669. X/* isheader - does this line look like a header? */
  670. X
  671. Xstatic int isheader(buf)
  672. Xchar   *buf;
  673. X{
  674. X    static char blanks[] = " \t\f";
  675. X    char   *cp;
  676. X    char   *blk;
  677. X    char   *colon;
  678. X
  679. X    /*
  680. X     * A header line has no blanks before the first colon. Which means that a
  681. X     * line that starts with a colon character is treated as header line.
  682. X     * This turns out to be what many sendmail implementations do, too.
  683. X     */
  684. X
  685. X    if ((colon = strchr(buf, ':')) == 0) {    /* check for colon */
  686. X    return (0);
  687. X    } else {                    /* find preceding blanks */
  688. X    for (cp = blanks; *cp; cp++)
  689. X        if ((blk = strchr(buf, *cp)) != 0 && blk < colon)
  690. X        return (0);
  691. X    }
  692. X    return (1);
  693. X}
  694. X
  695. X#define    low(x)    ((isascii(x) && isupper(x)) ? tolower(x) : (x))
  696. X
  697. X/* istrncmp - case-insensitive strncmp */
  698. X
  699. Xstatic int istrncmp(s1, s2, len)
  700. Xchar   *s1;
  701. Xchar   *s2;
  702. Xint     len;
  703. X{
  704. X    while (len > 0 && *s1 && *s2 && low(*s1) == low(*s2))
  705. X    len--, s1++, s2++;
  706. X    return (len > 0 ? low(*s1) - low(*s2) : 0);
  707. X}
  708. END_OF_daemon/ms_parse.c
  709. if test 4182 -ne `wc -c <daemon/ms_parse.c`; then
  710.     echo shar: \"daemon/ms_parse.c\" unpacked with wrong size!
  711. fi
  712. # end of overwriting check
  713. fi
  714. if test -f main/Implement -a "${1}" != "-c" ; then 
  715.   echo shar: Will not over-write existing file \"main/Implement\"
  716. else
  717. echo shar: Extracting \"main/Implement\" \(4560 characters\)
  718. sed "s/^X//" >main/Implement <<'END_OF_main/Implement'
  719. X@(#) Implement 2.1 90/01/22 13:01:08
  720. X
  721. XThis document describes some implementation aspects of the pc-mail
  722. Xsoftware.
  723. X
  724. XMESSAGE DATA BASE
  725. X
  726. XThe message data base resides in the mail  spool  directory  (de-
  727. Xfined  with  the MAILDIR environment variable). There are various
  728. Xclasses of message files:
  729. X
  730. X - mail received from the network
  731. X
  732. X - mail ready to send over the network
  733. X
  734. X - messages in preparation
  735. X
  736. X - mail that has been sent
  737. X
  738. XIn addition there are administrative files (LOGFILE,  alias  data
  739. Xbase and communications parameters). Optional files  are:  header
  740. X(with  template  message  header)  and  trailer  (with the user's
  741. Xsignature).
  742. X
  743. XEach message takes two files: a data file (with the  actual  mes-
  744. Xsage)  and a meta file (with on the  first  line:  originator  or
  745. Xdestination addresses, or a one-line summary in case of a message
  746. Xin preparation; and on the second line: a subject).
  747. X
  748. XData/meta file names are constructed by concatenating  a  single-
  749. Xcharacter prefix with a five-digit sequence number. Corresponding
  750. Xdata and meta files have the same  sequence  number.  The  prefix
  751. Xcharacters are:
  752. X
  753. X E message in preparation
  754. X C description of message
  755. X
  756. X N message received from the net
  757. X H originator address and subject in case of an unread message
  758. X O originator address and subject in case of already read message
  759. X
  760. X D message ready to be sent over the net
  761. X X destination of that message and subject
  762. X
  763. X Q message already sent over the net
  764. X R destination of that message and subject
  765. X
  766. XAdministrative files are
  767. X
  768. X LOGFILE transaction log
  769. X s00000 communications parameters
  770. X a00000 alias data base
  771. X
  772. XAll files in the mail directory are ordinary text files,  with  a
  773. Xpossible  exception  for the message in preparation (this depends
  774. Xon the editor being used).
  775. X
  776. XFiles in the  mail  directory  are  normally  write-protected  to
  777. Xprevent accidents.
  778. X
  779. XThe length of lines in the "meta" files is  at  most  1024  bytes
  780. X(see the MAXLINE macro in the file defs.h).
  781. X
  782. XMost mailers will object to messages with lines longer than about
  783. X132 characters.
  784. X
  785. XHOW THE PROGRAMS OPERATE
  786. X
  787. XThe message data base is shared by  several  programs.  First  of
  788. Xall, there is the mail program itself that provides the main user
  789. Xinterface. Other programs are: cico (takes unsent  messages  from
  790. Xthe mail data base, and changes their status to "sent" after they
  791. Xhave been sent over the network), smail  (queues  a  message  for
  792. Xtransmission  by  the  cico  program), rmail (extracts originator
  793. Xnames and subject information from messages received by the  cico
  794. Xprogram)  and  cmail  (scans  the  mail  data  base  for   unread
  795. Xmessages).  If  the mail directory is mounted from a file server,
  796. Xthe cico program is not used; instead, its task is  performed  by
  797. Xthe  pc-mail  and  pc-maild  daemon programs that run on the file
  798. Xserver.
  799. X
  800. XThe following picture shows how the programs interact  with  each
  801. Xother, and with the mail data base.
  802. X
  803. X-----------------------------------------------------------------
  804. Xprogram    |purpose            |invokes
  805. X--------+-------------------------------+--------------------------
  806. Xmail    |main user interface        |cico, smail, rmail, editor
  807. X    |                |
  808. Xcico    |file transfer program        |none; invoked by mail, cmail
  809. X    |                |
  810. Xsmail    |queue file for transmission    |none; invoked by mail
  811. X    |                |
  812. Xrmail    |extract sender and subject    |none; invoked by mail, cmail
  813. X    |                |
  814. Xcmail    |search for unread mail        |none
  815. X--------+-------------------------------+--------------------------
  816. Xpc-mail    |deliver mail (on file server)    |none; invoked by sendmail
  817. X    |                |
  818. Xpc-maild|send mail (on file server)    |/usr/bin/rmail
  819. X-------------------------------------------------------------------
  820. X
  821. XUUCP FUNCTIONALITY
  822. X
  823. XThe cico program provided here supports a subset of the uucp file
  824. Xexchange  facilities,  just  enough  to  interface to the message
  825. Xdatabase structure (spool directory) described  in  the  previous
  826. Xsection.
  827. X
  828. XThe main differences with the unix uucico program are:
  829. X
  830. X- No  support  for  C  (command)  files.  cico  scans  the  spool
  831. Xdirectory for message and destination files instead.
  832. X
  833. X- Only the H  (hangup),  S  (send)  and  C  (copy)  requests  are
  834. Xsupported.  R  (receive)  requests  are  not allowed.  Sending or
  835. Xreceiving files by path name is rarely allowed anyway, and  works
  836. Xonly  between  adjacent  uucp  nodes.  This  is  only   a   minor
  837. Xlimitation; files can still be sent as mail messages.
  838. X
  839. X- The cico program assumes that all incoming D (data)  files  are
  840. Xmail messages.
  841. X
  842. X- The cico program ignores incoming X (execute)  files.  X  files
  843. Xnormally contain the commands to dispose of D (data) files.
  844. X
  845. END_OF_main/Implement
  846. if test 4560 -ne `wc -c <main/Implement`; then
  847.     echo shar: \"main/Implement\" unpacked with wrong size!
  848. fi
  849. # end of overwriting check
  850. fi
  851. if test -f main/invoke.c -a "${1}" != "-c" ; then 
  852.   echo shar: Will not over-write existing file \"main/invoke.c\"
  853. else
  854. echo shar: Extracting \"main/invoke.c\" \(4246 characters\)
  855. sed "s/^X//" >main/invoke.c <<'END_OF_main/invoke.c'
  856. X/*++
  857. X/* NAME
  858. X/*      invoke 3
  859. X/* SUMMARY
  860. X/*      system-dependent process control stuff
  861. X/* PROJECT
  862. X/*      pc-mail
  863. X/* PACKAGE
  864. X/*      mailsh
  865. X/* SYNOPSIS
  866. X/*      #include "status.h"
  867. X/*
  868. X/*    int invokelp(arg0,arg1,...)
  869. X/*      char *arg0,*arg1,...
  870. X/*
  871. X/*    int invokevp(argv)
  872. X/*    char **argv;
  873. X/* DESCRIPTION
  874. X/*      invokelp() creates a child process to execute a command.
  875. X/*      arg0, arg1,... is a null-terminated list of string pointers,
  876. X/*    the first being the name of the program. Use is made
  877. X/*    of the search path to locate the program in arg0.
  878. X/*    With MS-DOS, batch files can only be executed if their name is
  879. X/*    given including the suffix.
  880. X/*
  881. X/*    invokevp() is similar to invokelp; the difference is that
  882. X/*    argv is an array of pointers to arguments, and that MS-DOS batch
  883. X/*    files are not supported.
  884. X/* DIAGNOSTICS
  885. X/*    invokelp(), invokevp() return the exit status of the child process,
  886. X/*    E_SYSFAIL if there were insufficient resources, and
  887. X/*    E_NOPROG if the program in arg0 or argv[0] could not be found.
  888. X/* BUGS
  889. X/*    The invokexx() functions should not be used if the command involves
  890. X/*    shell built-ins, i/o redirection or other shell meta characters.
  891. X/* AUTHOR(S)
  892. X/*      W.Z. Venema
  893. X/*      Eindhoven University of Technology
  894. X/*      Department of Mathematics and Computer Science
  895. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  896. X/* CREATION DATE
  897. X/*      Sun Apr  5 15:27:37 GMT+1:00 1987
  898. X/* LAST MODIFICATION
  899. X/*    90/01/22 13:01:50
  900. X/* VERSION/RELEASE
  901. X/*    2.1
  902. X/*--*/
  903. X
  904. X#include <stdio.h>
  905. X#include <varargs.h>
  906. X#include <errno.h>
  907. X
  908. X#include "defs.h"
  909. X#include "status.h"
  910. X
  911. X#ifdef  MSDOS
  912. X#include <process.h>
  913. X#endif
  914. X
  915. X/* invokelp - create child process to execute command */
  916. X
  917. X/* VARARGS */
  918. X
  919. Xpublic int invokelp(va_alist) 
  920. Xva_dcl
  921. X{
  922. X    va_list ap;
  923. X#ifdef lint
  924. X     static
  925. X#endif
  926. X    char   *argv[BUFSIZ];
  927. X    char  **cpp = argv;
  928. X#ifdef    MSDOS
  929. X    char   *cp;
  930. X
  931. X    /*
  932. X     * Under MS-DOS, we must explicitly invoke a command processor in case of
  933. X     * batch files. If we see the command is a batch file we just stick a
  934. X     * command processor invocation in front of the argument vector. We try
  935. X     * to avoid the command processor since it presently does not return exit
  936. X     * status codes.
  937. X     */
  938. X
  939. X    va_start(ap);
  940. X    cp = va_arg(ap, char *);
  941. X    if (istrcmp(cp + strlen(cp) - 4, ".bat") == 0) {
  942. X    *cpp++ = "command";
  943. X    *cpp++ = "/c";
  944. X    }
  945. X    va_end(ap);
  946. X#endif
  947. X
  948. X    /* Copy variable-length argument list to variable-length vector */
  949. X
  950. X    va_start(ap);
  951. X    while (*cpp++ = va_arg(ap, char *))
  952. X     /* void */ ;
  953. X    va_end(ap);
  954. X
  955. X    /* invokevp will do the rest */
  956. X
  957. X    return (invokevp(argv));
  958. X
  959. X#if (!defined(unix) && !defined(MSDOS))
  960. X    "Specify how to do process management"
  961. X#endif
  962. X}
  963. X
  964. X/* invokevp - create child process to execute command */
  965. X
  966. Xpublic int invokevp(argv)
  967. Xchar  **argv;
  968. X{
  969. X    extern void _exit();
  970. X
  971. X    /*
  972. X     * On unix systems we fork a process and overlay the child with the
  973. X     * desired program. This means we get -1 if the fork did not succeed,
  974. X     * otherwise the exit status of the child process. The code is a bit
  975. X     * elaborate since we want to handle various error conditions.
  976. X     */
  977. X#ifdef unix
  978. X    register int pid;
  979. X
  980. X    if ((pid = fork()) < 0) {            /* fork off a process */
  981. X    return (E_SYSFAIL);            /* resources exhausted */
  982. X    } else if (pid == 0) {            /* this is the child process */
  983. X    (void) execvp(*argv, argv);        /* try to replace it */
  984. X    _exit(errno == ENOENT ? E_NOPROG : E_SYSFAIL);    /* sorry, failed */
  985. X    /* NOTREACHED */
  986. X    } else {                    /* this is the parent */
  987. X    int     xstat,
  988. X            wstat;
  989. X
  990. X    /* wait till above child terminates */
  991. X
  992. X    while ((wstat = wait(&xstat)) != -1 && wstat != pid)
  993. X         /* void */ ;
  994. X    if (wstat == -1) {
  995. X        return (E_SYSFAIL);            /* oops: no child! */
  996. X    } else if (xstat & 0377) {
  997. X        return (E_UNKNOWN);            /* child was killed */
  998. X    } else {
  999. X        return (xstat >> 8);        /* child died naturally */
  1000. X    }
  1001. X    /* NOTREACHED */
  1002. X    }
  1003. X#endif
  1004. X
  1005. X    /*
  1006. X     * With MS-DOS, less can go wrong. On the other hand, MS-DOS can do less.
  1007. X     */
  1008. X#ifdef MSDOS
  1009. X    int     stat;
  1010. X
  1011. X    return ((stat = spawnvp(P_WAIT, *argv, argv)) >= 0 ?
  1012. X        stat : (errno == ENOENT ? E_NOPROG : E_SYSFAIL));
  1013. X#endif
  1014. X
  1015. X#if (!defined(unix) && !defined(MSDOS))
  1016. X    "Specify how to do process management"
  1017. X#endif
  1018. X}
  1019. END_OF_main/invoke.c
  1020. if test 4246 -ne `wc -c <main/invoke.c`; then
  1021.     echo shar: \"main/invoke.c\" unpacked with wrong size!
  1022. fi
  1023. # end of overwriting check
  1024. fi
  1025. if test -f main/msd_dir.c -a "${1}" != "-c" ; then 
  1026.   echo shar: Will not over-write existing file \"main/msd_dir.c\"
  1027. else
  1028. echo shar: Extracting \"main/msd_dir.c\" \(4738 characters\)
  1029. sed "s/^X//" >main/msd_dir.c <<'END_OF_main/msd_dir.c'
  1030. X#ifdef    MSDOS
  1031. X/*
  1032. X * @(#)msd_dir.c 1.4 87/11/06    Public Domain.
  1033. X *
  1034. X *  A public domain implementation of BSD directory routines for
  1035. X *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  1036. X *  August 1897
  1037. X *
  1038. X * Return file names in lower case W.Z. Venema (wswietse@lso.win.tue.nl)
  1039. X * Aug 1988
  1040. X *
  1041. X * Added special-case code for the root directory WZV 891218
  1042. X */
  1043. X
  1044. X#include    <sys/types.h>
  1045. X#include    <sys/stat.h>
  1046. X#include    "msd_dir.h"    /* was: <sys/dir.h> */
  1047. X#include    <malloc.h>
  1048. X#include    <string.h>
  1049. X#include    <dos.h>
  1050. X#include    <ctype.h>    /* for upper->lower case code */
  1051. X
  1052. X#ifndef    NULL
  1053. X# define    NULL    0
  1054. X#endif    /* NULL */
  1055. X
  1056. X#ifndef    MAXPATHLEN
  1057. X# define    MAXPATHLEN    255
  1058. X#endif    /* MAXPATHLEN */
  1059. X
  1060. X/* attribute stuff */
  1061. X#define    A_RONLY        0x01
  1062. X#define    A_HIDDEN    0x02
  1063. X#define    A_SYSTEM    0x04
  1064. X#define    A_LABEL        0x08
  1065. X#define    A_DIR        0x10
  1066. X#define    A_ARCHIVE    0x20
  1067. X
  1068. X/* dos call values */
  1069. X#define    DOSI_FINDF    0x4e
  1070. X#define    DOSI_FINDN    0x4f
  1071. X#define    DOSI_SDTA    0x1a
  1072. X
  1073. X#define    Newisnull(a, t)        ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  1074. X#define    ATTRIBUTES        (A_DIR | A_HIDDEN | A_SYSTEM)
  1075. X
  1076. X/* what find first/next calls look use */
  1077. Xtypedef struct {
  1078. X    char        d_buf[21];
  1079. X    char        d_attribute;
  1080. X    unsigned short    d_time;
  1081. X    unsigned short    d_date;
  1082. X    long        d_size;
  1083. X    char        d_name[13];
  1084. X} Dta_buf;
  1085. X
  1086. Xstatic    char    *getdirent();
  1087. Xstatic    void    setdta();
  1088. Xstatic    void    free_dircontents();
  1089. X
  1090. Xstatic    Dta_buf        dtabuf;
  1091. Xstatic    Dta_buf        *dtapnt = &dtabuf;
  1092. Xstatic    union REGS    reg, nreg;
  1093. X
  1094. X#if    defined(M_I86LM)
  1095. Xstatic    struct SREGS    sreg;
  1096. X#endif
  1097. X
  1098. Xstatic char *Strcpy();    /* lower-case copy */
  1099. X
  1100. XDIR    *
  1101. Xopendir(name)
  1102. X    char    *name;
  1103. X{
  1104. X    struct    stat        statb;
  1105. X    DIR            *dirp;
  1106. X    char            c;
  1107. X    char            *s;
  1108. X    struct _dircontents    *dp;
  1109. X    char            nbuf[MAXPATHLEN + 1];
  1110. X    
  1111. X    /* 
  1112. X     * Need special-case code for ".", to avoid problems with stat()
  1113. X     * in the root directory -- WZV 891218
  1114. X     */
  1115. X
  1116. X    if (strcmp(name, ".") != 0 
  1117. X    && (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR))
  1118. X        return (DIR *) NULL;
  1119. X    if (Newisnull(dirp, DIR))
  1120. X        return (DIR *) NULL;
  1121. X    if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  1122. X        (void) strcat(strcpy(nbuf, name), "\\*.*");
  1123. X    else
  1124. X        (void) strcat(strcpy(nbuf, name), "*.*");
  1125. X    dirp->dd_loc = 0;
  1126. X    setdta();
  1127. X    dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  1128. X    if ((s = getdirent(nbuf)) == (char *) NULL)
  1129. X        return dirp;
  1130. X    do {
  1131. X        if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  1132. X            malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  1133. X        {
  1134. X            if (dp)
  1135. X                free((char *) dp);
  1136. X            free_dircontents(dirp->dd_contents);
  1137. X            return (DIR *) NULL;
  1138. X        }
  1139. X        if (dirp->dd_contents)
  1140. X            dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  1141. X        else
  1142. X            dirp->dd_contents = dirp->dd_cp = dp;
  1143. X        (void) strcpy(dp->_d_entry, s);
  1144. X        dp->_d_next = (struct _dircontents *) NULL;
  1145. X    } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  1146. X    dirp->dd_cp = dirp->dd_contents;
  1147. X
  1148. X    return dirp;
  1149. X}
  1150. X
  1151. Xvoid
  1152. Xclosedir(dirp)
  1153. X    DIR    *dirp;
  1154. X{
  1155. X    free_dircontents(dirp->dd_contents);
  1156. X    free((char *) dirp);
  1157. X}
  1158. X
  1159. Xstruct direct    *
  1160. Xreaddir(dirp)
  1161. X    DIR    *dirp;
  1162. X{
  1163. X    static    struct direct    dp;
  1164. X    
  1165. X    if (dirp->dd_cp == (struct _dircontents *) NULL)
  1166. X        return (struct direct *) NULL;
  1167. X    dp.d_namlen = dp.d_reclen =
  1168. X        strlen(Strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  1169. X    dp.d_ino = 0;
  1170. X    dirp->dd_cp = dirp->dd_cp->_d_next;
  1171. X    dirp->dd_loc++;
  1172. X
  1173. X    return &dp;
  1174. X}
  1175. X
  1176. Xvoid
  1177. Xseekdir(dirp, off)
  1178. X    DIR    *dirp;
  1179. X    long    off;
  1180. X{
  1181. X    long            i = off;
  1182. X    struct _dircontents    *dp;
  1183. X
  1184. X    if (off < 0)
  1185. X        return;
  1186. X    for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  1187. X        ;
  1188. X    dirp->dd_loc = off - (i + 1);
  1189. X    dirp->dd_cp = dp;
  1190. X}
  1191. X
  1192. Xlong
  1193. Xtelldir(dirp)
  1194. X    DIR    *dirp;
  1195. X{
  1196. X    return dirp->dd_loc;
  1197. X}
  1198. X
  1199. Xstatic    void
  1200. Xfree_dircontents(dp)
  1201. X    struct    _dircontents    *dp;
  1202. X{
  1203. X    struct _dircontents    *odp;
  1204. X
  1205. X    while (dp) {
  1206. X        if (dp->_d_entry)
  1207. X            free(dp->_d_entry);
  1208. X        dp = (odp = dp)->_d_next;
  1209. X        free((char *) odp);
  1210. X    }
  1211. X}
  1212. X
  1213. Xstatic    char    *
  1214. Xgetdirent(dir)
  1215. X    char    *dir;
  1216. X{
  1217. X    if (dir != (char *) NULL) {        /* get first entry */
  1218. X        reg.h.ah = DOSI_FINDF;
  1219. X        reg.h.cl = ATTRIBUTES;
  1220. X#if    defined(M_I86LM)
  1221. X        reg.x.dx = FP_OFF(dir);
  1222. X        sreg.ds = FP_SEG(dir);
  1223. X#else
  1224. X        reg.x.dx = (unsigned) dir;
  1225. X#endif
  1226. X    } else {                /* get next entry */
  1227. X        reg.h.ah = DOSI_FINDN;
  1228. X#if    defined(M_I86LM)
  1229. X        reg.x.dx = FP_OFF(dtapnt);
  1230. X        sreg.ds = FP_SEG(dtapnt);
  1231. X#else
  1232. X        reg.x.dx = (unsigned) dtapnt;
  1233. X#endif
  1234. X    }
  1235. X#if    defined(M_I86LM)
  1236. X    intdosx(®, &nreg, &sreg);
  1237. X#else
  1238. X    intdos(®, &nreg);
  1239. X#endif
  1240. X    if (nreg.x.cflag)
  1241. X        return (char *) NULL;
  1242. X
  1243. X    return dtabuf.d_name;
  1244. X}
  1245. X
  1246. Xstatic    void
  1247. Xsetdta()
  1248. X{
  1249. X    reg.h.ah = DOSI_SDTA;
  1250. X#if    defined(M_I86LM)
  1251. X    reg.x.dx = FP_OFF(dtapnt);
  1252. X    sreg.ds = FP_SEG(dtapnt);
  1253. X    intdosx(®, &nreg, &sreg);
  1254. X#else
  1255. X    reg.x.dx = (int) dtapnt;
  1256. X    intdos(®, &nreg);
  1257. X#endif
  1258. X}
  1259. X
  1260. Xstatic char *Strcpy(to,from)
  1261. Xregister char *to,*from;
  1262. X{
  1263. X    register int c;
  1264. X    char *start = to;
  1265. X
  1266. X    while (*to++ = (islower(c = *from++) ? c : tolower(c)))
  1267. X    ;
  1268. X    return(start);
  1269. X}
  1270. X#endif
  1271. END_OF_main/msd_dir.c
  1272. if test 4738 -ne `wc -c <main/msd_dir.c`; then
  1273.     echo shar: \"main/msd_dir.c\" unpacked with wrong size!
  1274. fi
  1275. # end of overwriting check
  1276. fi
  1277. if test -f main/screen.h -a "${1}" != "-c" ; then 
  1278.   echo shar: Will not over-write existing file \"main/screen.h\"
  1279. else
  1280. echo shar: Extracting \"main/screen.h\" \(4726 characters\)
  1281. sed "s/^X//" >main/screen.h <<'END_OF_main/screen.h'
  1282. X/*++
  1283. X/* NAME
  1284. X/*    screen
  1285. X/* SUMMARY
  1286. X/*    structure of mail shell command windows
  1287. X/* PROJECT
  1288. X/*    pc-mail
  1289. X/* PACKAGE
  1290. X/*    mail
  1291. X/* SYNOPSIS
  1292. X/*    #include "screen.h"
  1293. X/* DESCRIPTION
  1294. X/*    The data structures in this file are used by the interactive shell to 
  1295. X/*    define what a screen looks like, and what commands the user can give.
  1296. X/*
  1297. X/*    For each screen, one has to define a table of (selector, command name, 
  1298. X/*    help string, and function pointer) tuples.
  1299. X/*    The command names are listed in the top window. If the user enters
  1300. X/*    the type of input specified by the selector, the associated function
  1301. X/*    is called. A null function pointer means go back to the calling screen. 
  1302. X/*
  1303. X/*    The table is terminated with a null selector entry; its help 
  1304. X/*    string is displayed in the bottom window (as a prompt), and the 
  1305. X/*    associated function is invoked upon entry of the screen.
  1306. X/*
  1307. X/*    The return value of an action function determines what happens next.
  1308. X/*    An action function can signal an error condition, that the screen
  1309. X/*    needs to be redrawn, and whether the calling screen should terminate.
  1310. X/*
  1311. X/*    User input can be of various forms: single-character, string or
  1312. X/*    escape/enter.
  1313. X/*
  1314. X/*    In case of single-character input the selector fields should contain 
  1315. X/*    for each key the (upper case) key code,
  1316. X/*    a label that is displayed at the top of the screen, and a help
  1317. X/*    text that explains the key's function. 
  1318. X/*
  1319. X/*    In case of string input the associated function is called with the 
  1320. X/*    string input as argument. If that function returns an error status the
  1321. X/*    text in the help field is printed in the error window and the 
  1322. X/*    user is given another chance.
  1323. X/*
  1324. X/*    An alternative form of string input takes the text from the help field
  1325. X/*    as default input, and allows the user to edit that. Otherwise the
  1326. X/*    same functions are performed as with ordinary string input.
  1327. X/*
  1328. X/*    A third form of string input only accepts yes or no. The action
  1329. X/*    function is called with an integer argument (1 = yes, 0 = no).
  1330. X/*
  1331. X/*    In case of escape/enter the interpreter invokes the action function when
  1332. X/*    the user presses enter, and does nothing when escape is pressed. 
  1333. X/* .nf
  1334. X
  1335. X /* there is a Screen structure for each command for each screen */
  1336. X
  1337. Xtypedef struct {
  1338. X    short   key;            /* type of input */
  1339. X    char   *name;            /* key label (for top window) */
  1340. X    int   (*action) ();            /* action when command is selected */
  1341. X    char   *help;            /* explanation (for H command) */
  1342. X} Screen;
  1343. X
  1344. X /* action function return masks */
  1345. X
  1346. X#define    S_BREAK        1        /* return immediately after action */
  1347. X#define    S_REDRAW    2        /* redraw screen */
  1348. X#define    S_ERROR        4        /* action failed */
  1349. X
  1350. X /* input types: ordinary character keys are encoded as themselves */
  1351. X
  1352. X#define    CTL(x)    (x ^ 0100)        /* ASCII control code */
  1353. X#define    BS    CTL('H')
  1354. X#define    ENTER    CTL('M')
  1355. X#define    CTLU    CTL('U')
  1356. X#define    ESC    CTL('[')
  1357. X#define    DEL    CTL('?')
  1358. X
  1359. X#define    ANY    256            /* press any key */
  1360. X#define    UP    257            /* up-arrow key */
  1361. X#define    DOWN    258            /* down-arrow key */
  1362. X#define    LEFT    259            /* left-arrow key */
  1363. X#define    RIGHT    260            /* right-arrow key */
  1364. X#define    PGUP    261            /* page-up */
  1365. X#define    PGDN    262            /* page-down */
  1366. X#define    STRING    263            /* string input, ESC to quit */
  1367. X#define    ESCCR    264            /* CR to confirm, ESC to quit */
  1368. X#define    EDIT    265            /* edit string, ESC to quit */
  1369. X#define    YESNO    266            /* yes or no, ESC to quit */
  1370. X
  1371. X#define    iskey(key)    (key > 0 && key < STRING)
  1372. X
  1373. X /* system-dependent function-key labels */
  1374. X
  1375. X#ifdef unix
  1376. X#   define PgUp    "F1"
  1377. X#   define PgDn "F2"
  1378. X#endif
  1379. X
  1380. X#ifdef MSDOS
  1381. X#   define PgUp "PgUp"
  1382. X#   define PgDn "PgDn"
  1383. X#endif
  1384. X
  1385. X /* often-used strings and messages */
  1386. X
  1387. Xextern char anykey[];            /* Press any key to continue */
  1388. Xextern char initscreen[];        /* Return to initial screen */
  1389. Xextern char prevscreen[];        /* Return to previous screen */
  1390. Xextern char int_error[];        /* The program is confused */
  1391. Xextern char pageup[];            /* Move screen one page upwards */
  1392. Xextern char pagedn[];            /* Move screen one page downwards */
  1393. Xextern char csrup[];            /* Move cursor upwards */
  1394. Xextern char csrdn[];            /* Move cursor downwards */
  1395. Xextern char getsummary[];        /* Press ESC to cancel/give summary */
  1396. Xextern char getaddr[];            /* Press ESC to cancel/enter address */
  1397. Xextern char printcurr[];        /* Print current message */
  1398. Xextern char delcurr[];            /* Delete current message */
  1399. Xextern char *m_msgread[];        /* Cannot read that message */
  1400. X
  1401. X/* SEE ALSO
  1402. X/*    screen(3)    screen table implementation
  1403. X/*    kbdinp(3)    screen table interpreter
  1404. X/* AUTHOR(S)
  1405. X/*    W.Z. Venema
  1406. X/*    Eindhoven University of Technology
  1407. X/*    Department of Mathematics and Computer Science
  1408. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1409. X/* CREATION DATE
  1410. X/*    Wed Apr  1 21:14:53 GMT+1:00 1987
  1411. X/* LAST MODIFICATION
  1412. X/*    90/01/22 13:02:34
  1413. X/* VERSION/RELEASE
  1414. X/*    2.1
  1415. X/*--*/
  1416. END_OF_main/screen.h
  1417. if test 4726 -ne `wc -c <main/screen.h`; then
  1418.     echo shar: \"main/screen.h\" unpacked with wrong size!
  1419. fi
  1420. # end of overwriting check
  1421. fi
  1422. if test -f main/sendwork.c -a "${1}" != "-c" ; then 
  1423.   echo shar: Will not over-write existing file \"main/sendwork.c\"
  1424. else
  1425. echo shar: Extracting \"main/sendwork.c\" \(4553 characters\)
  1426. sed "s/^X//" >main/sendwork.c <<'END_OF_main/sendwork.c'
  1427. X/*++
  1428. X/* NAME
  1429. X/*      sendwork 3
  1430. X/* SUMMARY
  1431. X/*      send local work to remote system
  1432. X/* PROJECT
  1433. X/*      pc-mail
  1434. X/* PACKAGE
  1435. X/*      cico
  1436. X/* SYNOPSIS
  1437. X/*      #include "work.h"
  1438. X/*
  1439. X/*      void sendwork(wrk)
  1440. X/*      work *wrk;
  1441. X/* DESCRIPTION
  1442. X/*      sendwork converts names and contents of local work files,
  1443. X/*    sends them to the remote system and deletes the files after 
  1444. X/*    successfull transfer.
  1445. X/*
  1446. X/*    In particular, it generates appropriate "From " lines at the
  1447. X/*    beginning of an outgoing mail message.
  1448. X/* SEE ALSO
  1449. X/*      scanwork(3)     locates work in the spool directory
  1450. X/* DIAGNOSTICS
  1451. X/*    sendwork() returns via longjmp(systrap,errorcode) in case
  1452. X/*    of unrecoverable problems.
  1453. X/*
  1454. X/*    The error codes are: E_CONFUSED (unexpected work type),
  1455. X/*    E_LOST (timed out), E_READERR (file read error).
  1456. X/* AUTHOR(S)
  1457. X/*      W.Z. Venema
  1458. X/*      Eindhoven University of Technology
  1459. X/*      Department of Mathematics and Computer Science
  1460. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1461. X/* CREATION DATE
  1462. X/*      Thu Mar 26 11:32:23 GMT+1:00 1987
  1463. X/* LAST MODIFICATION
  1464. X/*    90/01/22 13:02:35
  1465. X/* VERSION/RELEASE
  1466. X/*    2.1
  1467. X/*--*/
  1468. X
  1469. X#include <stdio.h>
  1470. X#include <time.h>
  1471. X
  1472. X#include "defs.h"
  1473. X#include "work.h"
  1474. X#include "logs.h"
  1475. X#include "status.h"
  1476. X#include "params.h"
  1477. X#include "comm.h"
  1478. X
  1479. Xextern struct tm *localtime();        /* std C library */
  1480. X
  1481. X /*
  1482. X  * A pc-mail system can connect to the UNIX net in at least two modes:
  1483. X  * 
  1484. X  * 1. As a real UUCP node, with it's own node name. This node name will have to
  1485. X  * appear in the "From " lines of outgoing mail. A consequence is that the
  1486. X  * pc mail node name should be known in mailer routing tables. Obviously
  1487. X  * this implies some administrative work when a pc mail node is added to the
  1488. X  * net or taken out of operation.  This mode has not been tested by the
  1489. X  * author.
  1490. X  * 
  1491. X  * 2. As an ordinary user. The program lets the UNIX host believe that mail
  1492. X  * messages come from an ordinary user. Recipients of mail will not be able
  1493. X  * to see that the mail came from the pc. Only the UNIX host knows it should
  1494. X  * forward mail for unixhost!xyz to the pc-mail node. This approach has the
  1495. X  * advantage that adding/deleting pc-mail nodes is simpler.
  1496. X  */
  1497. X
  1498. X#ifdef    UUCP_NODE            /* case 1 */
  1499. X#   define UUSER    "root"        /* use current user's name */
  1500. X#   define UHOST    LOGIN_NAME    /* use pc host name */
  1501. X#else                    /* case 2 */
  1502. X#   define UUSER    LOGIN_NAME    /* use remote login name */
  1503. X#   define UHOST    rmthost        /* use remote host name */
  1504. X#endif
  1505. X
  1506. X/* sendwork - adapt file contents for remote host */
  1507. X
  1508. Xpublic  sendwork(wrk)
  1509. Xwork   *wrk;
  1510. X{
  1511. X    long    secs;
  1512. X    char    buf[MAXLINE];        /* recipient addresses */
  1513. X
  1514. X    switch (wrk->type) {
  1515. X
  1516. X    /*
  1517. X     * Local D files contain the mail message. Except for the addition of
  1518. X     * a UUCP-style "From " line (with originator/date/system), D files
  1519. X     * are sent without modification.
  1520. X     */
  1521. X
  1522. X    case 'd':
  1523. X    case 'D':
  1524. X    secs = time((long *) 0);
  1525. X    say(strcons("From %s %.24s remote from %s\n",
  1526. X            UUSER, asctime(localtime(&secs)), UHOST));
  1527. X    send_file(wrk->fp);
  1528. X    break;
  1529. X
  1530. X    /*
  1531. X     * The first line of local X files contains the destination address.
  1532. X         * Real UUCP expects something entirely different.
  1533. X         *
  1534. X     * We make up some extra info to make the remote uuxqt program happy.
  1535. X     */
  1536. X
  1537. X    case 'x':
  1538. X    case 'X':
  1539. X    say(strcons("U %s %s\n", UUSER, UHOST));/* U user system */
  1540. X    say(strcons("F %s\n",
  1541. X            rmtname('D', wrk->seqno)));    /* F D.rmtsysGnumber */
  1542. X    say(strcons("I %s\n",
  1543. X            rmtname('D', wrk->seqno)));    /* I D.rmtsysGnumber */
  1544. X    say("C rmail ");            /* C rmail */
  1545. X    (void) fgets(buf, sizeof(buf), wrk->fp);/* read destinations */
  1546. X    say(buf);                /* send destinations */
  1547. X    say("");                /* send EOF */
  1548. X    break;
  1549. X
  1550. X    default:
  1551. X    trap(E_CONFUSED, "INTERNAL ERROR (unexpected work type: %c)", wrk->type);
  1552. X    }
  1553. X}
  1554. X
  1555. X/* say - write string to host */
  1556. X
  1557. Xhidden  say(str)
  1558. Xchar   *str;
  1559. X{
  1560. X    if (CALL(Write) (ttfd, str, strlen(str)) < 0)
  1561. X    trap(E_LOST, "FAILED (link lost)");
  1562. X}
  1563. X
  1564. X/* send_file - do the nitty-gritty of file transfer; traps on all errors */
  1565. X
  1566. Xhidden  send_file(fp)
  1567. Xregister FILE *fp;
  1568. X{
  1569. X    register int nread;
  1570. X    register int nwrite = 0;
  1571. X    char    buf[BUFSIZ];
  1572. X    register int rerror;
  1573. X
  1574. X    while ((nread = fread(buf, sizeof(*buf), sizeof(buf), fp)) > 0
  1575. X       && (nwrite = CALL(Write) (ttfd, buf, nread)) == nread)
  1576. X     /* void */ ;
  1577. X    rerror = ferror(fp);
  1578. X    fclose(fp);
  1579. X
  1580. X    if (rerror) {
  1581. X    trap(E_READERR, "FILE READ ERROR (%s)", sys_errlist[errno]);
  1582. X    /* NOTREACHED */
  1583. X    } else if (nwrite < 0 || CALL(Write) (ttfd, buf, 0) != 0) {
  1584. X    trap(E_LOST, "FAILED (link lost)");
  1585. X    /* NOTREACHED */
  1586. X    }
  1587. X}
  1588. END_OF_main/sendwork.c
  1589. if test 4553 -ne `wc -c <main/sendwork.c`; then
  1590.     echo shar: \"main/sendwork.c\" unpacked with wrong size!
  1591. fi
  1592. # end of overwriting check
  1593. fi
  1594. if test -f main/setup.c -a "${1}" != "-c" ; then 
  1595.   echo shar: Will not over-write existing file \"main/setup.c\"
  1596. else
  1597. echo shar: Extracting \"main/setup.c\" \(4086 characters\)
  1598. sed "s/^X//" >main/setup.c <<'END_OF_main/setup.c'
  1599. X/*++
  1600. X/* NAME
  1601. X/*    setup 3
  1602. X/* SUMMARY
  1603. X/*    edit/display configuration parameters
  1604. X/* PROJECT
  1605. X/*    pc-mail
  1606. X/* PACKAGE
  1607. X/*    mail
  1608. X/* SYNOPSIS
  1609. X/*    #include "mail.h"
  1610. X/*
  1611. X/*    int setup()
  1612. X/* DESCRIPTION
  1613. X/*    The functions in this module handle the configurations file with
  1614. X/*    communications parameters.
  1615. X/*
  1616. X/*    setup() starts a dialogue with the user. It allows the user to
  1617. X/*    select a parameter and enter a new value. All modifications are
  1618. X/*    done in core (pager file). Upon exit, the setup is written to
  1619. X/*    disk if any changes were made.
  1620. X/* FUNCTIONS AND MACROS
  1621. X/*    open_pager(), app_pager(), gets_pager(), puts_pager()
  1622. X/*    kbdinp()
  1623. X/* FILES
  1624. X/*    In the spool directory: the configuration file s00000.
  1625. X/* SEE ALSO
  1626. X/*    cico(1)    communications program.
  1627. X/* DIAGNOSTICS
  1628. X/*    An error message if the setup file could not be created.
  1629. X/* BUGS
  1630. X/*    Does not check parameter values at all, just like the UUCP
  1631. X/*    configurations files L.sys etcetera.
  1632. X/* AUTHOR(S)
  1633. X/*    W.Z. Venema
  1634. X/*    Eindhoven University of Technology
  1635. X/*    Department of Mathematics and Computer Science
  1636. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1637. X/* CREATION DATE
  1638. X/*    Wed Apr  8 15:16:18 GMT+1:00 1987
  1639. X/* LAST MODIFICATION
  1640. X/*    90/01/22 13:02:36
  1641. X/* VERSION/RELEASE
  1642. X/*    2.1
  1643. X/*--*/
  1644. X
  1645. X#include "defs.h"
  1646. X#include "path.h"
  1647. X#include "screen.h"
  1648. X#include "mail.h"
  1649. X#include "pager.h"
  1650. X#include "params.h"
  1651. X#include "status.h"
  1652. X#include "window.h"
  1653. X
  1654. Xhidden void make_setup();        /* forward declarations */
  1655. Xhidden int change_setup();
  1656. Xhidden int pick_setup();
  1657. Xhidden int show_setup();
  1658. X
  1659. Xhidden File *setfile = 0;        /* memory! */
  1660. Xhidden Info *prmtable = 0;        /* more memory */
  1661. Xhidden int chgflag = 0;            /* more flags! */
  1662. X
  1663. Xhidden char setfmt[] = "%-20s %s";    /* display format */
  1664. X#define    LABLEN    20            /* length of first %s specifier */
  1665. X
  1666. X/* setup - start dialogue */
  1667. X
  1668. Xpublic int setup()
  1669. X{
  1670. X    static Screen screen[] = {
  1671. X    'C',    "Close",0,        prevscreen,
  1672. X    PGUP,    PgUp,    pu_pager,    pageup,
  1673. X    PGDN,    PgDn,    pd_pager,    pagedn,
  1674. X    UP,    "Up",    up_pager,    csrup,
  1675. X    DOWN,    "Down",    dn_pager,    csrdn,
  1676. X    ENTER,    "Enter",pick_setup,    "Modify selected parameter",
  1677. X    0,    0,    show_setup,
  1678. X    "Select communications parameter with cursor keys, then press ENTER",
  1679. X    };
  1680. X
  1681. X    kbdinp(screen);                /* start dialogue */
  1682. X    if (chgflag && cp_pager(parm_file())) {    /* save setup if changed */
  1683. X    errdisp(E_WRITERR);            /* save failed */
  1684. X    } else {
  1685. X    chgflag = 0;                /* save succeeded */
  1686. X    }
  1687. X    close_pager(setfile);
  1688. X    setfile = 0;
  1689. X    return (S_REDRAW);                /* refresh screen */
  1690. X}
  1691. X
  1692. X/* show_setup - make setup display or use existing one */
  1693. X
  1694. Xhidden int show_setup()
  1695. X{
  1696. X    if (setfile == 0 || prmtable == 0) {    /* no setup display */
  1697. X    prmtable = getparams();
  1698. X    setfile = open_pager();
  1699. X    make_setup();
  1700. X    } else {                    /* use existing display */
  1701. X    set_pager(setfile);
  1702. X    }
  1703. X    ds_pager();                    /* display it */
  1704. X    return (0);
  1705. X}
  1706. X
  1707. X/* make_setup - create setup display */
  1708. X
  1709. Xhidden void make_setup()
  1710. X{
  1711. X    register File *f = setfile;
  1712. X    register Info *i;
  1713. X
  1714. X    for (i = prmtable; i->ident; i++)
  1715. X    app_pager(f, strcons(setfmt, i->ident, i->strval ? i->strval : ""));
  1716. X}
  1717. X
  1718. X/* pick_setup - user has selected one parameter */
  1719. X
  1720. Xhidden int pick_setup()
  1721. X{
  1722. X    static Screen screen[] = {
  1723. X    EDIT,    0,    change_setup,    0,
  1724. X    0,    0,    0,
  1725. X    "Press ESC to cancel. New parameter value:"
  1726. X    };
  1727. X    register char *sp = gets_pager();
  1728. X    register Info *ip;
  1729. X
  1730. X    for (ip = prmtable; ip->ident; ip++)    /* check id string */
  1731. X    if (strncmp(ip->ident, sp, ip->length) == 0)
  1732. X        break;
  1733. X    if (ip) {
  1734. X    screen->help = sp + LABLEN + 1;        /* default is current value */
  1735. X    kbdinp(screen);                /* ask for new value */
  1736. X    return (S_REDRAW);
  1737. X    } else {
  1738. X    beep();                    /* bad id string */
  1739. X    return (0);
  1740. X    }
  1741. X}
  1742. X
  1743. X/* change_setup - enter new communications parameter value */
  1744. X
  1745. Xhidden int change_setup(newval)
  1746. Xchar   *newval;
  1747. X{
  1748. X    register char *sp = gets_pager();    /* read from display */
  1749. X    register Info *ip;
  1750. X
  1751. X    for (ip = prmtable; ip->ident; ip++) {    /* check id string */
  1752. X    if (strncmp(ip->ident, sp, ip->length) == 0) {
  1753. X        puts_pager(strcons(setfmt, ip->ident, newval));
  1754. X        chgflag = 1;            /* say change made */
  1755. X    }
  1756. X    }
  1757. X    return (S_BREAK | S_REDRAW);        /* screen changed */
  1758. X}
  1759. END_OF_main/setup.c
  1760. if test 4086 -ne `wc -c <main/setup.c`; then
  1761.     echo shar: \"main/setup.c\" unpacked with wrong size!
  1762. fi
  1763. # end of overwriting check
  1764. fi
  1765. if test -f main/switcher.c -a "${1}" != "-c" ; then 
  1766.   echo shar: Will not over-write existing file \"main/switcher.c\"
  1767. else
  1768. echo shar: Extracting \"main/switcher.c\" \(4183 characters\)
  1769. sed "s/^X//" >main/switcher.c <<'END_OF_main/switcher.c'
  1770. X/*++
  1771. X/* NAME
  1772. X/*      switcher 3
  1773. X/* SUMMARY
  1774. X/*      master/slave protocol control switcher
  1775. X/* PROJECT
  1776. X/*      pc-mail
  1777. X/* PACKAGE
  1778. X/*      cico
  1779. X/* SYNOPSIS
  1780. X/*      int switcher(role)
  1781. X/*      int role;
  1782. X/* DESCRIPTION
  1783. X/*      switcher() takes care of the high-level protocol on top of
  1784. X/*      the packet protocol. 
  1785. X/*
  1786. X/*    The system is in one of two roles: MASTER or SLAVE. In MASTER
  1787. X/*    mode (initial mode of the caller) a system scans its local
  1788. X/*    spool directory for work until no more is found, and then
  1789. X/*    sends a H (hangup) request. The slave will respond with HY
  1790. X/*    if it has no work, otherwise it will respond with HN and
  1791. X/*    the two systems switch roles.
  1792. X/*
  1793. X/*    Work can be of the form of S (send) requests or R (receive)
  1794. X/*    requests. The slave responds with SY (RY) or SN (RN), depending on
  1795. X/*    whether it is willing to process the request. The recipient
  1796. X/*    of a message sends a CY or CN message, depending on whether
  1797. X/*    transmission was successfull.
  1798. X/*
  1799. X/*      Only H(angup) and S(end) requests are implemented here. This is
  1800. X/*      for security reasons. Thus, the only way to exchange data is
  1801. X/*      through electronic mail.
  1802. X/* FUNCTIONS AND MACROS
  1803. X/*      isok, talk(), hear(), trap(), scanwork(), sendwork()
  1804. X/*      rmtwork(), getwork()
  1805. X/* DIAGNOSTICS
  1806. X/*      Various nonzero status codes are returned in case of problems.
  1807. X/* AUTHOR(S)
  1808. X/*      W.Z. Venema
  1809. X/*      Eindhoven University of Technology
  1810. X/*      Department of Mathematics and Computer Science
  1811. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1812. X/* CREATION DATE
  1813. X/*      Fri Mar 27 21:49:16 GMT+1:00 1987
  1814. X/* LAST MODIFICATION
  1815. X/*    90/01/22 13:02:45
  1816. X/* VERSION/RELEASE
  1817. X/*    2.1
  1818. X/*--*/
  1819. X
  1820. X#include <stdio.h>
  1821. X#include <setjmp.h>
  1822. X
  1823. X#include "defs.h"
  1824. X#include "work.h"
  1825. X#include "params.h"
  1826. X#include "comm.h"
  1827. X#include "logs.h"
  1828. X#include "status.h"
  1829. X
  1830. X/* switcher - handles master/slave role swicthing until all work is done */
  1831. X
  1832. Xpublic  switcher(role)
  1833. Xregister int role;
  1834. X{
  1835. X    int    *savetrap = systrap;
  1836. X    jmp_buf mytrap;
  1837. X    int     status;
  1838. X
  1839. X    if (status = setjmp(systrap = mytrap)) {
  1840. X    systrap = savetrap;            /* get here on fatal errors */
  1841. X    return (status);
  1842. X    }
  1843. X    /* switch roles until both ends out of work */
  1844. X
  1845. X    while (role != DONE) {
  1846. X    switch (role) {
  1847. X    case MASTER:
  1848. X        role = master();
  1849. X        break;
  1850. X    case SLAVE:
  1851. X        role = slave();
  1852. X        break;
  1853. X    default:
  1854. X        trap(E_CONFUSED, "INTERNAL ERROR (unexpected role: %d)", role);
  1855. X    }
  1856. X    }
  1857. X    systrap = savetrap;                /* no fatal errors */
  1858. X    return (0);
  1859. X}
  1860. X
  1861. X/* master - process local work; when done, switch roles or finish */
  1862. X
  1863. Xhidden int master()
  1864. X{
  1865. X    register work *wrk;
  1866. X    register char *resp;
  1867. X
  1868. X    while (wrk = scanwork()) {            /* scan for work */
  1869. X    log("REQUEST (%s)", wrk->rqst);
  1870. X    if (wrk->fp == 0) {            /* check file exists */
  1871. X        log("CAN'T READ DATA (%s)", sys_errlist[errno]);
  1872. X        trap(E_SYSFAIL, "FAILED");        /* don\'t loop forever */
  1873. X    } else if (isok(wrk->rqst) == NO) {    /* check xfer allowed */
  1874. X        log("PERMISSION (DENIED)");
  1875. X        trap(E_REJECT, "FAILED");        /* don\'t loop forever */
  1876. X    } else {
  1877. X        sendwork(wrk);            /* adapt and send data */
  1878. X        log("REQUESTED (%s)", resp = hear());/* get remote status */
  1879. X        if (strcmp(resp, "CY"))        /* check for sucessful */
  1880. X        trap(E_REJECT, "FAILED");    /* completion */
  1881. X        unlink(wrk->sent);            /* just in case */
  1882. X        rename(wrk->path, wrk->sent);    /* change status to "sent" */
  1883. X    }
  1884. X    }
  1885. X
  1886. X    /* switch roles or finish if slave has no work */
  1887. X
  1888. X    return (isok("H") == YES ? (talk("HY"), DONE) : SLAVE);
  1889. X}
  1890. X
  1891. X/* slave - process remote work; accept H and S requests only */
  1892. X
  1893. Xhidden int slave()
  1894. X{
  1895. X    register char *cmnd;
  1896. X    register work *wrk;
  1897. X
  1898. X    for (;;) {
  1899. X    switch ((cmnd = hear())[0]) {
  1900. X    case 'S':                /* master wants to send */
  1901. X        log("REQUESTED (%s)", cmnd);    /* log the request */
  1902. X        wrk = rmtwork(cmnd);        /* parse the request */
  1903. X        talk("SY");                /* say ok */
  1904. X        getwork(wrk);            /* receive work */
  1905. X        talk("CY");                /* we never copy */
  1906. X        log("COPY (SUCCEEDED)");
  1907. X        break;
  1908. X    case 'H':                /* master is out of work */
  1909. X        return (scanwork() ? (talk("HN"), MASTER) : (talk("HY"), DONE));
  1910. X    default:
  1911. X        talk(strcons("%cN", cmnd[0]));    /* refuse other type of work */
  1912. X        break;
  1913. X    }
  1914. X    }
  1915. X}
  1916. END_OF_main/switcher.c
  1917. if test 4183 -ne `wc -c <main/switcher.c`; then
  1918.     echo shar: \"main/switcher.c\" unpacked with wrong size!
  1919. fi
  1920. # end of overwriting check
  1921. fi
  1922. if test -f main/unalias.c -a "${1}" != "-c" ; then 
  1923.   echo shar: Will not over-write existing file \"main/unalias.c\"
  1924. else
  1925. echo shar: Extracting \"main/unalias.c\" \(4641 characters\)
  1926. sed "s/^X//" >main/unalias.c <<'END_OF_main/unalias.c'
  1927. X/*++
  1928. X/* NAME
  1929. X/*    unalias 3
  1930. X/* SUMMARY
  1931. X/*    alias processing
  1932. X/* PROJECT
  1933. X/*    pc-mail
  1934. X/* PACKAGE
  1935. X/*    smail
  1936. X/* SYNOPSIS
  1937. X/*    char **unalias(namevec)
  1938. X/*    char **namevec;
  1939. X/* DESCRIPTION
  1940. X/*    unalias() takes an array of string pointers and returns a vector
  1941. X/*    with string pointers to their alias expansions. The resulting
  1942. X/*    vector is in static memory.
  1943. X/*
  1944. X/*    After alias expansion, all addresses are sorted and duplicate
  1945. X/*    names are eliminated. The algorithms for alias expansion and
  1946. X/*    duplicate elimination are case-insensitive.
  1947. X/*
  1948. X/*    unalias() accesses the alias data base through the ascf ASCII
  1949. X/*    filter.
  1950. X/* DIAGNOSTICS
  1951. X/*    unalias() returns a null pointer in case of memory-allocation problems.
  1952. X/*
  1953. X/*    unalias() terminates prematurely when the alias expansion has
  1954. X/*    produced BUFSIZ recipients. This provides some defense against
  1955. X/*    cycles in the alias data base. It is up to the caller to
  1956. X/*    recognize this condition.
  1957. X/* BUGS
  1958. X/*    The overflow/cycle detection algorithm is inelegant.
  1959. X/* FILES
  1960. X/*    Alias data base in spool directory
  1961. X/* AUTHOR(S)
  1962. X/*      W.Z. Venema
  1963. X/*      Eindhoven University of Technology
  1964. X/*      Department of Mathematics and Computer Science
  1965. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1966. X/* CREATION DATE
  1967. X/*    Wed Apr  6 20:21:35 MET 1988
  1968. X/* LAST MODIFICATION
  1969. X/*    90/01/22 13:02:54
  1970. X/* VERSION/RELEASE
  1971. X/*    2.1
  1972. X/*--*/
  1973. X
  1974. X#include "defs.h"
  1975. X#include "hsearch.h"
  1976. X#include "path.h"
  1977. X#include "ascf.h"
  1978. X
  1979. X/* forward declarations */
  1980. X
  1981. Xhidden int hash_alias();
  1982. Xhidden void sort_alias();
  1983. Xhidden void uniq_alias();
  1984. Xhidden char **find_alias();
  1985. X
  1986. X/* unalias - replace aliases by their equivalents */
  1987. X
  1988. Xpublic char **unalias(names)
  1989. Xchar  **names;
  1990. X{
  1991. X    static int dohash = 1;        /* hash table not yet made */
  1992. X    static char *recp[BUFSIZ + 1];    /* the result of alias expansion */
  1993. X    char  **stop = recp + BUFSIZ;    /* overflow limit */
  1994. X
  1995. X    if (dohash && (dohash = hash_alias()))    /* build the hash table */
  1996. X    return (0);
  1997. X    if (stop > find_alias(names, recp, stop)) {    /* build vector of addresses */
  1998. X    sort_alias(recp);            /* sort the recp list */
  1999. X    uniq_alias(recp);            /* eliminate duplicates */
  2000. X    }
  2001. X    return (recp);
  2002. X}
  2003. X
  2004. X/* hash_alias - copy alias data base to hash table */
  2005. X
  2006. Xhidden int hash_alias()
  2007. X{
  2008. X    register FILE *fp;
  2009. X    char    buf[BUFSIZ];
  2010. X
  2011. X    /* initialize the hash table */
  2012. X
  2013. X    if (hcreate(BUFSIZ) == 0)
  2014. X    return (-1);
  2015. X
  2016. X    /*
  2017. X     * Lines in the alias data base are of the form
  2018. X     * 
  2019. X     * <left-hand part>    <right-hand part>
  2020. X     * 
  2021. X     * where the l.h. part is an alias, and the r.h. part one or more words. Of
  2022. X     * course, those words can be aliases. The order in which aliases are
  2023. X     * defined is not important. The alias data base is used only after it
  2024. X     * has been loaded into memory.
  2025. X     * 
  2026. X     * Each l.h. part is used as the key for finding the r.h. part in the hash
  2027. X     * table. The r.h. part is stored as a vector of pointers to strings.
  2028. X     */
  2029. X
  2030. X    if (fp = ascopen(aliases(), "r")) {        /* read through ASCII filter */
  2031. X    while (ascgets(buf, sizeof(buf), fp)) {    /* read entry from alias file */
  2032. X        register char **cpp;
  2033. X        ENTRY   e;
  2034. X
  2035. X        if ((cpp = strvec(buf, ", \t\r\n")) == 0)    /* split alias entry */
  2036. X        return (-1);
  2037. X        if ((e.key = *cpp)            /* left-hand part exists */
  2038. X        &&(e.data = (char *) (cpp + 1))    /* right-hand part exists */
  2039. X        &&(hsearch(e, ENTER) == 0))        /* enter hash table */
  2040. X        return (-1);
  2041. X    }
  2042. X    ascclose(fp);
  2043. X    }
  2044. X    return (0);
  2045. X}
  2046. X
  2047. X/* find_alias - recursively expand aliases */
  2048. X
  2049. Xhidden char **find_alias(from, to, stop)
  2050. Xchar  **from;
  2051. Xregister char **to;
  2052. Xregister char **stop;
  2053. X{
  2054. X    register char **cpp;
  2055. X    register ENTRY *sp;
  2056. X    ENTRY   e;
  2057. X
  2058. X    /* recursively replace aliases, but don't crash in case of cycles */
  2059. X
  2060. X    for (cpp = from; *cpp && (to < stop); cpp++) {
  2061. X    e.key = *cpp;
  2062. X    if (sp = hsearch(e, FIND)) {
  2063. X        to = find_alias((char **) sp->data, to, stop);
  2064. X    } else {
  2065. X        *to++ = *cpp;
  2066. X    }
  2067. X    }
  2068. X    *to = 0;
  2069. X    return (to);
  2070. X}
  2071. X
  2072. X/* Istrcmp - interface between qsort and istrcmp */
  2073. X
  2074. Xhidden int Istrcmp(p1, p2)
  2075. Xchar  **p1,
  2076. X      **p2;
  2077. X{
  2078. X    return (istrcmp(*p1, *p2));
  2079. X}
  2080. X
  2081. X/* sort_alias - sort the addresses after alias substitutions */
  2082. X
  2083. Xhidden void sort_alias(to)
  2084. Xchar  **to;
  2085. X{
  2086. X    register char **cpp;
  2087. X    int     istrcmp();
  2088. X
  2089. X    /* find out length of the list */
  2090. X
  2091. X    for (cpp = to; *cpp; cpp++)
  2092. X     /* void */ ;
  2093. X
  2094. X    /* sort the list */
  2095. X
  2096. X    qsort((char *) to, cpp - to, sizeof(*to), Istrcmp);
  2097. X}
  2098. X
  2099. X/* uniq_alias - collapse sequences of identical addresses */
  2100. X
  2101. Xhidden void uniq_alias(to)
  2102. Xchar  **to;
  2103. X{
  2104. X    register char **in = to;
  2105. X    register char **out = to;
  2106. X
  2107. X    while (*out = *in) {
  2108. X    while (*++in && istrcmp(*out, *in) == 0) {
  2109. X         /* void */ ;
  2110. X    }
  2111. X    ++out;
  2112. X    }
  2113. X}
  2114. END_OF_main/unalias.c
  2115. if test 4641 -ne `wc -c <main/unalias.c`; then
  2116.     echo shar: \"main/unalias.c\" unpacked with wrong size!
  2117. fi
  2118. # end of overwriting check
  2119. fi
  2120. echo shar: End of archive 4 \(of 11\).
  2121. cp /dev/null ark4isdone
  2122. MISSING=""
  2123. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  2124.     if test ! -f ark${I}isdone ; then
  2125.     MISSING="${MISSING} ${I}"
  2126.     fi
  2127. done
  2128. if test "${MISSING}" = "" ; then
  2129.     echo You have unpacked all 11 archives.
  2130.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2131. else
  2132.     echo You still need to unpack the following archives:
  2133.     echo "        " ${MISSING}
  2134. fi
  2135. ##  End of shell archive.
  2136. exit 0
  2137.  
  2138.