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

  1. Newsgroups: comp.sources.misc
  2. subject: v10i035: PC-MAIL release 2, 3/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 35
  7. Submitted-by: wswietse@lso.win.tue.nl (Wietse Venema)
  8. Archive-name: pcmail2/part03
  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 3 (of 11)."
  17. # Contents:  daemon/util.c main/PORTING main/alias.c main/cmail.c
  18. #   main/comport.h main/edit.c main/getwork.c main/hsearch.3
  19. #   main/kproto.ms main/lmail.c main/mail.c main/ms_parse.c
  20. #   main/params.c main/path.c main/scanwork.c main/smail.c
  21. #   main/snapshot.c
  22. # Wrapped by wswietse@tuewsa on Mon Jan 22 17:27:15 1990
  23. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  24. if test -f daemon/util.c -a "${1}" != "-c" ; then 
  25.   echo shar: Will not over-write existing file \"daemon/util.c\"
  26. else
  27. echo shar: Extracting \"daemon/util.c\" \(3152 characters\)
  28. sed "s/^X//" >daemon/util.c <<'END_OF_daemon/util.c'
  29. X/*++
  30. X/* NAME
  31. X/*    util 3
  32. X/* SUMMARY
  33. X/*    wrappers around standard library functions
  34. X/* PROJECT
  35. X/*    pc-mail
  36. X/* PACKAGE
  37. X/*    nfs
  38. X/* SYNOPSIS
  39. X/*    #include <stdio.h>
  40. X/*    #include <pwd.h>
  41. X/*    #include <directory_access_stuff.h>
  42. X/*
  43. X/*    FILE *u_fopen(uinfo,path,mode)
  44. X/*    struct passwd *uinfo;
  45. X/*    char *path;
  46. X/*    char *mode;
  47. X/*
  48. X/*    int u_link(uinfo, old, new)
  49. X/*    struct passwd *uinfo;
  50. X/*    char *old;
  51. X/*    char *new;
  52. X/*
  53. X/*    int u_unlink(uinfo, path)
  54. X/*    struct passwd *uinfo;
  55. X/*    char *path;
  56. X/*
  57. X/*    DIR *e_opendir(path)
  58. X/*    char *path;
  59. X/*
  60. X/*    int e_chdir(path)
  61. X/*    char *path;
  62. X/*
  63. X/*    int e_fork()
  64. X/* DESCRIPTION
  65. X/*    These functions are wrappers around some standard library functions.
  66. X/*    In case of problems, they append an entry to the system log (with
  67. X/*    priority LOG_WARNING). The \fIuinfo\fR argument specifies the owner
  68. X/*    of the mail subdirectory in which the problem occurred.
  69. X/* SEE ALSO
  70. X/*    syslog(3)
  71. X/* DIAGNOSTICS
  72. X/*    Diagnostics are logged via the syslog package; error return values
  73. X/*    are identical to those of the underlying library functions.
  74. X/* AUTHOR(S)
  75. X/*    Wietse Z. Venema
  76. X/*    Eindhoven University of Technology
  77. X/*    Department of Mathematics and Computer Science
  78. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  79. X/* CREATION DATE
  80. X/*    Sun Oct 29 16:21:02 MET 1989
  81. X/* LAST MODIFICATION
  82. X/*    12/4/89 23:22:13
  83. X/* VERSION/RELEASE
  84. X/*    1.2
  85. X/*--*/
  86. X
  87. X#ifndef lint
  88. Xstatic char sccsid[] = "@(#) util.c 1.2 12/4/89 23:22:13";
  89. X
  90. X#endif
  91. X
  92. X#include <stdio.h>
  93. X#include <pwd.h>
  94. X
  95. X#ifdef SYSV
  96. X#include <ndir.h>
  97. X#else
  98. X#include <sys/types.h>
  99. X#include <sys/dir.h>
  100. X#endif
  101. X
  102. X#ifdef SYSLOG
  103. X#include <syslog.h>
  104. X#else
  105. X#include "syslog.h"
  106. X#endif
  107. X
  108. X#include "util.h"            /* consistency check */
  109. X
  110. X/* u_fopen - open file in user directory, log any errors */
  111. X
  112. XFILE   *u_fopen(uinfo, file, mode)
  113. Xstruct passwd *uinfo;
  114. Xchar   *file;
  115. Xchar   *mode;
  116. X{
  117. X    register FILE *fp;
  118. X
  119. X    if ((fp = fopen(file, mode)) == 0)
  120. X    syslog(LOG_WARNING, "cannot open %s/%s: %m", uinfo->pw_name, file);
  121. X    return (fp);
  122. X}
  123. X
  124. X/* u_unlink - unlink file in user directory, log any errors */
  125. X
  126. Xint     u_unlink(uinfo, file)
  127. Xstruct passwd *uinfo;
  128. Xchar   *file;
  129. X{
  130. X    register int stat;
  131. X
  132. X    if (stat = unlink(file))
  133. X    syslog(LOG_WARNING, "cannot unlink %s/%s: %m", uinfo->pw_name, file);
  134. X    return (stat);
  135. X}
  136. X
  137. X/* u_link - link file in user directory, log any errors */
  138. X
  139. Xint     u_link(uinfo, old, new)
  140. Xstruct passwd *uinfo;
  141. Xchar   *old;
  142. Xchar   *new;
  143. X{
  144. X    register int stat;
  145. X
  146. X    if (stat = link(old, new))
  147. X    syslog(LOG_WARNING, "cannot link %s/%s: %m", uinfo->pw_name, new);
  148. X    return (stat);
  149. X}
  150. X
  151. X/* e_opendir - open directory, log any errors */
  152. X
  153. XDIR    *e_opendir(path)
  154. Xchar   *path;
  155. X{
  156. X    register DIR *dd;
  157. X
  158. X    if ((dd = opendir(path)) == 0)
  159. X    syslog(LOG_WARNING, "cannot open directory %s: %m", path);
  160. X    return (dd);
  161. X}
  162. X
  163. X/* e_chdir - change directory, log any errors */
  164. X
  165. Xint     e_chdir(path)
  166. Xchar   *path;
  167. X{
  168. X    register int ret;
  169. X
  170. X    if (ret = chdir(path))
  171. X    syslog(LOG_WARNING, "cannot chdir to directory %s: %m", path);
  172. X    return (ret);
  173. X}
  174. X
  175. X/* e_fork - do a fork(), log any errors */
  176. X
  177. Xint     e_fork()
  178. X{
  179. X    register int stat;
  180. X
  181. X    if ((stat = fork()) == -1)
  182. X    syslog(LOG_WARNING, "fork() failed: %m");
  183. X    return (stat);
  184. X}
  185. X
  186. END_OF_daemon/util.c
  187. if test 3152 -ne `wc -c <daemon/util.c`; then
  188.     echo shar: \"daemon/util.c\" unpacked with wrong size!
  189. fi
  190. # end of overwriting check
  191. fi
  192. if test -f main/PORTING -a "${1}" != "-c" ; then 
  193.   echo shar: Will not over-write existing file \"main/PORTING\"
  194. else
  195. echo shar: Extracting \"main/PORTING\" \(2946 characters\)
  196. sed "s/^X//" >main/PORTING <<'END_OF_main/PORTING'
  197. X@(#) PORTING 2.1 90/01/22 13:01:09
  198. X
  199. XThis document gives some hints to people who might consider to port the
  200. Xprograms to an environment different from UNIX or MS-DOS.  Fortunately,
  201. Xthe programs themselves are written in portable (old-style) C. The only
  202. Xexception is the MS-DOS serial port driver, which isn't portable at all.
  203. X
  204. XFirst of all, search the source files for #ifdef constructs.  This
  205. Xshould give an idea where the system-dependencies lurk.
  206. X
  207. XThe main problem will be serial-port I/O.  If possible, try to build on
  208. Xtop of what the GNUUCP people have already done in this field.
  209. X
  210. XA less severe problem should be console input/output.  The programs do
  211. Xnot use any graphics at all, nor are special input devices such as mice
  212. Xrequired.  If your machine provides some kind of vt52 or vt100
  213. Xemulation, adapt the console.c and tgoto.c files in the termcap
  214. Xsubdirectory.  On machines without some form of text window on the
  215. Xconsole, porting will require too much work.  Most keyboards generate
  216. Xcodes that can be easily encoded in the console.c file in the termcap
  217. Xsubdirectory.  Most C compilers provide some form of "raw" keyboard i/o
  218. Xthat does not require the user to press ENTER, and that produces no
  219. Xecho.  You may wish to consult a UNIX programmer's manual to find out
  220. Xwhat the two-letter codes in console.c are all about.
  221. X
  222. XProcess management may need some attention.  The programs were written
  223. Xin the UNIX style, i.e. many small programs dedicated to a single task.
  224. XPrograms invoke other programs.  Each program returns an exit status,
  225. Xsuch that the parent program can take appropriate action if things went
  226. Xwrong.  If your operating system does not provide facilities to invoke,
  227. Xfrom with a program, other programs with command-line arguments, you
  228. Xlose.  Sometimes, programs can only be invoked with the "aid" of a
  229. Xcommand-language interpreter.  This often causes the exit status of
  230. Xprograms to be lost; the net result will be less reliable operation of
  231. Xthe pc-mail software.  In the case of MS-DOS I compromised:  batch
  232. Xcommand files must be given including their suffix, so that special
  233. Xarrangements can be made; other programs are invoked directly without
  234. Xintervention of a command interpreter.
  235. X
  236. XFile i/o should be taken care of by your C library; make sure that
  237. X"text" and "binary" modes are used at the appropriate places.  Just look
  238. Xup where O_BINARY appears in the source.  If your C library does not
  239. Xneed to distinguish between text and binary file i/o, you are lucky.
  240. X
  241. XYou will have to provide some form of the Berkeley-UNIX directory
  242. Xlibrary routines; they allow any program to scan directories for the
  243. Xnames of files.  By now, these routines should be publicly available for
  244. Xmost reasonable operating systems.  Make sure that the version you use
  245. Xproduces file names in lower case (or take appropriate measures), and
  246. Xthat it behaves well even in the root directory of a file system
  247. X(MS-DOS doesn't, so I had to compromise again).
  248. END_OF_main/PORTING
  249. if test 2946 -ne `wc -c <main/PORTING`; then
  250.     echo shar: \"main/PORTING\" unpacked with wrong size!
  251. fi
  252. # end of overwriting check
  253. fi
  254. if test -f main/alias.c -a "${1}" != "-c" ; then 
  255.   echo shar: Will not over-write existing file \"main/alias.c\"
  256. else
  257. echo shar: Extracting \"main/alias.c\" \(3434 characters\)
  258. sed "s/^X//" >main/alias.c <<'END_OF_main/alias.c'
  259. X/*++
  260. X/* NAME
  261. X/*    alias
  262. X/* SUMMARY
  263. X/*    manipulate alias data base
  264. X/* PROJECT
  265. X/*    pc-mail
  266. X/* PACKAGE
  267. X/*    mail
  268. X/* SYNOPSIS
  269. X/*    #include "mail.h"
  270. X/*
  271. X/*    int alias()
  272. X/* DESCRIPTION
  273. X/*    The alias data base is a text file. Each line is of the form
  274. X/*
  275. X/*        word    one or more words
  276. X/*
  277. X/*    The first word is the alias; words are separated by blanks
  278. X/*    or commas. Upon alias expansion, the alias will be replaced
  279. X/*    by the words on the remainder of the line of its definition.
  280. X/*    An alias may be defined in terms of other aliases, but in terms
  281. X/*    of itself.  Aliases may defined in any order. If an alias is defined
  282. X/*    more than once, only the last definition will be effective.
  283. X/*
  284. X/*    alias() is invoked from the main menu and displays the contents
  285. X/*    of the alias data base. An editor is invoked if the user wants
  286. X/*    to make changes.
  287. X/* COMMANDS
  288. X/*    the program specified in the EDITOR environment variable,
  289. X/*    or a system-dependent default.
  290. X/* FILES
  291. X/*      temporary edit file in current directory
  292. X/*    $MAILDIR/a00000, alias data base
  293. X/* SEE ALSO
  294. X/*      pager(3), pager(5), kbdinp(3)
  295. X/* AUTHOR(S)
  296. X/*      W.Z. Venema
  297. X/*      Eindhoven University of Technology
  298. X/*      Department of Mathematics and Computer Science
  299. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  300. X/* CREATION DATE
  301. X/*    Wed Apr  6 20:21:35 MET 1988
  302. X/* LAST MODIFICATION
  303. X/*    90/01/22 13:01:13
  304. X/* VERSION/RELEASE
  305. X/*    2.1
  306. X/*--*/
  307. X
  308. X#include <errno.h>
  309. X#include "defs.h"
  310. X#include "path.h"
  311. X#include "pager.h"
  312. X#include "mail.h"
  313. X#include "screen.h"
  314. X#include "status.h"
  315. X
  316. X/* forward declarations */
  317. X
  318. Xhidden int edit_alias();
  319. Xhidden void junk_alias();
  320. Xhidden int show_alias();
  321. X
  322. Xhidden File *afile = 0;            /* pager file */
  323. X
  324. X/* alias - display alias data base */
  325. X
  326. Xpublic int alias()
  327. X{
  328. X    static Screen screen[] = {
  329. X    'C',    "Close",    0,    prevscreen,
  330. X    'E',    "Edit",        edit_alias,"Edit alias data base",
  331. X    'P',    "Print",    print,    "Print alias data base",
  332. X    PGUP,    PgUp,        pu_pager,pageup,
  333. X    PGDN,    PgDn,        pd_pager,pagedn,
  334. X    UP,    "Up",           up_pager,csrup,
  335. X    DOWN,    "Down",         dn_pager,csrdn,
  336. X    0,    0,              show_alias,
  337. X    "(Reading alias database)",
  338. X    };
  339. X
  340. X    kbdinp(screen);                /* ask disposition */
  341. X    junk_alias();                /* forget alias display */
  342. X    return(S_REDRAW);                /* say screen was changed */
  343. X}
  344. X
  345. X/* show_alias - show alias data base or default message in middle window */
  346. X
  347. Xhidden int show_alias()
  348. X{
  349. X    static char *noalias[] = {            /* Ha ha ha ho ho hum */
  350. X    "",
  351. X    "The alias data base is empty. Normally it holds lines of the form",
  352. X    "",
  353. X    "    alias-name   one-or-more-mail-addresses",
  354. X    "",
  355. X    "You can create or change the alias data base with the E command.",
  356. X    0,
  357. X    };
  358. X    if (afile) {                /* check pager file exists */
  359. X    set_pager(afile);            /* select existing display */
  360. X    } else if (rd_pager(afile = open_pager(),aliases())) {
  361. X    mesg_pager(afile,noalias);        /* no alias database */
  362. X    }
  363. X    ds_pager();                    /* (re)draw display */
  364. X    return(0);                    /* screen is up-to-date */
  365. X}
  366. X
  367. X/* junk_alias - destroy alias data base display */
  368. X
  369. Xhidden void junk_alias()
  370. X{
  371. X    if (afile) {                /* no-op if no display */
  372. X    close_pager(afile);            /* release memory */
  373. X    afile = 0;                /* say it is gone */
  374. X    }
  375. X}
  376. X
  377. X/* edit_alias - edit or create alias data base */
  378. X
  379. Xhidden int edit_alias()
  380. X{
  381. X    register int stat;
  382. X
  383. X    if (stat = edit(aliases(),TMPALIAS))
  384. X    errdisp(stat);                /* edit() had a problem */
  385. X    junk_alias();                /* force new display */
  386. X    return(S_REDRAW);                /* say screen has changed */
  387. X}
  388. END_OF_main/alias.c
  389. if test 3434 -ne `wc -c <main/alias.c`; then
  390.     echo shar: \"main/alias.c\" unpacked with wrong size!
  391. fi
  392. # end of overwriting check
  393. fi
  394. if test -f main/cmail.c -a "${1}" != "-c" ; then 
  395.   echo shar: Will not over-write existing file \"main/cmail.c\"
  396. else
  397. echo shar: Extracting \"main/cmail.c\" \(3814 characters\)
  398. sed "s/^X//" >main/cmail.c <<'END_OF_main/cmail.c'
  399. X/*++
  400. X/* NAME
  401. X/*    cmail 1
  402. X/* SUMMARY
  403. X/*    report if there are unread messages
  404. X/* PROJECT
  405. X/*    pc-mail
  406. X/* PACKAGE
  407. X/*    cmail
  408. X/* SYNOPSIS
  409. X/*    cmail [-p password]
  410. X/* DESCRIPTION
  411. X/*    cmail reports if there are unread mail messages in the
  412. X/*    pc-mail spool directory.
  413. X/*
  414. X/*    If the -p option is present, cmail first invokes the cico
  415. X/*    program to contact the mail server host.
  416. X/*
  417. X/*    Typically cmail is run immediately after system startup,
  418. X/*    while you are getting your first cup of coffee.
  419. X/*
  420. X/*    The program returns a nonzero exit status if it could not
  421. X/*    find any mail.
  422. X/* COMMANDS
  423. X/*    cico    file transfer program
  424. X/*    nmail    processes new mail
  425. X/* FILES
  426. X/*    Various files in the spool directory
  427. X/*
  428. X/*    LOGFILE system status messages
  429. X/*    n<seqno> mail messages
  430. X/*    h<seqno> header line of new mail
  431. X/*    o<seqno> header line of old mail
  432. X/* DIAGNOSTICS
  433. X/*    Error messages in case the environment is not properly set up.
  434. X/* BUGS
  435. X/*    Invites people to put their mail password into the autoexec file.
  436. X/* AUTHOR(S)
  437. X/*    W.Z. Venema
  438. X/*    Eindhoven University of Technology
  439. X/*    Department of Mathematics and Computer Science
  440. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  441. X/* CREATION DATE
  442. X/*    Sun Apr  3 19:34:57 MET 1988
  443. X/* LAST MODIFICATION
  444. X/*    90/01/22 13:01:19
  445. X/* VERSION/RELEASE
  446. X/*    2.1
  447. X/*--*/
  448. X
  449. X#include <stdio.h>
  450. X#include <signal.h>
  451. X#include <varargs.h>
  452. X
  453. X#include "defs.h"
  454. X#include "ndir.h"
  455. X#include "path.h"
  456. X#include "status.h"
  457. X
  458. Xhidden void parse_args();        /* forward declarations */
  459. Xhidden void usage();
  460. Xhidden void error();
  461. Xhidden int newmail();
  462. X
  463. Xhidden char *password = 0;        /* set by the -p option */
  464. X
  465. Xpublic char *progname = "cmail";    /* for diagnostics */
  466. X
  467. Xmain(argc, argv)
  468. Xint     argc;
  469. Xchar  **argv;
  470. X{
  471. X    signal(SIGINT, SIG_IGN);            /* disable ctrl-c */
  472. X    parse_args(argc, argv);            /* parse command args */
  473. X    if (pathinit())                /* check path info */
  474. X    error("cmail: bad MAILDIR environment variable");
  475. X    if (password && *password &&
  476. X    invokelp(CICO, "-p", password, (char *) 0) == E_NOPROG)
  477. X    error("cmail: cannot execute the CICO program");
  478. X    if (invokelp(NMAIL, (char *) 0) == E_NOPROG)
  479. X    error("cmail: cannot execute the NMAIL program");
  480. X    exit(newmail() == 0);            /* look for new mail */
  481. X}
  482. X
  483. X/* parse_args - process command-line arguments */
  484. X
  485. Xhidden void parse_args(argc, argv)
  486. Xint     argc;
  487. Xchar  **argv;
  488. X{
  489. X    while (--argc && *++argv && **argv == '-') {/* process options */
  490. X    switch (*++*argv) {
  491. X    case 'p':                /* call cico first */
  492. X        if (--argc == 0)
  493. X        usage("missing password");
  494. X        password = *++argv;
  495. X        break;
  496. X    default:                /* unknown option */
  497. X        usage("invalid option: -%s", *argv);
  498. X        break;
  499. X    }
  500. X    }
  501. X
  502. X    /* check for extraneous arguments */
  503. X
  504. X    if (argc > 0)
  505. X    usage("unexpected argument: %s", *argv);
  506. X}
  507. X
  508. X/* scan for new unread mail */
  509. X
  510. Xhidden int newmail()
  511. X{
  512. X    DIR    *dp;
  513. X    struct direct *de;
  514. X    FILE   *fp;
  515. X    char    from[MAXLINE];
  516. X    int     msgcount = 0;
  517. X    unsigned msgno;
  518. X
  519. X    /*
  520. X     * Scan the spool directory for unread messages and extract the
  521. X     * originator address from the corresponding meta file.
  522. X     */
  523. X
  524. X    if ((dp = opendir(maildir)) == 0) {
  525. X    error("cmail: cannot access the mail directory");
  526. X    } else {
  527. X    while (de = readdir(dp)) {
  528. X        if (de->d_name[0] == NEW_MESG
  529. X        && (msgno = seqno(de->d_name))
  530. X        && (fp = fopen(new_meta(msgno), "r")) != 0) {
  531. X        if (fgets(from, sizeof(from), fp))
  532. X            printf("You have new mail from %s", from);
  533. X        msgcount++;
  534. X        fclose(fp);
  535. X        }
  536. X    }
  537. X    closedir(dp);
  538. X    }
  539. X    return (msgcount);
  540. X}
  541. X
  542. Xhidden void error(str)
  543. Xchar   *str;
  544. X{
  545. X    fprintf(stderr, "%s\n", str);
  546. X    exit(1);
  547. X}
  548. X
  549. X/* VARARGS */
  550. X
  551. Xhidden void usage(va_alist) 
  552. Xva_dcl
  553. X{
  554. X    va_list ap;
  555. X    char   *fmt;
  556. X
  557. X    va_start(ap);
  558. X    fmt = va_arg(ap, char *);
  559. X    vfprintf(stderr, fmt, ap);
  560. X    va_end(ap);
  561. X    fprintf(stderr, "\nusage: cmail [-p password]\n");
  562. X    exit(1);
  563. X}
  564. END_OF_main/cmail.c
  565. if test 3814 -ne `wc -c <main/cmail.c`; then
  566.     echo shar: \"main/cmail.c\" unpacked with wrong size!
  567. fi
  568. # end of overwriting check
  569. fi
  570. if test -f main/comport.h -a "${1}" != "-c" ; then 
  571.   echo shar: Will not over-write existing file \"main/comport.h\"
  572. else
  573. echo shar: Extracting \"main/comport.h\" \(3203 characters\)
  574. sed "s/^X//" >main/comport.h <<'END_OF_main/comport.h'
  575. X/*
  576. X * Comport.h
  577. X *
  578. X * defines the bit masking for the get_mcr()
  579. X *
  580. X * @(#) comport.h    Version hoptoad-1.3    87/03/24
  581. X *
  582. X * Copyright (C) Tim M. Pozar 1987
  583. X * Anyone can use this code for anything, but it is copyright by Tim
  584. X * and you must leave his copyright in the code.
  585. X *
  586. X */
  587. X
  588. X/*
  589. X * get_msr()
  590. X *   Function to read (get) the byte located in the Modem Status 
  591. X * Register (3FEh).  The table below describes the byte returned.
  592. X *   bit  description
  593. X *    0   Delta Clear to Send (DCTS)
  594. X *        Indicates that the !CTS input to the chip has changed state
  595. X *        since the last time it was read by the processor.
  596. X *    1   Delta Data Set Ready (DDSR)
  597. X *        Indicates that the !DRS input to the chip has changed since 
  598. X *        last time it was read by the processor.
  599. X *    2   Trailing Edge Ring Indicator (TERI)
  600. X *        Indicates that the !RI input to the chip has changed from
  601. X *        an on (logical 1) to an off (logical 0) condition.
  602. X *    3   Delta Rx Line Signal detect (DRLSD)
  603. X *        Indicates that the !RLSD input to the chip has changed state.
  604. X * NOTE: Whenever bit 0, 1, 2, or 3 is set to a logical 1, a modem status
  605. X *       interrupt is generated.
  606. X *
  607. X *    4   Clear to Send (CTS)
  608. X *        This bit is the complement of the clear to send (!CTS) input.
  609. X *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
  610. X *        equivalent to RTS in the MCR.
  611. X *    5   Data Set Ready (DSR)
  612. X *        This bit is the complement of the data set ready (!DSR) input.
  613. X *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
  614. X *        equivalent to DTR in the MCR.
  615. X *    6   Ring Indicator (RI)
  616. X *        This bit is the complement of the ring indicator (!RI) input.
  617. X *        If bit 4 (LOOP) of the MCR is set to a logical 1, this is 
  618. X *        equivalent to OUT 1 in the MCR.
  619. X *    7   Receive Line Signal Detect (RLSD) or Carrier Detect (CD).
  620. X *        This bit is the complement of the received line signal detect
  621. X *        (!RLSD) input. If bit 4 (LOOP) of the MCR is set to a logical 1,
  622. X *        this is equivalent to OUT 2 in the MCR.
  623. X */
  624. X
  625. X#define  DCTS       1
  626. X#define  DDSR       2
  627. X#define  TERI       4
  628. X#define  DRLSD      8
  629. X#define  CTS       16
  630. X#define  DST       32
  631. X#define  RI        64
  632. X#define  RLSD     128   /* Also known as ... */
  633. X#define  CD       128   
  634. X#define  set_tty        SET_TTY     /* find current settings, and initialize */
  635. X#define  reset_tty      RESET_TTY   /* reset to settings that set_tty() found */
  636. X#define  get_msr        GET_MSR     /* get MSR byte from port. */
  637. X#define  init_comm      INIT_COMM   /* initialize the comm port interupts, */
  638. X#define  uninit_comm    UNINIT_COMM /* remove initialization, */
  639. X#define  set_xoff       SET_XOFF    /* enable/disable XON/XOFF, */
  640. X#define  get_xoff       GET_XOFF    /* read XON/XOFF state, */
  641. X#define  rcvd_xoff      RCVD_XOFF   /* returns true if XOFF rcvd, */
  642. X#define  sent_xoff      SENT_XOFF   /* true if XOFF sent, */
  643. X#define  inp_cnt        INP_CNT     /* returns count of rcv chars, */
  644. X#define  inp_char       INP_CHAR    /* get one char from buffer, */
  645. X#define  inp_flush      INP_FLUSH   /* flush input buffer, */
  646. X#define  outp_char      OUTP_CHAR   /* output a character, */
  647. END_OF_main/comport.h
  648. if test 3203 -ne `wc -c <main/comport.h`; then
  649.     echo shar: \"main/comport.h\" unpacked with wrong size!
  650. fi
  651. # end of overwriting check
  652. fi
  653. if test -f main/edit.c -a "${1}" != "-c" ; then 
  654.   echo shar: Will not over-write existing file \"main/edit.c\"
  655. else
  656. echo shar: Extracting \"main/edit.c\" \(3336 characters\)
  657. sed "s/^X//" >main/edit.c <<'END_OF_main/edit.c'
  658. X/*++
  659. X/* NAME
  660. X/*    edit 3
  661. X/* SUMMARY
  662. X/*    edit a file
  663. X/* PROJECT
  664. X/*    pc-mail
  665. X/* PACKAGE
  666. X/*    mail
  667. X/* SYNOPSIS
  668. X/*    #include "mail.h"
  669. X/*
  670. X/*    int edit(fname,tname)
  671. X/*    char *fname,*tname;
  672. X/* DESCRIPTION
  673. X/*    edit() copies the file in fname to the file tname,
  674. X/*    invokes the editor, and copies the result back.
  675. X/* COMMANDS
  676. X/*    the program specified in the EDITOR environment variable,
  677. X/*    or a system-dependent default.
  678. X/* AUTHOR(S)
  679. X/*      W.Z. Venema
  680. X/*      Eindhoven University of Technology
  681. X/*      Department of Mathematics and Computer Science
  682. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  683. X/* CREATION DATE
  684. X/*    Wed Apr  6 20:21:35 MET 1988
  685. X/* LAST MODIFICATION
  686. X/*    90/01/22 13:01:34
  687. X/* VERSION/RELEASE
  688. X/*    2.1
  689. X/*--*/
  690. X
  691. X#include <stdio.h>
  692. X#include <errno.h>
  693. X
  694. X#include "defs.h"
  695. X#include "path.h"
  696. X#include "mail.h"
  697. X#include "status.h"
  698. X
  699. X#ifdef MSDOS
  700. X#   include <fcntl.h>
  701. X#endif
  702. X
  703. X /*
  704. X  * Some editors (wordstar) do not accept path names. grrrr. So we copy the
  705. X  * edit file to a temp file in the current directory. After editing, the
  706. X  * temp file is copied back. We do not move files, since current dir and the
  707. X  * spool dir may be in different file systems, and people might turn off the
  708. X  * machine and lose their work.
  709. X  */
  710. X
  711. X/* edit - edit or create a file */
  712. X
  713. Xpublic int edit(fname, tname)
  714. Xchar   *fname,
  715. X       *tname;
  716. X{
  717. X    register int stat = 0;
  718. X    register FILE *fp;
  719. X
  720. X    /*
  721. X     * First make sure that we can get write permission on the permanent file
  722. X     * and temporary file (if they exist). Create an empty temp file if we
  723. X     * are not editing an existing file.
  724. X     */
  725. X
  726. X    if (chmod(fname, 0666) && errno != ENOENT) {
  727. X    stat = E_WRITERR;            /* original file is protected */
  728. X    } else if (chmod(tname, 0666) && errno != ENOENT) {
  729. X    stat = E_WRITERR;            /* scratch file is protected */
  730. X    } else if ((fp = fopen(fname, "a")) == 0) {
  731. X    stat = E_WRITERR;            /* file system is protected? */
  732. X    } else if (fclose(fp), stat = cpfile(fname, tname)) {
  733. X     /* void */ ;                /* could not make edit copy */
  734. X    } else {
  735. X    patience();                /* this may take some time */
  736. X    kbdrest();                /* reset tty modes */
  737. X    if (stat = invokelp(editor, tname, (char *) 0))    /* call editor */
  738. X        stat = (stat == E_NOPROG ? stat : E_UNKNOWN);
  739. X    else
  740. X        stat = cpfile(tname, fname);    /* copy back */
  741. X    kbdinit();                /* set tty modes */
  742. X    unlink(tname);                /* don't check status */
  743. X    }
  744. X    chmod(fname, 0444);                /* protect destination file */
  745. X    return (stat);
  746. X}
  747. X
  748. X/* cpfile - yet another file copy function */
  749. X
  750. Xhidden int cpfile(from, to)
  751. Xchar   *from;
  752. Xchar   *to;
  753. X{
  754. X    register FILE *in,
  755. X           *out;            /* file pointers */
  756. X    int     stat = 0;            /* error status */
  757. X    register int c;            /* character buffer */
  758. X
  759. X    if ((in = fopen(from, "r")) == 0) {        /* cannot read source */
  760. X    return (E_READERR);
  761. X    } else if ((out = fopen(to, "w")) == 0) {    /* cannot write destination */
  762. X    fclose(in);
  763. X    return (E_WRITERR);
  764. X    } else {
  765. X
  766. X#ifdef O_BINARY
  767. X    setmode(fileno(in), O_BINARY);        /* get rid of the */
  768. X    setmode(fileno(out), O_BINARY);        /* crlf translation */
  769. X#endif
  770. X    while ((c = getc(in)) != EOF)
  771. X        putc(c, out);
  772. X    if (ferror(in))                /* check read error status */
  773. X        stat = E_READERR;
  774. X    else if (ferror(out))            /* check write error status */
  775. X        stat = E_WRITERR;
  776. X    fclose(in);
  777. X    fclose(out);
  778. X    return (stat);                /* at most one type of error */
  779. X    }
  780. X}
  781. END_OF_main/edit.c
  782. if test 3336 -ne `wc -c <main/edit.c`; then
  783.     echo shar: \"main/edit.c\" unpacked with wrong size!
  784. fi
  785. # end of overwriting check
  786. fi
  787. if test -f main/getwork.c -a "${1}" != "-c" ; then 
  788.   echo shar: Will not over-write existing file \"main/getwork.c\"
  789. else
  790. echo shar: Extracting \"main/getwork.c\" \(2974 characters\)
  791. sed "s/^X//" >main/getwork.c <<'END_OF_main/getwork.c'
  792. X/*++
  793. X/* NAME
  794. X/*    getwork 3
  795. X/* SUMMARY
  796. X/*    receive work from remote system
  797. X/* PROJECT
  798. X/*    pc-mail
  799. X/* PACKAGE
  800. X/*    cico
  801. X/* SYNOPSIS
  802. X/*    #include "work.h"
  803. X/*
  804. X/*      work *rmtwork(rqst)
  805. X/*      char *rqst;
  806. X/*
  807. X/*    void getwork(wrk)
  808. X/*    work *wrk;
  809. X/* DESCRIPTION
  810. X/*      rmtwork() parses a remote Send request. A suitable destination
  811. X/*    file is opened. The resulting work structure is for use by
  812. X/*    getwork().
  813. X/*
  814. X/*    getwork() receives a file from the remote system, after the
  815. X/*    necessary preparations have been done by rmtwork().
  816. X/*    The file is deleted in case of transmission failure.
  817. X/* FUNCTIONS AND MACROS
  818. X/*    trap(), locname()
  819. X/* SEE ALSO
  820. X/*    sendwork(), scanwork()
  821. X/* DIAGNOSTICS
  822. X/*    Exceptions are handled with longjmp(systrap,errorcode).
  823. X/*
  824. X/*    rmtwork() traps in case of invalid requests or if the destination
  825. X/*    file could not be opened.
  826. X/*
  827. X/*    getwork() traps in case of read/write errors.
  828. X/* AUTHOR(S)
  829. X/*    W.Z. Venema
  830. X/*    Eindhoven University of Technology
  831. X/*    Department of Mathematics and Computer Science
  832. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  833. X/* CREATION DATE
  834. X/*    Sat Mar 28 16:57:57 GMT+1:00 1987
  835. X/* LAST MODIFICATION
  836. X/*    90/01/22 13:01:39
  837. X/* VERSION/RELEASE
  838. X/*    2.1
  839. X/*--*/
  840. X
  841. X#include <stdio.h>
  842. X
  843. X#include "defs.h"
  844. X#include "logs.h"
  845. X#include "status.h"
  846. X#include "work.h"
  847. X#include "params.h"
  848. X#include "comm.h"
  849. X
  850. X/* rmtwork - parse remote S request and open destination file */
  851. X
  852. Xpublic work *rmtwork(rqst)
  853. Xchar   *rqst;
  854. X{
  855. X    static work wrk;
  856. X    char    path[BUFSIZ];
  857. X
  858. X    if (sscanf(rqst, "S %*s %s", path) != 1)    /* pick destination file name */
  859. X    trap(E_LOST, "BAD REQUEST FORMAT");
  860. X    debug(5) ("rmtwork: path %s\n", path);
  861. X    strcpy(wrk.path, locname(path));        /* convert to local name */
  862. X    debug(5) ("rmtwork: file %s\n", wrk.path);
  863. X    if ((wrk.fp = fopen(wrk.path, "w")) == 0)    /* try to open that file */
  864. X    trap(E_WRITERR, "CAN'T CREATE FILE (%s)", sys_errlist[errno]);
  865. X    return (&wrk);
  866. X}
  867. X
  868. X/* getwork - receive file from remote host */
  869. X
  870. Xpublic void getwork(wrk)
  871. Xregister work *wrk;
  872. X{
  873. X    char    buf[BUFSIZ];
  874. X    register int nread;
  875. X    register int werror;
  876. X
  877. X    while ((nread = CALL(Read) (ttfd, buf, BUFSIZ)) > 0 &&
  878. X       fwrite(buf, sizeof(*buf), nread, wrk->fp) == nread)
  879. X     /* void */ ;
  880. X    werror = ferror(wrk->fp);            /* record error status */
  881. X    fclose(wrk->fp);
  882. X
  883. X    /*
  884. X     * In case of any errors we force a protocol shutdown. The oher side will
  885. X     * send the same file again next time we make a connection.
  886. X     */
  887. X
  888. X    if (nread < 0) {                /* did the protocol fail? */
  889. X    chmod(wrk->path, 0666);            /* make file deletable */
  890. X    unlink(wrk->path);            /* remove file */
  891. X    trap(E_LOST, "FAILED (lost link)");    /* handle exception */
  892. X    /* NOTREACHED */
  893. X    } else if (werror) {            /* file write error? */
  894. X    chmod(wrk->path, 0666);            /* make file deletable */
  895. X    unlink(wrk->path);            /* remove file */
  896. X    trap(E_WRITERR, "FILE WRITE ERROR (%s)", sys_errlist[errno]);
  897. X    /* NOTREACHED */
  898. X    } else {
  899. X    chmod(wrk->path, 0444);            /* protect the file */
  900. X    }
  901. X}
  902. END_OF_main/getwork.c
  903. if test 2974 -ne `wc -c <main/getwork.c`; then
  904.     echo shar: \"main/getwork.c\" unpacked with wrong size!
  905. fi
  906. # end of overwriting check
  907. fi
  908. if test -f main/hsearch.3 -a "${1}" != "-c" ; then 
  909.   echo shar: Will not over-write existing file \"main/hsearch.3\"
  910. else
  911. echo shar: Extracting \"main/hsearch.3\" \(3042 characters\)
  912. sed "s/^X//" >main/hsearch.3 <<'END_OF_main/hsearch.3'
  913. X.TH HSEARCH 3c local
  914. X.SH NAME
  915. Xhsearch, hcreate, hdestroy \- manage hash search tables
  916. X.SH SYNOPSIS
  917. X.nf
  918. X.ft B
  919. Xtypedef struct entry {
  920. X    char *key;
  921. X    char *data;
  922. X    } ENTRY;
  923. X
  924. Xtypedef enum {
  925. X    FIND,
  926. X    ENTER
  927. X    } ACTION;
  928. X
  929. XENTRY *hsearch (item, action)
  930. XENTRY item;
  931. XACTION action;
  932. X
  933. Xint hcreate (nel)
  934. Xunsigned int nel;
  935. X
  936. Xvoid hdestroy ();
  937. X.br
  938. X.ft R
  939. X.fi
  940. X.SH DESCRIPTION
  941. X.I Hsearch
  942. Xis a simple, public domain, reimplementation of the routine of the same
  943. Xname in
  944. X.SM UNIX
  945. XSystem V.
  946. X.PP
  947. X.I Hsearch
  948. Xreturns a pointer into a hash table where a given element can be found.
  949. XAn
  950. X.I item
  951. Xto be stored in the table is of type ENTRY.
  952. X.I Item.key
  953. Xpoints to the key used for comparison, while
  954. X.I item.data
  955. Xpoints to the data to be associated with the key.
  956. XIf the data pointed to is not a character string, it should be cast
  957. Xto type pointer-to-character before being assigned.
  958. XNote that
  959. X.I item
  960. Xis a structure, and
  961. X.I not
  962. Xa pointer to a structure.
  963. XIf the value of
  964. X.I action
  965. Xis FIND,
  966. X.I hsearch
  967. Xwill return a pointer to the item in the table, if it is there, otherwise
  968. Xit will return NULL.  If the action is ENTER, it will return a pointer
  969. Xto the new item, or NULL if it could not add the item to the table.
  970. XNote that if the action is ENTER, and the item was already in the table, the
  971. X.I data
  972. Xfield will be updated from the new
  973. X.IR item .
  974. X.PP
  975. X.I Hsearch
  976. Xdoes not provide all the (compile-time) options of the original routine;
  977. Xinstead it uses a
  978. X.I remainder modulo table size
  979. Xhashing algorithm,
  980. X.I chaining
  981. X(linked lists) to resolve collisions, with new entries being placed at
  982. Xthe end, and
  983. X.IR strcmp (3)
  984. Xfor the comparison function.
  985. XIt was felt that a simple reimplementation was called for,
  986. Xinstead of a brand new hash table package,
  987. Xsince the interface provided is a clean one,
  988. Xbut the original source code is not publicly available.
  989. X.PP
  990. X.I Hcreate
  991. Xcreates the hash table, allocating enough space for it.  It must be
  992. Xcalled before
  993. X.IR hsearch .
  994. X.I Nel
  995. Xis an estimate of the number of hash buckets that will be needed;
  996. Xthe table size will be adjusted up to the next largest prime number.  If
  997. X.I nel
  998. Xis larger than the largest prime known to
  999. X.IR hcreate , " nel"
  1000. Xwill be used directly.
  1001. X.PP
  1002. X.I Hdestroy
  1003. Xdestroys the hash table, freeing up all its storage.  It may be followed
  1004. Xby another call to
  1005. X.IR hcreate .
  1006. X.SH SEE ALSO
  1007. X.IR malloc (3),
  1008. X.IR strcmp (3),
  1009. Xthe various other searching routines available with System V.
  1010. X.SH DIAGNOSTICS
  1011. X.I Hsearch
  1012. Xreturns NULL
  1013. Xif either the action was FIND and the item is not in the table, or
  1014. Xthe action was ENTER but the item could not be inserted.
  1015. X.PP
  1016. X.I Hcreate
  1017. Xreturns zero if it could not create the initial table; it returns
  1018. Xone if all went well.
  1019. X.SH BUGS
  1020. X.PP
  1021. XOnly one hash table may be active at a given time.
  1022. X.PP
  1023. XNot as flexible as the original System V implementation.
  1024. X.SH AUTHOR
  1025. X.nf
  1026. XArnold Robbins
  1027. XSchool of Information and Computer Science
  1028. XGeorgia Institute of Technology
  1029. XAtlanta, Georgia   30332
  1030. X
  1031. XCSNET:    arnold@gatech
  1032. XARPA:    arnold%gatech.csnet@csnet-relay.arpa
  1033. XUUCP:    { akgua, allegra, hplabs, ihnp4, seismo, ut-sally }!gatech!arnold
  1034. END_OF_main/hsearch.3
  1035. if test 3042 -ne `wc -c <main/hsearch.3`; then
  1036.     echo shar: \"main/hsearch.3\" unpacked with wrong size!
  1037. fi
  1038. # end of overwriting check
  1039. fi
  1040. if test -f main/kproto.ms -a "${1}" != "-c" ; then 
  1041.   echo shar: Will not over-write existing file \"main/kproto.ms\"
  1042. else
  1043. echo shar: Extracting \"main/kproto.ms\" \(2984 characters\)
  1044. sed "s/^X//" >main/kproto.ms <<'END_OF_main/kproto.ms'
  1045. X.TL
  1046. Xuucp k protocol description
  1047. X.AU
  1048. XW.Z. Venema
  1049. XEindhoven University of Technology
  1050. X.AE
  1051. X.NH
  1052. XIntroduction
  1053. X.LP
  1054. XThe k protocol has been developed for the Sytek Localnet local area
  1055. Xnetwork at the Eindhoven University of Technology (TUE).
  1056. XMain features of this network are:
  1057. X.IP     1
  1058. XNetwork partners may talk at different baudrates. This implies that the network
  1059. Xdoes some buffering. This may cause timing
  1060. Xproblems (e.g. a system sending at 9600 baud to a system reading at 1200 baud).
  1061. X.IP     2
  1062. XThe network needs a flow control mechanism. Usually this is
  1063. Xbased on the XON/XOFF protocol. Other control character sequences are used
  1064. Xfor commands to the network.
  1065. X.IP     3
  1066. XSome network stations are connected to telephone modems.
  1067. X.LP
  1068. XFor these reasons, the k protocol must (i) cope with on XON/XOFF flow
  1069. Xcontrol, (ii) be suitable for 7-bit data paths, (iii) avoid
  1070. Xcontrol characters and (iv) provide reliable operation
  1071. Xover telephone lines as well as over the local area network.
  1072. X.NH
  1073. XPackets
  1074. X.LP
  1075. XData are sent as checksummed 256-byte packets, terminated by an
  1076. XASCII CR. Except for the packet header (^P), the k protocol only uses
  1077. XASCII codes 040 through 0137. Three data bytes are expanded to four
  1078. Xbytes upon transmission. Theoretically, this reduces throughput by 25 percent.
  1079. XAt 1200 baud, actual performances are:
  1080. X.DS
  1081. Xuucp, g protocol    110 cps
  1082. Xuucp, k protocol    74 cps
  1083. Xc-kermit        67 cps
  1084. X.DE
  1085. XNote that the values for c-kermit are for text files, with repeat-count
  1086. Xcompression enabled.
  1087. X.PP
  1088. XThe packet types are a subset of those used in the kermit programs:
  1089. X.DS
  1090. XD packets contain data.
  1091. XY packets are sent when a correct data packet was received.
  1092. XN packets are sent when incorrect data was received.
  1093. XA packets are sent to shut down the k protocol.
  1094. X.DE
  1095. XA packet always begins with a header:
  1096. X.DS
  1097. XSOH     packet header, ASCII control-P
  1098. Xlen     (size of data, low 6 bits) + 32
  1099. Xlen     (size of data, high 6 bits) + 32
  1100. Xnum     (packet number mod 64) + 32
  1101. Xtype    packet type
  1102. Xcheck   one-byte type-1 kermit checksum
  1103. X.DE
  1104. X.LP
  1105. XThe header is followed by checksummed data if len > 0:
  1106. X.DS
  1107. Xdata    len data bytes
  1108. Xcheck1  (upper 2 bits of type-3 kermit 16-bit checksum) + 32
  1109. Xcheck2  (middle 6 bits of type-3 kermit 16-bit checksum) + 32
  1110. Xcheck3  (lower 6 bits of type-3 kermit 16-bit checksum) + 32
  1111. X.DE
  1112. X.LP
  1113. XEvery packet is followed by an ASCII carriage return, which is
  1114. Xignored upon reception of a packet. It prevents timeout errors
  1115. Xwhen one byte gets lost (the most common case).
  1116. X.NH
  1117. XHandshake
  1118. X.LP
  1119. XHandshake is on a per-packet basis; a transmitter will not send
  1120. Xanother data packet before it knows that the receiver got the data
  1121. Xin good condition. There are various ways to obtain that knowledge:
  1122. Xthe receiver may send an ACK message (usual case), or a NAK for
  1123. Xthe next data packet, or a data packet with the next sequence number.
  1124. X.PP
  1125. XThe protocol is aborted when an unexpected
  1126. Xpacket type or when a packet out of sequence is received.
  1127. XSince 'A' packets are never expected, they always cause a protocol
  1128. Xfault.
  1129. END_OF_main/kproto.ms
  1130. if test 2984 -ne `wc -c <main/kproto.ms`; then
  1131.     echo shar: \"main/kproto.ms\" unpacked with wrong size!
  1132. fi
  1133. # end of overwriting check
  1134. fi
  1135. if test -f main/lmail.c -a "${1}" != "-c" ; then 
  1136.   echo shar: Will not over-write existing file \"main/lmail.c\"
  1137. else
  1138. echo shar: Extracting \"main/lmail.c\" \(2815 characters\)
  1139. sed "s/^X//" >main/lmail.c <<'END_OF_main/lmail.c'
  1140. X/*++
  1141. X/* NAME
  1142. X/*      lmail 1
  1143. X/* SUMMARY
  1144. X/*      local delivery of mail received via GNUUCP
  1145. X/* PROJECT
  1146. X/*      pc-mail
  1147. X/* PACKAGE
  1148. X/*      gnu
  1149. X/* SYNOPSIS
  1150. X/*      lmail [arguments]
  1151. X/* DESCRIPTION
  1152. X/*    This program replaces the receiving function of the pc-mail "cico"
  1153. X/*    program, on systems that use GNUUCP for message transport.
  1154. X/*
  1155. X/*      lmail reads one mail message from its standard input and installs
  1156. X/*    it as a message file in the pc-mail mail data base. Any command-line
  1157. X/*    arguments are ignored (since pc-mail is a single-user mail system).
  1158. X/*
  1159. X/*    This command should be installed such that it can be found by the 
  1160. X/*    GNUUCP "rmail" command. The actual program name may be different
  1161. X/*    from "lmail"; this depends on how the GNUUCP software was configured.
  1162. X/* ENVIRONMENT
  1163. X/*    MAILDIR, path to pc-mail message data base
  1164. X/* FILES
  1165. X/*      In the spool directory:
  1166. X/*    h<seqno>    new mail message.
  1167. X/* SEE ALSO
  1168. X/*      path(5)         spool directory, file names
  1169. X/*    nmail(1)    extracts sender and subject from new mail.
  1170. X/* DIAGNOSTICS
  1171. X/*      Problems are reported on the standard error output, and cause the
  1172. X/*    program to terminate with a nonzero exit status.
  1173. X/* AUTHOR(S)
  1174. X/*      W.Z. Venema
  1175. X/*      Eindhoven University of Technology
  1176. X/*      Department of Mathematics and Computer Science
  1177. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1178. X/* CREATION DATE
  1179. X/*    Wed Jan  3 22:16:08 MET 1990
  1180. X/* LAST MODIFICATION
  1181. X/*    90/01/22 13:02:00
  1182. X/* VERSION/RELEASE
  1183. X/*    2.1
  1184. X/*--*/
  1185. X
  1186. X#include <stdio.h>
  1187. X#include <varargs.h>
  1188. X
  1189. X#include "defs.h"
  1190. X#include "path.h"
  1191. X
  1192. Xextern int errno;
  1193. Xextern char *sys_errlist[];
  1194. X
  1195. Xextern char *fgets();
  1196. X
  1197. Xhidden void error();
  1198. Xpublic char *progname = "lmail";
  1199. X
  1200. X/* pc-mail is a single-user mailer, so we ignore command-line arguments */
  1201. X
  1202. Xmain()
  1203. X{
  1204. X    char    buf[BUFSIZ];
  1205. X    char   *fname;
  1206. X    FILE   *fp;
  1207. X
  1208. X    /* Find out where the mail data base lives */
  1209. X
  1210. X    if (pathinit())
  1211. X    error("no mail directory or MAILDIR environment variable not set");
  1212. X
  1213. X    /* Create a mail message file only - let nmail extract sender and subject */
  1214. X
  1215. X    (void) umask(0222);                /* make files read-only */
  1216. X    if ((fp = fopen(fname = new_mesg(newseqno()), "w")) == 0)
  1217. X    error("cannot open %s: %s", fname, sys_errlist[errno]);
  1218. X
  1219. X    /* Copy standard input to message file */
  1220. X
  1221. X    while (fgets(buf, sizeof(buf), stdin))
  1222. X    (void) fputs(buf, fp);
  1223. X
  1224. X    /* Error checking */
  1225. X
  1226. X    if (fflush(fp) || ferror(fp) || fclose(fp))
  1227. X    error("%s: write error: %s", fname, sys_errlist[errno]);
  1228. X
  1229. X    exit(0);
  1230. X    /* NOTREACHED */
  1231. X}
  1232. X
  1233. X/* error - complain */
  1234. X
  1235. X/* VARARGS */
  1236. X
  1237. Xhidden void error(va_alist) 
  1238. Xva_dcl
  1239. X{
  1240. X    va_list ap;
  1241. X    char   *fmt;
  1242. X
  1243. X    (void) fprintf(stderr, "%s: ", progname);
  1244. X    va_start(ap);
  1245. X    fmt = va_arg(ap, char *);
  1246. X    (void) vfprintf(stderr, fmt, ap);
  1247. X    va_end(ap);
  1248. X    (void) putc('\n', stderr);
  1249. X    exit(2);
  1250. X}
  1251. END_OF_main/lmail.c
  1252. if test 2815 -ne `wc -c <main/lmail.c`; then
  1253.     echo shar: \"main/lmail.c\" unpacked with wrong size!
  1254. fi
  1255. # end of overwriting check
  1256. fi
  1257. if test -f main/mail.c -a "${1}" != "-c" ; then 
  1258.   echo shar: Will not over-write existing file \"main/mail.c\"
  1259. else
  1260. echo shar: Extracting \"main/mail.c\" \(4002 characters\)
  1261. sed "s/^X//" >main/mail.c <<'END_OF_main/mail.c'
  1262. X/*++
  1263. X/* NAME
  1264. X/*      mail
  1265. X/* SUMMARY
  1266. X/*      visual mail-shell
  1267. X/* PROJECT
  1268. X/*      pc-mail
  1269. X/* PACKAGE
  1270. X/*      mail
  1271. X/* SYNOPSIS
  1272. X/*      mail
  1273. X/* DESCRIPTION
  1274. X/*      mail is an interactive program for reading, receiving
  1275. X/*      and producing electronic mail. Actually, most of the work
  1276. X/*    is done by programs called by the mail program.
  1277. X/*
  1278. X/*      By default, the program presents the user display of a list of
  1279. X/*      mail messages in the form of one-line summaries. Single-key
  1280. X/*    commands are available to select and manipulate mail messages.
  1281. X/*    Mail messages are created with an editor chosen by the user.
  1282. X/*
  1283. X/*      The name of the spool directory, printer program and editor
  1284. X/*      are taken from the environment, or assume system-dependent defaults.
  1285. X/* ENVIRONMENT
  1286. X/*      MAILDIR        name of spool directory
  1287. X/*      EDITOR          name of program to create mail
  1288. X/*    MAILPRN        name of program/file to print with/to
  1289. X/*    MAILCMD        command to execute upon termination
  1290. X/* COMMANDS
  1291. X/*      cico            network communications program
  1292. X/*      nmail           postprocessor for mail received by cico
  1293. X/* FILES
  1294. X/*      The mail system maintains various files in a spool directory,
  1295. X/*      as well as a logfile of all network transactions.
  1296. X/* SEE ALSO
  1297. X/*      path(3)         system-dependent path names
  1298. X/* DIAGNOSTICS
  1299. X/*      Error messages should be self-explanatory.
  1300. X/* BUGS
  1301. X/*      The user has to explicitly tell the system to contact a remote
  1302. X/*    mail host. This is a limitation of MS-DOS, not of the program.
  1303. X/* AUTHOR(S)
  1304. X/*      W.Z. Venema
  1305. X/*      Eindhoven University of Technology
  1306. X/*      Department of Mathematics and Computer Science
  1307. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1308. X/* CREATION DATE
  1309. X/*      Thu Apr  2 21:54:08 GMT+1:00 1987
  1310. X/* LAST MODIFICATION
  1311. X/*    90/01/22 13:02:04
  1312. X/* VERSION/RELEASE
  1313. X/*    2.1
  1314. X/*--*/
  1315. X
  1316. X#include <stdio.h>
  1317. X#include <signal.h>
  1318. X#include "defs.h"
  1319. X#include "path.h"
  1320. X#include "status.h"
  1321. X#include "mail.h"
  1322. X#include "window.h"
  1323. X
  1324. Xpublic char *progname = "mail";        /* for diagnostics */
  1325. X
  1326. X/* forward declarations */
  1327. X
  1328. Xhidden int checkfiles();
  1329. X
  1330. X/* for now, don't even try to look at command args */
  1331. X
  1332. Xpublic  main(argc, argv)
  1333. Xint     argc;
  1334. Xchar  **argv;
  1335. X{
  1336. X    register int stat;
  1337. X
  1338. X    /*
  1339. X     * Initializations: get screen control and function-key codes (wininit).
  1340. X     * check if the limit on the number of open files is ok (checkfiles), get
  1341. X     * the values from environment variables (pathinit), set the terminal
  1342. X     * driver to the desired mode (kbdinit), check for partally processed new
  1343. X     * mail with the nmail program. Also make sure that our file permissions
  1344. X     * are safe (umask).
  1345. X     */
  1346. X
  1347. X    if (!isatty(fileno(stdin))) {
  1348. X    perror("mail: standard input");
  1349. X    exit(1);
  1350. X    }
  1351. X    umask(022);                    /* avoid problems */
  1352. X    wininit();                    /* do termcap stuff */
  1353. X    clrscreen();                /* clear screen */
  1354. X    (stat = checkfiles())            /* get max nbr of open files */
  1355. X    ||(stat = pathinit())            /* get spool, printer, editor */
  1356. X    ||(stat = invokelp(NMAIL, (char *) 0));    /* just in case there's mail */
  1357. X    kbdinit();                    /* set to tty RAW, NOECHO */
  1358. X    if (stat) {
  1359. X    errdisp(stat);                /* we have a problem */
  1360. X    } else {
  1361. X    init();                    /* start the machine */
  1362. X    }
  1363. X
  1364. X    /* finalizations */
  1365. X
  1366. X    kbdrest();                    /* restore tty driver */
  1367. X    clrscreen();                /* clear screen */
  1368. X    fflush(stdout);
  1369. X    if (stat == 0)
  1370. X    onexit(mailcmd);            /* do exit command */
  1371. X    exit(stat);
  1372. X    /* NOTREACHED */
  1373. X}
  1374. X
  1375. X/* checkfiles - make sure we can open as many files as we want */
  1376. X
  1377. Xhidden int checkfiles()
  1378. X{
  1379. X    register int i;
  1380. X    int     fds[MINFILES];
  1381. X    register int stat;
  1382. X
  1383. X    for (i = 0; i < MINFILES; i++)        /* try to open many files */
  1384. X    if ((fds[i] = open(NULLDEV, 0)) < 0)
  1385. X        break;
  1386. X
  1387. X    stat = (i < MINFILES ? E_FILENO : 0);    /* did we fail? */
  1388. X
  1389. X    while (--i >= 0)                /* release files */
  1390. X    close(fds[i]);
  1391. X    return (stat);
  1392. X}
  1393. X
  1394. X/* onexit - exec another command */
  1395. X
  1396. Xint     onexit(command)
  1397. Xchar   *command;
  1398. X{
  1399. X    if (command && *command)
  1400. X    return (system(command));
  1401. X}
  1402. END_OF_main/mail.c
  1403. if test 4002 -ne `wc -c <main/mail.c`; then
  1404.     echo shar: \"main/mail.c\" unpacked with wrong size!
  1405. fi
  1406. # end of overwriting check
  1407. fi
  1408. if test -f main/ms_parse.c -a "${1}" != "-c" ; then 
  1409.   echo shar: Will not over-write existing file \"main/ms_parse.c\"
  1410. else
  1411. echo shar: Extracting \"main/ms_parse.c\" \(3953 characters\)
  1412. sed "s/^X//" >main/ms_parse.c <<'END_OF_main/ms_parse.c'
  1413. X/*++
  1414. X/* NAME
  1415. X/*      ms_parse 3
  1416. X/* SUMMARY
  1417. X/*      message parser
  1418. X/* PROJECT
  1419. X/*      pc-mail
  1420. X/* PACKAGE
  1421. X/*      mailsh
  1422. X/* SYNOPSIS
  1423. X/*    #include "ms_parse.h"
  1424. X/*
  1425. X/*    int ms_parse(context, line)
  1426. X/*    int context;
  1427. X/*    char *line;
  1428. X/*
  1429. X/*    int hscanf(line, prefix, format, result)
  1430. X/*    char *line;
  1431. X/*    char *prefix;
  1432. X/*    char *format;
  1433. X/*    char *result;
  1434. X/* DESCRIPTION
  1435. X/*    The routines in this module recognize
  1436. X/*    the context in which successive lines of text occur within an
  1437. X/*    e-mail message, or extract specific information from header
  1438. X/*    lines.
  1439. X/*
  1440. X/*    The expected format of an e-mail message is: UUCP header lines,
  1441. X/*    RFC822-like header lines, message body. Each of these sections
  1442. X/*    may be missing from the message. A header line is a line that
  1443. X/*    has no blanks before the first colon appearing on that line.
  1444. X/*
  1445. X/*    ms_parse() determines the context in which a line of text was found:
  1446. X/*
  1447. X/* .nf
  1448. X    MS_UUCP        UUCP-style From_ line
  1449. X    MS_HEADER    RFC822-like header line
  1450. X    MS_CONT        Continued header line
  1451. X    MS_BODY        Line within message body
  1452. X/* .fi
  1453. X/*
  1454. X/*    During the first call of ms_parse(), the context argument should have 
  1455. X/*    the value MS_UUCP. Upon successive calls the value should be equal
  1456. X/*    to the last value returned by ms_parse(). The algorithm is transparent
  1457. X/*    to other context values (i.e. they cause no transitions).
  1458. X/*
  1459. X/*    hscanf() compares the beginning of a line with the specified prefix
  1460. X/*    (ignoring case differences), and if the comparison succeeds, it
  1461. X/*    invokes sscanf() on the remainder of that line. A zero return value
  1462. X/*    means that no information was extracted with sscanf.
  1463. X/* AUTHOR(S)
  1464. X/*      W.Z. Venema
  1465. X/*      Eindhoven University of Technology
  1466. X/*      Department of Mathematics and Computer Science
  1467. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1468. X/* CREATION DATE
  1469. X/*    Sat Dec  9 18:50:35 MET 1989
  1470. X/* LAST MODIFICATION
  1471. X/*    90/01/22 13:02:12
  1472. X/* VERSION/RELEASE
  1473. X/*    2.1
  1474. X/*--*/
  1475. X
  1476. X#include <stdio.h>
  1477. X#include <ctype.h>
  1478. X
  1479. X#include "defs.h"
  1480. X#include "ms_parse.h"
  1481. X
  1482. X/* forward declarations */
  1483. X
  1484. Xhidden int isheader();
  1485. X
  1486. X/* hscanf - match header and extract info from remainder of header line */
  1487. X
  1488. Xpublic int hscanf(line, pre, fmt, ptr)
  1489. Xchar   *line;
  1490. Xchar   *pre;
  1491. Xchar   *fmt;
  1492. Xchar   *ptr;
  1493. X{
  1494. X    int     len = strlen(pre);
  1495. X
  1496. X    return (istrncmp(pre, line, len) == 0 && sscanf(line + len, fmt, ptr) == 1);
  1497. X}
  1498. X
  1499. X/* ms_parse - parse one message line */
  1500. X
  1501. Xpublic int ms_parse(context, line)
  1502. Xregister int context;
  1503. Xregister char *line;
  1504. X{
  1505. X
  1506. X    /*
  1507. X     * A message may begin with UUCP header lines ("From blablabla",
  1508. X     * sometimes escaped with a ">" character), followed by RFC822-like
  1509. X     * header lines (lines that start with a word + colon, or continuation
  1510. X     * lines that start with whitespace), followed by the remainder of the
  1511. X     * message. Header and body are usually separated by an empty line (on
  1512. X     * systems that can handle that) but the we do not require this.
  1513. X     */
  1514. X
  1515. X    switch (context) {
  1516. X    case MS_UUCP:
  1517. X    if (line[0] == '>' || strncmp(line, "From ", 5) == 0)
  1518. X        return (MS_UUCP);
  1519. X    if (isspace(line[0]))
  1520. X        return (MS_BODY);
  1521. X    /* FALLTHROUGH */
  1522. X    case MS_HEADER:
  1523. X    case MS_CONT:
  1524. X    if (isspace(line[0]))
  1525. X        return (MS_CONT);
  1526. X    if (isheader(line))
  1527. X        return (MS_HEADER);
  1528. X    /* FALLTHROUGH */
  1529. X    case MS_BODY:
  1530. X    return (MS_BODY);
  1531. X    }
  1532. X    /* NOTREACHED */
  1533. X}
  1534. X
  1535. X/* isheader - does this line look like a header? */
  1536. X
  1537. Xhidden int isheader(buf)
  1538. Xchar   *buf;
  1539. X{
  1540. X    static char blanks[] = " \t\f";
  1541. X    char   *cp;
  1542. X    char   *blk;
  1543. X    char   *colon;
  1544. X
  1545. X    /*
  1546. X     * A header line has no blanks before the first colon. Which means that a
  1547. X     * line that starts with a colon character is treated as header line.
  1548. X     * This turns out to be what many sendmail implementations do, too.
  1549. X     */
  1550. X
  1551. X    if ((colon = index(buf, ':')) == 0) {    /* check for colon */
  1552. X    return (0);
  1553. X    } else {                    /* find preceding blanks */
  1554. X    for (cp = blanks; *cp; cp++)
  1555. X        if ((blk = index(buf, *cp)) != 0 && blk < colon)
  1556. X        return (0);
  1557. X    }
  1558. X    return (1);
  1559. X}
  1560. END_OF_main/ms_parse.c
  1561. if test 3953 -ne `wc -c <main/ms_parse.c`; then
  1562.     echo shar: \"main/ms_parse.c\" unpacked with wrong size!
  1563. fi
  1564. # end of overwriting check
  1565. fi
  1566. if test -f main/params.c -a "${1}" != "-c" ; then 
  1567.   echo shar: Will not over-write existing file \"main/params.c\"
  1568. else
  1569. echo shar: Extracting \"main/params.c\" \(3364 characters\)
  1570. sed "s/^X//" >main/params.c <<'END_OF_main/params.c'
  1571. X/*++
  1572. X/* NAME
  1573. X/*    params 3
  1574. X/* SUMMARY
  1575. X/*    communication parameter access
  1576. X/* PROJECT
  1577. X/*    pc-mail
  1578. X/* PACKAGE
  1579. X/*    library
  1580. X/* SYNOPSIS
  1581. X/*    #include "params.h"
  1582. X/*
  1583. X/*    Info *getparams();
  1584. X/* DESCRIPTION
  1585. X/*    getparams() returns a pointer to a table with communications
  1586. X/*    parameters. Usually communications parameters are set with the
  1587. X/*    "setup" option in the main menu of the interactive mail program.
  1588. X/*
  1589. X/*    First getparams() attempts to read from the setup file.
  1590. X/*    If that fails it creates an empty parameter table with
  1591. X/*    null string pointers as parameter values.
  1592. X/* FUNCTIONS AND MACROS
  1593. X/*    myalloc()
  1594. X/* BUGS
  1595. X/*    getparams() silently ignores any information in the
  1596. X/*    parameter file that it does not recognize.
  1597. X/*    getparams() will read the parameter file upon each call, even
  1598. X/*    if nothing has changed since the last read. Let us say that
  1599. X/*    it anticipates on multi-user environments.
  1600. X/* AUTHOR(S)
  1601. X/*    W.Z. Venema
  1602. X/*    Eindhoven University of Technology
  1603. X/*    Department of Mathematics and Computer Science
  1604. X/*    Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1605. X/* CREATION DATE
  1606. X/*    Wed Apr  8 15:39:23 GMT+1:00 1987
  1607. X/* LAST MODIFICATION
  1608. X/*    90/01/22 13:02:24
  1609. X/* VERSION/RELEASE
  1610. X/*    2.1
  1611. X/*--*/
  1612. X
  1613. X#include <stdio.h>
  1614. X#include <ctype.h>
  1615. X
  1616. X#include "defs.h"
  1617. X#include "path.h"
  1618. X#include "params.h"
  1619. X
  1620. X/* Storage area for setup parameters */
  1621. X
  1622. Xhidden Info params[] = {
  1623. X    /* name */    /* name length */    /* value */    /* default */
  1624. X    S_IGNORE,    sizeof(S_IGNORE) -1,    0,        D_IGNORE,
  1625. X#ifndef    DAEMON
  1626. X    S_PORT,    sizeof(S_PORT) - 1,    0,        0,
  1627. X    S_BAUD,    sizeof(S_BAUD) - 1,    0,        0,
  1628. X    S_HOST,    sizeof(S_HOST) - 1,    0,        0,
  1629. X    S_LOGIN,    sizeof(S_LOGIN) - 1,    0,        0,
  1630. X    S_DIAL,    sizeof(S_DIAL) - 1,    0,        0,
  1631. X    S_DISC,    sizeof(S_DISC) - 1,    0,        D_DISC,
  1632. X#endif
  1633. X    0,        0,            0,        0,
  1634. X};
  1635. X
  1636. Xhidden char *hackstr();            /* forward declaration */
  1637. X
  1638. X/* getparams - try to get info from file, else make empty table */
  1639. X
  1640. Xpublic Info *getparams()
  1641. X{
  1642. X    char    line[BUFSIZ];
  1643. X    register Info *ip;
  1644. X    FILE   *fp;
  1645. X
  1646. X    /* for cleanliness, we first clear all table entries */
  1647. X
  1648. X    for (ip = params; ip->ident; ip++) {
  1649. X    if (ip->strval)
  1650. X        free(ip->strval);
  1651. X    ip->strval = 0;
  1652. X    }
  1653. X
  1654. X    /* then, try to copy parameter file info to the table */
  1655. X
  1656. X    if (fp = fopen(parm_file(), "r")) {
  1657. X    while (fgets(line, sizeof(line), fp)) {
  1658. X        for (ip = params; ip->ident; ip++) {
  1659. X        if (strncmp(ip->ident, line, ip->length) == 0) {
  1660. X            ip->strval = hackstr(line + ip->length);
  1661. X            break;
  1662. X        }
  1663. X        }
  1664. X    }
  1665. X    (void) fclose(fp);
  1666. X    }
  1667. X
  1668. X    /* set defaults for undefined values */
  1669. X
  1670. X    for (ip = params; ip->ident; ip++)
  1671. X    if (ip->strval == 0 && ip->defval != 0)
  1672. X        ip->strval = hackstr(ip->defval);
  1673. X
  1674. X    return (params);
  1675. X}
  1676. X
  1677. X/* hackstr - cut away blanks around string and make copy */
  1678. X
  1679. Xhidden char *hackstr(s)
  1680. Xregister char *s;
  1681. X{
  1682. X    register char *r;
  1683. X    int     len;
  1684. X
  1685. X    /* strip leading and trailing blanks */
  1686. X
  1687. X    while (*s && isspace(*s))
  1688. X    s++;
  1689. X    for (r = s + strlen(s); r > s && isspace(r[-1]); r--)
  1690. X    /* void */ ;
  1691. X
  1692. X    /*
  1693. X     * s is at the terminator or first non-blank char. r is at the terminator
  1694. X     * or first blank after the last non-blank char. Thus, the actual string
  1695. X     * length is r-s. We add one for the terminator. We don't allocate memory
  1696. X     * if the string is empty.
  1697. X     */
  1698. X
  1699. X    if (len = r - s) {
  1700. X    char   *cp = strncpy(myalloc(len + 1), s, len);
  1701. X
  1702. X    cp[len] = '\0';
  1703. X    return (cp);
  1704. X    } else {
  1705. X    return (0);
  1706. X    }
  1707. X}
  1708. END_OF_main/params.c
  1709. if test 3364 -ne `wc -c <main/params.c`; then
  1710.     echo shar: \"main/params.c\" unpacked with wrong size!
  1711. fi
  1712. # end of overwriting check
  1713. fi
  1714. if test -f main/path.c -a "${1}" != "-c" ; then 
  1715.   echo shar: Will not over-write existing file \"main/path.c\"
  1716. else
  1717. echo shar: Extracting \"main/path.c\" \(3423 characters\)
  1718. sed "s/^X//" >main/path.c <<'END_OF_main/path.c'
  1719. X/*++
  1720. X/* NAME
  1721. X/*      path 3
  1722. X/* SUMMARY
  1723. X/*      system-dependent file name stuff
  1724. X/* PROJECT
  1725. X/*      pc-mail
  1726. X/* PACKAGE
  1727. X/*      general
  1728. X/* SYNOPSIS
  1729. X/*    #include "str.h"
  1730. X/*      #include "path.h"
  1731. X/*
  1732. X/*      int pathinit()
  1733. X/*
  1734. X/*      FILE *propen()
  1735. X/*
  1736. X/*      char *fspool(file)
  1737. X/*      char *file;
  1738. X/* DESCRIPTION
  1739. X/*      The routines in this module know the system-dependent rules
  1740. X/*      for file names and printers.
  1741. X/*
  1742. X/*      pathinit() extracts the values of the environment variables
  1743. X/*      MAILDIR, MAILPRN, MAILCMD and EDITOR, and assumes system-dependent 
  1744. X/*    defaults for undefined environment variables. It checks for the 
  1745. X/*      existence of the spool directory.
  1746. X/*
  1747. X/*    Under Unix, the MAILPRN environment variable should be the name
  1748. X/*    of a command. Under MS-DOS, it should be the name of a device or file.
  1749. X/*
  1750. X/*      propen() returns a stream to print to.
  1751. X/*
  1752. X/*      fspool() constructs a path name from the spool directory and 
  1753. X/*    the file name in its argument.
  1754. X/*    Real unix uses uucp spool file names of the form 
  1755. X/*
  1756. X/*        <letter> . <system> <grade> <sequence_nr>
  1757. X/*
  1758. X/*    This is problematic for MS-DOS and similar systems that
  1759. X/*    only allow three characters after the dot. Instead of building
  1760. X/*    a tiny file system on top of MS-DOS, the pc-mail programs
  1761. X/*    use a different way of spool file naming:
  1762. X/*
  1763. X/*        <letter> <sequence_nr>
  1764. X/*
  1765. X/*    This scheme assumes that the pc has access to exactly one unix
  1766. X/*    host, since the host name is not part of spool file names.
  1767. X/* COMMANDS
  1768. X/*      lp(1)  (under unix) printer spooler program
  1769. X/* FILES
  1770. X/*      PRN     under MS-DOS
  1771. X/* DIAGNOSTICS
  1772. X/*      pathinit() returns a nonzero value (see status(5)) if one of the 
  1773. X/*    environment variables (or defaults) are incorrect.
  1774. X/*
  1775. X/*      File open functions return a null pointer when a file could not
  1776. X/*      be opened.
  1777. X/* BUGS
  1778. X/*    pathinit() only verifies the MAILDIR name.
  1779. X/*
  1780. X/*      fspool() returns a pointer to static memory.
  1781. X/* AUTHOR(S)
  1782. X/*      W.Z. Venema
  1783. X/*      Eindhoven University of Technology
  1784. X/*      Department of Mathematics and Computer Science
  1785. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1786. X/* CREATION DATE
  1787. X/*      Sun Apr  5 15:27:37 GMT+1:00 1987
  1788. X/* LAST MODIFICATION
  1789. X/*    90/01/22 13:02:26
  1790. X/* VERSION/RELEASE
  1791. X/*    2.1
  1792. X/*--*/
  1793. X
  1794. X#include <sys/types.h>
  1795. X#include <sys/stat.h>
  1796. X#include "defs.h"
  1797. X#include "path.h"
  1798. X#include "status.h"
  1799. X
  1800. X /*
  1801. X  * Environment variables are loaded here. Most of them have a default; We
  1802. X  * only check the validity of the MAILDIR variable.
  1803. X  */
  1804. X
  1805. Xpublic char *maildir = DEFSPOOL;    /* spool directory */
  1806. Xpublic char *editor  = DEFEDIT;        /* editor program */
  1807. Xpublic char *mailprn = DEFPRINT;    /* where to print to */
  1808. Xpublic char *mailcmd = 0;        /* do this on exit */
  1809. X
  1810. Xtypedef struct {
  1811. X    char   *vname;
  1812. X    char  **ptr;
  1813. X} Environ;
  1814. X
  1815. Xstatic Environ env[] = {
  1816. X    "SPOOL",    &maildir,        /* backwards compatibility... */
  1817. X    "MAILDIR",    &maildir,
  1818. X    "EDITOR",    &editor,
  1819. X    "MAILPRN",    &mailprn,
  1820. X    "MAILCMD",    &mailcmd,
  1821. X    0,        0,            /* terminator */
  1822. X};
  1823. X
  1824. X/* pathinit - consult the environment; checks existence of spool directory */
  1825. X
  1826. Xpublic int pathinit()
  1827. X{
  1828. X    register char *cp;
  1829. X    struct stat s;
  1830. X    register Environ *ep;
  1831. X
  1832. X    /* load environment variables */
  1833. X
  1834. X    for (ep = env; ep->vname; ep++)
  1835. X    if (cp = getenv(ep->vname))
  1836. X        *(ep->ptr) = cp;
  1837. X
  1838. X    /* check existence of the spool directory */
  1839. X
  1840. X    return (stat(maildir, &s) || (s.st_mode & S_IFMT) != S_IFDIR ? E_NOSPOOL : 0);
  1841. X}
  1842. END_OF_main/path.c
  1843. if test 3423 -ne `wc -c <main/path.c`; then
  1844.     echo shar: \"main/path.c\" unpacked with wrong size!
  1845. fi
  1846. # end of overwriting check
  1847. fi
  1848. if test -f main/scanwork.c -a "${1}" != "-c" ; then 
  1849.   echo shar: Will not over-write existing file \"main/scanwork.c\"
  1850. else
  1851. echo shar: Extracting \"main/scanwork.c\" \(2975 characters\)
  1852. sed "s/^X//" >main/scanwork.c <<'END_OF_main/scanwork.c'
  1853. X/*++
  1854. X/* NAME
  1855. X/*      scanwork 3
  1856. X/* SUMMARY
  1857. X/*      search spool directory for outbound messages
  1858. X/* PROJECT
  1859. X/*      pc-mail
  1860. X/* PACKAGE
  1861. X/*      cico
  1862. X/* SYNOPSIS
  1863. X/*    #include "work.h"
  1864. X/*
  1865. X/*      work *scanwork()
  1866. X/* DESCRIPTION
  1867. X/*      scanwork() searches the spool directory for files to be sent to
  1868. X/*    the remote system. If a file is found, scanwork() attempts to
  1869. X/*    open that file. A null pointer is returned if no work was found.
  1870. X/*
  1871. X/*    The result is normally used by sendwork().
  1872. X/* FUNCTIONS AND MACROS
  1873. X/*      scandir(), newseqno(), fspool()
  1874. X/* SEE ALSO
  1875. X/*      sendwork()      send spool file to remote host
  1876. X/*      getwork()       receive remote spool file
  1877. X/*      rmtname()       local spool-file to remote-file name mapping
  1878. X/* AUTHOR(S)
  1879. X/*      W.Z. Venema
  1880. X/*      Eindhoven University of Technology
  1881. X/*      Department of Mathematics and Computer Science
  1882. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  1883. X/* CREATION DATE
  1884. X/*      Sat Mar 28 17:28:09 GMT+1:00 1987
  1885. X/* LAST MODIFICATION
  1886. X/*    90/01/22 13:02:31
  1887. X/* VERSION/RELEASE
  1888. X/*    2.1
  1889. X/*--*/
  1890. X
  1891. X#include <stdio.h>
  1892. X#include <ctype.h>
  1893. X
  1894. X#include "defs.h"
  1895. X#include "params.h"
  1896. X#include "comm.h"
  1897. X#include "work.h"
  1898. X#include "path.h"
  1899. X#include "ndir.h"
  1900. X#include "logs.h"
  1901. X
  1902. X /*
  1903. X  * The present implementation assumes that work for the remote system is in
  1904. X  * the form of pairs of spool files with names d<seqno> and x<seqno>.
  1905. X  * 
  1906. X  * The d files contain an electronic mail message, and the x files contain the
  1907. X  * destination. Both have the same <seqno> suffix which is just a five-digit
  1908. X  * sequence number.
  1909. X  * 
  1910. X  * The task of scanwork() thus is trivial: just locate a file of which the name
  1911. X  * begins with a d or x and do some file name parsing. The major work is
  1912. X  * done by rmtname() and sendwork(): depending on the type of file, generate
  1913. X  * an appropriate remote file name and send the appropriate messages to the
  1914. X  * remote system.
  1915. X  *
  1916. X  * After a file has been transmitted it is renamed to reflect the "Sent"
  1917. X  * status.
  1918. X  */
  1919. X
  1920. X/* scanwork - search spool directory for work */
  1921. X
  1922. Xpublic work *scanwork()
  1923. X{
  1924. X    register DIR *dp;
  1925. X    register struct direct *de;
  1926. X    static work wrk;            /* overwritten each time */
  1927. X    static char unsent[] = "DdXx";    /* prefixes for unsent messages */
  1928. X    char   *p_unsent;            /* pointer into unsent array */
  1929. X    static char sent[] = "qqrr";    /* prefixes for sent messages */
  1930. X
  1931. X    if ((dp = opendir(maildir)) == 0) {
  1932. X    return (0);
  1933. X    } else {
  1934. X    while (de = readdir(dp)) {
  1935. X        debug(5) ("scanwork: file %s\n", de->d_name);
  1936. X        if (((p_unsent = index(unsent, wrk.type = de->d_name[0])) != 0)
  1937. X        && (wrk.seqno = seqno(de->d_name))) {
  1938. X        strcpy(wrk.path, fspool(de->d_name));
  1939. X        strcpy(wrk.sent, fspool(strcons(SPOOLFMT,
  1940. X                      sent[p_unsent - unsent], wrk.seqno)));
  1941. X        sprintf(wrk.rqst, "S %s %s %s - %s 0660", de->d_name,
  1942. X            rmtname(wrk.type, wrk.seqno), "uucp", de->d_name);
  1943. X        wrk.fp = fopen(wrk.path, "r");
  1944. X        break;
  1945. X        }
  1946. X    }
  1947. X    closedir(dp);
  1948. X    return (de ? &wrk : NULL);
  1949. X    }
  1950. X}
  1951. END_OF_main/scanwork.c
  1952. if test 2975 -ne `wc -c <main/scanwork.c`; then
  1953.     echo shar: \"main/scanwork.c\" unpacked with wrong size!
  1954. fi
  1955. # end of overwriting check
  1956. fi
  1957. if test -f main/smail.c -a "${1}" != "-c" ; then 
  1958.   echo shar: Will not over-write existing file \"main/smail.c\"
  1959. else
  1960. echo shar: Extracting \"main/smail.c\" \(2780 characters\)
  1961. sed "s/^X//" >main/smail.c <<'END_OF_main/smail.c'
  1962. X/*++
  1963. X/* NAME
  1964. X/*      smail 1
  1965. X/* SUMMARY
  1966. X/*      mail spooler
  1967. X/* PROJECT
  1968. X/*      pc-mail
  1969. X/* PACKAGE
  1970. X/*      smail
  1971. X/* SYNOPSIS
  1972. X/*      smail file destinations
  1973. X/* DESCRIPTION
  1974. X/*      smail makes preparations to send a copy of a text file
  1975. X/*    to another person. If a "-" is specifie instead of a file
  1976. X/*    name, standard input is read.
  1977. X/*
  1978. X/*    The contents of the original file are filtered in order to
  1979. X/*    get rid of control characters, high most-significant bits,
  1980. X/*    or non-standard carriage-control conventions. The filter
  1981. X/*    has no effect on ordinary flat text files, such as program 
  1982. X/*    sources.
  1983. X/*
  1984. X/*    Aliases in the list of destinations are expanded, and multiple
  1985. X/*    occurrances of the same recipient are eliminated. The algorithms
  1986. X/*    that manipulate the list of destinations are case-insensitive.
  1987. X/* FILES
  1988. X/*    In the spool directory. Files that belong together have the
  1989. X/*    same sequence number in their name.
  1990. X/*      d<seqno>    message body (data file)
  1991. X/*    x<seqno>    destination and message subject (meta file)
  1992. X/* SEE ALSO
  1993. X/*    ascf(3)        ASCII filter
  1994. X/*    spoolfil(3)    create data-file/meta-file pair
  1995. X/*      path(5)         system-dependent path names
  1996. X/*    unalias(3)    alias expansion and cleanup
  1997. X/* DIAGNOSTICS
  1998. X/*      Error messages if invoked with insufficient arguments.
  1999. X/*      The program terminates with a nonzero exit status if 
  2000. X/*      problems were detected (out of memory, file access problems,
  2001. X/*    loops in the alias data base). The exit status indicates the
  2002. X/*    nature of the problem.
  2003. X/* AUTHOR(S)
  2004. X/*      W.Z. Venema
  2005. X/*      Eindhoven University of Technology
  2006. X/*      Department of Mathematics and Computer Science
  2007. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2008. X/* CREATION DATE
  2009. X/*      Mon Apr  6 16:58:42 GMT+1:00 1987
  2010. X/* LAST MODIFICATION
  2011. X/*    90/01/22 13:02:38
  2012. X/* VERSION/RELEASE
  2013. X/*    2.1
  2014. X/*--*/
  2015. X
  2016. X#include <stdio.h>
  2017. X
  2018. X#include "defs.h"
  2019. X#include "path.h"
  2020. X#include "status.h"
  2021. X
  2022. Xextern char **unalias();
  2023. X
  2024. Xpublic char *progname = "smail";        /* for diagnostics */
  2025. X
  2026. Xmain(argc,argv)
  2027. Xint argc;
  2028. Xchar **argv;
  2029. X{
  2030. X    int stat = 0;                /* pathinit() status code */
  2031. X    char **vec;                    /* final destinations vector */
  2032. X    char *str;                    /* final destinations string */
  2033. X
  2034. X    if (argc <= 2) {
  2035. X    fprintf(stderr,"usage: smail filename destination(s)\n");
  2036. X    exit(1);
  2037. X    } else if (stat = pathinit()) {        /* check environment vars */
  2038. X    exit(stat);
  2039. X    } else if ((vec = unalias(argv+2)) == 0) {    /* expand aliases */
  2040. X    exit(E_SYSFAIL);
  2041. X    } else if (vec[BUFSIZ-1]) {            /* alias overflow */
  2042. X    exit(E_OVALIAS);
  2043. X    } else if ((str = vecstr(vec," ")) == 0) {    /* list -> string conversion */
  2044. X    exit(E_SYSFAIL);
  2045. X    } else if (strlen(str) >= MAXLINE) {
  2046. X    exit(E_TOOLONG);            /* too many recipients */
  2047. X    } else {
  2048. X    exit(sendmail(argv[1],str));        /* make spool files */
  2049. X    }
  2050. X    /* NOTREACHED */
  2051. X}
  2052. END_OF_main/smail.c
  2053. if test 2780 -ne `wc -c <main/smail.c`; then
  2054.     echo shar: \"main/smail.c\" unpacked with wrong size!
  2055. fi
  2056. # end of overwriting check
  2057. fi
  2058. if test -f main/snapshot.c -a "${1}" != "-c" ; then 
  2059.   echo shar: Will not over-write existing file \"main/snapshot.c\"
  2060. else
  2061. echo shar: Extracting \"main/snapshot.c\" \(2760 characters\)
  2062. sed "s/^X//" >main/snapshot.c <<'END_OF_main/snapshot.c'
  2063. X/*++
  2064. X/* NAME
  2065. X/*    snapshot 3
  2066. X/* SUMMARY
  2067. X/*    keep overview of the mail directory
  2068. X/* PROJECT
  2069. X/*    pc-mail
  2070. X/* PACKAGE
  2071. X/*    mail
  2072. X/* SYNOPSIS
  2073. X/*    #include "snapshot.h"
  2074. X/*
  2075. X/*    SNAP_SHOT *snap_shot(list)
  2076. X/*    char *list;
  2077. X/*
  2078. X/*    void snap_junk()
  2079. X/* DESCRIPTION
  2080. X/*      These functions maintain a "snapshot" of the mail directory;
  2081. X/*    this is a table of meta files.
  2082. X/*
  2083. X/*    snap_shot() make sure that a "snapshot" exists. list is
  2084. X/*    a null-terminated string of metafile suffix characters.
  2085. X/*    This function returns a list with as terminator an entry
  2086. X/*    with all zeros.
  2087. X/*
  2088. X/*    snap_junk() schedules a re-scan of the mail directory.
  2089. X/* FILES
  2090. X/*      mail header files in the spool directory
  2091. X/* BUGS
  2092. X/*      Since a message can be accessed only if its metafile exists,
  2093. X/*    a message is "lost" when for some reason the metafile is
  2094. X/*    not available.
  2095. X/* AUTHOR(S)
  2096. X/*      W.Z. Venema
  2097. X/*      Eindhoven University of Technology
  2098. X/*      Department of Mathematics and Computer Science
  2099. X/*      Den Dolech 2, P.O. Box 513, 5600 MB Eindhoven, The Netherlands
  2100. X/* CREATION DATE
  2101. X/*    Sun Dec 17 19:52:12 MET 1989
  2102. X/* LAST MODIFICATION
  2103. X/*    90/01/22 13:02:38
  2104. X/* VERSION/RELEASE
  2105. X/*    2.1
  2106. X/*--*/
  2107. X
  2108. X#include <stdio.h>
  2109. X
  2110. X#include "defs.h"
  2111. X#include "path.h"
  2112. X#include "ndir.h"
  2113. X#include "snapshot.h"
  2114. X
  2115. X#define    SNAP_ALLOC    200        /* growth increment of table */
  2116. X
  2117. Xhidden SNAP_SHOT *snap_table = 0;    /* at most 16k messages on a PC */
  2118. Xhidden int snap_used = 0;        /* nr of elements actually used */
  2119. Xhidden int snap_length = 0;        /* actual length of table */
  2120. X
  2121. X/* snap_add - add message to snapshot table */
  2122. X
  2123. Xhidden void snap_add(msgno, prefix)
  2124. Xunsigned msgno;
  2125. Xchar    prefix;
  2126. X{
  2127. X    /* myrealloc() accepts a null pointer */
  2128. X
  2129. X    if (snap_used >= snap_length) {
  2130. X    snap_length += SNAP_ALLOC;
  2131. X    if ((snap_table = (SNAP_SHOT *) myrealloc((char *) snap_table,
  2132. X                     snap_length * sizeof(snap_table))) == 0)
  2133. X        fatal("insufficient free memory for operation");
  2134. X    }
  2135. X    snap_table[snap_used].msgno = msgno;
  2136. X    snap_table[snap_used].prefix = prefix;
  2137. X    snap_used++;
  2138. X}
  2139. X
  2140. X/* snap_build - record meta files in the mail directory */
  2141. X
  2142. Xhidden void snap_build(list)
  2143. Xchar   *list;
  2144. X{
  2145. X    DIR    *dp;                /* dir search id */
  2146. X    register struct direct *de;        /* directory entry */
  2147. X    unsigned msgno;            /* message sequence number */
  2148. X
  2149. X    if (dp = opendir(maildir)) {
  2150. X    while (de = readdir(dp)) {
  2151. X        if ((msgno = seqno(de->d_name)) && strchr(list, de->d_name[0]) != 0)
  2152. X        snap_add(msgno, de->d_name[0]);
  2153. X    }
  2154. X    closedir(dp);
  2155. X    }
  2156. X    snap_add(0, 0);            /* add terminator */
  2157. X}
  2158. X
  2159. X/* snap_junk - schedule re-build of snapshot table */
  2160. X
  2161. Xpublic void snap_junk()
  2162. X{
  2163. X    snap_used = 0;
  2164. X}
  2165. X
  2166. X/* snap_shot - make sure snapshot table exists */
  2167. X
  2168. Xpublic SNAP_SHOT *snap_shot(list)
  2169. Xchar   *list;
  2170. X{
  2171. X    if (snap_used == 0)
  2172. X    snap_build(list);
  2173. X     return(snap_table);
  2174. X}
  2175. END_OF_main/snapshot.c
  2176. if test 2760 -ne `wc -c <main/snapshot.c`; then
  2177.     echo shar: \"main/snapshot.c\" unpacked with wrong size!
  2178. fi
  2179. # end of overwriting check
  2180. fi
  2181. echo shar: End of archive 3 \(of 11\).
  2182. cp /dev/null ark3isdone
  2183. MISSING=""
  2184. for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
  2185.     if test ! -f ark${I}isdone ; then
  2186.     MISSING="${MISSING} ${I}"
  2187.     fi
  2188. done
  2189. if test "${MISSING}" = "" ; then
  2190.     echo You have unpacked all 11 archives.
  2191.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2192. else
  2193.     echo You still need to unpack the following archives:
  2194.     echo "        " ${MISSING}
  2195. fi
  2196. ##  End of shell archive.
  2197. exit 0
  2198.  
  2199.