home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / pcmail2.lzh / pcmail.4 < prev    next >
Encoding:
Text File  |  1990-01-31  |  59.5 KB  |  2,131 lines

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