home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / alt / sources / 3063 < prev    next >
Encoding:
Internet Message Format  |  1993-01-23  |  50.6 KB

  1. Path: sparky!uunet!stanford.edu!rutgers!modus!lpds!wcp
  2. From: wcp@lpds.sublink.org (Walter C. Pelissero)
  3. Newsgroups: alt.sources
  4. Subject: mgetty - A modular getty v1.0, Part01/04
  5. Message-ID: <1993Jan22.161629.754@lpds.sublink.org>
  6. Date: 22 Jan 93 16:16:29 GMT
  7. Organization: Sweet home under white clouds
  8. Lines: 1888
  9. Phone: + 39 2 8464117 - 8435411 (work)    8267089 (home)
  10. Postal-Address: Via G. de Ruggiero 87, 20142 Milano - Italia
  11.  
  12. Since I had enough requests to justify a posting, here it is.
  13.  
  14. From the README file:
  15.  
  16. Mgetty is a getty replacement, programmable via Tcl scripts, for lines
  17. hooked to a DCE. Tcl is a language written by John Ousterhout, that
  18. within mgetty let you do what you want with ttys and modems without
  19. writing complex C code, at least for the trivial actions.
  20.  
  21. Mgetty is modular for two reasons: it is built around Tcl, which is
  22. itself a modular script language (you can add, delete, and rewrite
  23. commands in terms of C functions); it needs some external program to
  24. perform some advanced action (like fax receiving, voice playing and
  25. recording).
  26.  
  27. Please send any bug report, fix, hint to
  28.  
  29.        wcp@lpds.sublink.org
  30.  
  31.  
  32.  
  33. Submitted-by: wcp@lpds
  34. Archive-name: mgetty-1.0/part01
  35.  
  36. ---- Cut Here and feed the following to sh ----
  37. #!/bin/sh
  38. # This is mgetty-1.0, a shell archive (produced by shar 3.49)
  39. # To extract the files from this archive, save it to a file, remove
  40. # everything above the "!/bin/sh" line above, and type "sh file_name".
  41. #
  42. # made 01/22/1993 16:10 UTC by wcp@lpds
  43. # Source directory /u/wcp/c/mgetty
  44. #
  45. # existing files will NOT be overwritten unless -c is specified
  46. # This format requires very little intelligence at unshar time.
  47. # "if test", "cat", "rm", "echo", "true", and "sed" may be needed.
  48. #
  49. # This is part 1 of a multipart archive                                    
  50. # do not concatenate these parts, unpack them in order with /bin/sh        
  51. #
  52. # This shar contains:
  53. # length  mode       name
  54. # ------ ---------- ------------------------------------------
  55. #   3356 -r-------- Makefile
  56. #   2782 -r-------- README
  57. #    954 -r-------- ZyXEL
  58. #   7879 -r-------- c2rec.c
  59. #  12233 -r-------- class2rec.c
  60. #   2612 -r-------- common.c
  61. #   3004 -r-------- common.h
  62. #   2047 -r-------- config.h
  63. #   2411 -r-------- doc/c2rec.8
  64. #   7282 -r-------- doc/mgetty.8
  65. #   2518 -r-------- doc/play.8
  66. #   3592 -r-------- doc/record.8
  67. #   1446 -r-------- listen.sh
  68. #   1121 -r-------- localize.c
  69. #   3323 -r-------- locks.c
  70. #  29247 -r-------- mgetty.c
  71. #   5215 -r-------- modemio.c
  72. #   1125 -r-------- modemio.h
  73. #   6653 -r-------- play.c
  74. #   2012 -r-------- printfax.sh
  75. #  11162 -r-------- record.c
  76. #   2445 -r-------- scripts/zyxel4.tcl
  77. #   3953 -r-------- scripts/zyxel5.tcl
  78. #   5120 -r-------- scripts/zyxel5cb.tcl
  79. #   1463 -r-------- temp.c
  80. #   3354 -r-------- voice.c
  81. #   1472 -r-------- voice.h
  82. #   1641 -r-------- xgetty.c
  83. #   2724 -r-------- zyxel.c
  84. #   1666 -r-------- zyxel.h
  85. #
  86. if test -r _shar_seq_.tmp; then
  87.     echo 'Must unpack archives in sequence!'
  88.     echo Please unpack part `cat _shar_seq_.tmp` next
  89.     exit 1
  90. fi
  91. # ============= Makefile ==============
  92. if test -f 'Makefile' -a X"$1" != X"-c"; then
  93.     echo 'x - skipping Makefile (File already exists)'
  94.     rm -f _shar_wnt_.tmp
  95. else
  96. > _shar_wnt_.tmp
  97. echo 'x - extracting Makefile (Text)'
  98. sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
  99. X#
  100. X# $Id: Makefile,v 1.2 1993/01/07 23:14:50 wcp Exp $
  101. X#
  102. X# Copyright (C) 1992    Walter Pelissero
  103. X#
  104. X# This program is free software; you can redistribute it and/or modify
  105. X# it under the terms of the GNU General Public License as published by
  106. X# the Free Software Foundation; either version 1, or (at your option)
  107. X# any later version.
  108. X#
  109. X# This program is distributed in the hope that it will be useful,
  110. X# but WITHOUT ANY WARRANTY; without even the implied warranty of
  111. X# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  112. X# GNU General Public License for more details.
  113. X#
  114. X# You should have received a copy of the GNU General Public License
  115. X# along with this program; if not, write to the Free Software
  116. X# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  117. X#
  118. X
  119. X#
  120. X# $Log: Makefile,v $
  121. X# Revision 1.2  1993/01/07  23:14:50  wcp
  122. X# Added listen shell script, and moved tcl scripts under appropriate
  123. X# directory ("scripts").
  124. X#
  125. X# Revision 1.1  1993/01/06  18:23:05  wcp
  126. X# Initial revision
  127. X#
  128. X# Revision 1.2  1992/07/07  16:51:47  wally
  129. X# Added class2 and zyxel senders.
  130. X# Ps2pbm is a C program now.
  131. X# Minor fixes.
  132. X#
  133. X# Revision 1.1  1992/04/28  16:13:28  wally
  134. X# Initial revision
  135. X#
  136. X#
  137. X
  138. XCC = gcc
  139. XCFLAGS = -g -Wall -DDEBUG=7 -DLIB_DIR=\"$(LIBDIR)\" -DETC_DIR=\"$(ETCDIR)\" \
  140. X     -DTMP_DIR=\"$(TMPDIR)\" -DBIN_DIR=\"$(BINDIR)\" \
  141. X     -DPBMPLUS=\"$(PBMPLUS)\"
  142. XLDFLAGS = -g -ldbmalloc -lstdc -ltcl -lx
  143. XINSTALL = /usr/local/gnubin/install
  144. XBINDIR = /usr/local/bin
  145. XETCDIR = /usr/local/etc
  146. XLIBDIR = /usr/local/lib/mgetty
  147. XTMPDIR = /tmp
  148. XPBMPLUS = /usr/local/pbmplus
  149. X
  150. XBINARIES = localize mgetty c2rec xgetty record play
  151. XSCRIPTS = printfax listen
  152. X
  153. X%: %.sh
  154. X    sed -e "`localize`" $< > $@
  155. X
  156. Xall: $(BINARIES) $(SCRIPTS)
  157. X
  158. X($SCRIPTS): localize
  159. X
  160. X#
  161. X# Binary executables
  162. X#
  163. Xc2rec: c2rec.o common.o modemio.o zyxel.o
  164. Xrecord: record.o common.o modemio.o zyxel.o voice.o
  165. Xplay: play.o common.o modemio.o zyxel.o voice.o
  166. Xxgetty: xgetty.o
  167. Xmgetty: mgetty.o common.o locks.o temp.o modemio.o
  168. X
  169. X#
  170. X# Object modules
  171. X#
  172. Xc2rec.o : c2rec.c common.h config.h modemio.h zyxel.h 
  173. Xcommon.o : common.c 
  174. Xlocalize.o : localize.c 
  175. Xlocks.o : locks.c common.h config.h 
  176. Xmgetty.o : mgetty.c common.h config.h modemio.h 
  177. Xmodemio.o : modemio.c common.h config.h 
  178. Xplay.o : play.c common.h config.h modemio.h zyxel.h voice.h 
  179. Xrecord.o : record.c common.h config.h modemio.h zyxel.h voice.h 
  180. Xtemp.o : temp.c common.h config.h 
  181. Xvoice.o : voice.c voice.h common.h config.h modemio.h zyxel.h 
  182. Xxgetty.o : xgetty.c 
  183. Xzyxel.o : zyxel.c common.h config.h modemio.h zyxel.h 
  184. X
  185. X#
  186. X# Miscellaneous
  187. X#
  188. Xinstall: all
  189. X    -mkdir $(LIBDIR) && chmod 755 $(LIBDIR)
  190. X    -mkdir $(LIBDIR)/ttys && chmod 755 $(LIBDIR)/ttys
  191. X    $(INSTALL) -m 644 -o bin -g bin scripts/*.tcl $(LIBDIR)/ttys
  192. X    $(INSTALL) -m 711 -o bin -g bin c2rec record play $(LIBDIR)
  193. X    $(INSTALL) -m 755 -o bin -g bin printfax $(LIBDIR)
  194. X    $(INSTALL) -m 755 -o bin -g bin listen $(LIBDIR)
  195. X    -mkdir $(ETCDIR) && chmod 755 $(ETCDIR)
  196. X    $(INSTALL) -m 700 -o bin -g bin mgetty $(ETCDIR)
  197. X    -mkdir $(LIBDIR)/sound && chmod 755 $(LIBDIR)/sound
  198. X    $(INSTALL) -m 644 -o bin -g bin sound/* $(LIBDIR)/sound
  199. X
  200. Xinstall_xenix: install
  201. X    [ -f /etc/Getty ] || mv /etc/getty /etc/Getty
  202. X    $(INSTALL) -m 700 -o bin -g bin xgetty /etc/getty
  203. X
  204. Xclean:
  205. X    $(RM) *.o faxem core a.out *.a lp-model $(SCRIPTS) $(BINARIES) \
  206. X          c2rec mgetty
  207. X
  208. Xdist: clean
  209. X    $(RM) *~ \#*\#
  210. X    rcsclean
  211. X
  212. X.PHONY: clean dist all install install_xenix
  213. SHAR_EOF
  214. true || echo 'restore of Makefile failed'
  215. rm -f _shar_wnt_.tmp
  216. fi
  217. # ============= README ==============
  218. if test -f 'README' -a X"$1" != X"-c"; then
  219.     echo 'x - skipping README (File already exists)'
  220.     rm -f _shar_wnt_.tmp
  221. else
  222. > _shar_wnt_.tmp
  223. echo 'x - extracting README (Text)'
  224. sed 's/^X//' << 'SHAR_EOF' > 'README' &&
  225. X$Id: README,v 1.4 1993/01/22 16:08:27 wcp Exp $
  226. X
  227. X
  228. X                   
  229. X                  MGETTY 1.0
  230. X               a modular getty
  231. X
  232. XMgetty is a getty replacement, programmable via Tcl scripts, for lines
  233. Xhooked to a DCE. Tcl is a language written by John Ousterhout, that
  234. Xwithin mgetty let you do what you want with ttys and modems without
  235. Xwriting complex C code, at least for the trivial actions.
  236. X
  237. XMgetty is modular for two reasons: it is built around Tcl, which is
  238. Xitself a modular script language (you can add, delete, and rewrite
  239. Xcommands in terms of C functions); it needs some external program to
  240. Xperform some advanced action (like fax receiving, voice playing and
  241. Xrecording).
  242. X
  243. XWhile mgetty has been thought as a multi purposes getty, it was tested
  244. Xonly on a ZyXEL U-1496 attached on a Xenix 2.3.3 system, so all the
  245. Xexternal programs and configuration scripts were modeled around that
  246. Xkind of modem, and code may be not so portable. However it's likely
  247. Xthat most of the work will not be lost adapting Tcl scripts and
  248. Xexternal programs to a new modem (the fax receiver, for example, could
  249. Xbe used as is), but if you make any change, please mail me.
  250. X
  251. X
  252. X
  253. XINSTALLATION.
  254. X
  255. XFirst of all you must have Tcl 6.1 or better to be able to compile
  256. Xmgetty. If you don't have that library you can remove mgetty from your
  257. Xdirectory, because Tcl is essential.
  258. X
  259. XTo install mgetty:
  260. X
  261. X- edit the config.h file
  262. X- edit the Makefile
  263. X- "make"
  264. X- do a "make install" or "make install_xenix"
  265. X
  266. XManual pages are in doc directory. They are not installed by "make
  267. Xinstall", you have to do it by hand. The documentation is quite brief
  268. Xand it relies completely on Tcl docs. You must know Tcl script
  269. Xlanguage before you start make anything useful with mgetty besides
  270. Xusing sample scripts.
  271. X
  272. XIf you are on a Xenix site you have to substitute your /etc/getty
  273. Xprogram with xgetty (provided with mgetty) that looking into a file
  274. X(currently /usr/local/etc/gettys, see the source code) it spawns the
  275. Xappropriate getty. A sample gettys file is:
  276. X
  277. X    # Some comment
  278. X    tty05=/u/wcp/c/mgetty/mgetty
  279. X    tty2A=/u/wcp/c/mgetty/mgetty
  280. X
  281. XIf an appropriate entry for the tty is not found then the original
  282. Xgetty is spawned.
  283. X
  284. XSample voice files are not provided, so the sound directory is empty.
  285. XYou can create your greeting messages once you compiled successfully,
  286. Xand put them in sound directory to install them automatically whenever
  287. Xyou type "make install". Read ZyXEL, for details.
  288. X
  289. XSample mgetty scripts can be found in scripts directory. They are
  290. Xautomatically installed when you type "make install". Feel free to
  291. Xmodify them and write many others, and, please, send me the ones you
  292. Xthink can be interesting to other people, if I also think so, I'll
  293. Xmake them available with mgetty sources.
  294. X
  295. XPlease send any bug report, fix, hint to
  296. X
  297. X       wcp@lpds.sublink.org
  298. SHAR_EOF
  299. true || echo 'restore of README failed'
  300. rm -f _shar_wnt_.tmp
  301. fi
  302. # ============= ZyXEL ==============
  303. if test -f 'ZyXEL' -a X"$1" != X"-c"; then
  304.     echo 'x - skipping ZyXEL (File already exists)'
  305.     rm -f _shar_wnt_.tmp
  306. else
  307. > _shar_wnt_.tmp
  308. echo 'x - extracting ZyXEL (Text)'
  309. sed 's/^X//' << 'SHAR_EOF' > 'ZyXEL' &&
  310. X$Id: ZyXEL,v 1.1 1993/01/15 23:10:08 wcp Exp $
  311. X
  312. XZyXEL U-1496 owners may use the voice features of their modem to send
  313. Xor receive sound messages. These features are supported with the play
  314. Xand record programs.
  315. X
  316. XStart recording a greeting message using record. You can find the
  317. Xdocumentation in doc directory. You may also need to read the
  318. Xdocumentation about this topic that comes with the modem. Here the
  319. Xtrick to avoid recording of a trailing silence is to interrup the
  320. Xrecording program (type DEL or whatever is appropriate on you
  321. Xkeyboard). Record handle this interrumption in the right way.
  322. X
  323. XTo listen to your messages use the play program.
  324. X
  325. XUnfortunately, I could implement the voice features only for ZyXEL
  326. XU-1496 modems, because I have only this kind of modem at hand. If you
  327. Xwrite something for other modems, please send me your work and I'll
  328. Xmake it available with mgetty.
  329. X
  330. XPlease send bug reports, fixes, hints, to
  331. X
  332. X       wcp@lpds.sublink.org
  333. SHAR_EOF
  334. true || echo 'restore of ZyXEL failed'
  335. rm -f _shar_wnt_.tmp
  336. fi
  337. # ============= c2rec.c ==============
  338. if test -f 'c2rec.c' -a X"$1" != X"-c"; then
  339.     echo 'x - skipping c2rec.c (File already exists)'
  340.     rm -f _shar_wnt_.tmp
  341. else
  342. > _shar_wnt_.tmp
  343. echo 'x - extracting c2rec.c (Text)'
  344. sed 's/^X//' << 'SHAR_EOF' > 'c2rec.c' &&
  345. X/*
  346. X * $Id: c2rec.c,v 4.3 1993/01/22 15:14:24 wcp Exp $
  347. X *
  348. X * Copyright (C) 1992    Walter Pelissero
  349. X *
  350. X * This program is free software; you can redistribute it and/or modify
  351. X * it under the terms of the GNU General Public License as published by
  352. X * the Free Software Foundation; either version 1, or (at your option)
  353. X * any later version.
  354. X *
  355. X * This program is distributed in the hope that it will be useful,
  356. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  357. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  358. X * GNU General Public License for more details.
  359. X *
  360. X * You should have received a copy of the GNU General Public License
  361. X * along with this program; if not, write to the Free Software
  362. X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  363. X */
  364. X
  365. X/*
  366. X * $Log: c2rec.c,v $
  367. X * Revision 4.3  1993/01/22  15:14:24  wcp
  368. X * Removed magic string.
  369. X *
  370. X * Revision 4.2  1993/01/06  17:47:40  wcp
  371. X * More robust handling of inter-page negotiation.
  372. X * Already_connected is no longer needed.
  373. X * Added SPEED as header entry in output files.
  374. X * Converted debug messages to dprint() syntax.
  375. X * Modified output file name generation (base name may be a directory
  376. X * or a file). Removed -b option: now basename is mandatory.
  377. X *
  378. X * Revision 4.1  1993/01/02  18:55:30  wcp
  379. X * Rewritten to make it work under mgetty just as fax receiver.
  380. X *
  381. X * Revision 3.2  1992/09/04  13:30:18  wally
  382. X * Deleted unnecessary array reference in mdread().
  383. X * Corrected some misspelling.
  384. X * Fix in getLoginName(): returned value had to point to static area.
  385. X *
  386. X * Revision 3.1  1992/08/29  18:21:51  wally
  387. X * This is now a getty program (no need of an external getty).
  388. X *
  389. X * Revision 2.1  1992/08/27  19:30:11  wally
  390. X * Modified to be a real replacement for getty.
  391. X * Better baud rates handling.
  392. X * /etc/utmp management.
  393. X * New signal handling.
  394. X * Many bug fixes.
  395. X *
  396. X * Revision 1.1  1992/07/17  16:43:57  wally
  397. X * Initial revision
  398. X *
  399. X */
  400. X
  401. X#include <sys/types.h>
  402. X#ifdef DEBUG
  403. X#include <dbmalloc.h>
  404. X#endif
  405. X#include <stdio.h>
  406. X#include <fcntl.h>
  407. X#include <termio.h>
  408. X#include <getopt.h>
  409. X#include <string.h>
  410. X#include <ctype.h>
  411. X#include <errno.h>
  412. X#include <signal.h>
  413. X#include <utmp.h>
  414. X#include <stdlib.h>
  415. X#include "common.h"
  416. X#include "modemio.h"
  417. X#include "zyxel.h"
  418. X
  419. X#ifdef DEBUG
  420. Xstatic int verbosity = 9;
  421. X#else
  422. Xstatic int verbosity = 0;
  423. X#endif
  424. X
  425. Xconst char *myname;
  426. Xstatic char RcsId[] = "$Id: c2rec.c,v 4.3 1993/01/22 15:14:24 wcp Exp $";
  427. Xstatic bool timedout;
  428. X
  429. Xstatic SIGTYPE timeout(int sig)
  430. X{
  431. X  timedout = TRUE;
  432. X  signal(sig, timeout);
  433. X#if SIGTYPE == int
  434. X  return 0;
  435. X#endif
  436. X}
  437. X
  438. Xstatic bool tryRead(ModemReturnCode answer, int fd)
  439. X{
  440. X  unsigned i;
  441. X  ModemReturnCode ret;
  442. X
  443. X  dprint(5, (stderr, "%s: trying to read \"%s\"\n", myname,
  444. X         ModemAnswers[answer]));
  445. X  for (i = 0; i < 10; ++i)
  446. X    {
  447. X      if ((ret = receive(10, fd)) == answer)
  448. X    return SUCCEEDED;
  449. X      if (ret < 0)
  450. X    break;
  451. X    }
  452. X  return FAILED;
  453. X}
  454. X
  455. Xstatic bool receivePage(int infd, int outfd)
  456. X{
  457. X  register unsigned bytes = 0;
  458. X
  459. X  timedout = FALSE;
  460. X  for (bytes = 0; TRUE; ++bytes)
  461. X    {
  462. X      char c;
  463. X
  464. X      if ((bytes % 1000) == 0)
  465. X    alarm(30);
  466. X      if (timedout || read(infd, &c, 1) < 1)
  467. X    {
  468. X      alarm(0);
  469. X      return FAILED;
  470. X    }
  471. X      if (c == DLE)
  472. X    {
  473. X      if (timedout || read(infd, &c, 1) < 1)
  474. X        {
  475. X          alarm(0);
  476. X          return FAILED;
  477. X        }
  478. X      switch (c)
  479. X        {
  480. X        case DLE:
  481. X          break;
  482. X        case ETX:
  483. X          alarm(0);
  484. X          return SUCCEEDED;
  485. X        default:
  486. X          continue;
  487. X        }
  488. X    }
  489. X      write(outfd, &c, 1);
  490. X    }
  491. X}
  492. X
  493. Xstatic bool receiveFax(const char *base_name)
  494. X{
  495. X  unsigned page = 0;
  496. X
  497. X  do
  498. X    {
  499. X      char pathname[1024];
  500. X      int outfd, ret;
  501. X      FILE *outfp;
  502. X
  503. X      sprintf(pathname, "%s.%03u", base_name, ++page);
  504. X      if ((outfd = open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0)
  505. X    {
  506. X      fprintf(stderr, "%s: cannot open for writing %s (%s)\n",
  507. X          myname, pathname, sys_errlist[errno]);
  508. X      return FAILED;
  509. X    }
  510. X      else
  511. X    {
  512. X      long t = time(0);
  513. X
  514. X      outfp = fdopen(outfd, "w");
  515. X      fprintf(outfp, "DATE: %s", ctime(&t));
  516. X    }
  517. X      do
  518. X    {
  519. X      switch (ret = receive(10, 0))
  520. X        {
  521. X        case MDOK:
  522. X        case MDFCFR:
  523. X          mdwrite("AT+FDR\r", 1);
  524. X          break;
  525. X        case MDFDCS:
  526. X        case MDFTSI:
  527. X        case MDCONNECT:
  528. X          /* allowed answers */
  529. X          break;
  530. X        default:
  531. X          /* all the other ones are errors */
  532. X          ret = MDERROR;
  533. X          break;
  534. X        }
  535. X    }
  536. X      while (ret != MDCONNECT && ret != MDERROR);
  537. X      if (ret == MDERROR)
  538. X    {
  539. X      fclose(outfp);
  540. X      unlink(pathname);
  541. X      return FAILED;
  542. X    }
  543. X      else
  544. X    {
  545. X      fprintf(outfp, "RESOLUTION: %d\n", C2_resolution);
  546. X      fprintf(outfp, "CALLER: %s\n", C2_caller);
  547. X      fprintf(outfp, "ENCODING: 0\n"); /* 0=plain, 1=reversed */
  548. X      fprintf(outfp, "SPEED: %d\n", (C2_baud + 1) * 2400);
  549. X      fprintf(outfp, "DATA:");    /* no \n because there is one still
  550. X                       outstanding since last response */
  551. X      fflush(outfp);
  552. X      dprint(7, (stderr, "%s: sending initial DC2\n", myname));
  553. X      sleep(1);
  554. X      mdwrite("\022", 1);
  555. X      dprint(2, (stderr, "%s: receiving page %u\n", myname, page));
  556. X      if (!receivePage(0, outfd))
  557. X        {
  558. X          dprint(1, (stderr, "%s: page %u discarded\n", myname, page));
  559. X          unlink(pathname);
  560. X        }
  561. X      fclose(outfp);
  562. X      do
  563. X        {
  564. X          switch (ret = receive(10, 0))
  565. X        {
  566. X        case MDFPTS:    /* Is it a ZyXEL bug? */
  567. X          mdwrite("AT+FDR\r", 1);
  568. X        case MDFET:
  569. X          break;
  570. X        default:
  571. X          ret = MDERROR;
  572. X          break;
  573. X        }
  574. X        }
  575. X      while (ret != MDERROR && ret != MDFET);
  576. X      if (ret == MDERROR)
  577. X        return FAILED;
  578. X    }
  579. X    }
  580. X  while (C2_eop == 0);
  581. X  mdwrite("AT+FDR\r", 1);
  582. X  if (tryRead(MDFHNG, 0))
  583. X    tryRead(MDOK, 0);
  584. X  sleep(1);    /* let modem recover */
  585. X  return SUCCEEDED;
  586. X}
  587. X
  588. Xstatic bool printPages(const char *base_name)
  589. X{
  590. X  char command[1024];
  591. X
  592. X  sprintf(command, "%s/printfax %s", LIB_DIR, base_name);
  593. X  return !system(command);
  594. X}
  595. X
  596. Xstatic void deletePages(const char *base_name)
  597. X{
  598. X  char buf[strlen(base_name) + 10];
  599. X  unsigned i = 0;
  600. X
  601. X  do sprintf(buf, "%s.%03u", base_name, ++i);
  602. X  while (unlink(buf) == 0);
  603. X}
  604. X
  605. Xstatic SIGTYPE terminate(int sig)
  606. X{
  607. X  dprint(0, (stderr, "%s: got HANGUP signal\n", myname));
  608. X  mdhangup(1);
  609. X  exit(0);
  610. X#if SIGTYPE == int
  611. X  return 0;
  612. X#endif
  613. X}
  614. X      
  615. Xint main(unsigned argc, char *argv[])
  616. X{
  617. X  bool error = FALSE;
  618. X  unsigned print = 0;
  619. X  int i;
  620. X  const char *base = 0;
  621. X  char fax_base_name[1024];
  622. X
  623. X  myname = basename(argv[0]);
  624. X  while ((i = getopt(argc, argv, "px:")) != EOF)
  625. X    switch (i)
  626. X      {
  627. X      case 'p':
  628. X    ++print;
  629. X    break;
  630. X      case 'x':
  631. X    verbosity = atoi(optarg);
  632. X    break;
  633. X      default:
  634. X    error = TRUE;
  635. X    break;
  636. X      }
  637. X  if (optind == argc)
  638. X    error = TRUE;
  639. X  base = argv[optind++];
  640. X  if (optind < argc)        /* too many arguments */
  641. X    error = TRUE;
  642. X  if (error)
  643. X    {
  644. X      fprintf(stderr, "%s\nusage: %s [-x level][-p ...] out{file|dir}\n",
  645. X          RcsId, myname);
  646. X      exit(-1);
  647. X    }
  648. X  mdverbosity = verbosity;
  649. X  signal(SIGALRM, timeout);
  650. X  signal(SIGQUIT, terminate);
  651. X  signal(SIGTERM, terminate);
  652. X  signal(SIGHUP, timeout);
  653. X  signal(SIGINT, terminate);
  654. X  {
  655. X    unsigned nfax = 1;
  656. X    struct stat st;
  657. X
  658. X    if (stat(base, &st) == 0 && (st.st_mode & S_IFDIR))
  659. X      {
  660. X    /* Base is a directory.
  661. X     */
  662. X    for (; nfax > 0; ++nfax)
  663. X      {
  664. X        sprintf(fax_base_name, "%s/in%08u.%03u", base, nfax, 1);
  665. X        /* We avoid to overwrite existing faxes */
  666. X        if (access(fax_base_name, F_OK))
  667. X          {
  668. X        *strrchr(fax_base_name, '.') = '\0'; /* chop ".001" */
  669. X        break;
  670. X          }
  671. X      }
  672. X      }
  673. X    else
  674. X      /* Base is a probably inexistent file name.
  675. X       */
  676. X      strcpy(fax_base_name, base);
  677. X    if (nfax == 0)
  678. X      {
  679. X    fprintf(stderr, "%s: spool area is full.\n", myname);
  680. X    exit(1);
  681. X      }
  682. X  }
  683. X  receiveFax(fax_base_name);
  684. X  mdhangup(1);
  685. X  if (print-- > 0)
  686. X    {
  687. X      if (fork() == 0)
  688. X    {
  689. X      close(0); close(1); close(2);
  690. X      setpgrp();
  691. X      dup(dup(open("/dev/null", O_RDWR)));
  692. X      if (printPages(fax_base_name) && print > 0)
  693. X        deletePages(fax_base_name);
  694. X    }
  695. X      signal(SIGCLD, SIG_IGN);
  696. X    }
  697. X  return exit(0), 0;
  698. X}
  699. SHAR_EOF
  700. true || echo 'restore of c2rec.c failed'
  701. rm -f _shar_wnt_.tmp
  702. fi
  703. # ============= class2rec.c ==============
  704. if test -f 'class2rec.c' -a X"$1" != X"-c"; then
  705.     echo 'x - skipping class2rec.c (File already exists)'
  706.     rm -f _shar_wnt_.tmp
  707. else
  708. > _shar_wnt_.tmp
  709. echo 'x - extracting class2rec.c (Text)'
  710. sed 's/^X//' << 'SHAR_EOF' > 'class2rec.c' &&
  711. X/*
  712. X * $Id: class2rec.c,v 1.1 1992/07/17 16:44:41 wally Exp $
  713. X *
  714. X * Copyright (C) 1992    Walter Pelissero
  715. X *
  716. X * This program is free software; you can redistribute it and/or modify
  717. X * it under the terms of the GNU General Public License as published by
  718. X * the Free Software Foundation; either version 1, or (at your option)
  719. X * any later version.
  720. X *
  721. X * This program is distributed in the hope that it will be useful,
  722. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  723. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  724. X * GNU General Public License for more details.
  725. X *
  726. X * You should have received a copy of the GNU General Public License
  727. X * along with this program; if not, write to the Free Software
  728. X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  729. X */
  730. X
  731. X/*
  732. X * $Log: class2rec.c,v $
  733. X * Revision 1.1  1992/07/17  16:44:41  wally
  734. X * Initial revision
  735. X *
  736. X */
  737. X
  738. X#include <stdio.h>
  739. X#include <fcntl.h>
  740. X#include <termio.h>
  741. X#include <string.h>
  742. X#include <ctype.h>
  743. X#include <errno.h>
  744. X#include <signal.h>
  745. X#include <stdlib.h>
  746. X#include <getopt.h>
  747. X#include "/u/wally/c/faxem/src/common.h"
  748. X
  749. Xextern const char *TMP_DIR;
  750. Xextern bool loadDefaults(void);
  751. Xextern char *makeTemp(const char *);
  752. X
  753. Xtypedef enum {
  754. X  MDERROR,
  755. X  MDOK,
  756. X  MDRING,
  757. X  MDCONNECT,
  758. X  MDNOCARRIER,
  759. X  MDNODIALTONE,
  760. X  MDBUSY,
  761. X  MDNOANSWER,
  762. X  MDFCON,
  763. X  MDFDCS,
  764. X  MDFDIS,
  765. X  MDFCFR,
  766. X  MDFTSI,
  767. X  MDFCSI,
  768. X  MDFPTS,
  769. X  MDFET,
  770. X  MDFHNG,
  771. X  MDLAST_ANS = MDFHNG
  772. X} ModemReturnCode;
  773. X
  774. Xchar *ModemAnswers[] = {
  775. X  "ERROR",
  776. X  "OK",
  777. X  "RING",
  778. X  "CONNECT",
  779. X  "NO CARRIER",
  780. X  "NO DIAL TONE",
  781. X  "BUSY",
  782. X  "NO ANSWER",
  783. X  "+FCON",
  784. X  "+FDCS:",
  785. X  "+FDIS:",
  786. X  "+FCFR",
  787. X  "+FTSI:",
  788. X  "+FCSI:",
  789. X  "+FPTS:",
  790. X  "+FET:",
  791. X  "+FHNG:",
  792. X  0
  793. X};
  794. X
  795. Xtypedef struct {
  796. X  int infd, outfd;
  797. X  struct termio orig_tty_settings;
  798. X} Port;
  799. X
  800. Xstatic SIGTYPE    catcher();
  801. X
  802. X#define DLE    '\020'
  803. X#define ETX    '\003'
  804. X#define DC1    '\021'
  805. X#define DC3    '\023'
  806. X#define XON    DC1
  807. X#define XOFF    DC3
  808. X/* #define SLOWRITE */
  809. X
  810. X#ifdef DEBUG
  811. Xstatic int verbosity = 9;
  812. X#else
  813. Xstatic int verbosity = 0;
  814. X#endif
  815. X
  816. Xchar *myname;
  817. Xstatic char *local_phone = "";
  818. Xstatic char RcsId[] = "$Id: class2rec.c,v 1.1 1992/07/17 16:44:41 wally Exp $";
  819. Xstatic char read_buffer[1024];
  820. X
  821. X#define    toprint(x)    ((x)<' '?((x)+'@'):'?')
  822. X
  823. X/* vgets - Format one character in "always printable" format (like cat -v)
  824. X */
  825. Xstatic char *vgets(unsigned char c)
  826. X{
  827. X  static char buffer[10];
  828. X  char *pnt;
  829. X  
  830. X  pnt = buffer;
  831. X  if (iscntrl(c) || !isprint(c))
  832. X    {
  833. X      if (!isascii(c))
  834. X    {            /* Top bit is set */
  835. X      *pnt++ = 'M';
  836. X      *pnt++ = '-';
  837. X      c = toascii(c);
  838. X    }
  839. X      if (iscntrl(c))
  840. X    {            /* Not printable */
  841. X      *pnt++ = '^';
  842. X      c = toprint(c);
  843. X    }
  844. X    }
  845. X  *pnt++ = c;
  846. X  *pnt = '\0';
  847. X  return(buffer);
  848. X}
  849. X
  850. Xstatic SIGTYPE catcher(int sig)
  851. X{
  852. X  signal(sig, catcher);
  853. X#if SIGTYPE == int
  854. X  return 0;
  855. X#endif
  856. X}
  857. X
  858. X/* Flush file input.
  859. X   Here we hog all the bytes from fd until alarm() expires. */
  860. Xstatic void flush_input(int fd)
  861. X{
  862. X  char c;
  863. X
  864. X  alarm(2);
  865. X  errno = 0;
  866. X  while (errno != EINTR)
  867. X    read(fd, &c, 1);
  868. X}
  869. X
  870. X/*
  871. X *  mdwrite(c)
  872. X *
  873. X *  Function:    Outputs the string pointed to by c to the ACU device.
  874. X *
  875. X *  Returns:    0 on completion.
  876. X *        -1 on write errors.
  877. X *
  878. X */
  879. Xstatic int mdwrite(const char *c, int fd)
  880. X{
  881. X  int err;
  882. X  
  883. X  if (verbosity > 6)
  884. X    fprintf(stderr, "Sent MODEM <<");
  885. X  while (*c)
  886. X    {
  887. X      if ((err = write(fd, c, 1)) != 1)
  888. X    {
  889. X      if (verbosity > 6)
  890. X        fprintf(stderr, ">>-FAIL\n");
  891. X      fprintf(stderr, "ACU write error (%s)\n", sys_errlist[errno]);
  892. X      return(-1);
  893. X    }
  894. X      if (verbosity > 6)
  895. X    fprintf(stderr, "%s", vgets(*c));
  896. X#ifdef SLOWRITE
  897. X      nap(100);
  898. X#endif
  899. X      c++;
  900. X    }
  901. X  if (verbosity > 6)
  902. X    fprintf(stderr, ">>-OK\n");
  903. X  return(0);
  904. X}
  905. X
  906. X
  907. X/*
  908. X *  substr(s, l)
  909. X *
  910. X *  Function:    Checks for the presence of the string pointed to by s
  911. X *        somewhere within the string pointed to by l.
  912. X *
  913. X *  Returns:    0 if found.
  914. X *        -1 if not found.
  915. X */
  916. Xstatic int substr(const char *s, const char *l)
  917. X{
  918. X  int len;
  919. X  
  920. X  len = strlen(s);
  921. X  while ((l = strchr(l, *s)) != NULL)
  922. X    {
  923. X      if (!strncmp(s, l, len))
  924. X    return(0);
  925. X      l++;
  926. X    }
  927. X  return(-1);
  928. X}
  929. X
  930. X/*
  931. X *  mdread(rtime, fd)
  932. X *
  933. X *  Function:    Reads from the ACU until it finds a valid response (found
  934. X *        in ModemAnswers) or times out after rtime seconds.
  935. X *
  936. X *  Returns:    The index in ModemAnswers of the modem response found.
  937. X *        -1 on timeout.
  938. X *
  939. X */
  940. Xstatic ModemReturnCode mdread(unsigned rtime, int fd)
  941. X{
  942. X  char **mp, *bp;
  943. X  unsigned char c;
  944. X  
  945. X  bp = read_buffer;
  946. X  alarm(rtime);
  947. X  if (verbosity > 6)
  948. X    fprintf(stderr, "MODEM returned <<");
  949. X  while (read(fd, &c, 1) == 1)
  950. X    {
  951. X      c &= 0177;
  952. X      if ((*bp = c) != '\0')
  953. X    *++bp = '\0';
  954. X      if (verbosity > 6)
  955. X    fprintf(stderr, "%s", vgets(c));
  956. X      if (bp >= read_buffer + sizeof(read_buffer))
  957. X    {
  958. X      alarm(0);
  959. X      if (verbosity > 6)
  960. X        fprintf(stderr, ">>-FAIL\n");
  961. X      return -1;
  962. X    }
  963. X      if (c == '\r')
  964. X    {
  965. X      for (mp = ModemAnswers; *mp; ++mp)
  966. X        if (substr(*mp, read_buffer) == 0)
  967. X          {
  968. X        alarm(0);
  969. X        if (verbosity > 6)
  970. X          fprintf(stderr, ">>-OK\n");
  971. X        if (verbosity > 4)
  972. X          fprintf(stderr, "got %s\n", ModemAnswers[mp - ModemAnswers]);
  973. X        return mp - ModemAnswers;
  974. X          }
  975. X    }
  976. X    }
  977. X  alarm(0);
  978. X  if (verbosity > 6)
  979. X    fprintf(stderr, ">>-FAIL");
  980. X  if (verbosity > 4)
  981. X    fprintf(stderr, " no response\n");
  982. X  return -1;
  983. X}
  984. X
  985. Xstatic bool hangup(Port port)
  986. X{
  987. X  struct termio tty_settings, old_tty;
  988. X
  989. X  if (ioctl(port.outfd, TCGETA, &tty_settings) < 0)
  990. X    return FAILED;
  991. X  old_tty = tty_settings;
  992. X  tty_settings.c_cflag = B0;
  993. X  if (verbosity > 5)
  994. X    fprintf(stderr, "%s: hanging\n", myname);
  995. X  if (ioctl(port.outfd, TCSETA, &tty_settings) < 0)
  996. X    return FAILED;
  997. X  sleep(1);
  998. X  if (ioctl(port.outfd, TCSETA, &old_tty) < 0)
  999. X    return FAILED;
  1000. X  return SUCCEEDED;
  1001. X}
  1002. X
  1003. Xbool initModem(Port port)
  1004. X{
  1005. X  char outbuf[128];
  1006. X
  1007. X  mdwrite("ATZ\r", port.outfd);
  1008. X  sleep(1);            /* to let modem recover */
  1009. X  mdwrite("ATPE0V1Q0X6S0=3S7=60&B1&C1&D3\r", port.outfd);
  1010. X  flush_input(port.infd);    /* to avoid OK propagation */
  1011. X  
  1012. X  sprintf(outbuf, "ATM%u+FCLASS=2\r", !!verbosity);
  1013. X  if (mdwrite(outbuf, port.outfd) < 0)
  1014. X    return FAILED;
  1015. X  if (mdread(2, port.infd) != MDOK)
  1016. X    return FAILED;
  1017. X  /* I don't know if the following is necessary, but I saw it in
  1018. X     an example session so .... */
  1019. X  if (mdwrite("AT+FCR=1\r", port.outfd) < 0)
  1020. X    return FAILED;
  1021. X  if (mdread(2, port.infd) != MDOK)
  1022. X    return FAILED;
  1023. X  /* Setting Local IDentification (actually,
  1024. X     it is the local fax number). */
  1025. X  sprintf(outbuf, "AT+FLID=\"%s\"\r", local_phone);
  1026. X  if (mdwrite(outbuf, port.outfd) < 0)
  1027. X    return FAILED;
  1028. X  if (mdread(2, port.infd) != MDOK)
  1029. X    return FAILED;
  1030. X  /* Setting Byte ORder (0 = normal, 1 = reverse). */
  1031. X  if (mdwrite("AT+FBOR=0\r", port.outfd) < 0)
  1032. X    return FAILED;
  1033. X  if (mdread(2, port.infd) != MDOK)
  1034. X    return FAILED;
  1035. X  /* Setting DCE capabilities. */
  1036. X  if (mdwrite("AT+FDCC=1\r", port.outfd) < 0)
  1037. X    return FAILED;
  1038. X  if (mdread(2, port.infd) != MDOK)
  1039. X    return FAILED;
  1040. X  return SUCCEEDED;
  1041. X}
  1042. X
  1043. Xbool waitConnection(Port port)
  1044. X{
  1045. X  int ret = -1;
  1046. X
  1047. X  do
  1048. X    {
  1049. X      switch (ret = mdread(1000, port.infd))
  1050. X    {
  1051. X      unsigned i;
  1052. X
  1053. X    case MDFCON:
  1054. X      for (i = 0; i < 10; ++i)
  1055. X        if ((ret = mdread(10, port.infd)) == MDOK)
  1056. X          break;
  1057. X      if (ret != MDOK)
  1058. X        {
  1059. X          initModem(port);
  1060. X          ret = -1;
  1061. X        }
  1062. X      break;
  1063. X    case MDRING:
  1064. X      mdwrite("ATA\r", port.outfd);
  1065. X      ret = -1;
  1066. X      break;
  1067. X    default:    /* Nothing read */
  1068. X      ret = -1;
  1069. X      break;
  1070. X    }
  1071. X    }
  1072. X  while (ret < 0);
  1073. X  return SUCCEEDED;
  1074. X}
  1075. X    
  1076. Xbool tryRead(ModemReturnCode answer, int fd)
  1077. X{
  1078. X  unsigned i;
  1079. X  ModemReturnCode ret;
  1080. X
  1081. X  for (i = 0; i < 10; ++i)
  1082. X    if ((ret = mdread(10, fd)) == answer)
  1083. X      return SUCCEEDED;
  1084. X  return FAILED;
  1085. X}
  1086. X
  1087. Xstatic void receivePage(int infd, int outfd)
  1088. X{
  1089. X  register bool dle_read = FALSE;
  1090. X
  1091. X  do
  1092. X    {
  1093. X      char c;
  1094. X
  1095. X      if (read(infd, &c, 1) < 1)
  1096. X    return;
  1097. X      if (c == DLE)
  1098. X    {
  1099. X      if (dle_read = !dle_read)
  1100. X        continue;
  1101. X    }
  1102. X      else
  1103. X    {
  1104. X      if (c == ETX && dle_read)
  1105. X        return;
  1106. X      dle_read = FALSE;
  1107. X    }
  1108. X      write(outfd, &c, 1);
  1109. X    }
  1110. X  while (TRUE);
  1111. X}
  1112. X
  1113. Xvoid receiveFax(Port port, const char *base_name)
  1114. X{
  1115. X  bool eot;
  1116. X  unsigned page = 0;
  1117. X
  1118. X  do
  1119. X    {
  1120. X      mdwrite("AT+FDR\r", port.outfd);
  1121. X      if (tryRead(MDCONNECT, port.infd))
  1122. X    {
  1123. X      char pathname[1024];
  1124. X      int outfd;
  1125. X
  1126. X      sprintf(pathname, "%s.%u", base_name, ++page);
  1127. X      if ((outfd = open(pathname, O_WRONLY | O_TRUNC | O_CREAT, 0640)) < 0)
  1128. X        {
  1129. X          fprintf(stderr, "%s: cannot open for writing %s (%s)\n",
  1130. X              myname, pathname, sys_errlist[errno]);
  1131. X          return;
  1132. X        }
  1133. X      else
  1134. X        {
  1135. X          if (verbosity > 7)
  1136. X        fprintf(stderr, "%s: sending initial DC2\n", myname);
  1137. X          sleep(1);
  1138. X          mdwrite("\022", port.outfd);
  1139. X          receivePage(port.infd, outfd);
  1140. X          close(outfd);
  1141. X          if (tryRead(MDFET, port.infd))
  1142. X        {
  1143. X          char *fet = strstr(read_buffer, "+FET:") + 5;
  1144. X          
  1145. X          *strpbrk(fet, "\r,;") = '\0';
  1146. X          eot = (atoi(fet) == 2);
  1147. X          tryRead(MDOK, port.infd);
  1148. X        }
  1149. X          else
  1150. X        {
  1151. X          initModem(port);
  1152. X          return;
  1153. X        }
  1154. X        }
  1155. X    }
  1156. X      else
  1157. X    return;
  1158. X    }
  1159. X  while (!eot);
  1160. X  mdwrite("AT+FDR\r", port.outfd);
  1161. X  if (tryRead(MDFHNG, port.infd))
  1162. X    tryRead(MDOK, port.infd);
  1163. X}
  1164. X
  1165. X
  1166. X
  1167. Xstatic bool closeLine(Port port)
  1168. X{
  1169. X  bool errflag = FALSE;
  1170. X  
  1171. X  sleep(1);
  1172. X  errflag |= !hangup(port);
  1173. X  if (ioctl(port.outfd, TCSETA, &port.orig_tty_settings) < 0)
  1174. X    return FAILED;
  1175. X  close(port.infd);
  1176. X  close(port.outfd);
  1177. X  return errflag;
  1178. X}
  1179. X
  1180. Xstatic Port openLine(const char *portname)
  1181. X{
  1182. X  Port port;
  1183. X  struct termio    tty_settings;
  1184. X
  1185. X  errno = 0;
  1186. X  if (!strcmp(portname, "-"))
  1187. X    {
  1188. X      port.infd = fileno(stdin);
  1189. X      port.outfd = fileno(stdout);
  1190. X    }
  1191. X  else
  1192. X    {
  1193. X      if ((port.infd = open(portname, (O_RDONLY | O_NDELAY), 0600)) < 0)
  1194. X    {
  1195. X      if (errno == EBUSY)
  1196. X        fprintf(stderr, "%s: port %s BUSY\n", myname, portname);
  1197. X      else
  1198. X        fprintf(stderr, "%s: can't connect into %s\n", myname, portname);
  1199. X      port.infd = ERROR;
  1200. X      return port;
  1201. X    }
  1202. X      if ((port.outfd = open(portname, (O_WRONLY | O_NDELAY), 0600)) < 0)
  1203. X    {
  1204. X      if (errno == EBUSY)
  1205. X        fprintf(stderr, "%s: port %s BUSY\n", myname, portname);
  1206. X      else
  1207. X        fprintf(stderr, "%s: can't connect into %s\n", myname, portname);
  1208. X      port.infd = ERROR;
  1209. X      return port;
  1210. X    }
  1211. X    }
  1212. X  if (ioctl(port.outfd, TCGETA, &port.orig_tty_settings) < 0)
  1213. X    {
  1214. X      fprintf(stderr, "%s: can't ioctl on %s\n", myname, portname);
  1215. X      port.infd = ERROR;
  1216. X      return port;
  1217. X    }
  1218. X  tty_settings = port.orig_tty_settings;
  1219. X  
  1220. X  tty_settings.c_iflag &= ~(BRKINT | ICRNL | ISTRIP | IXON | IXANY);
  1221. X  tty_settings.c_cflag &= ~(CBAUD | PARENB);
  1222. X  /* ZyXEL U-1496E ROM 4.09 can receive faxes at 19200 baud only. */
  1223. X  tty_settings.c_cflag |= (CSIZE | CS8 | HUPCL | CREAD | B19200);
  1224. X  tty_settings.c_cflag |= (CTSFLOW | RTSFLOW);
  1225. X  tty_settings.c_lflag &= ~(ISIG | ECHO | ICANON);
  1226. X  tty_settings.c_lflag |= XCLUDE;
  1227. X  tty_settings.c_cc[VMIN] = 1;
  1228. X  tty_settings.c_cc[VTIME] = 0;
  1229. X  tty_settings.c_oflag &= ~OPOST;
  1230. X  
  1231. X  if (ioctl(port.outfd, TCSETAF, &tty_settings) < 0)
  1232. X    {
  1233. X      fprintf(stderr, "%s: can't set baud for %s\n", myname, portname);
  1234. X      port.infd = ERROR;
  1235. X      return port;
  1236. X    }
  1237. X  
  1238. X  if (fcntl(port.infd, F_SETFL, O_RDONLY) == ERROR)
  1239. X    {
  1240. X      fprintf(stderr, "%s: can't unset O_NDELAY for %s\n", myname, portname);
  1241. X      port.infd = ERROR;
  1242. X      return port;
  1243. X    }
  1244. X  if (fcntl(port.outfd, F_SETFL, O_WRONLY) == ERROR)
  1245. X    {
  1246. X      fprintf(stderr, "%s: can't unset O_NDELAY for %s\n", myname, portname);
  1247. X      port.infd = ERROR;
  1248. X      return port;
  1249. X    }
  1250. X  if (verbosity > 5)
  1251. X    fprintf(stderr, "%s: baud set for %s\n", myname, portname);
  1252. X  return port;
  1253. X}
  1254. X
  1255. Xint main(unsigned argc, char *argv[])
  1256. X{
  1257. X  Port port;
  1258. X  int i;
  1259. X  bool error = FALSE;
  1260. X  struct option options[] = {
  1261. X    { "debug", 2, 0, 'x' },
  1262. X    { 0, 0, 0, 0 }
  1263. X  };
  1264. X  
  1265. X  myname = argv[0];
  1266. X  while ((i = getopt_long(argc, argv, "x::", options, (int *)0))
  1267. X     != EOF)
  1268. X    switch (i)
  1269. X      {
  1270. X      case 'x':
  1271. X    if (optarg)
  1272. X      verbosity = atoi(optarg);
  1273. X    break;
  1274. X      case '?':
  1275. X    ++error;
  1276. X    break;
  1277. X      }
  1278. X  if (argc - optind < 2 || error)
  1279. X    {
  1280. X      fprintf(stderr, "usage: %s [-x[debug_level]] [+debug[=level]] device fax_pages_base_name\n", myname);
  1281. X      exit(-1);
  1282. X    }
  1283. X  signal(SIGALRM, catcher);
  1284. X  port = openLine(argv[1]);
  1285. X  if (port.infd < 0)
  1286. X    exit(3);
  1287. X  if (!initModem(port))
  1288. X    exit(1);
  1289. X  if (!waitConnection(port))
  1290. X    exit(2);
  1291. X  receiveFax(port, argv[2]);
  1292. X  closeLine(port);
  1293. X  return exit(0), 1;
  1294. X}
  1295. SHAR_EOF
  1296. true || echo 'restore of class2rec.c failed'
  1297. rm -f _shar_wnt_.tmp
  1298. fi
  1299. # ============= common.c ==============
  1300. if test -f 'common.c' -a X"$1" != X"-c"; then
  1301.     echo 'x - skipping common.c (File already exists)'
  1302.     rm -f _shar_wnt_.tmp
  1303. else
  1304. > _shar_wnt_.tmp
  1305. echo 'x - extracting common.c (Text)'
  1306. sed 's/^X//' << 'SHAR_EOF' > 'common.c' &&
  1307. X/*
  1308. X * $Id: common.c,v 1.1 1993/01/06 17:58:33 wcp Exp $
  1309. X *
  1310. X * Copyright (C) 1992    Walter Pelissero
  1311. X *
  1312. X * This program is free software; you can redistribute it and/or modify
  1313. X * it under the terms of the GNU General Public License as published by
  1314. X * the Free Software Foundation; either version 1, or (at your option)
  1315. X * any later version.
  1316. X *
  1317. X * This program is distributed in the hope that it will be useful,
  1318. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1319. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1320. X * GNU General Public License for more details.
  1321. X *
  1322. X * You should have received a copy of the GNU General Public License
  1323. X * along with this program; if not, write to the Free Software
  1324. X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1325. X */
  1326. X
  1327. X/*
  1328. X * $Log: common.c,v $
  1329. X * Revision 1.1  1993/01/06  17:58:33  wcp
  1330. X * Initial revision
  1331. X *
  1332. X */
  1333. X
  1334. X#include <ctype.h>
  1335. X#include <string.h>
  1336. X#include <stdio.h>
  1337. X#include <sys/utsname.h>
  1338. X
  1339. Xstatic char RcsId[] = "$Id: common.c,v 1.1 1993/01/06 17:58:33 wcp Exp $";
  1340. X
  1341. X
  1342. X/* vgets - Format one character in "always printable" format (like cat -v)
  1343. X */
  1344. Xconst char *vgets(unsigned char c)
  1345. X{
  1346. X  static char buffer[10];
  1347. X  char *pnt;
  1348. X  
  1349. X  pnt = buffer;
  1350. X  if (iscntrl(c) || !isprint(c))
  1351. X    {
  1352. X      if (!isascii(c))
  1353. X    {            /* Top bit is set */
  1354. X      *pnt++ = 'M';
  1355. X      *pnt++ = '-';
  1356. X      c = toascii(c);
  1357. X    }
  1358. X      if (iscntrl(c))
  1359. X    {            /* Not printable */
  1360. X      *pnt++ = '^';
  1361. X      c = c < ' ' ? (c + '@') : '?';
  1362. X    }
  1363. X    }
  1364. X  *pnt++ = c;
  1365. X  *pnt = '\0';
  1366. X  return(buffer);
  1367. X}
  1368. X
  1369. Xint strcomp(const char *s1, const char *s2)
  1370. X{
  1371. X  for (; *s1 && *s2; ++s1, ++s2)
  1372. X    {
  1373. X      if (isalpha(*s1) && isalpha(*s2))
  1374. X    {
  1375. X      int c;
  1376. X
  1377. X      if (c = tolower(*s1) -tolower(*s2))
  1378. X        return c;
  1379. X    }
  1380. X      else
  1381. X    {
  1382. X      if (*s1 != *s2)
  1383. X        return *s1 - *s2;
  1384. X    }
  1385. X    }
  1386. X  return *s1 - *s2;
  1387. X}
  1388. X
  1389. Xconst char *basename(const char *n)
  1390. X{
  1391. X  const char *name;
  1392. X
  1393. X  if ((name = strrchr(n, '/')) == NULL)
  1394. X    name = n;
  1395. X  else
  1396. X    ++name;
  1397. X  return name;
  1398. X}
  1399. X
  1400. Xchar *strlower(char *s)
  1401. X{
  1402. X  char *p = s;
  1403. X
  1404. X  for (; *s; ++s)
  1405. X    *s = tolower(*s);
  1406. X  return p;
  1407. X}
  1408. X
  1409. Xchar *strupper(char *s)
  1410. X{
  1411. X  char *p = s;
  1412. X
  1413. X  for (; *s; ++s)
  1414. X    *s = toupper(*s);
  1415. X  return p;
  1416. X}
  1417. X
  1418. Xchar *siteName()
  1419. X{
  1420. X  struct utsname un;
  1421. X  
  1422. X  if (uname(&un) >= 0 && un.nodename[0] != '\0')
  1423. X    return strdup(un.nodename);
  1424. X  else
  1425. X    {
  1426. X      /* trying to get site name from the uuname -l command */
  1427. X      FILE *fd = popen("uuname -l", "r");
  1428. X
  1429. X      if (fd != (FILE *)0)
  1430. X    {
  1431. X      char site[256];
  1432. X
  1433. X      site[0] = '\0';
  1434. X      if (fgets(site, sizeof(site), fd))
  1435. X        site[strlen(site) - 1] = '\0';    /* chop '\n' */
  1436. X      pclose(fd);
  1437. X      return strdup(site);
  1438. X    }
  1439. X    }
  1440. X  return 0;
  1441. X}
  1442. SHAR_EOF
  1443. true || echo 'restore of common.c failed'
  1444. rm -f _shar_wnt_.tmp
  1445. fi
  1446. # ============= common.h ==============
  1447. if test -f 'common.h' -a X"$1" != X"-c"; then
  1448.     echo 'x - skipping common.h (File already exists)'
  1449.     rm -f _shar_wnt_.tmp
  1450. else
  1451. > _shar_wnt_.tmp
  1452. echo 'x - extracting common.h (Text)'
  1453. sed 's/^X//' << 'SHAR_EOF' > 'common.h' &&
  1454. X/*
  1455. X * $Id: common.h,v 1.2 1993/01/15 23:04:26 wcp Exp $
  1456. X *
  1457. X * Copyright (C) 1992    Walter Pelissero
  1458. X *
  1459. X * This program is free software; you can redistribute it and/or modify
  1460. X * it under the terms of the GNU General Public License as published by
  1461. X * the Free Software Foundation; either version 1, or (at your option)
  1462. X * any later version.
  1463. X *
  1464. X * This program is distributed in the hope that it will be useful,
  1465. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1466. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1467. X * GNU General Public License for more details.
  1468. X *
  1469. X * You should have received a copy of the GNU General Public License
  1470. X * along with this program; if not, write to the Free Software
  1471. X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1472. X */
  1473. X
  1474. X/*
  1475. X * $Log: common.h,v $
  1476. X * Revision 1.2  1993/01/15  23:04:26  wcp
  1477. X * Removed some garbage from comments.
  1478. X *
  1479. X * Revision 1.1  1993/01/06  17:59:05  wcp
  1480. X * Initial revision
  1481. X *
  1482. X */
  1483. X
  1484. X#ifndef _common_h_INCLUDED
  1485. X#define _common_h_INCLUDED
  1486. X
  1487. X#include "config.h"
  1488. X#undef FALSE
  1489. X#undef TRUE
  1490. Xtypedef enum { FALSE, OFF = FALSE, TRUE, ON = TRUE } bool;
  1491. Xtypedef enum { LOW, HIGH, FINE = HIGH } Resolution;
  1492. Xtypedef enum { NoIntrSheet, English, Deutsche, Italiano, Francais } IntrSheet;
  1493. X
  1494. X#define SUCCEEDED    TRUE
  1495. X#define FAILED        FALSE
  1496. X#define DLE    '\020'
  1497. X#define ETX    '\003'
  1498. X#define DC1    '\021'
  1499. X#define DC3    '\023'
  1500. X#define XON    DC1
  1501. X#define XOFF    DC3
  1502. X
  1503. X
  1504. X#define ALLOW_FILE        "allow"
  1505. X#define DENY_FILE        "deny"
  1506. X#define CONFIG_FILE        "config"
  1507. X#define PERSONAL_CONFIG_FILE    ".faxem/config"
  1508. X#define HIGH_RES_FONT        "hires.font"
  1509. X#define LOW_RES_FONT        "lores.font"
  1510. X#define ALIAS_FILE        "alias"
  1511. X#define LOG_FILE        "log"
  1512. X#define PERSONAL_ALIAS_FILE    ".faxem/alias"
  1513. X
  1514. X#undef min
  1515. X#undef max
  1516. X#ifdef __cplusplus
  1517. Xinline int min(int a, int b) { return (a < b) ? a : b; }
  1518. Xinline int max(int a, int b) { return (a < b) ? b : a; }
  1519. Xinline unsigned min(unsigned a, unsigned b) { return (a < b) ? a : b; }
  1520. Xinline unsigned max(unsigned a, unsigned b) { return (a < b) ? b : a; }
  1521. Xinline long min(long a, long b) { return (a < b) ? a : b; }
  1522. Xinline long max(long a, long b) { return (a < b) ? b : a; }
  1523. Xinline unsigned long min(unsigned long a, unsigned long b)
  1524. X{
  1525. X  return (a < b) ? a : b;
  1526. X}
  1527. Xinline unsigned long max(unsigned long a, unsigned long b)
  1528. X{
  1529. X  return (a < b) ? b : a;
  1530. X}
  1531. X
  1532. X#else    /* __cplusplus */
  1533. X#define min(a,b)    (((a) < (b)) ? (a) : (b))
  1534. X#define max(a,b)    (((a) < (b)) ? (b) : (a))
  1535. X#endif    /* __cplusplus */
  1536. X
  1537. X#define ERROR    (-1)
  1538. X#define dprint(l,c)    if (verbosity > (l)) fprintf c ;
  1539. X
  1540. X/* The followings are in common.c */
  1541. Xextern const char *basename(const char *);
  1542. Xextern const char *vgets(unsigned);
  1543. Xextern int strcomp(const char*, const char *);
  1544. Xextern char *strlower(char *);
  1545. Xextern char *strupper(char *);
  1546. Xextern char *siteName(void);
  1547. X
  1548. Xextern bool lockLine(const char *, int);
  1549. Xextern bool isLocked(const char *);
  1550. Xextern bool unlockLine(const char *);
  1551. Xextern char *makeTemp(const char *);
  1552. Xextern bool glob(const char *, const char *);
  1553. X#endif    /* _common_h_INCLUDED */
  1554. SHAR_EOF
  1555. true || echo 'restore of common.h failed'
  1556. rm -f _shar_wnt_.tmp
  1557. fi
  1558. # ============= config.h ==============
  1559. if test -f 'config.h' -a X"$1" != X"-c"; then
  1560.     echo 'x - skipping config.h (File already exists)'
  1561.     rm -f _shar_wnt_.tmp
  1562. else
  1563. > _shar_wnt_.tmp
  1564. echo 'x - extracting config.h (Text)'
  1565. sed 's/^X//' << 'SHAR_EOF' > 'config.h' &&
  1566. X/*
  1567. X * $Id: config.h,v 1.2 1993/01/15 23:05:25 wcp Exp $
  1568. X *
  1569. X * Copyright (C) 1992    Walter Pelissero
  1570. X *
  1571. X * This program is free software; you can redistribute it and/or modify
  1572. X * it under the terms of the GNU General Public License as published by
  1573. X * the Free Software Foundation; either version 1, or (at your option)
  1574. X * any later version.
  1575. X *
  1576. X * This program is distributed in the hope that it will be useful,
  1577. X * but WITHOUT ANY WARRANTY; without even the implied warranty of
  1578. X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1579. X * GNU General Public License for more details.
  1580. X *
  1581. X * You should have received a copy of the GNU General Public License
  1582. X * along with this program; if not, write to the Free Software
  1583. X * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1584. X */
  1585. X
  1586. X/*
  1587. X * $Log: config.h,v $
  1588. X * Revision 1.2  1993/01/15  23:05:25  wcp
  1589. X * Removed some garbage from comments.
  1590. X *
  1591. X * Revision 1.1  1993/01/06  17:59:35  wcp
  1592. X * Initial revision
  1593. X *
  1594. X */
  1595. X
  1596. X#ifndef _config_h_INCLUDED
  1597. X#define _config_h_INCLUDED
  1598. X
  1599. X#define SIGTYPE int    /* set it to the return value type of your
  1600. X               signal handling functions [wally] */
  1601. X            /* some common bits 'n pieces */
  1602. X
  1603. X#define LOCK_DIR    "/usr/spool/uucp"
  1604. X#define MAX_NAME_LEN    14    /* Maximum file name length. Define it if
  1605. X                   your file system have such constraint.
  1606. X                   Otherwise leave it undefined. */
  1607. X
  1608. X#ifdef __cplusplus
  1609. Xextern "C" {
  1610. X#endif
  1611. X# include <sys/types.h>
  1612. X  volatile void abort(void);
  1613. X  char *sys_errlist[];
  1614. X  int errno;
  1615. X  volatile void exit(int);
  1616. X  int unlink(const char *);
  1617. X  char *mktemp(char *);
  1618. X  int system(const char *);
  1619. X  void exit(int);
  1620. X  int system(const char *);
  1621. X  int atoi(const char *);
  1622. X  char *regcmp(const char *, const char *, ...);
  1623. X  char *regex(const char *, const char *, ...);
  1624. X  extern int getpid(void);
  1625. X  uid_t getuid(void);
  1626. X  const char *getlogin(void);
  1627. X  int defopen(const char *);
  1628. X  const char *defread(const char *);
  1629. X  const char *logname(void);
  1630. X  char *getenv(const char *);
  1631. X  char *ctime(long *);
  1632. X#ifdef __cplusplus
  1633. X}
  1634. X#endif
  1635. X
  1636. X#endif    /* _config_h_INCLUDED */
  1637. SHAR_EOF
  1638. true || echo 'restore of config.h failed'
  1639. rm -f _shar_wnt_.tmp
  1640. fi
  1641. # ============= doc/c2rec.8 ==============
  1642. if test ! -d 'doc'; then
  1643.     echo 'x - creating directory doc'
  1644.     mkdir 'doc'
  1645. fi
  1646. if test -f 'doc/c2rec.8' -a X"$1" != X"-c"; then
  1647.     echo 'x - skipping doc/c2rec.8 (File already exists)'
  1648.     rm -f _shar_wnt_.tmp
  1649. else
  1650. > _shar_wnt_.tmp
  1651. echo 'x - extracting doc/c2rec.8 (Text)'
  1652. sed 's/^X//' << 'SHAR_EOF' > 'doc/c2rec.8' &&
  1653. X.\"    -*- Nroff -*-
  1654. X.\"
  1655. X.\" $Id: c2rec.8,v 1.2 1993/01/21 19:45:21 wcp Exp $
  1656. X.\"
  1657. X.\" Copyright (C) 1992    Walter Pelissero
  1658. X.\"
  1659. X.\" This program is free software; you can redistribute it and/or modify
  1660. X.\" it under the terms of the GNU General Public License as published by
  1661. X.\" the Free Software Foundation; either version 2 of the License, or
  1662. X.\" (at your option) any later version.
  1663. X.\"
  1664. X.\" This program is distributed in the hope that it will be useful,
  1665. X.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
  1666. X.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1667. X.\" GNU General Public License for more details.
  1668. X.\"
  1669. X.\" You should have received a copy of the GNU General Public License
  1670. X.\" along with this program; if not, write to the Free Software
  1671. X.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1672. X.\"
  1673. X.\"
  1674. X.\" $Log: c2rec.8,v $
  1675. X.\" Revision 1.2  1993/01/21  19:45:21  wcp
  1676. X.\" Changed .I in \fI/\fP.
  1677. X.\"
  1678. X.\" Revision 1.1  1993/01/13  21:40:54  wcp
  1679. X.\" Initial revision
  1680. X.\"
  1681. X.\"
  1682. X.de XX
  1683. X.ds XX \\$4\ (v\\$3)
  1684. X..
  1685. X.XX $Id: c2rec.8,v 1.2 1993/01/21 19:45:21 wcp Exp $
  1686. X.TH C2REC 8 \*(XX
  1687. X.AT 3
  1688. X.SH NAME
  1689. Xc2rec \- Class 2 receiver program
  1690. X.SH SYNOPSIS
  1691. X.B c2rec
  1692. X.RI [ -x\ level ]
  1693. X.RI [ -p\ ... ]
  1694. X.I outfile_or_directory
  1695. X.SH DESCRIPTION
  1696. X\fIC2rec\fP is fax front end for \fImgetty\fP.  On a successfully
  1697. Xestablished connection \fIc2rec\fP negotiate and receive fax pages,
  1698. Xdriving the connection until hang up.  Fax pages take the name
  1699. Xspecified on command line plus a dotted extension (eg. \fIfile.001\fP)
  1700. Xnumbering pages. If a directory is specified instead of a file, pages
  1701. Xare created with this name template: inXXXXXXXX.YYY. Where XXXXXXXX
  1702. Xstands for a fax sequence number, and YYY stands for the page sequence
  1703. Xnumber for fax number XXXXXXXX. The program adjust fax sequence number
  1704. Xto avoid overwriting of existing faxes.
  1705. X.SH OPTIONS
  1706. X.IP "-x \fIlevel\fP"
  1707. XTell the verbosity of debug informations displayed during processing.
  1708. X.IP -p
  1709. XEach succesfully received fax should be printed on the default
  1710. Xprinter. Two occurences of this flag cause faxes to be deleted after
  1711. Xprinting.
  1712. X.SH BUGS
  1713. XThis program is not based on any official document describing Class 2
  1714. Xstandard. This may cause incompatibility with other Class 2 modems or
  1715. Xsubsequent implementations of the modem this program is based on.
  1716. X.SH AUTHOR
  1717. XWalter Pelissero <wally@lpds.sublink.org>
  1718. X.SH "SEE ALSO"
  1719. Xmgetty(8), play(8), record(8)
  1720. SHAR_EOF
  1721. true || echo 'restore of doc/c2rec.8 failed'
  1722. rm -f _shar_wnt_.tmp
  1723. fi
  1724. # ============= doc/mgetty.8 ==============
  1725. if test -f 'doc/mgetty.8' -a X"$1" != X"-c"; then
  1726.     echo 'x - skipping doc/mgetty.8 (File already exists)'
  1727.     rm -f _shar_wnt_.tmp
  1728. else
  1729. > _shar_wnt_.tmp
  1730. echo 'x - extracting doc/mgetty.8 (Text)'
  1731. sed 's/^X//' << 'SHAR_EOF' > 'doc/mgetty.8' &&
  1732. X.\"    -*- Nroff -*-
  1733. X.\"
  1734. X.\" $Id: mgetty.8,v 1.3 1993/01/21 20:02:17 wcp Exp $
  1735. X.\"
  1736. X.\" Copyright (C) 1992    Walter Pelissero
  1737. X.\"
  1738. X.\" This program is free software; you can redistribute it and/or modify
  1739. X.\" it under the terms of the GNU General Public License as published by
  1740. X.\" the Free Software Foundation; either version 2 of the License, or
  1741. X.\" (at your option) any later version.
  1742. X.\"
  1743. X.\" This program is distributed in the hope that it will be useful,
  1744. X.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
  1745. X.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  1746. X.\" GNU General Public License for more details.
  1747. X.\"
  1748. X.\" You should have received a copy of the GNU General Public License
  1749. X.\" along with this program; if not, write to the Free Software
  1750. X.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  1751. X.\"
  1752. X.\"
  1753. X.\" $Log: mgetty.8,v $
  1754. X.\" Revision 1.3  1993/01/21  20:02:17  wcp
  1755. X.\" Added command line arguments.
  1756. X.\"
  1757. X.\" Revision 1.2  1993/01/21  19:43:47  wcp
  1758. X.\" Changed .I in \fI/\fP.
  1759. X.\"
  1760. X.\" Revision 1.1  1993/01/13  21:40:54  wcp
  1761. X.\" Initial revision
  1762. X.\"
  1763. X.\"
  1764. X.de XX
  1765. X.ds XX \\$4\ (v\\$3)
  1766. X..
  1767. X.XX $Id: mgetty.8,v 1.3 1993/01/21 20:02:17 wcp Exp $
  1768. X.TH MGETTY 8 \*(XX
  1769. X.AT 3
  1770. X.SH NAME
  1771. Xmgetty \- modular getty for multipurposes DCEs
  1772. X.SH SYNOPSIS
  1773. X.B mgetty
  1774. X.I orig_getty
  1775. X.RI [ options ] \ tty_name
  1776. X.SH DESCRIPTION
  1777. X\fIMgetty\fP is a programmable getty program designed to drive any DCE
  1778. X(modems, fax-modems, answering-machines, etc.) that needs more control
  1779. Xthan a normal getty can do.
  1780. X.PP
  1781. X\fIMgetty\fP is executed by \fIinit\fP as a normal getty, it sets line
  1782. Xto some default value and start interpreting a Tcl script associated
  1783. Xwith the line (\fItty_name\fP). If there is no such script,
  1784. X\fImgetty\fP gives up and executes the original getty program
  1785. X(\fIorig_getty\fP).
  1786. X.PP
  1787. X\fIMgetty\fP ignores any option your system \fIinit\fP
  1788. Xprogram may supply because \fImgetty\fP doesn't need it. All the
  1789. Xinformations and logic must me enclosed in the Tcl script.
  1790. X.SH "NEW TCL COMMANDS"
  1791. XIn order to do some tty specific operations or some special and
  1792. Xfrequently used action on tty/DCE, the basic Tcl interpreter has been
  1793. Xmodified a little.
  1794. X.LP
  1795. XSUBSTITUTED COMMANDS
  1796. X.IP "exit [\fIreturn_value\fP]"
  1797. XOn exit, \fImgetty\fP Tcl scripts must restore ttys and DCEs to some
  1798. Xwell known state (normally the one before \fImgetty\fP started). The
  1799. Xnew \fIexit\fP command hangs up the line and do all such things.
  1800. XSyntax is unchanged.
  1801. X.LP
  1802. XADDED COMMANDS
  1803. X.IP "send \fIstring\fP ..."
  1804. XSends one or more strings to DCE returning an error message if there
  1805. Xare problems on the line.
  1806. X.IP "receive [\fIwait_time\fP] [\fItoken ...\fP]"
  1807. XReceive, looking for input for \fIwait_time\fP seconds (or 30 if not
  1808. Xspecified), any input matching one of the tokens (or any '\\r' or
  1809. X'\\n' terminated string, if no tokens are specified). I returns the
  1810. Xreceived string.
  1811. X.IP listen
  1812. XThis is a variation of \fIreceive.\fP It waits indefinitively for a
  1813. X'\\r' or '\\n' terminated string returning it to application.
  1814. X.IP flush_input
  1815. XDiscard any outstanding characters from DCE.
  1816. X.IP hangup
  1817. XHang up the line.
  1818. X.IP login
  1819. XDo the normal getty operations. Send a login prompt waiting for an
  1820. Xaccount name, then invoke \fIlogin\fP for password autentication. This
  1821. Xcommand doesn't fork the original getty. This command should not
  1822. Xreturn. If it is the case it returns an error message.
  1823. X.IP "spawn \fIarg ...\fP"
  1824. X\fIExec\fP replacement.  Frequently \fImgetty\fP forked programs need
  1825. Xto deal with tty as stdin/stdout; the standard \fIexec\fP command
  1826. Xcannot be used in such situations.  \fISpawn\fP, instead, attachs
  1827. Xstdin and stdout of invoked programs to tty. Syntax is the same as
  1828. X\fIexec\fP. Returned value is the exit status of last program (in case
  1829. Xof pipe).
  1830. X.IP "baudrate [\fIspeed\fP]"
  1831. XSet line speed. All numerical values are allowed but your system may
  1832. Xnot accept all; in this case appropriate conversion to the next lower
  1833. Xbaud rate is made automatically. Return value is the current baud
  1834. Xrate. Without argument it just reports the speed.
  1835. X.IP "stty \fIarg ...\fP"
  1836. XSet special tty settings to arguments. This can viewed as a
  1837. Xreplacement for /etc/gettydef, since \fImgetty doesn't use it. In fact
  1838. Xthis command is a clone of the Unix\fP command \fIstty\fP (refer to
  1839. Xits documentation, for any detail). Both \fIbaudrate\fP and \fImode\fP
  1840. Xcommands do the same things but at higher level and with a more
  1841. Xfriendly interface: you should use \fIstty\fP only when you have no
  1842. Xchoice.
  1843. X.IP "mode \fImode ...\fP"
  1844. XSet to canned modes the tty. This is a higher level interface to stty
  1845. Xfeatures. Currently supported settings are (case is insignificant):
  1846. X.TP
  1847. X    raw
  1848. XEach character written to tty or sent by tty is passed without any
  1849. Xprocessing or delay.
  1850. X.TP
  1851. X    cooked
  1852. XThe normal status when you login into the system. Characters are
  1853. Xpacked together into lines, interrupts are interpreted, backspaces
  1854. Xerase last character typed, etc.
  1855. X.TP
  1856. X    xon_xoff
  1857. XEnable xon/xoff flow control between tty and DCE.
  1858. X.TP
  1859. X    cts_rts
  1860. XEnable cts/rts flow control between tty and DCE.
  1861. X.TP
  1862. X    no_flow
  1863. XDisable any flow control between tty and DCE.
  1864. X.TP
  1865. X    local
  1866. XSet in \fIlocal\fP mode. In other words, CD signal is ignored by
  1867. Xsystem.
  1868. X.TP
  1869. X    remote
  1870. XSet in \fI"non local"\fP mode. In other words, CD transition from ON
  1871. Xto OFF causes an \fIhangup\fP signal to be sent to \fImgetty\fP; this
  1872. Xnormally causes a respawning of mgetty.
  1873. X.IP "sleep \fIsecondsfP"
  1874. XWait for at least as many seconds as specified.
  1875. X.IP "slow_write [\fION|OFF|1|0|TRUE|FALSE|TOGGLE\fP]
  1876. XSet the way \fImgetty\fP send strings (see \fIsend\fP ) to DCE. If
  1877. Xthis setting is on (chose the notation you prefer), mgetty will wait
  1878. Xabout 100ns between one character and subsequent. If this is off,
  1879. Xmgetty will send characters as a continuos stream. It returns the
  1880. Xcurrent status. The special value \fITOGGLE\fP may be used to exchange
  1881. Xany previous value. Normally this is off.
  1882. X.SH "EXTERNAL PROGRAMS"
  1883. XThere are some application that cannot be handled efficently or in a
  1884. Xsufficient general way in terms of Tcl commands. These task are done
  1885. Xwith the intervention of external programs. At the current
  1886. Ximplementation only few programs can be inoked from an \fImgetty\fP
  1887. Xscript.
  1888. X.TP
  1889. Xplay
  1890. XThis is a ZyXEL U-1496 specific program able to send voice files
  1891. SHAR_EOF
  1892. true || echo 'restore of doc/mgetty.8 failed'
  1893. fi
  1894. echo 'End of mgetty-1.0 part 1'
  1895. echo 'File doc/mgetty.8 is continued in part 2'
  1896. echo 2 > _shar_seq_.tmp
  1897. exit 0
  1898. -- 
  1899. P4 32 8 @A ^@@A ^@@Ax^@@A ^@DA"^@D]%xJe&H1\236\331\306
  1900.