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