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