Commit 51f40ab4 authored by Mike Hibler's avatar Mike Hibler
Browse files

The Evisceration of Tip, Chapter 1.

Taken from the man page (ntip.1):
----
     Ntip differs from the traditional tip in a number of ways:

     1.   It does not support calling a remote system, all auto-dialing code
          has been removed.

     2.   All the cheezy file transfer support has been removed.

     3.   Most of the tilde escapes have been removed.  Mostly these were the
          file trasfer related ones.  See below for what remains.

     4.   Ntip ignores 90% of the remote(5) capabilities.  You can set the
          baud rate (br) and the device (dv).  Period.

     5.   All of tips variables are still present, but most don't do anything.
          It is left as an exercise to the interested user to differentiate.

     6.   By default, it operates in ``raw'' mode instead of the usual
          ``cbreak'' mode.  This means that all input processing (if any) is
          performed by the remote system.  Raw mode also disables
          ``raisechar'' and ``force'' variable interpretation.  Yes, you can
          actually run emacs on an ntip line (modulo the '~' thing).

     7.   Tip is the poster-child for fork-without-exec, creating separate
          reader and writer processes executing ``the same code.''  Ntip is a
          child of convenience and consists of a single process using
          select(2).

     8.   Ntip no longer uses uucp(1) style locking.  It relies on the TIOCEX-
          CL ioctl (see tty(4))  to provide ``reasonably mutually exclusive''
          access.  While it is still technically possible that two parties
          could open the same line and both get ``exclusive'' access to it, we
          consider this to be the source of amusing anecdotes rather than a
          bug.
