home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume15
/
cu-shell
< prev
next >
Wrap
Text File
|
1988-07-06
|
16KB
|
627 lines
Subject: v15i083: A "shell" for CU, Kermit, etc.
Newsgroups: comp.sources.unix
Sender: sources
Approved: rsalz@uunet.UU.NET
Submitted-by: bsmith@csuchico.EDU (Bennett Smith)
Posting-number: Volume 15, Issue 83
Archive-name: cu-shell
This program attempts to solve some of the problems with having kermit
cu, and uucp sharing the same lines. It also keeps a log of all connections
that are made. Access to costly resources such as phone lines may be
restricted by way of a Call-sys file. It will not allow the use of cu or
kermit directly, thus a user cannot specify a phone number.
Hope this helps. Chico State University has been using it for about one
month, and it seems to solve most of their problems. Have Fun.
Bennett (bsmith@csuchico.EDU)
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# Makefile
# call.c
# call.1L
# Call-sys
export PATH; PATH=/bin:$PATH
if test -f 'Makefile'
then
echo shar: will not over-write existing file "'Makefile'"
else
cat << \SHAR_EOF > 'Makefile'
# Copyright (c) 1988 Cascade Research
# All Rights Reserved
#
# THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CASCADE RESEARCH
# The copyright notice above does not evidence any actual or
# intended publication of such source code
#
# @(#)Makefile 1.2 */
#
# WHO MODIFICATION DATE DONE
# --- ------------------------------------- ---------
# cbs Creation of Makefile for call.c 12-Apr-88
# Comment out if you don't have HonneyDANBER lockfiles.
HDB = 1
# Full path to file containing list of valid systems for call.
CALLFILE = /usr/lib/uucp/Call-sys
# Full path to call log file.
LOGFILE = /usr/lib/uucp/Call-log
# Sprintf string for pathname of lockfile.
LOCKFILE = /usr/spool/locks/LCK..%s
# Full path to kermit executable.
KERMIT = /usr/local/bin/kermit
# Full path to cu executable.
CU = /usr/bin/cu
# User and group id for uucp (used to chown the device back after call).
UIDUUCP = 5
GIDUUCP = 5
# Mode of device for kermit and uucp/cu (used to chmod the device during call).
MODKER = 00600
MODUUCP = 00622
DEFS = -DHDB=\"$(HDB)\" -DCALLFILE=\"$(CALLFILE)\" \
-DLOGFILE=\"$(LOGFILE)\" -DLOCKFILE=\"$(LOCKFILE)\" \
-DKERMIT=\"$(KERMIT)\" -DCU=\"$(CU)\" \
-DUIDUUCP=\"$(UIDUUCP)\" -DGIDUUCP=\"$(GIDUUCP)\" \
-DMODKER=\"$(MODKER)\" -DMODUUCP=\"$(MODUUCP)\"
# Directory for call executable
BINDIR = /usr/local/bin
# Directory for call manual page ([nt]roff form)
MANDIR = /usr/man/l_man/man1
############################################################################
SRC = call.c
OBJ = call.o
MAN = call.1L
CFLAGS = -O ${DEFS}
LFLAGS =
LINTFLAGS = ${DEFS}
ROFF = psroff -man
LP = remsh bugs rlp pluto
call: $(OBJ)
cc $(LFLAGS) $(OBJ) -o call
man:
$(ROFF) $(MAN)
print:
pr Makefile call.c | $(LP)
$(ROFF) $(MAN) | $(LP)
clean:
-rm -f $(OBJ) call
install:
-cp call $(BINDIR)
-cp Call-sys $(CALLFILE)
-cp call.1 $(MANDIR)
-chmod 4555 $(BINDIR)/call
-chown root $(BINDIR)/call
-chgrp bin $(BINDIR)/call
-chmod 600 $(CALLFILE)
-chown root $(CALLFILE)
-chgrp bin $(CALLFILE)
-chmod 444 $(MANDIR)/call.1
SHAR_EOF
fi # end of overwriting check
if test -f 'call.c'
then
echo shar: will not over-write existing file "'call.c'"
else
cat << \SHAR_EOF > 'call.c'
/* Copyright (c) 1988 Cascade Research */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF CASCADE RESEARCH */
/* The copyright notice above does not evidence any actual or */
/* intended publication of such source code */
/* @(#)call.c 1.2 */
/* WHO MODIFICATION DATE DONE */
/* --- ------------------------------------- --------- */
/* cbs Initial creation of call.c program. 05-Apr-88 */
/* cbs Added code for the -d option. 07-Apr-88 */
/* cbs Added -l with no machine name to show 07-Apr-88 */
/* entire contents of log file. */
/* cbs Added code to set the HUPCL value for 12-Apr-88 */
/* the device to be connected to. */
/* Call allows the invocation of cu or kermit in a more */
/* restrictive environment. It allows for the monitoring */
/* of callers, and the duration of their connections to */
/* various machines. Call gets a list of available */
/* machines from the Call-devices file which is located */
/* in the /usr/lib/uucp directory. The log file of all */
/* actions is in /usr/adm/Call-log. */
/* Call must run setuid(root). It respects the HDB type */
/* lock files as well as the v7 ones. It will set the */
/* permissions and ownerships of the appropriate device */
/* for the duration of the call. */
#include <fcntl.h>
#include <termio.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
/* The following are the defaults. If you wish to make changes, do so */
/* in the Makefile, not here. */
#ifndef CALLFILE
#define CALLFILE "/usr/lib/uucp/Call-sys"
#endif
#ifndef LOGFILE
#define LOGFILE "/usr/lib/uucp/Call-log"
#endif
#ifndef LOCKFILE
#define LOCKFILE "/usr/spool/locks/LCK..%s"
#endif
#ifndef KERMIT
#define KERMIT "/usr/local/bin/kermit"
#endif
#ifndef CU
#define CU "/usr/bin/cu"
#endif
#ifndef UIDUUCP
#define UIDUUCP 5
#endif
#ifndef GIDUUCP
#define GIDUUCP 5
#endif
#ifndef MODKER
#define MODKER 00600
#endif
#ifndef MODUUCP
#define MODUUCP 00622
#endif
struct calldev {
char *name; /* name of system */
char *dev; /* device attached to */
char *baud; /* baud rate to connect at */
char *mdmtype; /* modem type */
char *telno; /* telephone number */
struct calldev *next; /* pointer to next available device */
};
struct calldev *callhead, *callcur, *match, *getcall();
char *pname, *getlogin(), typecall[50], whocall[50];
struct termio *devparam;
int fd;
int errflg,kflg,cflg,lflg,sflg,dflg;
main(argc,argv)
int argc;
char *argv[];
{
extern char *optarg;
extern int optind,opterr;
int c;
char *callsys, cmd[100];
FILE *cf, *fopen();
devparam = (struct termio *)malloc(sizeof(struct termio));
pname=(char *)malloc(sizeof(argv[0])+1);
strcpy(pname,argv[0]);
strcpy(typecall,"?????");
strcpy(whocall,"?????");
dflg=sflg=errflg=kflg=lflg=0;
cflg=1;
while ((c=getopt(argc,argv,"dckls"))!=EOF)
switch (c) {
case 'd': dflg++;
break;
case 'c': cflg++;
if (kflg) kflg=0;
break;
case 'k': kflg++;
if (cflg) cflg=0;
break;
case 'l': lflg++;
break;
case 's': sflg++;
break;
case '?': errflg++;
}
if (errflg || argc < 2) {
fprintf(stderr,"usage: %s [-d] [-c|-k|-l] system | [-s]\n",pname);
exit (2);
}
callsys = argv[optind];
if ((cf=fopen(CALLFILE,"r"))==(FILE *)NULL) {
fprintf(stderr,"%s: cannot open %s\n",pname,CALLFILE);
exit (2);
}
callhead = getcall(cf); /* load the call structure from the CALLFILE */
if (sflg) {
strcpy(typecall,"SYSTEM LIST");
for (callcur=callhead; callcur!=(struct calldev *)NULL; callcur=callcur->next)
printf("%s\n",callcur->name);
exit(0);
}
if (lflg && (optind==argc)) {
sprintf(cmd,"/bin/cat %s 2>/dev/null",LOGFILE);
system(cmd);
exit(0);
}
match=(struct calldev *)NULL;
for (callcur=callhead; callcur!=(struct calldev *)NULL; callcur=callcur->next)
if (strcmp(callsys,callcur->name)==0) match=callcur;
if (match==(struct calldev *)NULL) {
if (!lflg)
fprintf(stderr,"%s: %s is not a valid system\n",pname,callsys);
else
fprintf(stderr,"%s: must specify system for log viewing\n",pname);
exit (2);
}
strcpy(whocall,match->name);
if (!lflg) {
exit (kflg?dokermit(match):docu(match));
} else if (lflg)
exit (showlog(match));
exit(0);
}
/* showlog() - display the log for the specified match to CALLFILE */
int showlog(where)
struct calldev *where;
{
char cmd[100];
sprintf(cmd,"/bin/grep %s %s 2>/dev/null",where->name,LOGFILE);
system(cmd);
return (0);
}
/* dokermit() - invoke KERMIT for the specified match to CALLFILE */
int dokermit(where)
struct calldev *where;
{
char line[35],rmlck[70];
strcpy(typecall,"KERMIT");
fprintf(stderr,"Calling with kermit\n");
if(checklock(where->dev)==0) {
sprintf(rmlck,"rm -f ");
sprintf(line,LOCKFILE,where->dev);
strcat(rmlck,line);
strcat(rmlck," 2>&1 1>/dev/null");
if (dflg)
fprintf(stderr,"%s: removing invalid lock file [%s]\n",pname,line);
system(rmlck);
sprintf(line,"/dev/%s",where->dev);
if (chown(line,getuid(),getgid())<0) {
fprintf(stderr,"%s: cannot chown %s for kermit\n",pname,line);
writelog("CHOWN FAILED");
exit(2);
}
if (chmod(line,MODKER)<0) {
fprintf(stderr,"%s: cannot chmod %s for kermit\n",pname,line);
writelog("CHMOD FAILED");
exit(2);
}
ioctl((fd=open(line,O_RDONLY)),devparam,TCGETA);
devparam->c_cflag=devparam->c_cflag||HUPCL;
ioctl(fd,devparam,TCSETA);
close(fd);
writelog("CONNECT");
if (fork() == 0) {
setuid(getuid());
if (dflg)
execlp(KERMIT,"kermit","-d","-l",line,"-b",where->baud,(char *)0);
else
execlp(KERMIT,"kermit","-l",line,"-b",where->baud,(char *)0);
fprintf(stderr,"%s: cannot execute kermit\n",pname);
exit(2);
}
wait((int *)0);
writelog("DISCONNECT");
if (chown(line,UIDUUCP,GIDUUCP)<0) {
fprintf(stderr,"%s: cannot reset %s\n",pname,line);
writelog("CHOWN FAILED");
exit(2);
}
if (chmod(line,MODUUCP)<0) {
fprintf(stderr,"%s: cannot reset %s\n",pname,line);
writelog("CHMOD FAILED");
exit(2);
}
return (0);
} else {
fprintf(stderr,"%s: line busy - try later\n",pname);
return (1);
}
}
/* docu() - invoke CU for the specified match to CALLFILE */
int docu(where)
struct calldev *where;
{
char line[35];
strcpy(typecall,"CU");
fprintf(stderr,"Calling with cu\n");
if(checklock(where->dev)==0) {
sprintf(line,LOCKFILE,where->dev);
ioctl((fd=open(line,O_RDONLY)),devparam,TCGETA);
devparam->c_cflag=devparam->c_cflag||HUPCL;
ioctl(fd,devparam,TCSETA);
close(fd);
writelog("CONNECT");
if (fork() == 0) {
if (dflg)
execlp(CU,"cu","-d",where->name,(char *)0); /* run cu */
else
execlp(CU,"cu",where->name,(char *)0); /* run cu */
fprintf(stderr,"%s: cannot execute cu\n",pname);
exit(2);
}
wait((int *)0); /* wait for cu to disconnect */
writelog("DISCONNECT");
return (0);
} else {
fprintf(stderr,"%s: line busy - try later\n",pname);
return (1);
}
}
/* writelog() - write a line into the call logfile */
int writelog(desc)
char *desc;
{
FILE *fopen(), *log;
long clock;
if ((log=fopen(LOGFILE,"a"))==(FILE *)NULL) {
fprintf(stderr,"%s: could not open log file\n",pname);
exit(2);
}
clock=time((long *)0);
if (dflg)
fprintf(stderr,"%-10s %-10s %-10s %-20s %s",whocall,getlogin(),typecall,desc,asctime(localtime(&clock)));
fprintf(log,"%-10s %-10s %-10s %-20s %s",whocall,getlogin(),typecall,desc,asctime(localtime(&clock)));
fclose(log);
return (0);
}
/* checklock() - check that the device which we want is available */
/* return: 0=ok 1=device in use */
int checklock(dev)
char *dev;
{
char lckfile[100];
int lkpid;
FILE *lf;
sprintf(lckfile,LOCKFILE,dev);
if (access(lckfile,0)==0) { /* check if lockfile exists */
#ifdef HDB
if ((lf=fopen(lckfile,"r"))!=(FILE *)NULL) {
fscanf(lf,"%d",&lkpid);
if (kill(lkpid,0)==(-1)) /* check if line avail */
return(0); /* pid is invalid, line avail */
else return (1); /* valid pid, line busy */
}
#endif
return(1);
}
return(0);
}
/* getcall() - read and parse the CALLFILE and setup the linked list */
/* of allowed connections */
struct calldev *getcall(cf)
FILE *cf;
{
struct calldev *head, *cur;
int c;
char tname[25], tdev[25], tbaud[25], tmdmtype[25], ttelno[25];
cur=head=(struct calldev *)NULL;
while ((c=fgetc(cf))!=EOF)
if (c=='#' || c==' ' || c=='\t' || c=='\n')
while ((c=fgetc(cf))!='\n');
else {
ungetc(c,cf);
fscanf(cf,"%s %s %s %s %s\n",tname,tdev,tbaud,tmdmtype,ttelno);
if (cur==(struct calldev *)NULL) {
head=(struct calldev *)malloc(sizeof(struct calldev));
cur=head;
} else {
cur->next=(struct calldev *)malloc(sizeof(struct calldev));
cur=cur->next;
}
cur->name=(char *)malloc(strlen(tname)+1);
strcpy(cur->name,tname);
cur->dev=(char *)malloc(strlen(tdev)+1);
strcpy(cur->dev,tdev);
cur->baud=(char *)malloc(strlen(tbaud)+1);
strcpy(cur->baud,tbaud);
cur->mdmtype=(char *)malloc(strlen(tmdmtype)+1);
strcpy(cur->mdmtype,tmdmtype);
cur->telno=(char *)malloc(strlen(ttelno)+1);
strcpy(cur->telno,ttelno);
}
fclose(cf);
return (head);
}
SHAR_EOF
fi # end of overwriting check
if test -f 'call.1L'
then
echo shar: will not over-write existing file "'call.1L'"
else
cat << \SHAR_EOF > 'call.1L'
.TH CALL 1L local
.SH NAME
call \- make a connection to an available machine via cu or kermit
.SH SYNOPSIS
.B call "[ -d ]" "[ -ck ]" "system"
.P
.B call "[ -d ]" -l "[ system ]"
.P
.B call "[ -d ]" "-s"
.SH DESCRIPTION
.I Call
provides a means to connect to another UNIX system, a terminal, or possibly
a non-UNIX system. It restricts access to the actual calling programs,
.I cu
and
.IR kermit ,
in an effort to limit access to expensive resources (ie. phone lines).
.I Call
maintains a log of all activity on the available lines. It will only allow
access to
.I cu
with a valid system name, thus preventing direct dialing.
.P
.I Call
allows for the peaceful co-existence of
.I kermit
with
.I cu
and
.IR uucp ,
because it will not execute
.I kermit
unless the specified line is currently available. It respects HoneyDANBER
lockfiles with the pid of the active process, and the older lockfiles which
simply indicate that the line is used.
.TP
.B call
accepts the following options and arguments.
.TP
-c
Invokes
.B call
with
.I cu
as the calling program. This is the default calling program, if neither
.B "-c"
or
.B "-k"
is present.
.TP
-k
Invokes
.B call
with
.I kermit
as the calling program. It will supply
.I kermit
with the device name and baud rate. Calling with
.I kermit
is not premitted over a dialed line. Only "direct" connections are
supported with this option.
.TP
system
A valid system name obtained from the
.B /usr/lib/uucp/Call-sys
file. To list the currently available system names, see the
.B -s
option below.
.TP
-d
Turn on the debugging mode for the calling program. This is useful
when connecting over an unreliable line since the progression of the
connection may be monitored.
.I Cu
will display the debugging information on the screen whereas
.I kermit
will send all debugging information to the file
.B debug.log
in the current directory.
.TP
-s
Display a list of available systems.
.TP
-l
List the log file for the specified system name. If no system is
specified, the entire log is displayed, sorted by machine and then
by time.
.SH FILES
.P
/usr/lib/uucp/Call-sys
.P
/usr/lib/uucp/Call-log
/usr/spool/uucp/LCK..(tty-device)
.SH SEE ALSO
.P
cu(1C), uucp(1C), kermit(1L)
.SH DIAGNOSTICS
.P
Exit code is zero for normal exit, non-zero (various values) otherwise.
.SH BUGS
As yet, none have been reported.
.SH AUTHORS
.P
Bennett Smith
.br
Jim Garlick
SHAR_EOF
fi # end of overwriting check
if test -f 'Call-sys'
then
echo shar: will not over-write existing file "'Call-sys'"
else
cat << \SHAR_EOF > 'Call-sys'
# Connections contains a list of all valid connections for the call
# program.
#
# Line syntax:
# system \t device \t baud \t modemtype \t telno
#
# If an argument does not apply, use a dash '-' as a place holder for it.
# There must be 5 arguments per line, and comments are NOT allowed to
# follow the arguments. Comments are OK on other lines, and start with
# a hatch '#' character.
#
# The system and device fields are always necessary, but the baud, modemtype,
# and telno fields are only used by kermit.
#
# examples -
# bugs tty106 9600 - -
# bunky tty021 9600 - -
#
SHAR_EOF
fi # end of overwriting check
# End of shell archive
exit 0
--
Cascade Research | uucp: ihnp4!csun!csuchico!bsmith
Bennett Smith, Software Engineer | voice: (916) 343-5731