home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-02-22 | 52.9 KB | 2,301 lines |
- Newsgroups: comp.sources.misc
- From: ag@monique.bubble.org (Keith Gabryelski)
- Subject: v28i070: advise - Attach to another user, v2.0, Part01/02
- Message-ID: <csm-v28i070=advise.221330@sparky.IMD.Sterling.COM>
- X-Md4-Signature: e0f7d8b39d119422b99037865b9bd813
- Date: Mon, 24 Feb 1992 04:14:17 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: ag@monique.bubble.org (Keith Gabryelski)
- Posting-number: Volume 28, Issue 70
- Archive-name: advise/part01
- Environment: SunOS, SYSVR4i386
-
- Advise attaches a user (the advisor) to another user's (the advisee)
- terminal in such a way the the advisor can type for the advisee and
- view what the advisee's terminal is displaying.
-
- The advisee would typically type ``advise -a'' to allow advise attaches;
- the advisor would then type ``advise user name'' which would connect the
- advisors terminal the the advisee's.
-
- All characters the advisor types are sent to the advisee's terminal
- as if the advisee typed them save the meta character.
-
- Keith Gabryelski
- ------------------
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: COPYING Makefile.SUNOS Makefile.SVR4i386 advise.c advise.h
- # advise.id advise.man advisedev.c advisemod.c advmod.id
- # Wrapped by kent@sparky on Sun Feb 23 21:54:18 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 1 (of 2)."'
- if test -f 'COPYING' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'COPYING'\"
- else
- echo shar: Extracting \"'COPYING'\" \(7166 characters\)
- sed "s/^X//" >'COPYING' <<'END_OF_FILE'
- X
- X Advise GENERAL PUBLIC LICENSE
- X (Clarified 11 Feb 1988)
- X
- X Copyright (C) 1988 Free Software Foundation, Inc.
- X Everyone is permitted to copy and distribute verbatim copies
- X of this license, but changing it is not allowed. You can also
- X use this wording to make the terms for other programs.
- X
- X The license agreements of most software companies keep you at the
- Xmercy of those companies. By contrast, our general public license is
- Xintended to give everyone the right to share Advise. To make sure that
- Xyou get the rights we want you to have, we need to make restrictions
- Xthat forbid anyone to deny you these rights or to ask you to surrender
- Xthe rights. Hence this license agreement.
- X
- X Specifically, we want to make sure that you have the right to give
- Xaway copies of Advise, that you receive source code or else can get it
- Xif you want it, that you can change Advise or use pieces of it in new
- Xfree programs, and that you know you can do these things.
- X
- X To make sure that everyone has such rights, we have to forbid you to
- Xdeprive anyone else of these rights. For example, if you distribute
- Xcopies of Advise, you must give the recipients all the rights that you
- Xhave. You must make sure that they, too, receive or can get the
- Xsource code. And you must tell them their rights.
- X
- X Also, for our own protection, we must make certain that everyone
- Xfinds out that there is no warranty for Advise. If Advise is modified by
- Xsomeone else and passed on, we want its recipients to know that what
- Xthey have is not what we distributed, so that any problems introduced
- Xby others will not reflect on our reputation.
- X
- X Therefore we (Richard Stallman and the Free Software Foundation,
- XInc.) make the following terms which say what you must do to be
- Xallowed to distribute or change Advise.
- X
- X
- X COPYING POLICIES
- X
- X 1. You may copy and distribute verbatim copies of Advise source code
- Xas you receive it, in any medium, provided that you conspicuously and
- Xappropriately publish on each copy a valid copyright notice "Copyright
- X(C) 1988 Free Software Foundation, Inc." (or with whatever year is
- Xappropriate); keep intact the notices on all files that refer to this
- XLicense Agreement and to the absence of any warranty; and give any
- Xother recipients of the Advise program a copy of this License
- XAgreement along with the program. You may charge a distribution fee
- Xfor the physical act of transferring a copy.
- X
- X 2. You may modify your copy or copies of Advise or any portion of it,
- Xand copy and distribute such modifications under the terms of
- XParagraph 1 above, provided that you also do the following:
- X
- X a) cause the modified files to carry prominent notices stating
- X that you changed the files and the date of any change; and
- X
- X b) cause the whole of any work that you distribute or publish,
- X that in whole or in part contains or is a derivative of Advise or
- X any part thereof, to be licensed at no charge to all third
- X parties on terms identical to those contained in this License
- X Agreement (except that you may choose to grant more extensive
- X warranty protection to some or all third parties, at your option).
- X
- X c) You may charge a distribution fee for the physical act of
- X transferring a copy, and you may at your option offer warranty
- X protection in exchange for a fee.
- X
- XMere aggregation of another unrelated program with this program (or its
- Xderivative) on a volume of a storage or distribution medium does not bring
- Xthe other program under the scope of these terms.
- X
- X 3. You may copy and distribute Advise (or a portion or derivative of it,
- Xunder Paragraph 2) in object code or executable form under the terms of
- XParagraphs 1 and 2 above provided that you also do one of the following:
- X
- X a) accompany it with the complete corresponding machine-readable
- X source code, which must be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X b) accompany it with a written offer, valid for at least three
- X years, to give any third party free (except for a nominal
- X shipping charge) a complete machine-readable copy of the
- X corresponding source code, to be distributed under the terms of
- X Paragraphs 1 and 2 above; or,
- X
- X c) accompany it with the information you received as to where the
- X corresponding source code may be obtained. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form alone.)
- X
- XFor an executable file, complete source code means all the source code for
- Xall modules it contains; but, as a special exception, it need not include
- Xsource code for modules which are standard libraries that accompany the
- Xoperating system on which the executable file runs.
- X
- X 4. You may not copy, sublicense, distribute or transfer Advise
- Xexcept as expressly provided under this License Agreement. Any attempt
- Xotherwise to copy, sublicense, distribute or transfer Advise is void and
- Xyour rights to use the program under this License agreement shall be
- Xautomatically terminated. However, parties who have received computer
- Xsoftware programs from you with this License Agreement will not have
- Xtheir licenses terminated so long as such parties remain in full compliance.
- X
- X 5. If you wish to incorporate parts of Advise into other free programs
- Xwhose distribution conditions are different, write to the Free Software
- XFoundation at 675 Mass Ave, Cambridge, MA 02139. We have not yet worked
- Xout a simple rule that can be stated here, but we will often permit this.
- XWe will be guided by the two goals of preserving the free status of all
- Xderivatives of our free software and of promoting the sharing and reuse of
- Xsoftware.
- X
- XYour comments and suggestions about our licensing policies and our
- Xsoftware are welcome! Please contact the Free Software Foundation, Inc.,
- X675 Mass Ave, Cambridge, MA 02139, or call (617) 876-3296.
- X
- X NO WARRANTY
- X
- X BECAUSE ADVISE IS LICENSED FREE OF CHARGE, WE PROVIDE ABSOLUTELY NO
- XWARRANTY, TO THE EXTENT PERMITTED BY APPLICABLE STATE LAW. EXCEPT
- XWHEN OTHERWISE STATED IN WRITING, FREE SOFTWARE FOUNDATION, INC,
- XRICHARD M. STALLMAN AND/OR OTHER PARTIES PROVIDE ADVISE "AS IS" WITHOUT
- XWARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
- XLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- XA PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND
- XPERFORMANCE OF ADVISE IS WITH YOU. SHOULD ADVISE PROVE DEFECTIVE, YOU
- XASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- X
- X IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL RICHARD M.
- XSTALLMAN, THE FREE SOFTWARE FOUNDATION, INC., AND/OR ANY OTHER PARTY
- XWHO MAY MODIFY AND REDISTRIBUTE GNU SEND AS PERMITTED ABOVE, BE LIABLE TO
- XYOU FOR DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER
- XSPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- XINABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- XBEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
- XFAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS) GNU SEND, EVEN
- XIF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES, OR FOR
- XANY CLAIM BY ANY OTHER PARTY.
- END_OF_FILE
- if test 7166 -ne `wc -c <'COPYING'`; then
- echo shar: \"'COPYING'\" unpacked with wrong size!
- fi
- # end of 'COPYING'
- fi
- if test -f 'Makefile.SUNOS' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile.SUNOS'\"
- else
- echo shar: Extracting \"'Makefile.SUNOS'\" \(787 characters\)
- sed "s/^X//" >'Makefile.SUNOS' <<'END_OF_FILE'
- X
- XMODDIR=/etc/modules
- XBINDIR=/local/bin
- XMANDIR=/local/man/man1
- XMANEXT=.1
- X
- XINSTALL=install
- XINSTBIN=$(INSTALL) -o root -m 4111
- XINSTMAN=$(INSTALL) -m 444
- X
- XALL= advise advisedev.o
- X
- Xall: $(ALL)
- X
- Xadvise: advise.h advise.c
- X cc -O -s -o advise advise.c
- X
- XCFLAGS= -O -DKERNEL -D`arch -k`
- X
- Xadvisedev.o: advisemod.c advisedev.c advise.h
- X
- Xclean:
- X rm -f $(ALL)
- X
- Xinstall: $(ALL)
- X $(INSTBIN) advise $(BINDIR)/advise
- X $(INSTMAN) advise.man $(MANDIR)/advise$(MANEXT)
- X if [ ! -d $(MODDIR) ]; then ( mkdir $(MODDIR) ); fi
- X install -m 444 advisedev.o $(MODDIR)/advise.o
- X install -m 555 advise.exec $(MODDIR)/advise.exec
- X @echo ""
- X @echo "The following line should be placed somewhere near the end in /etc/rc.local:"
- X @echo ""
- X @echo "/usr/etc/modload $(MODDIR)/advise.o -exec $(MODDIR)/advise.exec"
- X @echo ""
- END_OF_FILE
- if test 787 -ne `wc -c <'Makefile.SUNOS'`; then
- echo shar: \"'Makefile.SUNOS'\" unpacked with wrong size!
- fi
- # end of 'Makefile.SUNOS'
- fi
- if test -f 'Makefile.SVR4i386' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile.SVR4i386'\"
- else
- echo shar: Extracting \"'Makefile.SVR4i386'\" \(710 characters\)
- sed "s/^X//" >'Makefile.SVR4i386' <<'END_OF_FILE'
- X
- XBINDIR=/local/bin
- XMANDIR=/local/man/man1
- XMANEXT=.1
- X
- XINSTALL=/usr/ucb/install
- XINSTBIN=$(INSTALL) -o root -m 4111
- XINSTMAN=$(INSTALL) -m 444
- X
- XIDINSTALL=/etc/conf/bin/idinstall
- X
- XKOBJS=advisedev.o advisemod.o
- XCFLAGS= -O -D_KERNEL -DINKERNEL
- X
- XALL=$(KOBJS) advise
- X
- Xall: $(ALL)
- X
- Xadvisedev.o: advise.h
- X
- Xadvisemod.o: advise.h
- X
- Xadvise: advise.h advise.c
- X cc -O -s -o advise advise.c
- X -mcs -d advise
- X
- Xclean:
- X rm -f $(ALL)
- X
- Xinstall: install.kernel install.user
- X
- Xinstall.kernel: $(KOBJS)
- X -$(IDINSTALL) -d advise
- X cd advise.id; $(IDINSTALL) -ka advise
- X -$(IDINSTALL) -d advmod
- X cd advmod.id; $(IDINSTALL) -ka advmod
- X
- Xinstall.user: advise
- X $(INSTBIN) advise $(BINDIR)/advise
- X $(INSTMAN) advise.man $(MANDIR)/advise$(MANEXT)
- END_OF_FILE
- if test 710 -ne `wc -c <'Makefile.SVR4i386'`; then
- echo shar: \"'Makefile.SVR4i386'\" unpacked with wrong size!
- fi
- # end of 'Makefile.SVR4i386'
- fi
- if test -f 'advise.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'advise.c'\"
- else
- echo shar: Extracting \"'advise.c'\" \(15710 characters\)
- sed "s/^X//" >'advise.c' <<'END_OF_FILE'
- X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
- X
- XThis file is part of advise.
- X
- Xadvise is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY. No author or distributor
- Xaccepts responsibility to anyone for the consequences of using it
- Xor for whether it serves any particular purpose or works at all,
- Xunless he says so in writing. Refer to the advise General Public
- XLicense for full details.
- X
- XEveryone is granted permission to copy, modify and redistribute
- Xadvise, but only under the conditions described in the
- Xadvise General Public License. A copy of this license is
- Xsupposed to have been given to you along with advise so you
- Xcan know your rights and responsibilities. It should be in a
- Xfile named COPYING. Among other things, the copyright notice
- Xand this notice must be preserved on all copies. */
- X
- X/*
- X** Author: Keith Gabryelski (ag@amix.commodore.com)
- X*/
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <signal.h>
- X#include <stdio.h>
- X#include <stdlib.h>
- X#include <unistd.h>
- X#include <fcntl.h>
- X#include <stropts.h>
- X#include <poll.h>
- X#include <sys/stream.h>
- X#include <errno.h>
- X#include <utmp.h>
- X#include <pwd.h>
- X#include <termios.h>
- X#include <string.h>
- X#include <ctype.h>
- X#include "advise.h"
- X
- X#ifdef sun
- Xextern int optind;
- X
- X#ifndef CTRL
- X#define CTRL(c) ((c)&037)
- X#endif /* !CTRL */
- X
- X#ifndef EUNATCH
- X#define EUNATCH ENOPROTOOPT
- X#endif /* ! EUNATCH */
- X
- X#endif /* sun */
- X
- Xextern char *optarg;
- X
- X#define max(a,b) ((a)>(b)?(a):(b))
- X
- Xstatic struct module_list
- X{
- X char *name; /* name of module */
- X struct module_list *next; /* next module to be pushed */
- X} advise_module_list =
- X{
- X ADVMODNAME, NULL,
- X};
- X
- X#ifdef __STDC__
- X#define PR_(x) x
- X#else
- X#define PR_(x) ()
- X#endif /* __STDC__ */
- X
- Xstatic void usage PR_( (void) ), advise PR_( (char *) );
- Xstatic char *strchar PR_( (char) );
- Xstatic struct module_list *list_modules PR_( (int, char *));
- X
- Xstatic int allow_deny_p, allow_deny;
- Xstatic int allow_advise_p, allow_advise;
- Xstatic int error_flag;
- Xstatic int secret, spy, reverse;
- Xstatic int meta_character = '~';
- Xstatic char *progname;
- Xstatic char *module = "ldterm";
- X
- X#ifdef sun
- X
- X#ifndef __STDC__
- X/*
- X * strerror - map error number to descriptive string
- X * (stolen from cnews/libfake/strerror.c)
- X *
- X */
- Xstatic char *
- Xstrerror(errnum)
- Xint errnum;
- X{
- X extern int sys_nerr;
- X extern char *sys_errlist[];
- X
- X if (errnum > 0 && errnum < sys_nerr)
- X return(sys_errlist[errnum]);
- X else if (errnum != 0)
- X return("unknown error");
- X else
- X return("no details given");
- X}
- X#endif /* ! __STDC__ */
- X
- Xstatic int utmpfd=-1;
- X
- Xvoid
- Xendutent(
- X#ifdef __STDC__
- X void
- X#endif /* __STDC__ */
- X )
- X{
- X if(utmpfd!=-1) close(utmpfd);
- X utmpfd=-1;
- X}
- X
- Xvoid
- Xsetutent(
- X#ifdef __STDC__
- X void
- X#endif /* __STDC__ */
- X )
- X{
- X endutent();
- X utmpfd=open("/etc/utmp", O_RDONLY);
- X}
- X
- Xstruct utmp *
- Xgetutent(
- X#ifdef __STDC__
- X void
- X#endif /* __STDC__ */
- X )
- X{
- X static struct utmp ut;
- X int ret;
- X
- X if(utmpfd==-1) return(NULL);
- X do {
- X if(read(utmpfd, &ut, sizeof(ut)) != sizeof(ut)) return(NULL);
- X } while(nonuser(ut));
- X
- X return(&ut);
- X}
- X
- Xstruct utmp *
- X#ifdef __STDC__
- Xgetutline(struct utmp *ut)
- X#else
- Xgetutline(ut)
- Xstruct utmp *ut;
- X#endif /* __STDC__ */
- X{
- X struct utmp *utm;
- X
- X while(utm=getutent())
- X if(!strncmp(utm->ut_line, ut->ut_line)) return(utm);
- X
- X return(NULL);
- X}
- X#endif /* sun */
- X
- Xint
- X#ifdef __STDC__
- Xmain(int argc, char **argv)
- X#else
- Xmain(argc, argv)
- Xchar **argv;
- X#endif /* __STDC__ */
- X{
- X int c, error=0;
- X struct termios termios;
- X struct module_list *modules;
- X
- X progname = *argv;
- X
- X while((c = getopt(argc, argv, "ADM:Sardm:s?")) != EOF)
- X {
- X switch(c)
- X {
- X case 's':
- X spy++;
- X break;
- X
- X case 'r':
- X if (!getuid())
- X reverse++;
- X else
- X {
- X (void) fprintf(stderr, "%s: -r option only available to the super user\n", progname);
- X error_flag++;
- X }
- X break;
- X
- X case 'S':
- X if (!getuid())
- X secret++;
- X else
- X {
- X (void) fprintf(stderr, "%s: -S option only available to the super user\n", progname);
- X error_flag++;
- X }
- X break;
- X
- X case 'a':
- X allow_deny_p++;
- X allow_deny=ADVISE_ALLOW;
- X allow_advise_p++;
- X allow_advise++;
- X break;
- X
- X case 'd':
- X allow_advise_p++;
- X allow_advise=0;
- X break;
- X
- X case 'A':
- X allow_deny_p++;
- X allow_deny=ADVISE_ALLOW;
- X break;
- X
- X case 'D':
- X allow_deny_p++;
- X allow_deny=ADVISE_DENY;
- X break;
- X
- X case 'm':
- X meta_character = optarg[0];
- X break;
- X
- X case 'M':
- X module = optarg;
- X break;
- X
- X case '?':
- X error_flag++;
- X break;
- X }
- X
- X if (error_flag)
- X {
- X usage();
- X }
- X }
- X
- X if (allow_advise_p)
- X {
- X int status = ioctl(0, ADVISE_STATUS, &status);
- X
- X if (allow_advise && status)
- X {
- X int advise_module_pushed = 0;
- X
- X /* Push advise module on stream */
- X (void) ioctl(0, TCGETS, &termios);
- X
- X modules = list_modules(0, module);
- X
- X advise_module_list.next = modules;
- X
- X for (modules = &advise_module_list;
- X modules != NULL;
- X modules = modules->next)
- X {
- X
- X if (!strcmp(modules->name, ADVMODNAME))
- X {
- X if (advise_module_pushed)
- X continue;
- X
- X advise_module_pushed = 1;
- X }
- X
- X if (ioctl(0, I_PUSH, modules->name))
- X {
- X (void) fprintf(stderr, "%s: Couldn't I_PUSH: %s (%s).\n",
- X progname, modules->name, strerror(errno));
- X error++;
- X }
- X }
- X
- X (void) ioctl(0, TCSETS, &termios);
- X }
- X
- X if (!allow_advise && !status)
- X {
- X (void) ioctl(0, TCGETS, &termios);
- X
- X modules = list_modules(0, ADVMODNAME);
- X
- X while (modules != NULL)
- X {
- X if (strcmp(modules->name, ADVMODNAME))
- X {
- X if (ioctl(0, I_PUSH, modules->name))
- X {
- X (void) fprintf(stderr,
- X "%s: Couldn't I_PUSH: %s (%s).\n",
- X progname, modules->name,
- X strerror(errno));
- X error++;
- X }
- X }
- X
- X modules = modules->next;
- X }
- X
- X (void) ioctl(0, TCSETS, &termios);
- X }
- X
- X if (!allow_deny_p)
- X return error ? 1 : 0;
- X }
- X
- X if (allow_deny_p)
- X {
- X if (ioctl(0, allow_deny, 0))
- X {
- X if (errno == EINVAL)
- X {
- X (void) fprintf(stderr, "%s: module \"%s\" not in stream.\n",
- X progname, ADVMODNAME);
- X }
- X else
- X {
- X (void) fprintf(stderr, "%s: Couldn't set advisory mode (%s).\n",
- X progname, strerror(errno));
- X }
- X
- X return 1;
- X }
- X
- X goto advstat;
- X }
- X
- X /* All switches have been handled */
- X
- X argc -= optind;
- X argv += optind;
- X
- X if (argc > 1)
- X {
- X usage();
- X }
- X
- X if (argc == 0)
- X {
- X int retval, status;
- X
- Xadvstat:
- X /*
- X ** Status of advise.
- X */
- X
- X retval = ioctl(0, ADVISE_STATUS, &status);
- X#if !defined(M_COPYOUT) && !defined(sun)
- X status = !retval;
- X#endif /* n M_COPYOUT */
- X
- X if (retval)
- X {
- X printf("Module \"%s\" not pushed on stream.\n", ADVMODNAME);
- X }
- X else
- X {
- X printf("Advise access %s\n", status ? "allowed" : "denied");
- X }
- X
- X return 0;
- X }
- X
- X advise(*argv);
- X
- X return 0;
- X}
- X
- Xstatic void
- Xusage(
- X#ifdef __STDC__
- X void
- X#endif /* __STDC__ */
- X )
- X{
- X (void) fprintf(stderr, "usage: %s [-ADad?] [-M module] | [-Ssr] [-m char] [ device | username ]\n",
- X progname);
- X exit(1);
- X}
- X
- Xstruct termios termios, oldtermios;
- X
- Xvoid restoretermios(sig)
- X{
- X (void) ioctl(0, TCSETS, &oldtermios);
- X exit(0);
- X}
- X
- Xstatic void
- X#ifdef __STDC__
- Xadvise(char *who)
- X#else
- Xadvise(who)
- Xchar *who;
- X#endif /* __STDC__ */
- X{
- X int ret, fd, metad=0;
- X char buf[1024], *device=NULL, *devname, *login_name, *tty_name;
- X struct pollfd pfds[2];
- X struct stat stbuf;
- X struct utmp *ut, uts;
- X char username[sizeof(ut->ut_name) + 1];
- X
- X username[0] = '\0';
- X
- X if (*who == '/') /* full path name */
- X device = who;
- X else
- X {
- X /* Either this is /dev/ + who OR a username */
- X
- X setutent();
- X
- X while ((ut = getutent()) != NULL)
- X {
- X if (
- X#ifdef USER_PROCESS
- X (ut->ut_type==USER_PROCESS) &&
- X#endif /* USER_PROCESS */
- X (!strncmp(who, ut->ut_name, sizeof(ut->ut_name))))
- X {
- X if(device) free(device);
- X device = (char *)malloc(sizeof("/dev/") +
- X sizeof(ut->ut_line));
- X
- X if (device == NULL)
- X {
- X (void) fprintf(stderr,
- X "%s: malloc failed (Out of Memory)\n",
- X progname);
- X
- X exit(1);
- X }
- X
- X strcpy(device, "/dev/");
- X strncat(device, ut->ut_line, sizeof(ut->ut_line));
- X device[sizeof("/dev/")+sizeof(ut->ut_line)] = '\0';
- X
- X strncpy(username, ut->ut_name, sizeof(ut->ut_name));
- X username[sizeof(ut->ut_name)] = '\0';
- X if(!strcmp(device, ttyname(0))) continue;
- X break;
- X }
- X }
- X
- X if (device == NULL) /* Is /dev/ + who */
- X {
- X device = (char *)malloc(sizeof("/dev/") + strlen(who));
- X
- X if (device == NULL)
- X {
- X (void) fprintf(stderr, "%s: malloc failed (Out of Memory)\n",
- X progname);
- X
- X exit(1);
- X }
- X
- X strcpy(device, "/dev/");
- X strcat(device, who);
- X }
- X
- X endutent();
- X }
- X
- X devname = device + sizeof("/dev/") - 1;
- X
- X if (username[0] == '\0')
- X {
- X setutent();
- X
- X strncpy(uts.ut_line, devname, sizeof(uts.ut_line));
- X
- X if ((ut = getutline(&uts)) != NULL)
- X {
- X strncpy(username, ut->ut_name, sizeof(ut->ut_name));
- X username[sizeof(ut->ut_name)] = '\0';
- X }
- X else
- X {
- X strcpy(username, "unknown");
- X }
- X
- X endutent();
- X }
- X
- X if(!strcmp(device, ttyname(0)))
- X {
- X (void) fprintf(stderr, "%s: Can't advise yourself!\n", progname);
- X exit(1);
- X }
- X
- X if (stat(device, &stbuf) < 0)
- X {
- X if (errno == ENOENT)
- X {
- X if(*who=='/') (void) fprintf(stderr, "%s: no advisee device \"%s\"\n", progname, device);
- X else (void) fprintf(stderr, "%s: unknown user \"%s\" or no advisee device \"%s\"\n", progname, who, device);
- X }
- X else
- X {
- X (void) fprintf(stderr,
- X "%s: Couldn't stat() advisee device: %s (%s)\n",
- X progname, device, strerror(errno));
- X }
- X exit(1);
- X }
- X
- X if ((fd = open("/dev/advise", O_RDWR|O_NONBLOCK)) < 0)
- X {
- X (void) fprintf(stderr,
- X "%s: Couldn't open advisory device: /dev/advise (%s)\n",
- X progname, strerror(errno));
- X exit(1);
- X }
- X setuid(getuid());
- X
- X if (ioctl(fd, reverse?ADVISE_SETADVISEERD:ADVISE_SETADVISEEWR,
- X#ifdef sun
- X &
- X#endif /* sun */
- X stbuf.st_rdev))
- X {
- X if (errno == EUNATCH)
- X {
- X (void) fprintf(stderr,
- X "%s: module \"%s\" not in place for %s\n",
- X progname, ADVMODNAME, device);
- X } else if (errno == EACCES)
- X {
- X (void) fprintf(stderr, "%s: Permission denied\n", progname);
- X } else
- X {
- X (void) fprintf(stderr,
- X "%s: Couldn't set advisee: %s (%lu, %lu) (%s)\n",
- X progname, device,
- X#ifdef sun
- X major(stbuf.st_rdev), minor(stbuf.st_rdev),
- X#else
- X ((stbuf.st_rdev >> 16) &0xFFFF), (stbuf.st_rdev&0xFFFF),
- X#endif /* sun */
- X strerror(errno));
- X }
- X exit(1);
- X }
- X
- X if (!secret)
- X {
- X char *str;
- X struct passwd *pt;
- X
- X if ((login_name = getlogin()) == NULL)
- X {
- X pt = getpwuid(getuid());
- X
- X if (pt == NULL || pt->pw_name == NULL)
- X {
- X login_name = "somebody";
- X }
- X else
- X {
- X login_name = pt->pw_name;
- X }
- X }
- X
- X if ((tty_name = ttyname(2)) != NULL)
- X {
- X if (!strncmp(tty_name, "/dev/", sizeof("/dev/")-1))
- X tty_name += sizeof("/dev/")-1;
- X }
- X else
- X tty_name = "somewhere";
- X
- X str = malloc(strlen(login_name) + strlen(tty_name) +
- X sizeof("[: advising :]\n\r") + strlen(username) +
- X strlen(devname));
- X
- X if (str)
- X {
- X struct advise_message m;
- X struct strbuf ctl, data;
- X
- X m.type = ADVISE_READDATA;
- X
- X ctl.len = sizeof(m);
- X ctl.buf = (void *)&m;
- X
- X sprintf(str, "[%s:%s %s %s:%s]\n\r", login_name,
- X tty_name, spy ? "spying" : "advising", username, devname);
- X
- X data.len = strlen(str);
- X data.buf = str;
- X
- X (void) putmsg(fd, &ctl, &data, 0);
- X
- X free(str);
- X }
- X }
- X
- X
- X (void) ioctl(0, TCGETS, &termios);
- X
- X oldtermios = termios;
- X signal(SIGTERM, restoretermios);
- X termios.c_oflag &= ~OPOST;
- X
- X if (!spy)
- X {
- X termios.c_cc[VMIN] = 1;
- X termios.c_cc[VTIME] = 0;
- X termios.c_lflag &= ~(ISIG|ICANON|ECHO);
- X } else signal(SIGINT, restoretermios);
- X (void) ioctl(0, TCSETS, &termios);
- X
- X pfds[0].fd = fd;
- X pfds[0].events = POLLIN;
- X
- X pfds[1].fd = 0;
- X pfds[1].events = POLLIN;
- X
- X for (;;)
- X {
- X if (poll(pfds, spy?1:2, INFTIM) < 0)
- X continue;
- X
- X if ((pfds[0].revents&POLLHUP) != 0) /* module removed */
- X {
- X (void) ioctl(0, TCSETS, &oldtermios);
- X exit(0);
- X }
- X if ((pfds[0].revents&POLLIN) != 0) /* data from advisee ready */
- X {
- X if ((ret = read(fd, buf, sizeof(buf))) > 0)
- X write(1, buf, ret);
- X }
- X
- X if (!spy && ((pfds[1].revents&POLLIN) != 0)) /* data from advisor ready */
- X {
- X if ((ret = read(0, buf, sizeof(buf))) > 0)
- X {
- X register int i;
- X register char *p = buf, *pp=buf;
- X
- X for (i=0; i < ret; ++i, p++)
- X {
- X if (metad)
- X {
- X if (metad == 2)
- X {
- X meta_character = *p;
- X printf("The meta character is now: %s\n",
- X strchar(meta_character));
- X pp++;
- X metad = 0;
- X continue;
- X }
- X
- X switch (*p)
- X {
- X case '=':
- X metad=2;
- X pp++;
- X break;
- X
- X case '?':
- X {
- X char *escstr = strchar(meta_character);
- X
- X printf("Help for meta character <%s>:\n",
- X escstr);
- X printf("%s?\t-- This help message.\n", escstr);
- X printf("%s~\t-- Send a single meta character.\n",
- X escstr);
- X printf("%s.\t-- Disconnect advise session.\n",
- X escstr);
- X printf("%s=C\t-- Change meta character to C.\n",
- X escstr);
- X printf("%s^Z\t-- Suspend advise session.\n",
- X escstr);
- X pp++;
- X metad=0;
- X break;
- X }
- X
- X case '.':
- X {
- X if (!secret)
- X {
- X char *str;
- X
- X str = malloc(strlen(login_name) +
- X strlen(tty_name) +
- X sizeof("[: disconnecting from :]\n") +
- X strlen(username) + strlen(devname));
- X
- X if (str)
- X {
- X struct advise_message m;
- X struct strbuf ctl, data;
- X
- X m.type = ADVISE_READDATA;
- X
- X ctl.len = sizeof(m);
- X ctl.buf = (void *)&m;
- X
- X sprintf(str, "[%s:%s disconnecting from %s:%s]\n\r",
- X login_name, tty_name, username,
- X devname);
- X
- X data.len = strlen(str);
- X data.buf = str;
- X
- X (void) putmsg(fd, &ctl, &data, 0);
- X
- X free(str);
- X }
- X }
- X
- X close(fd);
- X
- X (void) ioctl(0, TCSETS, &oldtermios);
- X
- X exit(0);
- X }
- X
- X case CTRL('Z'):
- X {
- X (void) ioctl(0, TCSETS, &oldtermios);
- X (void) signal(SIGTSTP, SIG_DFL);
- X (void) kill(0, SIGTSTP);
- X (void) ioctl(0, TCSETS, &termios);
- X pp++;
- X metad=0;
- X break;
- X }
- X
- X default:
- X metad=0;
- X break;
- X }
- X }
- X else
- X {
- X if (*p == meta_character)
- X {
- X int d = p - pp;
- X
- X metad=1;
- X
- X if (d) write(fd, pp, d);
- X
- X pp += d + 1;
- X i += d;
- X }
- X }
- X }
- X
- X if (p - pp) write(fd, pp, p-pp);
- X }
- X }
- X }
- X}
- X
- Xstatic struct module_list *
- X#ifdef __STDC__
- Xlist_modules(int fd, char *push_below)
- X#else
- Xlist_modules(fd, push_below)
- Xchar *push_below;
- X#endif /* __STDC__ */
- X{
- X char lookbuf[max(FMNAMESZ+1,256)];
- X struct module_list *mp, *mpp;
- X
- X mp = NULL;
- X
- X while (ioctl(fd, I_LOOK, lookbuf) == 0)
- X {
- X if (ioctl(fd, I_POP, 0))
- X {
- X (void) fprintf(stderr, "%s: Couldn't I_POP: %s (%s).\n", progname,
- X lookbuf, strerror(errno));
- X return mp;
- X }
- X
- X if ((mpp = (struct module_list *)malloc(sizeof(struct module_list)))
- X == NULL || (mpp->name = malloc(strlen(lookbuf) + 1)) == NULL)
- X {
- X (void) fprintf(stderr, "%s: Couldn't malloc (out of memory).\n",
- X progname);
- X return mp;
- X }
- X
- X mpp->next = mp;
- X mp = mpp;
- X
- X strcpy(mp->name, lookbuf);
- X
- X if (!strcmp(push_below, lookbuf))
- X break;
- X }
- X
- X return mp;
- X}
- X
- Xstatic char *
- X#ifdef __STDC__
- Xstrchar(char character)
- X#else
- Xstrchar(character)
- Xchar character;
- X#endif /* __STDC__ */
- X{
- X static char retbuf[4];
- X char *p = retbuf;
- X int capit = 0;
- X
- X if (!isascii(character))
- X {
- X *p++ = '~';
- X capit = 1;
- X character = toascii(character);
- X }
- X
- X if (iscntrl(character))
- X {
- X *p++ = '^';
- X capit = 1;
- X character += '@';
- X }
- X
- X if (capit)
- X *p++ = toupper(character);
- X else
- X *p++ = character;
- X
- X *p = '\0';
- X
- X return retbuf;
- X}
- END_OF_FILE
- if test 15710 -ne `wc -c <'advise.c'`; then
- echo shar: \"'advise.c'\" unpacked with wrong size!
- fi
- # end of 'advise.c'
- fi
- if test -f 'advise.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'advise.h'\"
- else
- echo shar: Extracting \"'advise.h'\" \(2277 characters\)
- sed "s/^X//" >'advise.h' <<'END_OF_FILE'
- X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
- X
- XThis file is part of advise.
- X
- Xadvise is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY. No author or distributor
- Xaccepts responsibility to anyone for the consequences of using it
- Xor for whether it serves any particular purpose or works at all,
- Xunless he says so in writing. Refer to the advise General Public
- XLicense for full details.
- X
- XEveryone is granted permission to copy, modify and redistribute
- Xadvise, but only under the conditions described in the
- Xadvise General Public License. A copy of this license is
- Xsupposed to have been given to you along with advise so you
- Xcan know your rights and responsibilities. It should be in a
- Xfile named COPYING. Among other things, the copyright notice
- Xand this notice must be preserved on all copies. */
- X
- X/*
- X** Author: Keith Gabryelski (ag@amix.commodore.com)
- X*/
- X
- Xstruct advise_queue_list
- X{
- X mblk_t *savbp; /* ptr to this mblk for freeb()ing */
- X queue_t *q; /* advisor's queue */
- X int minord; /* minor device for this advisor */
- X int wdir; /* direction of writes */
- X struct advise_state *state; /* ptr back to advise_state struct */
- X struct advise_queue_list *next; /* ptr to next advisor */
- X};
- X
- Xstruct advise_state
- X{
- X mblk_t *savbp; /* ptr to this mblk for freeb()ing */
- X int status; /* current status */
- X dev_t dev; /* our device */
- X queue_t *q; /* queue for advisor writing */
- X struct advise_queue_list *q_wlist, *q_rlist; /* lists of spies */
- X struct advise_state *next; /* next in advise_table */
- X};
- X
- X#define ALLOW_ADVICE (0x01)
- X
- Xstruct advise_message
- X{
- X int type; /* What type of data is this? */
- X};
- X
- X#define ADVISE_DATA (0x00)
- X#define ADVISE_READDATA (0x01)
- X
- X#ifdef sun
- X#define ADVISE_SETADVISEEWR _IOW(z, 1, dev_t)
- X#define ADVISE_SETADVISEERD _IOW(z, 2, dev_t)
- X#define ADVISE_ALLOW _IO(z, 3)
- X#define ADVISE_DENY _IO(z, 4)
- X#define ADVISE_STATUS _IOR(z, 5, int)
- X#else
- X#define ADVISE ('z'<<16)
- X#define ADVISE_SETADVISEEWR (ADVISE|0x01)
- X#define ADVISE_SETADVISEERD (ADVISE|0x02)
- X#define ADVISE_ALLOW (ADVISE|0x03)
- X#define ADVISE_DENY (ADVISE|0x04)
- X#define ADVISE_STATUS (ADVISE|0x05)
- X#endif /* sun */
- X
- X#define spladvise spltty
- X
- X#define ADVMODNAME "advmod"
- END_OF_FILE
- if test 2277 -ne `wc -c <'advise.h'`; then
- echo shar: \"'advise.h'\" unpacked with wrong size!
- fi
- # end of 'advise.h'
- fi
- if test ! -d 'advise.id' ; then
- echo shar: Creating directory \"'advise.id'\"
- mkdir 'advise.id'
- fi
- if test -f 'advise.man' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'advise.man'\"
- else
- echo shar: Extracting \"'advise.man'\" \(2161 characters\)
- sed "s/^X//" >'advise.man' <<'END_OF_FILE'
- X.TH advise 1
- X.SH NAME
- Xadvise \- Attach to another user.
- X.SH SYNOPSIS
- X.B advise
- X[-ADad?] [-M module] | [-Ss] [-m char] [ device | username ]
- X.SH DESCRIPTION
- X.B Advise
- Xattaches a user (the advisor) to another user's (the advisee) terminal in
- Xsuch a way the the advisor can type for the advisee and view what
- Xthe advisee's terminal is displaying.
- X.PP
- XThe advisee would typically type ``advise -a'' to allow advise attaches;
- Xthe advisor would then type ``advise username'' which would connect the
- Xadvisors terminal the the advisee's.
- X.PP
- XAll characters the advisor types are sent to the advisee's terminal
- Xas if the advisee typed them save the meta character.
- X.PP
- XThe default meta character is tilde (~). The advisor uses the meta
- Xcharacter to disconnect or suspend the advise session. The meta
- Xcommands that are available to the advisor are:
- X.PP
- X.RS
- X.TP
- X~?
- XMeta character help message.
- X.TP
- X~~
- XSend the meta character to the advisee's terminal.
- X.TP
- X~.
- XDisconnect advise session.
- X.TP
- X~=C
- XChange the meta character to C.
- X.TP
- X~^Z
- XSuspend this advise session.
- X.RE
- X.PP
- XIn Advise mode the advisor uses ``~.'' to disconnect the advise session
- X(Note: the advisor should use ``~~'' to send one tilde to the advisee's
- Xterminal).
- X.PP
- XIn ``spy mode'' the advisor should use an interrupt is use to disconnect
- Xthe advise session.
- X.PP
- X``advise -d'' can be used by the advisee to disconnect the advise
- Xsession.
- X.SH OPTIONS
- X.TP
- X-A
- XAllow advise attaches to this terminal.
- X.TP
- X-D
- XDisallow advise attaches to this terminal.
- X.TP
- X-M module
- XName of module to place advise module under.
- X.TP
- X-S
- XWhen attaching to another user, don't send the attach message.
- X(available to the super user, only).
- X.TP
- X-a
- XPush advise module on standard input stream and allow advise
- Xattaches.
- X.TP
- X-d
- XPush advise module on standard input stream and disallow advise
- Xattaches.
- X.TP
- X-m char
- XChange the meta character to ``char''. The default meta character
- Xis tilde (~).
- X.TP
- X-s
- XSpy mode only (ie, input from the advisor is not passed to the
- Xadvisee).
- X.TP
- Xdevice
- XThe name of the tty device to advise.
- X.TP
- Xusername
- XThe name of the user to advise.
- X.SH AUTHOR
- X.RS
- X.PP
- XKeith M. Gabryelski (ag@amix.commodore.com)
- X.RE
- END_OF_FILE
- if test 2161 -ne `wc -c <'advise.man'`; then
- echo shar: \"'advise.man'\" unpacked with wrong size!
- fi
- # end of 'advise.man'
- fi
- if test -f 'advisedev.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'advisedev.c'\"
- else
- echo shar: Extracting \"'advisedev.c'\" \(10422 characters\)
- sed "s/^X//" >'advisedev.c' <<'END_OF_FILE'
- X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
- X
- XThis file is part of advise.
- X
- Xadvise is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY. No author or distributor
- Xaccepts responsibility to anyone for the consequences of using it
- Xor for whether it serves any particular purpose or works at all,
- Xunless he says so in writing. Refer to the advise General Public
- XLicense for full details.
- X
- XEveryone is granted permission to copy, modify and redistribute
- Xadvise, but only under the conditions described in the
- Xadvise General Public License. A copy of this license is
- Xsupposed to have been given to you along with advise so you
- Xcan know your rights and responsibilities. It should be in a
- Xfile named COPYING. Among other things, the copyright notice
- Xand this notice must be preserved on all copies. */
- X
- X/*
- X** Author: Keith Gabryelski (ag@amix.commodore.com)
- X*/
- X
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/sysmacros.h>
- X#include <sys/signal.h>
- X#include <sys/file.h>
- X#if !defined(sun) && !defined(i386) /* AmigaUnix ? */
- X#include <sys/user.h>
- X#endif /* !sun && !i386 */
- X#include <sys/proc.h>
- X#include <sys/termios.h>
- X#include <sys/ttold.h>
- X#ifndef sun
- X#include <sys/cmn_err.h>
- X#endif /* !sun */
- X#include <sys/stream.h>
- X#include <sys/stropts.h>
- X#include <sys/errno.h>
- X#include <sys/debug.h>
- X#include "advise.h"
- X#ifndef sun
- X#include <sys/inline.h>
- X#else
- X#include "advisemod.c"
- X
- X#ifndef L_MAXMIN
- X#define L_MAXMIN 0377
- X#endif /* ! L_MAXMIN */
- X
- X#ifndef EUNATCH
- X#define EUNATCH ENOPROTOOPT
- X#endif /* ! EUNATCH */
- X
- X#endif /* ! sun */
- X
- X#ifdef i386
- X#include <sys/ddi.h>
- X
- Xint advisedevflag = 0; /* Used by the Kernel */
- X#endif /* i386 */
- X
- Xint adviseopen(), adviseclose(), adviserput(), advisewput();
- Xvoid advisesrvioc();
- X
- Xstatic struct module_info adviseiinfo =
- X{
- X 0, "advise", 0, INFPSZ, 2048, 128,
- X};
- X
- Xstatic struct qinit adviserinit =
- X{
- X adviserput, NULL, adviseopen, adviseclose, NULL, &adviseiinfo, NULL
- X};
- X
- Xstatic struct module_info adviseoinfo =
- X{
- X 42, "advise", 0, INFPSZ, 300, 200,
- X};
- X
- Xstatic struct qinit advisewinit =
- X{
- X advisewput, NULL, NULL, NULL, NULL, &adviseoinfo, NULL
- X};
- X
- X#ifndef sun
- Xextern struct advise_state advise_table;
- X#else
- Xstatic
- X#endif /* sun */
- Xstruct streamtab adviseinfo =
- X{
- X &adviserinit, &advisewinit, NULL, NULL,
- X};
- X
- Xstatic char minoralloc[((L_MAXMIN+1+7)&~7)/8];
- X
- X/*ARGSUSED*/
- Xstatic int
- Xadviseopen(q, dev, flag, sflag
- X#ifndef sun
- X , credp
- X#endif /* !sun */
- X)
- Xregister queue_t *q;
- X#ifdef sun
- X#define openerr(x) return OPENFAIL
- X#else
- X#define openerr(x) return x
- Xdev_t *dev;
- Xcred_t *credp;
- X#endif /* sun */
- X{
- X register mblk_t *bp;
- X struct advise_queue_list *ql;
- X struct advise_state *sp;
- X int i;
- X int s;
- X
- X if (sflag != CLONEOPEN)
- X openerr(EINVAL);
- X
- X s=spladvise();
- X for (i=0; i < L_MAXMIN && minoralloc[i/8]&(1<<(i%8)); ++i);
- X
- X if(i==L_MAXMIN) {
- X splx(s);
- X openerr(ENOMEM); /* no more resources */
- X }
- X
- X minoralloc[i/8] |= 1<<(i%8);
- X i++;
- X splx(s);
- X
- X#ifndef sun
- X *dev = makedevice(getmajor(*dev), i);
- X#endif /* sun */
- X
- X if ((bp = allocb((int)sizeof(struct advise_queue_list), BPRI_MED)) == NULL)
- X {
- X openerr(ENOMEM);
- X }
- X
- X bp->b_wptr += sizeof(struct advise_queue_list);
- X ql = (struct advise_queue_list *)bp->b_rptr;
- X ql->savbp = bp;
- X ql->next = NULL;
- X ql->q = q;
- X ql->minord = i;
- X ql->wdir = 0;
- X ql->state = NULL;
- X
- X q->q_ptr = (caddr_t)ql;
- X WR(q)->q_ptr = (caddr_t)ql;
- X
- X#ifdef sun
- X return minor(i);
- X#else
- X return 0;
- X#endif /* sun */
- X}
- X
- Xstatic struct advise_state *
- Xvalidstate(sp)
- Xstruct advise_state *sp;
- X{
- X struct advise_state *llist = &advise_table;
- X
- X if(sp != NULL) if (sp->q != NULL) {
- X while (llist != NULL && llist->next != sp)
- X llist = llist->next;
- X
- X return(llist);
- X }
- X return(NULL);
- X}
- X
- Xstatic
- Xadviseclose(q)
- Xregister queue_t *q;
- X{
- X struct advise_state *llist = &advise_table;
- X struct advise_queue_list *qp = (struct advise_queue_list *)q->q_ptr;
- X struct advise_queue_list *ql, *qlp;
- X int s;
- X
- X s=spladvise();
- X
- X /* Remove us from the advisor's list */
- X if (llist = validstate(qp->state))
- X {
- X if(ql = llist->next->q_wlist) {
- X
- X if (ql->q == q)
- X llist->next->q_wlist = ql->next;
- X else
- X {
- X while (ql->next != NULL && ql->next->q != q)
- X ql = ql->next;
- X
- X if (ql->next != NULL)
- X ql->next = ql->next->next;
- X }
- X }
- X
- X if(ql = llist->next->q_rlist) {
- X
- X if (ql->q == q)
- X llist->next->q_rlist = ql->next;
- X else
- X {
- X while (ql->next != NULL && ql->next->q != q)
- X ql = ql->next;
- X
- X if (ql->next != NULL)
- X ql->next = ql->next->next;
- X }
- X }
- X }
- X
- X /* mark minor device number as free in our allocation bitmap */
- X minoralloc[(qp->minord-1)/8] &= ~(1<<((qp->minord-1)%8));
- X
- X splx(s);
- X
- X qp->state = NULL;
- X freeb(qp->savbp);
- X
- X q->q_ptr = NULL;
- X WR(q)->q_ptr = NULL;
- X}
- X
- Xstatic int
- Xadviserput(q, bp)
- Xstruct queue *q;
- Xmblk_t *bp;
- X{
- X putnext(q, bp);
- X}
- X
- Xstatic int
- Xadvisewput(q, mp)
- Xstruct queue *q;
- Xmblk_t *mp;
- X{
- X struct advise_queue_list *qp = (struct advise_queue_list *)q->q_ptr;
- X struct advise_state *sp = qp->state;
- X int s;
- X
- X switch (mp->b_datap->db_type)
- X {
- X case M_PROTO:
- X {
- X struct advise_message *ms = (struct advise_message *)mp->b_rptr;
- X mblk_t *mp2 = unlinkb(mp);
- X
- X if (mp2)
- X {
- X s=spladvise();
- X if (validstate(sp))
- X {
- X if (ms->type == ADVISE_READDATA)
- X {
- X putnext(WR(sp->q), mp2);
- X }
- X else
- X {
- X putnext(sp->q, mp2);
- X }
- X }
- X else
- X freemsg(mp2);
- X splx(s);
- X }
- X
- X freemsg(mp);
- X break;
- X }
- X
- X case M_DATA:
- X /*
- X ** Write data to advisee.
- X */
- X s=spladvise();
- X if (validstate(sp))
- X putnext(qp->wdir?WR(sp->q):sp->q, mp);
- X else
- X freemsg(mp);
- X splx(s);
- X break;
- X
- X#ifdef M_COPYOUT
- X case M_IOCDATA:
- X#endif /* M_COPYOUT */
- X case M_IOCTL:
- X advisesrvioc(q, mp);
- X break;
- X
- X default:
- X freemsg(mp);
- X break;
- X }
- X}
- X
- X
- Xstatic void
- Xadvisesrvioc(q, mp)
- Xqueue_t *q;
- Xmblk_t *mp;
- X{
- X mblk_t *mp1;
- X struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
- X struct advise_queue_list *qp=(struct advise_queue_list *)q->q_ptr;
- X int s;
- X
- X#ifdef M_COPYOUT
- X if (mp->b_datap->db_type == M_IOCDATA)
- X {
- X /* For copyin/copyout failures, just free message. */
- X if (((struct copyresp *)mp->b_rptr)->cp_rval)
- X {
- X freemsg(mp);
- X return;
- X }
- X
- X if (!((struct copyresp *)mp->b_rptr)->cp_private)
- X {
- X mp->b_datap->db_type = M_IOCACK;
- X freemsg(unlinkb(mp));
- X iocbp->ioc_count = 0;
- X iocbp->ioc_rval = 0;
- X iocbp->ioc_error = 0;
- X putnext(RD(q), mp);
- X return;
- X }
- X }
- X#endif /* M_COPYOUT */
- X
- X switch (iocbp->ioc_cmd)
- X {
- X case ADVISE_SETADVISEEWR:
- X case ADVISE_SETADVISEERD:
- X {
- X register dev_t p;
- X struct advise_queue_list *qlp, **qlist;
- X struct advise_state *llist;
- X
- X if (qp->state != NULL) /* already advising someone */
- X {
- X iocbp->ioc_error = EBUSY;
- X mp->b_datap->db_type = M_IOCNAK;
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X }
- X
- X if (!mp->b_cont)
- X {
- X iocbp->ioc_error = EINVAL;
- X mp->b_datap->db_type = M_IOCNAK;
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X }
- X
- X p = *(dev_t *)mp->b_cont->b_rptr;
- X
- X s = spladvise();
- X
- X#ifdef sun
- Xconsoletryagain: /* ugly hack to allow advising of /dev/console */
- X#endif /* sun */
- X llist = advise_table.next;
- X
- X while (llist != NULL && llist->dev != p)
- X {
- X llist = llist->next;
- X }
- X
- X if (llist == NULL)
- X {
- X#ifdef sun
- X if(major(p)==0) {
- X p=makedev(1, minor(p));
- X goto consoletryagain;
- X }
- X#endif /* sun */
- X splx(s);
- X iocbp->ioc_error = EUNATCH;
- X mp->b_datap->db_type = M_IOCNAK;
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X }
- X
- X if ((llist->status & ALLOW_ADVICE) == 0 && (
- X#ifdef sun
- X iocbp->ioc_uid
- X#else
- X#ifdef i386
- X drv_priv(iocbp->ioc_cr)
- X#else
- X !suser(u.u_cred)
- X#endif /* i386 */
- X#endif /* sun */
- X ))
- X {
- X splx(s);
- X iocbp->ioc_error = EACCES;
- X mp->b_datap->db_type = M_IOCNAK;
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X }
- X
- X /*
- X ** Add ourself to the list of advisors for this advisee.
- X */
- X
- X if(iocbp->ioc_cmd==ADVISE_SETADVISEERD) qlist=&llist->q_rlist;
- X else qlist=&llist->q_wlist;
- X
- X if (*qlist == NULL)
- X {
- X qlp = *qlist = qp;
- X }
- X else
- X {
- X qlp = *qlist;
- X
- X while (qlp->next != NULL)
- X qlp = qlp->next;
- X
- X qlp->next = qp;
- X qlp = qp;
- X }
- X
- X qlp->state = llist;
- X
- X if(iocbp->ioc_cmd==ADVISE_SETADVISEERD) qlp->wdir=1;
- X else qlp->wdir=0;
- X
- X splx(s);
- X
- X mp->b_datap->db_type = M_IOCACK;
- X mp1 = unlinkb(mp);
- X if (mp1)
- X freeb(mp1);
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X }
- X
- X default:
- X /* Unrecognized ioctl command */
- X if (canput(RD(q)->q_next))
- X {
- X mp->b_datap->db_type = M_IOCNAK;
- X putnext(RD(q), mp);
- X }
- X else
- X putbq(q, mp);
- X break;
- X }
- X}
- X
- X#ifdef sun
- X
- X/* autoload support for SunOS 4.1.
- X Derived from example in section 5.7 of Sun manual "Writing Device Drivers",
- X and code of similar purpose in a streams logging module written by
- X Matthias Urlichs <urlichs@smurf.sub.org>.
- X*/
- X#include <sys/conf.h>
- X#include <sys/buf.h>
- X#include <sundev/mbvar.h>
- X#include <sun/autoconf.h>
- X#include <sun/vddrv.h>
- X
- Xextern nodev();
- X
- Xstatic struct cdevsw advisecdev = {
- X nodev, nodev, nodev, nodev,
- X nodev, nodev, nodev, 0,
- X &adviseinfo, 0
- X};
- X
- Xstatic struct vdldrv vd = {
- X VDMAGIC_PSEUDO,
- X "advise",
- X NULL,
- X#ifndef sun4c
- X NULL,NULL,0,1,
- X#endif /* sun4c */
- X NULL,&advisecdev,0,0
- X};
- X
- Xstatic struct fmodsw *fmod_advmod=NULL;
- X
- Xxxxinit(fc,vdp,vdi,vds)
- Xunsigned int fc;
- Xstruct vddrv *vdp;
- Xaddr_t vdi;
- Xstruct vdstat *vds;
- X{
- X switch(fc) {
- X case VDLOAD:
- X if(fmod_advmod) return(EBUSY);
- X {
- X int dev,i;
- X
- X for(dev=0; dev < fmodcnt; dev++) {
- X if(fmodsw[dev].f_str == NULL)
- X break;
- X }
- X if(dev == fmodcnt) return(ENODEV);
- X
- X fmod_advmod = &fmodsw[dev];
- X for(i=0;i<=FMNAMESZ;i++)
- X fmod_advmod->f_name[i] = advmodinfo.st_rdinit->qi_minfo->mi_idname[i];
- X }
- X fmod_advmod->f_str = &advmodinfo;
- X vdp->vdd_vdtab = (struct vdlinkage *)&vd;
- X return 0;
- X
- X case VDUNLOAD:
- X if(advise_table.next) return(EIO);
- X for(i=0; i<sizeof(minoralloc); i++)
- X if(minoralloc[i]) return(EIO);
- X
- X if(fmod_advmod) {
- X fmod_advmod->f_name[0] = '\0';
- X fmod_advmod->f_str = NULL;
- X fmod_advmod=NULL;
- X } else return(ENODEV);
- X return 0;
- X
- X case VDSTAT:
- X return 0;
- X
- X default:
- X return EIO;
- X }
- X}
- X#endif /* sun */
- END_OF_FILE
- if test 10422 -ne `wc -c <'advisedev.c'`; then
- echo shar: \"'advisedev.c'\" unpacked with wrong size!
- fi
- # end of 'advisedev.c'
- fi
- if test -f 'advisemod.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'advisemod.c'\"
- else
- echo shar: Extracting \"'advisemod.c'\" \(7510 characters\)
- sed "s/^X//" >'advisemod.c' <<'END_OF_FILE'
- X/* Copyright (C) 1990 Keith Gabryelski (ag@amix.commodore.com)
- X
- XThis file is part of advise.
- X
- Xadvise is distributed in the hope that it will be useful,
- Xbut WITHOUT ANY WARRANTY. No author or distributor
- Xaccepts responsibility to anyone for the consequences of using it
- Xor for whether it serves any particular purpose or works at all,
- Xunless he says so in writing. Refer to the advise General Public
- XLicense for full details.
- X
- XEveryone is granted permission to copy, modify and redistribute
- Xadvise, but only under the conditions described in the
- Xadvise General Public License. A copy of this license is
- Xsupposed to have been given to you along with advise so you
- Xcan know your rights and responsibilities. It should be in a
- Xfile named COPYING. Among other things, the copyright notice
- Xand this notice must be preserved on all copies. */
- X
- X/*
- X** Author: Keith Gabryelski (ag@amix.commodore.com)
- X*/
- X
- X#ifndef sun
- X#include <sys/types.h>
- X#include <sys/param.h>
- X#include <sys/signal.h>
- X#include <sys/file.h>
- X#include <sys/user.h>
- X#include <sys/proc.h>
- X#include <sys/termios.h>
- X#include <sys/ttold.h>
- X#include <sys/cmn_err.h>
- X#include <sys/stream.h>
- X#include <sys/stropts.h>
- X#include <sys/errno.h>
- X#include <sys/debug.h>
- X#include "advise.h"
- X#include <sys/inline.h>
- X#endif /* sun */
- X
- X#ifdef i386
- X#include <sys/ddi.h>
- X
- Xint advmoddevflag = 0; /* Used by the Kernel */
- X#endif /* i386 */
- X
- Xint advisemopen(), advisemclose(), advisemput();
- X
- Xstatic struct module_info advisemiinfo =
- X{
- X 0, ADVMODNAME, 0, INFPSZ, 2048, 128,
- X};
- X
- Xstatic struct qinit advisemrinit =
- X{
- X advisemput, NULL, advisemopen, advisemclose, NULL, &advisemiinfo, NULL
- X};
- X
- Xstatic struct module_info advisemoinfo =
- X{
- X 42, ADVMODNAME, 0, INFPSZ, 300, 200,
- X};
- X
- Xstatic struct qinit advisemwinit =
- X{
- X advisemput, NULL, NULL, NULL, NULL, &advisemoinfo, NULL
- X};
- X
- X#ifdef sun
- Xstatic
- X#endif /* sun */
- Xstruct streamtab advmodinfo =
- X{
- X &advisemrinit, &advisemwinit, NULL, NULL,
- X};
- X
- X#ifdef sun
- Xstatic
- X#endif /* sun */
- Xstruct advise_state advise_table;
- X
- X
- X/*ARGSUSED*/
- Xstatic int
- Xadvisemopen(q, dev, flag, sflag
- X#ifndef sun
- X , credp
- X#endif /* !sun */
- X)
- Xregister queue_t *q;
- X#ifdef sun
- X#define DEVP dev
- X#else
- X#define DEVP *dev
- Xdev_t DEVP;
- Xcred_t *credp;
- X#endif /* !sun */
- X{
- X register struct advise_state *sp;
- X register mblk_t *bp;
- X struct advise_state *llist = &advise_table;
- X int s;
- X
- X if (sflag != MODOPEN)
- X return EINVAL;
- X
- X if ((bp = allocb((int)sizeof(struct advise_state), BPRI_MED)) == NULL)
- X {
- X return ENOMEM;
- X }
- X
- X bp->b_wptr += sizeof(struct advise_state);
- X sp = (struct advise_state *)bp->b_rptr;
- X sp->savbp = bp;
- X
- X sp->dev = DEVP;
- X sp->status = 0; /* Deny access by default */
- X sp->next = NULL;
- X sp->q_wlist = sp->q_rlist = NULL;
- X sp->q = q;
- X
- X s=spladvise();
- X while (llist->next != NULL)
- X {
- X if (llist->next->dev == DEVP)
- X {
- X /*
- X ** We are already pushed on this stream.
- X */
- X freeb(bp);
- X
- X sp = llist->next;
- X
- X break;
- X }
- X
- X llist = llist->next;
- X }
- X
- X llist->next = sp;
- X splx(s);
- X
- X q->q_ptr = (caddr_t)sp;
- X WR(q)->q_ptr = (caddr_t)sp;
- X
- X return 0;
- X}
- X
- Xstatic
- Xadvisemclose(q)
- Xregister queue_t *q;
- X{
- X register struct advise_state *sp = (struct advise_state *)q->q_ptr;
- X struct advise_state *llist = &advise_table;
- X struct advise_queue_list *qp;
- X int s;
- X
- X sp->status = 0;
- X
- X s = spladvise();
- X
- X /* unlink us from the state table */
- X
- X while (llist->next != sp)
- X llist = llist->next;
- X
- X llist->next = llist->next->next;
- X
- X /* tell each advisor that we're shutting down */
- X for (qp = sp->q_rlist; qp != NULL; qp = qp->next)
- X {
- X flushq(qp->q, FLUSHDATA);
- X putctl(qp->q->q_next, M_HANGUP);
- X }
- X for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
- X {
- X flushq(qp->q, FLUSHDATA);
- X putctl(qp->q->q_next, M_HANGUP);
- X }
- X splx(s);
- X
- X freeb(sp->savbp);
- X
- X q->q_ptr = NULL;
- X WR(q)->q_ptr = NULL;
- X}
- X
- Xstatic int
- Xadvisemput(q, mp)
- Xregister queue_t *q;
- Xregister mblk_t *mp;
- X{
- X struct advise_state *sp = (struct advise_state *)q->q_ptr;
- X register struct advise_queue_list *qp;
- X int s;
- X
- X if(q==sp->q) { /* called as read-side put proc */
- X if(mp->b_datap->db_type==M_DATA) {
- X /*
- X ** Write data to advisors.
- X */
- X s = spladvise();
- X for (qp = sp->q_rlist; qp != NULL; qp = qp->next) {
- X mblk_t *mp1 = copymsg(mp);
- X
- X if (mp1 != NULL) putnext(qp->q, mp1);
- X }
- X splx(s);
- X }
- X
- X }
- X else switch (mp->b_datap->db_type) /* called as write-side put proc */
- X {
- X case M_DATA:
- X /*
- X ** Write data to advisors.
- X */
- X s = spladvise();
- X for (qp = sp->q_wlist; qp != NULL; qp = qp->next)
- X {
- X mblk_t *mp1 = copymsg(mp);
- X
- X if (mp1 != NULL)
- X putnext(qp->q, mp1);
- X }
- X
- X splx(s);
- X break;
- X
- X#ifdef M_COPYOUT
- X case M_IOCDATA:
- X#endif /* !M_COPYOUT */
- X case M_IOCTL:
- X if (advisemsrvioc(q, mp)) /* handled? */
- X return 0;
- X break;
- X }
- X
- X putnext(q, mp);
- X
- X return 0;
- X}
- X
- Xstatic int
- Xadvisemsrvioc(q, mp)
- Xqueue_t *q;
- Xmblk_t *mp;
- X{
- X mblk_t *mp1;
- X struct iocblk *iocbp = (struct iocblk *)mp->b_rptr;
- X struct advise_state *sp = (struct advise_state *)q->q_ptr;
- X
- X#ifdef M_COPYOUT
- X if (mp->b_datap->db_type == M_IOCDATA)
- X {
- X struct copyresp *csp = (struct copyresp *)mp->b_rptr;
- X
- X switch(csp->cp_cmd)
- X {
- X case ADVISE_STATUS:
- X case ADVISE_ALLOW:
- X case ADVISE_DENY:
- X /* For copyin/copyout failures, just free message. */
- X
- X if (csp->cp_rval)
- X freemsg(mp);
- X else if (!csp->cp_private)
- X {
- X mp->b_datap->db_type = M_IOCACK;
- X freemsg(unlinkb(mp));
- X iocbp->ioc_count = 0;
- X iocbp->ioc_rval = 0;
- X iocbp->ioc_error = 0;
- X putnext(RD(q), mp);
- X }
- X
- X return 1;
- X }
- X }
- X#endif /* M_COPYOUT */
- X
- X switch (iocbp->ioc_cmd)
- X {
- X#if defined(M_COPYOUT) || defined(sun)
- X case ADVISE_STATUS:
- X {
- X int *status;
- X#ifdef M_COPYOUT
- X caddr_t arg = *(caddr_t *)mp->b_cont->b_rptr;
- X
- X freemsg(mp->b_cont);
- X#endif /* M_COPYOUT */
- X
- X mp->b_cont = allocb(sizeof(int), BPRI_MED);
- X if (!mp->b_cont)
- X {
- X mp->b_datap->db_type = M_IOCNAK;
- X freemsg(unlinkb(mp));
- X iocbp->ioc_count = 0;
- X iocbp->ioc_rval = 0;
- X iocbp->ioc_error = ENOMEM;
- X putnext(RD(q), mp);
- X return 1;
- X }
- X
- X status = (int *)mp->b_cont->b_rptr;
- X mp->b_cont->b_wptr += sizeof(int);
- X
- X *status = sp->status;
- X
- X#ifdef M_COPYOUT
- X if (mp->b_datap->db_type == M_IOCTL &&
- X iocbp->ioc_count == TRANSPARENT)
- X {
- X struct copyreq *creq = (struct copyreq *)mp->b_rptr;
- X mp->b_datap->db_type = M_COPYOUT;
- X creq->cq_addr = arg;
- X mp->b_wptr = mp->b_rptr + sizeof *creq;
- X mp->b_cont->b_wptr = mp->b_cont->b_rptr + sizeof(int);
- X creq->cq_size = sizeof(int);
- X creq->cq_flag = 0;
- X creq->cq_private = (mblk_t *)NULL;
- X putnext(RD(q), mp);
- X return 1;
- X }
- X#else /* !M_COPYOUT */
- X mp->b_datap->db_type = M_IOCACK;
- X iocbp->ioc_count = sizeof(int);
- X putnext(RD(q), mp);
- X#endif /* M_COPYOUT */
- X }
- X
- X break;
- X
- X#else /* !M_COPYOUT && !sun */
- X
- X case ADVISE_STATUS:
- X mp->b_datap->db_type = M_IOCACK;
- X mp1 = unlinkb(mp);
- X if (mp1)
- X freeb(mp1);
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X#endif /* M_COPYOUT || sun */
- X
- X case ADVISE_ALLOW:
- X sp->status |= ALLOW_ADVICE;
- X
- X mp->b_datap->db_type = M_IOCACK;
- X mp1 = unlinkb(mp);
- X if (mp1)
- X freeb(mp1);
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X
- X case ADVISE_DENY:
- X sp->status &= ~(ALLOW_ADVICE);
- X
- X mp->b_datap->db_type = M_IOCACK;
- X mp1 = unlinkb(mp);
- X if (mp1)
- X freeb(mp1);
- X iocbp->ioc_count = 0;
- X putnext(RD(q), mp);
- X break;
- X
- X default:
- X return 0;
- X }
- X
- X return 1;
- X}
- END_OF_FILE
- if test 7510 -ne `wc -c <'advisemod.c'`; then
- echo shar: \"'advisemod.c'\" unpacked with wrong size!
- fi
- # end of 'advisemod.c'
- fi
- if test ! -d 'advmod.id' ; then
- echo shar: Creating directory \"'advmod.id'\"
- mkdir 'advmod.id'
- fi
- echo shar: End of archive 1 \(of 2\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 2 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked both archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-