home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-07-25 | 105.9 KB | 4,157 lines |
- Newsgroups: comp.sources.unix
- From: mlschroe@immd4.informatik.uni-erlangen.de (Michael Schroeder)
- Subject: v26i302: screen-3.5 - screen manager with VT100/ANSI terminal emulation, V3.5, Part03/10
- Sender: unix-sources-moderator@gw.home.vix.com
- Approved: vixie@gw.home.vix.com
-
- Submitted-By: mlschroe@immd4.informatik.uni-erlangen.de (Michael Schroeder)
- Posting-Number: Volume 26, Issue 302
- Archive-Name: screen-3.5/part03
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 3 (of 10)."
- # Contents: COPYING attacher.c fileio.c help.c termcap.c utmp.c
- # Wrapped by vixie@gw.home.vix.com on Sun Jul 25 12:57:16 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'COPYING' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'COPYING'\"
- else
- echo shar: Extracting \"'COPYING'\" \(17982 characters\)
- sed "s/^X//" >'COPYING' <<'END_OF_FILE'
- X GNU GENERAL PUBLIC LICENSE
- X Version 2, June 1991
- X
- X Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- X 675 Mass Ave, Cambridge, MA 02139, USA
- X Everyone is permitted to copy and distribute verbatim copies
- X of this license document, but changing it is not allowed.
- X
- X Preamble
- X
- X The licenses for most software are designed to take away your
- Xfreedom to share and change it. By contrast, the GNU General Public
- XLicense is intended to guarantee your freedom to share and change free
- Xsoftware--to make sure the software is free for all its users. This
- XGeneral Public License applies to most of the Free Software
- XFoundation's software and to any other program whose authors commit to
- Xusing it. (Some other Free Software Foundation software is covered by
- Xthe GNU Library General Public License instead.) You can apply it to
- Xyour programs, too.
- X
- X When we speak of free software, we are referring to freedom, not
- Xprice. Our General Public Licenses are designed to make sure that you
- Xhave the freedom to distribute copies of free software (and charge for
- Xthis service if you wish), that you receive source code or can get it
- Xif you want it, that you can change the software or use pieces of it
- Xin new free programs; and that you know you can do these things.
- X
- X To protect your rights, we need to make restrictions that forbid
- Xanyone to deny you these rights or to ask you to surrender the rights.
- XThese restrictions translate to certain responsibilities for you if you
- Xdistribute copies of the software, or if you modify it.
- X
- X For example, if you distribute copies of such a program, whether
- Xgratis or for a fee, you must give the recipients all the rights that
- Xyou have. You must make sure that they, too, receive or can get the
- Xsource code. And you must show them these terms so they know their
- Xrights.
- X
- X We protect your rights with two steps: (1) copyright the software, and
- X(2) offer you this license which gives you legal permission to copy,
- Xdistribute and/or modify the software.
- X
- X Also, for each author's protection and ours, we want to make certain
- Xthat everyone understands that there is no warranty for this free
- Xsoftware. If the software is modified by someone else and passed on, we
- Xwant its recipients to know that what they have is not the original, so
- Xthat any problems introduced by others will not reflect on the original
- Xauthors' reputations.
- X
- X Finally, any free program is threatened constantly by software
- Xpatents. We wish to avoid the danger that redistributors of a free
- Xprogram will individually obtain patent licenses, in effect making the
- Xprogram proprietary. To prevent this, we have made it clear that any
- Xpatent must be licensed for everyone's free use or not licensed at all.
- X
- X The precise terms and conditions for copying, distribution and
- Xmodification follow.
- X
- X GNU GENERAL PUBLIC LICENSE
- X TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
- X
- X 0. This License applies to any program or other work which contains
- Xa notice placed by the copyright holder saying it may be distributed
- Xunder the terms of this General Public License. The "Program", below,
- Xrefers to any such program or work, and a "work based on the Program"
- Xmeans either the Program or any derivative work under copyright law:
- Xthat is to say, a work containing the Program or a portion of it,
- Xeither verbatim or with modifications and/or translated into another
- Xlanguage. (Hereinafter, translation is included without limitation in
- Xthe term "modification".) Each licensee is addressed as "you".
- X
- XActivities other than copying, distribution and modification are not
- Xcovered by this License; they are outside its scope. The act of
- Xrunning the Program is not restricted, and the output from the Program
- Xis covered only if its contents constitute a work based on the
- XProgram (independent of having been made by running the Program).
- XWhether that is true depends on what the Program does.
- X
- X 1. You may copy and distribute verbatim copies of the Program's
- Xsource code as you receive it, in any medium, provided that you
- Xconspicuously and appropriately publish on each copy an appropriate
- Xcopyright notice and disclaimer of warranty; keep intact all the
- Xnotices that refer to this License and to the absence of any warranty;
- Xand give any other recipients of the Program a copy of this License
- Xalong with the Program.
- X
- XYou may charge a fee for the physical act of transferring a copy, and
- Xyou may at your option offer warranty protection in exchange for a fee.
- X
- X 2. You may modify your copy or copies of the Program or any portion
- Xof it, thus forming a work based on the Program, and copy and
- Xdistribute such modifications or work under the terms of Section 1
- Xabove, provided that you also meet all of these conditions:
- X
- X a) You must cause the modified files to carry prominent notices
- X stating that you changed the files and the date of any change.
- X
- X b) You must cause any work that you distribute or publish, that in
- X whole or in part contains or is derived from the Program or any
- X part thereof, to be licensed as a whole at no charge to all third
- X parties under the terms of this License.
- X
- X c) If the modified program normally reads commands interactively
- X when run, you must cause it, when started running for such
- X interactive use in the most ordinary way, to print or display an
- X announcement including an appropriate copyright notice and a
- X notice that there is no warranty (or else, saying that you provide
- X a warranty) and that users may redistribute the program under
- X these conditions, and telling the user how to view a copy of this
- X License. (Exception: if the Program itself is interactive but
- X does not normally print such an announcement, your work based on
- X the Program is not required to print an announcement.)
- X
- XThese requirements apply to the modified work as a whole. If
- Xidentifiable sections of that work are not derived from the Program,
- Xand can be reasonably considered independent and separate works in
- Xthemselves, then this License, and its terms, do not apply to those
- Xsections when you distribute them as separate works. But when you
- Xdistribute the same sections as part of a whole which is a work based
- Xon the Program, the distribution of the whole must be on the terms of
- Xthis License, whose permissions for other licensees extend to the
- Xentire whole, and thus to each and every part regardless of who wrote it.
- X
- XThus, it is not the intent of this section to claim rights or contest
- Xyour rights to work written entirely by you; rather, the intent is to
- Xexercise the right to control the distribution of derivative or
- Xcollective works based on the Program.
- X
- XIn addition, mere aggregation of another work not based on the Program
- Xwith the Program (or with a work based on the Program) on a volume of
- Xa storage or distribution medium does not bring the other work under
- Xthe scope of this License.
- X
- X 3. You may copy and distribute the Program (or a work based on it,
- Xunder Section 2) in object code or executable form under the terms of
- XSections 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 Sections
- X 1 and 2 above on a medium customarily used for software interchange; or,
- X
- X b) Accompany it with a written offer, valid for at least three
- X years, to give any third party, for a charge no more than your
- X cost of physically performing source distribution, a complete
- X machine-readable copy of the corresponding source code, to be
- X distributed under the terms of Sections 1 and 2 above on a medium
- X customarily used for software interchange; or,
- X
- X c) Accompany it with the information you received as to the offer
- X to distribute corresponding source code. (This alternative is
- X allowed only for noncommercial distribution and only if you
- X received the program in object code or executable form with such
- X an offer, in accord with Subsection b above.)
- X
- XThe source code for a work means the preferred form of the work for
- Xmaking modifications to it. For an executable work, complete source
- Xcode means all the source code for all modules it contains, plus any
- Xassociated interface definition files, plus the scripts used to
- Xcontrol compilation and installation of the executable. However, as a
- Xspecial exception, the source code distributed need not include
- Xanything that is normally distributed (in either source or binary
- Xform) with the major components (compiler, kernel, and so on) of the
- Xoperating system on which the executable runs, unless that component
- Xitself accompanies the executable.
- X
- XIf distribution of executable or object code is made by offering
- Xaccess to copy from a designated place, then offering equivalent
- Xaccess to copy the source code from the same place counts as
- Xdistribution of the source code, even though third parties are not
- Xcompelled to copy the source along with the object code.
- X
- X 4. You may not copy, modify, sublicense, or distribute the Program
- Xexcept as expressly provided under this License. Any attempt
- Xotherwise to copy, modify, sublicense or distribute the Program is
- Xvoid, and will automatically terminate your rights under this License.
- XHowever, parties who have received copies, or rights, from you under
- Xthis License will not have their licenses terminated so long as such
- Xparties remain in full compliance.
- X
- X 5. You are not required to accept this License, since you have not
- Xsigned it. However, nothing else grants you permission to modify or
- Xdistribute the Program or its derivative works. These actions are
- Xprohibited by law if you do not accept this License. Therefore, by
- Xmodifying or distributing the Program (or any work based on the
- XProgram), you indicate your acceptance of this License to do so, and
- Xall its terms and conditions for copying, distributing or modifying
- Xthe Program or works based on it.
- X
- X 6. Each time you redistribute the Program (or any work based on the
- XProgram), the recipient automatically receives a license from the
- Xoriginal licensor to copy, distribute or modify the Program subject to
- Xthese terms and conditions. You may not impose any further
- Xrestrictions on the recipients' exercise of the rights granted herein.
- XYou are not responsible for enforcing compliance by third parties to
- Xthis License.
- X
- X 7. If, as a consequence of a court judgment or allegation of patent
- Xinfringement or for any other reason (not limited to patent issues),
- Xconditions are imposed on you (whether by court order, agreement or
- Xotherwise) that contradict the conditions of this License, they do not
- Xexcuse you from the conditions of this License. If you cannot
- Xdistribute so as to satisfy simultaneously your obligations under this
- XLicense and any other pertinent obligations, then as a consequence you
- Xmay not distribute the Program at all. For example, if a patent
- Xlicense would not permit royalty-free redistribution of the Program by
- Xall those who receive copies directly or indirectly through you, then
- Xthe only way you could satisfy both it and this License would be to
- Xrefrain entirely from distribution of the Program.
- X
- XIf any portion of this section is held invalid or unenforceable under
- Xany particular circumstance, the balance of the section is intended to
- Xapply and the section as a whole is intended to apply in other
- Xcircumstances.
- X
- XIt is not the purpose of this section to induce you to infringe any
- Xpatents or other property right claims or to contest validity of any
- Xsuch claims; this section has the sole purpose of protecting the
- Xintegrity of the free software distribution system, which is
- Ximplemented by public license practices. Many people have made
- Xgenerous contributions to the wide range of software distributed
- Xthrough that system in reliance on consistent application of that
- Xsystem; it is up to the author/donor to decide if he or she is willing
- Xto distribute software through any other system and a licensee cannot
- Ximpose that choice.
- X
- XThis section is intended to make thoroughly clear what is believed to
- Xbe a consequence of the rest of this License.
- X
- X 8. If the distribution and/or use of the Program is restricted in
- Xcertain countries either by patents or by copyrighted interfaces, the
- Xoriginal copyright holder who places the Program under this License
- Xmay add an explicit geographical distribution limitation excluding
- Xthose countries, so that distribution is permitted only in or among
- Xcountries not thus excluded. In such case, this License incorporates
- Xthe limitation as if written in the body of this License.
- X
- X 9. The Free Software Foundation may publish revised and/or new versions
- Xof the General Public License from time to time. Such new versions will
- Xbe similar in spirit to the present version, but may differ in detail to
- Xaddress new problems or concerns.
- X
- XEach version is given a distinguishing version number. If the Program
- Xspecifies a version number of this License which applies to it and "any
- Xlater version", you have the option of following the terms and conditions
- Xeither of that version or of any later version published by the Free
- XSoftware Foundation. If the Program does not specify a version number of
- Xthis License, you may choose any version ever published by the Free Software
- XFoundation.
- X
- X 10. If you wish to incorporate parts of the Program into other free
- Xprograms whose distribution conditions are different, write to the author
- Xto ask for permission. For software which is copyrighted by the Free
- XSoftware Foundation, write to the Free Software Foundation; we sometimes
- Xmake exceptions for this. Our decision will be guided by the two goals
- Xof preserving the free status of all derivatives of our free software and
- Xof promoting the sharing and reuse of software generally.
- X
- X NO WARRANTY
- X
- X 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
- XFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
- XOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
- XPROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
- XOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- XMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
- XTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
- XPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
- XREPAIR OR CORRECTION.
- X
- X 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
- XWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
- XREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
- XINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
- XOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
- XTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
- XYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
- XPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
- XPOSSIBILITY OF SUCH DAMAGES.
- X
- X END OF TERMS AND CONDITIONS
- X
- X Appendix: How to Apply These Terms to Your New Programs
- X
- X If you develop a new program, and you want it to be of the greatest
- Xpossible use to the public, the best way to achieve this is to make it
- Xfree software which everyone can redistribute and change under these terms.
- X
- X To do so, attach the following notices to the program. It is safest
- Xto attach them to the start of each source file to most effectively
- Xconvey the exclusion of warranty; and each file should have at least
- Xthe "copyright" line and a pointer to where the full notice is found.
- X
- X <one line to give the program's name and a brief idea of what it does.>
- X Copyright (C) 19yy <name of author>
- X
- X This program is free software; you can redistribute it and/or modify
- X it under the terms of the GNU General Public License as published by
- X the Free Software Foundation; either version 2 of the License, or
- X (at your option) any later version.
- X
- X This program is distributed in the hope that it will be useful,
- X but WITHOUT ANY WARRANTY; without even the implied warranty of
- X MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X GNU General Public License for more details.
- X
- X You should have received a copy of the GNU General Public License
- X along with this program; if not, write to the Free Software
- X Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- XAlso add information on how to contact you by electronic and paper mail.
- X
- XIf the program is interactive, make it output a short notice like this
- Xwhen it starts in an interactive mode:
- X
- X Gnomovision version 69, Copyright (C) 19yy name of author
- X Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- X This is free software, and you are welcome to redistribute it
- X under certain conditions; type `show c' for details.
- X
- XThe hypothetical commands `show w' and `show c' should show the appropriate
- Xparts of the General Public License. Of course, the commands you use may
- Xbe called something other than `show w' and `show c'; they could even be
- Xmouse-clicks or menu items--whatever suits your program.
- X
- XYou should also get your employer (if you work as a programmer) or your
- Xschool, if any, to sign a "copyright disclaimer" for the program, if
- Xnecessary. Here is a sample; alter the names:
- X
- X Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- X `Gnomovision' (which makes passes at compilers) written by James Hacker.
- X
- X <signature of Ty Coon>, 1 April 1989
- X Ty Coon, President of Vice
- X
- XThis General Public License does not permit incorporating your program into
- Xproprietary programs. If your program is a subroutine library, you may
- Xconsider it more useful to permit linking proprietary applications with the
- Xlibrary. If this is what you want to do, use the GNU Library General
- XPublic License instead of this License.
- END_OF_FILE
- if test 17982 -ne `wc -c <'COPYING'`; then
- echo shar: \"'COPYING'\" unpacked with wrong size!
- fi
- # end of 'COPYING'
- fi
- if test -f 'attacher.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'attacher.c'\"
- else
- echo shar: Extracting \"'attacher.c'\" \(18578 characters\)
- sed "s/^X//" >'attacher.c' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: attacher.c,v 1.3 1993/07/21 15:42:48 mlschroe Exp $ FAU")
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X#include <signal.h>
- X#include <pwd.h>
- X#include "config.h"
- X#include "screen.h"
- X#include "extern.h"
- X
- X#ifdef SHADOWPW
- X# include <shadow.h>
- X#endif /* SHADOWPW */
- X
- Xstatic sig_t AttacherSigInt __P(SIGPROTOARG);
- X#ifdef PASSWORD
- Xstatic void trysend __P((int, struct msg *, char *));
- X#endif
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- Xstatic sig_t AttacherWinch __P(SIGPROTOARG);
- X#endif
- X#ifdef LOCK
- Xstatic sig_t DoLock __P(SIGPROTOARG);
- Xstatic void LockTerminal __P((void));
- Xstatic sig_t LockHup __P(SIGPROTOARG);
- Xstatic void screen_builtin_lck __P((void));
- X#endif
- X#ifdef DEBUG
- Xstatic sig_t AttacherChld __P(SIGPROTOARG);
- X#endif
- X
- Xextern int real_uid, real_gid, eff_uid, eff_gid;
- Xextern char *SockName, *SockNamePtr, SockPath[];
- Xextern struct passwd *ppp;
- Xextern char *attach_tty, *attach_term, *LoginName;
- Xextern int xflag, dflag, rflag, quietflag, adaptflag;
- Xextern struct mode attach_Mode;
- Xextern int MasterPid;
- Xextern int nethackflag;
- X
- X#ifdef MULTIUSER
- Xextern char *multi;
- Xextern int multiattach, multi_uid, own_uid;
- Xextern int tty_mode, tty_oldmode;
- X# ifdef NOREUID
- Xstatic int multipipe[2];
- X# endif
- X#endif
- X
- X
- X
- X/*
- X * Send message to a screen backend.
- X * returns 1 if we could attach one, or 0 if none.
- X */
- X
- Xint
- XAttach(how)
- Xint how;
- X{
- X int lasts;
- X struct msg m;
- X struct stat st;
- X char *s;
- X
- X debug2("Attach: how=%d, tty=%s\n", how, attach_tty);
- X#ifdef MULTIUSER
- X# ifdef NOREUID
- X while ((how == MSG_ATTACH || how == MSG_CONT) && multiattach)
- X {
- X int ret;
- X
- X if (pipe(multipipe))
- X Panic(errno, "pipe");
- X eff_uid = -1; /* make UserContext fork */
- X real_uid = multi_uid;
- X if ((ret = UserContext()) <= 0)
- X {
- X char dummy;
- X eff_uid = 0;
- X real_uid = own_uid;
- X if (ret < 0)
- X Panic(errno, "UserContext");
- X close(multipipe[1]);
- X read(multipipe[0], &dummy, 1);
- X if (tty_oldmode >= 0)
- X {
- X chmod(attach_tty, tty_oldmode);
- X tty_oldmode = -1;
- X }
- X ret = UserStatus();
- X#ifdef LOCK
- X if (ret == SIG_LOCK)
- X LockTerminal();
- X else
- X#endif
- X#ifdef SIGTSTP
- X if (ret == SIG_STOP)
- X kill(getpid(), SIGTSTP);
- X else
- X#endif
- X if (ret == SIG_POWER_BYE)
- X {
- X int ppid;
- X setuid(real_uid);
- X setgid(real_gid);
- X if ((ppid = getppid()) > 1)
- X Kill(ppid, SIGHUP);
- X exit(0);
- X }
- X else
- X exit(ret);
- X dflag = 0;
- X#ifdef MULTI
- X xflag = 1;
- X#endif
- X how = MSG_ATTACH;
- X continue;
- X }
- X close(multipipe[0]);
- X eff_uid = real_uid;
- X break;
- X }
- X# else /* NOREUID */
- X if ((how == MSG_ATTACH || how == MSG_CONT) && multiattach)
- X {
- X real_uid = multi_uid;
- X eff_uid = own_uid;
- X setreuid(real_uid, eff_uid);
- X if (chmod(attach_tty, 0666))
- X Panic(errno, "chmod %s", attach_tty);
- X tty_oldmode = tty_mode;
- X }
- X# endif /* NOREUID */
- X#endif /* MULTIUSER */
- X
- X bzero((char *) &m, sizeof(m));
- X m.type = how;
- X strcpy(m.m_tty, attach_tty);
- X
- X if (how == MSG_WINCH)
- X {
- X if ((lasts = MakeClientSocket(0, SockName)) >= 0)
- X {
- X write(lasts, (char *)&m, sizeof(m));
- X close(lasts);
- X }
- X return 0;
- X }
- X
- X if (how == MSG_CONT)
- X {
- X if ((lasts = MakeClientSocket(0, SockName)) < 0)
- X {
- X Panic(0, "Sorry, cannot contact session \"%s\" again\r\n",
- X SockName ? SockName : "<NULL>");
- X }
- X }
- X else
- X {
- X switch (FindSocket(how, &lasts))
- X {
- X case 0:
- X if (rflag == 2)
- X return 0;
- X if (quietflag)
- X eexit(10);
- X Panic(0, SockName && *SockName ? "There is no screen to be %sed matching %s." : "There is no screen to be %sed.",
- X xflag ? "attach" :
- X dflag ? "detach" :
- X "resum", SockName);
- X /* NOTREACHED */
- X case 1:
- X break;
- X default:
- X Panic(0, "Type \"screen [-d] -r [pid.]tty.host\" to resume one of them.");
- X /* NOTREACHED */
- X }
- X }
- X /*
- X * Go in UserContext. Advantage is, you can kill your attacher
- X * when things go wrong. Any disadvantages? jw.
- X * Do this before the attach to prevent races!
- X */
- X#ifdef MULTIUSER
- X if (!multiattach)
- X#endif
- X setuid(real_uid);
- X#if defined(MULTIUSER) && !defined(NOREUID)
- X else
- X setreuid(eff_uid, real_uid);
- X#endif
- X setgid(real_gid);
- X
- X debug2("Attach: uid %d euid %d\n", getuid(), geteuid());
- X SockName = SockNamePtr;
- X MasterPid = 0;
- X while (*SockName)
- X {
- X if (*SockName > '9' || *SockName < '0')
- X break;
- X MasterPid = 10 * MasterPid + *SockName - '0';
- X SockName++;
- X }
- X SockName = SockNamePtr;
- X debug1("Attach decided, it is '%s'\n", SockPath);
- X debug1("Attach found MasterPid == %d\n", MasterPid);
- X if (stat(SockPath, &st) == -1)
- X Panic(errno, "stat %s", SockPath);
- X if ((st.st_mode & 0600) != 0600)
- X Panic(0, "Socket is in wrong mode (%03o)", st.st_mode);
- X if ((dflag || !xflag) && (st.st_mode & 0700) != (dflag ? 0700 : 0600))
- X Panic(0, "That screen is %sdetached.", dflag ? "already " : "not ");
- X#ifdef REMOTE_DETACH
- X if (dflag &&
- X (how == MSG_ATTACH || how == MSG_DETACH || how == MSG_POW_DETACH))
- X {
- X m.m.detach.dpid = getpid();
- X strncpy(m.m.detach.duser, LoginName, sizeof(m.m.detach.duser) - 1);
- X m.m.detach.duser[sizeof(m.m.detach.duser) - 1] = 0;
- X# ifdef POW_DETACH
- X if (dflag == 2)
- X m.type = MSG_POW_DETACH;
- X else
- X# endif
- X m.type = MSG_DETACH;
- X if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m))
- X Panic(errno, "write");
- X close(lasts);
- X if (how != MSG_ATTACH)
- X return 0; /* we detached it. jw. */
- X sleep(1); /* we dont want to overrun our poor backend. jw. */
- X if ((lasts = MakeClientSocket(0, SockName)) == -1)
- X Panic(0, "Cannot contact screen again. Shit.");
- X m.type = how;
- X }
- X#endif
- X strcpy(m.m.attach.envterm, attach_term);
- X debug1("attach: sending %d bytes... ", sizeof m);
- X
- X strncpy(m.m.attach.auser, LoginName, sizeof(m.m.attach.auser) - 1);
- X m.m.attach.auser[sizeof(m.m.attach.auser) - 1] = 0;
- X m.m.attach.apid = getpid();
- X m.m.attach.adaptflag = adaptflag;
- X m.m.attach.lines = m.m.attach.columns = 0;
- X if ((s = getenv("LINES")))
- X m.m.attach.lines = atoi(s);
- X if ((s = getenv("COLUMNS")))
- X m.m.attach.columns = atoi(s);
- X
- X#ifdef PASSWORD
- X if (how == MSG_ATTACH || how == MSG_CONT)
- X trysend(lasts, &m, m.m.attach.password);
- X else
- X#endif
- X {
- X if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m))
- X Panic(errno, "write");
- X close(lasts);
- X }
- X debug1("Attach(%d): sent\n", m.type);
- X#ifdef MULTIUSER
- X if (multi && (how == MSG_ATTACH || how == MSG_CONT))
- X {
- X# ifndef PASSWORD
- X pause();
- X# endif
- X# ifdef NOREUID
- X close(multipipe[1]);
- X# else
- X setreuid(real_uid, eff_uid);
- X if (tty_oldmode >= 0)
- X if (chmod(attach_tty, tty_oldmode))
- X Panic(errno, "chmod %s", attach_tty);
- X tty_oldmode = -1;
- X setreuid(eff_uid, real_uid);
- X# endif
- X }
- X#endif
- X rflag = 0;
- X return 1;
- X}
- X
- X
- X#ifdef PASSWORD
- X
- Xstatic trysendstatok, trysendstatfail;
- X
- Xstatic sig_t
- Xtrysendok(SIGDEFARG)
- X{
- X trysendstatok = 1;
- X}
- X
- Xstatic sig_t
- Xtrysendfail(SIGDEFARG)
- X{
- X# ifdef SYSVSIGS
- X signal(SIG_PW_FAIL, trysendfail);
- X# endif /* SYSVSIGS */
- X trysendstatfail = 1;
- X}
- X
- Xstatic char screenpw[9];
- X
- Xstatic void
- Xtrysend(fd, m, pwto)
- Xint fd;
- Xstruct msg *m;
- Xchar *pwto;
- X{
- X char *npw = NULL;
- X sig_t (*sighup)__P(SIGPROTOARG);
- X sig_t (*sigusr1)__P(SIGPROTOARG);
- X int tries;
- X
- X sigusr1 = signal(SIG_PW_OK, trysendok);
- X sighup = signal(SIG_PW_FAIL, trysendfail);
- X for (tries = 0; ; )
- X {
- X strcpy(pwto, screenpw);
- X trysendstatok = trysendstatfail = 0;
- X if (write(fd, (char *) m, sizeof(*m)) != sizeof(*m))
- X Panic(errno, "write");
- X close(fd);
- X while (trysendstatok == 0 && trysendstatfail == 0)
- X pause();
- X if (trysendstatok)
- X {
- X signal(SIG_PW_OK, sigusr1);
- X signal(SIG_PW_FAIL, sighup);
- X if (trysendstatfail)
- X kill(getpid(), SIG_PW_FAIL);
- X return;
- X }
- X if (++tries > 1 || (npw = getpass("Screen Password:")) == 0 || *npw == 0)
- X {
- X#ifdef NETHACK
- X if (nethackflag)
- X Panic(0, "The guard slams the door in your face.");
- X else
- X#endif
- X Panic(0, "Password incorrect.");
- X }
- X strncpy(screenpw, npw, 8);
- X if ((fd = MakeClientSocket(0, SockName)) == -1)
- X Panic(0, "Cannot contact screen again. Shit.");
- X }
- X}
- X#endif /* PASSWORD */
- X
- X
- X#ifdef DEBUG
- Xstatic int AttacherPanic;
- X
- Xstatic sig_t
- XAttacherChld(SIGDEFARG)
- X{
- X AttacherPanic=1;
- X#ifndef SIGVOID
- X return((sig_t) 0);
- X#endif
- X}
- X#endif
- X
- X/*
- X * the frontend's Interrupt handler
- X * we forward SIGINT to the poor backend
- X */
- Xstatic sig_t
- XAttacherSigInt(SIGDEFARG)
- X{
- X signal(SIGINT, AttacherSigInt);
- X Kill(MasterPid, SIGINT);
- X# ifndef SIGVOID
- X return (sig_t) 0;
- X# endif
- X}
- X
- X/*
- X * Unfortunatelly this is also the SIGHUP handler, so we have to
- X * check, if the backend is already detached.
- X */
- X
- Xsig_t
- XAttacherFinit(SIGDEFARG)
- X{
- X struct stat statb;
- X struct msg m;
- X int s;
- X
- X debug("AttacherFinit();\n");
- X signal(SIGHUP, SIG_IGN);
- X /* Check if signal comes from backend */
- X if (SockName)
- X {
- X strcpy(SockNamePtr, SockName);
- X if (stat(SockPath, &statb) == 0 && (statb.st_mode & 0777) != 0600)
- X {
- X debug("Detaching backend!\n");
- X bzero((char *) &m, sizeof(m));
- X strcpy(m.m_tty, attach_tty);
- X debug1("attach_tty is %s\n", attach_tty);
- X m.m.detach.dpid = getpid();
- X m.type = MSG_HANGUP;
- X if ((s = MakeClientSocket(0, SockName)) >= 0)
- X {
- X write(s, (char *)&m, sizeof(m));
- X close(s);
- X }
- X }
- X }
- X#ifdef MULTIUSER
- X if (tty_oldmode >= 0)
- X {
- X setuid(own_uid);
- X chmod(attach_tty, tty_oldmode);
- X }
- X#endif
- X exit(0);
- X#ifndef SIGVOID
- X return((sig_t) 0);
- X#endif
- X}
- X
- X#ifdef POW_DETACH
- Xstatic sig_t
- XAttacherFinitBye(SIGDEFARG)
- X{
- X int ppid;
- X debug("AttacherFintBye()\n");
- X#if defined(MULTIUSER) && defined(NOREUID)
- X if (multiattach)
- X exit(SIG_POWER_BYE);
- X#endif
- X#ifdef MULTIUSER
- X setuid(own_uid);
- X#else
- X setuid(real_uid);
- X#endif
- X setgid(real_gid);
- X /* we don't want to disturb init (even if we were root), eh? jw */
- X if ((ppid = getppid()) > 1)
- X Kill(ppid, SIGHUP); /* carefully say good bye. jw. */
- X exit(0);
- X#ifndef SIGVOID
- X return((sig_t) 0);
- X#endif
- X}
- X#endif
- X
- Xstatic int SuspendPlease;
- X
- Xstatic sig_t
- XSigStop(SIGDEFARG)
- X{
- X debug("SigStop()\n");
- X SuspendPlease = 1;
- X#ifndef SIGVOID
- X return((sig_t) 0);
- X#endif
- X}
- X
- X#ifdef LOCK
- Xstatic int LockPlease;
- X
- Xstatic sig_t
- XDoLock(SIGDEFARG)
- X{
- X# ifdef SYSVSIGS
- X signal(SIG_LOCK, DoLock);
- X# endif
- X debug("DoLock()\n");
- X LockPlease = 1;
- X# ifndef SIGVOID
- X return((sig_t) 0);
- X# endif
- X}
- X#endif
- X
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- Xstatic int SigWinchPlease;
- X
- Xstatic sig_t
- XAttacherWinch(SIGDEFARG)
- X{
- X debug("AttacherWinch()\n");
- X SigWinchPlease = 1;
- X# ifndef SIGVOID
- X return((sig_t) 0);
- X# endif
- X}
- X#endif
- X
- X
- X/*
- X * Attacher loop - no return
- X */
- X
- Xvoid
- XAttacher()
- X{
- X signal(SIGHUP, AttacherFinit);
- X signal(SIG_BYE, AttacherFinit);
- X#ifdef POW_DETACH
- X signal(SIG_POWER_BYE, AttacherFinitBye);
- X#endif
- X#ifdef LOCK
- X signal(SIG_LOCK, DoLock);
- X#endif
- X signal(SIGINT, AttacherSigInt);
- X#ifdef BSDJOBS
- X signal(SIG_STOP, SigStop);
- X#endif
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X signal(SIGWINCH, AttacherWinch);
- X#endif
- X#ifdef DEBUG
- X signal(SIGCHLD, AttacherChld);
- X#endif
- X debug("attacher: going for a nap.\n");
- X dflag = 0;
- X#ifdef MULTI
- X xflag = 1;
- X#endif
- X for (;;)
- X {
- X pause();
- X debug("attacher: huh! a signal!\n");
- X#ifdef DEBUG
- X if (AttacherPanic)
- X {
- X fcntl(0, F_SETFL, 0);
- X SetTTY(0, &attach_Mode);
- X printf("\nSuddenly the Dungeon collapses!! - You die...\n");
- X eexit(1);
- X }
- X#endif
- X#ifdef BSDJOBS
- X if (SuspendPlease)
- X {
- X SuspendPlease = 0;
- X#if defined(MULTIUSER) && defined(NOREUID)
- X if (multiattach)
- X exit(SIG_STOP);
- X#endif
- X signal(SIGTSTP, SIG_DFL);
- X debug("attacher: killing myself SIGTSTP\n");
- X kill(getpid(), SIGTSTP);
- X debug("attacher: continuing from stop\n");
- X signal(SIG_STOP, SigStop);
- X (void) Attach(MSG_CONT);
- X }
- X#endif
- X#ifdef LOCK
- X if (LockPlease)
- X {
- X LockPlease = 0;
- X#if defined(MULTIUSER) && defined(NOREUID)
- X if (multiattach)
- X exit(SIG_LOCK);
- X#endif
- X LockTerminal();
- X# ifdef SYSVSIGS
- X signal(SIG_LOCK, DoLock);
- X# endif
- X (void) Attach(MSG_CONT);
- X }
- X#endif /* LOCK */
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X if (SigWinchPlease)
- X {
- X SigWinchPlease = 0;
- X# ifdef SYSVSIGS
- X signal(SIGWINCH, AttacherWinch);
- X# endif
- X (void) Attach(MSG_WINCH);
- X }
- X#endif /* SIGWINCH */
- X }
- X}
- X
- X#ifdef LOCK
- X
- X/* ADDED by Rainer Pruy 10/15/87 */
- X/* POLISHED by mls. 03/10/91 */
- X
- Xstatic char LockEnd[] = "Welcome back to screen !!\n";
- X
- Xstatic sig_t
- XLockHup(SIGDEFARG)
- X{
- X int ppid = getppid();
- X setuid(real_uid);
- X setgid(real_gid);
- X if (ppid > 1)
- X Kill(ppid, SIGHUP);
- X exit(0);
- X}
- X
- Xstatic void
- XLockTerminal()
- X{
- X char *prg;
- X int sig, pid;
- X sig_t (*sigs[NSIG])__P(SIGPROTOARG);
- X
- X for (sig = 1; sig < NSIG; sig++)
- X {
- X sigs[sig] = signal(sig, SIG_IGN);
- X }
- X signal(SIGHUP, LockHup);
- X printf("\n");
- X
- X prg = getenv("LOCKPRG");
- X if (prg && strcmp(prg, "builtin") && !access(prg, X_OK))
- X {
- X signal(SIGCHLD, SIG_DFL);
- X debug1("lockterminal: '%s' seems executable, execl it!\n", prg);
- X if ((pid = fork()) == 0)
- X {
- X /* Child */
- X setuid(real_uid); /* this should be done already */
- X setgid(real_gid);
- X closeallfiles(0); /* important: /etc/shadow may be open */
- X execl(prg, "SCREEN-LOCK", NULL);
- X exit(errno);
- X }
- X if (pid == -1)
- X {
- X#ifdef NETHACK
- X if (nethackflag)
- X Msg(errno, "Cannot fork terminal - lock failed");
- X else
- X#endif
- X Msg(errno, "Cannot lock terminal - fork failed");
- X }
- X else
- X {
- X#ifdef BSDWAIT
- X union wait wstat;
- X#else
- X int wstat;
- X#endif
- X int wret;
- X
- X#ifdef hpux
- X signal(SIGCHLD, SIG_DFL);
- X#endif
- X errno = 0;
- X while (((wret = wait(&wstat)) != pid) ||
- X ((wret == -1) && (errno == EINTR))
- X )
- X errno = 0;
- X
- X if (errno)
- X {
- X Msg(errno, "Lock");
- X sleep(2);
- X }
- X else if (WTERMSIG(wstat) != 0)
- X {
- X fprintf(stderr, "Lock: %s: Killed by signal: %d%s\n", prg,
- X WTERMSIG(wstat), WIFCORESIG(wstat) ? " (Core dumped)" : "");
- X sleep(2);
- X }
- X else if (WEXITSTATUS(wstat))
- X {
- X debug2("Lock: %s: return code %d\n", prg, WEXITSTATUS(wstat));
- X }
- X else
- X printf(LockEnd);
- X }
- X }
- X else
- X {
- X if (prg)
- X {
- X debug1("lockterminal: '%s' seems NOT executable, we use our builtin\n", prg);
- X }
- X else
- X {
- X debug("lockterminal: using buitin.\n");
- X }
- X screen_builtin_lck();
- X }
- X /* reset signals */
- X for (sig = 1; sig < NSIG; sig++)
- X {
- X if (sigs[sig] != (sig_t(*)__P(SIGPROTOARG)) -1)
- X signal(sig, sigs[sig]);
- X }
- X} /* LockTerminal */
- X
- X/* -- original copyright by Luigi Cannelloni 1985 (luigi@faui70.UUCP) -- */
- Xstatic void
- Xscreen_builtin_lck()
- X{
- X char fullname[100], *cp1, message[BUFSIZ];
- X char c, *pass, mypass[9];
- X#ifdef SHADOWPW
- X struct spwd *sss = NULL;
- X#endif
- X int t;
- X
- X#ifdef undef
- X /* get password entry */
- X if ((ppp = getpwuid(real_uid)) == NULL)
- X {
- X fprintf(stderr, "screen_builtin_lck: No passwd entry.\007\n");
- X sleep(2);
- X return;
- X }
- X if (!isatty(0))
- X {
- X fprintf(stderr, "screen_builtin_lck: Not a tty.\007\n");
- X sleep(2);
- X return;
- X }
- X#endif
- X pass = ppp->pw_passwd;
- X#ifdef SHADOWPW
- Xrealpw:
- X#endif /* SHADOWPW */
- X for (t = 0; t < 13; t++)
- X {
- X c = pass[t];
- X if (!(c == '.' || c == '/' ||
- X (c >= '0' && c <= '9') ||
- X (c >= 'a' && c <= 'z') ||
- X (c >= 'A' && c <= 'Z')))
- X break;
- X }
- X if (t < 13)
- X {
- X debug("builtin_lock: ppp->pw_passwd bad, has it a shadow?\n");
- X#ifdef SHADOWPW
- X setspent(); /* rewind shadow file */
- X if ((sss == NULL) && (sss = getspnam(ppp->pw_name)))
- X {
- X pass = sss->sp_pwdp;
- X goto realpw;
- X }
- X#endif /* SHADOWPW */
- X if ((pass = getpass("Key: ")))
- X {
- X strncpy(mypass, pass, 8);
- X mypass[8] = 0;
- X if (*mypass == 0)
- X return;
- X if ((pass = getpass("Again: ")))
- X {
- X if (strcmp(mypass, pass))
- X {
- X fprintf(stderr, "Passwords don't match.\007\n");
- X sleep(2);
- X return;
- X }
- X }
- X }
- X if (pass == 0)
- X {
- X fprintf(stderr, "Getpass error.\007\n");
- X sleep(2);
- X return;
- X }
- X pass = 0;
- X }
- X
- X debug("screen_builtin_lck looking in gcos field\n");
- X strcpy(fullname, ppp->pw_gecos);
- X if ((cp1 = index(fullname, ',')) != NULL)
- X *cp1 = '\0';
- X if ((cp1 = index(fullname, '&')) != NULL)
- X {
- X sprintf(cp1, "%s", ppp->pw_name);
- X if (*cp1 >= 'a' && *cp1 <= 'z')
- X *cp1 -= 'a' - 'A';
- X }
- X
- X sprintf(message, "Screen used by %s <%s>.\nPassword:\007",
- X fullname, ppp->pw_name);
- X
- X /* loop here to wait for correct password */
- X for (;;)
- X {
- X debug("screen_builtin_lck awaiting password\n");
- X errno = 0;
- X if ((cp1 = getpass(message)) == NULL)
- X {
- X AttacherFinit(SIGARG);
- X /* NOTREACHED */
- X }
- X debug3("getpass(%d): %x == %s\n", errno, (unsigned int)cp1, cp1);
- X if (pass)
- X {
- X if (!strcmp(crypt(cp1, pass), pass))
- X break;
- X }
- X else
- X {
- X if (!strcmp(cp1, mypass))
- X break;
- X }
- X debug("screen_builtin_lck: NO!!!!!\n");
- X }
- X debug("password ok.\n");
- X}
- X
- X#endif /* LOCK */
- END_OF_FILE
- if test 18578 -ne `wc -c <'attacher.c'`; then
- echo shar: \"'attacher.c'\" unpacked with wrong size!
- fi
- # end of 'attacher.c'
- fi
- if test -f 'fileio.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'fileio.c'\"
- else
- echo shar: Extracting \"'fileio.c'\" \(15658 characters\)
- sed "s/^X//" >'fileio.c' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: fileio.c,v 1.2 1993/06/23 17:46:30 jnweiger Exp $ FAU")
- X
- X
- X#include <sys/types.h>
- X#ifndef sgi
- X# include <sys/file.h>
- X#endif /* sgi */
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X
- X#include <signal.h>
- X
- X#include "config.h"
- X#include "screen.h"
- X#include "extern.h"
- X
- X#ifdef NETHACK
- Xextern nethackflag;
- X#endif
- X
- Xextern struct display *display;
- Xextern struct win *fore;
- Xextern int real_uid, eff_uid;
- Xextern int real_gid, eff_gid;
- Xextern char *extra_incap, *extra_outcap;
- Xextern char *home, *RcFileName;
- Xextern char SockPath[], *SockNamePtr;
- X#ifdef COPY_PASTE
- Xextern char *BufferFile;
- X#endif
- Xextern int hardcopy_append;
- Xextern char *hardcopydir;
- X
- Xstatic char *CatExtra __P((char *, char *));
- X
- X
- Xstatic FILE *fp = NULL;
- Xchar *rc_name;
- X
- Xstatic char *
- XCatExtra(str1, str2)
- Xregister char *str1, *str2;
- X{
- X register char *cp;
- X register int len1, len2, add_colon;
- X
- X len1 = strlen(str1);
- X if (len1 == 0)
- X return(str2);
- X add_colon = (str1[len1 - 1] != ':');
- X if (str2)
- X {
- X len2 = strlen(str2);
- X if ((cp = realloc(str2, (unsigned) len1 + len2 + add_colon + 1)) == NULL)
- X Panic(0, strnomem);
- X bcopy(cp, cp + len1 + add_colon, len2 + 1);
- X }
- X else
- X {
- X if (len1 == 0)
- X return 0;
- X if ((cp = malloc((unsigned) len1 + add_colon + 1)) == NULL)
- X Panic(0, strnomem);
- X cp[len1 + add_colon] = '\0';
- X }
- X bcopy(str1, cp, len1);
- X if (add_colon)
- X cp[len1] = ':';
- X
- X return cp;
- X}
- X
- Xstatic char *
- Xfindrcfile(rcfile)
- Xchar *rcfile;
- X{
- X static char buf[256];
- X char *rc, *p;
- X
- X if (rcfile)
- X {
- X rc = SaveStr(rcfile);
- X debug1("findrcfile: you specified '%s'\n", rcfile);
- X }
- X else
- X {
- X debug("findrcfile: you specified nothing...\n");
- X if ((p = getenv("ISCREENRC")) != NULL && *p != '\0')
- X {
- X debug1(" ... but $ISCREENRC has: '%s'\n", p);
- X rc = SaveStr(p);
- X }
- X else if ((p = getenv("SCREENRC")) != NULL && *p != '\0')
- X {
- X debug1(" ... but $SCREENRC has: '%s'\n", p);
- X rc = SaveStr(p);
- X }
- X else
- X {
- X debug(" ...nothing in $SCREENRC, defaulting $HOME/.screenrc\n");
- X if (strlen(home) > 244)
- X Panic(0, "Rc: home too large");
- X sprintf(buf, "%s/.iscreenrc", home);
- X if (access(buf, R_OK))
- X sprintf(buf, "%s/.screenrc", home);
- X rc = SaveStr(buf);
- X }
- X }
- X return rc;
- X}
- X
- X/*
- X * this will be called twice:
- X * 1) rcfilename = "/etc/screenrc"
- X * 2) rcfilename = RcFileName
- X */
- Xvoid
- XStartRc(rcfilename)
- Xchar *rcfilename;
- X{
- X register int argc, len;
- X register char *p, *cp;
- X char buf[256];
- X char *args[MAXARGS];
- X
- X rc_name = findrcfile(rcfilename);
- X
- X if ((fp = secfopen(rc_name, "r")) == NULL)
- X {
- X if (RcFileName && strcmp(RcFileName, rc_name) == 0)
- X {
- X /*
- X * User explicitly gave us that name,
- X * this is the only case, where we get angry, if we can't read
- X * the file.
- X */
- X debug3("StartRc: '%s','%s', '%s'\n", RcFileName, rc_name, rcfilename);
- X Panic(0, "Unable to open \"%s\".", rc_name);
- X /* NOTREACHED */
- X }
- X debug1("StartRc: '%s' no good. ignored\n", rc_name);
- X Free(rc_name);
- X rc_name = "";
- X return;
- X }
- X while (fgets(buf, sizeof buf, fp) != NULL)
- X {
- X if ((p = rindex(buf, '\n')) != NULL)
- X *p = '\0';
- X if ((argc = Parse(buf, args)) == 0)
- X continue;
- X if (strcmp(args[0], "echo") == 0)
- X {
- X if (!display)
- X continue;
- X if (argc < 2 || (argc == 3 && strcmp(args[1], "-n")) || argc > 3)
- X {
- X Msg(0, "%s: 'echo [-n] \"string\"' expected.", rc_name);
- X continue;
- X }
- X AddStr(args[argc - 1]);
- X if (argc != 3)
- X {
- X AddStr("\r\n");
- X Flush();
- X }
- X }
- X else if (strcmp(args[0], "sleep") == 0)
- X {
- X if (!display)
- X continue;
- X debug("sleeeeeeep\n");
- X if (argc != 2)
- X {
- X Msg(0, "%s: sleep: one numeric argument expected.", rc_name);
- X continue;
- X }
- X DisplaySleep(atoi(args[1]));
- X }
- X#ifdef TERMINFO
- X else if (strcmp(args[0], "terminfo") == 0)
- X#else
- X else if (strcmp(args[0], "termcap") == 0)
- X#endif
- X {
- X if (!display)
- X continue;
- X if (argc < 3 || argc > 4)
- X {
- X Msg(0, "%s: %s: incorrect number of arguments.", rc_name, args[0]);
- X continue;
- X }
- X for (p = args[1]; p && *p; p = cp)
- X {
- X if ((cp = index(p, '|')) != 0)
- X *cp++ = '\0';
- X len = strlen(p);
- X if (p[len - 1] == '*')
- X {
- X if (!(len - 1) || !strncmp(p, d_termname, len - 1))
- X break;
- X }
- X else if (!strcmp(p, d_termname))
- X break;
- X }
- X if (!(p && *p))
- X continue;
- X extra_incap = CatExtra(args[2], extra_incap);
- X if (argc == 4)
- X extra_outcap = CatExtra(args[3], extra_outcap);
- X }
- X }
- X fclose(fp);
- X Free(rc_name);
- X rc_name = "";
- X}
- X
- Xvoid
- XFinishRc(rcfilename)
- Xchar *rcfilename;
- X{
- X char buf[256];
- X
- X rc_name = findrcfile(rcfilename);
- X
- X if ((fp = secfopen(rc_name, "r")) == NULL)
- X {
- X if (RcFileName && strcmp(RcFileName, rc_name) == 0)
- X {
- X /*
- X * User explicitly gave us that name,
- X * this is the only case, where we get angry, if we can't read
- X * the file.
- X */
- X debug3("FinishRc:'%s','%s','%s'\n", RcFileName, rc_name, rcfilename);
- X Panic(0, "Unable to open \"%s\".", rc_name);
- X /* NOTREACHED */
- X }
- X debug1("FinishRc: '%s' no good. ignored\n", rc_name);
- X Free(rc_name);
- X rc_name = "";
- X return;
- X }
- X
- X debug("finishrc is going...\n");
- X while (fgets(buf, sizeof buf, fp) != NULL)
- X {
- X RcLine(buf);
- X }
- X (void) fclose(fp);
- X Free(rc_name);
- X rc_name = "";
- X}
- X
- X/*
- X * "$HOST blafoo" -> "localhost blafoo"
- X * "${HOST}blafoo" -> "localhostblafoo"
- X * "\$HOST blafoo" -> "$HOST blafoo"
- X * "\\$HOST blafoo" -> "\localhost blafoo"
- X * "'$HOST ${HOST}'" -> "'$HOST ${HOST}'"
- X * "'\$HOST'" -> "'\$HOST'"
- X * "\'$HOST' $HOST" -> "'localhost' $HOST"
- X *
- X * "$:termcapname:" -> "termcapvalue"
- X * "$:terminfoname:" -> "termcapvalue"
- X *
- X * "\101" -> "A"
- X */
- Xchar *
- Xexpand_vars(ss)
- Xchar *ss;
- X{
- X static char ebuf[2048];
- X register int esize = 2047, vtype, quofl = 0;
- X register char *e = ebuf;
- X register char *s = ss;
- X register char *v;
- X char xbuf[11];
- X
- X while (*s && *s != '\0' && *s != '\n' && esize > 0)
- X {
- X if (*s == '\'')
- X quofl ^= 1;
- X if (*s == '$' && !quofl)
- X {
- X char *p, c;
- X
- X p = ++s;
- X switch (*s)
- X {
- X case '{':
- X p = ++s;
- X while (*p != '}')
- X if (*p++ == '\0')
- X return ss;
- X vtype = 0; /* env var */
- X break;
- X case ':':
- X p = ++s;
- X while (*p != ':')
- X if (*p++ == '\0')
- X return ss;
- X vtype = 1; /* termcap string */
- X break;
- X default:
- X while (*p != ' ' && *p != '\0' && *p != '\n')
- X p++;
- X vtype = 0; /* env var */
- X }
- X c = *p;
- X debug1("exp: c='%c'\n", c);
- X *p = '\0';
- X if (vtype == 0)
- X {
- X v = xbuf;
- X if (strcmp(s, "TERM") == 0)
- X v = display ? d_termname : "unknown";
- X else if (strcmp(s, "COLUMNS") == 0)
- X sprintf(xbuf, "%d", display ? d_width : -1);
- X else if (strcmp(s, "LINES") == 0)
- X sprintf(xbuf, "%d", display ? d_height : -1);
- X else
- X v = getenv(s);
- X }
- X else
- X v = gettermcapstring(s);
- X if (v)
- X {
- X debug2("exp: $'%s'='%s'\n", s, v);
- X while (*v && esize-- > 0)
- X *e++ = *v++;
- X }
- X else
- X debug1("exp: '%s' not env\n", s); /* {-: */
- X if ((*p = c) == '}' || c == ':')
- X p++;
- X s = p;
- X }
- X else
- X {
- X /*
- X * \$, \\$, \\, \\\, \012 are reduced here,
- X * d_other sequences starting whith \ are passed through.
- X */
- X if (s[0] == '\\' && !quofl)
- X {
- X if (s[1] >= '0' && s[1] <= '7')
- X {
- X int i;
- X
- X s++;
- X i = *s - '0';
- X s++;
- X if (*s >= '0' && *s <= '7')
- X {
- X i = i * 8 + *s - '0';
- X s++;
- X if (*s >= '0' && *s <= '7')
- X {
- X i = i * 8 + *s - '0';
- X s++;
- X }
- X }
- X debug2("expandvars: octal coded character %o (%d)\n", i, i);
- X *e++ = i;
- X }
- X else
- X {
- X if (s[1] == '$' ||
- X (s[1] == '\\' && s[2] == '$') ||
- X s[1] == '\'' ||
- X (s[1] == '\\' && s[2] == '\''))
- X s++;
- X }
- X }
- X *e++ = *s++;
- X esize--;
- X }
- X }
- X if (esize <= 0)
- X Msg(0, "expand_vars: buffer overflow\n");
- X *e = '\0';
- X return ebuf;
- X}
- X
- Xvoid
- XRcLine(ubuf)
- Xchar *ubuf;
- X{
- X char *args[MAXARGS], *buf;
- X struct action act;
- X
- X buf = expand_vars(ubuf);
- X if (Parse(buf, args) <= 0)
- X return;
- X if ((act.nr = FindCommnr(*args)) == RC_ILLEGAL)
- X {
- X Msg(0, "%s: unknown command '%s'", rc_name, *args);
- X return;
- X }
- X act.args = args + 1;
- X DoAction(&act, -1);
- X}
- X
- X
- Xvoid
- XWriteFile(dump)
- Xint dump;
- X{
- X /* dump==0: create .termcap,
- X * dump==1: hardcopy,
- X * #ifdef COPY_PASTE
- X * dump==2: BUFFERFILE
- X * #endif COPY_PASTE
- X */
- X register int i, j, k;
- X register char *p;
- X register FILE *f;
- X char fn[1024];
- X char *mode = "w";
- X
- X switch (dump)
- X {
- X case DUMP_TERMCAP:
- X i = SockNamePtr - SockPath;
- X strncpy(fn, SockPath, i);
- X strcpy(fn + i, ".termcap");
- X break;
- X case DUMP_HARDCOPY:
- X if (hardcopydir)
- X sprintf(fn, "%s/hardcopy.%d", hardcopydir, fore->w_number);
- X else
- X sprintf(fn, "hardcopy.%d", fore->w_number);
- X if (hardcopy_append && !access(fn, W_OK))
- X mode = "a";
- X break;
- X#ifdef COPY_PASTE
- X case DUMP_EXCHANGE:
- X sprintf(fn, "%s", BufferFile);
- X umask(0);
- X break;
- X#endif
- X }
- X
- X debug2("WriteFile(%d) %s\n", dump, fn);
- X if (UserContext() > 0)
- X {
- X debug("Writefile: usercontext\n");
- X if ((f = fopen(fn, mode)) == NULL)
- X {
- X debug2("WriteFile: fopen(%s,\"%s\") failed\n", fn, mode);
- X UserReturn(0);
- X }
- X else
- X {
- X switch (dump)
- X {
- X case DUMP_HARDCOPY:
- X if (*mode == 'a')
- X {
- X putc('>', f);
- X for (j = d_width - 2; j > 0; j--)
- X putc('=', f);
- X fputs("<\n", f);
- X }
- X for (i = 0; i < d_height; i++)
- X {
- X p = fore->w_image[i];
- X for (k = d_width - 1; k >= 0 && p[k] == ' '; k--)
- X ;
- X for (j = 0; j <= k; j++)
- X putc(p[j], f);
- X putc('\n', f);
- X }
- X break;
- X case DUMP_TERMCAP:
- X if ((p = index(MakeTermcap(fore->w_aflag), '=')) != NULL)
- X {
- X fputs(++p, f);
- X putc('\n', f);
- X }
- X break;
- X#ifdef COPY_PASTE
- X case DUMP_EXCHANGE:
- X p = d_copybuffer;
- X for (i = 0; i < d_copylen; i++)
- X putc(*p++, f);
- X break;
- X#endif
- X }
- X (void) fclose(f);
- X UserReturn(1);
- X }
- X }
- X if (UserStatus() <= 0)
- X Msg(0, "Cannot open \"%s\"", fn);
- X else
- X {
- X switch (dump)
- X {
- X case DUMP_TERMCAP:
- X Msg(0, "Termcap entry written to \"%s\".", fn);
- X break;
- X case DUMP_HARDCOPY:
- X Msg(0, "Screen image %s to \"%s\".",
- X (*mode == 'a') ? "appended" : "written", fn);
- X break;
- X#ifdef COPY_PASTE
- X case DUMP_EXCHANGE:
- X Msg(0, "Copybuffer written to \"%s\".", fn);
- X#endif
- X }
- X }
- X}
- X
- X#ifdef COPY_PASTE
- X
- Xvoid
- XReadFile()
- X{
- X int i, l, size;
- X char fn[1024], c;
- X struct stat stb;
- X
- X sprintf(fn, "%s", BufferFile);
- X debug1("ReadFile(%s)\n", fn);
- X if ((i = secopen(fn, O_RDONLY, 0)) < 0)
- X {
- X Msg(errno, "no %s -- no slurp", fn);
- X return;
- X }
- X if (fstat(i, &stb))
- X {
- X Msg(errno, "no good %s -- no slurp", fn);
- X close(i);
- X return;
- X }
- X size = stb.st_size;
- X if (d_copybuffer)
- X free(d_copybuffer);
- X d_copylen = 0;
- X if ((d_copybuffer = malloc(size)) == NULL)
- X {
- X close(i);
- X Msg(0, strnomem);
- X return;
- X }
- X errno = 0;
- X if ((l = read(i, d_copybuffer, size)) != size)
- X {
- X d_copylen = (l > 0) ? l : 0;
- X#ifdef NETHACK
- X if (nethackflag)
- X Msg(errno, "You choke on your food: %d bytes", d_copylen);
- X else
- X#endif
- X Msg(errno, "Got only %d bytes from %s", d_copylen, fn);
- X close(i);
- X return;
- X }
- X d_copylen = l;
- X if (read(i, &c, 1) > 0)
- X Msg(0, "Slurped only %d characters into buffer - try again", d_copylen);
- X else
- X Msg(0, "Slurped %d characters into buffer", d_copylen);
- X close(i);
- X return;
- X}
- X
- Xvoid
- XKillBuffers()
- X{
- X char fn[1024];
- X sprintf(fn, "%s", BufferFile);
- X errno = 0;
- X#ifndef NOREUID
- X setreuid(eff_uid, real_uid);
- X setregid(eff_gid, real_gid);
- X#else
- X if (access(fn, W_OK) == -1)
- X {
- X Msg(errno, "%s not removed", fn);
- X return;
- X }
- X#endif
- X unlink(fn);
- X Msg(errno, "%s removed", fn);
- X#ifndef NOREUID
- X setreuid(real_uid, eff_uid);
- X setregid(real_gid, eff_gid);
- X#endif
- X}
- X#endif /* COPY_PASTE */
- X
- X
- X/*
- X * (Almost) secure open and fopen...
- X */
- X
- XFILE *
- Xsecfopen(name, mode)
- Xchar *name;
- Xchar *mode;
- X{
- X FILE *fi;
- X#ifdef NOREUID
- X int flags, fd;
- X#endif
- X
- X debug2("secfopen(%s, %s)\n", name, mode);
- X#ifndef NOREUID
- X setreuid(eff_uid, real_uid);
- X setregid(eff_gid, real_gid);
- X fi = fopen(name, mode);
- X setreuid(real_uid, eff_uid);
- X setregid(real_gid, eff_gid);
- X return fi;
- X#else
- X if (eff_uid == real_uid)
- X return(fopen(name, mode));
- X if (mode[0] && mode[1] == '+')
- X flags = O_RDWR;
- X else
- X flags = (mode[0] == 'r') ? O_RDONLY : O_WRONLY;
- X if (mode[0] == 'w')
- X flags |= O_CREAT | O_TRUNC;
- X else if (mode[0] == 'a')
- X flags |= O_CREAT | O_APPEND;
- X else if (mode[0] != 'r')
- X {
- X errno = EINVAL;
- X return(0);
- X }
- X if ((fd = secopen(name, flags, 0666)) < 0)
- X return(0);
- X if ((fi = fdopen(fd, mode)) == 0)
- X {
- X close(fd);
- X return(0);
- X }
- X return(fi);
- X#endif
- X}
- X
- X
- Xint
- Xsecopen(name, flags, mode)
- Xchar *name;
- Xint flags;
- Xint mode;
- X{
- X int fd;
- X#ifdef NOREUID
- X int q;
- X struct stat stb;
- X#endif
- X
- X debug3("secopen(%s, 0x%x, 0%03o)\n", name, flags, mode);
- X#ifndef NOREUID
- X setreuid(eff_uid, real_uid);
- X setregid(eff_gid, real_gid);
- X fd = open(name, flags, mode);
- X setreuid(real_uid, eff_uid);
- X setregid(real_gid, eff_gid);
- X return fd;
- X#else
- X if (eff_uid == real_uid)
- X return(open(name, flags, mode));
- X /* Truncation/creation is done in UserContext */
- X if ((flags & O_TRUNC) || ((flags & O_CREAT) && access(name, F_OK)))
- X {
- X if (UserContext() > 0)
- X {
- X if ((fd = open(name, flags, mode)) >= 0)
- X {
- X close(fd);
- X UserReturn(0);
- X }
- X if (errno == 0)
- X errno = EACCES;
- X UserReturn(errno);
- X }
- X if (q = UserStatus())
- X {
- X if (q > 0)
- X errno = q;
- X return(-1);
- X }
- X }
- X if (access(name, F_OK))
- X return(-1);
- X if ((fd = open(name, flags & ~(O_TRUNC | O_CREAT), 0)) < 0)
- X return(-1);
- X debug("open successful\n");
- X if (fstat(fd, &stb))
- X {
- X close(fd);
- X return(-1);
- X }
- X debug("fstat successful\n");
- X if (stb.st_uid != real_uid)
- X {
- X switch (flags & (O_RDONLY | O_WRONLY | O_RDWR))
- X {
- X case O_RDONLY:
- X q = 0004;
- X break;
- X case O_WRONLY:
- X q = 0002;
- X break;
- X default:
- X q = 0006;
- X break;
- X }
- X if ((stb.st_mode & q) != q)
- X {
- X debug("secopen: permission denied\n");
- X close(fd);
- X errno = EACCES;
- X return(-1);
- X }
- X }
- X debug1("secopen ok - returning %d\n", fd);
- X return(fd);
- X#endif
- X}
- END_OF_FILE
- if test 15658 -ne `wc -c <'fileio.c'`; then
- echo shar: \"'fileio.c'\" unpacked with wrong size!
- fi
- # end of 'fileio.c'
- fi
- if test -f 'help.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'help.c'\"
- else
- echo shar: Extracting \"'help.c'\" \(15096 characters\)
- sed "s/^X//" >'help.c' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: help.c,v 1.1.1.1 1993/06/16 23:51:12 jnweiger Exp $ FAU")
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X
- X#include "config.h"
- X
- X#include "screen.h"
- X#include "extern.h"
- X
- Xchar version[40]; /* initialised by main() */
- Xextern char Esc, MetaEsc;
- Xextern struct display *display;
- Xextern char *noargs[];
- X
- X
- Xvoid
- Xexit_with_usage(myname)
- Xchar *myname;
- X{
- X printf("Use: %s [-opts] [cmd [args]]\n", myname);
- X printf(" or: %s -r [host.tty]\n\nOptions:\n", myname);
- X printf("-a Force all capabilities into each window's termcap.\n");
- X printf("-A -[r|R] Adapt all windows to the new display width & height.\n");
- X printf("-c file Read configuration file instead of '.screenrc'.\n");
- X#ifdef REMOTE_DETACH
- X printf("-d (-r) Detach the elsewhere running screen (and reattach here).\n");
- X printf("-D (-r) Detach and logout remote (and reattach here).\n");
- X#endif
- X printf("-e xy Change command characters.\n");
- X printf("-f Flow control on, -fn = off, -fa = auto.\n");
- X printf("-h lines Set the size of the scrollback history buffer.\n");
- X printf("-i Interrupt output sooner when flow control is on.\n");
- X printf("-l Login mode on (update %s), -ln = off.\n", UTMPFILE);
- X printf("-list or -ls. Do nothing, just list our SockDir.\n");
- X printf("-L Terminal's last character can be safely updated.\n");
- X printf("-m ignore $STY variable, do create a new screen session.\n");
- X printf("-O Choose optimal output rather than exact vt100 emulation.\n");
- X printf("-q Quiet startup. Exits with non-zero return code if unsuccessful.\n");
- X printf("-r Reattach to a detached screen process.\n");
- X printf("-R Reattach if possible, otherwise start a new session.\n");
- X printf("-s shell Shell to execute rather than $SHELL.\n");
- X printf("-S sockname Name this session <pid>.sockname instead of <pid>.<tty>.<host>.\n");
- X printf("-t title Set command's a.k.a. (window title).\n");
- X printf("-T term Use term as $TERM for windows, rather than \"screen\".\n");
- X printf("-v Print \"Screen version %s\".\n", version);
- X printf("-wipe Do nothing, just clean up SockDir.\n");
- X#ifdef MULTI
- X printf("-x Attach to a not detached screen. (Multi display mode).\n");
- X#endif /* MULTI */
- X exit(1);
- X}
- X
- X
- X/*
- X** Here come the help page routines
- X*/
- X
- Xextern struct comm comms[];
- Xextern struct action ktab[];
- X
- Xstatic void HelpProcess __P((char **, int *));
- Xstatic void HelpAbort __P((void));
- Xstatic void HelpRedisplayLine __P((int, int, int, int));
- Xstatic void HelpSetCursor __P((void));
- Xstatic void add_key_to_buf __P((char *, int));
- Xstatic int helppage __P((void));
- X
- Xstruct helpdata
- X{
- X int maxrow, grow, numcols, numrows, num_names;
- X int numskip, numpages;
- X int command_search, command_bindings;
- X int refgrow, refcommand_search;
- X int inter, mcom, mkey;
- X int nact[RC_LAST + 1];
- X};
- X
- X#define MAXKLEN 256
- X
- Xstatic struct LayFuncs HelpLf =
- X{
- X HelpProcess,
- X HelpAbort,
- X HelpRedisplayLine,
- X DefClearLine,
- X DefRewrite,
- X HelpSetCursor,
- X DefResize,
- X DefRestore
- X};
- X
- X
- Xvoid
- Xdisplay_help()
- X{
- X int i, n, key, mcom, mkey, l;
- X struct helpdata *helpdata;
- X int used[RC_LAST + 1];
- X
- X if (d_height < 6)
- X {
- X Msg(0, "Window height too small for help page");
- X return;
- X }
- X if (InitOverlayPage(sizeof(*helpdata), &HelpLf, 0))
- X return;
- X
- X helpdata = (struct helpdata *)d_lay->l_data;
- X helpdata->num_names = helpdata->command_bindings = 0;
- X helpdata->command_search = 0;
- X for (n = 0; n <= RC_LAST; n++)
- X used[n] = 0;
- X mcom = 0;
- X mkey = 0;
- X for (key = 0; key < 256; key++)
- X {
- X n = ktab[key].nr;
- X if (n == RC_ILLEGAL)
- X continue;
- X if (ktab[key].args == noargs)
- X {
- X used[n] += (key <= ' ' || key == 0x7f) ? 3 :
- X (key > 0x7f) ? 5 : 2;
- X }
- X else
- X helpdata->command_bindings++;
- X }
- X for (n = i = 0; n <= RC_LAST; n++)
- X if (used[n])
- X {
- X l = strlen(comms[n].name);
- X if (l > mcom)
- X mcom = l;
- X if (used[n] > mkey)
- X mkey = used[n];
- X helpdata->nact[i++] = n;
- X }
- X debug1("help: %d commands bound to keys with no arguments\n", i);
- X debug2("mcom: %d mkey: %d\n", mcom, mkey);
- X helpdata->num_names = i;
- X
- X if (mkey > MAXKLEN)
- X mkey = MAXKLEN;
- X helpdata->numcols = (d_width - !CLP)/(mcom + mkey + 1);
- X if (helpdata->numcols == 0)
- X {
- X HelpAbort();
- X Msg(0, "Width too small");
- X return;
- X }
- X helpdata->inter = (d_width - !CLP - (mcom + mkey) * helpdata->numcols) / (helpdata->numcols + 1);
- X if (helpdata->inter <= 0)
- X helpdata->inter = 1;
- X debug1("inter: %d\n", helpdata->inter);
- X helpdata->mcom = mcom;
- X helpdata->mkey = mkey;
- X helpdata->numrows = (helpdata->num_names + helpdata->numcols - 1) / helpdata->numcols;
- X debug1("Numrows: %d\n", helpdata->numrows);
- X helpdata->numskip = d_height-5 - (2 + helpdata->numrows);
- X while (helpdata->numskip < 0)
- X helpdata->numskip += d_height-5;
- X helpdata->numskip %= d_height-5;
- X debug1("Numskip: %d\n", helpdata->numskip);
- X if (helpdata->numskip > d_height/3 || helpdata->numskip > helpdata->command_bindings)
- X helpdata->numskip = 1;
- X helpdata->maxrow = 2 + helpdata->numrows + helpdata->numskip + helpdata->command_bindings;
- X helpdata->grow = 0;
- X
- X helpdata->numpages = (helpdata->maxrow + d_height-6) / (d_height-5);
- X helppage();
- X}
- X
- Xstatic void
- XHelpSetCursor()
- X{
- X GotoPos(0, d_height - 1);
- X}
- X
- Xstatic void
- XHelpProcess(ppbuf, plen)
- Xchar **ppbuf;
- Xint *plen;
- X{
- X int done = 0;
- X
- X GotoPos(0, d_height-1);
- X while (!done && *plen > 0)
- X {
- X switch (**ppbuf)
- X {
- X case ' ':
- X if (helppage() == 0)
- X break;
- X /* FALLTHROUGH */
- X case '\r':
- X case '\n':
- X done = 1;
- X break;
- X default:
- X break;
- X }
- X ++*ppbuf;
- X --*plen;
- X }
- X if (done)
- X HelpAbort();
- X}
- X
- Xstatic void
- XHelpAbort()
- X{
- X LAY_CALL_UP(Activate(0));
- X ExitOverlayPage();
- X}
- X
- X
- Xstatic int
- Xhelppage()
- X{
- X struct helpdata *helpdata;
- X int col, crow, n, key;
- X char buf[MAXKLEN], Esc_buf[5], cbuf[256];
- X
- X helpdata = (struct helpdata *)d_lay->l_data;
- X
- X if (helpdata->grow >= helpdata->maxrow)
- X {
- X return(-1);
- X }
- X helpdata->refgrow = helpdata->grow;
- X helpdata->refcommand_search = helpdata->command_search;
- X
- X /* Clear the help screen */
- X SetAttrFont(0, ASCII);
- X ClearDisplay();
- X
- X sprintf(cbuf,"Screen key bindings, page %d of %d.", helpdata->grow / (d_height-5) + 1, helpdata->numpages);
- X centerline(cbuf);
- X AddChar('\n');
- X crow = 2;
- X
- X *Esc_buf = '\0';
- X add_key_to_buf(Esc_buf, Esc);
- X
- X for (; crow < d_height - 3; crow++)
- X {
- X if (helpdata->grow < 1)
- X {
- X *buf = '\0';
- X add_key_to_buf(buf, MetaEsc);
- X sprintf(cbuf,"Command key: %s Literal %s: %s", Esc_buf, Esc_buf, buf);
- X centerline(cbuf);
- X helpdata->grow++;
- X }
- X else if (helpdata->grow >= 2 && helpdata->grow-2 < helpdata->numrows)
- X {
- X for (col = 0; col < helpdata->numcols && (n = helpdata->numrows * col + (helpdata->grow-2)) < helpdata->num_names; col++)
- X {
- X AddStrn("", helpdata->inter - !col);
- X n = helpdata->nact[n];
- X debug1("help: searching key %d\n", n);
- X buf[0] = '\0';
- X for (key = 0; key < 256; key++)
- X if (ktab[key].nr == n && ktab[key].args == noargs)
- X {
- X strcat(buf, " ");
- X add_key_to_buf(buf, key);
- X }
- X AddStrn(comms[n].name, helpdata->mcom);
- X AddStrn(buf, helpdata->mkey);
- X }
- X AddStr("\r\n");
- X helpdata->grow++;
- X }
- X else if (helpdata->grow-2-helpdata->numrows >= helpdata->numskip
- X && helpdata->grow-2-helpdata->numrows-helpdata->numskip < helpdata->command_bindings)
- X {
- X char **pp, *cp;
- X
- X while ((n = ktab[helpdata->command_search].nr) == RC_ILLEGAL
- X || ktab[helpdata->command_search].args == noargs)
- X {
- X if (++helpdata->command_search >= 256)
- X return -1;
- X }
- X buf[0] = '\0';
- X add_key_to_buf(buf, helpdata->command_search);
- X AddStrn(buf, 4);
- X col = 4;
- X AddStr(comms[n].name);
- X AddChar(' ');
- X col += strlen(comms[n].name) + 1;
- X pp = ktab[helpdata->command_search++].args;
- X while (pp && (cp = *pp) != NULL)
- X {
- X if (!*cp || (index(cp, ' ') != NULL))
- X {
- X if (index(cp, '\'') != NULL)
- X *buf = '"';
- X else
- X *buf = '\'';
- X sprintf(buf + 1, "%s%c", cp, *buf);
- X cp = buf;
- X }
- X if ((col += strlen(cp) + 1) >= d_width)
- X {
- X col = d_width - (col - (strlen(cp) + 1)) - 2;
- X if (col >= 0)
- X {
- X n = cp[col];
- X cp[col] = '\0';
- X AddStr(*pp);
- X AddChar('$');
- X cp[col] = (char) n;
- X }
- X break;
- X }
- X AddStr(cp);
- X AddChar((d_width - col != 1 || !pp[1]) ? ' ' : '$');
- X pp++;
- X }
- X AddStr("\r\n");
- X helpdata->grow++;
- X }
- X else
- X {
- X AddChar('\n');
- X helpdata->grow++;
- X }
- X }
- X AddChar('\n');
- X sprintf(cbuf,"[Press Space %s Return to end.]",
- X helpdata->grow < helpdata->maxrow ? "for next page;" : "or");
- X centerline(cbuf);
- X SetLastPos(0, d_height-1);
- X return(0);
- X}
- X
- Xstatic void
- Xadd_key_to_buf(buf, key)
- Xchar *buf;
- Xint key;
- X{
- X debug1("help: key found: %c\n", key);
- X buf += strlen(buf);
- X if (key == ' ')
- X sprintf(buf, "sp");
- X else if (key < ' ' || key == 0x7f)
- X sprintf(buf, "^%c", (key ^ 0x40));
- X else if (key >= 0x80)
- X sprintf(buf, "\\%03o", key);
- X else
- X sprintf(buf, "%c", key);
- X}
- X
- X
- Xstatic void
- XHelpRedisplayLine(y, xs, xe, isblank)
- Xint y, xs, xe, isblank;
- X{
- X if (y < 0)
- X {
- X struct helpdata *helpdata;
- X
- X helpdata = (struct helpdata *)d_lay->l_data;
- X helpdata->grow = helpdata->refgrow;
- X helpdata->command_search = helpdata->refcommand_search;
- X helppage();
- X return;
- X }
- X if (y != 0 && y != d_height - 1)
- X return;
- X if (isblank)
- X return;
- X Clear(xs, y, xe, y);
- X}
- X
- X
- X/*
- X**
- X** here is all the copyright stuff
- X**
- X*/
- X
- Xstatic void CopyrightProcess __P((char **, int *));
- Xstatic void CopyrightRedisplayLine __P((int, int, int, int));
- Xstatic void CopyrightAbort __P((void));
- Xstatic void CopyrightSetCursor __P((void));
- Xstatic void copypage __P((void));
- X
- Xstruct copydata
- X{
- X char *cps, *savedcps; /* position in the message */
- X char *refcps, *refsavedcps; /* backup for redisplaying */
- X};
- X
- Xstatic struct LayFuncs CopyrightLf =
- X{
- X CopyrightProcess,
- X CopyrightAbort,
- X CopyrightRedisplayLine,
- X DefClearLine,
- X DefRewrite,
- X CopyrightSetCursor,
- X DefResize,
- X DefRestore
- X};
- X
- Xstatic const char cpmsg[] = "\
- X\n\
- XiScreen version %v\n\
- X\n\
- XCopyright (c) 1993 Juergen Weigert, Michael Schroeder\n\
- XCopyright (c) 1987 Oliver Laumann\n\
- X\n\
- XThis program is free software; you can redistribute it and/or \
- Xmodify it under the terms of the GNU General Public License as published \
- Xby the Free Software Foundation; either version 1, or (at your option) \
- Xany later version.\n\
- X\n\
- XThis program is distributed in the hope that it will be useful, \
- Xbut WITHOUT ANY WARRANTY; without even the implied warranty of \
- XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the \
- XGNU General Public License for more details.\n\
- X\n\
- XYou should have received a copy of the GNU General Public License \
- Xalong with this program (see the file COPYING); if not, write to the \
- XFree Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.\n\
- X\n\
- XSend bugreports, fixes, enhancements, t-shirts, money, beer & pizza to \
- Xscreen@informatik.uni-erlangen.de\n";
- X
- X
- Xstatic void
- XCopyrightSetCursor()
- X{
- X GotoPos(0, d_height - 1);
- X}
- X
- Xstatic void
- XCopyrightProcess(ppbuf, plen)
- Xchar **ppbuf;
- Xint *plen;
- X{
- X int done = 0;
- X struct copydata *copydata;
- X
- X copydata = (struct copydata *)d_lay->l_data;
- X GotoPos(0, d_height - 1);
- X while (!done && *plen > 0)
- X {
- X switch (**ppbuf)
- X {
- X case ' ':
- X if (*copydata->cps)
- X {
- X copypage();
- X break;
- X }
- X /* FALLTHROUGH */
- X case '\r':
- X case '\n':
- X CopyrightAbort();
- X done = 1;
- X break;
- X default:
- X break;
- X }
- X ++*ppbuf;
- X --*plen;
- X }
- X}
- X
- Xstatic void
- XCopyrightAbort()
- X{
- X LAY_CALL_UP(Activate(0));
- X ExitOverlayPage();
- X}
- X
- Xvoid
- Xdisplay_copyright()
- X{
- X struct copydata *copydata;
- X
- X if (d_width < 10 || d_height < 5)
- X {
- X Msg(0, "Window size too small for copyright page");
- X return;
- X }
- X if (InitOverlayPage(sizeof(*copydata), &CopyrightLf, 0))
- X return;
- X copydata = (struct copydata *)d_lay->l_data;
- X copydata->cps = (char *)cpmsg;
- X copydata->savedcps = 0;
- X copypage();
- X}
- X
- X
- Xstatic void
- Xcopypage()
- X{
- X register char *cps;
- X char *ws;
- X int x, y, l;
- X char cbuf[80];
- X struct copydata *copydata;
- X
- X copydata = (struct copydata *)d_lay->l_data;
- X SetAttrFont(0, ASCII);
- X ClearDisplay();
- X x = y = 0;
- X cps = copydata->cps;
- X copydata->refcps = cps;
- X copydata->refsavedcps = copydata->savedcps;
- X while (*cps && y < d_height - 3)
- X {
- X ws = cps;
- X while (*cps == ' ')
- X cps++;
- X if (strncmp(cps, "%v", 2) == 0)
- X {
- X copydata->savedcps = cps + 2;
- X cps = version;
- X continue;
- X }
- X while (*cps && *cps != ' ' && *cps != '\n')
- X cps++;
- X l = cps - ws;
- X cps = ws;
- X if (l > d_width - 1)
- X l = d_width - 1;
- X if (x && x + l >= d_width - 2)
- X {
- X AddStr("\r\n");
- X x = 0;
- X y++;
- X continue;
- X }
- X if (x)
- X {
- X AddChar(' ');
- X x++;
- X }
- X if (l)
- X AddStrn(ws, l);
- X x += l;
- X cps += l;
- X if (*cps == 0 && copydata->savedcps)
- X {
- X cps = copydata->savedcps;
- X copydata->savedcps = 0;
- X }
- X if (*cps == '\n')
- X {
- X AddStr("\r\n");
- X x = 0;
- X y++;
- X }
- X if (*cps == ' ' || *cps == '\n')
- X cps++;
- X }
- X while (*cps == '\n')
- X cps++;
- X while (y++ < d_height - 2)
- X AddStr("\r\n");
- X sprintf(cbuf,"[Press Space %s Return to end.]",
- X *cps ? "for next page;" : "or");
- X centerline(cbuf);
- X SetLastPos(0, d_height-1);
- X copydata->cps = cps;
- X}
- X
- Xstatic void
- XCopyrightRedisplayLine(y, xs, xe, isblank)
- Xint y, xs, xe, isblank;
- X{
- X if (y < 0)
- X {
- X struct copydata *copydata;
- X
- X copydata = (struct copydata *)d_lay->l_data;
- X copydata->cps = copydata->refcps;
- X copydata->savedcps = copydata->refsavedcps;
- X copypage();
- X return;
- X }
- X if (y != 0 && y != d_height - 1)
- X return;
- X if (isblank)
- X return;
- X Clear(xs, y, xe, y);
- X}
- X
- END_OF_FILE
- if test 15096 -ne `wc -c <'help.c'`; then
- echo shar: \"'help.c'\" unpacked with wrong size!
- fi
- # end of 'help.c'
- fi
- if test -f 'termcap.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'termcap.c'\"
- else
- echo shar: Extracting \"'termcap.c'\" \(14829 characters\)
- sed "s/^X//" >'termcap.c' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: termcap.c,v 1.3 1993/07/21 15:43:35 mlschroe Exp $ FAU")
- X
- X#include <sys/types.h>
- X#include "config.h"
- X#include "screen.h"
- X#include "extern.h"
- X
- Xextern struct display *display;
- X
- Xstatic void AddCap __P((char *));
- Xstatic void MakeString __P((char *, char *, int, char *));
- Xstatic char *findcap __P((char *, char **, int));
- Xstatic char *e_tgetstr __P((char *, char **));
- Xstatic int e_tgetflag __P((char *));
- Xstatic int e_tgetnum __P((char *));
- X
- Xextern struct term term[]; /* terminal capabilities */
- Xextern struct NewWindow nwin_undef, nwin_default, nwin_options;
- Xextern int force_vt, assume_LP;
- Xextern int Z0width, Z1width;
- X
- Xchar Termcap[TERMCAP_BUFSIZE + 8]; /* new termcap +8:"TERMCAP=" */
- Xstatic int Termcaplen;
- Xstatic int tcLineLen;
- Xchar Term[MAXSTR+5]; /* +5: "TERM=" */
- Xchar screenterm[20]; /* new $TERM, usually "screen" */
- X
- Xchar *extra_incap, *extra_outcap;
- X
- Xstatic const char TermcapConst[] = "\\\n\
- X\t:DO=\\E[%dB:LE=\\E[%dD:RI=\\E[%dC:UP=\\E[%dA:bs:bt=\\E[Z:\\\n\
- X\t:cd=\\E[J:ce=\\E[K:cl=\\E[H\\E[J:cm=\\E[%i%d;%dH:ct=\\E[3g:\\\n\
- X\t:do=^J:nd=\\E[C:pt:rc=\\E8:rs=\\Ec:sc=\\E7:st=\\EH:up=\\EM:\\\n\
- X\t:le=^H:bl=^G:cr=^M:it#8:ho=\\E[H:nw=\\EE:ta=^I:is=\\E)0:";
- X
- Xchar *
- Xgettermcapstring(s)
- Xchar *s;
- X{
- X int i;
- X
- X if (display == 0 || s == 0)
- X return 0;
- X for (i = 0; i < T_N; i++)
- X {
- X if (term[i].type != T_STR)
- X continue;
- X if (strcmp(term[i].tcname, s) == 0)
- X return d_tcs[i].str;
- X }
- X return 0;
- X}
- X
- Xint
- XInitTermcap(wi, he)
- Xint wi;
- Xint he;
- X{
- X register char *s;
- X int i;
- X char tbuf[TERMCAP_BUFSIZE], *tp;
- X
- X ASSERT(display);
- X bzero(tbuf, sizeof(tbuf));
- X debug1("InitTermcap: looking for tgetent('%s')\n", d_termname);
- X if (tgetent(tbuf, d_termname) != 1)
- X {
- X Msg(0, "Cannot find termcap entry for %s.", d_termname);
- X return -1;
- X }
- X debug1("got it:\n%s\n",tbuf);
- X#ifdef DEBUG
- X if (extra_incap)
- X debug1("Extra incap: %s\n", extra_incap);
- X if (extra_outcap)
- X debug1("Extra outcap: %s\n", extra_outcap);
- X#endif
- X tp = d_tentry;
- X
- X for (i = 0; i < T_N; i++)
- X {
- X switch(term[i].type)
- X {
- X case T_FLG:
- X d_tcs[i].flg = e_tgetflag(term[i].tcname);
- X break;
- X case T_NUM:
- X d_tcs[i].num = e_tgetnum(term[i].tcname);
- X break;
- X case T_STR:
- X d_tcs[i].str = e_tgetstr(term[i].tcname, &tp);
- X /* no empty strings, please */
- X if (d_tcs[i].str && *d_tcs[i].str == 0)
- X d_tcs[i].str = 0;
- X break;
- X default:
- X Panic(0, "Illegal tc type in entry #%d", i);
- X /*NOTREACHED*/
- X }
- X }
- X if (HC)
- X {
- X Msg(0, "You can't run screen on a hardcopy terminal.");
- X return -1;
- X }
- X if (OS)
- X {
- X Msg(0, "You can't run screen on a terminal that overstrikes.");
- X return -1;
- X }
- X if (NS)
- X {
- X Msg(0, "Terminal must support scrolling.");
- X return -1;
- X }
- X if (!CL)
- X {
- X Msg(0, "Clear screen capability required.");
- X return -1;
- X }
- X if (!CM)
- X {
- X Msg(0, "Addressable cursor capability required.");
- X return -1;
- X }
- X if ((s = getenv("COLUMNS")) && (i = atoi(s)) > 0)
- X CO = i;
- X if ((s = getenv("LINES")) && (i = atoi(s)) > 0)
- X LI = i;
- X if (wi)
- X CO = wi;
- X if (he)
- X LI = he;
- X if (CO <= 0)
- X CO = 80;
- X if (LI <= 0)
- X LI = 24;
- X
- X if (nwin_options.flowflag == nwin_undef.flowflag)
- X nwin_default.flowflag = CNF ? FLOW_NOW * 0 :
- X XO ? FLOW_NOW * 1 :
- X FLOW_AUTOFLAG;
- X CLP |= assume_LP || !AM || XV || XN ||
- X (!extra_incap && !strncmp(d_termname, "vt", 2));
- X if (!(BL = e_tgetstr("bl", &tp)))
- X if (!BL)
- X BL = "\007";
- X if (!BC)
- X {
- X if (BS)
- X BC = "\b";
- X else
- X BC = LE;
- X }
- X if (!CR)
- X CR = "\r";
- X if (!NL)
- X NL = "\n";
- X if (SG <= 0 && UG <= 0)
- X {
- X /*
- X * Does ME also reverse the effect of SO and/or US? This is not
- X * clearly specified by the termcap manual. Anyway, we should at
- X * least look whether ME and SE/UE are equal:
- X */
- X if (UE && ((SE && strcmp(SE, UE) == 0) || (ME && strcmp(ME, UE) == 0)))
- X UE = 0;
- X if (SE && (ME && strcmp(ME, SE) == 0))
- X SE = 0;
- X
- X for (i = 0; i < NATTR; i++)
- X d_attrtab[i] = d_tcs[T_ATTR + i].str;
- X /* Set up missing entries */
- X s = 0;
- X for (i = NATTR-1; i >= 0; i--)
- X if (d_attrtab[i])
- X s = d_attrtab[i];
- X for (i = 0; i < NATTR; i++)
- X {
- X if (d_attrtab[i] == 0)
- X d_attrtab[i] = s;
- X else
- X s = d_attrtab[i];
- X }
- X }
- X else
- X {
- X MS = 1;
- X for (i = 0; i < NATTR; i++)
- X d_attrtab[i] = d_tcs[T_ATTR + i].str = 0;
- X }
- X if (!DO)
- X DO = NL;
- X if (!SF)
- X SF = NL;
- X if (IN)
- X IC = IM = 0;
- X if (EI == 0)
- X IM = 0;
- X /* some strange termcap entries have IC == IM */
- X if (IC && IM && strcmp(IC, IM) == 0)
- X IC = 0;
- X if (KE == 0)
- X KS = 0;
- X if (CCE == 0)
- X CCS = 0;
- X if (CG0)
- X {
- X if (CS0 == 0)
- X#ifdef TERMINFO
- X CS0 = "\033(%p1%c";
- X#else
- X CS0 = "\033(%.";
- X#endif
- X if (CE0 == 0)
- X CE0 = "\033(B";
- X }
- X else if (AS && AE)
- X {
- X CG0 = 1;
- X CS0 = AS;
- X CE0 = AE;
- X CC0 = AC;
- X }
- X else
- X {
- X CS0 = CE0 = "";
- X CC0 = "g.h.i'j-k-l-m-n+o~p\"q-r-s_t+u+v+w+x|y<z>";
- X }
- X for (i = 0; i < 256; i++)
- X d_c0_tab[i] = i;
- X if (CC0)
- X for (i = strlen(CC0) & ~1; i >= 0; i -= 2)
- X d_c0_tab[(unsigned int)CC0[i]] = CC0[i + 1];
- X debug1("ISO2022 = %d\n", CG0);
- X if (PF == 0)
- X PO = 0;
- X debug2("terminal size is %d, %d (says TERMCAP)\n", CO, LI);
- X
- X /* Termcap fields Z0 & Z1 contain width-changing sequences. */
- X if (CZ1 == 0)
- X CZ0 = 0;
- X Z0width = 132;
- X Z1width = 80;
- X
- X CheckScreenSize(0);
- X
- X if (TS == 0 || FS == 0 || DS == 0)
- X HS = 0;
- X if (HS)
- X {
- X debug("oy! we have a hardware status line, says termcap\n");
- X if (WS <= 0)
- X WS = d_width;
- X }
- X
- X d_UPcost = CalcCost(UP);
- X d_DOcost = CalcCost(DO);
- X d_NLcost = CalcCost(NL);
- X d_LEcost = CalcCost(BC);
- X d_NDcost = CalcCost(ND);
- X d_CRcost = CalcCost(CR);
- X d_IMcost = CalcCost(IM);
- X d_EIcost = CalcCost(EI);
- X
- X#ifdef AUTO_NUKE
- X if (CAN)
- X {
- X debug("termcap has AN, setting autonuke\n");
- X d_auto_nuke = 1;
- X }
- X#endif
- X if (COL > 0)
- X {
- X debug1("termcap has OL (%d), setting limit\n", COL);
- X d_obufmax = COL;
- X }
- X
- X d_tcinited = 1;
- X MakeTermcap(0);
- X return 0;
- X}
- X
- X
- Xstatic void
- XAddCap(s)
- Xchar *s;
- X{
- X register int n;
- X
- X if (tcLineLen + (n = strlen(s)) > 55 && Termcaplen < TERMCAP_BUFSIZE - 4)
- X {
- X strcpy(Termcap + Termcaplen, "\\\n\t:");
- X Termcaplen += 4;
- X tcLineLen = 0;
- X }
- X if (Termcaplen + n < TERMCAP_BUFSIZE)
- X {
- X strcpy(Termcap + Termcaplen, s);
- X Termcaplen += n;
- X tcLineLen += n;
- X }
- X else
- X Panic(0, "TERMCAP overflow - sorry.");
- X}
- X
- Xchar *
- XMakeTermcap(aflag)
- Xint aflag;
- X{
- X char buf[TERMCAP_BUFSIZE];
- X register char *p, *cp, *s, ch, *tname;
- X int i, wi, he;
- X
- X if (display)
- X {
- X wi = d_width;
- X he = d_height;
- X tname = d_termname;
- X }
- X else
- X {
- X wi = 80;
- X he = 24;
- X tname = "vt100";
- X }
- X debug1("MakeTermcap(%d)\n", aflag);
- X if ((s = getenv("SCREENCAP")) && strlen(s) < TERMCAP_BUFSIZE)
- X {
- X sprintf(Termcap, "TERMCAP=%s", s); /* TERMCAP_BUFSIZE + ... ? XXX */
- X sprintf(Term, "TERM=screen");
- X debug("getenvSCREENCAP o.k.\n");
- X return Termcap;
- X }
- X Termcaplen = 0;
- X debug1("MakeTermcap screenterm='%s'\n", screenterm);
- X debug1("MakeTermcap termname='%s'\n", tname);
- X if (*screenterm == '\0')
- X {
- X debug("MakeTermcap sets screenterm=screen\n");
- X strcpy(screenterm, "screen");
- X }
- X do
- X {
- X sprintf(Term, "TERM=");
- X p = Term + 5;
- X if (!aflag && strlen(screenterm) + strlen(tname) < MAXSTR-1)
- X {
- X sprintf(p, "%s.%s", screenterm, tname);
- X if (tgetent(buf, p) == 1)
- X break;
- X }
- X if (wi >= 132)
- X {
- X sprintf(p, "%s-w", screenterm);
- X if (tgetent(buf, p) == 1)
- X break;
- X }
- X sprintf(p, "%s", screenterm);
- X if (tgetent(buf, p) == 1)
- X break;
- X sprintf(p, "vt100");
- X }
- X while (0); /* Goto free programming... */
- X tcLineLen = 100; /* Force NL */
- X sprintf(Termcap,
- X "TERMCAP=SC|%s|VT 100/ANSI X3.64 virtual terminal|", Term + 5);
- X Termcaplen = strlen(Termcap);
- X debug1("MakeTermcap decided '%s'\n", p);
- X if (extra_outcap && *extra_outcap)
- X {
- X for (cp = extra_outcap; (p = index(cp, ':')); cp = p)
- X {
- X ch = *++p;
- X *p = '\0';
- X AddCap(cp);
- X *p = ch;
- X }
- X tcLineLen = 100; /* Force NL */
- X }
- X debug1("MakeTermcap after outcap '%s'\n", (char *)TermcapConst);
- X if (Termcaplen + strlen(TermcapConst) < TERMCAP_BUFSIZE)
- X {
- X strcpy(Termcap + Termcaplen, (char *)TermcapConst);
- X Termcaplen += strlen(TermcapConst);
- X }
- X sprintf(buf, "li#%d:co#%d:", he, wi);
- X AddCap(buf);
- X AddCap("am:");
- X if (aflag || (force_vt && !COP) || CLP || !AM)
- X {
- X AddCap("xn:");
- X AddCap("xv:");
- X AddCap("LP:");
- X }
- X if (aflag || (CS && SR) || AL || CAL)
- X {
- X AddCap("sr=\\EM:");
- X AddCap("al=\\E[L:");
- X AddCap("AL=\\E[%dL:");
- X }
- X else if (SR)
- X AddCap("sr=\\EM:");
- X if (aflag || CS)
- X AddCap("cs=\\E[%i%d;%dr:");
- X if (aflag || CS || DL || CDL)
- X {
- X AddCap("dl=\\E[M:");
- X AddCap("DL=\\E[%dM:");
- X }
- X if (aflag || DC || CDC)
- X {
- X AddCap("dc=\\E[P:");
- X AddCap("DC=\\E[%dP:");
- X }
- X if (aflag || CIC || IC || IM)
- X {
- X AddCap("im=\\E[4h:");
- X AddCap("ei=\\E[4l:");
- X AddCap("mi:");
- X AddCap("IC=\\E[%d@:");
- X }
- X if (display)
- X {
- X if (US)
- X {
- X AddCap("us=\\E[4m:");
- X AddCap("ue=\\E[24m:");
- X }
- X if (SO)
- X {
- X AddCap("so=\\E[3m:");
- X AddCap("se=\\E[23m:");
- X }
- X if (MB)
- X AddCap("mb=\\E[5m:");
- X if (MD)
- X AddCap("md=\\E[1m:");
- X if (MH)
- X AddCap("mh=\\E[2m:");
- X if (MR)
- X AddCap("mr=\\E[7m:");
- X if (MB || MD || MH || MR)
- X AddCap("me=\\E[m:ms:");
- X if (VB)
- X AddCap("vb=\\E[?5h\\E[?5l:");
- X if (KS)
- X {
- X AddCap("ks=\\E=:");
- X AddCap("ke=\\E>:");
- X }
- X if (CCS)
- X {
- X AddCap("CS=\\E[?1h:");
- X AddCap("CE=\\E[?1l:");
- X }
- X if (CG0)
- X {
- X AddCap("G0:");
- X AddCap("as=\\E(0:");
- X AddCap("ae=\\E(B:");
- X }
- X if (PO)
- X {
- X AddCap("po=\\E[5i:");
- X AddCap("pf=\\E[4i:");
- X }
- X if (CZ0)
- X {
- X AddCap("Z0=\\E[?3h:");
- X AddCap("Z1=\\E[?3l:");
- X }
- X if (CWS)
- X AddCap("WS=\\E[8;%d;%dt:");
- X for (i = T_CAPS; i < T_ECAPS; i++)
- X {
- X switch(term[i].type)
- X {
- X case T_STR:
- X if (d_tcs[i].str == 0)
- X break;
- X MakeString(term[i].tcname, buf, sizeof(buf), d_tcs[i].str);
- X AddCap(buf);
- X break;
- X case T_FLG:
- X if (d_tcs[i].flg == 0)
- X break;
- X sprintf(buf, "%s:", term[i].tcname);
- X AddCap(buf);
- X break;
- X default:
- X break;
- X }
- X }
- X }
- X debug("MakeTermcap: end\n");
- X return Termcap;
- X}
- X
- Xstatic void
- XMakeString(cap, buf, buflen, s)
- Xchar *cap, *buf;
- Xint buflen;
- Xchar *s;
- X{
- X register char *p, *pmax;
- X register unsigned int c;
- X
- X p = buf;
- X pmax = p + buflen - (3+4+2);
- X *p++ = *cap++;
- X *p++ = *cap;
- X *p++ = '=';
- X while ((c = *s++) && (p < pmax))
- X {
- X switch (c)
- X {
- X case '\033':
- X *p++ = '\\';
- X *p++ = 'E';
- X break;
- X case ':':
- X sprintf(p, "\\072");
- X p += 4;
- X break;
- X case '^':
- X case '\\':
- X *p++ = '\\';
- X *p++ = c;
- X break;
- X default:
- X if (c >= 200)
- X {
- X sprintf(p, "\\%03o", c & 0377);
- X p += 4;
- X }
- X else if (c < ' ')
- X {
- X *p++ = '^';
- X *p++ = c + '@';
- X }
- X else
- X *p++ = c;
- X }
- X }
- X *p++ = ':';
- X *p = '\0';
- X}
- X
- X
- X/*
- X**
- X** Termcap routines that use our extra_incap
- X**
- X*/
- X
- X
- X/* findcap:
- X * cap = capability we are looking for
- X * tepp = pointer to bufferpointer
- X * n = size of buffer (0 = infinity)
- X */
- X
- Xstatic char *
- Xfindcap(cap, tepp, n)
- Xchar *cap;
- Xchar **tepp;
- Xint n;
- X{
- X char *tep;
- X char c, *p, *cp;
- X int mode; /* mode: 0=LIT 1=^ 2=\x 3,4,5=\nnn */
- X int num = 0, capl;
- X
- X if (!extra_incap)
- X return (0);
- X tep = *tepp;
- X capl = strlen(cap);
- X cp = 0;
- X mode = 0;
- X for (p = extra_incap; *p; )
- X {
- X if (strncmp(p, cap, capl) == 0)
- X {
- X p += capl;
- X c = *p;
- X if (c && c != ':' && c != '@')
- X p++;
- X if (c == 0 || c == '@' || c == '=' || c == ':' || c == '#')
- X cp = tep;
- X }
- X while ((c = *p))
- X {
- X p++;
- X if (mode == 0)
- X {
- X if (c == ':')
- X break;
- X if (c == '^')
- X mode = 1;
- X if (c == '\\')
- X mode = 2;
- X }
- X else if (mode == 1)
- X {
- X mode = 0;
- X c = c & 0x1f;
- X }
- X else if (mode == 2)
- X {
- X mode = 0;
- X switch(c)
- X {
- X case '0':
- X case '1':
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X mode = 3;
- X num = 0;
- X break;
- X case 'E':
- X c = 27;
- X break;
- X case 'n':
- X c = '\n';
- X break;
- X case 'r':
- X c = '\r';
- X break;
- X case 't':
- X c = '\t';
- X break;
- X case 'b':
- X c = '\b';
- X break;
- X case 'f':
- X c = '\f';
- X break;
- X }
- X }
- X if (mode > 2)
- X {
- X num = num * 8 + (c - '0');
- X if (mode++ == 5 || (*p < '0' || *p > '9'))
- X {
- X c = num;
- X mode = 0;
- X }
- X }
- X if (mode)
- X continue;
- X
- X if (cp && n != 1)
- X {
- X *cp++ = c;
- X n--;
- X }
- X }
- X if (cp)
- X {
- X *cp++ = 0;
- X *tepp = cp;
- X debug2("'%s' found in extra_incap -> %s\n", cap, tep);
- X return(tep);
- X }
- X }
- X return(0);
- X}
- X
- Xstatic char *
- Xe_tgetstr(cap, tepp)
- Xchar *cap;
- Xchar **tepp;
- X{
- X char *tep, *tgetstr();
- X if ((tep = findcap(cap, tepp, 0)))
- X return((*tep == '@') ? 0 : tep);
- X return (tgetstr(cap, tepp));
- X}
- X
- Xstatic int
- Xe_tgetflag(cap)
- Xchar *cap;
- X{
- X char buf[2], *bufp;
- X char *tep;
- X bufp = buf;
- X if ((tep = findcap(cap, &bufp, 2)))
- X return((*tep == '@') ? 0 : 1);
- X return (tgetflag(cap));
- X}
- X
- Xstatic int
- Xe_tgetnum(cap)
- Xchar *cap;
- X{
- X char buf[20], *bufp;
- X char *tep, c;
- X int res, base = 10;
- X
- X bufp = buf;
- X if ((tep = findcap(cap, &bufp, 20)))
- X {
- X c = *tep;
- X if (c == '@')
- X return(-1);
- X if (c == '0')
- X base = 8;
- X res = 0;
- X while ((c = *tep++) >= '0' && c <= '9')
- X res = res * base + (c - '0');
- X return(res);
- X }
- X return (tgetnum(cap));
- X}
- END_OF_FILE
- if test 14829 -ne `wc -c <'termcap.c'`; then
- echo shar: \"'termcap.c'\" unpacked with wrong size!
- fi
- # end of 'termcap.c'
- fi
- if test -f 'utmp.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'utmp.c'\"
- else
- echo shar: Extracting \"'utmp.c'\" \(18794 characters\)
- sed "s/^X//" >'utmp.c' <<'END_OF_FILE'
- X/* Copyright (c) 1993
- X * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de)
- X * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de)
- X * Copyright (c) 1987 Oliver Laumann
- X *
- X * This program is free software; you can redistribute it and/or modify
- X * it under the terms of the GNU General Public License as published by
- X * the Free Software Foundation; either version 2, or (at your option)
- X * any later version.
- X *
- X * This program is distributed in the hope that it will be useful,
- X * but WITHOUT ANY WARRANTY; without even the implied warranty of
- X * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- X * GNU General Public License for more details.
- X *
- X * You should have received a copy of the GNU General Public License
- X * along with this program (see the file COPYING); if not, write to the
- X * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X *
- X ****************************************************************
- X */
- X
- X#include "rcs.h"
- XRCS_ID("$Id: utmp.c,v 1.3 1993/07/21 15:43:38 mlschroe Exp $ FAU")
- X
- X
- X/*
- X * An explanation of some weird things:
- X *
- X * linux should have GETUTENT, but their pututline() doesn't have
- X * a return value.
- X *
- X * UTNOKEEP: A (ugly) hack for apollo, that does two things:
- X * 1) Always close and reopen the utmp file descriptor. (I don't know
- X * for what reason this is done...)
- X * 2) Implement an unsortet utmp file much like GETUTENT.
- X * (IMHO these two features should be split!)
- X */
- X
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <fcntl.h>
- X
- X#include "config.h"
- X#include "screen.h"
- X#include "extern.h"
- X
- X
- Xextern struct display *display;
- Xextern struct win *fore;
- Xextern char *LoginName;
- X#ifdef NETHACK
- Xextern nethackflag;
- X#endif
- X
- X#ifdef UTMPOK
- X
- Xstatic slot_t TtyNameSlot __P((char *));
- Xstatic int utmpok, utmpfd = -1;
- Xstatic char UtmpName[] = UTMPFILE;
- X
- X
- X# if defined(GETUTENT) && !defined(SVR4)
- X# if defined(hpux) /* cruel hpux release 8.0 */
- X# define pututline _pututline
- X# endif /* hpux */
- Xextern struct utmp *getutline(), *pututline();
- X# if defined(_SEQUENT_)
- Xextern struct utmp *ut_add_user(), *ut_delete_user();
- Xextern char *ut_find_host();
- X# define UTHOST /* _SEQUENT_ has got ut_find_host() */
- X# endif /* _SEQUENT_ */
- X# endif /* GETUTENT && !SVR4 */
- X
- X# if defined (GETTTYENT) && !defined(GETUTENT)
- X# include <ttyent.h>
- X# endif /* GETUTENT */
- X
- X# if !defined(GETTTYENT) && !defined(GETUTENT) && !defined(UTNOKEEP)
- Xstruct ttyent
- X{
- X char *ty_name;
- X};
- Xstatic void setttyent __P((void));
- Xstatic struct ttyent *getttyent __P((void));
- Xstatic char *tt, *ttnext;
- Xstatic char ttys[] = "/etc/ttys";
- X# endif /* !GETTTYENT && !GETUTENT && !UTNOKEEP */
- X
- X#endif /* UTMPOK */
- X
- X
- X
- X/*
- X * SlotToggle - modify the utmp slot of the fore window.
- X *
- X * how > 0 do try to set a utmp slot.
- X * how = 0 try to withdraw a utmp slot.
- X *
- X * w_slot = -1 window not logged in.
- X * w_slot = 0 window not logged in, but should be logged in.
- X * (unable to write utmp, or detached).
- X */
- Xvoid
- XSlotToggle(how)
- Xint how;
- X{
- X debug1("SlotToggle %d\n", how);
- X#ifdef UTMPOK
- X if (how)
- X {
- X debug(" try to log in\n");
- X if ((fore->w_slot == (slot_t) -1) || (fore->w_slot == (slot_t) 0))
- X {
- X# ifdef USRLIMIT
- X if (CountUsers() >= USRLIMIT)
- X Msg(0, "User limit reached.");
- X else
- X# endif
- X {
- X if (SetUtmp(fore) == 0)
- X Msg(0, "This window is now logged in.");
- X else
- X Msg(0, "This window should now be logged in.");
- X }
- X }
- X else
- X Msg(0, "This window is already logged in.");
- X }
- X else
- X {
- X debug(" try to log out\n");
- X if (fore->w_slot == (slot_t) -1)
- X Msg(0, "This window is already logged out\n");
- X else if (fore->w_slot == (slot_t) 0)
- X {
- X debug("What a relief! In fact, it was not logged in\n");
- X Msg(0, "This window is not logged in.");
- X fore->w_slot = (slot_t) -1;
- X }
- X else
- X {
- X RemoveUtmp(fore);
- X if (fore->w_slot != (slot_t) -1)
- X Msg(0, "What? Cannot remove Utmp slot?");
- X else
- X Msg(0, "This window is no longer logged in.");
- X }
- X }
- X#else /* !UTMPOK */
- X Msg(0, "Unable to modify %s.\n", UTMPFILE);
- X#endif
- X}
- X
- X
- X#ifdef UTMPOK
- X
- X
- Xvoid
- XInitUtmp()
- X{
- X debug1("InitUtmp testing '%s'...\n", UtmpName);
- X if ((utmpfd = open(UtmpName, O_RDWR)) == -1)
- X {
- X if (errno != EACCES)
- X Msg(errno, UtmpName);
- X debug("InitUtmp failed.\n");
- X utmpok = 0;
- X return;
- X }
- X# ifdef GETUTENT
- X close(utmpfd); /* it was just a test */
- X utmpfd = -1;
- X# endif /* GETUTENT */
- X utmpok = 1;
- X}
- X
- X
- X#ifdef USRLIMIT
- Xint
- XCountUsers()
- X{
- X# ifdef GETUTENT
- X struct utmp *ut, *getutent();
- X# else /* GETUTENT */
- X struct utmp utmpbuf;
- X# endif /* GETUTENT */
- X int UserCount;
- X
- X# ifdef UTNOKEEP
- X InitUtmp();
- X# endif /* UTNOKEEP */
- X debug1("CountUsers() - utmpok=%d\n", utmpok);
- X if (!utmpok)
- X return(0);
- X UserCount = 0;
- X# ifdef GETUTENT
- X setutent();
- X while (ut = getutent())
- X if (ut->ut_type == USER_PROCESS)
- X UserCount++;
- X# else /* GETUTENT */
- X (void) lseek(utmpfd, (off_t) 0, 0);
- X while (read(utmpfd, &utmpbuf, sizeof(struct utmp)) > 0)
- X {
- X if (utmpbuf.ut_name[0] != '\0')
- X UserCount++;
- X }
- X# endif /* GETUTENT */
- X# ifdef UTNOKEEP
- X close(utmpfd);
- X# endif /* UTNOKEEP */
- X return(UserCount);
- X}
- X#endif /* USRLIMIT */
- X
- X
- X
- X/*
- X * the utmp entry for tty is located and removed.
- X * it is stored in d_utmp_logintty.
- X */
- Xvoid
- XRemoveLoginSlot()
- X{
- X# ifdef GETUTENT
- X struct utmp *uu;
- X# endif /* GETUTENT */
- X struct utmp u; /* 'empty' slot that we write back */
- X# ifdef _SEQUENT_
- X char *p;
- X# endif /* _SEQUENT_ */
- X
- X ASSERT(display);
- X debug("RemoveLoginSlot: removing your logintty\n");
- X d_loginslot = TtyNameSlot(d_usertty);
- X# ifdef UTNOKEEP
- X InitUtmp();
- X# endif /* UTNOKEEP */
- X if (!utmpok)
- X {
- X debug("RemoveLoginSlot: utmpok == 0\n");
- X return;
- X }
- X if (d_loginslot == (slot_t)0 || d_loginslot == (slot_t)-1)
- X {
- X return;
- X }
- X# ifdef _SEQUENT_
- X if (p = ut_find_host(d_loginslot))
- X strncpy(d_loginhost, p, sizeof(d_loginhost) - 1);
- X d_loginhost[sizeof(d_loginhost) - 1] = 0;
- X# endif /* _SEQUENT_ */
- X
- X bzero((char *) &u, sizeof u);
- X
- X# ifdef GETUTENT
- X setutent();
- X strncpy(u.ut_line, d_loginslot, sizeof(u.ut_line));
- X if ((uu = getutline(&u)) == 0)
- X {
- X Msg(0, "Utmp slot not found -> not removed");
- X return;
- X }
- X d_utmp_logintty = *uu;
- X# ifdef _SEQUENT_
- X if (ut_delete_user(d_loginslot, uu->ut_pid, 0, 0) == 0)
- X# else /* _SEQUENT_ */
- X u = *uu;
- X u.ut_type = DEAD_PROCESS;
- X u.ut_exit.e_termination = 0;
- X u.ut_exit.e_exit= 0;
- X if (pututline(&u) == 0)
- X# endif /* _SEQUENT_ */
- X
- X# else /* GETUTENT */
- X
- X (void) lseek(utmpfd, (off_t) (d_loginslot * sizeof u), 0);
- X bzero((char *)&d_utmp_logintty, sizeof u);
- X if (read(utmpfd, (char *) &d_utmp_logintty, sizeof u) != sizeof u)
- X {
- X Msg(errno, "cannot read %s ??", UTMPFILE);
- X sleep(1);
- X }
- X (void) lseek(utmpfd, (off_t) (d_loginslot * sizeof u), 0);
- X# ifdef UTNOKEEP
- X /*
- X * as the utmp file is not sorted, we want to mark this slot occupied,
- X * as RestoreLoginSlot() will write exactly here.
- X */
- X bcopy((char *)&d_utmp_logintty, (char *)&u, sizeof u);
- X bzero(u.ut_name, sizeof(u.ut_name));
- X bzero(u.ut_host, sizeof(u.ut_host));
- X# endif /* UTNOKEEP */
- X if (write(utmpfd, (char *) &u, sizeof u) != sizeof u)
- X
- X# endif /* GETUTENT */
- X
- X {
- X# ifdef NETHACK
- X if (nethackflag)
- X {
- X Msg(errno, "%s is too hard to dig in", UTMPFILE);
- X }
- X else
- X# endif /* NETHACK */
- X {
- X Msg(errno, "Could not write %s", UTMPFILE);
- X }
- X }
- X# ifdef UTNOKEEP
- X close(utmpfd);
- X# endif /* UTNOKEEP */
- X debug1(" slot %d zapped\n", (int)d_loginslot);
- X}
- X
- X/*
- X * d_utmp_logintty is reinserted into utmp
- X */
- Xvoid
- XRestoreLoginSlot()
- X{
- X debug("RestoreLoginSlot()\n");
- X ASSERT(display);
- X# ifdef UTNOKEEP
- X InitUtmp();
- X# endif /* UTNOKEEP */
- X if (utmpok && d_loginslot != (slot_t)0 && d_loginslot != (slot_t)-1)
- X {
- X# ifdef GETUTENT
- X# ifdef _SEQUENT_
- X int fail;
- X debug1(" logging you in again (slot %s)\n", d_loginslot);
- X/*
- X * We have problems if we add the console and use ut_add_user()
- X * because the id will be 'scon' instead of 'co'. So we
- X * restore it with pututline(). The reason why we don't use
- X * pututline all the time is that we want to set the host field.
- X * Unfortunatelly this can only be done with ut_add_user().
- X */
- X if (*d_loginhost)
- X {
- X fail = (ut_add_user(d_utmp_logintty.ut_name, d_loginslot, d_utmp_logintty.ut_pid,
- X *d_loginhost ? d_loginhost : (char *)0) == 0);
- X }
- X else
- X {
- X setutent();
- X fail = (pututline(&d_utmp_logintty) == 0);
- X }
- X if (fail)
- X# else /* _SEQUENT_ */
- X debug1(" logging you in again (slot %s)\n", d_loginslot);
- X setutent();
- X if (pututline(&d_utmp_logintty)==0)
- X# endif /* _SEQUENT */
- X# else /* GETUTENT */
- X debug1(" logging you in again (slot %d)\n", d_loginslot);
- X# ifdef sequent
- X /*
- X * call sequent undocumented routine to count logins
- X * and add utmp entry if possible
- X */
- X if (add_utmp(d_loginslot, &d_utmp_logintty) == -1)
- X# else /* sequent */
- X (void) lseek(utmpfd, (off_t) (d_loginslot * sizeof(struct utmp)), 0);
- X if (write(utmpfd, (char *) &d_utmp_logintty, sizeof(struct utmp))
- X != sizeof(struct utmp))
- X# endif /* sequent */
- X# endif /* GETUTENT */
- X {
- X# ifdef NETHACK
- X if (nethackflag)
- X Msg(errno, "%s is too hard to dig in", UTMPFILE);
- X else
- X# endif /* NETHACK */
- X Msg(errno,"Could not write %s", UTMPFILE);
- X }
- X }
- X# ifdef UTNOKEEP
- X close(utmpfd);
- X# endif /* UTNOKEEP */
- X d_loginslot = (slot_t) 0;
- X}
- X
- X
- X
- X/*
- X * Construct a utmp entry for window wi.
- X * the hostname field reflects what we know about the d_user (i.e. display)
- X * location. If d_loginhost is not set, then he is local and we write
- X * down the name of his terminal line; else he is remote and we keep
- X * the hostname here. The letter S and the window id will be appended.
- X * A saved utmp entry in wi->w_savut serves as a template, usually.
- X */
- X
- Xint
- XSetUtmp(wi)
- Xstruct win *wi;
- X{
- X register char *p;
- X register slot_t slot;
- X# ifndef _SEQUENT_
- X char *line;
- X# endif
- X struct utmp u;
- X int saved_ut;
- X# ifdef UTHOST
- X# ifdef _SEQUENT_
- X char host[100+5];
- X# else /* _SEQUENT_ */
- X char host[sizeof(d_utmp_logintty.ut_host)+5];
- X# endif /* _SEQUENT_ */
- X# endif /* UTHOST */
- X
- X wi->w_slot = (slot_t) 0;
- X if (!utmpok)
- X return -1;
- X if ((slot = TtyNameSlot(wi->w_tty)) == (slot_t) NULL)
- X {
- X debug1("SetUtmp failed (tty %s).\n",wi->w_tty);
- X return -1;
- X }
- X debug2("SetUtmp %d will get slot %d...\n", wi->w_number, (int)slot);
- X# ifdef UTNOKEEP
- X /* open here, as TtyNameSlot used (and closed) our filedescriptor */
- X InitUtmp();
- X# endif /* UTNOKEEP */
- X
- X bzero((char *) &u, sizeof u);
- X if ((saved_ut = bcmp((char *) &wi->w_savut, (char *) &u, sizeof u)))
- X /* restore original, of which we will adopt all fields but ut_host */
- X bcopy((char *) &wi->w_savut, (char *) &u, sizeof u);
- X
- X# ifdef UTHOST
- X host[sizeof(host)-5] = '\0';
- X if (display)
- X {
- X# ifdef _SEQUENT_
- X strncpy(host, d_loginhost, sizeof(host) - 5);
- X# else /* _SEQUENT */
- X strncpy(host, d_utmp_logintty.ut_host, sizeof(host) - 5);
- X# endif /* _SEQUENT */
- X if (d_loginslot != (slot_t)0 && d_loginslot != (slot_t)-1 && host[0] != '\0')
- X {
- X /*
- X * we want to set our ut_host field to something like
- X * ":ttyhf:s.0" or
- X * "faui45:s.0" or
- X * "132.199.81.4:s.0" (even this may hurt..), but not
- X * "faui45.informati"......:s.0
- X */
- X for (p = host; *p; p++)
- X if ((*p < '0' || *p > '9') && (*p != '.'))
- X break;
- X if (*p)
- X {
- X for (p = host; *p; p++)
- X if (*p == '.')
- X {
- X *p = '\0';
- X break;
- X }
- X }
- X }
- X else
- X {
- X strncpy(host + 1, stripdev(d_usertty), sizeof(host) - 6);
- X host[0] = ':';
- X }
- X }
- X else
- X strncpy(host, "local", sizeof(host) - 5);
- X sprintf(host + strlen(host), ":S.%c", '0' + wi->w_number);
- X debug1("rlogin hostname: '%s'\n", host);
- X# if !defined(_SEQUENT_) && !defined(sequent)
- X strncpy(u.ut_host, host, sizeof(u.ut_host));
- X# endif
- X# endif /* UTHOST */
- X
- X# ifdef _SEQUENT_
- X if (ut_add_user(saved_ut ? u.ut_user : LoginName, slot, saved_ut ? u.ut_pid : wi->w_pid, host) == 0)
- X# else /* _SEQUENT_ */
- X if (!saved_ut)
- X { /* make new utmp from scratch */
- X line = stripdev(wi->w_tty);
- X# ifdef GETUTENT
- X strncpy(u.ut_user, LoginName, sizeof(u.ut_user));
- X# ifdef sgi
- X strncpy(u.ut_id, line + 3, sizeof(u.ut_id));
- X# else /* sgi */
- X strncpy(u.ut_id, line + strlen(line) - 2, sizeof(u.ut_id));
- X# endif /* sgi */
- X strncpy(u.ut_line, line, sizeof(u.ut_line));
- X u.ut_pid = wi->w_pid;
- X u.ut_type = USER_PROCESS;
- X (void) time((time_t *)&u.ut_time);
- X } /* !saved_ut {-: */
- X setutent();
- X if (pututline(&u) == 0)
- X# else /* GETUTENT */
- X strncpy(u.ut_line, line, sizeof(u.ut_line));
- X strncpy(u.ut_name, LoginName, sizeof(u.ut_name));
- X# if defined(linux) /* should have GETUTENT */
- X u.ut_type = USER_PROCESS;
- X u.ut_pid = wi->w_pid;
- X strncpy(u.ut_id, line + 3, sizeof(u.ut_id));
- X# endif /* linux */
- X (void) time((time_t *)&u.ut_time);
- X } /* !saved_ut */
- X# ifdef sequent
- X /*
- X * call sequent undocumented routine to count logins and
- X * add utmp entry if possible
- X */
- X if (add_utmp(slot, &u) == -1)
- X# else /* sequent */
- X (void) lseek(utmpfd, (off_t) (slot * sizeof u), 0);
- X if (write(utmpfd, (char *) &u, sizeof u) != sizeof u)
- X# endif /* sequent */
- X# endif /* GETUTENT */
- X# endif /* _SEQUENT_ */
- X
- X {
- X# ifdef NETHACK
- X if (nethackflag)
- X Msg(errno, "%s is too hard to dig in", UTMPFILE);
- X else
- X# endif /* NETHACK */
- X Msg(errno,"Could not write %s", UTMPFILE);
- X# ifdef UTNOKEEP
- X close(utmpfd);
- X# endif /* UTNOKEEP */
- X return -1;
- X }
- X debug("SetUtmp successful\n");
- X wi->w_slot = slot;
- X# ifdef UTNOKEEP
- X close(utmpfd);
- X# endif /* UTNOKEEP */
- X return 0;
- X}
- X
- X
- X
- X/*
- X * if slot could be removed or was 0, wi->w_slot = -1;
- X * else not changed.
- X */
- X
- Xint
- XRemoveUtmp(wi)
- Xstruct win *wi;
- X{
- X# ifdef GETUTENT
- X struct utmp *uu;
- X# endif /* GETUTENT */
- X struct utmp u;
- X slot_t slot;
- X
- X slot = wi->w_slot;
- X# ifdef GETUTENT
- X debug1("RemoveUtmp(%s)\n", (slot == (slot_t) 0) ?
- X "no slot (0)":((slot == (slot_t) -1) ? "no slot (-1)" : slot));
- X# else /* GETUTENT */
- X debug1("RemoveUtmp(wi.slot: %d)\n", slot);
- X# endif /* GETUTENT */
- X# ifdef UTNOKEEP
- X InitUtmp();
- X# endif /* UTNOKEEP */
- X if (!utmpok)
- X return -1;
- X if (slot == (slot_t) 0 || slot == (slot_t) -1)
- X {
- X debug1("There is no utmp-slot to be removed(%d)\n", (int)slot);
- X wi->w_slot = (slot_t) -1;
- X return 0;
- X }
- X bzero((char *) &u, sizeof u);
- X# ifdef GETUTENT
- X setutent();
- X strncpy(u.ut_line, slot, sizeof(u.ut_line));
- X if ((uu = getutline(&u)) == 0)
- X {
- X Msg(0, "Utmp slot not found -> not removed");
- X return -1;
- X }
- X bcopy((char *)uu, (char *)&wi->w_savut, sizeof(wi->w_savut));
- X# ifdef _SEQUENT_
- X if (ut_delete_user(slot, uu->ut_pid, 0, 0) == 0)
- X# else /* _SEQUENT_ */
- X u = *uu;
- X u.ut_type = DEAD_PROCESS;
- X u.ut_exit.e_termination = 0;
- X u.ut_exit.e_exit= 0;
- X if (pututline(&u) == 0)
- X# endif /* _SEQUENT_ */
- X# else /* GETUTENT */
- X (void) lseek(utmpfd, (off_t) (slot * sizeof(u)), 0);
- X if (read(utmpfd, (char *) &wi->w_savut, sizeof(wi->w_savut)) != sizeof u)
- X {
- X bzero((char *)&wi->w_savut, sizeof(wi->w_savut));
- X Msg(errno, "cannot read %s?", UTMPFILE);
- X sleep(1);
- X }
- X (void) lseek(utmpfd, (off_t) (slot * sizeof(u)), 0);
- X# ifdef UTNOKEEP
- X bcopy((char *)&wi->w_savut, (char *)&u, sizeof(u));
- X bzero(u.ut_name, sizeof(u.ut_name));
- X bzero(u.ut_host, sizeof(u.ut_host));
- X# endif /* UTNOKEEP */
- X if (write(utmpfd, (char *) &u, sizeof(u)) != sizeof(u))
- X# endif /* GETUTENT */
- X {
- X# ifdef NETHACK
- X if (nethackflag)
- X Msg(errno, "%s is too hard to dig in", UTMPFILE);
- X else
- X# endif /* NETHACK */
- X Msg(errno,"Could not write %s", UTMPFILE);
- X# ifdef UTNOKEEP
- X close(utmpfd);
- X# endif /* UTNOKEEP */
- X return -1;
- X }
- X debug("RemoveUtmp successfull\n");
- X wi->w_slot = (slot_t) -1;
- X# ifdef UTNOKEEP
- X close(utmpfd);
- X# endif /* UTNOKEEP */
- X return 0;
- X}
- X
- X
- X
- X/*
- X * TtyNameSlot:
- X * return an index, where the named tty is found in utmp.
- X */
- X
- Xstatic slot_t
- XTtyNameSlot(nam)
- Xchar *nam;
- X{
- X char *name;
- X register slot_t slot;
- X# ifdef UTNOKEEP
- X struct utmp u;
- X# else
- X# ifndef GETUTENT
- X register struct ttyent *tp;
- X# endif /* GETUTENT */
- X# endif /* UTNOKEEP */
- X
- X debug1("TtyNameSlot(%s)\n", nam);
- X# ifdef UTNOKEEP
- X InitUtmp();
- X# endif /* UTNOKEEP */
- X if (!utmpok || nam == NULL)
- X return (slot_t)0;
- X name = stripdev(nam);
- X# ifdef GETUTENT
- X slot = name;
- X# else /* GETUTENT */
- X# ifdef UTNOKEEP
- X slot = 0;
- X while ((read(utmpfd, (char *)&u, sizeof(u)) == sizeof(u))
- X && (strcmp(u.ut_line, name)))
- X slot++;
- X close(utmpfd);
- X# else /* UTNOKEEP */
- X slot = 1;
- X setttyent();
- X while ((tp = getttyent()) != NULL && strcmp(name, tp->ty_name) != 0)
- X slot++;
- X# endif /* UTNOKEEP */
- X# endif /* GETUTENT */
- X return slot;
- X}
- X
- X
- X
- X# if !defined(GETTTYENT) && !defined(GETUTENT) && !defined(UTNOKEEP)
- X
- Xstatic void
- Xsetttyent()
- X{
- X struct stat s;
- X register int f;
- X register char *p, *ep;
- X
- X if (ttnext)
- X {
- X ttnext = tt;
- X return;
- X }
- X if ((f = open(ttys, O_RDONLY)) == -1 || fstat(f, &s) == -1)
- X Panic(errno, ttys);
- X if ((tt = malloc((unsigned) s.st_size + 1)) == 0)
- X Panic(0, strnomem);
- X if (read(f, tt, s.st_size) != s.st_size)
- X Panic(errno, ttys);
- X close(f);
- X for (p = tt, ep = p + s.st_size; p < ep; ++p)
- X if (*p == '\n')
- X *p = '\0';
- X *p = '\0';
- X ttnext = tt;
- X}
- X
- Xstatic struct ttyent *
- Xgetttyent()
- X{
- X static struct ttyent t;
- X
- X if (*ttnext == '\0')
- X return NULL;
- X t.ty_name = ttnext + 2;
- X ttnext += strlen(ttnext) + 1;
- X return &t;
- X}
- X
- X# endif /* !GETTTYENT && !GETUTENT && !UTNOKEEP */
- X
- X
- X#endif /* UTMPOK */
- X
- X
- X
- X/*********************************************************************
- X *
- X * getlogin() replacement (for SVR4 machines)
- X */
- X
- X# if defined(BUGGYGETLOGIN)
- Xchar *
- Xgetlogin()
- X{
- X char *tty;
- X#ifdef utmp
- X# undef utmp
- X#endif
- X struct utmp u;
- X static char retbuf[sizeof(u.ut_user)+1];
- X int fd;
- X
- X for (fd = 0; fd <= 2 && (tty = ttyname(fd)) == NULL; fd++)
- X ;
- X if ((tty == NULL) || ((fd = open(UTMP_FILE, O_RDONLY)) < 0))
- X return NULL;
- X tty = stripdev(tty);
- X retbuf[0] = '\0';
- X while (read(fd, (char *)&u, sizeof(struct utmp)) == sizeof(struct utmp))
- X {
- X if (!strncmp(tty, u.ut_line, sizeof(u.ut_line)))
- X {
- X strncpy(retbuf, u.ut_user, sizeof(u.ut_user));
- X retbuf[sizeof(u.ut_user)] = '\0';
- X if (u.ut_type == USER_PROCESS)
- X break;
- X }
- X }
- X close(fd);
- X
- X return *retbuf ? retbuf : NULL;
- X}
- X# endif /* BUGGYGETLOGIN */
- X
- END_OF_FILE
- if test 18794 -ne `wc -c <'utmp.c'`; then
- echo shar: \"'utmp.c'\" unpacked with wrong size!
- fi
- # end of 'utmp.c'
- fi
- echo shar: End of archive 3 \(of 10\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 10 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-