17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
22*462be471Sceastha /*
23*462be471Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*462be471Sceastha * Use is subject to license terms.
25*462be471Sceastha */
26*462be471Sceastha
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate
30*462be471Sceastha #pragma ident "%Z%%M% %I% %E% SMI"
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate
337c478bd9Sstevel@tonic-gate /*
347c478bd9Sstevel@tonic-gate * cu [-cdevice] [-sspeed] [-lline] [-bbits] [-h] [-t] [-d] [-n]
357c478bd9Sstevel@tonic-gate * [-o|-e] [-L] [-C] telno | systemname [local-cmd]
367c478bd9Sstevel@tonic-gate *
377c478bd9Sstevel@tonic-gate * legal baud rates: 300, 1200, 2400, 4800, 9600, 19200, 38400.
387c478bd9Sstevel@tonic-gate *
397c478bd9Sstevel@tonic-gate * -c is used to specify which device will be used for making the
407c478bd9Sstevel@tonic-gate * call. The device argument is compared to the Type (first)
417c478bd9Sstevel@tonic-gate * field in the Devices file, and only those records that
427c478bd9Sstevel@tonic-gate * match will be used to make the call. Either -d or -t
437c478bd9Sstevel@tonic-gate * would be more intuitive options designations, but they
447c478bd9Sstevel@tonic-gate * are already in use.
457c478bd9Sstevel@tonic-gate * -l is for specifying a line unit from the file whose
467c478bd9Sstevel@tonic-gate * name is defined in /etc/uucp/Devices.
477c478bd9Sstevel@tonic-gate * -b is for forcing the number of bits per character processed on
487c478bd9Sstevel@tonic-gate * the connection. Valid values are '7' or '8'.
497c478bd9Sstevel@tonic-gate * -h is for half-duplex (local echoing).
507c478bd9Sstevel@tonic-gate * -t is for adding CR to LF on output to remote (for terminals).
517c478bd9Sstevel@tonic-gate * -d can be used to get some tracing & diagnostics.
527c478bd9Sstevel@tonic-gate * -o or -e is for odd or even parity on transmission to remote.
537c478bd9Sstevel@tonic-gate * -n will request the phone number from the user.
547c478bd9Sstevel@tonic-gate * -L will cause cu to go through the login chat sequence in the
557c478bd9Sstevel@tonic-gate * Systems file.
567c478bd9Sstevel@tonic-gate * -C will cause cu to run the local command specified at the end
577c478bd9Sstevel@tonic-gate * of the command line, instead of entering interactive mode.
587c478bd9Sstevel@tonic-gate * Telno is a telephone number with `=' for secondary dial-tone.
597c478bd9Sstevel@tonic-gate * If "-l dev" is used, speed is taken from /etc/uucp/Devices.
607c478bd9Sstevel@tonic-gate * Only systemnames that are included in /etc/uucp/Systems may
617c478bd9Sstevel@tonic-gate * be used.
627c478bd9Sstevel@tonic-gate *
637c478bd9Sstevel@tonic-gate * Escape with `~' at beginning of line:
647c478bd9Sstevel@tonic-gate *
657c478bd9Sstevel@tonic-gate * ~. quit,
667c478bd9Sstevel@tonic-gate *
677c478bd9Sstevel@tonic-gate * ~![cmd] execute shell (or 'cmd') locally,
687c478bd9Sstevel@tonic-gate *
697c478bd9Sstevel@tonic-gate * ~$cmd execute 'cmd' locally, stdout to remote,
707c478bd9Sstevel@tonic-gate *
717c478bd9Sstevel@tonic-gate * ~%break (alias ~%b) transmit BREAK to remote,
727c478bd9Sstevel@tonic-gate * ~%cd [dir] change directory to $HOME (or 'dir'),
737c478bd9Sstevel@tonic-gate * ~%debug (alias ~%d) toggles on/off the program debug trace,
747c478bd9Sstevel@tonic-gate * ~%divert allow unsolicited diversions to files,
757c478bd9Sstevel@tonic-gate * ~%ifc (alias ~%nostop) toggles on/off the DC3/DC1 input control,
767c478bd9Sstevel@tonic-gate * ~%ofc (alias ~%noostop) toggles on/off the DC3/DC1 output control,
777c478bd9Sstevel@tonic-gate * (certain remote systems cannot cope with DC3 or DC1).
787c478bd9Sstevel@tonic-gate * ~%old recognize old style silent diversions,
797c478bd9Sstevel@tonic-gate * ~%put from [to] put file from local to remote,
807c478bd9Sstevel@tonic-gate * ~%take from [to] take file from remote to local,
817c478bd9Sstevel@tonic-gate *
827c478bd9Sstevel@tonic-gate * ~l dump communication line ioctl settings,
837c478bd9Sstevel@tonic-gate * ~t dump terminal ioctl settings.
847c478bd9Sstevel@tonic-gate *
857c478bd9Sstevel@tonic-gate * Silent diversions are enabled only for use with the ~%take
867c478bd9Sstevel@tonic-gate * command by default for security reasons. Unsolicited diversions
877c478bd9Sstevel@tonic-gate * may be enabled using the ~%divert toggle. The 'new-style'
887c478bd9Sstevel@tonic-gate * diversion syntax is "~[local]>:filename", and is terminaled
897c478bd9Sstevel@tonic-gate * by "~[local]>", where 'local' is the nodename of the local
907c478bd9Sstevel@tonic-gate * system. This enables ~%take to operate properly when cu
917c478bd9Sstevel@tonic-gate * is used over multiple hops. 'old-style' diversion syntax may
927c478bd9Sstevel@tonic-gate * be enabled using the ~%old toggle. ('old-style' diversion
937c478bd9Sstevel@tonic-gate * should be avoided!)
947c478bd9Sstevel@tonic-gate *
957c478bd9Sstevel@tonic-gate * Cu no longer uses dial.c to reach the remote. Instead, cu places
967c478bd9Sstevel@tonic-gate * a telephone call to a remote system through the uucp conn() routine
977c478bd9Sstevel@tonic-gate * when the user picks the systemname option or through altconn()--
987c478bd9Sstevel@tonic-gate * which bypasses /etc/uucp/Systems -- if a telno or direct
997c478bd9Sstevel@tonic-gate * line is chosen. The line termio attributes are set in fixline(),
1007c478bd9Sstevel@tonic-gate * before the remote connection is made. As a device-lockout semaphore
1017c478bd9Sstevel@tonic-gate * mechanism, uucp creates an entry in /var/spool/locks whose name is
1027c478bd9Sstevel@tonic-gate * LK.<MAJ>.<maj>.<min> where MAJ is the major device of the
1037c478bd9Sstevel@tonic-gate * filesystem containing the device, and <maj> and <min> are the
1047c478bd9Sstevel@tonic-gate * major and minor of the device.
1057c478bd9Sstevel@tonic-gate * When cu terminates, for whatever reason, cleanup() must be
1067c478bd9Sstevel@tonic-gate * called to "release" the device, and clean up entries from
1077c478bd9Sstevel@tonic-gate * the locks directory. Cu runs with uucp ownership, and thus provides
1087c478bd9Sstevel@tonic-gate * extra insurance that lock files will not be left around.
1097c478bd9Sstevel@tonic-gate */
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate #include "uucp.h"
1127c478bd9Sstevel@tonic-gate #include <locale.h>
1137c478bd9Sstevel@tonic-gate #include <stropts.h>
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate #define MID BUFSIZ/2 /* mnemonic */
1167c478bd9Sstevel@tonic-gate #define RUB '\177' /* mnemonic */
1177c478bd9Sstevel@tonic-gate #define XON '\21' /* mnemonic */
1187c478bd9Sstevel@tonic-gate #define XOFF '\23' /* mnemonic */
1197c478bd9Sstevel@tonic-gate #define TTYIN 0 /* mnemonic */
1207c478bd9Sstevel@tonic-gate #define TTYOUT 1 /* mnemonic */
1217c478bd9Sstevel@tonic-gate #define TTYERR 2 /* mnemonic */
1227c478bd9Sstevel@tonic-gate #define HUNGUP 2
1237c478bd9Sstevel@tonic-gate #define YES 1 /* mnemonic */
1247c478bd9Sstevel@tonic-gate #define NO 0 /* mnemonic */
1257c478bd9Sstevel@tonic-gate #define IOERR 4 /* exit code */
1267c478bd9Sstevel@tonic-gate #define MAXPATH 100
1277c478bd9Sstevel@tonic-gate #define NPL 50
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate int Sflag=0;
1307c478bd9Sstevel@tonic-gate int Cn; /*fd for remote comm line */
1317c478bd9Sstevel@tonic-gate jmp_buf Sjbuf; /*needed by uucp routines*/
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate /* io buffering */
1347c478bd9Sstevel@tonic-gate /* Wiobuf contains, in effect, 3 write buffers (to remote, to tty */
1357c478bd9Sstevel@tonic-gate /* stdout, and to tty stderr) and Riobuf contains 2 read buffers */
1367c478bd9Sstevel@tonic-gate /* (from remote, from tty). [WR]IOFD decides which one to use. */
1377c478bd9Sstevel@tonic-gate /* [RW]iop holds current position in each. */
1387c478bd9Sstevel@tonic-gate #define WIOFD(fd) (fd == TTYOUT ? 0 : (fd == Cn ? 1 : 2))
1397c478bd9Sstevel@tonic-gate #define RIOFD(fd) (fd == TTYIN ? 0 : 1)
1407c478bd9Sstevel@tonic-gate #define WMASK(fd) (fd == Cn ? line_mask : term_mask)
1417c478bd9Sstevel@tonic-gate #define RMASK(fd) (fd == Cn ? line_mask : term_mask)
1427c478bd9Sstevel@tonic-gate #define WRIOBSZ 256
1437c478bd9Sstevel@tonic-gate static char Riobuf[2*WRIOBSZ];
1447c478bd9Sstevel@tonic-gate static char Wiobuf[3*WRIOBSZ];
1457c478bd9Sstevel@tonic-gate static int Riocnt[2] = {0, 0};
1467c478bd9Sstevel@tonic-gate static char *Riop[2];
1477c478bd9Sstevel@tonic-gate static char *Wiop[3];
1487c478bd9Sstevel@tonic-gate
1497c478bd9Sstevel@tonic-gate extern int optind; /* variable in getopt() */
1507c478bd9Sstevel@tonic-gate
1517c478bd9Sstevel@tonic-gate extern char
1527c478bd9Sstevel@tonic-gate *optarg;
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate static struct call Cucall; /* call structure for altconn() */
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate static int Saved_tty; /* was TCGETAW of _Tv0 successful? */
1577c478bd9Sstevel@tonic-gate static int Saved_termios; /* was TCGETSW of _Tv0 successful? */
1587c478bd9Sstevel@tonic-gate static struct termio _Tv, _Tv0; /* for saving, changing TTY atributes */
1597c478bd9Sstevel@tonic-gate static struct termios _Tv0s; /* for saving, changing TTY atributes */
1607c478bd9Sstevel@tonic-gate static struct termio _Lv; /* attributes for the line to remote */
1617c478bd9Sstevel@tonic-gate static struct termios _Lvs; /* attributes for the line to remote */
1627c478bd9Sstevel@tonic-gate static char prompt[BUFSIZ]= "[";
1637c478bd9Sstevel@tonic-gate static struct utsname utsn;
1647c478bd9Sstevel@tonic-gate static int command_line_hups = 0;
1657c478bd9Sstevel@tonic-gate
1667c478bd9Sstevel@tonic-gate static char filename[BUFSIZ] = "/dev/null";
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate static char
1697c478bd9Sstevel@tonic-gate _Cxc, /* place into which we do character io*/
1707c478bd9Sstevel@tonic-gate _Tintr, /* current input INTR */
1717c478bd9Sstevel@tonic-gate _Tquit, /* current input QUIT */
1727c478bd9Sstevel@tonic-gate _Terase, /* current input ERASE */
1737c478bd9Sstevel@tonic-gate _Tkill, /* current input KILL */
1747c478bd9Sstevel@tonic-gate _Teol, /* current secondary input EOL */
1757c478bd9Sstevel@tonic-gate _Myeof, /* current input EOF */
1767c478bd9Sstevel@tonic-gate term_mask, /* mask value for local terminal */
1777c478bd9Sstevel@tonic-gate line_mask; /* mask value for remote line */
1787c478bd9Sstevel@tonic-gate /* either '0177' or '0377' */
1797c478bd9Sstevel@tonic-gate
1807c478bd9Sstevel@tonic-gate int
1817c478bd9Sstevel@tonic-gate Echoe, /* save users ECHOE bit */
1827c478bd9Sstevel@tonic-gate Echok, /* save users ECHOK bit */
1837c478bd9Sstevel@tonic-gate Intrupt=NO, /* interrupt indicator */
1847c478bd9Sstevel@tonic-gate Ifc=YES, /* NO means remote can't XON/XOFF */
1857c478bd9Sstevel@tonic-gate Ofc=YES, /* NO means local can't XON/XOFF */
1867c478bd9Sstevel@tonic-gate Rtn_code=0, /* default return code */
1877c478bd9Sstevel@tonic-gate Divert=NO, /* don't allow unsolicited redirection */
1887c478bd9Sstevel@tonic-gate OldStyle=NO, /* don't handle old '~>:filename' syntax */
1897c478bd9Sstevel@tonic-gate /* this will be mandatory in SVR4.1 */
1907c478bd9Sstevel@tonic-gate Takeflag=NO, /* indicates a ~%take is in progress */
1917c478bd9Sstevel@tonic-gate Dologin=NO, /* go through the login chat sequence */
1927c478bd9Sstevel@tonic-gate Docmd=NO; /* execute command instead of interactive cu */
1937c478bd9Sstevel@tonic-gate
1947c478bd9Sstevel@tonic-gate EXTERN int /* These are initialized in line.c */
1957c478bd9Sstevel@tonic-gate Terminal, /* flag; remote is a terminal */
1967c478bd9Sstevel@tonic-gate Oddflag, /* flag- odd parity option*/
1977c478bd9Sstevel@tonic-gate Evenflag, /* flag- even parity option*/
1987c478bd9Sstevel@tonic-gate Duplex, /* Unix= full duplex=YES; half = NO */
1997c478bd9Sstevel@tonic-gate term_8bit, /* is terminal set for 8 bit processing */
2007c478bd9Sstevel@tonic-gate line_8bit; /* is line set for 8 bit processing */
2017c478bd9Sstevel@tonic-gate
2027c478bd9Sstevel@tonic-gate EXTERN int clear_hup();
2037c478bd9Sstevel@tonic-gate
2047c478bd9Sstevel@tonic-gate pid_t
2057c478bd9Sstevel@tonic-gate Child, /* pid for receive process */
2067c478bd9Sstevel@tonic-gate Shell; /* pid for escape process */
2077c478bd9Sstevel@tonic-gate
2087c478bd9Sstevel@tonic-gate static pid_t
2097c478bd9Sstevel@tonic-gate dofork(); /* fork and return pid */
2107c478bd9Sstevel@tonic-gate
2117c478bd9Sstevel@tonic-gate static int
2127c478bd9Sstevel@tonic-gate r_char(), /* local io routine */
2137c478bd9Sstevel@tonic-gate w_char(), /* local io routine */
2147c478bd9Sstevel@tonic-gate wioflsh();
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate static void
2177c478bd9Sstevel@tonic-gate _onintrpt(), /* interrupt routines */
2187c478bd9Sstevel@tonic-gate _rcvdead(),
2197c478bd9Sstevel@tonic-gate _quit(),
2207c478bd9Sstevel@tonic-gate _bye();
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate extern void cleanup();
2237c478bd9Sstevel@tonic-gate extern void tdmp();
2247c478bd9Sstevel@tonic-gate extern int conn(), altconn(), transmit(), tilda();
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate static void
2277c478bd9Sstevel@tonic-gate recfork(),
2287c478bd9Sstevel@tonic-gate sysname(),
2297c478bd9Sstevel@tonic-gate blckcnt(),
2307c478bd9Sstevel@tonic-gate _flush(),
2317c478bd9Sstevel@tonic-gate _shell(),
2327c478bd9Sstevel@tonic-gate _dopercen(),
2337c478bd9Sstevel@tonic-gate _receive(),
2347c478bd9Sstevel@tonic-gate _mode(),
2357c478bd9Sstevel@tonic-gate _w_str();
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate extern char *Myline; /* flag to force the requested line to be used */
2387c478bd9Sstevel@tonic-gate extern char *Mytype; /* flag to force requested line type to be used
2397c478bd9Sstevel@tonic-gate * rddev() will compare the string to the D_TYPE
2407c478bd9Sstevel@tonic-gate * (first) field of the Devices record and skip any
2417c478bd9Sstevel@tonic-gate * records where they are not equal. Mytype is set
2427c478bd9Sstevel@tonic-gate * to point to the argument of the -c option from
2437c478bd9Sstevel@tonic-gate * the command line. */
2447c478bd9Sstevel@tonic-gate static char *P_USAGE= "Usage: %s [-dhtnLC] [-c device] [-s speed] [-l line] [-b 7|8]\n\t[-o | -e] telno | systemname [local-cmd]\n";
2457c478bd9Sstevel@tonic-gate static char *P_CON_FAILED = "Connect failed: %s\r\n";
2467c478bd9Sstevel@tonic-gate static char *P_Ct_OPEN = "Cannot open: %s\r\n";
2477c478bd9Sstevel@tonic-gate static char *P_LINE_GONE = "Remote line gone\r\n";
2487c478bd9Sstevel@tonic-gate static char *P_Ct_EXSH = "Can't execute shell\r\n";
2497c478bd9Sstevel@tonic-gate static char *P_Ct_DIVERT = "Can't divert to %s\r\n";
2507c478bd9Sstevel@tonic-gate static char *P_Ct_UNDIVERT = "Can't end diversion to %s\r\n";
2517c478bd9Sstevel@tonic-gate static char *P_Bad_DIVERT = "Won't divert to %s. Unsolicited.\r\n";
2527c478bd9Sstevel@tonic-gate static char *P_STARTWITH = "Use `~~' to start line with `~'\r\n";
2537c478bd9Sstevel@tonic-gate static char *P_CNTAFTER = "File transmission interrupted after %ld bytes.\r\n";
2547c478bd9Sstevel@tonic-gate static char *P_CNTLINES = "%d lines/";
2557c478bd9Sstevel@tonic-gate static char *P_CNTCHAR = "%ld characters\r\n";
2567c478bd9Sstevel@tonic-gate static char *P_FILEINTR = "File transmission interrupted\r\n";
2577c478bd9Sstevel@tonic-gate static char *P_Ct_FK = "Can't fork -- try later\r\n";
2587c478bd9Sstevel@tonic-gate static char *P_Ct_SPECIAL = "r\nCan't transmit special character `%#o'\r\n";
2597c478bd9Sstevel@tonic-gate static char *P_TOOLONG = "\nLine too long\r\n";
2607c478bd9Sstevel@tonic-gate static char *P_IOERR = "r\nIO error\r\n";
2617c478bd9Sstevel@tonic-gate static char *P_USECMD = "Use `~$'cmd \r\n";
2627c478bd9Sstevel@tonic-gate #ifdef forfutureuse
2637c478bd9Sstevel@tonic-gate static char *P_USEPLUSCMD ="Use `~+'cmd \r\n";
2647c478bd9Sstevel@tonic-gate #endif
2657c478bd9Sstevel@tonic-gate #ifdef u3b
2667c478bd9Sstevel@tonic-gate static char *P_NOTERMSTAT = "Can't get terminal status\r\n";
2677c478bd9Sstevel@tonic-gate static char *P_3BCONSOLE = "Sorry, you can't cu from a 3B console\r\n";
2687c478bd9Sstevel@tonic-gate #endif
2697c478bd9Sstevel@tonic-gate static char *P_TELLENGTH = "Telno cannot exceed 58 digits!\r\n";
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate /***************************************************************
2727c478bd9Sstevel@tonic-gate * main: get command line args, establish connection, and fork.
2737c478bd9Sstevel@tonic-gate * Child invokes "receive" to read from remote & write to TTY.
2747c478bd9Sstevel@tonic-gate * Main line invokes "transmit" to read TTY & write to remote.
2757c478bd9Sstevel@tonic-gate ***************************************************************/
2767c478bd9Sstevel@tonic-gate
277*462be471Sceastha int
main(argc,argv)2787c478bd9Sstevel@tonic-gate main(argc, argv)
279*462be471Sceastha int argc;
2807c478bd9Sstevel@tonic-gate char *argv[];
2817c478bd9Sstevel@tonic-gate {
2827c478bd9Sstevel@tonic-gate extern void setservice();
2837c478bd9Sstevel@tonic-gate extern int sysaccess();
2847c478bd9Sstevel@tonic-gate char s[MAXPH];
2857c478bd9Sstevel@tonic-gate char *string;
2867c478bd9Sstevel@tonic-gate int i;
2877c478bd9Sstevel@tonic-gate int errflag=0;
2887c478bd9Sstevel@tonic-gate int lflag=0;
2897c478bd9Sstevel@tonic-gate int nflag=0;
2907c478bd9Sstevel@tonic-gate int systemname = 0;
2917c478bd9Sstevel@tonic-gate char vdisable;
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate /* Set locale environment variables local definitions */
2947c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
2957c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
2967c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it wasn't */
2977c478bd9Sstevel@tonic-gate #endif
2987c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
2997c478bd9Sstevel@tonic-gate
3007c478bd9Sstevel@tonic-gate Riop[0] = &Riobuf[0];
3017c478bd9Sstevel@tonic-gate Riop[1] = &Riobuf[WRIOBSZ];
3027c478bd9Sstevel@tonic-gate Wiop[0] = &Wiobuf[0];
3037c478bd9Sstevel@tonic-gate Wiop[1] = &Wiobuf[WRIOBSZ];
3047c478bd9Sstevel@tonic-gate Wiop[2] = &Wiobuf[2*WRIOBSZ];
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate Verbose = 1; /*for uucp callers, dialers feedback*/
3077c478bd9Sstevel@tonic-gate if ((string = strrchr(argv[0], '/')) != NULL)
3087c478bd9Sstevel@tonic-gate string++;
3097c478bd9Sstevel@tonic-gate else
3107c478bd9Sstevel@tonic-gate string = argv[0];
3117c478bd9Sstevel@tonic-gate if (strlcpy(Progname, string, NAMESIZE) >= NAMESIZE) {
3127c478bd9Sstevel@tonic-gate errno = ENAMETOOLONG;
3137c478bd9Sstevel@tonic-gate perror("cu");
3147c478bd9Sstevel@tonic-gate exit(1);
3157c478bd9Sstevel@tonic-gate }
3167c478bd9Sstevel@tonic-gate setservice(Progname);
3177c478bd9Sstevel@tonic-gate if ( sysaccess(EACCESS_SYSTEMS) != 0 ) {
3187c478bd9Sstevel@tonic-gate (void)fprintf(stderr,
3197c478bd9Sstevel@tonic-gate gettext("%s: Cannot read Systems files\n"), Progname);
3207c478bd9Sstevel@tonic-gate exit(1);
3217c478bd9Sstevel@tonic-gate }
3227c478bd9Sstevel@tonic-gate if ( sysaccess(EACCESS_DEVICES) != 0 ) {
3237c478bd9Sstevel@tonic-gate (void)fprintf(stderr,
3247c478bd9Sstevel@tonic-gate gettext("%s: Cannot read Devices files\n"), Progname);
3257c478bd9Sstevel@tonic-gate exit(1);
3267c478bd9Sstevel@tonic-gate }
3277c478bd9Sstevel@tonic-gate if ( sysaccess(EACCESS_DIALERS) != 0 ) {
3287c478bd9Sstevel@tonic-gate (void)fprintf(stderr,
3297c478bd9Sstevel@tonic-gate gettext("%s: Cannot read Dialers files\n"), Progname);
3307c478bd9Sstevel@tonic-gate exit(1);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate Cucall.speed = "Any"; /*default speed*/
3347c478bd9Sstevel@tonic-gate Cucall.line = CNULL;
3357c478bd9Sstevel@tonic-gate Cucall.telno = CNULL;
3367c478bd9Sstevel@tonic-gate Cucall.type = CNULL;
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate /*Flags for -h, -t, -e, and -o options set here; corresponding line attributes*/
3397c478bd9Sstevel@tonic-gate /*are set in fixline() in culine.c before remote connection is made */
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate while((i = getopt(argc, argv, "dhteons:l:c:b:LCH")) != EOF)
3427c478bd9Sstevel@tonic-gate switch(i) {
3437c478bd9Sstevel@tonic-gate case 'd':
3447c478bd9Sstevel@tonic-gate Debug = 9; /*turns on uucp debugging-level 9*/
3457c478bd9Sstevel@tonic-gate break;
3467c478bd9Sstevel@tonic-gate case 'h':
3477c478bd9Sstevel@tonic-gate Duplex = NO;
3487c478bd9Sstevel@tonic-gate Ifc = NO;
3497c478bd9Sstevel@tonic-gate Ofc = NO;
3507c478bd9Sstevel@tonic-gate break;
3517c478bd9Sstevel@tonic-gate case 't':
3527c478bd9Sstevel@tonic-gate Terminal = YES;
3537c478bd9Sstevel@tonic-gate break;
3547c478bd9Sstevel@tonic-gate case 'e':
3557c478bd9Sstevel@tonic-gate if ( Oddflag ) {
3567c478bd9Sstevel@tonic-gate (void)fprintf(stderr,
3577c478bd9Sstevel@tonic-gate gettext("%s: Cannot have both even and odd parity\n"),
3587c478bd9Sstevel@tonic-gate argv[0]);
3597c478bd9Sstevel@tonic-gate exit(1);
3607c478bd9Sstevel@tonic-gate }
3617c478bd9Sstevel@tonic-gate Evenflag = 1;
3627c478bd9Sstevel@tonic-gate break;
3637c478bd9Sstevel@tonic-gate case 'o':
3647c478bd9Sstevel@tonic-gate if ( Evenflag ) {
3657c478bd9Sstevel@tonic-gate (void)fprintf(stderr,
3667c478bd9Sstevel@tonic-gate gettext("%s: Cannot have both even and odd parity\n"),
3677c478bd9Sstevel@tonic-gate argv[0]);
3687c478bd9Sstevel@tonic-gate exit(1);
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate Oddflag = 1;
3717c478bd9Sstevel@tonic-gate break;
3727c478bd9Sstevel@tonic-gate case 'n':
3737c478bd9Sstevel@tonic-gate nflag++;
3747c478bd9Sstevel@tonic-gate printf(gettext("Please enter the number: "));
3757c478bd9Sstevel@tonic-gate /* Read line from stdin, remove trailing newline, if any */
3767c478bd9Sstevel@tonic-gate if (fgets(s, sizeof(s), stdin) != NULL &&
3777c478bd9Sstevel@tonic-gate strchr(s, '\n') != NULL)
3787c478bd9Sstevel@tonic-gate s[strlen(s)-1] = '\0';
3797c478bd9Sstevel@tonic-gate break;
3807c478bd9Sstevel@tonic-gate case 's':
3817c478bd9Sstevel@tonic-gate Sflag++;
3827c478bd9Sstevel@tonic-gate Cucall.speed = optarg;
3837c478bd9Sstevel@tonic-gate break;
3847c478bd9Sstevel@tonic-gate case 'l':
3857c478bd9Sstevel@tonic-gate lflag++;
3867c478bd9Sstevel@tonic-gate Cucall.line = optarg;
3877c478bd9Sstevel@tonic-gate break;
3887c478bd9Sstevel@tonic-gate case 'c':
3897c478bd9Sstevel@tonic-gate Cucall.type = optarg;
3907c478bd9Sstevel@tonic-gate Mytype = optarg;
3917c478bd9Sstevel@tonic-gate break;
3927c478bd9Sstevel@tonic-gate case 'b':
3937c478bd9Sstevel@tonic-gate line_8bit = ((*optarg=='7') ? NO : ((*optarg=='8') ? YES : -1));
3947c478bd9Sstevel@tonic-gate if ( line_8bit == -1 ) {
3957c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
3967c478bd9Sstevel@tonic-gate gettext("%s: b option value must be '7' or '8'\n"),
3977c478bd9Sstevel@tonic-gate argv[0]);
3987c478bd9Sstevel@tonic-gate exit(1);
3997c478bd9Sstevel@tonic-gate }
4007c478bd9Sstevel@tonic-gate break;
4017c478bd9Sstevel@tonic-gate case 'L':
4027c478bd9Sstevel@tonic-gate Dologin++;
4037c478bd9Sstevel@tonic-gate break;
4047c478bd9Sstevel@tonic-gate case 'C':
4057c478bd9Sstevel@tonic-gate Docmd++;
4067c478bd9Sstevel@tonic-gate break;
4077c478bd9Sstevel@tonic-gate case 'H':
4087c478bd9Sstevel@tonic-gate command_line_hups++;
4097c478bd9Sstevel@tonic-gate break;
4107c478bd9Sstevel@tonic-gate case '?':
4117c478bd9Sstevel@tonic-gate ++errflag;
4127c478bd9Sstevel@tonic-gate }
4137c478bd9Sstevel@tonic-gate
4147c478bd9Sstevel@tonic-gate #ifdef u3b
4157c478bd9Sstevel@tonic-gate {
4167c478bd9Sstevel@tonic-gate struct stat buff;
4177c478bd9Sstevel@tonic-gate if(fstat(TTYIN, &buff) < 0) {
4187c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_NOTERMSTAT),"");
4197c478bd9Sstevel@tonic-gate exit(1);
4207c478bd9Sstevel@tonic-gate } else if ( (buff.st_mode & S_IFMT) == S_IFCHR && buff.st_rdev == 0 ) {
4217c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_3BCONSOLE),"");
4227c478bd9Sstevel@tonic-gate exit(1);
4237c478bd9Sstevel@tonic-gate }
4247c478bd9Sstevel@tonic-gate }
4257c478bd9Sstevel@tonic-gate #endif
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate if((optind < argc && optind > 0) || (nflag && optind > 0)) {
4287c478bd9Sstevel@tonic-gate if(nflag)
4297c478bd9Sstevel@tonic-gate string=s;
4307c478bd9Sstevel@tonic-gate else
4317c478bd9Sstevel@tonic-gate string = strdup(argv[optind++]);
4327c478bd9Sstevel@tonic-gate Cucall.telno = string;
4337c478bd9Sstevel@tonic-gate if ( strlen(string) != strspn(string, "0123456789=-*#") ) {
4347c478bd9Sstevel@tonic-gate /* if it's not a legitimate telno, then it should be a systemname */
4357c478bd9Sstevel@tonic-gate if ( nflag ) {
4367c478bd9Sstevel@tonic-gate (void)fprintf(stderr, gettext("%s: Bad phone number %s\n"),
4377c478bd9Sstevel@tonic-gate argv[0], string);
4387c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Phone numbers may contain "
4397c478bd9Sstevel@tonic-gate "only the digits 0 through 9 and the special\n"
4407c478bd9Sstevel@tonic-gate "characters =, -, * and #.\n"));
4417c478bd9Sstevel@tonic-gate exit(1);
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate systemname++;
4447c478bd9Sstevel@tonic-gate }
4457c478bd9Sstevel@tonic-gate } else
4467c478bd9Sstevel@tonic-gate if(Cucall.line == CNULL) /*if none of above, must be direct */
4477c478bd9Sstevel@tonic-gate ++errflag;
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate if(errflag) {
4507c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_USAGE), argv[0]);
4517c478bd9Sstevel@tonic-gate exit(1);
4527c478bd9Sstevel@tonic-gate }
4537c478bd9Sstevel@tonic-gate
4547c478bd9Sstevel@tonic-gate if ((Cucall.telno != CNULL) &&
4557c478bd9Sstevel@tonic-gate (strlen(Cucall.telno) >= (size_t)(MAXPH - 1))) {
4567c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_TELLENGTH),"");
4577c478bd9Sstevel@tonic-gate exit(0);
4587c478bd9Sstevel@tonic-gate }
4597c478bd9Sstevel@tonic-gate
4607c478bd9Sstevel@tonic-gate /* save initial tty state */
4617c478bd9Sstevel@tonic-gate if (!(Saved_termios = ( ioctl(TTYIN, TCGETS, &_Tv0s) >= 0 ))) {
4627c478bd9Sstevel@tonic-gate Saved_tty = ( ioctl(TTYIN, TCGETA, &_Tv0) == 0 );
4637c478bd9Sstevel@tonic-gate _Tv0s.c_lflag = _Tv0.c_lflag;
4647c478bd9Sstevel@tonic-gate _Tv0s.c_oflag = _Tv0.c_oflag;
4657c478bd9Sstevel@tonic-gate _Tv0s.c_iflag = _Tv0.c_iflag;
4667c478bd9Sstevel@tonic-gate _Tv0s.c_cflag = _Tv0.c_cflag;
4677c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++)
4687c478bd9Sstevel@tonic-gate _Tv0s.c_cc[i] = _Tv0.c_cc[i];
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate if (Saved_termios || Saved_tty) {
4727c478bd9Sstevel@tonic-gate char *p;
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate /*
4757c478bd9Sstevel@tonic-gate * We consider the terminal to be in 8 bit mode only if cs8 is set,
4767c478bd9Sstevel@tonic-gate * istrip is not set, and we're not in the "C" locale. The "C"
4777c478bd9Sstevel@tonic-gate * locale is by definition 7 bit only. This provides reasonable
4787c478bd9Sstevel@tonic-gate * compatibility when running in the "C" locale (currently the default)
4797c478bd9Sstevel@tonic-gate * and connecting to other systems, which are most often 7 bit systems.
4807c478bd9Sstevel@tonic-gate */
4817c478bd9Sstevel@tonic-gate term_8bit = ( (_Tv0s.c_cflag & CS8) && !(_Tv0s.c_iflag & ISTRIP) &&
4827c478bd9Sstevel@tonic-gate ((p = setlocale(LC_CTYPE, NULL)) != NULL) && (strcmp(p, "C") != 0) );
4837c478bd9Sstevel@tonic-gate if ( !Oddflag && !Evenflag )
4847c478bd9Sstevel@tonic-gate if (_Tv0s.c_cflag & PARENB)
4857c478bd9Sstevel@tonic-gate if (_Tv0s.c_cflag & PARODD)
4867c478bd9Sstevel@tonic-gate Oddflag = 1;
4877c478bd9Sstevel@tonic-gate else
4887c478bd9Sstevel@tonic-gate Evenflag = 1;
4897c478bd9Sstevel@tonic-gate }
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate if (line_8bit == -1)
4927c478bd9Sstevel@tonic-gate line_8bit = term_8bit;
4937c478bd9Sstevel@tonic-gate
4947c478bd9Sstevel@tonic-gate term_mask = ( term_8bit ? 0377 : 0177 );
4957c478bd9Sstevel@tonic-gate line_mask = ( line_8bit ? 0377 : 0177 );
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate /* if not set, use the POSIX disabled designation */
4987c478bd9Sstevel@tonic-gate #ifdef _POSIX_VDISABLE
4997c478bd9Sstevel@tonic-gate vdisable = _POSIX_VDISABLE;
5007c478bd9Sstevel@tonic-gate #else
5017c478bd9Sstevel@tonic-gate vdisable = fpathconf(TTYIN, _PC_VDISABLE);
5027c478bd9Sstevel@tonic-gate #endif
5037c478bd9Sstevel@tonic-gate _Tintr = _Tv0s.c_cc[VINTR] ? _Tv0s.c_cc[VINTR] : vdisable;
5047c478bd9Sstevel@tonic-gate _Tquit = _Tv0s.c_cc[VQUIT] ? _Tv0s.c_cc[VQUIT] : vdisable;
5057c478bd9Sstevel@tonic-gate _Terase = _Tv0s.c_cc[VERASE] ? _Tv0s.c_cc[VERASE] : vdisable;
5067c478bd9Sstevel@tonic-gate _Tkill = _Tv0s.c_cc[VKILL] ? _Tv0s.c_cc[VKILL] : vdisable;
5077c478bd9Sstevel@tonic-gate _Teol = _Tv0s.c_cc[VEOL] ? _Tv0s.c_cc[VEOL] : vdisable;
5087c478bd9Sstevel@tonic-gate _Myeof = _Tv0s.c_cc[VEOF] ? _Tv0s.c_cc[VEOF] : '\04';
5097c478bd9Sstevel@tonic-gate Echoe = _Tv0s.c_lflag & ECHOE;
5107c478bd9Sstevel@tonic-gate Echok = _Tv0s.c_lflag & ECHOK;
5117c478bd9Sstevel@tonic-gate
5127c478bd9Sstevel@tonic-gate (void)signal(SIGHUP, cleanup);
5137c478bd9Sstevel@tonic-gate (void)signal(SIGQUIT, cleanup);
5147c478bd9Sstevel@tonic-gate (void)signal(SIGINT, cleanup);
5157c478bd9Sstevel@tonic-gate
5167c478bd9Sstevel@tonic-gate /* place call to system; if "cu systemname", use conn() from uucp
5177c478bd9Sstevel@tonic-gate directly. Otherwise, use altconn() which dummies in the
5187c478bd9Sstevel@tonic-gate Systems file line.
5197c478bd9Sstevel@tonic-gate */
5207c478bd9Sstevel@tonic-gate
5217c478bd9Sstevel@tonic-gate if(systemname) {
5227c478bd9Sstevel@tonic-gate if ( lflag )
5237c478bd9Sstevel@tonic-gate (void)fprintf(stderr,
5247c478bd9Sstevel@tonic-gate gettext("%s: Warning: -l flag ignored when system name used\n"),
5257c478bd9Sstevel@tonic-gate argv[0]);
5267c478bd9Sstevel@tonic-gate if ( Sflag )
5277c478bd9Sstevel@tonic-gate (void)fprintf(stderr,
5287c478bd9Sstevel@tonic-gate gettext("%s: Warning: -s flag ignored when system name used\n"),
5297c478bd9Sstevel@tonic-gate argv[0]);
5307c478bd9Sstevel@tonic-gate Cn = conn(string);
5317c478bd9Sstevel@tonic-gate if ( (Cn < 0) && (Cucall.type != CNULL) )
5327c478bd9Sstevel@tonic-gate Cn = altconn(&Cucall);
5337c478bd9Sstevel@tonic-gate } else
5347c478bd9Sstevel@tonic-gate Cn = altconn(&Cucall);
5357c478bd9Sstevel@tonic-gate
5367c478bd9Sstevel@tonic-gate if(Cn < 0) {
5377c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_CON_FAILED),UERRORTEXT);
5387c478bd9Sstevel@tonic-gate cleanup(-Cn);
5397c478bd9Sstevel@tonic-gate } else {
5407c478bd9Sstevel@tonic-gate struct stat Cnsbuf;
5417c478bd9Sstevel@tonic-gate if ( fstat(Cn, &Cnsbuf) == 0 )
5427c478bd9Sstevel@tonic-gate Dev_mode = Cnsbuf.st_mode;
5437c478bd9Sstevel@tonic-gate else
5447c478bd9Sstevel@tonic-gate Dev_mode = R_DEVICEMODE;
5457c478bd9Sstevel@tonic-gate fchmod(Cn, M_DEVICEMODE);
5467c478bd9Sstevel@tonic-gate }
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate if ((Docmd) && (argv[optind] == NULL)) {
5497c478bd9Sstevel@tonic-gate (void) fprintf(stderr,gettext("cu: local cmd is required, -C is ignored.\n"));
5507c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_USAGE), argv[0]);
5517c478bd9Sstevel@tonic-gate Docmd=NO;
5527c478bd9Sstevel@tonic-gate }
5537c478bd9Sstevel@tonic-gate
5547c478bd9Sstevel@tonic-gate if (!Docmd) {
5557c478bd9Sstevel@tonic-gate Euid = geteuid();
5567c478bd9Sstevel@tonic-gate if((setuid(getuid()) < 0) || (setgid(getgid()) < 0)) {
5577c478bd9Sstevel@tonic-gate VERBOSE("Unable to setuid/gid\n%s", "");
5587c478bd9Sstevel@tonic-gate cleanup(101);
5597c478bd9Sstevel@tonic-gate }
5607c478bd9Sstevel@tonic-gate }
5617c478bd9Sstevel@tonic-gate
5627c478bd9Sstevel@tonic-gate if(Debug)
5637c478bd9Sstevel@tonic-gate tdmp(Cn);
5647c478bd9Sstevel@tonic-gate
5657c478bd9Sstevel@tonic-gate /* At this point succeeded in getting an open communication line */
5667c478bd9Sstevel@tonic-gate /* Conn() takes care of closing the Systems file */
5677c478bd9Sstevel@tonic-gate
5687c478bd9Sstevel@tonic-gate if (!Docmd) {
5697c478bd9Sstevel@tonic-gate (void)signal(SIGINT,_onintrpt);
5707c478bd9Sstevel@tonic-gate _mode(1); /* put terminal in `raw' mode */
5717c478bd9Sstevel@tonic-gate VERBOSE("Connected\007\r\n%s", ""); /*bell!*/
5727c478bd9Sstevel@tonic-gate
5737c478bd9Sstevel@tonic-gate /* must catch signals before fork. if not and if _receive() */
5747c478bd9Sstevel@tonic-gate /* fails in just the right (wrong?) way, _rcvdead() can be */
5757c478bd9Sstevel@tonic-gate /* called and do "kill(getppid(),SIGUSR1);" before parent */
5767c478bd9Sstevel@tonic-gate /* has done calls to signal() after recfork(). */
5777c478bd9Sstevel@tonic-gate (void)signal(SIGUSR1, _bye);
5787c478bd9Sstevel@tonic-gate (void)signal(SIGHUP, cleanup);
5797c478bd9Sstevel@tonic-gate (void)signal(SIGQUIT, _onintrpt);
5807c478bd9Sstevel@tonic-gate
5817c478bd9Sstevel@tonic-gate sysname(&prompt[1]); /* set up system name prompt */
5827c478bd9Sstevel@tonic-gate (void) strcat(prompt, "]");
5837c478bd9Sstevel@tonic-gate
5847c478bd9Sstevel@tonic-gate recfork(); /* checks for child == 0 */
5857c478bd9Sstevel@tonic-gate
5867c478bd9Sstevel@tonic-gate if(Child > 0) {
5877c478bd9Sstevel@tonic-gate /*
5887c478bd9Sstevel@tonic-gate * Because the child counts hangups for the -H flag,
5897c478bd9Sstevel@tonic-gate * and because we fork a new child when doing (e.g.)
5907c478bd9Sstevel@tonic-gate * ~%take, we assume the first child we fork has
5917c478bd9Sstevel@tonic-gate * processed all the hangups and we reset the count here.
5927c478bd9Sstevel@tonic-gate * We really should pass the remaining count back from
5937c478bd9Sstevel@tonic-gate * the child to the parent when we kill the child.
5947c478bd9Sstevel@tonic-gate */
5957c478bd9Sstevel@tonic-gate command_line_hups = 0;
5967c478bd9Sstevel@tonic-gate Rtn_code = transmit();
5977c478bd9Sstevel@tonic-gate _quit(Rtn_code);
5987c478bd9Sstevel@tonic-gate /*NOTREACHED*/
5997c478bd9Sstevel@tonic-gate }
6007c478bd9Sstevel@tonic-gate } else {
6017c478bd9Sstevel@tonic-gate /*
6027c478bd9Sstevel@tonic-gate * Fork a child to run the specified command,
6037c478bd9Sstevel@tonic-gate * wait for it to finish, and clean up.
6047c478bd9Sstevel@tonic-gate */
6057c478bd9Sstevel@tonic-gate Child = dofork();
6067c478bd9Sstevel@tonic-gate if (Child == 0) {
6077c478bd9Sstevel@tonic-gate close(0);
6087c478bd9Sstevel@tonic-gate close(1);
6097c478bd9Sstevel@tonic-gate dup(Cn);
6107c478bd9Sstevel@tonic-gate dup(Cn);
6117c478bd9Sstevel@tonic-gate close(Cn);
6127c478bd9Sstevel@tonic-gate setgid(getgid());
6137c478bd9Sstevel@tonic-gate setuid(getuid());
6147c478bd9Sstevel@tonic-gate execvp(argv[optind], &argv[optind]);
6157c478bd9Sstevel@tonic-gate exit(-1);
6167c478bd9Sstevel@tonic-gate /* NOTREACHED */
6177c478bd9Sstevel@tonic-gate }
6187c478bd9Sstevel@tonic-gate wait(0);
6197c478bd9Sstevel@tonic-gate /* XXX - should return wait status as our exit code */
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate cleanup(Cn);
6227c478bd9Sstevel@tonic-gate /*NOTREACHED*/
623*462be471Sceastha return (0);
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate /*
6277c478bd9Sstevel@tonic-gate * Kill the present child, if it exists, then fork a new one.
6287c478bd9Sstevel@tonic-gate */
6297c478bd9Sstevel@tonic-gate
6307c478bd9Sstevel@tonic-gate static void
recfork()6317c478bd9Sstevel@tonic-gate recfork()
6327c478bd9Sstevel@tonic-gate {
6337c478bd9Sstevel@tonic-gate int ret, status;
6347c478bd9Sstevel@tonic-gate if (Child) {
6357c478bd9Sstevel@tonic-gate kill(Child, SIGKILL);
6367c478bd9Sstevel@tonic-gate while ( (ret = wait(&status)) != Child )
6377c478bd9Sstevel@tonic-gate if (ret == -1 && errno != EINTR)
6387c478bd9Sstevel@tonic-gate break;
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate Child = dofork();
6417c478bd9Sstevel@tonic-gate if(Child == 0) {
6427c478bd9Sstevel@tonic-gate (void)signal(SIGUSR1, SIG_DFL);
6437c478bd9Sstevel@tonic-gate (void)signal(SIGHUP, _rcvdead);
6447c478bd9Sstevel@tonic-gate (void)signal(SIGQUIT, SIG_IGN);
6457c478bd9Sstevel@tonic-gate (void)signal(SIGINT, SIG_IGN);
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate _receive(); /* This should run until killed */
6487c478bd9Sstevel@tonic-gate /*NOTREACHED*/
6497c478bd9Sstevel@tonic-gate }
6507c478bd9Sstevel@tonic-gate return;
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate /***************************************************************
6547c478bd9Sstevel@tonic-gate * transmit: copy stdin to remote fd, except:
6557c478bd9Sstevel@tonic-gate * ~. terminate
6567c478bd9Sstevel@tonic-gate * ~! local login-style shell
6577c478bd9Sstevel@tonic-gate * ~!cmd execute cmd locally
6587c478bd9Sstevel@tonic-gate * ~$proc execute proc locally, send output to line
6597c478bd9Sstevel@tonic-gate * ~%cmd execute builtin cmd (put, take, or break)
6607c478bd9Sstevel@tonic-gate ****************************************************************/
6617c478bd9Sstevel@tonic-gate #ifdef forfutureuse
6627c478bd9Sstevel@tonic-gate /*****************************************************************
6637c478bd9Sstevel@tonic-gate * ~+proc execute locally, with stdout to and stdin from line.
6647c478bd9Sstevel@tonic-gate ******************************************************************/
6657c478bd9Sstevel@tonic-gate #endif
6667c478bd9Sstevel@tonic-gate
6677c478bd9Sstevel@tonic-gate int
transmit()6687c478bd9Sstevel@tonic-gate transmit()
6697c478bd9Sstevel@tonic-gate {
6707c478bd9Sstevel@tonic-gate char b[BUFSIZ];
671*462be471Sceastha char *p;
672*462be471Sceastha int escape;
673*462be471Sceastha int id = 0; /* flag for systemname prompt on tilda escape */
6747c478bd9Sstevel@tonic-gate
6757c478bd9Sstevel@tonic-gate CDEBUG(4,"transmit started\n\r%s", "");
6767c478bd9Sstevel@tonic-gate
6777c478bd9Sstevel@tonic-gate /* In main loop, always waiting to read characters from */
6787c478bd9Sstevel@tonic-gate /* keyboard; writes characters to remote, or to TTYOUT */
6797c478bd9Sstevel@tonic-gate /* on a tilda escape */
6807c478bd9Sstevel@tonic-gate
6817c478bd9Sstevel@tonic-gate for (;;) {
6827c478bd9Sstevel@tonic-gate p = b;
6837c478bd9Sstevel@tonic-gate while(r_char(TTYIN) == YES) {
6847c478bd9Sstevel@tonic-gate if(p == b) /* Escape on leading ~ */
6857c478bd9Sstevel@tonic-gate escape = (_Cxc == '~');
6867c478bd9Sstevel@tonic-gate if(p == b+1) /* But not on leading ~~ */
6877c478bd9Sstevel@tonic-gate escape &= (_Cxc != '~');
6887c478bd9Sstevel@tonic-gate if(escape) {
6897c478bd9Sstevel@tonic-gate if(_Cxc == '\n' || _Cxc == '\r' || _Cxc == _Teol) {
6907c478bd9Sstevel@tonic-gate *p = '\0';
6917c478bd9Sstevel@tonic-gate if(tilda(b+1) == YES)
6927c478bd9Sstevel@tonic-gate return(0);
6937c478bd9Sstevel@tonic-gate id = 0;
6947c478bd9Sstevel@tonic-gate break;
6957c478bd9Sstevel@tonic-gate }
6967c478bd9Sstevel@tonic-gate if(_Cxc == _Tintr || _Cxc == _Tkill || _Cxc == _Tquit ||
6977c478bd9Sstevel@tonic-gate (Intrupt && _Cxc == '\0')) {
6987c478bd9Sstevel@tonic-gate if(_Cxc == _Tkill) {
6997c478bd9Sstevel@tonic-gate if(Echok)
7007c478bd9Sstevel@tonic-gate VERBOSE("\r\n%s", "");
7017c478bd9Sstevel@tonic-gate } else {
7027c478bd9Sstevel@tonic-gate _Cxc = '\r';
7037c478bd9Sstevel@tonic-gate if( w_char(Cn) == NO) {
7047c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_LINE_GONE),"");
7057c478bd9Sstevel@tonic-gate return(IOERR);
7067c478bd9Sstevel@tonic-gate }
7077c478bd9Sstevel@tonic-gate id=0;
7087c478bd9Sstevel@tonic-gate }
7097c478bd9Sstevel@tonic-gate break;
7107c478bd9Sstevel@tonic-gate }
7117c478bd9Sstevel@tonic-gate if((p == b+1) && (_Cxc != _Terase) && (!id)) {
7127c478bd9Sstevel@tonic-gate id = 1;
7137c478bd9Sstevel@tonic-gate VERBOSE("%s", prompt);
7147c478bd9Sstevel@tonic-gate }
7157c478bd9Sstevel@tonic-gate if(_Cxc == _Terase) {
7167c478bd9Sstevel@tonic-gate p = (--p < b)? b:p;
7177c478bd9Sstevel@tonic-gate if(p > b)
7187c478bd9Sstevel@tonic-gate if(Echoe) {
7197c478bd9Sstevel@tonic-gate VERBOSE("\b \b%s", "");
7207c478bd9Sstevel@tonic-gate } else
7217c478bd9Sstevel@tonic-gate (void)w_char(TTYOUT);
7227c478bd9Sstevel@tonic-gate } else {
7237c478bd9Sstevel@tonic-gate (void)w_char(TTYOUT);
7247c478bd9Sstevel@tonic-gate if(p-b < BUFSIZ)
7257c478bd9Sstevel@tonic-gate *p++ = _Cxc;
7267c478bd9Sstevel@tonic-gate else {
7277c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_TOOLONG),"");
7287c478bd9Sstevel@tonic-gate break;
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate }
7317c478bd9Sstevel@tonic-gate /*not a tilda escape command*/
7327c478bd9Sstevel@tonic-gate } else {
7337c478bd9Sstevel@tonic-gate if(Intrupt && _Cxc == '\0') {
7347c478bd9Sstevel@tonic-gate CDEBUG(4,"got break in transmit\n\r%s", "");
7357c478bd9Sstevel@tonic-gate Intrupt = NO;
7367c478bd9Sstevel@tonic-gate (*genbrk)(Cn);
7377c478bd9Sstevel@tonic-gate _flush();
7387c478bd9Sstevel@tonic-gate break;
7397c478bd9Sstevel@tonic-gate }
7407c478bd9Sstevel@tonic-gate if(w_char(Cn) == NO) {
7417c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_LINE_GONE),"");
7427c478bd9Sstevel@tonic-gate return(IOERR);
7437c478bd9Sstevel@tonic-gate }
7447c478bd9Sstevel@tonic-gate if(Duplex == NO) {
7457c478bd9Sstevel@tonic-gate if((w_char(TTYERR) == NO) || (wioflsh(TTYERR) == NO))
7467c478bd9Sstevel@tonic-gate return(IOERR);
7477c478bd9Sstevel@tonic-gate }
7487c478bd9Sstevel@tonic-gate if ((_Cxc == _Tintr) || (_Cxc == _Tquit) ||
7497c478bd9Sstevel@tonic-gate ( (p==b) && (_Cxc == _Myeof) ) ) {
7507c478bd9Sstevel@tonic-gate CDEBUG(4,"got a tintr\n\r%s", "");
7517c478bd9Sstevel@tonic-gate _flush();
7527c478bd9Sstevel@tonic-gate break;
7537c478bd9Sstevel@tonic-gate }
7547c478bd9Sstevel@tonic-gate if(_Cxc == '\n' || _Cxc == '\r' ||
7557c478bd9Sstevel@tonic-gate _Cxc == _Teol || _Cxc == _Tkill) {
7567c478bd9Sstevel@tonic-gate id=0;
7577c478bd9Sstevel@tonic-gate Takeflag = NO;
7587c478bd9Sstevel@tonic-gate break;
7597c478bd9Sstevel@tonic-gate }
7607c478bd9Sstevel@tonic-gate p = (char*)0;
7617c478bd9Sstevel@tonic-gate }
7627c478bd9Sstevel@tonic-gate }
7637c478bd9Sstevel@tonic-gate }
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate
7667c478bd9Sstevel@tonic-gate /***************************************************************
7677c478bd9Sstevel@tonic-gate * routine to halt input from remote and flush buffers
7687c478bd9Sstevel@tonic-gate ***************************************************************/
7697c478bd9Sstevel@tonic-gate static void
_flush()7707c478bd9Sstevel@tonic-gate _flush()
7717c478bd9Sstevel@tonic-gate {
7727c478bd9Sstevel@tonic-gate (void)ioctl(TTYOUT, TCXONC, 0); /* stop tty output */
7737c478bd9Sstevel@tonic-gate (void)ioctl(Cn, TCFLSH, 0); /* flush remote input */
7747c478bd9Sstevel@tonic-gate (void)ioctl(TTYOUT, TCFLSH, 1); /* flush tty output */
7757c478bd9Sstevel@tonic-gate (void)ioctl(TTYOUT, TCXONC, 1); /* restart tty output */
7767c478bd9Sstevel@tonic-gate if(Takeflag == NO) {
7777c478bd9Sstevel@tonic-gate return; /* didn't interupt file transmission */
7787c478bd9Sstevel@tonic-gate }
7797c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_FILEINTR),"");
7807c478bd9Sstevel@tonic-gate (void)sleep(3);
7817c478bd9Sstevel@tonic-gate _w_str("echo '\n~>\n';mesg y;stty echo\n");
7827c478bd9Sstevel@tonic-gate Takeflag = NO;
7837c478bd9Sstevel@tonic-gate return;
7847c478bd9Sstevel@tonic-gate }
7857c478bd9Sstevel@tonic-gate
7867c478bd9Sstevel@tonic-gate /**************************************************************
7877c478bd9Sstevel@tonic-gate * command interpreter for escape lines
7887c478bd9Sstevel@tonic-gate **************************************************************/
7897c478bd9Sstevel@tonic-gate int
tilda(cmd)7907c478bd9Sstevel@tonic-gate tilda(cmd)
791*462be471Sceastha char *cmd;
7927c478bd9Sstevel@tonic-gate {
7937c478bd9Sstevel@tonic-gate
7947c478bd9Sstevel@tonic-gate VERBOSE("\r\n%s", "");
7957c478bd9Sstevel@tonic-gate CDEBUG(4,"call tilda(%s)\r\n", cmd);
7967c478bd9Sstevel@tonic-gate
7977c478bd9Sstevel@tonic-gate switch(cmd[0]) {
7987c478bd9Sstevel@tonic-gate case CSUSP:
7997c478bd9Sstevel@tonic-gate case CDSUSP:
8007c478bd9Sstevel@tonic-gate _mode(0);
8017c478bd9Sstevel@tonic-gate kill(cmd[0] == CDSUSP ? getpid() : (pid_t) 0, SIGTSTP);
8027c478bd9Sstevel@tonic-gate _mode(1);
8037c478bd9Sstevel@tonic-gate break;
8047c478bd9Sstevel@tonic-gate case '.':
8057c478bd9Sstevel@tonic-gate if(Cucall.telno == CNULL)
8067c478bd9Sstevel@tonic-gate if(cmd[1] != '.') {
8077c478bd9Sstevel@tonic-gate _w_str("\04\04\04\04\04");
8087c478bd9Sstevel@tonic-gate if (Child)
8097c478bd9Sstevel@tonic-gate kill(Child, SIGKILL);
8107c478bd9Sstevel@tonic-gate if (ioctl (Cn, TCGETS, &_Lvs) < 0) {
8117c478bd9Sstevel@tonic-gate (void) ioctl (Cn, TCGETA, &_Lv);
8127c478bd9Sstevel@tonic-gate /* speed to zero for hangup */
8137c478bd9Sstevel@tonic-gate _Lv.c_cflag = 0;
8147c478bd9Sstevel@tonic-gate (void) ioctl (Cn, TCSETAW, &_Lv);
8157c478bd9Sstevel@tonic-gate } else {
8167c478bd9Sstevel@tonic-gate /* speed to zero for hangup */
8177c478bd9Sstevel@tonic-gate _Lvs.c_cflag &= 0xffff0000;
8187c478bd9Sstevel@tonic-gate cfsetospeed(&_Lvs, B0);
8197c478bd9Sstevel@tonic-gate (void) ioctl (Cn, TCSETSW, &_Lvs);
8207c478bd9Sstevel@tonic-gate }
8217c478bd9Sstevel@tonic-gate (void) sleep (2);
8227c478bd9Sstevel@tonic-gate }
8237c478bd9Sstevel@tonic-gate return(YES);
8247c478bd9Sstevel@tonic-gate case '!':
8257c478bd9Sstevel@tonic-gate _shell(cmd); /* local shell */
8267c478bd9Sstevel@tonic-gate VERBOSE("\r%c\r\n", *cmd);
8277c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
8287c478bd9Sstevel@tonic-gate break;
8297c478bd9Sstevel@tonic-gate case '$':
8307c478bd9Sstevel@tonic-gate if(cmd[1] == '\0') {
8317c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_USECMD),"");
8327c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
8337c478bd9Sstevel@tonic-gate } else {
8347c478bd9Sstevel@tonic-gate _shell(cmd); /*Local shell */
8357c478bd9Sstevel@tonic-gate VERBOSE("\r%c\r\n", *cmd);
8367c478bd9Sstevel@tonic-gate }
8377c478bd9Sstevel@tonic-gate break;
8387c478bd9Sstevel@tonic-gate
8397c478bd9Sstevel@tonic-gate #ifdef forfutureuse
8407c478bd9Sstevel@tonic-gate case '+':
8417c478bd9Sstevel@tonic-gate if(cmd[1] == '\0') {
8427c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_USEPLUSCMD), "");
8437c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
8447c478bd9Sstevel@tonic-gate } else {
8457c478bd9Sstevel@tonic-gate if (*cmd == '+')
8467c478bd9Sstevel@tonic-gate /* must suspend receive to give*/
8477c478bd9Sstevel@tonic-gate /*remote out to stdin of cmd */
8487c478bd9Sstevel@tonic-gate kill(Child, SIGKILL);
8497c478bd9Sstevel@tonic-gate _shell(cmd); /* Local shell */
8507c478bd9Sstevel@tonic-gate if (*cmd == '+')
8517c478bd9Sstevel@tonic-gate recfork();
8527c478bd9Sstevel@tonic-gate VERBOSE("\r%c\r\n", *cmd);
8537c478bd9Sstevel@tonic-gate }
8547c478bd9Sstevel@tonic-gate break;
8557c478bd9Sstevel@tonic-gate #endif
8567c478bd9Sstevel@tonic-gate case '%':
8577c478bd9Sstevel@tonic-gate _dopercen(++cmd);
8587c478bd9Sstevel@tonic-gate break;
8597c478bd9Sstevel@tonic-gate
8607c478bd9Sstevel@tonic-gate case 't':
8617c478bd9Sstevel@tonic-gate tdmp(TTYIN);
8627c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
8637c478bd9Sstevel@tonic-gate break;
8647c478bd9Sstevel@tonic-gate case 'l':
8657c478bd9Sstevel@tonic-gate tdmp(Cn);
8667c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
8677c478bd9Sstevel@tonic-gate break;
8687c478bd9Sstevel@tonic-gate
8697c478bd9Sstevel@tonic-gate default:
8707c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_STARTWITH),"");
8717c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
8727c478bd9Sstevel@tonic-gate break;
8737c478bd9Sstevel@tonic-gate }
8747c478bd9Sstevel@tonic-gate return(NO);
8757c478bd9Sstevel@tonic-gate }
8767c478bd9Sstevel@tonic-gate
8777c478bd9Sstevel@tonic-gate /***************************************************************
8787c478bd9Sstevel@tonic-gate * The routine "shell" takes an argument starting with
8797c478bd9Sstevel@tonic-gate * either "!" or "$", and terminated with '\0'.
8807c478bd9Sstevel@tonic-gate * If $arg, arg is the name of a local shell file which
8817c478bd9Sstevel@tonic-gate * is executed and its output is passed to the remote.
8827c478bd9Sstevel@tonic-gate * If !arg, we escape to a local shell to execute arg
8837c478bd9Sstevel@tonic-gate * with output to TTY, and if arg is null, escape to
8847c478bd9Sstevel@tonic-gate * a local shell and blind the remote line. In either
8857c478bd9Sstevel@tonic-gate * case, '^D' will kill the escape status.
8867c478bd9Sstevel@tonic-gate **************************************************************/
8877c478bd9Sstevel@tonic-gate
8887c478bd9Sstevel@tonic-gate #ifdef forfutureuse
8897c478bd9Sstevel@tonic-gate /***************************************************************
8907c478bd9Sstevel@tonic-gate * Another argument to the routine "shell" may be +. If +arg,
8917c478bd9Sstevel@tonic-gate * arg is the name of a local shell file which is executed with
8927c478bd9Sstevel@tonic-gate * stdin from and stdout to the remote.
8937c478bd9Sstevel@tonic-gate **************************************************************/
8947c478bd9Sstevel@tonic-gate #endif
8957c478bd9Sstevel@tonic-gate
8967c478bd9Sstevel@tonic-gate static void
_shell(str)8977c478bd9Sstevel@tonic-gate _shell(str)
8987c478bd9Sstevel@tonic-gate char *str;
8997c478bd9Sstevel@tonic-gate {
9007c478bd9Sstevel@tonic-gate pid_t fk, w_ret;
9017c478bd9Sstevel@tonic-gate void (*xx)(), (*yy)();
9027c478bd9Sstevel@tonic-gate
9037c478bd9Sstevel@tonic-gate CDEBUG(4,"call _shell(%s)\r\n", str);
9047c478bd9Sstevel@tonic-gate fk = dofork();
9057c478bd9Sstevel@tonic-gate if(fk < 0)
9067c478bd9Sstevel@tonic-gate return;
9077c478bd9Sstevel@tonic-gate Shell = fk;
9087c478bd9Sstevel@tonic-gate _mode(0); /* restore normal tty attributes */
9097c478bd9Sstevel@tonic-gate xx = signal(SIGINT, SIG_IGN);
9107c478bd9Sstevel@tonic-gate yy = signal(SIGQUIT, SIG_IGN);
9117c478bd9Sstevel@tonic-gate if(fk == 0) {
9127c478bd9Sstevel@tonic-gate char *shell;
9137c478bd9Sstevel@tonic-gate
9147c478bd9Sstevel@tonic-gate if( (shell = getenv("SHELL")) == NULL)
9157c478bd9Sstevel@tonic-gate /* use default if user's shell is not set */
9167c478bd9Sstevel@tonic-gate shell = SHELL;
9177c478bd9Sstevel@tonic-gate (void)close(TTYOUT);
9187c478bd9Sstevel@tonic-gate
9197c478bd9Sstevel@tonic-gate /***********************************************
9207c478bd9Sstevel@tonic-gate * Hook-up our "standard output"
9217c478bd9Sstevel@tonic-gate * to either the tty for '!' or the line
9227c478bd9Sstevel@tonic-gate * for '$' as appropriate
9237c478bd9Sstevel@tonic-gate ***********************************************/
9247c478bd9Sstevel@tonic-gate #ifdef forfutureuse
9257c478bd9Sstevel@tonic-gate
9267c478bd9Sstevel@tonic-gate /************************************************
9277c478bd9Sstevel@tonic-gate * Or to the line for '+'.
9287c478bd9Sstevel@tonic-gate **********************************************/
9297c478bd9Sstevel@tonic-gate #endif
9307c478bd9Sstevel@tonic-gate
9317c478bd9Sstevel@tonic-gate (void)fcntl((*str == '!')? TTYERR:Cn,F_DUPFD,TTYOUT);
9327c478bd9Sstevel@tonic-gate
9337c478bd9Sstevel@tonic-gate #ifdef forfutureuse
9347c478bd9Sstevel@tonic-gate /*************************************************
9357c478bd9Sstevel@tonic-gate * Hook-up "standard input" to the line for '+'.
9367c478bd9Sstevel@tonic-gate * **********************************************/
9377c478bd9Sstevel@tonic-gate if (*str == '+') {
9387c478bd9Sstevel@tonic-gate (void)close(TTYIN);
9397c478bd9Sstevel@tonic-gate (void)fcntl(Cn,F_DUPFD,TTYIN);
9407c478bd9Sstevel@tonic-gate }
9417c478bd9Sstevel@tonic-gate #endif
9427c478bd9Sstevel@tonic-gate
9437c478bd9Sstevel@tonic-gate /***********************************************
9447c478bd9Sstevel@tonic-gate * Hook-up our "standard input"
9457c478bd9Sstevel@tonic-gate * to the tty for '!' and '$'.
9467c478bd9Sstevel@tonic-gate ***********************************************/
9477c478bd9Sstevel@tonic-gate
9487c478bd9Sstevel@tonic-gate (void)close(Cn); /*parent still has Cn*/
9497c478bd9Sstevel@tonic-gate (void)signal(SIGINT, SIG_DFL);
9507c478bd9Sstevel@tonic-gate (void)signal(SIGHUP, SIG_DFL);
9517c478bd9Sstevel@tonic-gate (void)signal(SIGQUIT, SIG_DFL);
9527c478bd9Sstevel@tonic-gate (void)signal(SIGUSR1, SIG_DFL);
9537c478bd9Sstevel@tonic-gate if(*++str == '\0')
9547c478bd9Sstevel@tonic-gate (void)execl(shell,shell,(char*) 0,(char*) 0,(char *) 0);
9557c478bd9Sstevel@tonic-gate else
9567c478bd9Sstevel@tonic-gate (void)execl(shell,"sh","-c",str,(char *) 0);
9577c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_Ct_EXSH),"");
9587c478bd9Sstevel@tonic-gate exit(0);
9597c478bd9Sstevel@tonic-gate }
9607c478bd9Sstevel@tonic-gate while ((w_ret = wait((int*)0)) != fk)
9617c478bd9Sstevel@tonic-gate if (w_ret == -1 && errno != EINTR)
9627c478bd9Sstevel@tonic-gate break;
9637c478bd9Sstevel@tonic-gate Shell = 0;
9647c478bd9Sstevel@tonic-gate (void)signal(SIGINT, xx);
9657c478bd9Sstevel@tonic-gate (void)signal(SIGQUIT, yy);
9667c478bd9Sstevel@tonic-gate _mode(1);
9677c478bd9Sstevel@tonic-gate return;
9687c478bd9Sstevel@tonic-gate }
9697c478bd9Sstevel@tonic-gate
9707c478bd9Sstevel@tonic-gate
9717c478bd9Sstevel@tonic-gate /***************************************************************
9727c478bd9Sstevel@tonic-gate * This function implements the 'put', 'take', 'break',
9737c478bd9Sstevel@tonic-gate * 'ifc' (aliased to nostop) and 'ofc' (aliased to noostop)
9747c478bd9Sstevel@tonic-gate * commands which are internal to cu.
9757c478bd9Sstevel@tonic-gate ***************************************************************/
9767c478bd9Sstevel@tonic-gate
9777c478bd9Sstevel@tonic-gate static void
_dopercen(cmd)9787c478bd9Sstevel@tonic-gate _dopercen(cmd)
979*462be471Sceastha char *cmd;
9807c478bd9Sstevel@tonic-gate {
9817c478bd9Sstevel@tonic-gate char *arg[5];
9827c478bd9Sstevel@tonic-gate char *getpath;
9837c478bd9Sstevel@tonic-gate char mypath[MAXPATH];
9847c478bd9Sstevel@tonic-gate int narg;
9857c478bd9Sstevel@tonic-gate
9867c478bd9Sstevel@tonic-gate blckcnt((long)(-1));
9877c478bd9Sstevel@tonic-gate
9887c478bd9Sstevel@tonic-gate CDEBUG(4,"call _dopercen(\"%s\")\r\n", cmd);
9897c478bd9Sstevel@tonic-gate
9907c478bd9Sstevel@tonic-gate arg[narg=0] = strtok(cmd, " \t\n");
9917c478bd9Sstevel@tonic-gate
9927c478bd9Sstevel@tonic-gate /* following loop breaks out the command and args */
9937c478bd9Sstevel@tonic-gate while((arg[++narg] = strtok((char*) NULL, " \t\n")) != NULL) {
9947c478bd9Sstevel@tonic-gate if(narg < 4)
9957c478bd9Sstevel@tonic-gate continue;
9967c478bd9Sstevel@tonic-gate else
9977c478bd9Sstevel@tonic-gate break;
9987c478bd9Sstevel@tonic-gate }
9997c478bd9Sstevel@tonic-gate
10007c478bd9Sstevel@tonic-gate /* ~%take file option */
10017c478bd9Sstevel@tonic-gate if(EQUALS(arg[0], "take")) {
10027c478bd9Sstevel@tonic-gate if(narg < 2 || narg > 3) {
10037c478bd9Sstevel@tonic-gate VERBOSE("usage: ~%%take from [to]\r\n%s", "");
10047c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
10057c478bd9Sstevel@tonic-gate return;
10067c478bd9Sstevel@tonic-gate }
10077c478bd9Sstevel@tonic-gate if(narg == 2)
10087c478bd9Sstevel@tonic-gate arg[2] = arg[1];
10097c478bd9Sstevel@tonic-gate (void) strcpy(filename, arg[2]);
10107c478bd9Sstevel@tonic-gate recfork(); /* fork so child (receive) knows filename */
10117c478bd9Sstevel@tonic-gate
10127c478bd9Sstevel@tonic-gate /*
10137c478bd9Sstevel@tonic-gate * be sure that the remote file (arg[1]) exists before
10147c478bd9Sstevel@tonic-gate * you try to take it. otherwise, the error message from
10157c478bd9Sstevel@tonic-gate * cat will wind up in the local file (arg[2])
10167c478bd9Sstevel@tonic-gate *
10177c478bd9Sstevel@tonic-gate * what we're doing is:
10187c478bd9Sstevel@tonic-gate * stty -echo; \
10197c478bd9Sstevel@tonic-gate * if test -r arg1
10207c478bd9Sstevel@tonic-gate * then (echo '~[local]'>arg2; cat arg1; echo '~[local]'>)
10217c478bd9Sstevel@tonic-gate * else echo can't open: arg1
10227c478bd9Sstevel@tonic-gate * fi; \
10237c478bd9Sstevel@tonic-gate * stty echo
10247c478bd9Sstevel@tonic-gate *
10257c478bd9Sstevel@tonic-gate */
10267c478bd9Sstevel@tonic-gate _w_str("stty -echo;if test -r ");
10277c478bd9Sstevel@tonic-gate _w_str(arg[1]);
10287c478bd9Sstevel@tonic-gate _w_str("; then (echo '~");
10297c478bd9Sstevel@tonic-gate _w_str(prompt);
10307c478bd9Sstevel@tonic-gate _w_str(">'");
10317c478bd9Sstevel@tonic-gate _w_str(arg[2]);
10327c478bd9Sstevel@tonic-gate _w_str(";cat ");
10337c478bd9Sstevel@tonic-gate _w_str(arg[1]);
10347c478bd9Sstevel@tonic-gate _w_str(";echo '~");
10357c478bd9Sstevel@tonic-gate _w_str(prompt);
10367c478bd9Sstevel@tonic-gate _w_str(">'); else echo cant\\'t open: ");
10377c478bd9Sstevel@tonic-gate _w_str(arg[1]);
10387c478bd9Sstevel@tonic-gate _w_str("; fi;stty echo\n");
10397c478bd9Sstevel@tonic-gate Takeflag = YES;
10407c478bd9Sstevel@tonic-gate return;
10417c478bd9Sstevel@tonic-gate }
10427c478bd9Sstevel@tonic-gate /* ~%put file option*/
10437c478bd9Sstevel@tonic-gate if(EQUALS(arg[0], "put")) {
10447c478bd9Sstevel@tonic-gate FILE *file;
10457c478bd9Sstevel@tonic-gate char ch, buf[BUFSIZ], spec[NCC+1], *b, *p, *q;
10467c478bd9Sstevel@tonic-gate int i, j, len, tc=0, lines=0;
10477c478bd9Sstevel@tonic-gate long chars=0L;
10487c478bd9Sstevel@tonic-gate
10497c478bd9Sstevel@tonic-gate if(narg < 2 || narg > 3) {
10507c478bd9Sstevel@tonic-gate VERBOSE("usage: ~%%put from [to]\r\n%s", "");
10517c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
10527c478bd9Sstevel@tonic-gate return;
10537c478bd9Sstevel@tonic-gate }
10547c478bd9Sstevel@tonic-gate if(narg == 2)
10557c478bd9Sstevel@tonic-gate arg[2] = arg[1];
10567c478bd9Sstevel@tonic-gate
10577c478bd9Sstevel@tonic-gate if((file = fopen(arg[1], "r")) == NULL) {
10587c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_Ct_OPEN), arg[1]);
10597c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
10607c478bd9Sstevel@tonic-gate return;
10617c478bd9Sstevel@tonic-gate }
10627c478bd9Sstevel@tonic-gate /*
10637c478bd9Sstevel@tonic-gate * if cannot write into file on remote machine, write into
10647c478bd9Sstevel@tonic-gate * /dev/null
10657c478bd9Sstevel@tonic-gate *
10667c478bd9Sstevel@tonic-gate * what we're doing is:
10677c478bd9Sstevel@tonic-gate * stty -echo
10687c478bd9Sstevel@tonic-gate * (cat - > arg2) || cat - > /dev/null
10697c478bd9Sstevel@tonic-gate * stty echo
10707c478bd9Sstevel@tonic-gate */
10717c478bd9Sstevel@tonic-gate _w_str("stty -echo;(cat - >");
10727c478bd9Sstevel@tonic-gate _w_str(arg[2]);
10737c478bd9Sstevel@tonic-gate _w_str(")||cat - >/dev/null;stty echo\n");
10747c478bd9Sstevel@tonic-gate Intrupt = NO;
10757c478bd9Sstevel@tonic-gate for(i=0,j=0; i < NCC; ++i)
10767c478bd9Sstevel@tonic-gate if((ch=_Tv0s.c_cc[i]) != '\0')
10777c478bd9Sstevel@tonic-gate spec[j++] = ch;
10787c478bd9Sstevel@tonic-gate spec[j] = '\0';
10797c478bd9Sstevel@tonic-gate _mode(2); /*accept interrupts from keyboard*/
10807c478bd9Sstevel@tonic-gate (void)sleep(5); /*hope that w_str info digested*/
10817c478bd9Sstevel@tonic-gate
10827c478bd9Sstevel@tonic-gate /* Read characters line by line into buf to write to */
10837c478bd9Sstevel@tonic-gate /* remote with character and line count for blckcnt */
10847c478bd9Sstevel@tonic-gate while(Intrupt == NO &&
10857c478bd9Sstevel@tonic-gate fgets(b= &buf[MID],MID,file) != NULL) {
10867c478bd9Sstevel@tonic-gate /* worse case is each char must be escaped*/
10877c478bd9Sstevel@tonic-gate len = strlen(b);
10887c478bd9Sstevel@tonic-gate chars += len; /* character count */
10897c478bd9Sstevel@tonic-gate p = b;
10907c478bd9Sstevel@tonic-gate while(q = strpbrk(p, spec)) {
10917c478bd9Sstevel@tonic-gate if(*q == _Tintr || *q == _Tquit || *q == _Teol) {
10927c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_Ct_SPECIAL), *q);
10937c478bd9Sstevel@tonic-gate (void)strcpy(q, q+1);
10947c478bd9Sstevel@tonic-gate Intrupt = YES;
10957c478bd9Sstevel@tonic-gate } else {
10967c478bd9Sstevel@tonic-gate b = strncpy(b-1, b, q-b);
10977c478bd9Sstevel@tonic-gate *(q-1) = '\\';
10987c478bd9Sstevel@tonic-gate }
10997c478bd9Sstevel@tonic-gate p = q+1;
11007c478bd9Sstevel@tonic-gate }
11017c478bd9Sstevel@tonic-gate if((tc += len) >= MID) {
11027c478bd9Sstevel@tonic-gate (void)sleep(1);
11037c478bd9Sstevel@tonic-gate tc = len;
11047c478bd9Sstevel@tonic-gate }
11057c478bd9Sstevel@tonic-gate if(write(Cn, b, (unsigned)strlen(b)) < 0) {
11067c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_IOERR),"");
11077c478bd9Sstevel@tonic-gate Intrupt = YES;
11087c478bd9Sstevel@tonic-gate break;
11097c478bd9Sstevel@tonic-gate }
11107c478bd9Sstevel@tonic-gate ++lines; /* line count */
11117c478bd9Sstevel@tonic-gate blckcnt((long)chars);
11127c478bd9Sstevel@tonic-gate }
11137c478bd9Sstevel@tonic-gate _mode(1);
11147c478bd9Sstevel@tonic-gate blckcnt((long)(-2)); /* close */
11157c478bd9Sstevel@tonic-gate (void)fclose(file);
11167c478bd9Sstevel@tonic-gate if(Intrupt == YES) {
11177c478bd9Sstevel@tonic-gate Intrupt = NO;
11187c478bd9Sstevel@tonic-gate _w_str("\n");
11197c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_CNTAFTER), ++chars);
11207c478bd9Sstevel@tonic-gate } else {
11217c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_CNTLINES), lines);
11227c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_CNTCHAR),chars);
11237c478bd9Sstevel@tonic-gate }
11247c478bd9Sstevel@tonic-gate (void)sleep(3);
11257c478bd9Sstevel@tonic-gate _w_str("\04");
11267c478bd9Sstevel@tonic-gate return;
11277c478bd9Sstevel@tonic-gate }
11287c478bd9Sstevel@tonic-gate
11297c478bd9Sstevel@tonic-gate /* ~%b or ~%break */
11307c478bd9Sstevel@tonic-gate if(EQUALS(arg[0], "b") || EQUALS(arg[0], "break")) {
11317c478bd9Sstevel@tonic-gate (*genbrk)(Cn);
11327c478bd9Sstevel@tonic-gate return;
11337c478bd9Sstevel@tonic-gate }
11347c478bd9Sstevel@tonic-gate /* ~%d or ~%debug toggle */
11357c478bd9Sstevel@tonic-gate if(EQUALS(arg[0], "d") || EQUALS(arg[0], "debug")) {
11367c478bd9Sstevel@tonic-gate if(Debug == 0)
11377c478bd9Sstevel@tonic-gate Debug = 9;
11387c478bd9Sstevel@tonic-gate else
11397c478bd9Sstevel@tonic-gate Debug = 0;
11407c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
11417c478bd9Sstevel@tonic-gate return;
11427c478bd9Sstevel@tonic-gate }
11437c478bd9Sstevel@tonic-gate /* ~%[ifc|nostop] toggles start/stop input control */
11447c478bd9Sstevel@tonic-gate if( EQUALS(arg[0], "ifc") || EQUALS(arg[0], "nostop") ) {
11457c478bd9Sstevel@tonic-gate (void)ioctl(Cn, TCGETA, &_Tv);
11467c478bd9Sstevel@tonic-gate Ifc = !Ifc;
11477c478bd9Sstevel@tonic-gate if(Ifc == YES)
11487c478bd9Sstevel@tonic-gate _Tv.c_iflag |= IXOFF;
11497c478bd9Sstevel@tonic-gate else
11507c478bd9Sstevel@tonic-gate _Tv.c_iflag &= ~IXOFF;
11517c478bd9Sstevel@tonic-gate (void)ioctl(Cn, TCSETAW, &_Tv);
11527c478bd9Sstevel@tonic-gate _mode(1);
11537c478bd9Sstevel@tonic-gate VERBOSE("(ifc %s)", (Ifc ? "enabled" : "disabled"));
11547c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
11557c478bd9Sstevel@tonic-gate return;
11567c478bd9Sstevel@tonic-gate }
11577c478bd9Sstevel@tonic-gate /* ~%[ofc|noostop] toggles start/stop output control */
11587c478bd9Sstevel@tonic-gate if( EQUALS(arg[0], "ofc") || EQUALS(arg[0], "noostop") ) {
11597c478bd9Sstevel@tonic-gate (void)ioctl(Cn, TCGETA, &_Tv);
11607c478bd9Sstevel@tonic-gate Ofc = !Ofc;
11617c478bd9Sstevel@tonic-gate if(Ofc == YES)
11627c478bd9Sstevel@tonic-gate _Tv.c_iflag |= IXON;
11637c478bd9Sstevel@tonic-gate else
11647c478bd9Sstevel@tonic-gate _Tv.c_iflag &= ~IXON;
11657c478bd9Sstevel@tonic-gate (void)ioctl(Cn, TCSETAW, &_Tv);
11667c478bd9Sstevel@tonic-gate _mode(1);
11677c478bd9Sstevel@tonic-gate VERBOSE("(ofc %s)", (Ofc ? "enabled" : "disabled"));
11687c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
11697c478bd9Sstevel@tonic-gate return;
11707c478bd9Sstevel@tonic-gate }
11717c478bd9Sstevel@tonic-gate /* ~%divert toggles unsolicited redirection security */
11727c478bd9Sstevel@tonic-gate if( EQUALS(arg[0], "divert") ) {
11737c478bd9Sstevel@tonic-gate Divert = !Divert;
11747c478bd9Sstevel@tonic-gate recfork(); /* fork a new child so it knows about change */
11757c478bd9Sstevel@tonic-gate VERBOSE("(unsolicited diversion %s)", (Divert ? "enabled" : "disabled"));
11767c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
11777c478bd9Sstevel@tonic-gate return;
11787c478bd9Sstevel@tonic-gate }
11797c478bd9Sstevel@tonic-gate /* ~%old toggles recognition of old-style '~>:filename' */
11807c478bd9Sstevel@tonic-gate if( EQUALS(arg[0], "old") ) {
11817c478bd9Sstevel@tonic-gate OldStyle = !OldStyle;
11827c478bd9Sstevel@tonic-gate recfork(); /* fork a new child so it knows about change */
11837c478bd9Sstevel@tonic-gate VERBOSE("(old-style diversion %s)", (OldStyle ? "enabled" : "disabled"));
11847c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
11857c478bd9Sstevel@tonic-gate return;
11867c478bd9Sstevel@tonic-gate }
11877c478bd9Sstevel@tonic-gate /* Change local current directory */
11887c478bd9Sstevel@tonic-gate if(EQUALS(arg[0], "cd")) {
11897c478bd9Sstevel@tonic-gate if (narg < 2) {
11907c478bd9Sstevel@tonic-gate getpath = getenv("HOME");
11917c478bd9Sstevel@tonic-gate strlcpy(mypath, getpath, sizeof (mypath));
11927c478bd9Sstevel@tonic-gate if(chdir(mypath) < 0) {
11937c478bd9Sstevel@tonic-gate VERBOSE("Cannot change to %s\r\n", mypath);
11947c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
11957c478bd9Sstevel@tonic-gate return;
11967c478bd9Sstevel@tonic-gate }
11977c478bd9Sstevel@tonic-gate } else if (chdir(arg[1]) < 0) {
11987c478bd9Sstevel@tonic-gate VERBOSE("Cannot change to %s\r\n", arg[1]);
11997c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
12007c478bd9Sstevel@tonic-gate return;
12017c478bd9Sstevel@tonic-gate }
12027c478bd9Sstevel@tonic-gate recfork(); /* fork a new child so it knows about change */
12037c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
12047c478bd9Sstevel@tonic-gate return;
12057c478bd9Sstevel@tonic-gate }
12067c478bd9Sstevel@tonic-gate
12077c478bd9Sstevel@tonic-gate if (arg[0] == (char *) NULL)
12087c478bd9Sstevel@tonic-gate arg[0] = "";
12097c478bd9Sstevel@tonic-gate
12107c478bd9Sstevel@tonic-gate VERBOSE("~%%%s unknown to cu\r\n", arg[0]);
12117c478bd9Sstevel@tonic-gate VERBOSE("(continue)%s", "");
12127c478bd9Sstevel@tonic-gate return;
12137c478bd9Sstevel@tonic-gate }
12147c478bd9Sstevel@tonic-gate
12157c478bd9Sstevel@tonic-gate /***************************************************************
12167c478bd9Sstevel@tonic-gate * receive: read from remote line, write to fd=1 (TTYOUT)
12177c478bd9Sstevel@tonic-gate * catch:
12187c478bd9Sstevel@tonic-gate * ~>[>]:file
12197c478bd9Sstevel@tonic-gate * .
12207c478bd9Sstevel@tonic-gate * . stuff for file
12217c478bd9Sstevel@tonic-gate * .
12227c478bd9Sstevel@tonic-gate * ~> (ends diversion)
12237c478bd9Sstevel@tonic-gate ***************************************************************/
12247c478bd9Sstevel@tonic-gate
12257c478bd9Sstevel@tonic-gate static void
_receive()12267c478bd9Sstevel@tonic-gate _receive()
12277c478bd9Sstevel@tonic-gate {
1228*462be471Sceastha int silent = NO, file = -1;
1229*462be471Sceastha char *p;
12307c478bd9Sstevel@tonic-gate int tic;
12317c478bd9Sstevel@tonic-gate int for_me = NO;
12327c478bd9Sstevel@tonic-gate char b[BUFSIZ];
12337c478bd9Sstevel@tonic-gate char *b_p;
12347c478bd9Sstevel@tonic-gate long count;
12357c478bd9Sstevel@tonic-gate int line_ok = 1, rval;
12367c478bd9Sstevel@tonic-gate
12377c478bd9Sstevel@tonic-gate CDEBUG(4,"_receive started\r\n%s", "");
12387c478bd9Sstevel@tonic-gate
12397c478bd9Sstevel@tonic-gate b[0] = '\0';
12407c478bd9Sstevel@tonic-gate b_p = p = b;
12417c478bd9Sstevel@tonic-gate
12427c478bd9Sstevel@tonic-gate while(line_ok) {
12437c478bd9Sstevel@tonic-gate rval = r_char(Cn);
12447c478bd9Sstevel@tonic-gate if (rval == NO) {
12457c478bd9Sstevel@tonic-gate line_ok = 0;
12467c478bd9Sstevel@tonic-gate continue;
12477c478bd9Sstevel@tonic-gate }
12487c478bd9Sstevel@tonic-gate if (rval == HUNGUP) {
12497c478bd9Sstevel@tonic-gate if (command_line_hups > 0) {
12507c478bd9Sstevel@tonic-gate CDEBUG(4, "Ignoring device hangup\n%s", "");
12517c478bd9Sstevel@tonic-gate command_line_hups--;
12527c478bd9Sstevel@tonic-gate (void) setuid(Euid); /* reacquire privileges */
12537c478bd9Sstevel@tonic-gate if (clear_hup(Cn) != SUCCESS) {
12547c478bd9Sstevel@tonic-gate DEBUG(4, "Unable to clear hup on device\n%s", "");
12557c478bd9Sstevel@tonic-gate line_ok = 0;
12567c478bd9Sstevel@tonic-gate }
12577c478bd9Sstevel@tonic-gate (void) setuid(getuid()); /* relinquish privileges */
12587c478bd9Sstevel@tonic-gate } else
12597c478bd9Sstevel@tonic-gate line_ok = 0;
12607c478bd9Sstevel@tonic-gate continue;
12617c478bd9Sstevel@tonic-gate }
12627c478bd9Sstevel@tonic-gate
12637c478bd9Sstevel@tonic-gate if(silent == NO) /* ie., if not redirecting from screen */
12647c478bd9Sstevel@tonic-gate if(w_char(TTYOUT) == NO)
12657c478bd9Sstevel@tonic-gate _rcvdead(IOERR); /* this will exit */
12667c478bd9Sstevel@tonic-gate /* remove CR's and fill inserted by remote */
12677c478bd9Sstevel@tonic-gate if(_Cxc == '\0' || _Cxc == RUB || _Cxc == '\r')
12687c478bd9Sstevel@tonic-gate continue;
12697c478bd9Sstevel@tonic-gate *p++ = _Cxc;
12707c478bd9Sstevel@tonic-gate if(_Cxc != '\n' && (p-b) < BUFSIZ)
12717c478bd9Sstevel@tonic-gate continue;
12727c478bd9Sstevel@tonic-gate /* ****************************************** */
12737c478bd9Sstevel@tonic-gate /* This code deals with ~%take file diversion */
12747c478bd9Sstevel@tonic-gate /* ****************************************** */
12757c478bd9Sstevel@tonic-gate if (b[0] == '~') {
12767c478bd9Sstevel@tonic-gate int append;
12777c478bd9Sstevel@tonic-gate
12787c478bd9Sstevel@tonic-gate if (EQUALSN(&b[1],prompt,strlen(prompt))) {
12797c478bd9Sstevel@tonic-gate b_p = b + 1 + strlen(prompt);
12807c478bd9Sstevel@tonic-gate for_me = YES;
12817c478bd9Sstevel@tonic-gate } else {
12827c478bd9Sstevel@tonic-gate b_p = b + 1;
12837c478bd9Sstevel@tonic-gate for_me = NO;
12847c478bd9Sstevel@tonic-gate }
12857c478bd9Sstevel@tonic-gate if ( (for_me || OldStyle) && (*b_p == '>') ) {
12867c478bd9Sstevel@tonic-gate /* This is an acceptable '~[uname]>' line */
12877c478bd9Sstevel@tonic-gate b_p++;
12887c478bd9Sstevel@tonic-gate if ( (*b_p == '\n') && (silent == YES) ) {
12897c478bd9Sstevel@tonic-gate /* end of diversion */
12907c478bd9Sstevel@tonic-gate *b_p = '\0';
12917c478bd9Sstevel@tonic-gate (void) strcpy(filename, "/dev/null");
12927c478bd9Sstevel@tonic-gate if ( file >= 0 && close(file) ) {
12937c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_Ct_UNDIVERT), b_p);
12947c478bd9Sstevel@tonic-gate perror(gettext("cu: close failed"));
12957c478bd9Sstevel@tonic-gate VERBOSE("%s","\r");
12967c478bd9Sstevel@tonic-gate }
12977c478bd9Sstevel@tonic-gate silent = NO;
12987c478bd9Sstevel@tonic-gate blckcnt((long)(-2));
12997c478bd9Sstevel@tonic-gate VERBOSE("%s\r\n", b);
13007c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_CNTLINES), tic);
13017c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_CNTCHAR), count);
13027c478bd9Sstevel@tonic-gate file = -1;
13037c478bd9Sstevel@tonic-gate p = b;
13047c478bd9Sstevel@tonic-gate continue;
13057c478bd9Sstevel@tonic-gate } else if (*b_p != '\n') {
13067c478bd9Sstevel@tonic-gate if ( *b_p == '>' ) {
13077c478bd9Sstevel@tonic-gate append = 1;
13087c478bd9Sstevel@tonic-gate b_p++;
13097c478bd9Sstevel@tonic-gate }
13107c478bd9Sstevel@tonic-gate if ( (for_me || (OldStyle && (*b_p == ':'))) && (silent == NO) ) {
13117c478bd9Sstevel@tonic-gate /* terminate filename string */
13127c478bd9Sstevel@tonic-gate *(p-1) = '\0';
13137c478bd9Sstevel@tonic-gate if ( *b_p == ':' )
13147c478bd9Sstevel@tonic-gate b_p++;
13157c478bd9Sstevel@tonic-gate if ( !EQUALS(filename, b_p) ) {
13167c478bd9Sstevel@tonic-gate if ( !Divert || !EQUALS(filename, "/dev/null") ) {
13177c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_Bad_DIVERT), b_p);
13187c478bd9Sstevel@tonic-gate (void) strcpy(filename, "/dev/null");
13197c478bd9Sstevel@tonic-gate append = 1;
13207c478bd9Sstevel@tonic-gate } else {
13217c478bd9Sstevel@tonic-gate (void) strcpy(filename, b_p);
13227c478bd9Sstevel@tonic-gate }
13237c478bd9Sstevel@tonic-gate }
13247c478bd9Sstevel@tonic-gate if ( append && ((file=open(filename,O_WRONLY)) >= 0) )
13257c478bd9Sstevel@tonic-gate (void)lseek(file, 0L, 2);
13267c478bd9Sstevel@tonic-gate else
13277c478bd9Sstevel@tonic-gate file = creat(filename, PUB_FILEMODE);
13287c478bd9Sstevel@tonic-gate if (file < 0) {
13297c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_Ct_DIVERT), filename);
13307c478bd9Sstevel@tonic-gate perror(gettext("cu: open|creat failed"));
13317c478bd9Sstevel@tonic-gate VERBOSE("%s","\r");
13327c478bd9Sstevel@tonic-gate (void)sleep(5); /* 10 seemed too long*/
13337c478bd9Sstevel@tonic-gate }
13347c478bd9Sstevel@tonic-gate silent = YES;
13357c478bd9Sstevel@tonic-gate count = tic = 0;
13367c478bd9Sstevel@tonic-gate p = b;
13377c478bd9Sstevel@tonic-gate continue;
13387c478bd9Sstevel@tonic-gate }
13397c478bd9Sstevel@tonic-gate }
13407c478bd9Sstevel@tonic-gate }
13417c478bd9Sstevel@tonic-gate }
13427c478bd9Sstevel@tonic-gate /* Regular data, divert if appropriate */
13437c478bd9Sstevel@tonic-gate if ( silent == YES ) {
13447c478bd9Sstevel@tonic-gate if ( file >= 0)
13457c478bd9Sstevel@tonic-gate (void)write(file, b, (unsigned)(p-b));
13467c478bd9Sstevel@tonic-gate count += p-b; /* tally char count */
13477c478bd9Sstevel@tonic-gate ++tic; /* tally lines */
13487c478bd9Sstevel@tonic-gate blckcnt((long)count);
13497c478bd9Sstevel@tonic-gate }
13507c478bd9Sstevel@tonic-gate p = b;
13517c478bd9Sstevel@tonic-gate }
13527c478bd9Sstevel@tonic-gate /*
13537c478bd9Sstevel@tonic-gate * we used to tell of lost carrier here, but now
13547c478bd9Sstevel@tonic-gate * defer to _bye() so that escape processes are
13557c478bd9Sstevel@tonic-gate * not interrupted.
13567c478bd9Sstevel@tonic-gate */
13577c478bd9Sstevel@tonic-gate _rcvdead(IOERR);
13587c478bd9Sstevel@tonic-gate return;
13597c478bd9Sstevel@tonic-gate }
13607c478bd9Sstevel@tonic-gate
13617c478bd9Sstevel@tonic-gate /***************************************************************
13627c478bd9Sstevel@tonic-gate * change the TTY attributes of the users terminal:
13637c478bd9Sstevel@tonic-gate * 0 means restore attributes to pre-cu status.
13647c478bd9Sstevel@tonic-gate * 1 means set `raw' mode for use during cu session.
13657c478bd9Sstevel@tonic-gate * 2 means like 1 but accept interrupts from the keyboard.
13667c478bd9Sstevel@tonic-gate ***************************************************************/
13677c478bd9Sstevel@tonic-gate static void
_mode(arg)13687c478bd9Sstevel@tonic-gate _mode(arg)
13697c478bd9Sstevel@tonic-gate {
13707c478bd9Sstevel@tonic-gate int i;
13717c478bd9Sstevel@tonic-gate
13727c478bd9Sstevel@tonic-gate CDEBUG(4,"call _mode(%d)\r\n", arg);
13737c478bd9Sstevel@tonic-gate if(arg == 0) {
13747c478bd9Sstevel@tonic-gate if ( Saved_termios )
13757c478bd9Sstevel@tonic-gate (void)ioctl(TTYIN, TCSETSW, &_Tv0s);
13767c478bd9Sstevel@tonic-gate else if ( Saved_tty ) {
13777c478bd9Sstevel@tonic-gate _Tv0.c_lflag = _Tv0s.c_lflag;
13787c478bd9Sstevel@tonic-gate _Tv0.c_oflag = _Tv0s.c_oflag;
13797c478bd9Sstevel@tonic-gate _Tv0.c_iflag = _Tv0s.c_iflag;
13807c478bd9Sstevel@tonic-gate _Tv0.c_cflag = _Tv0s.c_cflag;
13817c478bd9Sstevel@tonic-gate for(i = 0; i < NCC; i++)
13827c478bd9Sstevel@tonic-gate _Tv0.c_cc[i] = _Tv0s.c_cc[i];
13837c478bd9Sstevel@tonic-gate (void)ioctl(TTYIN, TCSETAW, &_Tv0);
13847c478bd9Sstevel@tonic-gate }
13857c478bd9Sstevel@tonic-gate } else {
13867c478bd9Sstevel@tonic-gate (void)ioctl(TTYIN, TCGETA, &_Tv);
13877c478bd9Sstevel@tonic-gate if(arg == 1) {
13887c478bd9Sstevel@tonic-gate _Tv.c_iflag &= ~(INLCR | ICRNL | IGNCR | IUCLC);
13897c478bd9Sstevel@tonic-gate if ( !term_8bit )
13907c478bd9Sstevel@tonic-gate _Tv.c_iflag |= ISTRIP;
13917c478bd9Sstevel@tonic-gate _Tv.c_oflag |= OPOST;
13927c478bd9Sstevel@tonic-gate _Tv.c_oflag &= ~(OLCUC | ONLCR | OCRNL | ONOCR | ONLRET);
13937c478bd9Sstevel@tonic-gate _Tv.c_lflag &= ~(ICANON | ISIG | ECHO);
13947c478bd9Sstevel@tonic-gate if(Ifc == NO)
13957c478bd9Sstevel@tonic-gate _Tv.c_iflag &= ~IXON;
13967c478bd9Sstevel@tonic-gate else
13977c478bd9Sstevel@tonic-gate _Tv.c_iflag |= IXON;
13987c478bd9Sstevel@tonic-gate if(Ofc == NO)
13997c478bd9Sstevel@tonic-gate _Tv.c_iflag &= ~IXOFF;
14007c478bd9Sstevel@tonic-gate else
14017c478bd9Sstevel@tonic-gate _Tv.c_iflag |= IXOFF;
14027c478bd9Sstevel@tonic-gate if(Terminal) {
14037c478bd9Sstevel@tonic-gate _Tv.c_oflag |= ONLCR;
14047c478bd9Sstevel@tonic-gate _Tv.c_iflag |= ICRNL;
14057c478bd9Sstevel@tonic-gate }
14067c478bd9Sstevel@tonic-gate _Tv.c_cc[VEOF] = '\01';
14077c478bd9Sstevel@tonic-gate _Tv.c_cc[VEOL] = '\0';
14087c478bd9Sstevel@tonic-gate }
14097c478bd9Sstevel@tonic-gate if(arg == 2) {
14107c478bd9Sstevel@tonic-gate _Tv.c_iflag |= IXON;
14117c478bd9Sstevel@tonic-gate _Tv.c_lflag |= ISIG;
14127c478bd9Sstevel@tonic-gate }
14137c478bd9Sstevel@tonic-gate (void)ioctl(TTYIN, TCSETAW, &_Tv);
14147c478bd9Sstevel@tonic-gate }
14157c478bd9Sstevel@tonic-gate return;
14167c478bd9Sstevel@tonic-gate }
14177c478bd9Sstevel@tonic-gate
14187c478bd9Sstevel@tonic-gate
14197c478bd9Sstevel@tonic-gate static pid_t
dofork()14207c478bd9Sstevel@tonic-gate dofork()
14217c478bd9Sstevel@tonic-gate {
1422*462be471Sceastha int i;
14237c478bd9Sstevel@tonic-gate pid_t x;
14247c478bd9Sstevel@tonic-gate
14257c478bd9Sstevel@tonic-gate for(i = 0; i < 6; ++i) {
14267c478bd9Sstevel@tonic-gate if((x = fork()) >= 0) {
14277c478bd9Sstevel@tonic-gate return(x);
14287c478bd9Sstevel@tonic-gate }
14297c478bd9Sstevel@tonic-gate }
14307c478bd9Sstevel@tonic-gate
14317c478bd9Sstevel@tonic-gate if(Debug) perror("dofork");
14327c478bd9Sstevel@tonic-gate
14337c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_Ct_FK),"");
14347c478bd9Sstevel@tonic-gate return(x);
14357c478bd9Sstevel@tonic-gate }
14367c478bd9Sstevel@tonic-gate
14377c478bd9Sstevel@tonic-gate static int
r_char(fd)14387c478bd9Sstevel@tonic-gate r_char(fd)
14397c478bd9Sstevel@tonic-gate {
14407c478bd9Sstevel@tonic-gate int rtn = 1, rfd;
14417c478bd9Sstevel@tonic-gate char *riobuf;
14427c478bd9Sstevel@tonic-gate
14437c478bd9Sstevel@tonic-gate /* find starting pos in correct buffer in Riobuf */
14447c478bd9Sstevel@tonic-gate rfd = RIOFD(fd);
14457c478bd9Sstevel@tonic-gate riobuf = &Riobuf[rfd*WRIOBSZ];
14467c478bd9Sstevel@tonic-gate
14477c478bd9Sstevel@tonic-gate if (Riop[rfd] >= &riobuf[Riocnt[rfd]]) {
14487c478bd9Sstevel@tonic-gate /* empty read buffer - refill it */
14497c478bd9Sstevel@tonic-gate
14507c478bd9Sstevel@tonic-gate /* flush any waiting output */
14517c478bd9Sstevel@tonic-gate if ( (wioflsh(Cn) == NO ) || (wioflsh(TTYOUT) == NO) )
14527c478bd9Sstevel@tonic-gate return(NO);
14537c478bd9Sstevel@tonic-gate
14547c478bd9Sstevel@tonic-gate while((rtn = read(fd, riobuf, WRIOBSZ)) < 0){
14557c478bd9Sstevel@tonic-gate if(errno == EINTR) {
14567c478bd9Sstevel@tonic-gate /* onintrpt() called asynchronously before this line */
14577c478bd9Sstevel@tonic-gate if(Intrupt == YES) {
14587c478bd9Sstevel@tonic-gate /* got a BREAK */
14597c478bd9Sstevel@tonic-gate _Cxc = '\0';
14607c478bd9Sstevel@tonic-gate return(YES);
14617c478bd9Sstevel@tonic-gate } else {
14627c478bd9Sstevel@tonic-gate /*a signal other than interrupt*/
14637c478bd9Sstevel@tonic-gate /*received during read*/
14647c478bd9Sstevel@tonic-gate continue;
14657c478bd9Sstevel@tonic-gate }
14667c478bd9Sstevel@tonic-gate } else {
14677c478bd9Sstevel@tonic-gate CDEBUG(4,"got read error, not EINTR\n\r%s", "");
14687c478bd9Sstevel@tonic-gate break; /* something wrong */
14697c478bd9Sstevel@tonic-gate }
14707c478bd9Sstevel@tonic-gate }
14717c478bd9Sstevel@tonic-gate if (rtn > 0) {
14727c478bd9Sstevel@tonic-gate /* reset current position in buffer */
14737c478bd9Sstevel@tonic-gate /* and count of available chars */
14747c478bd9Sstevel@tonic-gate Riop[rfd] = riobuf;
14757c478bd9Sstevel@tonic-gate Riocnt[rfd] = rtn;
14767c478bd9Sstevel@tonic-gate }
14777c478bd9Sstevel@tonic-gate }
14787c478bd9Sstevel@tonic-gate
14797c478bd9Sstevel@tonic-gate if ( rtn > 0 ) {
14807c478bd9Sstevel@tonic-gate _Cxc = *(Riop[rfd]++) & RMASK(fd); /* mask off appropriate bits */
14817c478bd9Sstevel@tonic-gate return(YES);
14827c478bd9Sstevel@tonic-gate } else if (rtn == 0) {
14837c478bd9Sstevel@tonic-gate _Cxc = '\0';
14847c478bd9Sstevel@tonic-gate return (HUNGUP);
14857c478bd9Sstevel@tonic-gate } else {
14867c478bd9Sstevel@tonic-gate _Cxc = '\0';
14877c478bd9Sstevel@tonic-gate return(NO);
14887c478bd9Sstevel@tonic-gate }
14897c478bd9Sstevel@tonic-gate }
14907c478bd9Sstevel@tonic-gate
14917c478bd9Sstevel@tonic-gate static int
w_char(fd)14927c478bd9Sstevel@tonic-gate w_char(fd)
14937c478bd9Sstevel@tonic-gate {
14947c478bd9Sstevel@tonic-gate int wfd;
14957c478bd9Sstevel@tonic-gate char *wiobuf;
14967c478bd9Sstevel@tonic-gate
14977c478bd9Sstevel@tonic-gate /* find starting pos in correct buffer in Wiobuf */
14987c478bd9Sstevel@tonic-gate wfd = WIOFD(fd);
14997c478bd9Sstevel@tonic-gate wiobuf = &Wiobuf[wfd*WRIOBSZ];
15007c478bd9Sstevel@tonic-gate
15017c478bd9Sstevel@tonic-gate if (Wiop[wfd] >= &wiobuf[WRIOBSZ]) {
15027c478bd9Sstevel@tonic-gate /* full output buffer - flush it */
15037c478bd9Sstevel@tonic-gate if ( wioflsh(fd) == NO )
15047c478bd9Sstevel@tonic-gate return(NO);
15057c478bd9Sstevel@tonic-gate }
15067c478bd9Sstevel@tonic-gate *(Wiop[wfd]++) = _Cxc & WMASK(fd); /* mask off appropriate bits */
15077c478bd9Sstevel@tonic-gate return(YES);
15087c478bd9Sstevel@tonic-gate }
15097c478bd9Sstevel@tonic-gate
15107c478bd9Sstevel@tonic-gate /* wioflsh flush output buffer */
15117c478bd9Sstevel@tonic-gate static int
wioflsh(fd)15127c478bd9Sstevel@tonic-gate wioflsh(fd)
15137c478bd9Sstevel@tonic-gate int fd;
15147c478bd9Sstevel@tonic-gate {
15157c478bd9Sstevel@tonic-gate int wfd;
15167c478bd9Sstevel@tonic-gate char *wiobuf;
15177c478bd9Sstevel@tonic-gate
15187c478bd9Sstevel@tonic-gate /* find starting pos in correct buffer in Wiobuf */
15197c478bd9Sstevel@tonic-gate wfd = WIOFD(fd);
15207c478bd9Sstevel@tonic-gate wiobuf = &Wiobuf[wfd*WRIOBSZ];
15217c478bd9Sstevel@tonic-gate
15227c478bd9Sstevel@tonic-gate if (Wiop[wfd] > wiobuf) {
15237c478bd9Sstevel@tonic-gate /* there's something in the buffer */
15247c478bd9Sstevel@tonic-gate while(write(fd, wiobuf, (Wiop[wfd] - wiobuf)) < 0) {
15257c478bd9Sstevel@tonic-gate if(errno == EINTR) {
15267c478bd9Sstevel@tonic-gate if(Intrupt == YES) {
15277c478bd9Sstevel@tonic-gate VERBOSE("\ncu: Output blocked\r\n%s", "");
15287c478bd9Sstevel@tonic-gate _quit(IOERR);
15297c478bd9Sstevel@tonic-gate } else
15307c478bd9Sstevel@tonic-gate continue; /* alarm went off */
15317c478bd9Sstevel@tonic-gate } else {
15327c478bd9Sstevel@tonic-gate Wiop[wfd] = wiobuf;
15337c478bd9Sstevel@tonic-gate return(NO); /* bad news */
15347c478bd9Sstevel@tonic-gate }
15357c478bd9Sstevel@tonic-gate }
15367c478bd9Sstevel@tonic-gate }
15377c478bd9Sstevel@tonic-gate Wiop[wfd] = wiobuf;
15387c478bd9Sstevel@tonic-gate return(YES);
15397c478bd9Sstevel@tonic-gate }
15407c478bd9Sstevel@tonic-gate
15417c478bd9Sstevel@tonic-gate
15427c478bd9Sstevel@tonic-gate static void
_w_str(string)15437c478bd9Sstevel@tonic-gate _w_str(string)
1544*462be471Sceastha char *string;
15457c478bd9Sstevel@tonic-gate {
15467c478bd9Sstevel@tonic-gate int len;
15477c478bd9Sstevel@tonic-gate
15487c478bd9Sstevel@tonic-gate len = strlen(string);
15497c478bd9Sstevel@tonic-gate if ( write(Cn, string, (unsigned)len) != len )
15507c478bd9Sstevel@tonic-gate VERBOSE(gettext(P_LINE_GONE),"");
15517c478bd9Sstevel@tonic-gate return;
15527c478bd9Sstevel@tonic-gate }
15537c478bd9Sstevel@tonic-gate
15547c478bd9Sstevel@tonic-gate /* ARGSUSED */
15557c478bd9Sstevel@tonic-gate static void
_onintrpt(sig)15567c478bd9Sstevel@tonic-gate _onintrpt(sig)
15577c478bd9Sstevel@tonic-gate int sig;
15587c478bd9Sstevel@tonic-gate {
15597c478bd9Sstevel@tonic-gate (void)signal(SIGINT, _onintrpt);
15607c478bd9Sstevel@tonic-gate (void)signal(SIGQUIT, _onintrpt);
15617c478bd9Sstevel@tonic-gate Intrupt = YES;
15627c478bd9Sstevel@tonic-gate return;
15637c478bd9Sstevel@tonic-gate }
15647c478bd9Sstevel@tonic-gate
15657c478bd9Sstevel@tonic-gate static void
_rcvdead(arg)15667c478bd9Sstevel@tonic-gate _rcvdead(arg) /* this is executed only in the receive process */
15677c478bd9Sstevel@tonic-gate int arg;
15687c478bd9Sstevel@tonic-gate {
15697c478bd9Sstevel@tonic-gate CDEBUG(4,"call _rcvdead(%d)\r\n", arg);
15707c478bd9Sstevel@tonic-gate (void)kill(getppid(), SIGUSR1);
15717c478bd9Sstevel@tonic-gate exit((arg == SIGHUP)? SIGHUP: arg);
15727c478bd9Sstevel@tonic-gate /*NOTREACHED*/
15737c478bd9Sstevel@tonic-gate }
15747c478bd9Sstevel@tonic-gate
15757c478bd9Sstevel@tonic-gate static void
_quit(arg)15767c478bd9Sstevel@tonic-gate _quit(arg) /* this is executed only in the parent process */
15777c478bd9Sstevel@tonic-gate int arg;
15787c478bd9Sstevel@tonic-gate {
15797c478bd9Sstevel@tonic-gate CDEBUG(4,"call _quit(%d)\r\n", arg);
15807c478bd9Sstevel@tonic-gate (void)kill(Child, SIGKILL);
15817c478bd9Sstevel@tonic-gate _bye(arg);
15827c478bd9Sstevel@tonic-gate /*NOTREACHED*/
15837c478bd9Sstevel@tonic-gate }
15847c478bd9Sstevel@tonic-gate
15857c478bd9Sstevel@tonic-gate static void
_bye(arg)15867c478bd9Sstevel@tonic-gate _bye(arg) /* this is executed only in the parent proccess */
15877c478bd9Sstevel@tonic-gate int arg;
15887c478bd9Sstevel@tonic-gate {
15897c478bd9Sstevel@tonic-gate int status;
15907c478bd9Sstevel@tonic-gate pid_t obit;
15917c478bd9Sstevel@tonic-gate
15927c478bd9Sstevel@tonic-gate if ( Shell > 0 )
15937c478bd9Sstevel@tonic-gate while ((obit = wait(&status)) != Shell) {
15947c478bd9Sstevel@tonic-gate if (obit == -1 && errno != EINTR)
15957c478bd9Sstevel@tonic-gate break;
15967c478bd9Sstevel@tonic-gate /* _receive (Child) may have ended - check it out */
15977c478bd9Sstevel@tonic-gate if (obit == Child)
15987c478bd9Sstevel@tonic-gate Child = 0;
15997c478bd9Sstevel@tonic-gate }
16007c478bd9Sstevel@tonic-gate
16017c478bd9Sstevel@tonic-gate /* give user customary message after escape command returns */
16027c478bd9Sstevel@tonic-gate if (arg == SIGUSR1)
16037c478bd9Sstevel@tonic-gate VERBOSE("\r\nLost Carrier\r\n%s", "");
16047c478bd9Sstevel@tonic-gate
16057c478bd9Sstevel@tonic-gate CDEBUG(4,"call _bye(%d)\r\n", arg);
16067c478bd9Sstevel@tonic-gate
16077c478bd9Sstevel@tonic-gate (void)signal(SIGINT, SIG_IGN);
16087c478bd9Sstevel@tonic-gate (void)signal(SIGQUIT, SIG_IGN);
16097c478bd9Sstevel@tonic-gate /* if _receive() ended already, don't wait for it again */
16107c478bd9Sstevel@tonic-gate if ( Child != 0 )
16117c478bd9Sstevel@tonic-gate while ((obit = wait(&status)) != Child)
16127c478bd9Sstevel@tonic-gate if (obit == -1 && errno != EINTR)
16137c478bd9Sstevel@tonic-gate break;
16147c478bd9Sstevel@tonic-gate VERBOSE("\r\nDisconnected\007\r\n%s", "");
16157c478bd9Sstevel@tonic-gate cleanup((arg == SIGUSR1)? (status >>= 8): arg);
16167c478bd9Sstevel@tonic-gate /*NOTREACHED*/
16177c478bd9Sstevel@tonic-gate }
16187c478bd9Sstevel@tonic-gate
16197c478bd9Sstevel@tonic-gate
16207c478bd9Sstevel@tonic-gate
16217c478bd9Sstevel@tonic-gate void
cleanup(code)16227c478bd9Sstevel@tonic-gate cleanup(code) /*this is executed only in the parent process*/
16237c478bd9Sstevel@tonic-gate int code; /*Closes device; removes lock files */
16247c478bd9Sstevel@tonic-gate {
16257c478bd9Sstevel@tonic-gate
16267c478bd9Sstevel@tonic-gate CDEBUG(4,"call cleanup(%d)\r\n", code);
16277c478bd9Sstevel@tonic-gate
16287c478bd9Sstevel@tonic-gate if (Docmd) {
16297c478bd9Sstevel@tonic-gate if (Child > 0)
16307c478bd9Sstevel@tonic-gate (void)kill(Child, SIGTERM);
16317c478bd9Sstevel@tonic-gate } else
16327c478bd9Sstevel@tonic-gate (void) setuid(Euid);
16337c478bd9Sstevel@tonic-gate if(Cn > 0) {
16347c478bd9Sstevel@tonic-gate fchmod(Cn, Dev_mode);
16357c478bd9Sstevel@tonic-gate fd_rmlock(Cn);
16367c478bd9Sstevel@tonic-gate (void)close(Cn);
16377c478bd9Sstevel@tonic-gate }
16387c478bd9Sstevel@tonic-gate
16397c478bd9Sstevel@tonic-gate
16407c478bd9Sstevel@tonic-gate rmlock((char*) NULL); /* remove all lock files for this process */
16417c478bd9Sstevel@tonic-gate if (!Docmd)
16427c478bd9Sstevel@tonic-gate _mode(0);
16437c478bd9Sstevel@tonic-gate exit(code); /* code=negative for signal causing disconnect*/
16447c478bd9Sstevel@tonic-gate }
16457c478bd9Sstevel@tonic-gate
16467c478bd9Sstevel@tonic-gate
16477c478bd9Sstevel@tonic-gate
16487c478bd9Sstevel@tonic-gate void
tdmp(arg)16497c478bd9Sstevel@tonic-gate tdmp(arg)
16507c478bd9Sstevel@tonic-gate int arg;
16517c478bd9Sstevel@tonic-gate {
16527c478bd9Sstevel@tonic-gate
16537c478bd9Sstevel@tonic-gate struct termio xv;
16547c478bd9Sstevel@tonic-gate int i;
16557c478bd9Sstevel@tonic-gate
16567c478bd9Sstevel@tonic-gate VERBOSE("\rdevice status for fd=%d\r\n", arg);
16577c478bd9Sstevel@tonic-gate VERBOSE("F_GETFL=%o,", fcntl(arg, F_GETFL,1));
16587c478bd9Sstevel@tonic-gate if(ioctl(arg, TCGETA, &xv) < 0) {
16597c478bd9Sstevel@tonic-gate char buf[100];
16607c478bd9Sstevel@tonic-gate i = errno;
16617c478bd9Sstevel@tonic-gate (void)snprintf(buf, sizeof (buf), gettext("\rtdmp for fd=%d"), arg);
16627c478bd9Sstevel@tonic-gate errno = i;
16637c478bd9Sstevel@tonic-gate perror(buf);
16647c478bd9Sstevel@tonic-gate return;
16657c478bd9Sstevel@tonic-gate }
16667c478bd9Sstevel@tonic-gate VERBOSE("iflag=`%o',", xv.c_iflag);
16677c478bd9Sstevel@tonic-gate VERBOSE("oflag=`%o',", xv.c_oflag);
16687c478bd9Sstevel@tonic-gate VERBOSE("cflag=`%o',", xv.c_cflag);
16697c478bd9Sstevel@tonic-gate VERBOSE("lflag=`%o',", xv.c_lflag);
16707c478bd9Sstevel@tonic-gate VERBOSE("line=`%o'\r\n", xv.c_line);
16717c478bd9Sstevel@tonic-gate VERBOSE("cc[0]=`%o',", xv.c_cc[0]);
16727c478bd9Sstevel@tonic-gate for(i=1; i<8; ++i) {
16737c478bd9Sstevel@tonic-gate VERBOSE("[%d]=", i);
16747c478bd9Sstevel@tonic-gate VERBOSE("`%o',",xv.c_cc[i]);
16757c478bd9Sstevel@tonic-gate }
16767c478bd9Sstevel@tonic-gate VERBOSE("\r\n%s", "");
16777c478bd9Sstevel@tonic-gate return;
16787c478bd9Sstevel@tonic-gate }
16797c478bd9Sstevel@tonic-gate
16807c478bd9Sstevel@tonic-gate
16817c478bd9Sstevel@tonic-gate
16827c478bd9Sstevel@tonic-gate static void
sysname(name)16837c478bd9Sstevel@tonic-gate sysname(name)
16847c478bd9Sstevel@tonic-gate char * name;
16857c478bd9Sstevel@tonic-gate {
16867c478bd9Sstevel@tonic-gate
1687*462be471Sceastha char *s;
16887c478bd9Sstevel@tonic-gate
16897c478bd9Sstevel@tonic-gate if(uname(&utsn) < 0)
16907c478bd9Sstevel@tonic-gate s = "Local";
16917c478bd9Sstevel@tonic-gate else
16927c478bd9Sstevel@tonic-gate s = utsn.nodename;
16937c478bd9Sstevel@tonic-gate
16947c478bd9Sstevel@tonic-gate strcpy(name, s);
16957c478bd9Sstevel@tonic-gate return;
16967c478bd9Sstevel@tonic-gate }
16977c478bd9Sstevel@tonic-gate
16987c478bd9Sstevel@tonic-gate
16997c478bd9Sstevel@tonic-gate static void
blckcnt(count)17007c478bd9Sstevel@tonic-gate blckcnt(count)
17017c478bd9Sstevel@tonic-gate long count;
17027c478bd9Sstevel@tonic-gate {
17037c478bd9Sstevel@tonic-gate static long lcharcnt = 0;
1704*462be471Sceastha long c1, c2;
1705*462be471Sceastha int i;
17067c478bd9Sstevel@tonic-gate char c;
17077c478bd9Sstevel@tonic-gate
17087c478bd9Sstevel@tonic-gate if(count == (long) (-1)) { /* initialization call */
17097c478bd9Sstevel@tonic-gate lcharcnt = 0;
17107c478bd9Sstevel@tonic-gate return;
17117c478bd9Sstevel@tonic-gate }
17127c478bd9Sstevel@tonic-gate c1 = lcharcnt/BUFSIZ;
17137c478bd9Sstevel@tonic-gate if(count != (long)(-2)) { /* regular call */
17147c478bd9Sstevel@tonic-gate c2 = count/BUFSIZ;
17157c478bd9Sstevel@tonic-gate for(i = c1; i++ < c2;) {
17167c478bd9Sstevel@tonic-gate c = '0' + i%10;
17177c478bd9Sstevel@tonic-gate write(2, &c, 1);
17187c478bd9Sstevel@tonic-gate if(i%NPL == 0)
17197c478bd9Sstevel@tonic-gate write(2, "\n\r", 2);
17207c478bd9Sstevel@tonic-gate }
17217c478bd9Sstevel@tonic-gate lcharcnt = count;
17227c478bd9Sstevel@tonic-gate } else {
17237c478bd9Sstevel@tonic-gate c2 = (lcharcnt + BUFSIZ -1)/BUFSIZ;
17247c478bd9Sstevel@tonic-gate if(c1 != c2)
17257c478bd9Sstevel@tonic-gate write(2, "+\n\r", 3);
17267c478bd9Sstevel@tonic-gate else if(c2%NPL != 0)
17277c478bd9Sstevel@tonic-gate write(2, "\n\r", 2);
17287c478bd9Sstevel@tonic-gate lcharcnt = 0;
17297c478bd9Sstevel@tonic-gate }
17307c478bd9Sstevel@tonic-gate return;
17317c478bd9Sstevel@tonic-gate }
17327c478bd9Sstevel@tonic-gate
17337c478bd9Sstevel@tonic-gate /*VARARGS*/
17347c478bd9Sstevel@tonic-gate /*ARGSUSED*/
17357c478bd9Sstevel@tonic-gate void
assert(s1,s2,i1,s3,i2)17367c478bd9Sstevel@tonic-gate assert (s1, s2, i1, s3, i2)
17377c478bd9Sstevel@tonic-gate char *s1, *s2, *s3;
17387c478bd9Sstevel@tonic-gate int i1, i2;
17397c478bd9Sstevel@tonic-gate { } /* for ASSERT in gnamef.c */
17407c478bd9Sstevel@tonic-gate
17417c478bd9Sstevel@tonic-gate /*ARGSUSED*/
17427c478bd9Sstevel@tonic-gate void
logent(s1,s2)17437c478bd9Sstevel@tonic-gate logent (s1, s2)
17447c478bd9Sstevel@tonic-gate char *s1, *s2;
17457c478bd9Sstevel@tonic-gate { } /* so we can load ulockf() */
1746