----
parent a2df644d
CC = gcc -g
CC = gcc -g -O2
# for BSD
#CFLAGS = -O
#LIBS= -lutil
OBJS = cmds.o cmdtab.o hunt.o partab.o \
remote.o tip.o value.o vars.o getcap.o
# for Linux
CFLAGS = -O -DLINUX
LIBS= -ldb
#
# If HAVE_UUCPLOCK is defined you need -lutil for BSD
#
LIBS=
OBJS = acu.o acutab.o cmds.o cmdtab.o cu.o hunt.o log.o partab.o \
remote.o tip.o tipout.o value.o vars.o getcap.o
DESTDIR = /usr/site
DESTDIR = /usr/testbed
all: tip
all: tip.static # tip
tip: $(OBJS)
$(CC) -o tip $(OBJS) $(LIBS)
......@@ -20,8 +18,11 @@ tip: $(OBJS)
tip.static: $(OBJS)
$(CC) -static -o tip.static $(OBJS) $(LIBS)
install:
install -s -c tip $(DESTDIR)/bin/tip
$(OBJS): tipconf.h tip.h
install: all
# install -s -c tip $(DESTDIR)/bin/tip
install -s -c tip.static $(DESTDIR)/bin/ntip
clean:
rm -f $(OBJS) tip tip.static
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)acu.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$Id: acu.c,v 1.1 2000-12-22 18:48:46 mike Exp $";
#endif /* not lint */
#include "tipconf.h"
#include "tip.h"
#if UNIDIALER
acu_t* unidialer_getmodem (const char *modem_name);
#endif
static acu_t *acu = NOACU;
static int conflag;
static void acuabort();
static acu_t *acutype();
static jmp_buf jmpbuf;
/*
* Establish connection for tip
*
* If DU is true, we should dial an ACU whose type is AT.
* The phone numbers are in PN, and the call unit is in CU.
*
* If the PN is an '@', then we consult the PHONES file for
* the phone numbers. This file is /etc/phones, unless overriden
* by an exported shell variable.
*
* The data base files must be in the format:
* host-name[ \t]*phone-number
* with the possibility of multiple phone numbers
* for a single host acting as a rotary (in the order
* found in the file).
*/
char *
connect()
{
register char *cp = PN;
char *phnum, string[256];
FILE *fd;
int tried = 0;
if (!DU) { /* regular connect message */
if (CM != NOSTR)
xpwrite(FD, CM, size(CM));
logent(value(HOST), "", DV, "call completed");
return (NOSTR);
}
/*
* @ =>'s use data base in PHONES environment variable
* otherwise, use /etc/phones
*/
signal(SIGINT, acuabort);
signal(SIGQUIT, acuabort);
if (setjmp(jmpbuf)) {
signal(SIGINT, SIG_IGN);
signal(SIGQUIT, SIG_IGN);
printf("\ncall aborted\n");
logent(value(HOST), "", "", "call aborted");
if (acu != NOACU) {
boolean(value(VERBOSE)) = FALSE;
if (conflag)
disconnect(NOSTR);
else
(*acu->acu_abort)();
}
return ("interrupt");
}
if ((acu = acutype(AT)) == NOACU)
return ("unknown ACU type");
if (*cp != '@') {
while (*cp) {
for (phnum = cp; *cp && *cp != ','; cp++)
;
if (*cp)
*cp++ = '\0';
if ((conflag = (*acu->acu_dialer)(phnum, CU))) {
if (CM != NOSTR)
xpwrite(FD, CM, size(CM));
logent(value(HOST), phnum, acu->acu_name,
"call completed");
return (NOSTR);
} else
logent(value(HOST), phnum, acu->acu_name,
"call failed");
tried++;
}
} else {
if ((fd = fopen(PH, "r")) == NOFILE) {
printf("%s: ", PH);
return ("can't open phone number file");
}
while (fgets(string, sizeof(string), fd) != NOSTR) {
for (cp = string; !any(*cp, " \t\n"); cp++)
;
if (*cp == '\n') {
fclose(fd);
return ("unrecognizable host name");
}
*cp++ = '\0';
if (strcmp(string, value(HOST)))
continue;
while (any(*cp, " \t"))
cp++;
if (*cp == '\n') {
fclose(fd);
return ("missing phone number");
}
for (phnum = cp; *cp && *cp != ',' && *cp != '\n'; cp++)
;
if (*cp)
*cp++ = '\0';
if ((conflag = (*acu->acu_dialer)(phnum, CU))) {
fclose(fd);
if (CM != NOSTR)
xpwrite(FD, CM, size(CM));
logent(value(HOST), phnum, acu->acu_name,
"call completed");
return (NOSTR);
} else
logent(value(HOST), phnum, acu->acu_name,
"call failed");
tried++;
}
fclose(fd);
}
if (!tried)
logent(value(HOST), "", acu->acu_name, "missing phone number");
else
(*acu->acu_abort)();
return (tried ? "call failed" : "missing phone number");
}
void
disconnect(reason)
char *reason;
{
if (!conflag) {
logent(value(HOST), "", DV, "call terminated");
return;
}
if (reason == NOSTR) {
logent(value(HOST), "", acu->acu_name, "call terminated");
if (boolean(value(VERBOSE)))
printf("\r\ndisconnecting...");
} else
logent(value(HOST), "", acu->acu_name, reason);
(*acu->acu_disconnect)();
}
static void
acuabort(s)
{
signal(s, SIG_IGN);
longjmp(jmpbuf, 1);
}
static acu_t *
acutype(s)
register char *s;
{
register acu_t *p;
extern acu_t acutable[];
for (p = acutable; p->acu_name != '\0'; p++)
if (!strcmp(s, p->acu_name))
return (p);
#if UNIDIALER
return unidialer_getmodem (s);
#else
return (NOACU);
#endif
}
/*
* Copyright (c) 1983, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
#if 0
static char sccsid[] = "@(#)acutab.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$Id: acutab.c,v 1.1 2000-12-22 18:48:46 mike Exp $";
#endif /* not lint */
#include "tipconf.h"
#include "tip.h"
extern int df02_dialer(), df03_dialer(),
biz31f_dialer(),
biz31w_dialer(),
biz22f_dialer(),
biz22w_dialer(),
ven_dialer(),
hay_dialer(),
cour_dialer(),
multitech_dialer(),
t3000_dialer(),
v3451_dialer(),
v831_dialer(),
dn_dialer();
extern void df_disconnect(), df_abort(),
biz31_disconnect(), biz31_abort(),
biz22_disconnect(), biz22_abort(),
ven_disconnect(), ven_abort(),
hay_disconnect(), hay_abort(),
cour_disconnect(), cour_abort(),
multitech_disconnect(), multitech_abort(),
t3000_disconnect(), t3000_abort(),
v3451_disconnect(), v3451_abort(),
v831_disconnect(), v831_abort(),
dn_disconnect(), dn_abort();
acu_t acutable[] = {
#if BIZ1031
"biz31f", biz31f_dialer, biz31_disconnect, biz31_abort,
"biz31w", biz31w_dialer, biz31_disconnect, biz31_abort,
#endif
#if BIZ1022
"biz22f", biz22f_dialer, biz22_disconnect, biz22_abort,
"biz22w", biz22w_dialer, biz22_disconnect, biz22_abort,
#endif
#if DF02
"df02", df02_dialer, df_disconnect, df_abort,
#endif
#if DF03
"df03", df03_dialer, df_disconnect, df_abort,
#endif
#if DN11
"dn11", dn_dialer, dn_disconnect, dn_abort,
#endif
#if VENTEL
"ventel",ven_dialer, ven_disconnect, ven_abort,
#endif
#if HAYES
"hayes",hay_dialer, hay_disconnect, hay_abort,
#endif
#if COURIER
"courier",cour_dialer, cour_disconnect, cour_abort,
#endif
#if MULTITECH
"multitech",multitech_dialer, multitech_disconnect, multitech_abort,
#endif
#if T3000
"t3000",t3000_dialer, t3000_disconnect, t3000_abort,
#endif
#if V3451
#if !V831
"vadic",v3451_dialer, v3451_disconnect, v3451_abort,
#endif
"v3451",v3451_dialer, v3451_disconnect, v3451_abort,
#endif
#if V831
#if !V3451
"vadic",v831_dialer, v831_disconnect, v831_abort,
#endif
"v831",v831_dialer, v831_disconnect, v831_abort,
#endif
0, 0, 0, 0
};
......@@ -36,10 +36,9 @@
static char sccsid[] = "@(#)cmds.c 8.1 (Berkeley) 6/6/93";
#endif
static const char rcsid[] =
"$Id: cmds.c,v 1.1 2000-12-22 18:48:46 mike Exp $";
"$Id: cmds.c,v 1.2 2000-12-27 00:49:33 mike Exp $";
#endif /* not lint */
#include "tipconf.h"
#include "tip.h"
#include "pathnames.h"
......@@ -50,7 +49,6 @@ static const char rcsid[] =
#include <libutil.h>
#endif
#include <stdio.h>
#include <unistd.h>
/*
* tip
......@@ -58,15 +56,9 @@ static const char rcsid[] =
* miscellaneous commands
*/
int quant[] = { 60, 60, 24 };
char null = '\0';
char *sep[] = { "second", "minute", "hour" };
static char *argv[10]; /* argument vector for take and put */
void timeout(); /* timeout function called on alarm */
static void stopsnd(); /* SIGINT handler during file transfers */
static void intcopy(); /* interrupt routine for file transfers */
void suspend __P((char));
void genbrk __P((void));
......@@ -75,46 +67,11 @@ void finish __P((void));
void tipabort __P((char *));
void chdirectory __P((void));
void shell __P((void));
void cu_put __P((char));
void sendfile __P((char));
void pipefile __P((void));
void cu_take __P((char));
void getfl __P((char));
static int anyof __P((char *, char *));
static void tandem __P((char *));
static void prtime __P((char *, time_t));
static int args __P((char *, char **, int));
static void execute __P((char *));
static void send __P((char));
static void transmit __P((FILE *, char *, char *));
static void transfer __P((char *, int, char *));
static void xfer __P((char *, int, char *));
void
usedefchars ()
{
#if HAVE_TERMIOS
int cnt;
struct termios ttermios;
ttermios = ctermios;
for (cnt = 0; cnt < NCCS; cnt++)
ttermios.c_cc [cnt] = otermios.c_cc [cnt];
tcsetattr (0, TCSANOW, &ttermios);
#else
ioctl(0, TIOCSETC, &defchars);
#endif
}
void
usetchars ()
{
#if HAVE_TERMIOS
tcsetattr (0, TCSANOW, &ctermios);
#else
ioctl(0, TIOCSETC, &tchars);
#endif
}
void
flush_remote ()
......@@ -133,483 +90,6 @@ flush_remote ()
#endif
}
/*
* FTP - remote ==> local
* get a file from the remote host
*/
void
getfl(c)
char c;
{
char buf[256], *cp, *expand();
putchar(c);
/*
* get the UNIX receiving file's name
*/
if (prompt("Local file name? ", copyname, sizeof(copyname)))
return;
cp = expand(copyname);
if ((sfd = creat(cp, 0666)) < 0) {
printf("\r\n%s: cannot creat\r\n", copyname);
return;
}
/*
* collect parameters
*/
if (prompt("List command for remote system? ", buf, sizeof(buf))) {
unlink(copyname);
return;
}
transfer(buf, sfd, value(EOFREAD));
}
/*
* Cu-like take command
*/
void
cu_take(cc)
char cc;
{
int fd, argc;
char line[BUFSIZ], *expand(), *cp;
if (prompt("[take] ", copyname, sizeof(copyname)))
return;
if ((argc = args(copyname, argv, sizeof(argv)/sizeof(argv[0]))) < 1 || argc > 2) {
printf("usage: <take> from [to]\r\n");
return;
}
if (argc == 1)
argv[1] = argv[0];
cp = expand(argv[1]);
if ((fd = creat(cp, 0666)) < 0) {
printf("\r\n%s: cannot create\r\n", argv[1]);
return;
}
(void)snprintf(line, sizeof(line), "cat %s ; echo \"\" ; echo ___tip_end_of_file_marker___", argv[0]);
xfer(line, fd, "\n___tip_end_of_file_marker___\n");
}
static jmp_buf intbuf;
static void
xfer(buf, fd, eofchars)
char *buf, *eofchars;
{
int ct;
char c, *match;
int cnt, eof, v;
time_t start;
sig_t f;
char r;
FILE *ff;
v = boolean(value(VERBOSE));
if ((ff = fdopen (fd, "w")) == NULL) {
warn("file open");
return;
}
if ((cnt = number(value(FRAMESIZE))) != BUFSIZ)
if (setvbuf(ff, NULL, _IOFBF, cnt) != 0) {
warn("file allocation");
(void)fclose(ff);
return;
}
xpwrite(FD, buf, size(buf));
quit = 0;
kill(pid, SIGIOT);
read(repdes[0], (char *)&ccc, 1); /* Wait until read process stops */
/*
* finish command
*/
r = '\r';
xpwrite(FD, &r, 1);
do
read(FD, &c, 1);
while ((c&0177) != '\n');
usedefchars ();
(void) setjmp(intbuf);
f = signal(SIGINT, intcopy);
start = time(0);
match = eofchars;
for (ct = 0; !quit;) {
eof = read(FD, &c, 1) <= 0;
c &= 0177;
if (quit)
continue;
if (eof)
break;
if (c == 0)
continue; /* ignore nulls */
if (c == '\r')
continue;
if (c != *match && match > eofchars) {
register char *p = eofchars;
while (p < match) {
if (*p == '\n'&& v)
(void)printf("\r%d", ++ct);
fputc(*p++, ff);
}
match = eofchars;
}
if (c == *match) {
if (*++match == '\0')
break;
} else {
if (c == '\n' && v)
(void)printf("\r%d", ++ct);
fputc(c, ff);
}
}
if (v)
prtime(" lines transferred in ", time(0)-start);
usetchars ();
write(fildes[1], (char *)&ccc, 1);
signal(SIGINT, f);
(void)fclose(ff);
}
/*
* Bulk transfer routine --
* used by getfl(), cu_take(), and pipefile()
*/
static void
transfer(buf, fd, eofchars)
char *buf, *eofchars;
{
register int ct;
char c;
register int cnt, eof, v;
time_t start;
sig_t f;
char r;
FILE *ff;
v = boolean(value(VERBOSE));
if ((ff = fdopen (fd, "w")) == NULL) {
warn("file open");
return;
}
if ((cnt = number(value(FRAMESIZE))) != BUFSIZ)
if (setvbuf(ff, NULL, _IOFBF, cnt) != 0) {
warn("file allocation");
(void)fclose(ff);
return;
}