From 0636e9ecb5a32db4d4520f50a20652faa825feaf Mon Sep 17 00:00:00 2001 From: Axel Beckert Date: Sat, 3 Sep 2011 14:05:19 +0200 Subject: Imported Upstream version 3.7.2 --- COPYING | 339 +++ ChangeLog | 409 +++ FAQ | 253 ++ INSTALL | 110 + Makefile | 2 + Makefile.in | 253 ++ NEWS | 80 + NEWS.3.5 | 119 + NEWS.3.6 | 48 + README | 102 + acls.c | 545 ++++ acls.h | 89 + ansi.c | 2511 ++++++++++++++++++ ansi.h | 116 + attacher.c | 815 ++++++ comm.c | 223 ++ comm.h.dist | 177 ++ comm.sh | 77 + config.h.in | 466 ++++ configure | 3257 ++++++++++++++++++++++++ configure.in | 1033 ++++++++ display.c | 1937 ++++++++++++++ display.h | 222 ++ doc/FAQ | 253 ++ doc/Makefile.in | 54 + doc/fdpat.ps | 6501 +++++++++++++++++++++++++++++++++++++++++++++++ doc/install.sh | 119 + doc/screen.1 | 3349 ++++++++++++++++++++++++ doc/screen.info | 167 ++ doc/screen.info-1 | 1514 +++++++++++ doc/screen.info-2 | 1255 +++++++++ doc/screen.info-3 | 1381 ++++++++++ doc/screen.info-4 | 375 +++ doc/screen.texinfo | 4061 +++++++++++++++++++++++++++++ etc/etcscreenrc | 95 + etc/mkinstalldirs | 35 + etc/newsyntax | 64 + etc/screenrc | 124 + etc/toolcheck | 44 + extern.h | 315 +++ fileio.c | 760 ++++++ help.c | 857 +++++++ image.h | 106 + input.c | 291 +++ install.sh | 119 + kmapdef.c.dist | 130 + loadav.c | 249 ++ mark.c | 1320 ++++++++++ mark.h | 47 + misc.c | 468 ++++ os.h | 480 ++++ osdef.h.in | 182 ++ osdef.sh | 46 + overlay.h | 68 + patchlevel.h | 237 ++ process.c | 3777 +++++++++++++++++++++++++++ pty.c | 331 +++ putenv.c | 213 ++ rcs.h | 46 + resize.c | 750 ++++++ screen.c | 2605 +++++++++++++++++++ screen.h | 251 ++ search.c | 336 +++ socket.c | 1190 +++++++++ tek.patch | 79 + term.c | 257 ++ term.h.dist | 237 ++ term.sh | 166 ++ termcap.c | 1272 ++++++++++ terminfo/8bits | 17 + terminfo/README | 19 + terminfo/checktc.c | 204 ++ terminfo/sco.mail | 65 + terminfo/screencap | 21 + terminfo/screeninfo.src | 48 + terminfo/test.txt | 603 +++++ terminfo/tetris.c | 20 + tty.c.dist | 1025 ++++++++ tty.sh | 862 +++++++ utmp.c | 800 ++++++ window.c | 1118 ++++++++ window.h | 233 ++ 82 files changed, 54794 insertions(+) create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 FAQ create mode 100644 INSTALL create mode 100644 Makefile create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 NEWS.3.5 create mode 100644 NEWS.3.6 create mode 100644 README create mode 100644 acls.c create mode 100644 acls.h create mode 100644 ansi.c create mode 100644 ansi.h create mode 100644 attacher.c create mode 100644 comm.c create mode 100644 comm.h.dist create mode 100644 comm.sh create mode 100644 config.h.in create mode 100755 configure create mode 100644 configure.in create mode 100644 display.c create mode 100644 display.h create mode 100644 doc/FAQ create mode 100644 doc/Makefile.in create mode 100644 doc/fdpat.ps create mode 100755 doc/install.sh create mode 100644 doc/screen.1 create mode 100644 doc/screen.info create mode 100644 doc/screen.info-1 create mode 100644 doc/screen.info-2 create mode 100644 doc/screen.info-3 create mode 100644 doc/screen.info-4 create mode 100644 doc/screen.texinfo create mode 100644 etc/etcscreenrc create mode 100755 etc/mkinstalldirs create mode 100755 etc/newsyntax create mode 100644 etc/screenrc create mode 100755 etc/toolcheck create mode 100644 extern.h create mode 100644 fileio.c create mode 100644 help.c create mode 100644 image.h create mode 100644 input.c create mode 100755 install.sh create mode 100644 kmapdef.c.dist create mode 100644 loadav.c create mode 100644 mark.c create mode 100644 mark.h create mode 100644 misc.c create mode 100644 os.h create mode 100644 osdef.h.in create mode 100644 osdef.sh create mode 100644 overlay.h create mode 100644 patchlevel.h create mode 100644 process.c create mode 100644 pty.c create mode 100644 putenv.c create mode 100644 rcs.h create mode 100644 resize.c create mode 100644 screen.c create mode 100644 screen.h create mode 100644 search.c create mode 100644 socket.c create mode 100644 tek.patch create mode 100644 term.c create mode 100644 term.h.dist create mode 100644 term.sh create mode 100644 termcap.c create mode 100644 terminfo/8bits create mode 100644 terminfo/README create mode 100644 terminfo/checktc.c create mode 100644 terminfo/sco.mail create mode 100644 terminfo/screencap create mode 100644 terminfo/screeninfo.src create mode 100644 terminfo/test.txt create mode 100644 terminfo/tetris.c create mode 100644 tty.c.dist create mode 100644 tty.sh create mode 100644 utmp.c create mode 100644 window.c create mode 100644 window.h diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..13c9d42 --- /dev/null +++ b/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 0000000..2256d80 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,409 @@ +30.10.94 + +This is a quick overview of screen's life story. But it is not up +to date. You'll find more details about the revision history in +patchlevel.h and newer changes are only documented there. + +31.7.93 -- 3.5.1 +================ + +* writelock, number, paste with arg, at, zombie and wall commands added. + +* Access Control Lists and more multi-user support added. + +* select and setenv commands enhanced. + +* socket.c: motorola bugfix. + +* configure.in: --srcdir support. + +* configure.in: recognize alpha and SUNOS3 correctly. + +* doc/screen.texinfo: Documentation by Jason Merrill. + +13.05.93 -- 3.3.3 +================= + +* defautonuke, silence commands added. + +* exec command added. + +* hardcopydir, logdir commands added. + +* Made a superb configure script. + +* BROKEN_PIPE, SOCK_NOT_IN_FS added for braindamaged systems. + +* multi display, multi user support. + +* process command. CS, CE switch cursorkeycap in application mode. + +* lockprg pow_detaches on SIGHUP + +* ins_reg copy_reg commands. + +* new screenrc syntax. + +* split up screen.c and ansi.c + +21.10.92 -- 3.2.9 +================ + +* ChangeLog: replaces CHANGES and is in GNUish format. + +* Makefile (CFLAGS, M_CFLAGS, LIBS, OPTIONS): moved user config here, + merged all Makefiles, GNUified + +* socket.c (FindSocket): ignoring bad files in $SCREENDIR + +* config/config.linux: ported. + +* utmp.c, exec.c, loadav.c: split apart from screen.c/fileio.c + +15.07.92 -- 3.2.8 +================= + +* ansi.c (WriteString): automatic character set switching for 8bit support + +3.2.3-3.2.7 +=========== + +* concept changes: Display structure, Multi attacher + +... + +3.2.2 +===== + +* screen.c (main): -m option, "_M_ake always new session", ignore $STY + +* screen.c (main): -Ssessionname +* fileio.c (RcLine): ^A:sessionname give your session a nicer name. + +* screen.c (main): supporting detached startup via screen -d -m -Ssockname + +* fileio.c (stripdev): moved, could not compile + +* overlay.h: "stackable overlay concept" + +* search.c: vi-like / and ? search AND emacs-like ^S and ^R incremental search + in scrollback + +* mark.c: I meant BSDI not BSD + +* concept change: struct display and struct newwin introduced. + +* screen.c (main): -v option prints version. + +* screen.c (MakeWindow): ^A:screen /dev/ttya opens a character device + instead of forking ShellProg with a pty pair. + +3.2.0 +===== + +Ultrix port + +Irix 3.3 SGI port + +shadow password suite supported + +data loss on stdin overflow fixed + +"refresh off" keyword added. + +3.1.1 +------ + +Screen is now under the GNU copyleft license. See file COPYING. + +command line option -A. $LINES, $COLUMNS improved. + +C-A : vbellwait + +XENIX support (Ronald Khoo) + +SYSV has uname() instead of gethostname(). + +hpux has setresuid. + +ClearScreen now saves image to scrollback buffer. + +mips has setenv. + +numerous bugfixes. + +3.1 finally released version. +============================= + +3.0.99: last minute changes: +---------------------------- + +MIPS support (J{rvinen Markku) + +SVR4 support (Marc Boucher) + +secopen() secfopen() calls replace stat/access/open. +C-a : echo improved. +'register int' + +Changes up to Screen 3.0 Patchlevel 7 +===================================== + +Better terminfo support: Screen now checks if a termcap/info +entry which the name "screen.$TERM" does exist. Look in the +"VIRTUAL TERMINAL" section of the manual for more details. + +Many security improvements. + +ScrollRegion() bug fixed which caused slow scrolling if AL +or DL was used. + +Pyramid and Ultrix support added. (Tim and Larry) + +ENVIRONMENT support. + /local/etc/screenrc checks for $SYSSCREENRC + $HOME/.screenrc checks for $ISCREENRC and $SCREENRC + /local/screens checks for $ISCREENDIR and $SCREENDIR + .screenrc understands ${VAR} and $VAR . + +screen 3.0 Patchlevel 6 +======================= + +.screenrc: + screen now only opens the windows you explicitly ask for. if you + specify none, you still get one window, of course. + +screen 3.0. Patchlevel 5 +======================== + +Ansi prototyping by Christos. + +copy mode: CTRL-U / CTRL-D exchanged. code cleanup. + +changes to screen 3.0 patchlevel 4 +================================== + +markkeys "string" + allows to rebind the keys used in copy/history mode. + string is made up of pairs "=" which are separated + by a colon. Oldchar and newchar are either single ascii characters, + or the two character sequence ^x, where x is an ascii character, or + a 3 digit octal value prepended with '\'. the string "\040=.:^M=q" + rebinds '.' to set marks, and the return rey will abort copy mode. + +set scrollback 100 + resizes the scrollback history buffer to 100 lines. a default of 50 + is installed. + +A Howard Chu like scrollback history is installed. Many vi-like keys + are added to the copy mode. The '?' key reports on cursor position. + +screen 3.0 Patchlevel 3 +======================= + +WriteString fixed, it did kill the display variable. + +Yet another LP bugfix. + +non vt100 semi-graphics character support. + +waynes patch fixed + +screen 3.0 Patchlevel 2 +======================= + +wayne patches cursor motion outside scrollregions. + +.screenrc + monitor on|off + +changes in Screen 3.0 Patchlevel 1 +================================== + +screen -wipe + +^A : set vbell_msg "Wuff Wuff" + +Thousand enhancements: help resizible, copy'n'paste in main + socket loop, and no more '\0' hackin'. :WS=\E8;%d;%dt: + +screen can now resize windows under sunview. + +^A : set crlf on|off + effects markroutine join. + +screen learned about sized windows under X + +screen -ls (-d) -q + quiet option. We count the number of detached (attached) sessions and set + a return value of 10+n. The -q option inhibits all startup + warnings/messages. i.e. screen -R -q may return with code 12 or higher + or start a new/old session. + +pow_detach_msg "text string" + new command, allows messages, terminal reset, etc. on logout caused + by pow_detach. + +^A : learned a new keyword "set": + commands like "login on" , "vbell off", ... affect the default for + windows to be created. But commands like "set login off" affect + the actual setting of this window. and not the default. + such commands may be bound to keys. example: + bind 'O' set login off + is valid in your .screenrc as well as typed at the ':' prompt. + a bonus is ":set all" which is synonym to ":help". + At the Colon prompt also KeyNames can be entered, alothough that makes + not always sense. + +^A x uses a builtin lockprg, if + a) we don't find our lockprg, or + b) user supplies us with the environmet variable LOCKPRG set to "builtin" + the builtin locks until your login password is typed. on systems using + "shadow password files" you are prompted for a password. + +markroutine can append joined. + +screen removes the "controlling tty" from utmp while ptys are attached. + +markroutine performs CR+NL when '\n' is pressed + +screen may die quietly, when no TERMCAP entry for "screen" is +found, and screen is run under X-windows + +_SEQUENT_ marks sequent386_ptx + +screen runs now under SunOS4.1.1 (we need setsid()!). + +bug in SetForeWindow fixed. + +rare markroutine bug fixed. + +we dont open every file the attacher tells us. + +we have now our wonderful "Wuff, Wuff" visual_bell + +we have now the interprocess-communication-buffer. secure version. + +'^A =' removes the interprocess-communication-buffer. + +markroutine as in 2.1 + +markroutine: 'a' toggles append mode, + '>' like ' ', but immediately WriteFile(DUMP_EXCHANGE) then. + 'A' like ' ', but first switch to append mode. + +.screenrc understands "screen 2:faui09 rlogin faui09 -l jnweiger" + and "password none" + and "vbell [on|off]" + +'^A :' allows .screenrc commands "online". + +screen now receives new $TERM from attacher, when it is reattached + +MakeClientSocket() fifo version does now test for access. + +.screenrc learns "hardstatus {on|off}" + +termcap's VB is used for vbell if available. + +Attach() code rewritten: + screen now lists socket directory, if it does not find a suitable socket + screen -d [host.tty] detaches a running screen. + +screen -[ls|list] + list all sockets that we find in our sockdir + +when the socket has been removed, send a SIGCHLD to the poor SCREEN +process and it will try to recover. then try a 'screen -r' again. +all the socket stuff lives now in an extra file. + +Major changes in version 2.4: +============================= + +* Test version that presents the erlangen extensions from 2.0 in a 2.3 + screen. + +* window resize support + +* screen locking C-a x + +* support for SYSV + +* password protection + +* copy & paste across screens + +* remote detach and power detach + +Major changes in version 2.3: + +* Terminal emulation has been significantly enhanced and bugfixed. + +* We now fully update the last character on the screen for true auto- + margin terminals, though there may be some delay before the character + can be safely added to the screen. If your terminal has character + insert it will be used to shorten the delay. + +* Added the "termcap" .screenrc command to tweak your terminal's termcap + entry AND to customize the termcap generated for the virtual terminals. + See also the -L and -O command-line options, and the SCREENCAP environ- + ment variable. + +* Fixed screen's character handling when detached or suspended to NOT block + the child processes in their windows -- output continues to be processed + in the background. + +* Added a.k.a.s (window-name aliases) that allow you to customize the + window-information line, including being able to change the name on- + the-fly to reflect what's currently running in the window (see the + -k option, shellaka command, and ALSO KNOWN AS discussion in the doc). + +* Added the ability to log the output of a window to a file (see the + "C-a H" (log) command). + +* Flow-control can now be set for each window and switched interactively + (see the "flow" command, -f option, and FLOW CONTROL discussion). + +* Individual windows can be included or excluded from mention in the + /etc/utmp file (see the "login" command and -l option). + +* Added an activity monitor, which allows you to have a window watched for + the start of any output and alert you when it occurs (see the "C-a M" + (monitor) command). + +* Enhanced the information in the window-information line to keep track of + windows that have: logging turned on '(L)'; beeped in the background '!'; + became active while being monitored '@' (see the "C-a w" (windows) command). + +* Added an on-line help display that lists all the commands and their + key bindings (see the "C-a ?" (help) command). + +* Extended handling of the beep message (and also the new activity message) + to allow '~' to specify a literal beep (see the "beep" and "activity" + .screenrc commands). + +* You can now set the default action on receipt of a hangup signal: detach + or terminate (see the "autodetach" .screenrc command). + +* Routing of characters to their virtual terminals has been enhanced to + not drop characters nor (in rare circumstances) hang up screen. + +* The NFS compatibility has been enhanced. + +Major changes in version 2.0a: + +* Screen allows you to `detach' the "screen" session from the physical + terminal and resume it at a later point in time (possibly on a + different terminal or in a different login session). + + To get an impression of this functionality do the following: + + - call "screen" and create a couple of windows + - type Control-A Control-D (screen terminates; you are back + in the shell) + - call "screen -r" to resume the detached screen + +* Screen supports multiple character sets and the ISO 2022 control + functions to designate and switch between character sets. + This allows you, for instance, to make use of the VT100 graphics + character set or national character sets. diff --git a/FAQ b/FAQ new file mode 100644 index 0000000..6c9c8af --- /dev/null +++ b/FAQ @@ -0,0 +1,253 @@ + jw 21.10.93 + 05.05.94 + + screen: frequently asked questions -- known problems -- unimplemented bugs +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + +Q: Why is it impossible to download a file with Kermit/sz/rz when + screen is running? Do I need to set some special variables? + +A: Screen always interprets control-sequences sent by the + applications and translates/optimizes them for the current + terminal type. Screen always parses the user input for its + escape character (CTRL-A). Both are basic screen features and + cannot be switched off. Even if it were possible to switch + screen into a completely transparent mode, you could never switch + between windows, while kermit/sz/rz is downloading a file. You + must wait til the end as kermit/sz/rz will not transmit your + input during a file transfer and as kermit/sz/rz would be very + confused if screen switched away the window containing the + other kermit/sz/rz. Simply detach your screen session for each + file transfer and start the transfer program only from the shell + where you started screen. + +Q: I am using screen with a YYY terminal, which supports the XXX + graphic language. I am very happy with it, except one thing: I + cannot render graphics into screen windows. + +A: You are out of luck there. Screen provides a fixed set of escape + sequences in order to make it possible to switch terminal types. + Screen has to know exactly what the escape sequences do to the + terminal because it must hold an image in memory. Otherwise + screen could not restore the image if you switch to another + window. Because of this you have to change screens escape + sequence parser (ansi.c) to pass the XXX graphics sequences to + the terminal. Of course the graphics will be lost if you switch + to another window. Screen will only honour graphics sequences + that are demanded by an overwhelming majority. + +Q: For some unknown reason, the fifo in /tmp/screens/S-myname is + gone, and i can't resume my screen session. Is there a way to + recreate the fifo? + +A: Screen checks the fifo/socket whenever it receives a SIGCHLD + signal. If missing, the fifo/socket is recreated then. If screen + is running non set-uid the user can issue a 'kill -CHLD + screenpid' directly (it is -CHILD on some systems). Screenpid is + the process-id of the screen process found in a 'ps -x' listing. + But usually this won't work, as screen should be installed set- + uid root. In this case you will not be able to send it a signal, + but the kernel will. It does so, whenever a child of screen + changes its state. Find the process-id (shellpid below) of the + "least important" shell running inside screen. The try 'kill + -STOP shellpid'. If the fifo/socket does not reappear, destroy + the shell process. You sacrify one shell to save the rest. If + nothing works, please do not forget to remove all processes + running in the lost screen session. + +Q: When you start "screen" a page of text comes up to start you + off. Is there a way to get rid of this text as a command line + argument or by using a switch of some sort. + +A: Just put the following line in your ~/.screenrc: + startup_message off + Many peole ask this, although it is in the man page, too :-) + +Q: Start "screen emacs" and run emacs function suspend-emacs + (ctrl-z). The window containing emacs vanishes. + +A: This is a known bug. Unfortunatly there is no easy fix + because this is specified in the POSIX standard. When a new + window is created Screen opens up a new session because the + window has to get the pty as a controlling terminal (a + session can only have one controlling terminal). With the + setsid() call the process also creates a new process + group. This process group is orphaned, because there is no + process in the session which is not in the process + group. Now if the process group leader (i.e. your program) + gets a TTIN/TTOU/TSTP, POSIX states that the kernel must + send a KILL signal to the process group because there is no + one left to continue the process. Even if screen would + try to restart the program, that would be after it received the + KILL signal which cannot be caught or ignored. + + tromey@klab.caltech.edu (Tom Tromey): I've noticed this exact + same problem. I put this in my .emacs file. It seems to work: + + ;; If running under screen, disable C-z. + (if (and (getenv "STY") (not window-system)) + (global-unset-key "\C-z")) + +Q: Screen gets the terminal size wrong and messes up. + +A: Before you start screen: Check with 'stty -a' what the terminal + driver thinks about rows and columns. Check the environment + variables LINES and COLUMNS. Then from within screen check with + the info command (CTRL-A i) what size screen thinks your terminal + is. If correcting tty driver setting and environment variables + does not help, look up the terminal capability definition. First + the TERMCAP environment variable. If this is not set, look up the + terminals name as defined in the environment variable TERM in + /etc/termcap or in the terminfo database with untic or infocmp. + There may be :li=...: and :co=...: or even :ll=...: entries + (cols#... and lines#... when it's terminfo) defined incorrectly. + Either construct your own TERMCAP environment variables with + correct settings, use screens terminfo/termcap command in your + .screenrc file or have the database corrected by the system + administrator. + +Q: Screen messes up the terminal output when I use my favourite ap- + plication. Setting the terminal size does not help. + +A: Probably you got the termcap/terminfo entries wrong. Fixing this + is a three stage procedure. First, find out if terminfo or + termcap is used. If your system only has /etc/termcap, + but not /usr/lib/terminfo/... then you are using termcap. + Easy. But if your system has both, then it depends how the appli- + cation and how screen were linked. Beware, if your applica- + tion runs on another host via rlogin, telnet or the like, you + should check the terminfo/termcap databases there. If you cannot + tell if terminfo or termcap is used (or you just want to be + save), the do all steps in stage 3 in parallel for both + systems (on all envolved hosts). Second: Understand the basic + rules how screen does its terminal emulation. When screen is + started or reattached, it relies on the TERM environment variable + to correctly reflect the terminal type you have physically + in front of you. And the entry should either exist in the system + terminfo/termcap database or be specified via the TERMCAP en- + vironment variable (if screen is using the termcap system). On + the other end, screen understands one set of control codes. It + relies on the application using these codes. This means applica- + tions that run under screen must be able to adapt their con- + trol codes to screen. The application should use the TERM vari- + able and termcap or terminfo library to find out how to drive + its terminal. When running under screen, the terminal is virtual + and is only defined by the set of control codes that screen + understands. The TERM variable is automatically set to + "screen" and the "screen"-entries should exist in the data- + bases. If your application uses hardcoded control codes rather + than a database, you are on your own. Hint: The codes under- + stood by screen are a superset of the very common definition + named "vt100". Look at the documentation of screen. The + codes are listed there. Third: Have the entry "screen" in- + stalled on all hosts or make sure you can live with "vt100". + Check the codes sent by your application, when the TERM variable + is set to "screen". Do not try to set the TERM variable inside + screen to anything other than "screen" or "vt100" or compati- + ble. Thus your application can drive screen correctly. Also take + care that a good entry is installed for your physical terminal + that screen has to drive. Even if the entry was good enough + for your application to drive the terminal directly, screen may + find flaws, as it tries to use other capabilities while op- + timizing the screen output. The screenrc commands + "termcap" and/or "terminfo" may help to fine-tune capabilities + without calling the supervisor to change the database. + +Q: I cannot configure screen. Sed does not work. + +A: The regular expressions used in our configure scrip are too + complicated for GNU sed version 2.03. In this regard it is bug + compatible with Ultrix 3.1 "sed": GNU sed version 2.03 dumps + core with our configure script. Try an older release. E.g. from + ftp.uni-erlangen.de:/pub/utilities/screen/sed-2.02b.tar.gz + +Q: When reattaching a session from a different Workstation, the + DISPLAY environment variable should be updated. Even ``CTLR-A + : setenv DISPLAY newhost:0'' does not work as expected. + +A: Under unix every process has its own environment. The environ- + ment of the SCREEN process can be changed with the `setenv' com- + mand. This however cannot affect the environment of the + shells or applications already running under screen. Subsequently + spawned processes will reflect the changes. One should be aware + of this problem when running applications from very old shells. + Screen is a means for keeping processes alive. + +Q: About once every 5 times I ran the program, rather than getting + a "screen," I got someone elses IRC output/input. + +A: What probably happened is that an IRC process was left running on + a pseudo tty in such a way that the kernel thought the tty was + available for reallocation. You can fix this behaviour by + applying the SunOS 4.1.x tty jumbo patch (100513-04). + +Q: Screen compiled on SunOS 5.3 cannot reattach a detached session. + +A: You are using /usr/ucb/cc, this compiler is wrong. Actually it + links with a C-library that mis-interprets dirent. Try again + with /opt/SUNWspro/bin/cc! + +Q: The "talk" command does not work when Screen is active. + +A: Talk and several other programs rely on entries in the Utmp- + Database (/etc/utmp). On some systems this Database is world + writable, on others it is not. If it is not, screen must be + installed with the appropriate permissions (user or group s-bit) + just like any program that uses PTYs (rlogin, xterm, ...). When + screen cannot write to utmp, you will see messages on you display + which do not belong to any screen window. + When screen can update utmp, it is not guaranteed that it does as + you expect. First this depends on the config.h file defining + UTMPOK, LOGINDEFAULT, and perhaps CAREFULUTMP. Second it depends + on the screenrc files (system wide and per user), if utmp entries + are done. Third, you can control whether windows are logged in + with screens ``login'' command. + +Q: Seteuid() does not work as expected in AIX. Attempting a multi- + user-attach results in a screen-panic: "seteuid: not owner". + +A: This is not a screen problem. According to Kay Nettle + (pkn@cs.utexas.edu) you need the AIX patch PTF 423674. + +Q: When I type cd directory (any directory or just blank) from + within one of the windows in screen, the whole thing just freezes + up. + +A: You display the current working directory in xterm's title bar, + This may be caused by hardcoded ESC-sequences in the shell prompt + or in an cd alias. In Xterm the coding is + ESC ] n ; string_to_display ^G + where n = 1, 2, 3 selects the location of the displayed string. + Screen misinterprets this as the ansi operating system comment + sequence: + ESC ] osc_string + and waits (according to ansi) for the string terminator + ESC \ + Screen versions after 3.5.12 may provide a workaround. + +Q: Mesg or biff cannot be turned on or off while running screen. + +A: Screen failed to change the owner of the pty it uses. You need to + install screen setuid-root. See the file INSTALL for details. + +Q: The cursor left key deletes the characters instead of just moving the + cursor. A redisplay (^Al) brings everything back. + +A: Your terminal emulator treats the backspace as "destructive". You + can probably change this somewhere in the setup. We can't think + of a reason why anybody would want a destructive backspace, but + if you really must have it, add the lines + termcap 'bc@:bs@' + terminfo 'bc@:bs@' + to your ~/.screenrc (replace with the terminal type your + emulator uses). + +Q: I have an old SysV OS (like Motorola SysV68) and sometimes screen + doesn't reset the attributes correctly. A redisplay (^Al) doesn't + make things better. + +A: The libcurses library has a bug if attributes are cleared with + the special ue/se capabilities. As a workaround (other than upgrading + your system) modify 'rmul' (and 'rmso'?) in screen's terminfo entry: + rmul=\E[m, rmso=\E[m diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..d382078 --- /dev/null +++ b/INSTALL @@ -0,0 +1,110 @@ +Installation of screen3.6 jw 9.04.95 + + +0.) This instruction is quite lengthy +------------------------------------- +.. and there are still important items near the end. Start here: +Unpack. Screen comes as a compressed tar archive. You need gzip to +uncompress. And... well, you probably already managed that step, +when you are reading this. + +For general documentation on the coding and usage standards this +distributions follows, see the GNU standards document on +prep.ai.mit.edu:pub/gnu/standards.*, especially the `Makefile +Conventions', `Configuration', and `User Interfaces' sections. + + +1.) configure & config.status +----------------------------- +Run configure. This should create a reasonable Makefile and a config.h file +suited for your machine. Rename config.status to reflect the architecture +(hostname) where it was built. To reconfigure quickly for that architecture +just run that config.status file. +If this process fails, try to find out what configure did do and what it +should have checked. Mail me. +Actually the initial Makefile that comes with the distribution just runs +configure -- thus you can start by typing 'make' right after unpacking. +You will be prompted to run 'make' again, which will really make screen. + +2.) Makefile & config.h +----------------------- +Look through the Makefile & user configuration section in config.h and check +pathnames. Change them to suit your installation requirements. Usually +sysadmins discuss the location of SOCKDIR, whether it should be in /tmp or +not. At least it must be on a filesystem that supports sockets/fifos. +SOCKDIR must not point into an AFS (Andrew File System) mounted directory. +If you are uncrertain about your NFS implementation, use a UFS directory for +SOCKDIR. Personally, I favour a users home directory and recommend the the +/tmp/ area. +The path for ETCSCREENRC may also need to be adapted. + +3.) how to actually compile +--------------------------- +Run 'make'. Screen should compile without too many warnings :) +The creation of term.h, comm.h, tty.c or osdef.h may fail on some machines +for some odd reason. (E.g. the sed under SCO-unix is known to be +case-insensitive and breaks term.h) If so, please mail a short description +of the problem to screen@uni-erlangen.de and use the files ending in .dist +as a replacement (or in case of osdef.h retry with an empty file). +You can then try 'make install' (if you dare). + +4.) where to install +-------------------- +You may well run screen from your private binary directory and with a +private socket directory like $HOME/.screen. But to have a full featured +screen and (from a users point of view) more secure pty's you should +consult a system administrator and discuss installing screen setuid-root +in some globally accessible directory like /usr/local/bin. + +Consider this, when deciding whether you install screen setuid-root: +- On some machines root priviliges are required to open pty's. +- Pty's should be owned by the user, so that she can do chmod to prevent + intrudor attacks. The PTYs used by screen will remain world read-writable + if screen is not installed setuid-root. +- Some commands only work properly when the pty is owned by the user. + These include mesg and biff. +- The ^At feature may need to lseek and read the kernel file to retrieve + the load average. +- On most machines utmp slots can only be created/manipulated with root + privileges. Users will appear to be logged on the primary terminal + instead of the screen windows, if screen is not installed setuid-root. +- Multi-user screen sessions are only allowed when screen has a root-s-bit. +- If screen sockets of multiple users are kept in one directory (e.g. + /tmp/screens), this directory must be world writeable when screen is not + installed setuid-root. Any user can remove or abuse any socket then. + + +5.) doc/screen.1 & doc/screen.texinfo +------------------------------------- +The man page doc/screen.1 should go to /usr/local/man/man1, or some similar +directory. It should format nicely with nroff -man. If it does not, then +try removing extra dots with: sed -e 's/^\.\././' < screen.1 | nroff -man +The info page doc/screen.texinfo contains basically the same information as +the man-page, we may have missed one or another thing in one of the files. +If so, mail me. + +6.) etc/screenrc & etc/etcscreenrc +---------------------------------- +The files screenrc and etc/etcscreenrc are instructive samples that +demonstrate what can/should be done from your private .screenrc and from +$ETCSCREENRC -- do not just copy them. Read them. Look through the +etcscreenrc file for system wide defaults that you like to set. e.g. +autodetach off, startup_message off, vbell on, ...aak +Since version 3.2.15 the screenrc file syntax changed slightly. All rc files +from previous versions should be run through the newsyntax script that comes +with this package. +If and only if you want to install screen as a console multiplexer, look +at the *.sample files and what 'make cscreen' suggests. + +7.) terminfo/screeninfo.src & terminfo/screencap +------------------------------------------------ +Every now and then we update the termcap/terminfo entries for screen. +E.g. keycodes were added in 3.6.0 -- thus you check that your termcap/terminfo +database is up to date. See the README in the terminfo subdirectory. + +8.) have fun +------------ +To get an idea what the basic screen commands are, read the file README. +Request snail mail address for liquid and solid donations. :-) + +Juergen Weigert. (screen@uni-erlangen.de) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9458230 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +install all Makefiles and config: + sh ./configure diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..f9fc599 --- /dev/null +++ b/Makefile.in @@ -0,0 +1,253 @@ +# +# Makefile template for screen +# +# See machine dependant config.h for more configuration options. +# + +srcdir = @srcdir@ +VPATH = @srcdir@ + +# Where to install screen. + +prefix = /usr/local +exec_prefix = $(prefix) + +# don't forget to change mandir and infodir in doc/Makefile. +bindir = $(exec_prefix)/bin + +VERSION = @VERSION@ + +ETCSCREENRC = `sed < config.h -n -e '/define ETCSCREENRC/s/^.*"\([^"]*\)"/\1/p'` + +CC = @CC@ +CFLAGS = -O +LDFLAGS = +LIBS = @LIBS@ + +CPP_DEPEND=/lib/cpp -MM + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_DATA = @INSTALL_DATA@ + +AWK = @AWK@ + +### Chose some debug configuration options: +# -DDEBUG +# Turn on really heavy debug output. This is written to +# /tmp/debug/screen.{front,back} Look at these files and quote +# questionable sections when sending bug-reports to the author. +# -DTMPTEST +# Change the socket directory to a location that does not interfere +# with the (suid-root) installed screen version. Use that in +# combination with -DDEBUG +# -DDUMPSHADOW +# With shadow-pw screen would never dump core. Use this option if you +# still want to have a core. Use only for debugging. +# -DFORKDEBUG +# Swap roles of father and son when forking the SCREEN process. +# Useful only for debugging. +OPTIONS= +#OPTIONS= -DDEBUG -DTMPTEST + +SHELL=/bin/sh + +CFILES= screen.c ansi.c fileio.c mark.c misc.c resize.c socket.c \ + search.c tty.c term.c window.c utmp.c loadav.c putenv.c help.c \ + termcap.c input.c attacher.c pty.c process.c display.c comm.c \ + kmapdef.c acls.c +OFILES= screen.o ansi.o fileio.o mark.o misc.o resize.o socket.o \ + search.o tty.o term.o window.o utmp.o loadav.o putenv.o help.o \ + termcap.o input.o attacher.o pty.o process.o display.o comm.o \ + kmapdef.o acls.o + +all: screen screen.info + +screen: $(OFILES) + $(CC) $(LDFLAGS) -o $@ $(OFILES) $(LIBS) + +.c.o: + $(CC) -c -I. -I$(srcdir) $(M_CFLAGS) $(DEFS) $(OPTIONS) $(CFLAGS) $< + +install_bin: screen + $(INSTALL_PROGRAM) screen $(bindir)/screen-$(VERSION) + -chown root $(bindir)/screen-$(VERSION) && chmod 4755 $(bindir)/screen-$(VERSION) +# This doesn't work if $(bindir)/screen is a symlink + -if [ -f $(bindir)/screen ] && [ ! -f $(bindir)/screen.old ]; then mv $(bindir)/screen $(bindir)/screen.old; fi + rm -f $(bindir)/screen + ln -s screen-$(VERSION) $(bindir)/screen + +install: installdirs install_bin + cd doc ; $(MAKE) install + -tic ${srcdir}/terminfo/screeninfo.src +# Better do this by hand. E.g. under RCS... +# cat ${srcdir}/terminfo/screencap >> /etc/termcap + @echo "termcap entry (${srcdir}/terminfo/screencap) should be installed manually." + @echo "You may also want to install $(srcdir)/etc/etcscreenrc in" $(ETCSCREENRC) + +installdirs: +# Path leading to ETCSCREENRC and Socketdirectory not checked. + $(srcdir)/etc/mkinstalldirs $(bindir) + cd doc ; $(MAKE) installdirs + +uninstall: + rm -f $(bindir)/screen-$(VERSION) + rm -f $(bindir)/screen + -mv $(bindir)/screen.old $(bindir)/screen + rm -f $(ETCSCREENRC) + cd doc; $(MAKE) uninstall + +shadow: + mkdir shadow; + cd shadow; ln -s ../*.[ch] ../*.in ../*.sh ../configure ../doc ../terminfo . + rm -f shadow/term.h shadow/tty.c shadow/comm.h shadow/osdef.h + +term.h: term.c term.sh + AWK=$(AWK) srcdir=$(srcdir) sh $(srcdir)/term.sh + +kmapdef.c: term.h + +tty.c: tty.sh + sh $(srcdir)/tty.sh tty.c + +comm.h: comm.c comm.sh config.h + AWK=$(AWK) CC="$(CC) $(CFLAGS)" srcdir=${srcdir} sh $(srcdir)/comm.sh + +osdef.h: osdef.sh config.h osdef.h.in + CC="$(CC) $(CFLAGS)" srcdir=${srcdir} sh $(srcdir)/osdef.sh + +docs: + cd doc; $(MAKE) dvi screen.info + +dvi info screen.info: + -cd doc; $(MAKE) $@ + +mostlyclean: + rm -f $(OFILES) screen + +clean celan: mostlyclean + rm -f tty.c term.h comm.h osdef.h + +# Delete all files from the current directory that are created by +# configuring or building the program. +# building of term.h/comm.h requires awk. Keep it in the distribution +# we keep config.h, as this file knows where 'make dist' finds the ETCSCREENRC. +distclean: mostlyclean + rm -f screen-$(VERSION).tar screen-$(VERSION).TZ + rm -f config.status Makefile + rm -f osdef.h doc/Makefile + echo "install all Makefiles and config:" > Makefile + echo " sh ./configure" >> Makefile + +# Delete everything from the current directory that can be +# reconstructed with this Makefile. +realclean: distclean + rm -f tty.c term.h comm.h + rm -f config.h + +TAGS: $(CFILES) + ctags $(CFILES) *.h + ctags -e $(CFILES) *.h + +dist: screen-$(VERSION).tar.gz + +screen-$(VERSION).tar: term.h comm.h tty.c kmapdef.c + -rm -rf dist + mkdir dist + mkdir dist/screen-$(VERSION) + ln acls.h ansi.h display.h extern.h mark.h os.h overlay.h \ + patchlevel.h rcs.h screen.h window.h image.h \ + osdef.h.in term.sh tty.sh comm.sh osdef.sh \ + acls.c ansi.c attacher.c comm.c display.c window.c fileio.c help.c \ + input.c loadav.c mark.c misc.c process.c pty.c putenv.c \ + screen.c search.c socket.c term.c termcap.c utmp.c resize.c \ + ChangeLog COPYING INSTALL NEWS* install.sh \ + dist/screen-$(VERSION) + ln configure.in configure dist/screen-$(VERSION) + sed -e 's@"/local/screens@"/tmp/screens@' -e 's@"/local@"/usr/local@g' < config.h.in > dist/screen-$(VERSION)/config.h.in + sed -e 's@[ ]/local@ /usr/local@g' -e 's/^CFLAGS = -g/CFLAGS = -O/' < Makefile.in > dist/screen-$(VERSION)/Makefile.in + ln term.h dist/screen-$(VERSION)/term.h.dist + ln comm.h dist/screen-$(VERSION)/comm.h.dist + ln tty.c dist/screen-$(VERSION)/tty.c.dist + ln kmapdef.c dist/screen-$(VERSION)/kmapdef.c.dist + ln README dist/screen-$(VERSION)/README + ln tek.patch dist/screen-$(VERSION)/tek.patch + mkdir dist/screen-$(VERSION)/terminfo + cd terminfo; ln 8bits README checktc.c sco.mail screencap \ + screeninfo.src test.txt tetris.c \ + ../dist/screen-$(VERSION)/terminfo + mkdir dist/screen-$(VERSION)/etc + cd etc; ln * ../dist/screen-$(VERSION)/etc + sed -e 's/^startup/#startup/' -e 's/^autodetach/#autodetach/' < $(ETCSCREENRC) > dist/screen-$(VERSION)/etc/etcscreenrc + cp $(HOME)/.screenrc dist/screen-$(VERSION)/etc/screenrc + mkdir dist/screen-$(VERSION)/doc + sed -e 's@/local/emacs@/usr/local@g' < doc/Makefile.in > dist/screen-$(VERSION)/doc/Makefile.in + cd doc; ln FAQ screen.1 screen.texinfo fdpat.ps \ + ../dist/screen-$(VERSION)/doc + cd doc; if test -f screen.info; then ln screen.info* \ + ../dist/screen-$(VERSION)/doc; fi + cd dist/screen-$(VERSION)/doc; ln -s ../install.sh . + cd dist/screen-$(VERSION); ln -s doc/FAQ . + echo "install all Makefiles and config:" > dist/screen-$(VERSION)/Makefile + echo " sh ./configure" >> dist/screen-$(VERSION)/Makefile + cd dist; tar chf ../screen-$(VERSION).tar screen-$(VERSION) + rm -rf dist + +screen-$(VERSION).tar.gz: screen-$(VERSION).tar + gzip -f screen-$(VERSION).tar + +# Perform self-tests (if any). +check: + +lint: + lint -I. $(CFILES) + +saber: + #load $(CFLAGS) screen.c ansi.c $(LIBS) + +mdepend: $(CFILES) term.h + @rm -f DEPEND ; \ + for i in ${CFILES} ; do \ + echo "$$i" ; \ + echo `echo "$$i" | sed -e 's/.c$$/.o/'`": $$i" `\ + cc -E $$i |\ + grep '^# .*"\./.*\.h"' |\ + sort -t'"' -u +1 -2 |\ + sed -e 's/.*"\.\/\(.*\)".*/\1/'\ + ` >> DEPEND ; \ + done + + +depend: $(CFILES) term.h + cp Makefile Makefile~ + sed -e '/\#\#\# Dependencies/q' < Makefile > tmp_make + for i in $(CFILES); do echo $$i; $(CPP_DEPEND) $$i >> tmp_make; done + mv tmp_make Makefile + +screen.o socket.o: Makefile + +### Dependencies: +screen.o: screen.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h patchlevel.h rcs.h screen.h term.h window.h +ansi.o: ansi.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +fileio.o: fileio.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +mark.o: mark.c acls.h ansi.h comm.h config.h display.h extern.h image.h mark.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +misc.o: misc.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +resize.o: resize.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +socket.o: socket.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +search.o: search.c acls.h ansi.h comm.h config.h display.h extern.h image.h mark.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +tty.o: tty.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +term.o: term.c rcs.h term.h +window.o: window.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +utmp.o: utmp.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +loadav.o: loadav.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +putenv.o: putenv.c config.h rcs.h +help.o: help.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +termcap.o: termcap.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +input.o: input.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +attacher.o: attacher.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +pty.o: pty.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +process.o: process.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +display.o: display.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h +comm.o: comm.c acls.h comm.h config.h rcs.h +kmapdef.o: kmapdef.c config.h +acls.o: acls.c acls.h ansi.h comm.h config.h display.h extern.h image.h os.h osdef.h overlay.h rcs.h screen.h term.h window.h diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..0224ff3 --- /dev/null +++ b/NEWS @@ -0,0 +1,80 @@ + + ---------------------------- + What's new in screen-3.7 ? + ---------------------------- + +* Color support. Screen understands the following capabilities: + AF (setaf) = Set foreground color (ANSI compatible) + AB (setab) = Set background color (ANSI compatible) + AX = Does understand ANSI set default fg/bg color + (\E[39m / \E[49m) + The tweaks for the color xterm would be: + termcap xterm 'AF=\E[3%dm:AB=\E[4%dm' + terminfo xterm 'AF=\E[3%p1%dm:AB=\E[4%p1%dm' + Caution: Screen exposes a bug in X11R6 color xterm. Either use the + patch ftp.uni-erlangen.de:pub/utilities/screen/color_xterm_patch + or a clean rewrite of xterm: rxvt. + +* Resize code completely rewritten. Long lines now get rewrapped, + no information gets lost when a window is narrowed and widened. This + affects both the visible window and its scrollback buffer. It is a + big improvement for the latter. In previous versions the scrollback + buffer was clipped when the window narrowed and padded with + whitespace when it widened. + +* Input handling changed. The command key can now be a prefix + of a function key sequence (hello wyse users :) ) + +* An empty argument to the escape command is allowed to disable + command key processing. This is only allowed if some key + is bound to the "command" command. This example makes F1 the + new command key and allows the previous command key (usually ^A) + to be typed directly: + bindkey -k k1 command + escape "" + +* New 'digraph' command (bound to ^A^V) + ^A^Va" or ^A^V0344 input an a-umlaut + This helps if you want to work in an ISO-latin1 environment but your + terminal's keyboard lacks a some of the more special characters. + +* activity/bell message strings can now include the window title + and the current date/time: + %t - title + %n - number (a single % still works) + %d - day + %D - weekday name + %m - month + %M - month name + %y - year (2 digit) + %Y - year (4 digit) + %w - hour:minutes (24h format) + %W - hour:minutes (12h format) + %s - seconds + %a - am/pm + %A - AM/PM + Please do not use a single '%' character for window titles any more. + It is obsoleted by '%n' and will vanish in future releases. + +* 'defhstatus' command to give every window a default + hardstatus line. '^E' is used as a string escape instead of '%'. + All the above substitution codes apply, but you must use ^E (octal + 005) here, as '%' is likely to appear in automaticaly generated + hardstatus lines. Try 'defhstatus "Screen: window ^E (^Et)"'. + +* In screenrc files and colon command mode: Input parser changed to + also understand caret notation ('^') to mean "Control-" (as in + the ^E example above). + +* "logdir" command changed to "logfile". You can now specify the + filename instead of the directory. The same directives as + understood by the activity/bell messages can be used. + The default is "screenlog.%n". + +* Special terminfo workaround make delay processing work for + the first time! If you had trouble with padding, then try again. + +* New incomprehensible capability XC added to specify character + translation depending on the terminal type. See the manual for + more details and examples. + diff --git a/NEWS.3.5 b/NEWS.3.5 new file mode 100644 index 0000000..d0d1970 --- /dev/null +++ b/NEWS.3.5 @@ -0,0 +1,119 @@ + + ---------------------------- + What's new in screen-3.5 ? + ---------------------------- + + +* Texinfo manpage! Thanks to Jason Merrill. + +* Screen now has a very large 'configure' script. If you have + problems with the resulting configuration please send mail to + screen@uni-erlangen.de. + +* Stackable overlay planes. + All commands are available even if you work with an overlay. Thus + you can be in copy/paste mode on several windows! + +* Unification of key bindings and screen commands. All keys now generate + commands. + +* Screen now reads/writes only in asyncronous mode. + +* Ansi parser speedup code resulting in much faster output of text. + +* Changed the rc file syntax. Commands now directly affect the current + window. The default settings are changed with 'def...' commands. + The 'set' keyword no longer exists. + Please run the 'newsyntax' script on your old screenrc files! + +* Emacs style isearch added to copy mode. Try ^A ESC ^R screen ^R ^R + to locate the last three occurences of the word 'screen' in the + history buffer. + +* New command 'silence'. Alarms the user whenever there was inactivity + for a specified amount of time on a certain window. + Useful if you want to wait for a compilation to end. + +* Much better margin handling: + Screen now handles autowrapped lines correctly in the redisplay and + copy/paste functions. + +* New commands for pastebuffer management: + 'copy_reg' copies the pastebuffer to a register, + 'ins_reg' pastes a register, + 'register' fills a register with a string, + 'process' stuffs a register into strings input queue. + +* Autonuke feature. Flush the output buffer if the window gets + cleared. Enable this with 'autonuke on'. + +* Modifications to save memory: Empty attribute and font lines don't + get allocated. This is very useful if you have a lage scrollback. + +* Multi display support: + You can now attach from more than one terminal to a session with + the '-x' option. + +* New option '-S' to specify socket name. + +* Experimental multiuser support added: + You can start screen in multiuser Mode by prepending the socket + name with a '/' (or by the command 'multiuser on'). + If another user wants to attach to the screen session, he can do + this by prepending the socketname with 'screenuser/'. + Of course he must be in the access control list for a successful + attach (see the acladd/acldel command). + +* Extension to the 'screen' command: You can now specify tty lines + instead of programs. This can be used for console management. + Added the command 'break' to send a break to the tty line. + Not really a new feature, but terminal initialisation now works + on suns. + +* Input/output filters added. This has been implemented to allow the + user to configure an open tty line, but got soon exended to allow + all sorts of filters. For more information read the explanation + of the 'exec' command in the man page and check the 'fdpat.ps' + document. + +* Screen can now be started detached (screen -d -m -S sockname). + This is usefull if you want to start screen in your /etc/rc file + (e.g. as a console multiplexer) + +* Console grabbing added ('console on' command). + +* Windows can now be selected by akas, too. (Per default bound to the + >'< key.) + +* New terminal capabiliteise CS/CE for cursorkey control. + +* setenv/unsetenv commands added. + +* Expansion of environment variables ($VAR) and terminal capabilities + ($:TC:) in the screenrc files and detach messages. + Example: pow_detach_msg "Session of \$LOGNAME \$:cr:\$:nl:ended." + +* New commands: + 'hardcopydir' and 'logdir' to change the output directories, + 'partial' and 'allpartial' to make screen only refresh the line + containing the cursor if a window is selected (useful for slow + modem connections). + +* Cleanup of the provided termcap/terminfo file. Please install + the new one! + +* The program 'terminfo/checktc.c' does a visual check of a + termcap/terminfo entry. Please try it before calling screen and + in a screen session. + +* LOTS of bugfixes and code cleanup. + +Thanks to all the beta testers who helped porting screen to at least +the following platforms: Ultrix, SunOS, Solaris, BSD43, linux, NEWSOS, +Irix, OSF/1, Harris CX/UX, hpux, dynix/ptx, AIX. +And even more thanks to the brave who attempted to use the 'exec' +command features. + + Donnate patches, bugreports, suggestions, money, beer & pizza to + screen@uni-erlangen.de + diff --git a/NEWS.3.6 b/NEWS.3.6 new file mode 100644 index 0000000..6d4360f --- /dev/null +++ b/NEWS.3.6 @@ -0,0 +1,48 @@ + + ---------------------------- + What's new in screen-3.6 ? + ---------------------------- + +* Input translation! This makes the vt100 emulation complete. + As an addition it is now possible to bind any command to any + (function-) key. See the man page for more details (bindkey + command). + +* Status line support. Each window can have a different status line. + Use the ANSI APC string to set the status line, i.e.: + _\ + (For convenience the xterm sequence is also accepted.) + You may want to add + termcap * '' ':hs:ts=\E_:fs=\E\\:ds=\E_\E\\:' + terminfo * '' ':hs:ts=\E_:fs=\E\\:ds=\E_\E\\:' + to your ~/.screenrc to make screen advertise the hardstatus + support. + +* Zombie feature added. Windows now may generate a message (with a + timestamp) if they die and stay around until the user presses + a key. + +* New paste syntax: Paste can now concatenate registers and paste + either on screen or in anouther register. + This makes the old "ins_reg", "copy_reg" commands obsolete. + +* More architecures supported. Screen now runs on AIX3.2.5, + Solaris, NeXT and some other exotic platforms. + +* Kanji support added. Screen understands JIS, EUC and SJIS coding. + This is an experimental feature. + +* GR charset switching (ISO 2022) implemented. Can be enabled with + the "gr" command. + +* C1 sequences implemented (see the "c1" command). + +* Tek support from Xiaoguang Zhang. Apply tek.patch if you want to + make screen pass tek sequences. + +* List of new commands: + bindkey, c1, command, defc1, defgr, defkanji, gr, kanji, mapdefault, + mapnotnext, maptimeout, pastefont, printcmd, readreg, stuff, zombie + +* Lots of other bugs fixed. + diff --git a/README b/README new file mode 100644 index 0000000..362674f --- /dev/null +++ b/README @@ -0,0 +1,102 @@ + + [If you just got the screen package, it pays to read the file INSTALL] + [This intro only describes the most common features to get you started] + + +Short introduction to screen (Version 3.6.0) lvirden 8-8-93 + + [note that this intro only describes the most common screen features] + +Send bugreports, fixes, enhancements, t-shirts, money, beer & pizza to + screen@uni-erlangen.de + +iscreen provides you with an ANSI/vt100 terminal emulator, which can multiplex +up to 10 pseudo-terminals. On startup, it executes $SHELL in window 0. +Then it reads $HOME/.screenrc to learn configuration, keybindings, and +possibly open more windows. + + C-a ? (help) Show all keybindings. + + C-a c (screen) Create new windows. + + C-a SPACE (next) Advance to next window (with wraparound). + + C-a C-a (other) Toggle between the current and previously + displayed windows. + + C-a 0 (select n) Switch to window n=0 ... 9. + ... + C-a 9 + + C-a w (windows) Show a list of window names in the status line. + + C-a a (meta) Send a literal C-a/C-s/C-q to the + C-a s (xoff) process in the window. + C-a q (xon) For instance, emacs uses C-a and C-s. + + C-a l (redisplay) Redraw this window. + + C-a W (width) Toggle between 80 & 132 columns mode. + + C-a L (login) Try to toggle the window's utmp-slot. + + C-a z (suspend) Suspend the whole screen session. + + C-a x (lockscreen) Execute /usr/bin/lock, $LOCKCMD or a + built-in terminal lock. + + C-a H (log) Log stdout of window n to screenlog.n. + + C-a C-[ (copy) Start copy mode. Move cursor with h,j,k,l. + Set 2 marks with SPACE or y. Abort with ESC. + (C-[ is ESC.) Preceeding second mark with + an a appends the text to the copy buffer. + + C-a C-] (paste) Output copy buffer to current window's stdin. + + C-a < (readbuf) Read the copy buffer from /tmp/screen-exchange. + C-a > (writebuf) Write the copy buffer to /tmp/screen-exchange. + + C-a d (detach) Detach screen. All processes continue and may + spool output to their pty's, but screen + disconnects from your terminal. + + C-a D D (pow_detach) Power detach. Disconnect like C-a d but also + kill the parent shell. + + C-a K (kill) Kill a window and send SIGHUP to its process + group. Per default this would be C-a C-k, + but it is redefined in the demo .screenrc + (think of killing a whole line in emacs). + + C-a : (colon) Online configuration change. + +See the man page or TeXinfo manual for many more keybindings and commands. + +screen -r [pid.tty.host|tty.host] + Reattach to a specific detached session. The terminal emulator + reconfigures according to your $TERMCAP or $TERM settings. + When you have multiple screens detached, you must supply the session + name. + +screen -R reattaches to a detached session or (if none) creates a new + session. + +screen -d [pid.tty.host|tty.host] + Detach a screen session remotely. Has the same effect as typing 'C-a d' + on the controlling terminal. 'screen -D' will power-detach. + +screen -list +screen -ls +screen -wipe + Show all available sessions and their status. Use -wipe to remove + DEAD sessions. + + If sockets are missing, you may send a SIGCHLD to its 'SCREEN' + process and the process will re-establish the socket (think of + someone cleaning /tmp thoroughly). + +screen -h 200 + Starts a new screen session and sets the number of lines in the scrollback + buffer to 200. The default is 100 lines. + diff --git a/acls.c b/acls.c new file mode 100644 index 0000000..f13e13c --- /dev/null +++ b/acls.c @@ -0,0 +1,545 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ +#include "rcs.h" +RCS_ID("$Id: acls.c,v 1.12 1994/05/31 12:31:21 mlschroe Exp $ FAU") + +#include + +#include "config.h" +#include "screen.h" /* includes acls.h */ +#include "extern.h" + + +/************************************************************************ + * user managing code, this does not really belong into the acl stuff * + ************************************************************************/ + +extern struct comm comms[]; +extern struct win *windows, *wtab[]; +extern struct display *display, *displays; +struct user *users; + +#ifdef MULTIUSER +/* record given user ids here */ +static AclBits userbits; + +/* rights a new unknown user will have on windows and cmds */ +static char default_w_bit[ACL_BITS_PER_WIN] = +{ + 1, /* EXEC */ + 1, /* WRITE */ + 1 /* READ */ +}; + +static char default_c_bit[ACL_BITS_PER_CMD] = +{ + 1 /* EXEC */ +}; + +/* rights of all users per newly created window */ +static AclBits default_w_userbits[ACL_BITS_PER_WIN]; + +/* +static AclBits default_c_userbits[ACL_BITS_PER_CMD]; +*/ + +static int maxusercount = 0; + +static int GrowBitfield __P((AclBits *, int, int, int)); + + + +static int +GrowBitfield(bfp, len, delta, defaultbit) +AclBits *bfp; +int len, delta, defaultbit; +{ + AclBits n, o = *bfp; + int i; + + if (!(n = (AclBits)calloc(1, (unsigned long)(&ACLBYTE((char *)0, len + delta + 1))))) + return -1; + for (i = 0; i < (len + delta); i++) + { + if (((i < len) && (ACLBIT(i) & ACLBYTE(o, i))) || + ((i >= len) && (defaultbit))) + ACLBYTE(n, i) |= ACLBIT(i); + } + if (len) + free((char *)o); + *bfp = n; + return 0; +} + +#endif /* MULTIUSER */ + +/* + * Returns an nonzero Address. Its contents is either a User-ptr, + * or NULL which may be replaced by a User-ptr to create the entry. + */ +struct user ** +FindUserPtr(name) +char *name; +{ + struct user **u; + + for (u = &users; *u; u = &(*u)->u_next) + if (!strcmp((*u)->u_name, name)) + break; +#ifdef MULTIUSER + debug3("FindUserPtr %s %sfound, id %d\n", name, (*u)?"":"not ", + (*u)?(*u)->id:-1); +#else + debug2("FindUserPtr %s %sfound\n", name, (*u)?"":"not "); +#endif + return u; +} + +int DefaultEsc = Ctrl('a'); +int DefaultMetaEsc = 'a'; + +/* + * Add a new user. His password may be NULL or "" if none. + * He has no rights. + */ +int +UserAdd(name, pass, up) +char *name, *pass; +struct user **up; +{ + if (!up) + up = FindUserPtr(name); + if (*up) + return 1; /* he is already there */ + *up = (struct user *)calloc(1, sizeof(struct user)); + if (!*up) + return -1; /* he still does not exist */ +#ifdef COPY_PASTE + (*up)->u_copybuffer = NULL; + (*up)->u_copylen = 0; +#endif + (*up)->u_Esc = DefaultEsc; + (*up)->u_MetaEsc = DefaultMetaEsc; + strncpy((*up)->u_name, name, 20); + if (pass) + strncpy((*up)->u_password, pass, 20); + +#ifdef MULTIUSER + /* now find an unused index */ + for ((*up)->id = 0; (*up)->id < maxusercount; (*up)->id++) + if (!(ACLBIT((*up)->id) & ACLBYTE(userbits, (*up)->id))) + break; + debug2("UserAdd %s id %d\n", name, (*up)->id); + if ((*up)->id == maxusercount) + { + int i, j; + struct win *w; + + debug2("growing all bitfields %d += %d\n", maxusercount, USER_CHUNK); + /* the bitfields are full, grow a chunk */ + /* first, the used_uid_indicator: */ + if (GrowBitfield(&userbits, maxusercount, USER_CHUNK, 0)) + { + free((char *)*up); *up = NULL; return -1; + } + /* second, default command bits */ + /* (only if we generate commands dynamically) */ +/* + for (j = 0; j < ACL_BITS_PER_CMD; j++) + if (GrowBitfield(&default_c_userbits[j], maxusercount, USER_CHUNK, + default_c_bit[j])) + { + free((char *)*up); *up = NULL; return -1; + } +*/ + /* third, the bits for each commands */ + for (i = 0; i <= RC_LAST; i++) + for (j = 0; j < ACL_BITS_PER_CMD; j++) + if (GrowBitfield(&comms[i].userbits[j], maxusercount, USER_CHUNK, + default_c_bit[j])) + { + free((char *)*up); *up = NULL; return -1; + } + /* fourth, default window and bits */ + for (j = 0; j < ACL_BITS_PER_WIN; j++) + if (GrowBitfield(&default_w_userbits[j], maxusercount, USER_CHUNK, + default_w_bit[j])) + { + free((char *)*up); *up = NULL; return -1; + } + /* fifth, the bits for each window */ + for (w = windows; w; w = w->w_next) + for (j = 0; j < ACL_BITS_PER_WIN; j++) + if (GrowBitfield(&w->w_userbits[j], maxusercount, USER_CHUNK, + default_w_bit[j])) + { + free((char *)*up); *up = NULL; return -1; + } + maxusercount += USER_CHUNK; + } + ACLBYTE(userbits, (*up)->id) |= ACLBIT((*up)->id); + /* user id 0 is the session creator, he has all rights */ + if ((*up)->id == 0) + AclSetPerm(*up, "+rwx", "#?"); +#else /* MULTIUSER */ + debug1("UserAdd %s\n", name); +#endif /* MULTIUSER */ + return 0; +} + +/* change user's password */ +int +UserSetPass(name, pass, up) +char *name, *pass; +struct user **up; +{ + if (!up) + up = FindUserPtr(name); + if (!*up) + return UserAdd(name, pass, up); + strncpy((*up)->u_password, pass ? pass : "", 20); + (*up)->u_password[20] = '\0'; + return 0; +} + +/* + * Remove a user from the list. + * Destroy all his permissions and completely detach him from the session. + */ +int +UserDel(name, up) +char *name; +struct user **up; +{ + struct user *u; + struct display *old, *next; + + if (!up) + up = FindUserPtr(name); + if ((u = *up) == 0) + return -1; /* he who does not exist cannot be removed */ + old = display; + for (display = displays; display; display = next) + { + next = display->d_next; + if (D_user != u) + continue; + if (display == old) + old = 0; + Detach(D_REMOTE); + } + display = old; + *up = u->u_next; +#ifdef MULTIUSER + ACLBYTE(userbits, u->id) &= ~ACLBIT(u->id); + /* restore the bits in his slot to default: */ + AclSetPerm(u, default_w_bit[ACL_READ] ? "+r" : "-r", "#"); + AclSetPerm(u, default_w_bit[ACL_WRITE]? "+w" : "-w", "#"); + AclSetPerm(u, default_w_bit[ACL_EXEC] ? "+x" : "-x", "#"); + AclSetPerm(u, default_c_bit[ACL_EXEC] ? "+x" : "-x", "?"); +#endif + debug1("FREEING user structure for %s\n", u->u_name); +#ifdef COPY_PASTE + UserFreeCopyBuffer(u); +#endif + free((char *)u); + return 0; +} + + +#ifdef COPY_PASTE + +/* + * returns 0 if the copy buffer was really deleted. + * Also removes any references into the users copybuffer + */ +int +UserFreeCopyBuffer(u) +struct user *u; +{ + struct win *w; + + if (!u->u_copybuffer) + return 1; + for (w = windows; w; w = w->w_next) + { + if (w->w_pasteptr >= u->u_copybuffer && + w->w_pasteptr - u->u_copybuffer < u->u_copylen) + { + if (w->w_pastebuf) + free(w->w_pastebuf); + w->w_pastebuf = 0; + w->w_pasteptr = 0; + w->w_pastelen = 0; + } + } + free(u->u_copybuffer); + D_user->u_copylen = 0; + u->u_copybuffer = NULL; + return 0; +} + +#endif /* COPY_PASTE */ + +/************************************************************************ + * end of user managing code * + ************************************************************************/ + + +#ifdef MULTIUSER + +extern char *multi; /* username */ + +/* This gives the users default rights to the new window */ +int +NewWindowAcl(w) +struct win *w; +{ + int i, j; + + debug1("NewWindowAcl default_w_userbits for window %d\n", w->w_number); + for (j = 0; j < ACL_BITS_PER_WIN; j++) + { + /* we start with len 0 for the new bitfield size and add maxusercount */ + if (GrowBitfield(&w->w_userbits[j], 0, maxusercount, 0)) + { + while (--j >= 0) + free((char *)w->w_userbits[j]); + return -1; + } + for (i = 0; i < maxusercount; i++) + if (ACLBIT(i) & ACLBYTE(default_w_userbits[j], i)) + ACLBYTE(w->w_userbits[j], i) |= ACLBIT(i); + } + return 0; +} + +/* if mode starts with '-' we remove the users exec bit for cmd */ +int +AclSetPermCmd(u, mode, cmd) +struct user *u; +char *mode; +struct comm *cmd; +{ + int neg = 0; + + if (!multi) + return 0; + debug3("AclSetPermCmd %s %s %s\n", u->u_name, mode, cmd->name); + while (*mode) + { + switch (*mode++) + { + case '-': + neg = 1; + continue; + case '+': + neg = 0; + continue; + case 'e': + case 'x': + if (neg) + ACLBYTE(cmd->userbits[ACL_EXEC], u->id) &= ~ACLBIT(u->id); + else + ACLBYTE(cmd->userbits[ACL_EXEC], u->id) |= ACLBIT(u->id); + break; + case 'r': + case 'w': + break; + default: + return -1; + } + } + return 0; +} + +/* mode strings of the form +rwx -w+rx r -wx are parsed and evaluated */ +/* + * aclchg nerd -w+w 2 + * releases a writelock on window 2 held by user nerd. + */ +int +AclSetPermWin(u, mode, win) +struct user *u; +char *mode; +struct win *win; +{ + int neg = 0; + int bit; + + if (!multi) + return 0; + debug3("AclSetPermWin %s %s %d\n", u->u_name, mode, win->w_number); + while (*mode) + { + switch (*mode++) + { + case '-': + neg = 1; + continue; + case '+': + neg = 0; + continue; + case 'r': + bit = ACL_READ; + break; + case 'w': + bit = ACL_WRITE; + break; + case 'x': + bit = ACL_EXEC; + break; + default: + return -1; + } + if (neg) + ACLBYTE(win->w_userbits[bit], u->id) &= ~ACLBIT(u->id); + else + ACLBYTE(win->w_userbits[bit], u->id) |= ACLBIT(u->id); + if ((win->w_wlockuser == u) && neg && (bit == ACL_WRITE)) + { + debug2("%s lost writelock on win %d\n", u->u_name, win->w_number); + win->w_wlockuser = NULL; + if (win->w_wlock == WLOCK_ON) + win->w_wlock = WLOCK_AUTO; + } + } + return 0; +} + +/* string is broken down into comand and window names, mode applies */ +int +AclSetPerm(u, mode, s) +struct user *u; +char *mode, *s; +{ + struct win *w; + int i; + char *p, ch; + + while (*s) + { + switch (*s) + { + case '*': /* all windows and all commands */ + return AclSetPerm(u, mode, "#?"); + case '#': /* all windows */ + for (w = windows; w; w = w->w_next) + AclSetPermWin(u, mode, w); + s++; + break; + case '?': /* all commands */ + for (i = 0; i <= RC_LAST; i++) + AclSetPermCmd(u, mode, &comms[i]); + s++; + break; + default: + for (p = s; *p && *p != ' ' && *p != '\t' && *p != ','; p++) + ; + if ((ch = *p) != 0) + *p++ = '\0'; + if ((i = FindCommnr(s)) != RC_ILLEGAL) + AclSetPermCmd(u, mode, &comms[i]); + else if (((i = WindowByNoN(s)) >= 0) && wtab[i]) + AclSetPermWin(u, mode, wtab[i]); + else + /* checking group name */ + return -1; + if (ch) + p[-1] = ch; + s = p; + } + } + return 0; +} + +#if 0 +void +AclWinSwap(a, b) +int a, b; +{ + int a_bit = 0, b_bit = 0; + AclGroupList **g; + AclBits p; + + debug2("acl lists swapping windows %d and %d\n", a, b); + + for (g = &aclgrouproot; *g; g = &(*g)->next) + { + p = (*g)->group->winbits; + /* see if there was a bit for window a. zap it */ + if (a >= 0) + if ((a_bit = ACLBIT(a) & ACLBYTE(p, a))) + ACLBYTE(p, a) &= ~ACLBIT(a); + /* see if there was a bit for window b. zap it */ + if (b >= 0) + if ((b_bit = ACLBIT(b) & ACLBYTE(p, b))) + ACLBYTE(p, b) &= ~ACLBIT(b); + /* b may cause a set */ + if (b_bit && a >= 0) + ACLBYTE(p, a) |= ACLBIT(a); + /* a may cause b set */ + if (a_bit && b >= 0) + ACLBYTE(p, b) |= ACLBIT(b); + } +} +#else +void +AclWinSwap(a, b) +int a, b; +{ + debug2("AclWinSwap(%d, %d) DUMMY\n", a, b); +} +#endif + +int +AclCheckPermWin(u, mode, w) +struct user *u; +int mode; +struct win *w; +{ + if (!multi) + return 0; + if (mode < 0 || mode >= ACL_BITS_PER_WIN) + return -1; + debug3("AclCheckPermWin(%s, %d, %d) = ", u->u_name, mode, w->w_number); + debug1("%d\n", !(ACLBYTE(w->w_userbits[mode], u->id) & ACLBIT(u->id))); + return !(ACLBYTE(w->w_userbits[mode], u->id) & ACLBIT(u->id)); +} + +int +AclCheckPermCmd(u, mode, c) +struct user *u; +int mode; +struct comm *c; +{ + if (!multi) + return 0; + if (mode < 0 || mode >= ACL_BITS_PER_CMD) + return -1; + debug3("AclCheckPermCmd(%s %d %s) = ", u->u_name, mode, c->name); + debug1("%d\n", !(ACLBYTE(c->userbits[mode], u->id) & ACLBIT(u->id))); + return !(ACLBYTE(c->userbits[mode], u->id) & ACLBIT(u->id)); +} + +#endif /* MULTIUSER */ diff --git a/acls.h b/acls.h new file mode 100644 index 0000000..3cbd583 --- /dev/null +++ b/acls.h @@ -0,0 +1,89 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + * RCS_ID("$Id: acl.h,v 1.7 1993/07/30 01:24:06 jnweiger Exp $ FAU") + */ + +#ifdef MULTIUSER + +/* three known bits: */ +#define ACL_EXEC 0 +#define ACL_WRITE 1 +#define ACL_READ 2 + +#define ACL_BITS_PER_CMD 1 /* for comm.h */ +#define ACL_BITS_PER_WIN 3 /* for window.h */ + +#define USER_CHUNK 8 + +#define ACLBYTE(data, w) ((data)[(w) >> 3]) +#define ACLBIT(w) (0x80 >> ((w) & 7)) + +typedef unsigned char * AclBits; + +/* a bitfield for windows and one for commands */ +typedef struct +{ + char name[20 + 1]; + AclBits wins, cmds; +} AclGroup; + +/* + * An AclGroupList is a chaind list of pointers to AclGroups. + * Each user has such a list to reference groups he is in. + * The aclgrouproot anchors all AclGroups. Delete and create + * groups there. + */ +typedef struct grouplist +{ + AclGroup *group; + struct grouplist *next; +} AclGroupList; + +#endif + +/*************** + * ==> user.h + */ + +/* + * A User has a list of groups, and points to other users. + * users is the User entry of the session owner (creator) + * and anchors all other users. Add/Delete users there. + */ +typedef struct user +{ + struct user *u_next; + char u_name[20+1]; /* login name how he showed up */ + char u_password[20+1]; /* his password (may be zero length). */ + int u_detachwin; /* the window where he last detached */ + int u_Esc, u_MetaEsc; /* the users screen escape character */ +#ifdef COPY_PASTE + char *u_copybuffer; + int u_copylen; +#endif +#ifdef MULTIUSER + int id; /* a uniq index in the bitfields. */ +#endif +} User; + +extern int DefaultEsc, DefaultMetaEsc; + diff --git a/ansi.c b/ansi.c new file mode 100644 index 0000000..3edbc81 --- /dev/null +++ b/ansi.c @@ -0,0 +1,2511 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ + +#include "rcs.h" +RCS_ID("$Id: ansi.c,v 1.22 1994/05/31 12:31:25 mlschroe Exp $ FAU") + +#include +#include +#include +#ifndef sun /* we want to know about TIOCPKT. */ +# include +#endif + +#include "config.h" +#include "screen.h" +#include "extern.h" + +extern struct win *windows; /* linked list of all windows */ +extern struct win *fore; +extern struct display *display, *displays; + +extern int force_vt; +extern int all_norefresh; /* => display */ +extern int ZombieKey_destroy, ZombieKey_resurrect; +extern int real_uid, real_gid; +extern time_t Now; +extern struct NewWindow nwin_default; /* for ResetWindow() */ +extern int nversion; + +int Z0width, Z1width; /* widths for Z0/Z1 switching */ + +static struct win *curr; /* window we are working on */ +static int rows, cols; /* window size of the curr window */ + +int visual_bell = 0; +int use_hardstatus = 1; +char *printcmd = 0; + +char *blank; /* line filled with spaces */ +char *null; /* line filled with '\0' */ + +struct mline mline_old; +struct mline mline_blank; +struct mline mline_null; + +struct mchar mchar_null; +struct mchar mchar_blank = {' ' /* , 0, 0, ... */}; +struct mchar mchar_so = {' ', A_SO /* , 0, 0, ... */}; + +static void WinProcess __P((char **, int *)); +static void WinRedisplayLine __P((int, int, int, int)); +static void WinClearLine __P((int, int, int)); +static int WinRewrite __P((int, int, int, int)); +static void WinSetCursor __P((void)); +static int WinResize __P((int, int)); +static void WinRestore __P((void)); +static int Special __P((int)); +static void DoESC __P((int, int)); +static void DoCSI __P((int, int)); +static void SetChar __P((int)); +static void StartString __P((enum string_t)); +static void SaveChar __P((int)); +static void PrintStart __P((void)); +static void PrintChar __P((int)); +static void PrintFlush __P((void)); +static void DesignateCharset __P((int, int)); +static void MapCharset __P((int)); +static void MapCharsetR __P((int)); +static void SaveCursor __P((void)); +static void RestoreCursor __P((void)); +static void BackSpace __P((void)); +static void Return __P((void)); +static void LineFeed __P((int)); +static void ReverseLineFeed __P((void)); +static void InsertAChar __P((int)); +static void InsertChar __P((int)); +static void DeleteChar __P((int)); +static void DeleteLine __P((int)); +static void InsertLine __P((int)); +static void ScrollUpMap __P((int)); +static void ScrollDownMap __P((int)); +static void Scroll __P((char *, int, int, char *)); +static void ForwardTab __P((void)); +static void BackwardTab __P((void)); +static void ClearScreen __P((void)); +static void ClearFromBOS __P((void)); +static void ClearToEOS __P((void)); +static void ClearFullLine __P((void)); +static void ClearToEOL __P((void)); +static void ClearFromBOL __P((void)); +static void ClearInLine __P((int, int, int)); +static void CursorRight __P((int)); +static void CursorUp __P((int)); +static void CursorDown __P((int)); +static void CursorLeft __P((int)); +static void ASetMode __P((int)); +static void SelectRendition __P((void)); +static void RestorePosRendition __P((void)); +static void FillWithEs __P((void)); +static void UpdateLine __P((struct mline *, int, int, int )); +static void FindAKA __P((void)); +static void Report __P((char *, int, int)); +static void FixLine __P((void)); +static void ScrollRegion __P((int)); +static void CheckLP __P((int)); +#ifdef COPY_PASTE +static void AddLineToHist __P((struct win *, struct mline *)); +#endif + + +/* + * The window layer functions + */ + +struct LayFuncs WinLf = +{ + WinProcess, + 0, + WinRedisplayLine, + WinClearLine, + WinRewrite, + WinSetCursor, + WinResize, + WinRestore +}; + +static void +WinProcess(bufpp, lenp) +char **bufpp; +int *lenp; +{ + int addlf, l2 = 0, f, *ilen, l = *lenp; + char *ibuf, *p, *buf = *bufpp; + + fore = D_fore; + /* if w_wlock is set, only one user may write, else we check acls */ + if (fore->w_ptyfd < 0) + { + while ((*lenp)-- > 0) + { + f = *(*bufpp)++; + if (f == ZombieKey_destroy) + { + debug2("Turning undead: %d(%s)\n", fore->w_number, fore->w_title); + KillWindow(fore); + l2--; + break; + } + if (f == ZombieKey_resurrect) + { + SetCurr(fore); + + debug1("Resurrecting Zombie: %d\n", fore->w_number); + LineFeed(2); + RemakeWindow(fore); + l2++; + break; + } + } + if (!l2) + { + char b1[10], b2[10]; + + b1[AddXChar(b1, ZombieKey_destroy)] = '\0'; + b2[AddXChar(b2, ZombieKey_resurrect)] = '\0'; + Msg(0, "Press %s to destroy or %s to resurrect window", b1, b2); + } + *bufpp += *lenp; + *lenp = 0; + return; + } +#ifdef MULTIUSER + if ((fore->w_wlock == WLOCK_OFF) ? + AclCheckPermWin(D_user, ACL_WRITE, fore) : + (D_user != fore->w_wlockuser)) + { + SetCurr(fore); + Special('\007'); + *bufpp += *lenp; + *lenp = 0; + return; + } +#endif /* MULTIUSER */ +#ifdef PSEUDOS + if (W_UWP(fore)) + { + /* we send the user input to our pseudowin */ + ibuf = fore->w_pwin->p_inbuf; ilen = &fore->w_pwin->p_inlen; + f = sizeof(fore->w_pwin->p_inbuf) - *ilen; + } + else +#endif /* PSEUDOS */ + { + /* we send the user input to the window */ + ibuf = fore->w_inbuf; ilen = &fore->w_inlen; + f = sizeof(fore->w_inbuf) - *ilen; + } + + buf = *bufpp; + + while (l) + { + l2 = l; + addlf = 0; + if (fore->w_autolf) + { + for (p = buf; l2; p++, l2--) + if (*p == '\r') + { + l2--; + addlf = 1; + break; + } + l2 = l - l2; + } + if (l2 + addlf > f) + { + debug1("Yuck! pty buffer full (%d chars missing). lets beep\n", l - f); + SetCurr(fore); + Special('\007'); + l = l2 = f; + addlf = 0; + } + if (l2 > 0) + { + bcopy(buf, ibuf + *ilen, l2); + *ilen += l2; + f -= l2; + buf += l2; + l -= l2; + if (f && addlf) + { + ibuf[(*ilen)++] = '\n'; + f--; + } + } + } + *bufpp += *lenp; + *lenp = 0; +} + +static void +WinRedisplayLine(y, from, to, isblank) +int y, from, to, isblank; +{ + if (y < 0) + return; + fore = D_fore; + DisplayLine(isblank ? &mline_blank : &mline_null, &fore->w_mlines[y], + y, from, to); +} + +static int +WinRewrite(y, x1, x2, doit) +int y, x1, x2, doit; +{ + register int cost, dx; + register char *p, *f, *i; +#ifdef COLOR + register char *c; +#endif + + fore = D_fore; + dx = x2 - x1; + if (doit) + { + i = fore->w_mlines[y].image + x1; + while (dx-- > 0) + PUTCHAR(*i++); + return 0; + } + p = fore->w_mlines[y].attr + x1; + f = fore->w_mlines[y].font + x1; +#ifdef COLOR + c = fore->w_mlines[y].color + x1; +#endif + + cost = dx = x2 - x1; + if (D_insert) + cost += D_EIcost + D_IMcost; + while(dx-- > 0) + { +#ifdef COLOR + if (*p++ != D_rend.attr || *f++ != D_rend.font || *c++ != D_rend.color) + return EXPENSIVE; +#else + if (*p++ != D_rend.attr || *f++ != D_rend.font) + return EXPENSIVE; +#endif + } + return cost; +} + +static void +WinClearLine(y, xs, xe) +int y, xs, xe; +{ + fore = D_fore; + DisplayLine(&fore->w_mlines[y], &mline_blank, y, xs, xe); +} + +static void +WinSetCursor() +{ + fore = D_fore; + GotoPos(fore->w_x, fore->w_y); +} + +static int +WinResize(wi, he) +int wi, he; +{ + fore = D_fore; + if (fore) + ChangeWindowSize(fore, wi, he, fore->w_histheight); + return 0; +} + +static void +WinRestore() +{ + fore = D_fore; + ChangeScrollRegion(fore->w_top, fore->w_bot); + KeypadMode(fore->w_keypad); + CursorkeysMode(fore->w_cursorkeys); + SetFlow(fore->w_flow & FLOW_NOW); + InsertMode(fore->w_insert); + ReverseVideo(fore->w_revvid); + CursorVisibility(fore->w_curinv ? -1 : fore->w_curvvis); + fore->w_active = 1; +} + +/* + * Activate - make fore window active + * norefresh = -1 forces a refresh, disregard all_norefresh then. + */ +void +Activate(norefresh) +int norefresh; +{ + debug1("Activate(%d)\n", norefresh); + if (display == 0) + return; + if (D_status) + { + Msg(0, "%s", ""); /* wait till mintime (keep gcc quiet) */ + RemoveStatus(); + } + fore = D_fore; + if (fore) + { + ASSERT(fore->w_display == display); + fore->w_active = D_layfn == &WinLf; + if (fore->w_monitor != MON_OFF) + fore->w_monitor = MON_ON; + fore->w_bell = BELL_OFF; + if (ResizeDisplay(fore->w_width, fore->w_height)) + { + debug2("Cannot resize from (%d,%d)", D_width, D_height); + debug2(" to (%d,%d) -> resize window\n", fore->w_width, fore->w_height); + DoResize(D_width, D_height); + } + } + Redisplay(norefresh + all_norefresh); +} + +void +ResetWindow(p) +register struct win *p; +{ + register int i; + + p->w_wrap = nwin_default.wrap; + p->w_origin = 0; + p->w_insert = 0; + p->w_revvid = 0; + p->w_curinv = 0; + p->w_curvvis = 0; + p->w_autolf = 0; + p->w_keypad = 0; + p->w_cursorkeys = 0; + p->w_top = 0; + p->w_bot = p->w_height - 1; + p->w_saved = 0; + p->w_x = p->w_y = 0; + p->w_state = LIT; + p->w_StringType = NONE; + bzero(p->w_tabs, p->w_width); + for (i = 8; i < p->w_width; i += 8) + p->w_tabs[i] = 1; + p->w_rend = mchar_null; + ResetCharsets(p); +} + +#ifdef KANJI +static char *kanjicharsets[3] = { + "BBBB02", /* jis */ + "\002IBB01", /* euc */ + "BIBB01" /* sjis */ +}; +#endif + +void +ResetCharsets(p) +register struct win *p; +{ + p->w_gr = nwin_default.gr; + p->w_c1 = nwin_default.c1; + SetCharsets(p, "BBBB02"); + if (nwin_default.charset) + SetCharsets(p, nwin_default.charset); +#ifdef KANJI + if (p->w_kanji) + { + p->w_gr = 1; + if (p->w_kanji == SJIS) + p->w_c1 = 0; + SetCharsets(p, kanjicharsets[p->w_kanji]); + } +#endif +} + +void +SetCharsets(p, s) +struct win *p; +char *s; +{ + int i; + + for (i = 0; i < 4 && *s; i++, s++) + if (*s != '.') + p->w_charsets[i] = ((*s == 'B') ? ASCII : *s); + if (*s && *s++ != '.') + p->w_Charset = s[-1] - '0'; + if (*s && *s != '.') + p->w_CharsetR = *s - '0'; + p->w_ss = 0; + p->w_FontL = p->w_charsets[p->w_Charset]; + p->w_FontR = p->w_charsets[p->w_CharsetR]; +} + +static void +FixLine() +{ + struct mline *ml = &curr->w_mlines[curr->w_y]; + if (curr->w_rend.attr && ml->attr == null) + { + if ((ml->attr = (char *)malloc(curr->w_width + 1)) == 0) + { + ml->attr = null; + curr->w_rend.attr = 0; + Msg(0, "Warning: no space for attr - turned off"); + } + bzero(ml->attr, curr->w_width + 1); + } + if ((curr->w_FontL || curr->w_FontR) && ml->font == null) + { + if ((ml->font = (char *)malloc(curr->w_width + 1)) == 0) + { + ml->font = null; + curr->w_FontL = curr->w_charsets[curr->w_ss ? curr->w_ss : curr->w_Charset] = 0; + curr->w_FontR = curr->w_charsets[curr->w_ss ? curr->w_ss : curr->w_CharsetR] = 0; + curr->w_rend.font = 0; + Msg(0, "Warning: no space for font - turned off"); + } + bzero(ml->font, curr->w_width + 1); + } +#ifdef COLOR + if (curr->w_rend.color && ml->color == null) + { + if ((ml->color = (char *)malloc(curr->w_width + 1)) == 0) + { + ml->color = null; + curr->w_rend.color = 0; + Msg(0, "Warning: no space for color - turned off"); + } + bzero(ml->color, curr->w_width + 1); + } +#endif +} + + +/* + * Here comes the vt100 emulator + */ +void +WriteString(wp, buf, len) +struct win *wp; +register char *buf; +register int len; +{ + register int c, font; + + if (!len) + return; + if (wp->w_logfp != NULL) + if ((int)fwrite(buf, len, 1, wp->w_logfp) < 1) + { + Msg(errno, "Error writing logfile"); + fclose(wp->w_logfp); + wp->w_logfp = NULL; + } + /* + * SetCurr() here may prevent output, as it may set display = 0 + */ + SetCurr(wp); + if (display) + { + if (D_status && !(use_hardstatus && D_HS)) + RemoveStatus(); + } + else + { + if (curr->w_tstamp.seconds) + curr->w_tstamp.lastio = Now; + + if (curr->w_monitor == MON_ON || curr->w_monitor == MON_DONE) + { + debug2("ACTIVITY %d %d\n", curr->w_monitor, curr->w_bell); + curr->w_monitor = MON_FOUND; + } + } + + do + { + c = (unsigned char)*buf++; + curr->w_rend.font = curr->w_FontL; /* Default: GL */ + + /* The next part is only for speedup + * (therefore no mchars are used) */ + if (curr->w_state == LIT && +#ifdef KANJI + curr->w_FontL != KANJI && curr->w_FontL != KANA && !curr->w_mbcs && +#endif + c >= ' ' && + ((c & 0x80) == 0 || ((c >= 0xa0 || !curr->w_c1) && !curr->w_gr)) && + !curr->w_insert && !curr->w_ss && curr->w_x < cols - 1) + { + register int currx; + register char *imp, *atp, *fop, at, fo; +#ifdef COLOR + register char *cop, co; +#endif + register char **xtable = 0; + register char *c0tab = 0; + + if (c == '\177') + continue; + FixLine(); + currx = curr->w_x; + imp = curr->w_mlines[curr->w_y].image + currx; + atp = curr->w_mlines[curr->w_y].attr + currx; + fop = curr->w_mlines[curr->w_y].font + currx; + at = curr->w_rend.attr; + fo = curr->w_rend.font; +#ifdef COLOR + cop = curr->w_mlines[curr->w_y].color + currx; + co = curr->w_rend.color; +#endif + if (display) + { + if (D_x != currx || D_y != curr->w_y) + GotoPos(currx, curr->w_y); + /* This is not SetRendition because the compiler would + * not use registers if at/fo/co would be an mchar */ + if (at != D_rend.attr) + SetAttr(at); +#ifdef COLOR + if (co != D_rend.color) + SetColor(co); +#endif + if (fo != D_rend.font) + SetFont(fo); + if (D_insert) + InsertMode(0); + if (D_xtable) + xtable = D_xtable[(int)(unsigned char)D_rend.font]; + if (D_rend.font == '0') + c0tab = D_c0_tab; + } + while (currx < cols - 1) + { + if (display) + { + if (xtable && xtable[c]) + AddStr(xtable[c]); + else if (c0tab) + AddChar(c0tab[c]); + else + AddChar(c); + } + *imp++ = c; + *atp++ = at; + *fop++ = fo; +#ifdef COLOR + *cop++ = co; +#endif + currx++; +skip: if (--len == 0) + break; + c = (unsigned char)*buf++; + if (c == '\177') + goto skip; + if (c < ' ' || ((c & 0x80) && ((c < 0xa0 && curr->w_c1) || curr->w_gr))) + break; + } + curr->w_x = currx; + if (display) + D_x = currx; + if (len == 0) + break; + } + /* end of speedup code */ + + tryagain: + switch (curr->w_state) + { + case PRIN: + switch (c) + { + case '\033': + curr->w_state = PRINESC; + break; + default: + PrintChar(c); + } + break; + case PRINESC: + switch (c) + { + case '[': + curr->w_state = PRINCSI; + break; + default: + PrintChar('\033'); + PrintChar(c); + curr->w_state = PRIN; + } + break; + case PRINCSI: + switch (c) + { + case '4': + curr->w_state = PRIN4; + break; + default: + PrintChar('\033'); + PrintChar('['); + PrintChar(c); + curr->w_state = PRIN; + } + break; + case PRIN4: + switch (c) + { + case 'i': + curr->w_state = LIT; + PrintFlush(); + if (curr->w_pdisplay && curr->w_pdisplay->d_printfd >= 0) + { + close(curr->w_pdisplay->d_printfd); + curr->w_pdisplay->d_printfd = -1; + } + curr->w_pdisplay = 0; + break; + default: + PrintChar('\033'); + PrintChar('['); + PrintChar('4'); + PrintChar(c); + curr->w_state = PRIN; + } + break; + case ASTR: + if (c == 0) + break; + if (c == '\033') + { + curr->w_state = STRESC; + break; + } + /* special xterm hack: accept SetStatus sequence. Yucc! */ + if (!(curr->w_StringType == OSC && c < ' ' && c != '\005')) + if (!curr->w_c1 || c != ('\\' ^ 0xc0)) + { + SaveChar(c); + break; + } + c = '\\'; + /* FALLTHROUGH */ + case STRESC: + switch (c) + { + case '\\': + curr->w_state = LIT; + *curr->w_stringp = '\0'; + switch (curr->w_StringType) + { + case OSC: /* special xterm compatibility hack */ + if (curr->w_stringp - curr->w_string < 2 || + curr->w_string[0] < '0' || + curr->w_string[0] > '2' || + curr->w_string[1] != ';') + break; + curr->w_stringp -= 2; + if (curr->w_stringp > curr->w_string) + bcopy(curr->w_string + 2, curr->w_string, curr->w_stringp - curr->w_string); + *curr->w_stringp = '\0'; + /* FALLTHROUGH */ + case APC: + if (curr->w_hstatus) + { + if (strcmp(curr->w_hstatus, curr->w_string) == 0) + break; /* not changed */ + free(curr->w_hstatus); + curr->w_hstatus = 0; + } + if (curr->w_string != curr->w_stringp) + curr->w_hstatus = SaveStr(curr->w_string); + if (display) + RefreshStatus(); + break; + case GM: + { + struct display *old = display; + for (display = displays; display; display = display->d_next) + if (display != old) + MakeStatus(curr->w_string); + display = old; + } + /*FALLTHROUGH*/ + case PM: + if (!display) + break; + MakeStatus(curr->w_string); + if (D_status && !(use_hardstatus && D_HS) && len > 1) + { + curr->w_outlen = len - 1; + bcopy(buf, curr->w_outbuf, curr->w_outlen); + return; + } + break; + case DCS: + if (display) + AddStr(curr->w_string); + break; + case AKA: + if (curr->w_title == curr->w_akabuf && !*curr->w_string) + break; + ChangeAKA(curr, curr->w_string, 20); + if (!*curr->w_string) + curr->w_autoaka = curr->w_y + 1; + break; + default: + break; + } + break; + case '\033': + SaveChar('\033'); + break; + default: + curr->w_state = ASTR; + SaveChar('\033'); + SaveChar(c); + break; + } + break; + case ESC: + switch (c) + { + case '[': + curr->w_NumArgs = 0; + curr->w_intermediate = 0; + bzero((char *) curr->w_args, MAXARGS * sizeof(int)); + curr->w_state = CSI; + break; + case ']': + StartString(OSC); + break; + case '_': + StartString(APC); + break; + case 'P': + StartString(DCS); + break; + case '^': + StartString(PM); + break; + case '!': + StartString(GM); + break; + case '"': + case 'k': + StartString(AKA); + break; + default: + if (Special(c)) + { + curr->w_state = LIT; + break; + } + debug1("not special. c = %x\n", c); + if (c >= ' ' && c <= '/') + { + if (curr->w_intermediate) +#ifdef KANJI + if (curr->w_intermediate == '$') + c |= '$' << 8; + else +#endif + c = -1; + curr->w_intermediate = c; + } + else if (c >= '0' && c <= '~') + { + DoESC(c, curr->w_intermediate); + curr->w_state = LIT; + } + else + { + curr->w_state = LIT; + goto tryagain; + } + } + break; + case CSI: + switch (c) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + if (curr->w_NumArgs < MAXARGS) + { + curr->w_args[curr->w_NumArgs] = + 10 * curr->w_args[curr->w_NumArgs] + (c - '0'); + } + break; + case ';': + case ':': + curr->w_NumArgs++; + break; + default: + if (Special(c)) + break; + if (c >= '@' && c <= '~') + { + curr->w_NumArgs++; + DoCSI(c, curr->w_intermediate); + if (curr->w_state != PRIN) + curr->w_state = LIT; + } + else if ((c >= ' ' && c <= '/') || (c >= '<' && c <= '?')) + curr->w_intermediate = curr->w_intermediate ? -1 : c; + else + { + curr->w_state = LIT; + goto tryagain; + } + } + break; + case LIT: + default: + if (c < ' ') + { + if (c == '\033') + { + curr->w_intermediate = 0; + curr->w_state = ESC; + if (display && D_lp_missing && (D_CIC || D_IC || D_IM)) + UpdateLine(&mline_blank, D_bot, cols - 2, cols - 1); + if (curr->w_autoaka < 0) + curr->w_autoaka = 0; + } + else + Special(c); + break; + } + if (c >= 0x80 && c < 0xa0 && curr->w_c1) + { + switch (c) + { + case 0xc0 ^ 'D': + case 0xc0 ^ 'E': + case 0xc0 ^ 'H': + case 0xc0 ^ 'M': + case 0xc0 ^ 'N': + case 0xc0 ^ 'O': + DoESC(c ^ 0xc0, 0); + break; + case 0xc0 ^ '[': + if (display && D_lp_missing && (D_CIC || D_IC || D_IM)) + UpdateLine(&mline_blank, D_bot, cols - 2, cols - 1); + if (curr->w_autoaka < 0) + curr->w_autoaka = 0; + curr->w_NumArgs = 0; + curr->w_intermediate = 0; + bzero((char *) curr->w_args, MAXARGS * sizeof(int)); + curr->w_state = CSI; + break; + case 0xc0 ^ 'P': + StartString(DCS); + break; + default: + break; + } + break; + } + + font = curr->w_rend.font = (c >= 0x80 ? curr->w_FontR : curr->w_FontL); +#ifdef KANJI + if (font == KANA && curr->w_kanji == SJIS && curr->w_mbcs == 0) + { + /* Lets see if it is the first byte of a kanji */ + debug1("%x may be first of SJIS\n", c); + if ((0x81 <= c && c <= 0x9f) || (0xe0 <= c && c <= 0xef)) + { + debug("YES!\n"); + curr->w_mbcs = c; + break; + } + } + if (font == KANJI || curr->w_mbcs) + { + int t = c; + if (curr->w_mbcs == 0) + { + curr->w_mbcs = c; + break; + } + if (curr->w_x == cols - 1) + { + curr->w_x += curr->w_wrap ? 1 : -1; + debug1("Patched w_x to %d\n", curr->w_x); + } + c = curr->w_mbcs; + if (font != KANJI) + { + debug2("SJIS !! %x %x\n", c, t); + if (0x40 <= t && t <= 0xfc && t != 0x7f) + { + if (c <= 0x9f) c = (c - 0x81) * 2 + 0x21; + else c = (c - 0xc1) * 2 + 0x21; + if (t <= 0x7e) t -= 0x1f; + else if (t <= 0x9e) t -= 0x20; + else t -= 0x7e, c++; + curr->w_rend.font = KANJI; + } + else + { + /* Incomplete shift-jis - skip first byte */ + c = t; + t = 0; + } + debug2("SJIS after %x %x\n", c, t); + } + curr->w_mbcs = t; + } + kanjiloop: +#endif + if (curr->w_gr) + { + c &= 0x7f; + if (c < ' ') /* this is ugly but kanji support */ + goto tryagain; /* prevents nicer programming */ + } + if (c == '\177') + break; + if (display) + SetRendition(&curr->w_rend); + if (curr->w_x < cols - 1) + { + if (curr->w_insert) + InsertAChar(c); + else + { + if (display) + PUTCHAR(c); + SetChar(c); + curr->w_x++; + } + } + else if (curr->w_x == cols - 1) + { + if (display && curr->w_wrap && (D_CLP || !force_vt || D_COP)) + { + RAW_PUTCHAR(c); /* don't care about D_insert */ + SetChar(c); + curr->w_x++; + if (D_AM && !D_CLP) + { + SetChar(0); + LineFeed(0); /* terminal auto-wrapped */ + } + } + else + { + if (display) + { + if (D_CLP || curr->w_y != D_bot) + { + RAW_PUTCHAR(c); + GotoPos(curr->w_x, curr->w_y); + } + else + CheckLP(c); + } + SetChar(c); + if (curr->w_wrap) + curr->w_x++; + } + } + else /* curr->w_x > cols - 1 */ + { + SetChar(0); /* we wrapped */ + if (curr->w_insert) + { + LineFeed(2); /* cr+lf, handle LP */ + InsertAChar(c); + } + else + { + if (display && D_AM && D_x != cols) /* write char again */ + { + SetRenditionMline(&curr->w_mlines[curr->w_y], cols - 1); + RAW_PUTCHAR(curr->w_mlines[curr->w_y].image[cols - 1]); + SetRendition(&curr->w_rend); + if (curr->w_y == D_bot) + D_lp_missing = 0; /* just wrote it */ + } + LineFeed((display == 0 || D_AM) ? 0 : 2); + if (display) + PUTCHAR(c); + SetChar(c); + curr->w_x = 1; + } + } +#ifdef KANJI + if (curr->w_mbcs) + { + c = curr->w_mbcs; + curr->w_mbcs = 0; + goto kanjiloop; /* what a hack! */ + } +#endif + if (curr->w_ss) + { + curr->w_FontL = curr->w_charsets[curr->w_Charset]; + curr->w_FontR = curr->w_charsets[curr->w_CharsetR]; + SetFont(curr->w_FontL); + curr->w_ss = 0; + } + break; + } + } + while (--len); + curr->w_outlen = 0; + if (curr->w_state == PRIN) + PrintFlush(); +} + +static int +Special(c) +register int c; +{ + switch (c) + { + case '\b': + BackSpace(); + return 1; + case '\r': + Return(); + return 1; + case '\n': + if (curr->w_autoaka) + FindAKA(); + LineFeed(1); + return 1; + case '\007': + if (display == 0) + curr->w_bell = BELL_ON; + else + { + if (!visual_bell) + PutStr(D_BL); + else + { + if (!D_VB) + curr->w_bell = BELL_VISUAL; + else + PutStr(D_VB); + } + } + return 1; + case '\t': + ForwardTab(); + return 1; + case '\017': /* SI */ + MapCharset(G0); + return 1; + case '\016': /* SO */ + MapCharset(G1); + return 1; + } + return 0; +} + +static void +DoESC(c, intermediate) +int c, intermediate; +{ + debug2("DoESC: %x - inter = %x\n", c, intermediate); + switch (intermediate) + { + case 0: + switch (c) + { + case 'E': + LineFeed(2); + break; + case 'D': + LineFeed(1); + break; + case 'M': + ReverseLineFeed(); + break; + case 'H': + curr->w_tabs[curr->w_x] = 1; + break; + case 'Z': /* jph: Identify as VT100 */ + Report("\033[?%d;%dc", 1, 2); + break; + case '7': + SaveCursor(); + break; + case '8': + RestoreCursor(); + break; + case 'c': + ClearScreen(); + ResetWindow(curr); + SetRendition(&mchar_null); + InsertMode(0); + KeypadMode(0); + CursorkeysMode(0); + ChangeScrollRegion(0, rows - 1); + break; + case '=': + KeypadMode(curr->w_keypad = 1); +#ifndef TIOCPKT + NewAutoFlow(curr, 0); +#endif /* !TIOCPKT */ + break; + case '>': + KeypadMode(curr->w_keypad = 0); +#ifndef TIOCPKT + NewAutoFlow(curr, 1); +#endif /* !TIOCPKT */ + break; + case 'n': /* LS2 */ + MapCharset(G2); + break; + case 'o': /* LS3 */ + MapCharset(G3); + break; + case '~': + MapCharsetR(G1); /* LS1R */ + break; + case '}': + MapCharsetR(G2); /* LS2R */ + break; + case '|': + MapCharsetR(G3); /* LS3R */ + break; + case 'N': /* SS2 */ + if (curr->w_charsets[curr->w_Charset] != curr->w_charsets[G2] + || curr->w_charsets[curr->w_CharsetR] != curr->w_charsets[G2]) + curr->w_FontR = curr->w_FontL = curr->w_charsets[curr->w_ss = G2]; + else + curr->w_ss = 0; + break; + case 'O': /* SS3 */ + if (curr->w_charsets[curr->w_Charset] != curr->w_charsets[G3] + || curr->w_charsets[curr->w_CharsetR] != curr->w_charsets[G3]) + curr->w_FontR = curr->w_FontL = curr->w_charsets[curr->w_ss = G3]; + else + curr->w_ss = 0; + break; + case 'g': /* VBELL, private screen sequence */ + if (display == 0) + curr->w_bell = BELL_ON; + else if (!D_VB) + curr->w_bell = BELL_VISUAL; + else + PutStr(D_VB); + break; + } + break; + case '#': + switch (c) + { + case '8': + FillWithEs(); + break; + } + break; + case '(': + DesignateCharset(c, G0); + break; + case ')': + DesignateCharset(c, G1); + break; + case '*': + DesignateCharset(c, G2); + break; + case '+': + DesignateCharset(c, G3); + break; +#ifdef KANJI +/* + * ESC $ ( Fn: invoke multi-byte charset, Fn, to G0 + * ESC $ Fn: same as above. (old sequence) + * ESC $ ) Fn: invoke multi-byte charset, Fn, to G1 + * ESC $ * Fn: invoke multi-byte charset, Fn, to G2 + * ESC $ + Fn: invoke multi-byte charset, Fn, to G3 + */ + case '$': + case '$'<<8 | '(': + DesignateCharset(c & 037, G0); + break; + case '$'<<8 | ')': + DesignateCharset(c & 037, G1); + break; + case '$'<<8 | '*': + DesignateCharset(c & 037, G2); + break; + case '$'<<8 | '+': + DesignateCharset(c & 037, G3); + break; +#endif + } +} + +static void +DoCSI(c, intermediate) +int c, intermediate; +{ + register int i, a1 = curr->w_args[0], a2 = curr->w_args[1]; + + if (curr->w_NumArgs > MAXARGS) + curr->w_NumArgs = MAXARGS; + switch (intermediate) + { + case 0: + switch (c) + { + case 'H': + case 'f': + if (a1 < 1) + a1 = 1; + if (curr->w_origin) + a1 += curr->w_top; + if (a1 > rows) + a1 = rows; + if (a2 < 1) + a2 = 1; + if (a2 > cols) + a2 = cols; + GotoPos(--a2, --a1); + curr->w_x = a2; + curr->w_y = a1; + if (curr->w_autoaka) + curr->w_autoaka = a1 + 1; + break; + case 'J': + if (a1 < 0 || a1 > 2) + a1 = 0; + switch (a1) + { + case 0: + ClearToEOS(); + break; + case 1: + ClearFromBOS(); + break; + case 2: + ClearScreen(); + GotoPos(curr->w_x, curr->w_y); + break; + } + break; + case 'K': + if (a1 < 0 || a1 > 2) + a1 %= 3; + switch (a1) + { + case 0: + ClearToEOL(); + break; + case 1: + ClearFromBOL(); + break; + case 2: + ClearFullLine(); + break; + } + break; + case 'A': + CursorUp(a1 ? a1 : 1); + break; + case 'B': + CursorDown(a1 ? a1 : 1); + break; + case 'C': + CursorRight(a1 ? a1 : 1); + break; + case 'D': + CursorLeft(a1 ? a1 : 1); + break; + case 'm': + SelectRendition(); + break; + case 'g': + if (a1 == 0) + curr->w_tabs[curr->w_x] = 0; + else if (a1 == 3) + bzero(curr->w_tabs, cols); + break; + case 'r': + if (!a1) + a1 = 1; + if (!a2) + a2 = rows; + if (a1 < 1 || a2 > rows || a1 >= a2) + break; + curr->w_top = a1 - 1; + curr->w_bot = a2 - 1; + ChangeScrollRegion(curr->w_top, curr->w_bot); + if (curr->w_origin) + { + GotoPos(0, curr->w_top); + curr->w_y = curr->w_top; + curr->w_x = 0; + } + else + { + GotoPos(0, 0); + curr->w_y = curr->w_x = 0; + } + break; + case 's': + SaveCursor(); + break; + case 't': + if (a1 != 8) + break; + a1 = curr->w_args[2]; + if (a1 < 1) + a1 = curr->w_width; + if (a2 < 1) + a2 = curr->w_height; + if (display && D_CWS == NULL) + { + a2 = curr->w_height; + if (D_CZ0 == NULL || (a1 != Z0width && a1 != Z1width)) + a1 = curr->w_width; + } + if (a1 == curr->w_width && a2 == curr->w_height) + break; + ChangeWindowSize(curr, a1, a2, curr->w_histheight); + SetCurr(curr); + if (display) + Activate(0); + break; + case 'u': + RestoreCursor(); + break; + case 'I': + if (!a1) + a1 = 1; + while (a1--) + ForwardTab(); + break; + case 'Z': + if (!a1) + a1 = 1; + while (a1--) + BackwardTab(); + break; + case 'L': + InsertLine(a1 ? a1 : 1); + break; + case 'M': + DeleteLine(a1 ? a1 : 1); + break; + case 'P': + DeleteChar(a1 ? a1 : 1); + break; + case '@': + InsertChar(a1 ? a1 : 1); + break; + case 'h': + ASetMode(1); + break; + case 'l': + ASetMode(0); + break; + case 'i': + if (display && a1 == 5) + PrintStart(); + break; + case 'n': + if (a1 == 5) /* Report terminal status */ + Report("\033[0n", 0, 0); + else if (a1 == 6) /* Report cursor position */ + Report("\033[%d;%dR", curr->w_y + 1, curr->w_x + 1); + break; + case 'c': /* Identify as VT100 */ + if (a1 == 0) + Report("\033[?%d;%dc", 1, 2); + break; + case 'x': /* decreqtparm */ + if (a1 == 0 || a1 == 1) + Report("\033[%d;1;1;112;112;1;0x", a1 + 2, 0); + break; + case 'p': /* obscure code from a 97801 term */ + if (a1 == 6 || a1 == 7) + { + curr->w_curinv = 7 - a1; + CursorVisibility(curr->w_curinv ? -1 : curr->w_curvvis); + } + break; + case 'S': /* obscure code from a 97801 term */ + ScrollRegion(a1 ? a1 : 1); + break; + case 'T': /* obscure code from a 97801 term */ + ScrollRegion(a1 ? -a1 : -1); + break; + } + break; + case '?': + for (a2 = 0; a2 < curr->w_NumArgs; a2++) + { + a1 = curr->w_args[a2]; + debug2("\\E[?%d%c\n",a1,c); + if (c != 'h' && c != 'l') + break; + i = (c == 'h'); + switch (a1) + { + case 1: /* CKM: cursor key mode */ + CursorkeysMode(curr->w_cursorkeys = i); +#ifndef TIOCPKT + NewAutoFlow(curr, !i); +#endif /* !TIOCPKT */ + break; + case 2: /* ANM: ansi/vt52 mode */ + if (i) + { +#ifdef KANJI + if (curr->w_kanji) + break; +#endif + curr->w_charsets[0] = curr->w_charsets[1] = + curr->w_charsets[2] = curr->w_charsets[2] = + curr->w_FontL = curr->w_FontR = ASCII; + curr->w_Charset = 0; + curr->w_CharsetR = 2; + curr->w_ss = 0; + } + break; + case 3: /* COLM: column mode */ + i = (i ? Z0width : Z1width); + if (curr->w_width != i && (display == 0 || (D_CZ0 || D_CWS))) + { + ChangeWindowSize(curr, i, curr->w_height, curr->w_histheight); + SetCurr(curr); /* update rows/cols */ + if (display) + Activate(0); + } + break; + /* case 4: SCLM: scrolling mode */ + case 5: /* SCNM: screen mode */ + /* This should be reverse video. + * Because it is used in some termcaps to emulate + * a visual bell we do this hack here. + * (screen uses \Eg as special vbell sequence) + */ + if (i) + ReverseVideo(1); + else + { + if (display && D_CVR) + ReverseVideo(0); + else + if (curr->w_revvid) + { + if (display && D_VB) + PutStr(D_VB); + else + curr->w_bell = BELL_VISUAL; + } + } + curr->w_revvid = i; + break; + case 6: /* OM: origin mode */ + if ((curr->w_origin = i) != 0) + { + curr->w_y = curr->w_top; + curr->w_x = 0; + } + else + curr->w_y = curr->w_x = 0; + if (display) + GotoPos(curr->w_x, curr->w_y); + break; + case 7: /* AWM: auto wrap mode */ + curr->w_wrap = i; + break; + /* case 8: ARM: auto repeat mode */ + /* case 9: INLM: interlace mode */ + /* case 10: EDM: edit mode */ + /* case 11: LTM: line transmit mode */ + /* case 13: SCFDM: space compression / field delimiting */ + /* case 14: TEM: transmit execution mode */ + /* case 16: EKEM: edit key execution mode */ + case 25: /* TCEM: text cursor enable mode */ + curr->w_curinv = !i; + CursorVisibility(curr->w_curinv ? -1 : curr->w_curvvis); + break; + /* case 40: 132 col enable */ + /* case 42: NRCM: 7bit NRC character mode */ + /* case 44: margin bell enable */ + } + } + break; + case '>': + switch (c) + { + case 'c': /* secondary DA */ + if (a1 == 0) + Report("\033[>%d;%d;0c", 83, nversion); /* 83 == 'S' */ + break; + } + break; + } +} + + +/* + * Store char in mline. Be sure, that w_Font is set correctly! + */ + +static void +SetChar(c) +register int c; +{ + register struct win *p = curr; + register struct mline *ml; + + FixLine(); + ml = &p->w_mlines[p->w_y]; + p->w_rend.image = c; + copy_mchar2mline(&p->w_rend, ml, p->w_x); +} + +static void +StartString(type) +enum string_t type; +{ + curr->w_StringType = type; + curr->w_stringp = curr->w_string; + curr->w_state = ASTR; +} + +static void +SaveChar(c) +int c; +{ + if (curr->w_stringp >= curr->w_string + MAXSTR - 1) + curr->w_state = LIT; + else + *(curr->w_stringp)++ = c; +} + +static void +PrintStart() +{ + int pi[2]; + + if (printcmd == 0 && D_PO == 0) + return; + curr->w_pdisplay = display; + curr->w_stringp = curr->w_string; + curr->w_state = PRIN; + if (printcmd == 0 || curr->w_pdisplay->d_printfd >= 0) + return; + if (pipe(pi)) + { + Msg(errno, "printing pipe"); + return; + } + switch (fork()) + { + case -1: + Msg(errno, "printing fork"); + return; + case 0: + close(0); + dup(pi[0]); + closeallfiles(0); + if (setuid(real_uid) || setgid(real_gid)) + _exit(1); +#ifdef SIGPIPE + signal(SIGPIPE, SIG_DFL); +#endif + execl("/bin/sh", "sh", "-c", printcmd, 0); + _exit(1); + default: + break; + } + close(pi[0]); + curr->w_pdisplay->d_printfd = pi[1]; +} + +static void +PrintChar(c) +int c; +{ + if (curr->w_stringp >= curr->w_string + MAXSTR - 1) + PrintFlush(); + *(curr->w_stringp)++ = c; +} + +static void +PrintFlush() +{ + struct display *odisp = display; + + display = curr->w_pdisplay; + if (display && printcmd) + { + char *bp = curr->w_string; + int len = curr->w_stringp - curr->w_string; + int r; + while (len && display->d_printfd >= 0) + { + r = write(display->d_printfd, bp, len); + if (r <= 0) + { + Msg(errno, "printing aborted"); + close(display->d_printfd); + display->d_printfd = -1; + break; + } + bp += r; + len -= r; + } + } + else if (display && curr->w_stringp > curr->w_string) + { + PutStr(D_PO); + AddStrn(curr->w_string, curr->w_stringp - curr->w_string); + PutStr(D_PF); + Flush(); + } + curr->w_stringp = curr->w_string; + display = odisp; +} + + +void +NewAutoFlow(win, on) +struct win *win; +int on; +{ + debug1("NewAutoFlow: %d\n", on); + SetCurr(win); + if (win->w_flow & FLOW_AUTOFLAG) + win->w_flow = FLOW_AUTOFLAG | (FLOW_AUTO|FLOW_NOW) * on; + else + win->w_flow = (win->w_flow & ~FLOW_AUTO) | FLOW_AUTO * on; + if (display) + SetFlow(win->w_flow & FLOW_NOW); +} + +static void +DesignateCharset(c, n) +int c, n; +{ + curr->w_ss = 0; +#ifdef KANJI + if (c == ('@' & 037)) + c = KANJI; +#endif + if (c == 'B' || c == 'J') + c = ASCII; + if (curr->w_charsets[n] != c) + { + curr->w_charsets[n] = c; + if (curr->w_Charset == n) + SetFont(curr->w_FontL = c); + if (curr->w_CharsetR == n) + curr->w_FontR = c; + } +} + +static void +MapCharset(n) +int n; +{ + curr->w_ss = 0; + if (curr->w_Charset != n) + { + curr->w_Charset = n; + SetFont(curr->w_FontL = curr->w_charsets[n]); + } +} + +static void +MapCharsetR(n) +int n; +{ + curr->w_ss = 0; + if (curr->w_CharsetR != n) + { + curr->w_CharsetR = n; + curr->w_FontR = curr->w_charsets[n]; + } + curr->w_gr = 1; +} + +static void +SaveCursor() +{ + curr->w_saved = 1; + curr->w_Saved_x = curr->w_x; + curr->w_Saved_y = curr->w_y; + curr->w_SavedRend= curr->w_rend; + curr->w_SavedCharset = curr->w_Charset; + curr->w_SavedCharsetR = curr->w_CharsetR; + bcopy((char *) curr->w_charsets, (char *) curr->w_SavedCharsets, + 4 * sizeof(int)); +} + +static void +RestoreCursor() +{ + if (curr->w_saved) + { + GotoPos(curr->w_Saved_x, curr->w_Saved_y); + curr->w_x = curr->w_Saved_x; + curr->w_y = curr->w_Saved_y; + curr->w_rend = curr->w_SavedRend; + bcopy((char *) curr->w_SavedCharsets, (char *) curr->w_charsets, + 4 * sizeof(int)); + curr->w_Charset = curr->w_SavedCharset; + curr->w_CharsetR = curr->w_SavedCharsetR; + curr->w_ss = 0; + curr->w_FontL = curr->w_charsets[curr->w_Charset]; + curr->w_FontR = curr->w_charsets[curr->w_CharsetR]; + SetRendition(&curr->w_rend); + } +} + +static void +BackSpace() +{ + if (curr->w_x > 0) + { + curr->w_x--; + } + else if (curr->w_wrap && curr->w_y > 0) + { + curr->w_x = cols - 1; + curr->w_y--; + } + if (display) + GotoPos(curr->w_x, curr->w_y); +} + +static void +Return() +{ + if (curr->w_x > 0) + { + curr->w_x = 0; + if (display) + GotoPos(curr->w_x, curr->w_y); + } +} + +static void +LineFeed(out_mode) +int out_mode; +{ + /* out_mode: 0=cr+lf no-output, 1=lf, 2=cr+lf */ + if (out_mode != 1) + curr->w_x = 0; + if (curr->w_y != curr->w_bot) /* Don't scroll */ + { + if (curr->w_y < rows-1) + curr->w_y++; + if (out_mode && display) + GotoPos(curr->w_x, curr->w_y); + return; + } + ScrollUpMap(1); + if (curr->w_autoaka > 1) + curr->w_autoaka--; + if (out_mode && display) + { + ScrollV(0, curr->w_top, cols - 1, curr->w_bot, 1); + GotoPos(curr->w_x, curr->w_y); + } +} + +static void +ReverseLineFeed() +{ + if (curr->w_y == curr->w_top) + { + ScrollDownMap(1); + if (!display) + return; + ScrollV(0, curr->w_top, cols - 1, curr->w_bot, -1); + GotoPos(curr->w_x, curr->w_y); + } + else if (curr->w_y > 0) + CursorUp(1); +} + +static void +InsertAChar(c) +int c; +{ + register int y = curr->w_y, x = curr->w_x; + + if (x == cols) + x--; + save_mline(&curr->w_mlines[y], cols); + if (cols - x - 1 > 0) + bcopy_mline(&curr->w_mlines[y], x, x + 1, cols - x - 1); + SetChar(c); + curr->w_x = x + 1; + if (!display) + return; + if (D_CIC || D_IC || D_IM) + { + InsertMode(curr->w_insert); + INSERTCHAR(c); + if (y == D_bot) + D_lp_missing = 0; + } + else + UpdateLine(&mline_old, y, x, cols - 1); +} + +static void +InsertChar(n) +int n; +{ + register int y = curr->w_y, x = curr->w_x; + + if (n <= 0) + return; + if (x == cols) + x--; + save_mline(&curr->w_mlines[y], cols); + if (n >= cols - x) + n = cols - x; + else + bcopy_mline(&curr->w_mlines[y], x, x + n, cols - x - n); + + ClearInLine(y, x, x + n - 1); + if (!display) + return; + ScrollH(y, x, curr->w_width - 1, -n, &mline_old); + GotoPos(x, y); +} + +static void +DeleteChar(n) +int n; +{ + register int y = curr->w_y, x = curr->w_x; + + if (x == cols) + x--; + save_mline(&curr->w_mlines[y], cols); + + if (n >= cols - x) + n = cols - x; + else + bcopy_mline(&curr->w_mlines[y], x + n, x, cols - x - n); + ClearInLine(y, cols - n, cols - 1); + if (!display) + return; + ScrollH(y, x, curr->w_width - 1, n, &mline_old); + GotoPos(x, y); +} + +static void +DeleteLine(n) +int n; +{ + register int old = curr->w_top; + + if (curr->w_y < curr->w_top || curr->w_y > curr->w_bot) + return; + if (n > curr->w_bot - curr->w_y + 1) + n = curr->w_bot - curr->w_y + 1; + curr->w_top = curr->w_y; + ScrollUpMap(n); + curr->w_top = old; + if (!display) + return; + ScrollV(0, curr->w_y, cols - 1, curr->w_bot, n); + GotoPos(curr->w_x, curr->w_y); +} + +static void +InsertLine(n) +int n; +{ + register int old = curr->w_top; + + if (curr->w_y < curr->w_top || curr->w_y > curr->w_bot) + return; + if (n > curr->w_bot - curr->w_y + 1) + n = curr->w_bot - curr->w_y + 1; + curr->w_top = curr->w_y; + ScrollDownMap(n); + curr->w_top = old; + if (!display) + return; + ScrollV(0, curr->w_y, cols - 1, curr->w_bot, -n); + GotoPos(curr->w_x, curr->w_y); +} + +static void +ScrollRegion(n) +int n; +{ + if (n > 0) + ScrollUpMap(n); + else + ScrollDownMap(-n); + if (!display) + return; + ScrollV(0, curr->w_top, cols - 1, curr->w_bot, n); + GotoPos(curr->w_x, curr->w_y); +} + +static void +ScrollUpMap(n) +int n; +{ + char tmp[256 * sizeof(struct mline)]; + register int i, cnt1, cnt2; + struct mline *ml; +#ifdef COPY_PASTE + register int ii; +#endif + + i = curr->w_top + n; + cnt1 = n * sizeof(struct mline); + cnt2 = (curr->w_bot - i + 1) * sizeof(struct mline); +#ifdef COPY_PASTE + for(ii = curr->w_top; ii < i; ii++) + AddLineToHist(curr, &curr->w_mlines[ii]); +#endif + ml = curr->w_mlines + i; + for (i = n; i; --i) + { + --ml; + clear_mline(ml, 0, cols + 1); + } + Scroll((char *) ml, cnt1, cnt2, tmp); +} + +static void +ScrollDownMap(n) +int n; +{ + char tmp[256 * sizeof(struct mline)]; + register int i, cnt1, cnt2; + struct mline *ml; + + i = curr->w_top; + cnt1 = (curr->w_bot - i - n + 1) * sizeof(struct mline); + cnt2 = n * sizeof(struct mline); + ml = curr->w_mlines + i; + Scroll((char *) ml, cnt1, cnt2, tmp); + for (i = n; i; --i) + { + clear_mline(ml, 0, cols + 1); + ml++; + } +} + +static void +Scroll(cp, cnt1, cnt2, tmp) +char *cp, *tmp; +int cnt1, cnt2; +{ + if (!cnt1 || !cnt2) + return; + if (cnt1 <= cnt2) + { + bcopy(cp, tmp, cnt1); + bcopy(cp + cnt1, cp, cnt2); + bcopy(tmp, cp + cnt2, cnt1); + } + else + { + bcopy(cp + cnt1, tmp, cnt2); + bcopy(cp, cp + cnt2, cnt1); + bcopy(tmp, cp, cnt2); + } +} + +static void +ForwardTab() +{ + register int x = curr->w_x; + + if (x == cols) + { + LineFeed(2); + x = 0; + } + if (curr->w_tabs[x] && x < cols - 1) + x++; + while (x < cols - 1 && !curr->w_tabs[x]) + x++; + GotoPos(x, curr->w_y); + curr->w_x = x; +} + +static void +BackwardTab() +{ + register int x = curr->w_x; + + if (curr->w_tabs[x] && x > 0) + x--; + while (x > 0 && !curr->w_tabs[x]) + x--; + GotoPos(x, curr->w_y); + curr->w_x = x; +} + +static void +ClearScreen() +{ + register int i; + register struct mline *ml = curr->w_mlines; + + for (i = 0; i < rows; ++i) + { +#ifdef COPY_PASTE + AddLineToHist(curr, ml); +#endif + clear_mline(ml, 0, cols + 1); + ml++; + } + if (display) + ClearDisplay(); +} + +static void +ClearFromBOS() +{ + register int n, y = curr->w_y, x = curr->w_x; + + if (display) + Clear(0, 0, 0, cols - 1, x, y, 1); + for (n = 0; n < y; ++n) + ClearInLine(n, 0, cols - 1); + ClearInLine(y, 0, x); + RestorePosRendition(); +} + +static void +ClearToEOS() +{ + register int n, y = curr->w_y, x = curr->w_x; + + if (x == 0 && y == 0) + { + ClearScreen(); + return; + } + if (display) + Clear(x, y, 0, cols - 1, cols - 1, rows - 1, 1); + ClearInLine(y, x, cols - 1); + for (n = y + 1; n < rows; n++) + ClearInLine(n, 0, cols - 1); + RestorePosRendition(); +} + +static void +ClearFullLine() +{ + register int y = curr->w_y; + + if (display) + Clear(0, y, 0, cols - 1, cols - 1, y, 1); + ClearInLine(y, 0, cols - 1); + RestorePosRendition(); +} + +static void +ClearToEOL() +{ + register int y = curr->w_y, x = curr->w_x; + + if (display) + Clear(x, y, 0, cols - 1, cols - 1, y, 1); + ClearInLine(y, x, cols - 1); + RestorePosRendition(); +} + +static void +ClearFromBOL() +{ + register int y = curr->w_y, x = curr->w_x; + + if (display) + Clear(0, y, 0, cols - 1, x, y, 1); + ClearInLine(y, 0, x); + RestorePosRendition(); +} + +static void +ClearInLine(y, x1, x2) +int y, x1, x2; +{ + register int n; + + if (x1 == cols) + x1--; + if (x2 == cols - 1) + x2++; + if ((n = x2 - x1 + 1) != 0) + clear_mline(&curr->w_mlines[y], x1, n); +} + +static void +CursorRight(n) +register int n; +{ + register int x = curr->w_x; + + if (x == cols) + { + LineFeed(2); + x = 0; + } + if ((curr->w_x += n) >= cols) + curr->w_x = cols - 1; + GotoPos(curr->w_x, curr->w_y); +} + +static void +CursorUp(n) +register int n; +{ + if (curr->w_y < curr->w_top) /* if above scrolling rgn, */ + { + if ((curr->w_y -= n) < 0) /* ignore its limits */ + curr->w_y = 0; + } + else + if ((curr->w_y -= n) < curr->w_top) + curr->w_y = curr->w_top; + GotoPos(curr->w_x, curr->w_y); +} + +static void +CursorDown(n) +register int n; +{ + if (curr->w_y > curr->w_bot) /* if below scrolling rgn, */ + { + if ((curr->w_y += n) > rows - 1) /* ignore its limits */ + curr->w_y = rows - 1; + } + else + if ((curr->w_y += n) > curr->w_bot) + curr->w_y = curr->w_bot; + GotoPos(curr->w_x, curr->w_y); +} + +static void +CursorLeft(n) +register int n; +{ + if ((curr->w_x -= n) < 0) + curr->w_x = 0; + GotoPos(curr->w_x, curr->w_y); +} + +static void +ASetMode(on) +int on; +{ + register int i; + + for (i = 0; i < curr->w_NumArgs; ++i) + { + switch (curr->w_args[i]) + { + case 4: + curr->w_insert = on; + InsertMode(on); + break; + case 20: + curr->w_autolf = on; + break; + case 34: + curr->w_curvvis = !on; + CursorVisibility(curr->w_curinv ? -1 : curr->w_curvvis); + break; + default: + break; + } + } +} + +static char rendlist[] = +{ + (1 << NATTR), A_BD, A_DI, A_SO, A_US, A_BL, 0, A_RV, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, ~(A_BD|A_SO|A_DI), ~A_SO, ~A_US, ~A_BL, 0, ~A_RV +}; + +static void +SelectRendition() +{ + register int j, i = 0, a = curr->w_rend.attr; +#ifdef COLOR + register int c = curr->w_rend.color; +#endif + + do + { + j = curr->w_args[i]; +#ifdef COLOR + if (j >= 30 && j <= 39) + c = (c & 0xf0) | (39 - j); + else if (j >= 40 && j <= 49) + c = (c & 0x0f) | ((49 - j) << 4); + if (j == 0) + c = 0; +#endif + if (j < 0 || j >= (sizeof(rendlist)/sizeof(*rendlist))) + continue; + j = rendlist[j]; + if (j & (1 << NATTR)) + a &= j; + else + a |= j; + } + while (++i < curr->w_NumArgs); + if (curr->w_rend.attr != a) + SetAttr(curr->w_rend.attr = a); +#ifdef COLOR + if (curr->w_rend.color != c) + SetColor(curr->w_rend.color = c); +#endif +} + +static void +FillWithEs() +{ + register int i; + register char *p, *ep; + + curr->w_y = curr->w_x = 0; + for (i = 0; i < rows; ++i) + { + clear_mline(&curr->w_mlines[i], 0, cols + 1); + p = curr->w_mlines[i].image; + ep = p + cols; + while (p < ep) + *p++ = 'E'; + } + if (display) + Redisplay(0); +} + + +static void +UpdateLine(oml, y, from, to) +struct mline *oml; +int from, to, y; +{ + ASSERT(display); + DisplayLine(oml, &curr->w_mlines[y], y, from, to); + RestorePosRendition(); +} + + +static void +CheckLP(n_ch) +int n_ch; +{ + register int x; + register struct mline *ml; + + ASSERT(display); + ml = &curr->w_mlines[D_bot]; + x = cols - 1; + + curr->w_rend.image = n_ch; + + D_lpchar = curr->w_rend; + D_lp_missing = 0; + + if (cmp_mchar_mline(&curr->w_rend, ml, x)) + return; + if (!cmp_mchar(&mchar_blank, &curr->w_rend)) /* is new not blank */ + D_lp_missing = 1; + if (!cmp_mchar_mline(&mchar_blank, ml, x)) /* is old char not blank? */ + { + /* old char not blank, new blank, try to delete */ + if (D_UT) + SetRendition(&mchar_null); + if (D_CE) + PutStr(D_CE); + else if (D_DC) + PutStr(D_DC); + else if (D_CDC) + CPutStr(D_CDC, 1); + else + D_lp_missing = 1; + } +} + +/* + * Ugly autoaka hack support: + * ChangeAKA() sets a new aka + * FindAKA() searches for an autoaka match + */ + +void +ChangeAKA(p, s, l) +struct win *p; +char *s; +int l; +{ + if (l > 20) + l = 20; + strncpy(p->w_akachange, s, l); + p->w_akachange[l] = 0; + p->w_title = p->w_akachange; + if (p->w_akachange != p->w_akabuf) + if (p->w_akachange[0] == 0 || p->w_akachange[-1] == ':') + p->w_title = p->w_akabuf + strlen(p->w_akabuf) + 1; + + /* yucc */ + if (p->w_hstatus) + { + display = p->w_display; + if (display) + RefreshStatus(); + } +} + +static void +FindAKA() +{ + register char *cp, *line; + register struct win *wp = curr; + register int len = strlen(wp->w_akabuf); + int y; + + y = (wp->w_autoaka > 0 && wp->w_autoaka <= wp->w_height) ? wp->w_autoaka - 1 : wp->w_y; + cols = wp->w_width; + try_line: + cp = line = wp->w_mlines[y].image; + if (wp->w_autoaka > 0 && *wp->w_akabuf != '\0') + { + for (;;) + { + if (cp - line >= cols - len) + { + if (++y == wp->w_autoaka && y < rows) + goto try_line; + return; + } + if (strncmp(cp, wp->w_akabuf, len) == 0) + break; + cp++; + } + cp += len; + } + for (len = cols - (cp - line); len && *cp == ' '; len--, cp++) + ; + if (len) + { + if (wp->w_autoaka > 0 && (*cp == '!' || *cp == '%' || *cp == '^')) + wp->w_autoaka = -1; + else + wp->w_autoaka = 0; + line = cp; + while (len && *cp != ' ') + { + if (*cp++ == '/') + line = cp; + len--; + } + ChangeAKA(wp, line, cp - line); + } + else + wp->w_autoaka = 0; +} + +void +SetCurr(wp) +struct win *wp; +{ + curr = wp; + if (curr == 0) + return; + cols = curr->w_width; + rows = curr->w_height; + display = curr->w_active ? curr->w_display : 0; +} + +static void +RestorePosRendition() +{ + if (!display) + return; + GotoPos(curr->w_x, curr->w_y); + SetRendition(&curr->w_rend); +} + +/* Send a terminal report as if it were typed. */ +static void +Report(fmt, n1, n2) +char *fmt; +int n1, n2; +{ + register int len; + char rbuf[40]; + + sprintf(rbuf, fmt, n1, n2); + len = strlen(rbuf); + + if ((unsigned)(curr->w_inlen + len) <= sizeof(curr->w_inbuf)) + { + bcopy(rbuf, curr->w_inbuf + curr->w_inlen, len); + curr->w_inlen += len; + } +} + +#ifdef COPY_PASTE +static void +AddLineToHist(wp, ml) +struct win *wp; +struct mline *ml; +{ + register char *q, *o; + struct mline *hml; + + if (wp->w_histheight == 0) + return; + hml = &wp->w_hlines[wp->w_histidx]; + q = ml->image; ml->image = hml->image; hml->image = q; + + q = ml->attr; o = hml->attr; hml->attr = q; ml->attr = null; + if (o != null) + free(o); + + q = ml->font; o = hml->font; hml->font = q; ml->font = null; + if (o != null) + free(o); + +#ifdef COLOR + q = ml->color; o = hml->color; hml->color = q; ml->color = null; + if (o != null) + free(o); +#endif + + if (++wp->w_histidx >= wp->w_histheight) + wp->w_histidx = 0; +} +#endif + diff --git a/ansi.h b/ansi.h new file mode 100644 index 0000000..1746f28 --- /dev/null +++ b/ansi.h @@ -0,0 +1,116 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + * $Id: ansi.h,v 1.6 1994/05/31 12:31:28 mlschroe Exp $ FAU + */ + +#define NATTR 6 + +#define ATTR_DI 0 /* Dim mode */ +#define ATTR_US 1 /* Underscore mode */ +#define ATTR_BD 2 /* Bold mode */ +#define ATTR_RV 3 /* Reverse mode */ +#define ATTR_SO 4 /* Standout mode */ +#define ATTR_BL 5 /* Blinking */ + +#define A_DI (1< +#include +#include +#include +#include "config.h" +#include "screen.h" +#include "extern.h" + +#include + +static sigret_t AttacherSigInt __P(SIGPROTOARG); +#ifdef PASSWORD +static void trysend __P((int, struct msg *, char *)); +#endif +#if defined(SIGWINCH) && defined(TIOCGWINSZ) +static sigret_t AttacherWinch __P(SIGPROTOARG); +#endif +#ifdef LOCK +static sigret_t DoLock __P(SIGPROTOARG); +static void LockTerminal __P((void)); +static sigret_t LockHup __P(SIGPROTOARG); +static void screen_builtin_lck __P((void)); +#endif +#ifdef DEBUG +static sigret_t AttacherChld __P(SIGPROTOARG); +#endif + +extern int real_uid, real_gid, eff_uid, eff_gid; +extern char *SockName, *SockMatch, SockPath[]; +extern struct passwd *ppp; +extern char *attach_tty, *attach_term, *LoginName; +extern int xflag, dflag, rflag, quietflag, adaptflag; +extern struct mode attach_Mode; +extern int MasterPid; +extern int nethackflag; + +#ifdef MULTIUSER +extern char *multi; +extern int multiattach, multi_uid, own_uid; +extern int tty_mode, tty_oldmode; +# ifndef USE_SETEUID +static int multipipe[2]; +# endif +#endif + + + +/* + * Send message to a screen backend. + * returns 1 if we could attach one, or 0 if none. + * Understands MSG_ATTACH, MSG_DETACH, MSG_POW_DETACH + * MSG_CONT, MSG_WINCH and nothing else! + */ + +int +Attach(how) +int how; +{ + int n, lasts; + struct msg m; + struct stat st; + char *s; + + debug2("Attach: how=%d, tty=%s\n", how, attach_tty); +#ifdef MULTIUSER +# ifndef USE_SETEUID + while ((how == MSG_ATTACH || how == MSG_CONT) && multiattach) + { + int ret; + + if (pipe(multipipe)) + Panic(errno, "pipe"); + if (chmod(attach_tty, 0666)) + Panic(errno, "chmod %s", attach_tty); + tty_oldmode = tty_mode; + eff_uid = -1; /* make UserContext fork */ + real_uid = multi_uid; + if ((ret = UserContext()) <= 0) + { + char dummy; + eff_uid = 0; + real_uid = own_uid; + if (ret < 0) + Panic(errno, "UserContext"); + close(multipipe[1]); + read(multipipe[0], &dummy, 1); + if (tty_oldmode >= 0) + { + chmod(attach_tty, tty_oldmode); + tty_oldmode = -1; + } + ret = UserStatus(); +#ifdef LOCK + if (ret == SIG_LOCK) + LockTerminal(); + else +#endif +#ifdef SIGTSTP + if (ret == SIG_STOP) + kill(getpid(), SIGTSTP); + else +#endif + if (ret == SIG_POWER_BYE) + { + int ppid; + setuid(real_uid); + setgid(real_gid); + if ((ppid = getppid()) > 1) + Kill(ppid, SIGHUP); + exit(0); + } + else + exit(ret); + dflag = 0; +#ifdef MULTI + xflag = 1; +#endif + how = MSG_ATTACH; + continue; + } + close(multipipe[0]); + eff_uid = real_uid; + break; + } +# else /* USE_SETEUID */ + if ((how == MSG_ATTACH || how == MSG_CONT) && multiattach) + { + real_uid = multi_uid; + eff_uid = own_uid; + xseteuid(multi_uid); + xseteuid(own_uid); + if (chmod(attach_tty, 0666)) + Panic(errno, "chmod %s", attach_tty); + tty_oldmode = tty_mode; + } +# endif /* USE_SETEUID */ +#endif /* MULTIUSER */ + + bzero((char *) &m, sizeof(m)); + m.type = how; + strcpy(m.m_tty, attach_tty); + + if (how == MSG_WINCH) + { + if ((lasts = MakeClientSocket(0)) >= 0) + { + write(lasts, (char *)&m, sizeof(m)); + close(lasts); + } + return 0; + } + + if (how == MSG_CONT) + { + if ((lasts = MakeClientSocket(0)) < 0) + { + Panic(0, "Sorry, cannot contact session \"%s\" again.\r\n", + SockName); + } + } + else + { + n = FindSocket(&lasts, (int *)0, SockMatch); + switch (n) + { + case 0: + if (rflag == 2) + return 0; + if (quietflag) + eexit(10); + Panic(0, SockMatch && *SockMatch ? "There is no screen to be %sed matching %s." : "There is no screen to be %sed.", + xflag ? "attach" : + dflag ? "detach" : + "resum", SockMatch); + /* NOTREACHED */ + case 1: + break; + default: + if (quietflag) + eexit(10 + n); + Panic(0, "Type \"screen [-d] -r [pid.]tty.host\" to resume one of them."); + /* NOTREACHED */ + } + } + /* + * Go in UserContext. Advantage is, you can kill your attacher + * when things go wrong. Any disadvantages? jw. + * Do this before the attach to prevent races! + */ +#ifdef MULTIUSER + if (!multiattach) +#endif + setuid(real_uid); +#if defined(MULTIUSER) && defined(USE_SETEUID) + else + xseteuid(real_uid); /* multi_uid, allow backend to send signals */ +#endif + setgid(real_gid); + eff_uid = real_uid; + eff_gid = real_gid; + + debug2("Attach: uid %d euid %d\n", getuid(), geteuid()); + MasterPid = 0; + for (s = SockName; *s; s++) + { + if (*s > '9' || *s < '0') + break; + MasterPid = 10 * MasterPid + (*s - '0'); + } + debug1("Attach decided, it is '%s'\n", SockPath); + debug1("Attach found MasterPid == %d\n", MasterPid); + if (stat(SockPath, &st) == -1) + Panic(errno, "stat %s", SockPath); + if ((st.st_mode & 0600) != 0600) + Panic(0, "Socket is in wrong mode (%03o)", st.st_mode); + if ((dflag || !xflag) && (st.st_mode & 0700) != (dflag ? 0700 : 0600)) + Panic(0, "That screen is %sdetached.", dflag ? "already " : "not "); +#ifdef REMOTE_DETACH + if (dflag && + (how == MSG_ATTACH || how == MSG_DETACH || how == MSG_POW_DETACH)) + { + m.m.detach.dpid = getpid(); + strncpy(m.m.detach.duser, LoginName, sizeof(m.m.detach.duser) - 1); + m.m.detach.duser[sizeof(m.m.detach.duser) - 1] = 0; +# ifdef POW_DETACH + if (dflag == 2) + m.type = MSG_POW_DETACH; + else +# endif + m.type = MSG_DETACH; + if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m)) + Panic(errno, "write"); + close(lasts); + if (how != MSG_ATTACH) + return 0; /* we detached it. jw. */ + sleep(1); /* we dont want to overrun our poor backend. jw. */ + if ((lasts = MakeClientSocket(0)) == -1) + Panic(0, "Cannot contact screen again. Sigh."); + m.type = how; + } +#endif + ASSERT(how == MSG_ATTACH || how == MSG_CONT); + strcpy(m.m.attach.envterm, attach_term); + debug1("attach: sending %d bytes... ", (int)sizeof(m)); + + strncpy(m.m.attach.auser, LoginName, sizeof(m.m.attach.auser) - 1); + m.m.attach.auser[sizeof(m.m.attach.auser) - 1] = 0; + m.m.attach.apid = getpid(); + m.m.attach.adaptflag = adaptflag; + m.m.attach.lines = m.m.attach.columns = 0; + if ((s = getenv("LINES"))) + m.m.attach.lines = atoi(s); + if ((s = getenv("COLUMNS"))) + m.m.attach.columns = atoi(s); + +#ifdef PASSWORD + if (how == MSG_ATTACH || how == MSG_CONT) + trysend(lasts, &m, m.m.attach.password); + else +#endif + { + if (write(lasts, (char *) &m, sizeof(m)) != sizeof(m)) + Panic(errno, "write"); + close(lasts); + } + debug1("Attach(%d): sent\n", m.type); +#ifdef MULTIUSER + if (multi && (how == MSG_ATTACH || how == MSG_CONT)) + { +# ifndef PASSWORD + pause(); +# endif +# ifndef USE_SETEUID + close(multipipe[1]); +# else + xseteuid(own_uid); + if (tty_oldmode >= 0) + if (chmod(attach_tty, tty_oldmode)) + Panic(errno, "chmod %s", attach_tty); + tty_oldmode = -1; + xseteuid(real_uid); +# endif + } +#endif + rflag = 0; + return 1; +} + + +#ifdef PASSWORD + +static trysendstatok, trysendstatfail; + +static sigret_t +trysendok SIGDEFARG +{ + trysendstatok = 1; +} + +static sigret_t +trysendfail SIGDEFARG +{ +# ifdef SYSVSIGS + signal(SIG_PW_FAIL, trysendfail); +# endif /* SYSVSIGS */ + trysendstatfail = 1; +} + +static char screenpw[9]; + +static void +trysend(fd, m, pwto) +int fd; +struct msg *m; +char *pwto; +{ + char *npw = NULL; + sigret_t (*sighup)__P(SIGPROTOARG); + sigret_t (*sigusr1)__P(SIGPROTOARG); + int tries; + + sigusr1 = signal(SIG_PW_OK, trysendok); + sighup = signal(SIG_PW_FAIL, trysendfail); + for (tries = 0; ; ) + { + strcpy(pwto, screenpw); + trysendstatok = trysendstatfail = 0; + if (write(fd, (char *) m, sizeof(*m)) != sizeof(*m)) + Panic(errno, "write"); + close(fd); + while (trysendstatok == 0 && trysendstatfail == 0) + pause(); + if (trysendstatok) + { + signal(SIG_PW_OK, sigusr1); + signal(SIG_PW_FAIL, sighup); + if (trysendstatfail) + kill(getpid(), SIG_PW_FAIL); + return; + } + if (++tries > 1 || (npw = getpass("Screen Password:")) == 0 || *npw == 0) + { +#ifdef NETHACK + if (nethackflag) + Panic(0, "The guard slams the door in your face."); + else +#endif + Panic(0, "Password incorrect."); + } + strncpy(screenpw, npw, 8); + if ((fd = MakeClientSocket(0)) == -1) + Panic(0, "Cannot contact screen again. Sigh."); + } +} +#endif /* PASSWORD */ + + +#ifdef DEBUG +static int AttacherPanic; + +static sigret_t +AttacherChld SIGDEFARG +{ + AttacherPanic=1; + SIGRETURN; +} +#endif + +/* + * the frontend's Interrupt handler + * we forward SIGINT to the poor backend + */ +static sigret_t +AttacherSigInt SIGDEFARG +{ + signal(SIGINT, AttacherSigInt); + Kill(MasterPid, SIGINT); + SIGRETURN; +} + +/* + * Unfortunatelly this is also the SIGHUP handler, so we have to + * check, if the backend is already detached. + */ + +sigret_t +AttacherFinit SIGDEFARG +{ + struct stat statb; + struct msg m; + int s; + + debug("AttacherFinit();\n"); + signal(SIGHUP, SIG_IGN); + /* Check if signal comes from backend */ + if (stat(SockPath, &statb) == 0 && (statb.st_mode & 0777) != 0600) + { + debug("Detaching backend!\n"); + bzero((char *) &m, sizeof(m)); + strcpy(m.m_tty, attach_tty); + debug1("attach_tty is %s\n", attach_tty); + m.m.detach.dpid = getpid(); + m.type = MSG_HANGUP; + if ((s = MakeClientSocket(0)) >= 0) + { + write(s, (char *)&m, sizeof(m)); + close(s); + } + } +#ifdef MULTIUSER + if (tty_oldmode >= 0) + { + setuid(own_uid); + chmod(attach_tty, tty_oldmode); + } +#endif + exit(0); + SIGRETURN; +} + +#ifdef POW_DETACH +static sigret_t +AttacherFinitBye SIGDEFARG +{ + int ppid; + debug("AttacherFintBye()\n"); +#if defined(MULTIUSER) && !defined(USE_SETEUID) + if (multiattach) + exit(SIG_POWER_BYE); +#endif +#ifdef MULTIUSER + setuid(own_uid); +#else + setuid(real_uid); +#endif + setgid(real_gid); + /* we don't want to disturb init (even if we were root), eh? jw */ + if ((ppid = getppid()) > 1) + Kill(ppid, SIGHUP); /* carefully say good bye. jw. */ + exit(0); + SIGRETURN; +} +#endif + +static int SuspendPlease; + +static sigret_t +SigStop SIGDEFARG +{ + debug("SigStop()\n"); + SuspendPlease = 1; + SIGRETURN; +} + +#ifdef LOCK +static int LockPlease; + +static sigret_t +DoLock SIGDEFARG +{ +# ifdef SYSVSIGS + signal(SIG_LOCK, DoLock); +# endif + debug("DoLock()\n"); + LockPlease = 1; + SIGRETURN; +} +#endif + +#if defined(SIGWINCH) && defined(TIOCGWINSZ) +static int SigWinchPlease; + +static sigret_t +AttacherWinch SIGDEFARG +{ + debug("AttacherWinch()\n"); + SigWinchPlease = 1; + SIGRETURN; +} +#endif + + +/* + * Attacher loop - no return + */ + +void +Attacher() +{ + signal(SIGHUP, AttacherFinit); + signal(SIG_BYE, AttacherFinit); +#ifdef POW_DETACH + signal(SIG_POWER_BYE, AttacherFinitBye); +#endif +#ifdef LOCK + signal(SIG_LOCK, DoLock); +#endif + signal(SIGINT, AttacherSigInt); +#ifdef BSDJOBS + signal(SIG_STOP, SigStop); +#endif +#if defined(SIGWINCH) && defined(TIOCGWINSZ) + signal(SIGWINCH, AttacherWinch); +#endif +#ifdef DEBUG + signal(SIGCHLD, AttacherChld); +#endif + debug("attacher: going for a nap.\n"); + dflag = 0; +#ifdef MULTI + xflag = 1; +#endif + for (;;) + { +#ifdef DEBUG + sleep(1); + if (kill(MasterPid, 0) < 0 && errno != EPERM) + { + debug1("attacher: Panic! MasterPid %d does not exist.\n", MasterPid); + AttacherPanic++; + } +#else + pause(); +#endif +/* + debug("attacher: ding!\n"); +*/ +#ifdef DEBUG + if (AttacherPanic) + { + fcntl(0, F_SETFL, 0); + SetTTY(0, &attach_Mode); + printf("\nSuddenly the Dungeon collapses!! - You die...\n"); + eexit(1); + } +#endif +#ifdef BSDJOBS + if (SuspendPlease) + { + SuspendPlease = 0; +#if defined(MULTIUSER) && !defined(USE_SETEUID) + if (multiattach) + exit(SIG_STOP); +#endif + signal(SIGTSTP, SIG_DFL); + debug("attacher: killing myself SIGTSTP\n"); + kill(getpid(), SIGTSTP); + debug("attacher: continuing from stop\n"); + signal(SIG_STOP, SigStop); + (void) Attach(MSG_CONT); + } +#endif +#ifdef LOCK + if (LockPlease) + { + LockPlease = 0; +#if defined(MULTIUSER) && !defined(USE_SETEUID) + if (multiattach) + exit(SIG_LOCK); +#endif + LockTerminal(); +# ifdef SYSVSIGS + signal(SIG_LOCK, DoLock); +# endif + (void) Attach(MSG_CONT); + } +#endif /* LOCK */ +#if defined(SIGWINCH) && defined(TIOCGWINSZ) + if (SigWinchPlease) + { + SigWinchPlease = 0; +# ifdef SYSVSIGS + signal(SIGWINCH, AttacherWinch); +# endif + (void) Attach(MSG_WINCH); + } +#endif /* SIGWINCH */ + } +} + +#ifdef LOCK + +/* ADDED by Rainer Pruy 10/15/87 */ +/* POLISHED by mls. 03/10/91 */ + +static char LockEnd[] = "Welcome back to screen !!\n"; + +static sigret_t +LockHup SIGDEFARG +{ + int ppid = getppid(); +#ifdef MULTIUSER + setuid(own_uid); +#else + setuid(real_uid); +#endif + setgid(real_gid); + if (ppid > 1) + Kill(ppid, SIGHUP); + exit(0); +} + +static void +LockTerminal() +{ + char *prg; + int sig, pid; + sigret_t (*sigs[NSIG])__P(SIGPROTOARG); + + for (sig = 1; sig < NSIG; sig++) + sigs[sig] = signal(sig, SIG_IGN); + signal(SIGHUP, LockHup); + printf("\n"); + + prg = getenv("LOCKPRG"); + if (prg && strcmp(prg, "builtin") && !access(prg, X_OK)) + { + signal(SIGCHLD, SIG_DFL); + debug1("lockterminal: '%s' seems executable, execl it!\n", prg); + if ((pid = fork()) == 0) + { + /* Child */ +#ifdef MULTIUSER + setuid(own_uid); +#else + setuid(real_uid); /* this should be done already */ +#endif + setgid(real_gid); + closeallfiles(0); /* important: /etc/shadow may be open */ + execl(prg, "SCREEN-LOCK", NULL); + exit(errno); + } + if (pid == -1) + { +#ifdef NETHACK + if (nethackflag) + Msg(errno, "Cannot fork terminal - lock failed"); + else +#endif + Msg(errno, "Cannot lock terminal - fork failed"); + } + else + { +#ifdef BSDWAIT + union wait wstat; +#else + int wstat; +#endif + int wret; + +#ifdef hpux + signal(SIGCHLD, SIG_DFL); +#endif + errno = 0; + while (((wret = wait(&wstat)) != pid) || + ((wret == -1) && (errno == EINTR)) + ) + errno = 0; + + if (errno) + { + Msg(errno, "Lock"); + sleep(2); + } + else if (WTERMSIG(wstat) != 0) + { + fprintf(stderr, "Lock: %s: Killed by signal: %d%s\n", prg, + WTERMSIG(wstat), WIFCORESIG(wstat) ? " (Core dumped)" : ""); + sleep(2); + } + else if (WEXITSTATUS(wstat)) + { + debug2("Lock: %s: return code %d\n", prg, WEXITSTATUS(wstat)); + } + else + printf(LockEnd); + } + } + else + { + if (prg) + { + debug1("lockterminal: '%s' seems NOT executable, we use our builtin\n", prg); + } + else + { + debug("lockterminal: using buitin.\n"); + } + screen_builtin_lck(); + } + /* reset signals */ + for (sig = 1; sig < NSIG; sig++) + { + if (sigs[sig] != (sigret_t(*)__P(SIGPROTOARG)) -1) + signal(sig, sigs[sig]); + } +} /* LockTerminal */ + +/* -- original copyright by Luigi Cannelloni 1985 (luigi@faui70.UUCP) -- */ +static void +screen_builtin_lck() +{ + char fullname[100], *cp1, message[BUFSIZ]; + char *pass, mypass[9]; + +#ifdef undef + /* get password entry */ + if ((ppp = getpwuid(real_uid)) == NULL) + { + fprintf(stderr, "screen_builtin_lck: No passwd entry.\007\n"); + sleep(2); + return; + } + if (!isatty(0)) + { + fprintf(stderr, "screen_builtin_lck: Not a tty.\007\n"); + sleep(2); + return; + } +#endif + pass = ppp->pw_passwd; + if (pass == 0 || *pass == 0) + { + if ((pass = getpass("Key: "))) + { + strncpy(mypass, pass, 8); + mypass[8] = 0; + if (*mypass == 0) + return; + if ((pass = getpass("Again: "))) + { + if (strcmp(mypass, pass)) + { + fprintf(stderr, "Passwords don't match.\007\n"); + sleep(2); + return; + } + } + } + if (pass == 0) + { + fprintf(stderr, "Getpass error.\007\n"); + sleep(2); + return; + } + pass = 0; + } + + debug("screen_builtin_lck looking in gcos field\n"); + strcpy(fullname, ppp->pw_gecos); + if ((cp1 = index(fullname, ',')) != NULL) + *cp1 = '\0'; + if ((cp1 = index(fullname, '&')) != NULL) + { + sprintf(cp1, "%s", ppp->pw_name); + if (*cp1 >= 'a' && *cp1 <= 'z') + *cp1 -= 'a' - 'A'; + } + + sprintf(message, "Screen used by %s <%s>.\nPassword:\007", + fullname, ppp->pw_name); + + /* loop here to wait for correct password */ + for (;;) + { + debug("screen_builtin_lck awaiting password\n"); + errno = 0; + if ((cp1 = getpass(message)) == NULL) + { + AttacherFinit(SIGARG); + /* NOTREACHED */ + } + debug3("getpass(%d): %x == %s\n", errno, (unsigned int)cp1, cp1); + if (pass) + { + if (!strncmp(crypt(cp1, pass), pass, strlen(pass))) + break; + } + else + { + if (!strcmp(cp1, mypass)) + break; + } + debug("screen_builtin_lck: NO!!!!!\n"); + } + debug("password ok.\n"); +} + +#endif /* LOCK */ diff --git a/comm.c b/comm.c new file mode 100644 index 0000000..a676cb6 --- /dev/null +++ b/comm.c @@ -0,0 +1,223 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ + +#include "rcs.h" +RCS_ID("$Id: comm.c,v 1.10 1993/11/30 19:28:07 mlschroe Exp $ FAU") + +#include "config.h" +#include "acls.h" +#include "comm.h" + +/* Must be in alpha order ! */ + +struct comm comms[RC_LAST + 1] = +{ +#ifdef MULTIUSER + { "acladd", ARGS_ONE }, + { "aclchg", ARGS_THREE }, + { "acldel", ARGS_ONE }, + { "aclgrp", ARGS_ONE }, +#endif + { "activity", ARGS_ONE }, + { "aka", NEED_FORE|ARGS_ZEROONE }, /* TO BE REMOVED */ + { "allpartial", NEED_DISPLAY|ARGS_ONE }, + { "at", NEED_DISPLAY|ARGS_TWO|ARGS_ORMORE }, + { "autodetach", ARGS_ONE }, +#ifdef AUTO_NUKE + { "autonuke", NEED_DISPLAY|ARGS_ONE }, +#endif + { "bell", ARGS_ZEROONE }, + { "bell_msg", ARGS_ZEROONE }, + { "bind", ARGS_ONE|ARGS_ORMORE }, +#ifdef MAPKEYS + { "bindkey", ARGS_ZERO|ARGS_ORMORE }, +#endif + { "break", NEED_FORE|ARGS_ZEROONE }, +#ifdef COPY_PASTE + { "bufferfile", ARGS_ZEROONE }, +#endif + { "c1", NEED_FORE|ARGS_ZEROONE }, + { "charset", NEED_FORE|ARGS_ONE }, + { "chdir", ARGS_ZEROONE }, + { "clear", NEED_FORE|ARGS_ZERO }, +#ifdef MULTI + { "clone", NEED_DISPLAY|ARGS_ONE|ARGS_ORMORE }, +#endif + { "colon", NEED_DISPLAY|ARGS_ZERO }, + { "command", NEED_DISPLAY|ARGS_ZERO }, + { "console", NEED_FORE|ARGS_ZEROONE }, +#ifdef COPY_PASTE + { "copy", NEED_FORE|ARGS_ZERO }, + { "crlf", ARGS_ONE }, +#endif + { "debug", ARGS_ZEROONE }, +#ifdef AUTO_NUKE + { "defautonuke", ARGS_ONE }, +#endif + { "defc1", ARGS_ONE }, + { "defcharset", ARGS_ZEROONE }, + { "defescape", ARGS_ONE }, + { "defflow", ARGS_ONETWO }, + { "defgr", ARGS_ONE }, + { "defhstatus", ARGS_ZEROONE }, +#ifdef KANJI + { "defkanji", ARGS_ONE }, +#endif +#if defined(UTMPOK) && defined(LOGOUTOK) + { "deflogin", ARGS_ONE }, +#endif + { "defmode", ARGS_ONE }, + { "defmonitor", ARGS_ONE }, + { "defobuflimit", ARGS_ONE }, +#ifdef COPY_PASTE + { "defscrollback", ARGS_ONE }, +#endif + { "defwrap", ARGS_ONE }, + { "defwritelock", ARGS_ONE }, + { "detach", NEED_DISPLAY|ARGS_ZERO }, + { "digraph", NEED_DISPLAY|ARGS_ZEROONE }, + { "displays", NEED_DISPLAY|ARGS_ZERO }, + { "dumptermcap", NEED_FORE|ARGS_ZERO }, + { "echo", ARGS_ONETWO }, + { "escape", NEED_DISPLAY|ARGS_ONE }, +#ifdef PSEUDOS + { "exec", NEED_FORE|ARGS_ZERO|ARGS_ORMORE }, +#endif + { "flow", NEED_FORE|ARGS_ZEROONE }, + { "gr", NEED_FORE|ARGS_ZEROONE }, + { "hardcopy", NEED_FORE|ARGS_ZERO }, + { "hardcopy_append", ARGS_ONE }, + { "hardcopydir", ARGS_ONE }, + { "hardstatus", NEED_DISPLAY|ARGS_ZEROONE }, + { "height", NEED_DISPLAY|ARGS_ZEROONE }, + { "help", NEED_DISPLAY|ARGS_ZERO }, +#ifdef COPY_PASTE + { "history", NEED_FORE|ARGS_ZERO }, +#endif + { "info", NEED_DISPLAY|ARGS_ZERO }, +#ifdef KANJI + { "kanji", NEED_FORE|ARGS_ONETWO }, +#endif + { "kill", NEED_FORE|ARGS_ZERO }, + { "lastmsg", NEED_DISPLAY|ARGS_ZERO }, + { "license", NEED_DISPLAY|ARGS_ZERO }, +#ifdef LOCK + { "lockscreen", NEED_DISPLAY|ARGS_ZERO }, +#endif + { "log", NEED_FORE|ARGS_ZEROONE }, + { "logfile", ARGS_ZEROONE }, +#if defined(UTMPOK) && defined(LOGOUTOK) + { "login", NEED_FORE|ARGS_ZEROONE }, +#endif +#ifdef MAPKEYS + { "mapdefault", NEED_DISPLAY|ARGS_ZERO }, + { "mapnotnext", NEED_DISPLAY|ARGS_ZERO }, + { "maptimeout", ARGS_ZEROONE }, +#endif +#ifdef COPY_PASTE + { "markkeys", ARGS_ONE }, +#endif + { "meta", NEED_DISPLAY|ARGS_ZERO }, + { "monitor", NEED_FORE|ARGS_ZEROONE }, + { "msgminwait", ARGS_ONE }, + { "msgwait", ARGS_ONE }, +#ifdef MULTIUSER + { "multiuser", ARGS_ONE }, +#endif +#ifdef NETHACK + { "nethack", ARGS_ONE }, +#endif + { "next", NEED_DISPLAY|NEED_FORE|ARGS_ZERO }, + { "number", NEED_FORE|ARGS_ZEROONE }, + { "obuflimit", NEED_DISPLAY|ARGS_ZEROONE }, + { "other", NEED_DISPLAY|NEED_FORE|ARGS_ZERO }, + { "partial", NEED_FORE|ARGS_ZEROONE }, +#ifdef PASSWORD + { "password", ARGS_ZEROONE }, +#endif +#ifdef COPY_PASTE + { "paste", NEED_DISPLAY|ARGS_ZEROONETWO }, + { "pastefont", ARGS_ZEROONE }, +#endif + { "pow_break", NEED_FORE|ARGS_ZEROONE }, +#ifdef POW_DETACH + { "pow_detach", NEED_DISPLAY|ARGS_ZERO }, + { "pow_detach_msg", ARGS_ZEROONE }, +#endif + { "prev", NEED_DISPLAY|NEED_FORE|ARGS_ZERO }, + { "printcmd", ARGS_ZEROONE }, + { "process", NEED_DISPLAY|ARGS_ZEROONE }, + { "quit", ARGS_ZERO }, +#ifdef COPY_PASTE + { "readbuf", NEED_DISPLAY|ARGS_ZERO }, +#endif + { "readreg", ARGS_ZEROONETWO }, + { "redisplay", NEED_DISPLAY|ARGS_ZERO }, + { "register", ARGS_TWO }, +#ifdef COPY_PASTE + { "removebuf", ARGS_ZERO }, +#endif + { "reset", NEED_FORE|ARGS_ZERO }, + { "screen", ARGS_ZERO|ARGS_ORMORE }, +#ifdef COPY_PASTE + { "scrollback", NEED_FORE|ARGS_ONE }, +#endif + { "select", ARGS_ZEROONE }, + { "sessionname", ARGS_ZEROONE }, + { "setenv", ARGS_ZEROONETWO }, + { "shell", ARGS_ONE }, + { "shellaka", ARGS_ONE }, /* TO BE REMOVED */ + { "shelltitle", ARGS_ONE }, + { "silence", NEED_FORE|ARGS_ZEROONE }, + { "silencewait", ARGS_ONE }, + { "sleep", ARGS_ONE }, + { "slowpaste", ARGS_ONE }, + { "sorendition", ARGS_ZEROONETWO }, + { "startup_message", ARGS_ONE }, + { "stuff", NEED_DISPLAY|ARGS_ONE }, +#ifdef BSDJOBS + { "suspend", NEED_DISPLAY|ARGS_ZERO }, +#endif + { "term", ARGS_ONE }, + { "termcap", ARGS_TWOTHREE }, + { "termcapinfo", ARGS_TWOTHREE }, + { "terminfo", ARGS_TWOTHREE }, + { "time", ARGS_ZERO }, + { "title", NEED_FORE|ARGS_ZEROONE }, + { "unsetenv", ARGS_ONE }, + { "vbell", ARGS_ZEROONE }, + { "vbell_msg", ARGS_ZEROONE }, + { "vbellwait", ARGS_ONE }, + { "version", ARGS_ZERO }, + { "wall", NEED_DISPLAY|ARGS_ONE|ARGS_ORMORE }, + { "width", NEED_DISPLAY|ARGS_ZEROONE }, + { "windows", NEED_DISPLAY|ARGS_ZERO }, + { "wrap", NEED_FORE|ARGS_ZEROONE }, +#ifdef COPY_PASTE + { "writebuf", NEED_DISPLAY|ARGS_ZERO }, +#endif + { "writelock", NEED_FORE|ARGS_ZEROONE }, + { "xoff", NEED_DISPLAY|ARGS_ZERO }, + { "xon", NEED_DISPLAY|ARGS_ZERO }, + { "zombie", ARGS_ZEROONE } +}; diff --git a/comm.h.dist b/comm.h.dist new file mode 100644 index 0000000..bbe0052 --- /dev/null +++ b/comm.h.dist @@ -0,0 +1,177 @@ +/* + * This file is automagically created from comm.c -- DO NOT EDIT + */ + +struct comm +{ + char *name; + int flags; +#ifdef MULTIUSER + AclBits userbits[ACL_BITS_PER_CMD]; +#endif +}; + +#define ARGS_MASK (3) + +#define ARGS_ZERO (0) +#define ARGS_ONE (1) +#define ARGS_TWO (2) +#define ARGS_THREE (3) + +#define ARGS_PLUSONE (1<<2) +#define ARGS_PLUSTWO (1<<3) +#define ARGS_ORMORE (1<<4) + +#define NEED_FORE (1<<5) /* this command needs a fore window */ +#define NEED_DISPLAY (1<<6) /* this command needs a display */ + +#define ARGS_ZEROONE (ARGS_ZERO|ARGS_PLUSONE) +#define ARGS_ONETWO (ARGS_ONE |ARGS_PLUSONE) +#define ARGS_TWOTHREE (ARGS_TWO |ARGS_PLUSONE) +#define ARGS_ZEROTWO (ARGS_ZERO|ARGS_PLUSTWO) +#define ARGS_ZEROONETWO (ARGS_ZERO|ARGS_PLUSONE|ARGS_PLUSTWO) + +struct action +{ + int nr; + char **args; +}; + +#define RC_ILLEGAL -1 + +#define RC_ACLADD 0 +#define RC_ACLCHG 1 +#define RC_ACLDEL 2 +#define RC_ACLGRP 3 +#define RC_ACTIVITY 4 +#define RC_AKA 5 +#define RC_ALLPARTIAL 6 +#define RC_AT 7 +#define RC_AUTODETACH 8 +#define RC_AUTONUKE 9 +#define RC_BELL 10 +#define RC_BELL_MSG 11 +#define RC_BIND 12 +#define RC_BINDKEY 13 +#define RC_BREAK 14 +#define RC_BUFFERFILE 15 +#define RC_C1 16 +#define RC_CHARSET 17 +#define RC_CHDIR 18 +#define RC_CLEAR 19 +#define RC_CLONE 20 +#define RC_COLON 21 +#define RC_COMMAND 22 +#define RC_CONSOLE 23 +#define RC_COPY 24 +#define RC_CRLF 25 +#define RC_DEBUG 26 +#define RC_DEFAUTONUKE 27 +#define RC_DEFC1 28 +#define RC_DEFCHARSET 29 +#define RC_DEFESCAPE 30 +#define RC_DEFFLOW 31 +#define RC_DEFGR 32 +#define RC_DEFHSTATUS 33 +#define RC_DEFKANJI 34 +#define RC_DEFLOGIN 35 +#define RC_DEFMODE 36 +#define RC_DEFMONITOR 37 +#define RC_DEFOBUFLIMIT 38 +#define RC_DEFSCROLLBACK 39 +#define RC_DEFWRAP 40 +#define RC_DEFWRITELOCK 41 +#define RC_DETACH 42 +#define RC_DIGRAPH 43 +#define RC_DISPLAYS 44 +#define RC_DUMPTERMCAP 45 +#define RC_ECHO 46 +#define RC_ESCAPE 47 +#define RC_EXEC 48 +#define RC_FLOW 49 +#define RC_GR 50 +#define RC_HARDCOPY 51 +#define RC_HARDCOPY_APPEND 52 +#define RC_HARDCOPYDIR 53 +#define RC_HARDSTATUS 54 +#define RC_HEIGHT 55 +#define RC_HELP 56 +#define RC_HISTORY 57 +#define RC_INFO 58 +#define RC_KANJI 59 +#define RC_KILL 60 +#define RC_LASTMSG 61 +#define RC_LICENSE 62 +#define RC_LOCKSCREEN 63 +#define RC_LOG 64 +#define RC_LOGFILE 65 +#define RC_LOGIN 66 +#define RC_MAPDEFAULT 67 +#define RC_MAPNOTNEXT 68 +#define RC_MAPTIMEOUT 69 +#define RC_MARKKEYS 70 +#define RC_META 71 +#define RC_MONITOR 72 +#define RC_MSGMINWAIT 73 +#define RC_MSGWAIT 74 +#define RC_MULTIUSER 75 +#define RC_NETHACK 76 +#define RC_NEXT 77 +#define RC_NUMBER 78 +#define RC_OBUFLIMIT 79 +#define RC_OTHER 80 +#define RC_PARTIAL 81 +#define RC_PASSWORD 82 +#define RC_PASTE 83 +#define RC_PASTEFONT 84 +#define RC_POW_BREAK 85 +#define RC_POW_DETACH 86 +#define RC_POW_DETACH_MSG 87 +#define RC_PREV 88 +#define RC_PRINTCMD 89 +#define RC_PROCESS 90 +#define RC_QUIT 91 +#define RC_READBUF 92 +#define RC_READREG 93 +#define RC_REDISPLAY 94 +#define RC_REGISTER 95 +#define RC_REMOVEBUF 96 +#define RC_RESET 97 +#define RC_SCREEN 98 +#define RC_SCROLLBACK 99 +#define RC_SELECT 100 +#define RC_SESSIONNAME 101 +#define RC_SETENV 102 +#define RC_SHELL 103 +#define RC_SHELLAKA 104 +#define RC_SHELLTITLE 105 +#define RC_SILENCE 106 +#define RC_SILENCEWAIT 107 +#define RC_SLEEP 108 +#define RC_SLOWPASTE 109 +#define RC_SORENDITION 110 +#define RC_STARTUP_MESSAGE 111 +#define RC_STUFF 112 +#define RC_SUSPEND 113 +#define RC_TERM 114 +#define RC_TERMCAP 115 +#define RC_TERMCAPINFO 116 +#define RC_TERMINFO 117 +#define RC_TIME 118 +#define RC_TITLE 119 +#define RC_UNSETENV 120 +#define RC_VBELL 121 +#define RC_VBELL_MSG 122 +#define RC_VBELLWAIT 123 +#define RC_VERSION 124 +#define RC_WALL 125 +#define RC_WIDTH 126 +#define RC_WINDOWS 127 +#define RC_WRAP 128 +#define RC_WRITEBUF 129 +#define RC_WRITELOCK 130 +#define RC_XOFF 131 +#define RC_XON 132 +#define RC_ZOMBIE 133 + +#define RC_LAST 133 diff --git a/comm.sh b/comm.sh new file mode 100644 index 0000000..9aa0a20 --- /dev/null +++ b/comm.sh @@ -0,0 +1,77 @@ +#! /bin/sh + +if test -z "$AWK"; then + AWK=awk +fi +if test -z "$CC"; then + CC=cc +fi +if test -z "$srcdir"; then + srcdir=. +fi + +rm -f comm.h +cat << EOF > comm.h +/* + * This file is automagically created from comm.c -- DO NOT EDIT + */ + +struct comm +{ + char *name; + int flags; +#ifdef MULTIUSER + AclBits userbits[ACL_BITS_PER_CMD]; +#endif +}; + +#define ARGS_MASK (3) + +#define ARGS_ZERO (0) +#define ARGS_ONE (1) +#define ARGS_TWO (2) +#define ARGS_THREE (3) + +#define ARGS_PLUSONE (1<<2) +#define ARGS_PLUSTWO (1<<3) +#define ARGS_ORMORE (1<<4) + +#define NEED_FORE (1<<5) /* this command needs a fore window */ +#define NEED_DISPLAY (1<<6) /* this command needs a display */ + +#define ARGS_ZEROONE (ARGS_ZERO|ARGS_PLUSONE) +#define ARGS_ONETWO (ARGS_ONE |ARGS_PLUSONE) +#define ARGS_TWOTHREE (ARGS_TWO |ARGS_PLUSONE) +#define ARGS_ZEROTWO (ARGS_ZERO|ARGS_PLUSTWO) +#define ARGS_ZEROONETWO (ARGS_ZERO|ARGS_PLUSONE|ARGS_PLUSTWO) + +struct action +{ + int nr; + char **args; +}; + +#define RC_ILLEGAL -1 + +EOF +$AWK < ${srcdir}/comm.c >> comm.h ' +/^ [{] ".*/ { if (old > $2) { + printf("***ERROR: %s <= %s !!!\n\n", $2, old); + exit 1; + } + old = $2; + } +' +$CC -E -I. -I${srcdir} ${srcdir}/comm.c > comm.cpp +sed < comm.cpp \ + -n \ + -e '/^ *{ "/y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \ + -e '/^ *{ "/s/^ *{ "\([^"]*\)".*/\1/p' \ +| $AWK ' +/.*/ { printf "#define RC_%s %d\n",$0,i++; + } +END { printf "\n#define RC_LAST %d\n",i-1; + } +' >> comm.h +chmod a-w comm.h +rm -f comm.cpp diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..2d79d57 --- /dev/null +++ b/config.h.in @@ -0,0 +1,466 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + **************************************************************** + * $Id: config.h.in,v 1.12 1994/05/31 12:31:36 mlschroe Exp $ FAU + */ + + + + + +/********************************************************************** + * + * User Configuration Section + */ + + + +/* + * Define SOCKDIR to be the directory to contain the named sockets + * screen creates. This should be in a common subdirectory, such as + * /usr/local or /tmp. It makes things a little more secure if you + * choose a directory which is not writable by everyone or where the + * "sticky" bit is on, but this isn't required. + * If SOCKDIR is not defined screen will put the named sockets in + * the user's home directory. Notice that this can cause you problems + * if some user's HOME directories are NFS-mounted and don't support + * named sockets. + * Screen will name the subdirectories "S-$USER" (e.g /tmp/S-davison). + * Do not define TMPTEST unless it's for debugging purpose. + */ + +#ifndef TMPTEST +# define SOCKDIR "/tmp/screens" +#else +# define SOCKDIR "/tmp/testscreens" +#endif + +/* + * Screen sources two startup files. First a global file with a path + * specified here, second your local $HOME/.screenrc + * Don't define this, if you don't want it. + */ +#ifndef ETCSCREENRC +# define ETCSCREENRC "/usr/local/etc/screenrc" +#endif + +/* + * Screen can look for the environment variable $SYSSCREENRC and -if it + * exists- load the file specified in that variable as global screenrc. + * If you want to enable this feature, define ALLOW_SYSSCREENRC to one (1). + * Otherwise ETCSCREENRC is always loaded. + */ +#define ALLOW_SYSSCREENRC 1 + +/* + * define PTYMODE if you do not like the default of 0622, which allows + * public write to your pty. + * define PTYGROUP to some numerical group-id if you do not want the + * tty to be in "your" group. + * Note, screen is unable to change mode or group of the pty if it + * is not installed with sufficient privilege. (e.g. set-uid-root) + */ +#undef PTYMODE +#undef PTYGROUP + +/* + * If screen is NOT installed set-uid root, screen can provide tty + * security by exclusively locking the ptys. While this keeps other + * users from opening your ptys, it also keeps your own subprocesses + * from being able to open /dev/tty. Define LOCKPTY to add this + * exclusive locking. + */ +#undef LOCKPTY + +/* + * If you'd rather see the status line on the first line of your + * terminal rather than the last, define TOPSTAT. + */ +#undef TOPSTAT + +/* + * here come the erlangen extensions to screen: + * define LOCK if you want to use a lock program for a screenlock. + * define PASSWORD for secure reattach of your screen. + * define COPY_PASTE to use the famous hacker's treasure zoo. + * define POW_DETACH to have a detach_and_logout key. + * define REMOTE_DETACH (-d option) to move screen between terminals. + * define AUTO_NUKE to enable Tim MacKenzies clear screen nuking + * define PSEUDOS to allow window input/output filtering + * define MULTI to allow multiple attaches. + * define MULTIUSER to allow other users attach to your session + * (if they are in the acl, of course) + * (jw) + */ +#undef SIMPLESCREEN +#ifndef SIMPLESCREEN +# define LOCK +# define PASSWORD +# define COPY_PASTE +# define REMOTE_DETACH +# define POW_DETACH +# define AUTO_NUKE +# define PSEUDOS +# define MULTI +# define MULTIUSER +# define MAPKEYS +# define COLOR +#endif /* SIMPLESCREEN */ +#define KANJI + +/* + * As error messages are mostly meaningless to the user, we + * try to throw out phrases that are somewhat more familiar + * to ...well, at least familiar to us NetHack players. + */ +#ifndef NONETHACK +# define NETHACK +#endif /* NONETHACK */ + +/* + * If screen is installed with permissions to update /etc/utmp (such + * as if it is installed set-uid root), define UTMPOK. + */ +#define UTMPOK + +/* Set LOGINDEFAULT to one (1) + * if you want entries added to /etc/utmp by default, else set it to + * zero (0). + * LOGINDEFAULT will be one (1) whenever LOGOUTOK is undefined! + */ +#define LOGINDEFAULT 1 + +/* Set LOGOUTOK to one (1) + * if you want the user to be able to log her/his windows out. + * (Meaning: They are there, but not visible in /etc/utmp). + * Disabling this feature only makes sense if you have a secure /etc/utmp + * database. + * Negative examples: suns usually have a world writable utmp file, + * xterm and script will run perfectly without s-bit. + * If LOGOUTOK is undefined and UTMPOK is defined, all windows are initially + * and permanently logged in. + */ +#define LOGOUTOK 1 + + +/* + * If UTMPOK is defined and your system (incorrectly) counts logins by + * counting non-null entries in /etc/utmp (instead of counting non-null + * entries with no hostname that are not on a pseudo tty), define USRLIMIT + * to have screen put an upper-limit on the number of entries to write + * into /etc/utmp. This helps to keep you from exceeding a limited-user + * license. + */ +#undef USRLIMIT + + +/* + * Some terminals, e.g. Wyse 120, use a bitfield to select attributes. + * This doesn't work with the standard so/ul/m? terminal entries, + * because they will cancel each other out. + * On TERMINFO machines, "sa" (sgr) may work. If you want screen + * to switch attributes only with sgr, define USE_SGR. + * This is *not* recomended, do this only if you must. + */ +#undef USE_SGR + + +/********************************************************************** + * + * End of User Configuration Section + * + * Rest of this file is modified by 'configure' + * Change at your own risk! + * + */ + +/* + * Some defines to identify special unix variants + */ +#ifndef SVR4 +#undef SVR4 +#endif + +/* #ifndef __osf__ */ +#ifndef MIPS +#undef MIPS +#endif +/* #endif */ + +#ifndef OSX +#undef OSX +#endif + +#ifndef ISC +#undef ISC +#endif + +#ifndef sysV68 +#undef sysV68 +#endif + +#ifndef _POSIX_SOURCE +#undef _POSIX_SOURCE +#endif + +/* + * Define POSIX if your system supports IEEE Std 1003.1-1988 (POSIX). + */ +#undef POSIX + +/* + * Define BSDJOBS if you have BSD-style job control (both process + * groups and a tty that deals correctly with them). + */ +#undef BSDJOBS + +/* + * Define TERMIO if you have struct termio instead of struct sgttyb. + * This is usually the case for SVID systems, where BSD uses sgttyb. + * POSIX systems should define this anyway, even though they use + * struct termios. + */ +#undef TERMIO + +/* + * Define CYTERMIO if you have cyrillic termio modes. + */ +#undef CYTERMIO + +/* + * Define TERMINFO if your machine emulates the termcap routines + * with the terminfo database. + * Thus the .screenrc file is parsed for + * the command 'terminfo' and not 'termcap'. + */ +#undef TERMINFO + +/* + * If your library does not define ospeed, define this. + */ +#undef NEED_OSPEED + +/* + * Define SYSV if your machine is SYSV complient (Sys V, HPUX, A/UX) + */ +#ifndef SYSV +#undef SYSV +#endif + +/* + * Define SIGVOID if your signal handlers return void. On older + * systems, signal returns int, but on newer ones, it returns void. + */ +#undef SIGVOID + +/* + * Define USESIGSET if you have sigset for BSD 4.1 reliable signals. + */ +#undef USESIGSET + +/* + * Define SYSVSIGS if signal handlers must be reinstalled after + * they have been called. + */ +#undef SYSVSIGS + +/* + * Define BSDWAIT if your system defines a 'union wait' in + * + * Only allow BSDWAIT i.e. wait3 on nonposix systems, since + * posix implies wait(3) and waitpid(3). vdlinden@fwi.uva.nl + * + */ +#ifndef POSIX +#undef BSDWAIT +#endif + +/* + * On RISCOS we prefer wait2() over wait3(). rouilj@sni-usa.com + */ +#ifdef BSDWAIT +#undef USE_WAIT2 +#endif + +/* + * Define DIRENT if your system has instead of + */ +#undef DIRENT + +/* + * If your system has getutent(), pututline(), etc. to write to the + * utmp file, define GETUTENT. + */ +#undef GETUTENT + +/* + * Define UTHOST if the utmp file has a host field. + */ +#undef UTHOST + +/* + * If ttyslot() breaks getlogin() by returning indexes to utmp entries + * of type DEAD_PROCESS, then our getlogin() replacement should be + * selected by defining BUGGYGETLOGIN. + */ +#undef BUGGYGETLOGIN + +/* + * If your system has the calls setreuid() and setregid(), + * define HAVE_SETREUID. Otherwise screen will use a forked process to + * safely create output files without retaining any special privileges. + * (Output logging will be disabled, however.) + */ +#undef HAVE_SETREUID + +/* + * If your system supports BSD4.4's seteuid() and setegid(), define + * HAVE_SETEUID. + */ +#undef HAVE_SETEUID + +/* + * If you want the "time" command to display the current load average + * define LOADAV. Maybe you must install screen with the needed + * privileges to read /dev/kmem. + * Note that NLIST_ stuff is only checked, when getloadavg() is not available. + */ +#undef LOADAV + +#undef LOADAV_NUM +#undef LOADAV_TYPE +#undef LOADAV_SCALE +#undef LOADAV_GETLOADAVG +#undef LOADAV_UNIX +#undef LOADAV_AVENRUN + +#undef NLIST_DECLARED +#undef NLIST_STRUCT +#undef NLIST_NAME_UNION + +/* + * If your system has the new format /etc/ttys (like 4.3 BSD) and the + * getttyent(3) library functions, define GETTTYENT. + */ +#undef GETTTYENT + +/* + * Define USEBCOPY if the bcopy/memcpy from your system's C library + * supports the overlapping of source and destination blocks. When + * undefined, screen uses its own (probably slower) version of bcopy(). + * + * SYSV machines may have a working memcpy() -- Oh, this is + * quite unlikely. Tell me if you see one. (Juergen) + * But then, memmove() should work, if at all available. + */ +#undef USEBCOPY +#undef USEMEMCPY +#undef USEMEMMOVE + +/* + * If your system has vsprintf() and requires the use of the macros in + * "varargs.h" to use functions with variable arguments, + * define USEVARARGS. + */ +#undef USEVARARGS + +/* + * If your system has strerror() define this. + */ +#undef HAVE_STRERROR + +/* + * If the select return value doesn't treat a descriptor that is + * usable for reading and writing as two hits, define SELECT_BROKEN. + */ +#undef SELECT_BROKEN + +/* + * Define this if your system supports named pipes. + */ +#undef NAMEDPIPE + +/* + * Define this if your system exits select() immediatly if a pipe is + * opened read-only and no writer has opened it. + */ +#undef BROKEN_PIPE + +/* + * Define this if the unix-domain socket implementation doesn't + * create a socket in the filesystem. + */ +#undef SOCK_NOT_IN_FS + +/* + * If your system has setenv() and unsetenv() define USESETENV + */ +#undef USESETENV + +/* + * If your system does not come with a setenv()/putenv()/getenv() + * functions, you may bring in our own code by defining NEEDPUTENV. + */ +#undef NEEDPUTENV + +/* + * If the passwords are stored in a shadow file and you want the + * builtin lock to work properly, define SHADOWPW. + */ +#undef SHADOWPW + +/* + * If you are on a SYS V machine that restricts filename length to 14 + * characters, you may need to enforce that by setting NAME_MAX to 14 + */ +#undef NAME_MAX /* KEEP_UNDEF_HERE override system value */ +#undef NAME_MAX + +/* + * define NEED_RENAME if your system doesn't have a rename() function + */ +#undef NEED_RENAME + +/* + * define HAVE__EXIT if your system has the _exit() call. + */ +#undef HAVE__EXIT + +/* + * define HAVE_LSTAT if your system has symlinks and the lstat() call. + */ +#undef HAVE_LSTAT + +/* + * define HAVE_DEV_PTC if you have a /dev/ptc character special + * device. + */ +#undef HAVE_DEV_PTC + +/* + * define PTYRANGE0 and or PTYRANGE1 if you want to adapt screen + * to unusual environments. E.g. For SunOs the defaults are "qpr" and + * "0123456789abcdef". For SunOs 4.1.2 + * #define PTYRANGE0 "pqrstuvwxyzPQRST" + * is recommended by Dan Jacobson. + */ +#undef PTYRANGE0 +#undef PTYRANGE1 + diff --git a/configure b/configure new file mode 100755 index 0000000..4ab7d58 --- /dev/null +++ b/configure @@ -0,0 +1,3257 @@ +#!/bin/sh +# From configure.in Revision: 1.17 +#!/bin/sh +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 1.11 +# Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. + +# This configure script is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This script is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +# Save the original args to write them into config.status later. +configure_args="$*" + +# Only options that might do something get documented. +ac_usage="Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +--build=BUILD configure for building on BUILD [BUILD=HOST] +--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) +--enable-FEATURE[=ARG] include FEATURE [ARG=yes] +--exec-prefix=PREFIX install host dependent files in PREFIX [/usr/local] +--help print this message +--host=HOST configure for HOST [guessed] +--prefix=PREFIX install host independent files in PREFIX [/usr/local] +--quiet, --silent do not print \`checking for...' messages +--srcdir=DIR find the sources in DIR [configure dir or ..] +--target=TARGET configure for TARGET [TARGET=HOST] +--verbose print results of checks +--version print the version of autoconf that created configure +--with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) +--x-includes=DIR X include files are in DIR +--x-libraries=DIR X library files are in DIR" + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +exec_prefix= +host=NONE +no_create= +nonopt=NONE +norecursion= +prefix= +program_prefix= +program_suffix= +program_transform_name= +silent= +srcdir= +target=NONE +verbose= +x_includes= +x_libraries= + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + # Accept (but ignore some of) the important Cygnus configure + # options, so we can diagnose typos. + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + case "$ac_option" in + + -build | --build | --buil | --bui | --bu | --b) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=* | --b=*) + build="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + echo "configure: $ac_feature: invalid feature name" >&2; exit 1 + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + echo "configure: $ac_feature: invalid feature name" >&2; exit 1 + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + # For backward compatibility, recognize -exec-prefix and --exec_prefix. + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + with_gas=yes ;; # Obsolete; use --with-gas. + + -help | --help | --hel | --he) + cat << EOF +$ac_usage +EOF + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -nfp | --nfp | --nf) + with_fp=no ;; # Obsolete; use --without-fp. + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -norecursion | --norecursion | --norecursio | --norecursi \ + | --norecurs | --norecur | --norecu | --norec | --nore | --nor) + norecursion=yes ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 1.11" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + echo "configure: $ac_package: invalid package name" >&2; exit 1 + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that aren't valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + echo "configure: $ac_package: invalid package name" >&2; exit 1 + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) with_x=yes ;; # Obsolete; use --with-x. + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) echo "configure: $ac_option: invalid option; use --help to show usage" >&2; exit 1 + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" >&2 + fi + if test "x$nonopt" != xNONE; then + echo "configure: can only configure for one host and one target at a time" >&2; exit 1 + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + echo "configure: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" >&2; exit 1 +fi + +trap 'rm -fr conftest* confdefs* core $ac_clean_files; exit 1' 1 2 15 +trap 'rm -fr confdefs* $ac_clean_files' 0 + +# Save the original args if we used an alternate arg parser. +ac_configure_temp="${configure_args-$*}" +# Strip out --no-create and --norecursion so they don't pile up. +configure_args= +for ac_arg in $ac_configure_temp; do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -norecursion | --norecursion | --norecursio | --norecursi \ + | --norecurs | --norecur | --norecu | --norec | --nore | --nor) ;; + *) configure_args="$configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = 'set'; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = 'set'; then LANG=C; export LANG; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=screen.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then `..'. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +fi +if test ! -r $srcdir/$ac_unique_file; then + if test x$ac_srcdir_defaulted = xyes; then + echo "configure: can not find sources in ${ac_confdir} or .." >&2; exit 1 + else + echo "configure: can not find sources in ${srcdir}" >&2; exit 1 + fi +fi +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='${CPP}' +ac_compile='${CC-cc} $CFLAGS $LDFLAGS conftest.${ac_ext} -o conftest $LIBS >/dev/null 2>&1' + + + + + +rev=`sed < ${srcdir}/patchlevel.h -n -e '/#define REV/s/#define REV *//p'` +vers=`sed < ${srcdir}/patchlevel.h -n -e '/#define VERS/s/#define VERS *//p'` +pat=`sed < ${srcdir}/patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVEL *//p'` +VERSION="$rev.$vers.$pat" +test -n "$silent" || echo "this is screen version $VERSION" + +if test -z "$prefix" +then + test -n "$silent" || echo "checking for gzip to derive installation directory prefix" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="$IFS:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test $ac_dir != . && test -f $ac_dir/gzip; then + # Not all systems have dirname. + prefix=`echo $ac_dir|sed 's%/[^/][^/]*$%%'` + break + fi + done + IFS="$ac_save_ifs" + test -n "$verbose" && echo " chose installation directory prefix ${prefix}" +fi + + +if test -z "$CC"; then + # Extract the first word of `gcc', so it can be a program name with args. + set ac_dummy gcc; ac_word=$2 + test -n "$silent" || echo "checking for $ac_word" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +test -z "$CC" && CC="cc" +test -n "$CC" && test -n "$verbose" && echo " setting CC to $CC" + +# Find out if we are using GNU C, under whatever name. +cat > conftest.c < conftest.out 2>&1 +if egrep yes conftest.out >/dev/null 2>&1; then + GCC=1 # For later tests. +fi +rm -f conftest* + +test -n "$silent" || echo "checking how to run the C preprocessor" +if test -z "$CPP"; then + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and ``${CC-cc}'' will simply confuse + # make. It must be expanded now. + CPP="${CC-cc} -E" + cat > conftest.${ac_ext} < +Syntax Error +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + : +else + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.${ac_ext} < +Syntax Error +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + : +else + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +test -n "$verbose" && echo " setting CPP to $CPP" + +if test -n "$GCC"; then + test -n "$silent" || echo "checking whether -traditional is needed" + ac_pattern="Autoconf.*'x'" + ac_prog='#include +Autoconf TIOCGETP' + cat > conftest.${ac_ext} < conftest.out 2>&1" +if egrep "$ac_pattern" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + ac_need_trad=1 + +fi +rm -f conftest* + + + if test -z "$ac_need_trad"; then + ac_prog='#include +Autoconf TCGETA' + cat > conftest.${ac_ext} < conftest.out 2>&1" +if egrep "$ac_pattern" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + ac_need_trad=1 + +fi +rm -f conftest* + + fi + test -n "$ac_need_trad" && CC="$CC -traditional" +fi + +test -n "$silent" || echo "checking for POSIXized ISC" +if test -d /etc/conf/kconfig.d && + grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1 +then + ISC=1 # If later tests want to check for ISC. + +{ +test -n "$verbose" && \ +echo " defining _POSIX_SOURCE" +echo "#define" _POSIX_SOURCE "1" >> confdefs.h +DEFS="$DEFS -D_POSIX_SOURCE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}_POSIX_SOURCE\${ac_dB}_POSIX_SOURCE\${ac_dC}1\${ac_dD} +\${ac_uA}_POSIX_SOURCE\${ac_uB}_POSIX_SOURCE\${ac_uC}1\${ac_uD} +\${ac_eA}_POSIX_SOURCE\${ac_eB}_POSIX_SOURCE\${ac_eC}1\${ac_eD} +" +} + + if test -n "$GCC"; then + CC="$CC -posix" + else + CC="$CC -Xp" + fi +fi + + +cat > conftest.${ac_ext} </dev/null; then + : +else + echo "configure: Can't run the compiler - sorry" >&2; exit 1 +fi +rm -fr conftest* + +cat > conftest.${ac_ext} </dev/null; then + echo "configure: Your compiler does not set the exit status - sorry" >&2; exit 1 + +fi +rm -fr conftest* + +for ac_prog in mawk gawk nawk awk +do +if test -z "$AWK"; then + # Extract the first word of `$ac_prog', so it can be a program name with args. + set ac_dummy $ac_prog; ac_word=$2 + test -n "$silent" || echo "checking for $ac_word" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + AWK="$ac_prog" + break + fi + done + IFS="$ac_save_ifs" +fi + +test -n "$AWK" && test -n "$verbose" && echo " setting AWK to $AWK" + +test -n "$AWK" && break +done + + +# Make sure to not get the incompatible SysV /etc/install and +# /usr/sbin/install, which might be in PATH before a BSD-like install, +# or the SunOS /usr/etc/install directory, or the AIX /bin/install, +# or the AFS install, which mishandles nonexistent args, or +# /usr/ucb/install on SVR4, which tries to use the nonexistent group +# `staff', or /sbin/install on IRIX which has incompatible command-line +# syntax. Sigh. +# +# On most BSDish systems install is in /usr/bin, not /usr/ucb +# anyway. +# This turns out not to be true, so the mere pathname isn't an indication +# of whether the program works. What we really need is a set of tests for +# the install program to see if it actually works in all the required ways. +# +# Avoid using ./install, which might have been erroneously created +# by make from ./install.sh. +if test -z "${INSTALL}"; then + test -n "$silent" || echo "checking for a BSD compatible install" + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:" + for ac_dir in $PATH; do + case "$ac_dir" in + ''|.|/etc|/sbin|/usr/sbin|/usr/etc|/usr/afsws/bin|/usr/ucb) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + for ac_prog in installbsd scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + # OSF/1 installbsd also uses dspmsg, but is usable. + : + else + INSTALL="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_ifs" +fi + +if test -z "$INSTALL"; then + # As a last resort, use the slow shell script. + for ac_dir in ${srcdir} ${srcdir}/.. ${srcdir}/../..; do + if test -f $ac_dir/install.sh; then + INSTALL="$ac_dir/install.sh -c"; break + fi + done +fi +if test -z "$INSTALL"; then + echo "configure: can not find install.sh in ${srcdir} or ${srcdir}/.. or ${srcdir}/../.." >&2; exit 1 +fi +test -n "$verbose" && echo " setting INSTALL to $INSTALL" + +# Use test -z because SunOS4 sh mishandles ${INSTALL_PROGRAM-'${INSTALL}'}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' +test -n "$verbose" && echo " setting INSTALL_PROGRAM to $INSTALL_PROGRAM" + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +test -n "$verbose" && echo " setting INSTALL_DATA to $INSTALL_DATA" + + +if test -f etc/toolcheck; then +test -n "$silent" || echo "checking for buggy tools" +sh etc/toolcheck +fi + +if test -n "$ISC"; then + +{ +test -n "$verbose" && \ +echo " defining ISC" +echo "#define" ISC "1" >> confdefs.h +DEFS="$DEFS -DISC=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}ISC\${ac_dB}ISC\${ac_dC}1\${ac_dD} +\${ac_uA}ISC\${ac_uB}ISC\${ac_uC}1\${ac_uD} +\${ac_eA}ISC\${ac_eB}ISC\${ac_eC}1\${ac_eD} +" +} + LIBS="$LIBS -linet" +fi + + +if test -f /sysV68 ; then + +{ +test -n "$verbose" && \ +echo " defining sysV68" +echo "#define" sysV68 "1" >> confdefs.h +DEFS="$DEFS -DsysV68=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}sysV68\${ac_dB}sysV68\${ac_dC}1\${ac_dD} +\${ac_uA}sysV68\${ac_uB}sysV68\${ac_uC}1\${ac_uD} +\${ac_eA}sysV68\${ac_eB}sysV68\${ac_eC}1\${ac_eD} +" +} + +fi + +test -n "$silent" || echo "checking for MIPS" +if test -f /lib/libmld.a || test -f /usr/lib/libmld.a || test -f /usr/lib/cmplrs/cc/libmld.a; then +test -f /bin/mx || LIBS="$LIBS -lmld" # for nlist. But not on alpha. +if test -r /dev/ptc; then + +{ +test -n "$verbose" && \ +echo " defining MIPS" +echo "#define" MIPS "1" >> confdefs.h +DEFS="$DEFS -DMIPS=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}MIPS\${ac_dB}MIPS\${ac_dC}1\${ac_dD} +\${ac_uA}MIPS\${ac_uB}MIPS\${ac_uC}1\${ac_uD} +\${ac_eA}MIPS\${ac_eB}MIPS\${ac_eC}1\${ac_eD} +" +} + +test -n "$silent" || echo "checking for wait3" +cat > conftest.${ac_ext} < conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DUSE_WAIT2=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}USE_WAIT2\${ac_dB}USE_WAIT2\${ac_dC}1\${ac_dD} +\${ac_uA}USE_WAIT2\${ac_uB}USE_WAIT2\${ac_uC}1\${ac_uD} +\${ac_eA}USE_WAIT2\${ac_eB}USE_WAIT2\${ac_eC}1\${ac_eD} +" +} + LIBS="$LIBS -lbsd" ; CC="$CC -I/usr/include/bsd" + + +fi +rm -f conftest* + +fi +rm -f conftest* + +fi +fi + +test -n "$silent" || echo "checking for Ultrix" +cat > conftest.${ac_ext} < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + ULTRIX=1 + +fi +rm -f conftest* + + +if test -f /usr/lib/libpyr.a ; then +oldlibs="$LIBS" +LIBS="$LIBS -lpyr" +test -n "$silent" || echo "checking for Pyramid OSX" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DOSX=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}OSX\${ac_dB}OSX\${ac_dC}1\${ac_dD} +\${ac_uA}OSX\${ac_uB}OSX\${ac_uC}1\${ac_uD} +\${ac_eA}OSX\${ac_eB}OSX\${ac_eC}1\${ac_eD} +" +} + + +else + rm -rf conftest* + LIBS="oldlibs" +fi +rm -f conftest* + +fi + +test -n "$silent" || echo "checking for butterfly" +cat > conftest.${ac_ext} < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + butterfly=1 + +fi +rm -f conftest* + + +if test -z "$butterfly"; then +if test -n "$ULTRIX"; then + test -z "$GCC" && CC="$CC -YBSD" +fi +test -n "$silent" || echo "checking for POSIX.1" +cat > conftest.${ac_ext} < +#include +main () { +#ifdef _POSIX_VERSION + yes +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + test -n "$silent" || echo "- you have a POSIX system" +{ +test -n "$verbose" && \ +echo " defining POSIX" +echo "#define" POSIX "1" >> confdefs.h +DEFS="$DEFS -DPOSIX=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}POSIX\${ac_dB}POSIX\${ac_dC}1\${ac_dD} +\${ac_uA}POSIX\${ac_uB}POSIX\${ac_uC}1\${ac_uD} +\${ac_eA}POSIX\${ac_eB}POSIX\${ac_eC}1\${ac_eD} +" +} + posix=1 + +fi +rm -f conftest* + +fi + +test -n "$silent" || echo "checking for System V" +cat > conftest.${ac_ext} < +#include +#include +int main() { return 0; } +int t() { int x = SIGCHLD | FNDELAY;; return 0; } +EOF +if eval $ac_compile; then + : +else + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SYSV" +echo "#define" SYSV "1" >> confdefs.h +DEFS="$DEFS -DSYSV=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSV\${ac_dB}SYSV\${ac_dC}1\${ac_dD} +\${ac_uA}SYSV\${ac_uB}SYSV\${ac_uC}1\${ac_uD} +\${ac_eA}SYSV\${ac_eB}SYSV\${ac_eC}1\${ac_eD} +" +} + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for sequent/ptx" +cat > conftest.${ac_ext} < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + LIBS="$LIBS -lsocket -linet";seqptx=1 + +fi +rm -f conftest* + + +oldlibs="$LIBS" +LIBS="$LIBS -lelf" +test -n "$silent" || echo "checking for SVR4" +cat > conftest.${ac_ext} < + +int main() { return 0; } +int t() { ; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + test -n "$silent" || echo "checking for dwarf.h" +cat > conftest.${ac_ext} < +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SVR4" +echo "#define" SVR4 "1" >> confdefs.h +DEFS="$DEFS -DSVR4=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SVR4\${ac_dB}SVR4\${ac_dC}1\${ac_dD} +\${ac_uA}SVR4\${ac_uB}SVR4\${ac_uC}1\${ac_uD} +\${ac_eA}SVR4\${ac_eB}SVR4\${ac_eC}1\${ac_eD} +" +} + +{ +test -n "$verbose" && \ +echo " defining BUGGYGETLOGIN" +echo "#define" BUGGYGETLOGIN "1" >> confdefs.h +DEFS="$DEFS -DBUGGYGETLOGIN=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}BUGGYGETLOGIN\${ac_dB}BUGGYGETLOGIN\${ac_dC}1\${ac_dD} +\${ac_uA}BUGGYGETLOGIN\${ac_uB}BUGGYGETLOGIN\${ac_uC}1\${ac_uD} +\${ac_eA}BUGGYGETLOGIN\${ac_eB}BUGGYGETLOGIN\${ac_eC}1\${ac_eD} +" +} + + +else + rm -rf conftest* + test -n "$silent" || echo "checking for elf.h" +cat > conftest.${ac_ext} < +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SVR4" +echo "#define" SVR4 "1" >> confdefs.h +DEFS="$DEFS -DSVR4=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SVR4\${ac_dB}SVR4\${ac_dC}1\${ac_dD} +\${ac_uA}SVR4\${ac_uB}SVR4\${ac_uC}1\${ac_uD} +\${ac_eA}SVR4\${ac_eB}SVR4\${ac_eC}1\${ac_eD} +" +} + +{ +test -n "$verbose" && \ +echo " defining BUGGYGETLOGIN" +echo "#define" BUGGYGETLOGIN "1" >> confdefs.h +DEFS="$DEFS -DBUGGYGETLOGIN=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}BUGGYGETLOGIN\${ac_dB}BUGGYGETLOGIN\${ac_dC}1\${ac_dD} +\${ac_uA}BUGGYGETLOGIN\${ac_uB}BUGGYGETLOGIN\${ac_uC}1\${ac_uD} +\${ac_eA}BUGGYGETLOGIN\${ac_eB}BUGGYGETLOGIN\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +fi +rm -f conftest* + + + +else + rm -rf conftest* + LIBS="$oldlibs" +fi +rm -f conftest* + + + + + +test -n "$silent" || echo "checking for BSD job control" +cat > conftest.${ac_ext} < +#include + +int main() { return 0; } +int t() { +#ifdef POSIX +tcsetpgrp(0, 0); +#else +int x = TIOCSPGRP; +#ifdef SYSV +setpgrp(); +#else +int y = TIOCNOTTY; +#endif +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + test -n "$silent" || echo "- you have jobcontrol" +{ +test -n "$verbose" && \ +echo " defining BSDJOBS" +echo "#define" BSDJOBS "1" >> confdefs.h +DEFS="$DEFS -DBSDJOBS=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}BSDJOBS\${ac_dB}BSDJOBS\${ac_dC}1\${ac_dD} +\${ac_uA}BSDJOBS\${ac_uB}BSDJOBS\${ac_uC}1\${ac_uD} +\${ac_eA}BSDJOBS\${ac_eB}BSDJOBS\${ac_eC}1\${ac_eD} +" +} + + +else + rm -rf conftest* + test -n "$silent" || echo "- you don't have jobcontrol" +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for setreuid" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DHAVE_SETREUID=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_SETREUID\${ac_dB}HAVE_SETREUID\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_SETREUID\${ac_uB}HAVE_SETREUID\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_SETREUID\${ac_eB}HAVE_SETREUID\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +test -n "$silent" || echo "checking for seteuid" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DHAVE_SETEUID=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_SETEUID\${ac_dB}HAVE_SETEUID\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_SETEUID\${ac_uB}HAVE_SETEUID\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_SETEUID\${ac_eB}HAVE_SETEUID\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for select" +cat > conftest.${ac_ext} < conftest.${ac_ext} <&2; exit 1 +fi +rm -f conftest* + + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking fifos" +cat > conftest.${ac_ext} < +#include +#include + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif + +char *fin = "/tmp/conftest$$"; + +main() +{ + struct stat stb; + int f; + + (void)alarm(5); +#ifdef POSIX + if (mkfifo(fin, 0777)) +#else + if (mknod(fin, S_IFIFO|0777, 0)) +#endif + exit(1); + if (stat(fin, &stb) || (stb.st_mode & S_IFIFO) != S_IFIFO) + exit(1); + close(0); +#ifdef __386BSD__ + /* + * The next test fails under 386BSD, but screen works using fifos. + * Fifos in O_RDWR mode are only used for the BROKEN_PIPE case and for + * the select() configuration test. + */ + exit(0); +#endif + if (open(fin, O_RDONLY | O_NONBLOCK)) + exit(1); + if (fork() == 0) + { + close(0); + if (open(fin, O_WRONLY | O_NONBLOCK)) + exit(1); + close(0); + if (open(fin, O_WRONLY | O_NONBLOCK)) + exit(1); + if (write(0, "TEST", 4) == -1) + exit(1); + exit(0); + } + f = 1; + if (select(1, &f, 0, 0, 0) == -1) + exit(1); + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + test -n "$silent" || echo "- your fifos are usable";fifo=1 + +else + test -n "$silent" || echo "- your fifos are not usable" +fi +rm -fr conftest* +rm -f /tmp/conftest* + +if test -n "$fifo"; then +test -n "$silent" || echo "checking for broken fifo implementation" +cat > conftest.${ac_ext} < +#include +#include +#include + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif + +char *fin = "/tmp/conftest$$"; + +main() +{ + struct timeval tv; + int r, x; + +#ifdef POSIX + if (mkfifo(fin, 0600)) +#else + if (mknod(fin, S_IFIFO|0600, 0)) +#endif + exit(1); + close(0); + if (open(fin, O_RDONLY|O_NONBLOCK)) + exit(1); + r = 1; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (select(1, &r, 0, 0, &tv)) + exit(1); + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + test -n "$silent" || echo "- your implementation is ok" + +else + test -n "$silent" || echo "- you have a broken implementation" +{ +test -n "$verbose" && \ +echo " defining BROKEN_PIPE" +echo "#define" BROKEN_PIPE "1" >> confdefs.h +DEFS="$DEFS -DBROKEN_PIPE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}BROKEN_PIPE\${ac_dB}BROKEN_PIPE\${ac_dC}1\${ac_dD} +\${ac_uA}BROKEN_PIPE\${ac_uB}BROKEN_PIPE\${ac_uC}1\${ac_uD} +\${ac_eA}BROKEN_PIPE\${ac_eB}BROKEN_PIPE\${ac_eC}1\${ac_eD} +" +} + fifobr=1 +fi +rm -fr conftest* +rm -f /tmp/conftest* +fi + + +test -n "$silent" || echo "checking sockets" +cat > conftest.${ac_ext} < +#include +#include +#include + +char *son = "/tmp/conftest$$"; + +main() +{ + int s1, s2, s3, l; + struct sockaddr_un a; + + (void)alarm(5); + if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + exit(1); + a.sun_family = AF_UNIX; + strcpy(a.sun_path, son); + (void) unlink(son); + if (bind(s1, (struct sockaddr *) &a, strlen(son)+2) == -1) + exit(1); + if (listen(s1, 2)) + exit(1); + if (fork() == 0) + { + if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + kill(getppid(), 3); + (void)connect(s2, (struct sockaddr *)&a, strlen(son) + 2); + if (write(s2, "HELLO", 5) == -1) + kill(getppid(), 3); + exit(0); + } + l = sizeof(a); + close(0); + if (accept(s1, &a, &l)) + exit(1); + l = 1; + if (select(1, &l, 0, 0, 0) == -1) + exit(1); + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + test -n "$silent" || echo "- your sockets are usable";sock=1 + +else + test -n "$silent" || echo "- your sockets are not usable" +fi +rm -fr conftest* +rm -f /tmp/conftest* + +if test -n "$sock"; then +test -n "$silent" || echo "checking socket implementation" +cat > conftest.${ac_ext} < +#include +#include +#include + +char *son = "/tmp/conftest$$"; + +main() +{ + int s; + struct stat stb; + struct sockaddr_un a; + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + exit(0); + a.sun_family = AF_UNIX; + strcpy(a.sun_path, son); + (void) unlink(son); + if (bind(s, (struct sockaddr *) &a, strlen(son)+2) == -1) + exit(0); + if (stat(son, &stb)) + exit(1); + close(s); + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + test -n "$silent" || echo "- you are normal" + +else + test -n "$silent" || echo "- unix domain sockets are not kept in the filesystem" + +{ +test -n "$verbose" && \ +echo " defining SOCK_NOT_IN_FS" +echo "#define" SOCK_NOT_IN_FS "1" >> confdefs.h +DEFS="$DEFS -DSOCK_NOT_IN_FS=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SOCK_NOT_IN_FS\${ac_dB}SOCK_NOT_IN_FS\${ac_dC}1\${ac_dD} +\${ac_uA}SOCK_NOT_IN_FS\${ac_uB}SOCK_NOT_IN_FS\${ac_uC}1\${ac_uD} +\${ac_eA}SOCK_NOT_IN_FS\${ac_eB}SOCK_NOT_IN_FS\${ac_eC}1\${ac_eD} +" +} + socknofs=1 +fi +rm -fr conftest* +rm -f /tmp/conftest* +fi + + +if test -n "$fifo"; then + if test -n "$sock"; then + if test -n "$nore"; then + test -n "$silent" || echo "- hmmm... better take the fifos" + +{ +test -n "$verbose" && \ +echo " defining NAMEDPIPE" +echo "#define" NAMEDPIPE "1" >> confdefs.h +DEFS="$DEFS -DNAMEDPIPE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NAMEDPIPE\${ac_dB}NAMEDPIPE\${ac_dC}1\${ac_dD} +\${ac_uA}NAMEDPIPE\${ac_uB}NAMEDPIPE\${ac_uC}1\${ac_uD} +\${ac_eA}NAMEDPIPE\${ac_eB}NAMEDPIPE\${ac_eC}1\${ac_eD} +" +} + + elif test -n "$fifobr"; then + test -n "$silent" || echo "- as your fifos are broken lets use the sockets." + else + test -n "$silent" || echo "- both sockets and fifos usable. let's take fifos." + +{ +test -n "$verbose" && \ +echo " defining NAMEDPIPE" +echo "#define" NAMEDPIPE "1" >> confdefs.h +DEFS="$DEFS -DNAMEDPIPE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NAMEDPIPE\${ac_dB}NAMEDPIPE\${ac_dC}1\${ac_dD} +\${ac_uA}NAMEDPIPE\${ac_uB}NAMEDPIPE\${ac_uC}1\${ac_uD} +\${ac_eA}NAMEDPIPE\${ac_eB}NAMEDPIPE\${ac_eC}1\${ac_eD} +" +} + + fi + else + test -n "$silent" || echo "- using named pipes" + +{ +test -n "$verbose" && \ +echo " defining NAMEDPIPE" +echo "#define" NAMEDPIPE "1" >> confdefs.h +DEFS="$DEFS -DNAMEDPIPE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NAMEDPIPE\${ac_dB}NAMEDPIPE\${ac_dC}1\${ac_dD} +\${ac_uA}NAMEDPIPE\${ac_uB}NAMEDPIPE\${ac_uC}1\${ac_uD} +\${ac_eA}NAMEDPIPE\${ac_eB}NAMEDPIPE\${ac_eC}1\${ac_eD} +" +} + + fi +elif test -n "$sock"; then + test -n "$silent" || echo "- using unix-domain sockets" +else + echo "configure: you have neither usable sockets nor usable pipes -> no screen" >&2; exit 1 +fi + + +test -n "$silent" || echo "checking select return value" +cat > conftest.${ac_ext} < +#include +#include + +char *nam = "/tmp/conftest$$"; + +#ifdef NAMEDPIPE + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif + + +main() +{ + int l; + +#ifdef __FreeBSD__ +/* From Andrew A. Chernov (ache@astral.msk.su): + * opening RDWR fifo fails in BSD 4.4, but select return values is + * right. + */ + exit(0); +#endif + (void)alarm(5); +#ifdef POSIX + if (mkfifo(nam, 0777)) +#else + if (mknod(nam, S_IFIFO|0777, 0)) +#endif + exit(1); + close(0); + if (open(nam, O_RDWR | O_NONBLOCK)) + exit(1); + if (write(0, "TEST", 4) == -1) + exit(1); + +#else + +#include +#include +#include + +main() +{ + int s1, s2, s3, l; + struct sockaddr_un a; + + (void)alarm(5); + if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + exit(1); + a.sun_family = AF_UNIX; + strcpy(a.sun_path, nam); + (void) unlink(nam); + if (bind(s1, (struct sockaddr *) &a, strlen(nam)+2) == -1) + exit(1); + if (listen(s1, 2)) + exit(1); + if (fork() == 0) + { + if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + kill(getppid(), 3); + (void)connect(s2, (struct sockaddr *)&a, strlen(nam) + 2); + if (write(s2, "HELLO", 5) == -1) + kill(getppid(), 3); + exit(0); + } + l = sizeof(a); + close(0); + if (accept(s1, (struct sockaddr *)&a, &l)) + exit(1); +#endif + + + l = 1; + if (select(1, &l, 0, 0, 0) == -1) + exit(1); + if (select(1, &l, &l, 0, 0) != 2) + exit(1); + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + test -n "$silent" || echo "- select is ok" + +else + test -n "$silent" || echo "- it is not usable" +{ +test -n "$verbose" && \ +echo " defining SELECT_BROKEN" +echo "#define" SELECT_BROKEN "1" >> confdefs.h +DEFS="$DEFS -DSELECT_BROKEN=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SELECT_BROKEN\${ac_dB}SELECT_BROKEN\${ac_dC}1\${ac_dD} +\${ac_uA}SELECT_BROKEN\${ac_uB}SELECT_BROKEN\${ac_uC}1\${ac_uD} +\${ac_eA}SELECT_BROKEN\${ac_eB}SELECT_BROKEN\${ac_eC}1\${ac_eD} +" +} + +fi +rm -fr conftest* + +test -n "$silent" || echo "checking for tgetent" +olibs="$LIBS" +LIBS="-lcurses $olibs" +test -n "$silent" || echo "checking for libcurses" +cat > conftest.${ac_ext} < conftest.${ac_ext} < conftest.${ac_ext} <&2; exit 1 +fi +rm -f conftest* + +fi +rm -f conftest* + +fi +rm -f conftest* + + +cat > conftest.${ac_ext} </dev/null; then + test -n "$silent" || echo "- you use the termcap database" + +else + test -n "$silent" || echo "- you use the terminfo database" +{ +test -n "$verbose" && \ +echo " defining TERMINFO" +echo "#define" TERMINFO "1" >> confdefs.h +DEFS="$DEFS -DTERMINFO=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}TERMINFO\${ac_dB}TERMINFO\${ac_dC}1\${ac_dD} +\${ac_uA}TERMINFO\${ac_uB}TERMINFO\${ac_uC}1\${ac_uD} +\${ac_eA}TERMINFO\${ac_eB}TERMINFO\${ac_eC}1\${ac_eD} +" +} + +fi +rm -fr conftest* +test -n "$silent" || echo "checking for ospeed" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DNEED_OSPEED=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NEED_OSPEED\${ac_dB}NEED_OSPEED\${ac_dC}1\${ac_dD} +\${ac_uA}NEED_OSPEED\${ac_uB}NEED_OSPEED\${ac_uC}1\${ac_uD} +\${ac_eA}NEED_OSPEED\${ac_eB}NEED_OSPEED\${ac_eC}1\${ac_eD} +" +} + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for /dev/ptc" +if test -r /dev/ptc; then + +{ +test -n "$verbose" && \ +echo " defining HAVE_DEV_PTC" +echo "#define" HAVE_DEV_PTC "1" >> confdefs.h +DEFS="$DEFS -DHAVE_DEV_PTC=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_DEV_PTC\${ac_dB}HAVE_DEV_PTC\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_DEV_PTC\${ac_uB}HAVE_DEV_PTC\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_DEV_PTC\${ac_eB}HAVE_DEV_PTC\${ac_eC}1\${ac_eD} +" +} + +fi + +test -n "$silent" || echo "checking for ptyranges" +if test -d /dev/ptym ; then +pdir='/dev/ptym' +else +pdir='/dev' +fi +ptys=`echo $pdir/pty??` +if test "$ptys" != "$pdir/pty??" ; then +p0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | sort -u | tr -d '\012'` +p1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | sort -u | tr -d '\012'` + +{ +test -n "$verbose" && \ +echo " defining" PTYRANGE0 to be "\"$p0\"" +echo "#define" PTYRANGE0 "\"$p0\"" >> confdefs.h +DEFS="$DEFS -DPTYRANGE0=\"$p0\"" +ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYRANGE0\${ac_dB}PTYRANGE0\${ac_dC}\"$p0\"\${ac_dD} +\${ac_uA}PTYRANGE0\${ac_uB}PTYRANGE0\${ac_uC}\"$p0\"\${ac_uD} +\${ac_eA}PTYRANGE0\${ac_eB}PTYRANGE0\${ac_eC}\"$p0\"\${ac_eD} +" +} + + +{ +test -n "$verbose" && \ +echo " defining" PTYRANGE1 to be "\"$p1\"" +echo "#define" PTYRANGE1 "\"$p1\"" >> confdefs.h +DEFS="$DEFS -DPTYRANGE1=\"$p1\"" +ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYRANGE1\${ac_dB}PTYRANGE1\${ac_dC}\"$p1\"\${ac_dD} +\${ac_uA}PTYRANGE1\${ac_uB}PTYRANGE1\${ac_uC}\"$p1\"\${ac_uD} +\${ac_eA}PTYRANGE1\${ac_eB}PTYRANGE1\${ac_eC}\"$p1\"\${ac_eD} +" +} + +fi + +test -n "$silent" || echo "checking default tty permissions/group" +rm -f conftest_grp +cat > conftest.${ac_ext} < +#include +#include +main() +{ + struct stat sb; + char *x,*ttyname(); + int om, m; + FILE *fp; + + if (!(x = ttyname(0))) exit(1); + if (stat(x, &sb)) exit(1); + om = sb.st_mode; + if (om & 002) exit(0); + m = system("mesg y"); + if (m == -1 || m == 127) exit(1); + if (stat(x, &sb)) exit(1); + m = sb.st_mode; + if (chmod(x, om)) exit(1); + if (m & 002) exit(0); + if (sb.st_gid == getgid()) exit(1); + if (!(fp=fopen("conftest_grp", "w"))) + exit(1); + fprintf(fp, "%d\n", sb.st_gid); + fclose(fp); + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + + if test -f conftest_grp; then + ptygrp=`cat conftest_grp` + test -n "$silent" || echo "- pty mode: 0620" + +{ +test -n "$verbose" && \ +echo " defining" PTYMODE to be "0620" +echo "#define" PTYMODE "0620" >> confdefs.h +DEFS="$DEFS -DPTYMODE=0620" +ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYMODE\${ac_dB}PTYMODE\${ac_dC}0620\${ac_dD} +\${ac_uA}PTYMODE\${ac_uB}PTYMODE\${ac_uC}0620\${ac_uD} +\${ac_eA}PTYMODE\${ac_eB}PTYMODE\${ac_eC}0620\${ac_eD} +" +} + + +{ +test -n "$verbose" && \ +echo " defining" PTYGROUP to be "$ptygrp" +echo "#define" PTYGROUP "$ptygrp" >> confdefs.h +DEFS="$DEFS -DPTYGROUP=$ptygrp" +ac_sed_defs="${ac_sed_defs}\${ac_dA}PTYGROUP\${ac_dB}PTYGROUP\${ac_dC}$ptygrp\${ac_dD} +\${ac_uA}PTYGROUP\${ac_uB}PTYGROUP\${ac_uC}$ptygrp\${ac_uD} +\${ac_eA}PTYGROUP\${ac_eB}PTYGROUP\${ac_eC}$ptygrp\${ac_eD} +" +} + + else + test -n "$silent" || echo "- ptys are world accessable" + fi + + +else + test -n "$silent" || echo "- can't determine - assume ptys are world accessable" + +fi +rm -fr conftest* +rm -f conftest_grp + +test -n "$silent" || echo "checking for getutent" +cat > conftest.${ac_ext} < /* to get time_t on SCO */ +#include +#if defined(SVR4) && !defined(DGUX) +#include +#define utmp utmpx +#else +#include +#endif +#ifdef __hpux +#define pututline _pututline +#endif + +int main() { return 0; } +int t() { int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining GETUTENT" +echo "#define" GETUTENT "1" >> confdefs.h +DEFS="$DEFS -DGETUTENT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}GETUTENT\${ac_dB}GETUTENT\${ac_dC}1\${ac_dD} +\${ac_uA}GETUTENT\${ac_uB}GETUTENT\${ac_uC}1\${ac_uD} +\${ac_eA}GETUTENT\${ac_eB}GETUTENT\${ac_eC}1\${ac_eD} +" +} + + +else + rm -rf conftest* + olibs="$LIBS" +LIBS="$LIBS -lgen" +test -n "$silent" || echo "checking for getutent with -lgen" +cat > conftest.${ac_ext} < +#include +#if defined(SVR4) && !defined(DGUX) +#include +#define utmp utmpx +#else +#include +#endif +#ifdef __hpux +#define pututline _pututline +#endif + +int main() { return 0; } +int t() { int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining GETUTENT" +echo "#define" GETUTENT "1" >> confdefs.h +DEFS="$DEFS -DGETUTENT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}GETUTENT\${ac_dB}GETUTENT\${ac_dC}1\${ac_dD} +\${ac_uA}GETUTENT\${ac_uB}GETUTENT\${ac_uC}1\${ac_uD} +\${ac_eA}GETUTENT\${ac_eB}GETUTENT\${ac_eC}1\${ac_eD} +" +} + + +else + rm -rf conftest* + LIBS="$olibs" +fi +rm -f conftest* + + +fi +rm -f conftest* + +test -n "$silent" || echo "checking for ut_host" +cat > conftest.${ac_ext} < +#include +#if defined(SVR4) && !defined(DGUX) +#include +#define utmp utmpx +#else +#include +#endif + +int main() { return 0; } +int t() { struct utmp u; u.ut_host[0] = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining UTHOST" +echo "#define" UTHOST "1" >> confdefs.h +DEFS="$DEFS -DUTHOST=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}UTHOST\${ac_dB}UTHOST\${ac_dC}1\${ac_dD} +\${ac_uA}UTHOST\${ac_uB}UTHOST\${ac_uC}1\${ac_uD} +\${ac_eA}UTHOST\${ac_eB}UTHOST\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + + +test -n "$silent" || echo "checking for libutil(s)" +test -f /usr/lib/libutils.a && LIBS="$LIBS -lutils" +test -f /usr/lib/libutil.a && LIBS="$LIBS -lutil" + +test -n "$silent" || echo "checking for getloadavg" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DLOADAV_GETLOADAVG=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_GETLOADAVG\${ac_dB}LOADAV_GETLOADAVG\${ac_dC}1\${ac_dD} +\${ac_uA}LOADAV_GETLOADAVG\${ac_uB}LOADAV_GETLOADAVG\${ac_uC}1\${ac_uD} +\${ac_eA}LOADAV_GETLOADAVG\${ac_eB}LOADAV_GETLOADAVG\${ac_eC}1\${ac_eD} +" +} + load=1 + +else + rm -rf conftest* + if test -f /usr/lib/libkvm.a ; then +olibs="$LIBS" +LIBS="$LIBS -lkvm" +test -n "$silent" || echo "checking for getloadavg with -lkvm" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DLOADAV_GETLOADAVG=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_GETLOADAVG\${ac_dB}LOADAV_GETLOADAVG\${ac_dC}1\${ac_dD} +\${ac_uA}LOADAV_GETLOADAVG\${ac_uB}LOADAV_GETLOADAVG\${ac_uC}1\${ac_uD} +\${ac_eA}LOADAV_GETLOADAVG\${ac_eB}LOADAV_GETLOADAVG\${ac_eC}1\${ac_eD} +" +} + load=1 + +else + rm -rf conftest* + LIBS="$olibs" +fi +rm -f conftest* + +fi + +fi +rm -f conftest* + + +if test -z "$load" ; then +cat > conftest.${ac_ext} < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + load=1 + +fi +rm -f conftest* + +fi +if test -z "$load" ; then +test -n "$silent" || echo "checking for kernelfile" +for core in /unix /vmunix /dynix /hp-ux /xelos /dev/ksyms /kernel/unix /kernel/genunix /unicos /mach /netbsd /386bsd /dgux /bsd /stand/vmunix; do + if test -f $core || test -c $core; then + break + fi +done +if test ! -f $core && test ! -c $core ; then + test -n "$silent" || echo "- no kernelfile found" +else + test -n "$silent" || echo "- using kernelfile '$core'" + +{ +test -n "$verbose" && \ +echo " defining" LOADAV_UNIX to be "\"$core\"" +echo "#define" LOADAV_UNIX "\"$core\"" >> confdefs.h +DEFS="$DEFS -DLOADAV_UNIX=\"$core\"" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_UNIX\${ac_dB}LOADAV_UNIX\${ac_dC}\"$core\"\${ac_dD} +\${ac_uA}LOADAV_UNIX\${ac_uB}LOADAV_UNIX\${ac_uC}\"$core\"\${ac_uD} +\${ac_eA}LOADAV_UNIX\${ac_eB}LOADAV_UNIX\${ac_eC}\"$core\"\${ac_eD} +" +} + + test -n "$silent" || echo "checking for nlist.h" +cat > conftest.${ac_ext} < +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining NLIST_STRUCT" +echo "#define" NLIST_STRUCT "1" >> confdefs.h +DEFS="$DEFS -DNLIST_STRUCT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NLIST_STRUCT\${ac_dB}NLIST_STRUCT\${ac_dC}1\${ac_dD} +\${ac_uA}NLIST_STRUCT\${ac_uB}NLIST_STRUCT\${ac_uC}1\${ac_uD} +\${ac_eA}NLIST_STRUCT\${ac_eB}NLIST_STRUCT\${ac_eC}1\${ac_eD} +" +} + + test -n "$silent" || echo "checking for n_un in struct nlist" +cat > conftest.${ac_ext} < +int main() { return 0; } +int t() { struct nlist n; n.n_un.n_name = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining NLIST_NAME_UNION" +echo "#define" NLIST_NAME_UNION "1" >> confdefs.h +DEFS="$DEFS -DNLIST_NAME_UNION=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NLIST_NAME_UNION\${ac_dB}NLIST_NAME_UNION\${ac_dC}1\${ac_dD} +\${ac_uA}NLIST_NAME_UNION\${ac_uB}NLIST_NAME_UNION\${ac_uC}1\${ac_uD} +\${ac_eA}NLIST_NAME_UNION\${ac_eB}NLIST_NAME_UNION\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +fi +rm -f conftest* + + + test -n "$silent" || echo "checking for nlist declaration" + cat > conftest.${ac_ext} < +#else +# include +#endif + +EOF +eval "$ac_cpp conftest.${ac_ext} > conftest.out 2>&1" +if egrep "nlist(( | )( | )*.*\(|\()" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining NLIST_DECLARED" +echo "#define" NLIST_DECLARED "1" >> confdefs.h +DEFS="$DEFS -DNLIST_DECLARED=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NLIST_DECLARED\${ac_dB}NLIST_DECLARED\${ac_dC}1\${ac_dD} +\${ac_uA}NLIST_DECLARED\${ac_uB}NLIST_DECLARED\${ac_uC}1\${ac_uD} +\${ac_eA}NLIST_DECLARED\${ac_eB}NLIST_DECLARED\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + + test -n "$silent" || echo "checking for avenrun symbol" + for av in avenrun _avenrun _Loadavg ; do + cat > conftest.${ac_ext} < +#ifdef NLIST_STRUCT +#include +#else +#include +#endif + +#ifdef __sgi +# if _MIPS_SZLONG == 64 +# define nlist nlist64 +# endif +#endif + +struct nlist nl[2]; + +main() +{ +#if !defined(_AUX_SOURCE) && !defined(AUX) +# ifdef NLIST_NAME_UNION + nl[0].n_un.n_name = "$av"; +# else + nl[0].n_name = "$av"; +# endif +#else + strncpy(nl[0].n_name, "$av", sizeof(nl[0].n_name)); +#endif + nlist(LOADAV_UNIX, nl); + if (nl[0].n_value == 0) + exit(1); + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + avensym=$av;break + +fi +rm -fr conftest* + done + if test -z "$avensym" ; then + test -n "$silent" || echo "- no avenrun symbol found" + else + test -n "$silent" || echo "- using avenrun symbol '$avensym'" + +{ +test -n "$verbose" && \ +echo " defining" LOADAV_AVENRUN to be "\"$avensym\"" +echo "#define" LOADAV_AVENRUN "\"$avensym\"" >> confdefs.h +DEFS="$DEFS -DLOADAV_AVENRUN=\"$avensym\"" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_AVENRUN\${ac_dB}LOADAV_AVENRUN\${ac_dC}\"$avensym\"\${ac_dD} +\${ac_uA}LOADAV_AVENRUN\${ac_uB}LOADAV_AVENRUN\${ac_uC}\"$avensym\"\${ac_uD} +\${ac_eA}LOADAV_AVENRUN\${ac_eB}LOADAV_AVENRUN\${ac_eC}\"$avensym\"\${ac_eD} +" +} + + load=1 + fi +fi +fi + +cat > conftest.c < +#include + +_CUT_HERE_ + +#if ((defined(hp300) && !defined(__hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news) || defined(__alpha) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) || defined(m88k)) +loadtype=long +# if defined(apollo) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) +loadscale=65536 +# else +# if defined(FSCALE) && !defined(__osf__) +# undef FSCALE +loadscale=FSCALE +# else +# ifdef sgi +loadscale=1024 +loadtype=int +# else +# if defined(MIPS) || defined(SVR4) || defined(m88k) +loadscale=256 +# else /* not MIPS */ +loadscale=1000 /* our default value */ +# endif /* MIPS */ +# endif /* sgi */ +# endif /* not FSCALE */ +# endif /* not apollo */ +#else +loadtype=double +loadscale=1 +#endif +#ifdef alliant +loadnum=4 +#else +loadnum=3 +#endif + +EOF +$CPP $DEFS conftest.c 2>/dev/null | sed -e '1,/_CUT_HERE_/d' > conftest.out +. ./conftest.out +rm -f conftest* + + +if test -n "$load" ; then +{ +test -n "$verbose" && \ +echo " defining LOADAV" +echo "#define" LOADAV "1" >> confdefs.h +DEFS="$DEFS -DLOADAV=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV\${ac_dB}LOADAV\${ac_dC}1\${ac_dD} +\${ac_uA}LOADAV\${ac_uB}LOADAV\${ac_uC}1\${ac_uD} +\${ac_eA}LOADAV\${ac_eB}LOADAV\${ac_eC}1\${ac_eD} +" +} + fi +if test -n "$loadtype" ; then +{ +test -n "$verbose" && \ +echo " defining" LOADAV_TYPE to be "$loadtype" +echo "#define" LOADAV_TYPE "$loadtype" >> confdefs.h +DEFS="$DEFS -DLOADAV_TYPE=$loadtype" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_TYPE\${ac_dB}LOADAV_TYPE\${ac_dC}$loadtype\${ac_dD} +\${ac_uA}LOADAV_TYPE\${ac_uB}LOADAV_TYPE\${ac_uC}$loadtype\${ac_uD} +\${ac_eA}LOADAV_TYPE\${ac_eB}LOADAV_TYPE\${ac_eC}$loadtype\${ac_eD} +" +} + fi +if test -n "$loadnum" ; then +{ +test -n "$verbose" && \ +echo " defining" LOADAV_NUM to be "$loadnum" +echo "#define" LOADAV_NUM "$loadnum" >> confdefs.h +DEFS="$DEFS -DLOADAV_NUM=$loadnum" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_NUM\${ac_dB}LOADAV_NUM\${ac_dC}$loadnum\${ac_dD} +\${ac_uA}LOADAV_NUM\${ac_uB}LOADAV_NUM\${ac_uC}$loadnum\${ac_uD} +\${ac_eA}LOADAV_NUM\${ac_eB}LOADAV_NUM\${ac_eC}$loadnum\${ac_eD} +" +} + fi +if test -n "$loadscale" ; then +{ +test -n "$verbose" && \ +echo " defining" LOADAV_SCALE to be "$loadscale" +echo "#define" LOADAV_SCALE "$loadscale" >> confdefs.h +DEFS="$DEFS -DLOADAV_SCALE=$loadscale" +ac_sed_defs="${ac_sed_defs}\${ac_dA}LOADAV_SCALE\${ac_dB}LOADAV_SCALE\${ac_dC}$loadscale\${ac_dD} +\${ac_uA}LOADAV_SCALE\${ac_uB}LOADAV_SCALE\${ac_uC}$loadscale\${ac_uD} +\${ac_eA}LOADAV_SCALE\${ac_eB}LOADAV_SCALE\${ac_eC}$loadscale\${ac_eD} +" +} + fi + + +if test -n "$posix" ; then + +test -n "$silent" || echo "assuming posix signal definition" + +{ +test -n "$verbose" && \ +echo " defining SIGVOID" +echo "#define" SIGVOID "1" >> confdefs.h +DEFS="$DEFS -DSIGVOID=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SIGVOID\${ac_dB}SIGVOID\${ac_dC}1\${ac_dD} +\${ac_uA}SIGVOID\${ac_uB}SIGVOID\${ac_uC}1\${ac_uD} +\${ac_eA}SIGVOID\${ac_eB}SIGVOID\${ac_eC}1\${ac_eD} +" +} + + +else + +test -n "$silent" || echo "checking for return type of signal handlers" +cat > conftest.${ac_ext} < +#include +#ifdef signal +#undef signal +#endif +extern void (*signal ()) (); +int main() { return 0; } +int t() { int i;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SIGVOID" +echo "#define" SIGVOID "1" >> confdefs.h +DEFS="$DEFS -DSIGVOID=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SIGVOID\${ac_dB}SIGVOID\${ac_dC}1\${ac_dD} +\${ac_uA}SIGVOID\${ac_uB}SIGVOID\${ac_uC}1\${ac_uD} +\${ac_eA}SIGVOID\${ac_eB}SIGVOID\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +test -n "$silent" || echo "checking for sigset" +cat > conftest.${ac_ext} < +#include + +int main() { return 0; } +int t() { +#ifdef SIGVOID +sigset(0, (void (*)())0); +#else +sigset(0, (int (*)())0); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining USESIGSET" +echo "#define" USESIGSET "1" >> confdefs.h +DEFS="$DEFS -DUSESIGSET=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}USESIGSET\${ac_dB}USESIGSET\${ac_dC}1\${ac_dD} +\${ac_uA}USESIGSET\${ac_uB}USESIGSET\${ac_uC}1\${ac_uD} +\${ac_eA}USESIGSET\${ac_eB}USESIGSET\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +test -n "$silent" || echo "checking signal implementation" +cat > conftest.${ac_ext} < +#include + +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif +#ifdef USESIGSET +#define signal sigset +#endif + +int got; + +#ifdef SIGVOID +void +#endif +hand() +{ + got++; +} + +main() +{ + /* on hpux we use sigvec to get bsd signals */ +#ifdef __hpux + (void)signal(SIGCLD, hand); + kill(getpid(), SIGCLD); + kill(getpid(), SIGCLD); + if (got < 2) + exit(1); +#endif + exit(0); +} + +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + +{ +test -n "$verbose" && \ +echo " defining SYSVSIGS" +echo "#define" SYSVSIGS "1" >> confdefs.h +DEFS="$DEFS -DSYSVSIGS=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSVSIGS\${ac_dB}SYSVSIGS\${ac_dC}1\${ac_dD} +\${ac_uA}SYSVSIGS\${ac_uB}SYSVSIGS\${ac_uC}1\${ac_uD} +\${ac_eA}SYSVSIGS\${ac_eB}SYSVSIGS\${ac_eC}1\${ac_eD} +" +} + +fi +rm -fr conftest* + +fi + + +test -n "$silent" || echo "checking for crypt and sec libraries" +test -f /lib/libcrypt_d.a || test -f /usr/lib/libcrypt_d.a && LIBS="$LIBS -lcrypt_d" +test -f /lib/libcrypt.a || test -f /usr/lib/libcrypt.a && LIBS="$LIBS -lcrypt" +test -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec" +test -f /lib/libshadow.a || test -f /usr/lib/libshadow.a && LIBS="$LIBS -lshadow" + +oldlibs="$LIBS" +LIBS="$LIBS -lsun" +test -n "$silent" || echo "checking for IRIX sun library" +cat > conftest.${ac_ext} < conftest.${ac_ext} < +#include + +int main() { return 0; } +int t() { + union wait x; + int y; +#ifdef WEXITSTATUS + y = WEXITSTATUS(x); +#endif +; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining BSDWAIT" +echo "#define" BSDWAIT "1" >> confdefs.h +DEFS="$DEFS -DBSDWAIT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}BSDWAIT\${ac_dB}BSDWAIT\${ac_dC}1\${ac_dD} +\${ac_uA}BSDWAIT\${ac_uB}BSDWAIT\${ac_uC}1\${ac_uD} +\${ac_eA}BSDWAIT\${ac_eB}BSDWAIT\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +if test -z "$butterfly"; then +test -n "$silent" || echo "checking for termio or termios" +cat > conftest.${ac_ext} < +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining TERMIO" +echo "#define" TERMIO "1" >> confdefs.h +DEFS="$DEFS -DTERMIO=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}TERMIO\${ac_dB}TERMIO\${ac_dC}1\${ac_dD} +\${ac_uA}TERMIO\${ac_uB}TERMIO\${ac_uC}1\${ac_uD} +\${ac_eA}TERMIO\${ac_eB}TERMIO\${ac_eC}1\${ac_eD} +" +} + + +else + rm -rf conftest* + if test -n "$posix"; then +cat > conftest.${ac_ext} < +EOF +# Some shells (Coherent) do redirections in the wrong order, so need +# the parens. +ac_err=`eval "($ac_cpp conftest.${ac_ext} >/dev/null) 2>&1"` +if test -z "$ac_err"; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining TERMIO" +echo "#define" TERMIO "1" >> confdefs.h +DEFS="$DEFS -DTERMIO=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}TERMIO\${ac_dB}TERMIO\${ac_dC}1\${ac_dD} +\${ac_uA}TERMIO\${ac_uB}TERMIO\${ac_uC}1\${ac_uD} +\${ac_eA}TERMIO\${ac_eB}TERMIO\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* +fi + +fi +rm -f conftest* +fi + +test -n "$silent" || echo "checking for getspnam" +cat > conftest.${ac_ext} < +int main() { return 0; } +int t() { getspnam("x");; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SHADOWPW" +echo "#define" SHADOWPW "1" >> confdefs.h +DEFS="$DEFS -DSHADOWPW=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SHADOWPW\${ac_dB}SHADOWPW\${ac_dC}1\${ac_dD} +\${ac_uA}SHADOWPW\${ac_uB}SHADOWPW\${ac_uC}1\${ac_uD} +\${ac_eA}SHADOWPW\${ac_eB}SHADOWPW\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for getttyent" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DGETTTYENT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}GETTTYENT\${ac_dB}GETTTYENT\${ac_dC}1\${ac_dD} +\${ac_uA}GETTTYENT\${ac_uB}GETTTYENT\${ac_uC}1\${ac_uD} +\${ac_eA}GETTTYENT\${ac_eB}GETTTYENT\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking whether memcpy/memmove/bcopy handles overlapping arguments" +cat > conftest.${ac_ext} </dev/null; then + +{ +test -n "$verbose" && \ +echo " defining USEBCOPY" +echo "#define" USEBCOPY "1" >> confdefs.h +DEFS="$DEFS -DUSEBCOPY=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}USEBCOPY\${ac_dB}USEBCOPY\${ac_dC}1\${ac_dD} +\${ac_uA}USEBCOPY\${ac_uB}USEBCOPY\${ac_uC}1\${ac_uD} +\${ac_eA}USEBCOPY\${ac_eB}USEBCOPY\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -fr conftest* + +cat > conftest.${ac_ext} </dev/null; then + +{ +test -n "$verbose" && \ +echo " defining USEMEMMOVE" +echo "#define" USEMEMMOVE "1" >> confdefs.h +DEFS="$DEFS -DUSEMEMMOVE=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}USEMEMMOVE\${ac_dB}USEMEMMOVE\${ac_dC}1\${ac_dD} +\${ac_uA}USEMEMMOVE\${ac_uB}USEMEMMOVE\${ac_uC}1\${ac_uD} +\${ac_eA}USEMEMMOVE\${ac_eB}USEMEMMOVE\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -fr conftest* + + +cat > conftest.${ac_ext} </dev/null; then + +{ +test -n "$verbose" && \ +echo " defining USEMEMCPY" +echo "#define" USEMEMCPY "1" >> confdefs.h +DEFS="$DEFS -DUSEMEMCPY=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}USEMEMCPY\${ac_dB}USEMEMCPY\${ac_dC}1\${ac_dD} +\${ac_uA}USEMEMCPY\${ac_uB}USEMEMCPY\${ac_uC}1\${ac_uD} +\${ac_eA}USEMEMCPY\${ac_eB}USEMEMCPY\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -fr conftest* + +test -n "$silent" || echo "checking for long file names" +(echo 1 > /tmp/conftest9012345) 2>/dev/null +(echo 2 > /tmp/conftest9012346) 2>/dev/null +val=`cat /tmp/conftest9012345 2>/dev/null` +if test -f /tmp/conftest9012345 && test "$val" = 1; then : +else +{ +test -n "$verbose" && \ +echo " defining" NAME_MAX to be "14" +echo "#define" NAME_MAX "14" >> confdefs.h +DEFS="$DEFS -DNAME_MAX=14" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NAME_MAX\${ac_dB}NAME_MAX\${ac_dC}14\${ac_dD} +\${ac_uA}NAME_MAX\${ac_uB}NAME_MAX\${ac_uC}14\${ac_uD} +\${ac_eA}NAME_MAX\${ac_eB}NAME_MAX\${ac_eC}14\${ac_eD} +" +} + +fi +rm -f /tmp/conftest* + +test -n "$silent" || echo "checking for vsprintf" +cat > conftest.${ac_ext} < +#include +int main() { return 0; } +int t() { vsprintf();; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining USEVARARGS" +echo "#define" USEVARARGS "1" >> confdefs.h +DEFS="$DEFS -DUSEVARARGS=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}USEVARARGS\${ac_dB}USEVARARGS\${ac_dC}1\${ac_dD} +\${ac_uA}USEVARARGS\${ac_uB}USEVARARGS\${ac_uC}1\${ac_uD} +\${ac_eA}USEVARARGS\${ac_eB}USEVARARGS\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for directory library header" +ac_dir_header= +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for dirent.h" +cat > conftest.${ac_ext} < +#include +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining DIRENT" +echo "#define" DIRENT "1" >> confdefs.h +DEFS="$DEFS -DDIRENT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}DIRENT\${ac_dB}DIRENT\${ac_dC}1\${ac_dD} +\${ac_uA}DIRENT\${ac_uB}DIRENT\${ac_uC}1\${ac_uD} +\${ac_eA}DIRENT\${ac_eB}DIRENT\${ac_eC}1\${ac_eD} +" +} + ac_dir_header=dirent.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for sys/ndir.h" +cat > conftest.${ac_ext} < +#include +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SYSNDIR" +echo "#define" SYSNDIR "1" >> confdefs.h +DEFS="$DEFS -DSYSNDIR=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSNDIR\${ac_dB}SYSNDIR\${ac_dC}1\${ac_dD} +\${ac_uA}SYSNDIR\${ac_uB}SYSNDIR\${ac_uC}1\${ac_uD} +\${ac_eA}SYSNDIR\${ac_eB}SYSNDIR\${ac_eC}1\${ac_eD} +" +} + ac_dir_header=sys/ndir.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for sys/dir.h" +cat > conftest.${ac_ext} < +#include +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining SYSDIR" +echo "#define" SYSDIR "1" >> confdefs.h +DEFS="$DEFS -DSYSDIR=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}SYSDIR\${ac_dB}SYSDIR\${ac_dC}1\${ac_dD} +\${ac_uA}SYSDIR\${ac_uB}SYSDIR\${ac_uC}1\${ac_uD} +\${ac_eA}SYSDIR\${ac_eB}SYSDIR\${ac_eC}1\${ac_eD} +" +} + ac_dir_header=sys/dir.h + +fi +rm -f conftest* +fi +if test -z "$ac_dir_header"; then + test -n "$silent" || echo "checking for ndir.h" +cat > conftest.${ac_ext} < +#include +int main() { return 0; } +int t() { DIR *dirp = 0;; return 0; } +EOF +if eval $ac_compile; then + rm -rf conftest* + +{ +test -n "$verbose" && \ +echo " defining NDIR" +echo "#define" NDIR "1" >> confdefs.h +DEFS="$DEFS -DNDIR=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NDIR\${ac_dB}NDIR\${ac_dC}1\${ac_dD} +\${ac_uA}NDIR\${ac_uB}NDIR\${ac_uC}1\${ac_uD} +\${ac_eA}NDIR\${ac_eB}NDIR\${ac_eC}1\${ac_eD} +" +} + ac_dir_header=ndir.h + +fi +rm -f conftest* +fi + +test -n "$silent" || echo "checking for closedir return value" +cat > conftest.${ac_ext} < +#include <$ac_dir_header> +int closedir(); main() { exit(closedir(opendir(".")) != 0); } +EOF +eval $ac_compile +if test -s conftest && (./conftest; exit) 2>/dev/null; then + : +else + +{ +test -n "$verbose" && \ +echo " defining VOID_CLOSEDIR" +echo "#define" VOID_CLOSEDIR "1" >> confdefs.h +DEFS="$DEFS -DVOID_CLOSEDIR=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}VOID_CLOSEDIR\${ac_dB}VOID_CLOSEDIR\${ac_dC}1\${ac_dD} +\${ac_uA}VOID_CLOSEDIR\${ac_uB}VOID_CLOSEDIR\${ac_uC}1\${ac_uD} +\${ac_eA}VOID_CLOSEDIR\${ac_eB}VOID_CLOSEDIR\${ac_eC}1\${ac_eD} +" +} + +fi +rm -fr conftest* + +test -n "$silent" || echo "checking for Xenix" +cat > conftest.${ac_ext} < conftest.out 2>&1" +if egrep "yes" conftest.out >/dev/null 2>&1; then + rm -rf conftest* + XENIX=1 + +fi +rm -f conftest* + +if test -n "$XENIX"; then + LIBS="$LIBS -lx" + case "$DEFS" in + *SYSNDIR*) ;; + *) LIBS="-ldir $LIBS" ;; # Make sure -ldir precedes any -lx. + esac +fi + + +test -n "$silent" || echo "checking for setenv" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DUSESETENV=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}USESETENV\${ac_dB}USESETENV\${ac_dC}1\${ac_dD} +\${ac_uA}USESETENV\${ac_uB}USESETENV\${ac_uC}1\${ac_uD} +\${ac_eA}USESETENV\${ac_eB}USESETENV\${ac_eC}1\${ac_eD} +" +} + + +else + rm -rf conftest* + test -n "$silent" || echo "checking for putenv" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DNEEDPUTENV=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NEEDPUTENV\${ac_dB}NEEDPUTENV\${ac_dC}1\${ac_dD} +\${ac_uA}NEEDPUTENV\${ac_uB}NEEDPUTENV\${ac_uC}1\${ac_uD} +\${ac_eA}NEEDPUTENV\${ac_eB}NEEDPUTENV\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +fi +rm -f conftest* + + +test -n "$silent" || echo "checking for rename" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DNEED_RENAME=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}NEED_RENAME\${ac_dB}NEED_RENAME\${ac_dC}1\${ac_dD} +\${ac_uA}NEED_RENAME\${ac_uB}NEED_RENAME\${ac_uC}1\${ac_uD} +\${ac_eA}NEED_RENAME\${ac_eB}NEED_RENAME\${ac_eC}1\${ac_eD} +" +} + +fi +rm -f conftest* + +test -n "$silent" || echo "checking for _exit" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DHAVE__EXIT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE__EXIT\${ac_dB}HAVE__EXIT\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE__EXIT\${ac_uB}HAVE__EXIT\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE__EXIT\${ac_eB}HAVE__EXIT\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +test -n "$silent" || echo "checking for lstat" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DHAVE_LSTAT=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_LSTAT\${ac_dB}HAVE_LSTAT\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_LSTAT\${ac_uB}HAVE_LSTAT\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_LSTAT\${ac_eB}HAVE_LSTAT\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + +test -n "$silent" || echo "checking for strerror" +cat > conftest.${ac_ext} <> confdefs.h +DEFS="$DEFS -DHAVE_STRERROR=1" +ac_sed_defs="${ac_sed_defs}\${ac_dA}HAVE_STRERROR\${ac_dB}HAVE_STRERROR\${ac_dC}1\${ac_dD} +\${ac_uA}HAVE_STRERROR\${ac_uB}HAVE_STRERROR\${ac_uC}1\${ac_uD} +\${ac_eA}HAVE_STRERROR\${ac_eB}HAVE_STRERROR\${ac_eC}1\${ac_eD} +" +} + + +fi +rm -f conftest* + + +test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lsec -lseq" + +cat > conftest.${ac_ext} </dev/null; then + : +else + echo "configure: Can't run the compiler - internal error. Sorry." >&2; exit 1 +fi +rm -fr conftest* +if test -n "$prefix"; then + +{ +test -n "$verbose" && \ +echo " defining" ETCSCREENRC to be "\"$prefix/etc/screenrc\"" +echo "#define" ETCSCREENRC "\"$prefix/etc/screenrc\"" >> confdefs.h +DEFS="$DEFS -DETCSCREENRC=\"$prefix/etc/screenrc\"" +ac_sed_defs="${ac_sed_defs}\${ac_dA}ETCSCREENRC\${ac_dB}ETCSCREENRC\${ac_dC}\"$prefix/etc/screenrc\"\${ac_dD} +\${ac_uA}ETCSCREENRC\${ac_uB}ETCSCREENRC\${ac_uC}\"$prefix/etc/screenrc\"\${ac_uD} +\${ac_eA}ETCSCREENRC\${ac_eB}ETCSCREENRC\${ac_eC}\"$prefix/etc/screenrc\"\${ac_eD} +" +} + +fi + + +# The preferred way to propogate these variables is regular @ substitutions. +if test -n "$prefix"; then + ac_prsub="s%^prefix\\([ ]*\\)=\\([ ]*\\).*$%prefix\\1=\\2$prefix%" +else + prefix=/usr/local +fi +if test -n "$exec_prefix"; then + ac_prsub="$ac_prsub +s%^exec_prefix\\([ ]*\\)=\\([ ]*\\).*$%exec_prefix\\1=\\2$exec_prefix%" +else + exec_prefix='${prefix}' # Let make expand it. +fi + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +# Quote sed substitution magic chars in DEFS. +cat >conftest.def < config.status </dev/null | sed 1q`: +# +# $0 $configure_args + +ac_cs_usage="Usage: config.status [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo running \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create + exec \${CONFIG_SHELL-/bin/sh} $0 $configure_args --no-create ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "config.status generated by autoconf version 1.11" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +trap 'rm -fr Makefile doc/Makefile config.h conftest*; exit 1' 1 2 15 +VERSION='$VERSION' +CC='$CC' +CPP='$CPP' +AWK='$AWK' +INSTALL='$INSTALL' +INSTALL_PROGRAM='$INSTALL_PROGRAM' +INSTALL_DATA='$INSTALL_DATA' +LIBS='$LIBS' +srcdir='$srcdir' +top_srcdir='$top_srcdir' +prefix='$prefix' +exec_prefix='$exec_prefix' +ac_prsub='$ac_prsub' +ac_vpsub='$ac_vpsub' +extrasub='$extrasub' +EOF +cat >> config.status <<\EOF + +ac_given_srcdir=$srcdir + +CONFIG_FILES=${CONFIG_FILES-"Makefile doc/Makefile"} +for ac_file in .. ${CONFIG_FILES}; do if test "x$ac_file" != x..; then + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/$ac_dir" + else + ac_dir_suffix= + fi + + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dir_suffix"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + comment_str="Generated automatically from `echo $ac_file|sed 's|.*/||'`.in by configure." + case "$ac_file" in + *.c | *.h | *.C | *.cc | *.m ) echo "/* $comment_str */" > "$ac_file" ;; + * ) echo "# $comment_str" > "$ac_file" ;; + esac + sed -e " +$ac_prsub +$ac_vpsub +$extrasub +s%@VERSION@%$VERSION%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@AWK@%$AWK%g +s%@INSTALL@%$INSTALL%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@LIBS@%$LIBS%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@prefix@%$prefix%g +s%@exec_prefix@%$exec_prefix%g +s%@DEFS@%-DHAVE_CONFIG_H%" $ac_given_srcdir/${ac_file}.in >> $ac_file +fi; done + +# These sed commands are put into ac_sed_defs when defining a macro. +# They are broken into pieces to make the sed script easier to manage. +# They are passed to sed as "A NAME B NAME C VALUE D", where NAME +# is the cpp macro being defined and VALUE is the value it is being given. +# Each defining turns into a single global substitution command. +# Hopefully no one uses "!" as a variable value. +# Other candidates for the sed separators, like , and @, do get used. +# +# ac_d sets the value in "#define NAME VALUE" lines. +ac_dA='s!^\([ ]*\)#\([ ]*define[ ][ ]*\)' +ac_dB='\([ ][ ]*\)[^ ]*!\1#\2' +ac_dC='\3' +ac_dD='!g' +# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE". +ac_uA='s!^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_uB='\([ ]\)!\1#\2define\3' +ac_uC=' ' +ac_uD='\4!g' +# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE". +ac_eA='s!^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)' +ac_eB='$!\1#\2define\3' +ac_eC=' ' +ac_eD='!g' +rm -f conftest.sed +EOF +# Turn off quoting long enough to insert the sed commands. +rm -f conftest.sh +cat > conftest.sh < conftest.s1 # Like head -9. + sed 1,${ac_max_sh_lines}d conftest.sh > conftest.s2 # Like tail +10. + # Write a limited-size here document to append to conftest.sed. + echo 'cat >> conftest.sed <> config.status + cat conftest.s1 >> config.status + echo 'CONFEOF' >> config.status + rm -f conftest.s1 conftest.sh + mv conftest.s2 conftest.sh +done +rm -f conftest.sh + +# Now back to your regularly scheduled config.status. +cat >> config.status <<\EOF +# This sed command replaces #undef's with comments. This is necessary, for +# example, in the case of _POSIX_SOURCE, which is predefined and required +# on some systems where configure will not decide to define it in +# config.h. +cat >> conftest.sed <<\CONFEOF +s,^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */, +CONFEOF +rm -f conftest.h +# Break up the sed commands because old seds have small limits. +ac_max_sed_lines=20 + +CONFIG_HEADERS=${CONFIG_HEADERS-"config.h"} +for ac_file in .. ${CONFIG_HEADERS}; do if test "x$ac_file" != x..; then + echo creating $ac_file + + cp $ac_given_srcdir/$ac_file.in conftest.h1 + cp conftest.sed conftest.stm + while : + do + ac_lines=`grep -c . conftest.stm` + if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi + rm -f conftest.s1 conftest.s2 conftest.h2 + sed ${ac_max_sed_lines}q conftest.stm > conftest.s1 # Like head -20. + sed 1,${ac_max_sed_lines}d conftest.stm > conftest.s2 # Like tail +21. + sed -f conftest.s1 < conftest.h1 > conftest.h2 + rm -f conftest.s1 conftest.h1 conftest.stm + mv conftest.h2 conftest.h1 + mv conftest.s2 conftest.stm + done + rm -f conftest.stm conftest.h + echo "/* $ac_file. Generated automatically by configure. */" > conftest.h + cat conftest.h1 >> conftest.h + rm -f conftest.h1 + if cmp -s $ac_file conftest.h 2>/dev/null; then + # The file exists and we would not be changing it. + echo "$ac_file is unchanged" + rm -f conftest.h + else + rm -f $ac_file + mv conftest.h $ac_file + fi +fi; done +rm -f conftest.sed + + + +exit 0 +EOF +chmod +x config.status +# Some shells look in PATH for config.status without the "./". +test -n "$no_create" || ${CONFIG_SHELL-/bin/sh} ./config.status + + +# a hook for preserving undef directive in config.h +if test -z "$no_create" ; then +mv config.h conftest +sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h +rm -f conftest +fi +cat >> config.status << EOF +mv config.h conftest +sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h +rm -f conftest +EOF + +echo "" +if test -z "$AWK"; then +echo "!!! Since you have no awk you must copy the files 'comm.h.dist'" +echo "!!! and 'term.h.dist' to 'comm.h' and 'term.h'." +echo "!!! Do _not_ change the user configuration section in config.h!" +echo "Please check the pathnames in the Makefile." +else +echo "Now please check the pathnames in the Makefile and the user" +echo "configuration section in config.h." +fi +echo "Then type 'make' to make screen. Good luck." +echo "" diff --git a/configure.in b/configure.in new file mode 100644 index 0000000..a655f0a --- /dev/null +++ b/configure.in @@ -0,0 +1,1033 @@ +dnl Process this file with autoconf to produce a configure script. +dnl +dnl $Id: configure.in,v 1.17 1994/05/31 12:31:46 mlschroe Exp $ FAU +dnl +dnl Many thanks to David MacKenzie for writing autoconf and +dnl providing a sample configure.in file for screen. +dnl +AC_REVISION($Revision: 1.17 $)dnl +AC_INIT(screen.c) +AC_CONFIG_HEADER(config.h) + +dnl +dnl Define some useful macros +dnl +define(AC_PROGRAM_SOURCE, +[AC_REQUIRE([AC_PROG_CPP])AC_PROVIDE([$0])cat > conftest.c </dev/null | sed -e '1,/_CUT_HERE_/d' > conftest.out +. ./conftest.out +rm -f conftest* +])dnl +dnl +define(AC_NOTE, +[test -n "$silent" || echo "$1"])dnl + +dnl +dnl Extract version from patchlevel.h +dnl +rev=`sed < ${srcdir}/patchlevel.h -n -e '/#define REV/s/#define REV *//p'` +vers=`sed < ${srcdir}/patchlevel.h -n -e '/#define VERS/s/#define VERS *//p'` +pat=`sed < ${srcdir}/patchlevel.h -n -e '/#define PATCHLEVEL/s/#define PATCHLEVEL *//p'` +VERSION="$rev.$vers.$pat" +AC_NOTE(this is screen version $VERSION) +AC_SUBST(VERSION) +AC_PREFIX(gzip) + +AC_PROG_CC +AC_PROG_CPP +AC_GCC_TRADITIONAL +AC_ISC_POSIX + +AC_TEST_PROGRAM(main(){exit(0);},,AC_ERROR(Can't run the compiler - sorry)) + +AC_TEST_PROGRAM([ +main() +{ + int __something_strange_(); + __something_strange_(0); +} +],AC_ERROR(Your compiler does not set the exit status - sorry)) + +AC_PROG_AWK + +AC_PROG_INSTALL + +if test -f etc/toolcheck; then +AC_CHECKING(for buggy tools) +sh etc/toolcheck +fi + +dnl +dnl **** special unix variants **** +dnl +if test -n "$ISC"; then + AC_DEFINE(ISC) LIBS="$LIBS -linet" +fi + +dnl AC_CHECKING(for OSF1) +dnl if test -f /bin/uname ; then +dnl if test `/bin/uname` = OSF1 || test -f /osf_boot; then +dnl AC_DEFINE(OSF1) # this disables MIPS again.... +dnl fi +dnl fi + +if test -f /sysV68 ; then +AC_DEFINE(sysV68) +fi + +AC_CHECKING(for MIPS) +if test -f /lib/libmld.a || test -f /usr/lib/libmld.a || test -f /usr/lib/cmplrs/cc/libmld.a; then +test -f /bin/mx || LIBS="$LIBS -lmld" # for nlist. But not on alpha. +dnl djm@eng.umd.edu: "... for one thing, it doubles the size of the executable" +dnl +if test -r /dev/ptc; then +AC_DEFINE(MIPS) +AC_COMPILE_CHECK(wait3, , [wait3();], , +AC_COMPILE_CHECK(wait2, , [wait2();], +dnl John Rouillard (rouilj@sni-usa.com): +dnl need -I/usr/include/bsd in RISCOS otherwise sockets are broken, no +dnl job control etc. +dnl Detect RISCOS if wait2 is present, but not wait3. +AC_DEFINE(USE_WAIT2) LIBS="$LIBS -lbsd" ; CC="$CC -I/usr/include/bsd" +)) +fi +fi + +AC_CHECKING(for Ultrix) +AC_PROGRAM_EGREP(yes, +[#if defined(ultrix) || defined(__ultrix) + yes +#endif +], ULTRIX=1) + +if test -f /usr/lib/libpyr.a ; then +oldlibs="$LIBS" +LIBS="$LIBS -lpyr" +AC_COMPILE_CHECK(Pyramid OSX,,[open_controlling_pty("");],AC_DEFINE(OSX),LIBS="oldlibs") +fi + +dnl ghazi@caip.rutgers.edu (Kaveh R. Ghazi): +dnl BBN butterfly is not POSIX, but a MACH BSD system. +dnl Do not define POSIX and TERMIO. +AC_CHECKING(for butterfly) +AC_PROGRAM_EGREP(yes, +[#if defined(butterfly) + yes +#endif +], butterfly=1) + +if test -z "$butterfly"; then +if test -n "$ULTRIX"; then + test -z "$GCC" && CC="$CC -YBSD" +fi +AC_CHECKING(for POSIX.1) +AC_PROGRAM_EGREP(yes, +[#include +#include +main () { +#ifdef _POSIX_VERSION + yes +#endif +], AC_NOTE(- you have a POSIX system) AC_DEFINE(POSIX) posix=1) +fi + +AC_COMPILE_CHECK([System V], +[#include +#include +#include ], [int x = SIGCHLD | FNDELAY;], , AC_DEFINE(SYSV)) + +AC_CHECKING(for sequent/ptx) +AC_PROGRAM_EGREP(yes, +[#ifdef _SEQUENT_ + yes +#endif +], LIBS="$LIBS -lsocket -linet";seqptx=1) + +oldlibs="$LIBS" +LIBS="$LIBS -lelf" +AC_COMPILE_CHECK(SVR4,[#include +],, +AC_HEADER_CHECK(dwarf.h, AC_DEFINE(SVR4) AC_DEFINE(BUGGYGETLOGIN), +AC_HEADER_CHECK(elf.h, AC_DEFINE(SVR4) AC_DEFINE(BUGGYGETLOGIN))) +,LIBS="$oldlibs") + + +dnl +dnl **** typedefs **** +dnl +dnl AC_CHECKING(for pid_t) +dnl AC_PROGRAM_EGREP(pid_t,[#include +dnl ],AC_DEFINE(PID_T_DEFINED)) +dnl +dnl AC_CHECKING(for sig_t) +dnl AC_PROGRAM_EGREP(sig_t,[#include +dnl #include +dnl ],AC_DEFINE(SIG_T_DEFINED)) +dnl +dnl AC_CHECKING(for uid_t) +dnl AC_PROGRAM_EGREP(uid_t,[#include +dnl ],AC_DEFINE(UID_T_DEFINED)) + +dnl +dnl **** Job control **** +dnl + +AC_COMPILE_CHECK([BSD job control], +[#include +#include +], [ +#ifdef POSIX +tcsetpgrp(0, 0); +#else +int x = TIOCSPGRP; +#ifdef SYSV +setpgrp(); +#else +int y = TIOCNOTTY; +#endif +#endif +], AC_NOTE(- you have jobcontrol) AC_DEFINE(BSDJOBS), AC_NOTE(- you don't have jobcontrol)) + +dnl +dnl **** setreuid(), seteuid() **** +dnl +AC_COMPILE_CHECK(setreuid, , [ +#ifdef __hpux +setresuid(0, 0, 0); +#else +setreuid(0, 0); +#endif +], AC_DEFINE(HAVE_SETREUID)) +dnl +dnl seteuid() check: +dnl linux seteuid was broken before V1.1.11 +dnl NeXT, AUX, ISC, and ultrix are still broken (no saved uid support) +dnl Solaris seteuid doesn't change the saved uid, bad for +dnl multiuser screen sessions +AC_COMPILE_CHECK(seteuid, , [ +#if defined(linux) || defined(NeXT) || defined(_AUX_SOURCE) || defined(AUX) || defined(ultrix) || (defined(sun) && defined(SVR4)) || defined(ISC) || defined(sony_news) +seteuid_is_broken(0); +#else +seteuid(0); +#endif +], AC_DEFINE(HAVE_SETEUID)) +dnl +dnl **** select() **** +dnl + +AC_COMPILE_CHECK(select,,[select(0, 0, 0, 0, 0);],, +LIBS="$LIBS -lnet -lnsl" +AC_COMPILE_CHECK(select with $LIBS,,[select(0, 0, 0, 0, 0);],, +AC_ERROR(!!! no select - no screen)) +) +dnl +dnl **** FIFO tests **** +dnl + +AC_CHECKING(fifos) +AC_TEST_PROGRAM([ +#include +#include +#include + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif + +char *fin = "/tmp/conftest$$"; + +main() +{ + struct stat stb; + int f; + + (void)alarm(5); +#ifdef POSIX + if (mkfifo(fin, 0777)) +#else + if (mknod(fin, S_IFIFO|0777, 0)) +#endif + exit(1); + if (stat(fin, &stb) || (stb.st_mode & S_IFIFO) != S_IFIFO) + exit(1); + close(0); +#ifdef __386BSD__ + /* + * The next test fails under 386BSD, but screen works using fifos. + * Fifos in O_RDWR mode are only used for the BROKEN_PIPE case and for + * the select() configuration test. + */ + exit(0); +#endif + if (open(fin, O_RDONLY | O_NONBLOCK)) + exit(1); + if (fork() == 0) + { + close(0); + if (open(fin, O_WRONLY | O_NONBLOCK)) + exit(1); + close(0); + if (open(fin, O_WRONLY | O_NONBLOCK)) + exit(1); + if (write(0, "TEST", 4) == -1) + exit(1); + exit(0); + } + f = 1; + if (select(1, &f, 0, 0, 0) == -1) + exit(1); + exit(0); +} +], AC_NOTE(- your fifos are usable);fifo=1, +AC_NOTE(- your fifos are not usable)) +rm -f /tmp/conftest* + +if test -n "$fifo"; then +AC_CHECKING(for broken fifo implementation) +AC_TEST_PROGRAM([ +#include +#include +#include +#include + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif + +char *fin = "/tmp/conftest$$"; + +main() +{ + struct timeval tv; + int r, x; + +#ifdef POSIX + if (mkfifo(fin, 0600)) +#else + if (mknod(fin, S_IFIFO|0600, 0)) +#endif + exit(1); + close(0); + if (open(fin, O_RDONLY|O_NONBLOCK)) + exit(1); + r = 1; + tv.tv_sec = 1; + tv.tv_usec = 0; + if (select(1, &r, 0, 0, &tv)) + exit(1); + exit(0); +} +], AC_NOTE(- your implementation is ok), +AC_NOTE(- you have a broken implementation) AC_DEFINE(BROKEN_PIPE) fifobr=1) +rm -f /tmp/conftest* +fi + +dnl +dnl **** SOCKET tests **** +dnl +dnl may need LIBS="$LIBS -lsocket" here +dnl + +AC_CHECKING(sockets) +AC_TEST_PROGRAM([ +#include +#include +#include +#include + +char *son = "/tmp/conftest$$"; + +main() +{ + int s1, s2, s3, l; + struct sockaddr_un a; + + (void)alarm(5); + if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + exit(1); + a.sun_family = AF_UNIX; + strcpy(a.sun_path, son); + (void) unlink(son); + if (bind(s1, (struct sockaddr *) &a, strlen(son)+2) == -1) + exit(1); + if (listen(s1, 2)) + exit(1); + if (fork() == 0) + { + if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + kill(getppid(), 3); + (void)connect(s2, (struct sockaddr *)&a, strlen(son) + 2); + if (write(s2, "HELLO", 5) == -1) + kill(getppid(), 3); + exit(0); + } + l = sizeof(a); + close(0); + if (accept(s1, &a, &l)) + exit(1); + l = 1; + if (select(1, &l, 0, 0, 0) == -1) + exit(1); + exit(0); +} +], AC_NOTE(- your sockets are usable);sock=1, +AC_NOTE(- your sockets are not usable)) +rm -f /tmp/conftest* + +if test -n "$sock"; then +AC_CHECKING(socket implementation) +AC_TEST_PROGRAM([ +#include +#include +#include +#include + +char *son = "/tmp/conftest$$"; + +main() +{ + int s; + struct stat stb; + struct sockaddr_un a; + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + exit(0); + a.sun_family = AF_UNIX; + strcpy(a.sun_path, son); + (void) unlink(son); + if (bind(s, (struct sockaddr *) &a, strlen(son)+2) == -1) + exit(0); + if (stat(son, &stb)) + exit(1); + close(s); + exit(0); +} +],AC_NOTE(- you are normal), +AC_NOTE(- unix domain sockets are not kept in the filesystem) +AC_DEFINE(SOCK_NOT_IN_FS) socknofs=1) +rm -f /tmp/conftest* +fi + + +dnl +dnl **** choose sockets or fifos **** +dnl +if test -n "$fifo"; then + if test -n "$sock"; then + if test -n "$nore"; then + AC_NOTE(- hmmm... better take the fifos) + AC_DEFINE(NAMEDPIPE) + elif test -n "$fifobr"; then + AC_NOTE(- as your fifos are broken lets use the sockets.) + else + AC_NOTE(- both sockets and fifos usable. let's take fifos.) + AC_DEFINE(NAMEDPIPE) + fi + else + AC_NOTE(- using named pipes, of course) + AC_DEFINE(NAMEDPIPE) + fi +elif test -n "$sock"; then + AC_NOTE(- using unix-domain sockets, of course) +else + AC_ERROR(you have neither usable sockets nor usable pipes -> no screen) +fi + +dnl +dnl **** check the select implementation **** +dnl + +AC_CHECKING(select return value) +AC_TEST_PROGRAM([ +#include +#include +#include + +char *nam = "/tmp/conftest$$"; + +#ifdef NAMEDPIPE + +#ifndef O_NONBLOCK +#define O_NONBLOCK O_NDELAY +#endif +#ifndef S_IFIFO +#define S_IFIFO 0010000 +#endif + + +main() +{ + int l; + +#ifdef __FreeBSD__ +/* From Andrew A. Chernov (ache@astral.msk.su): + * opening RDWR fifo fails in BSD 4.4, but select return values is + * right. + */ + exit(0); +#endif + (void)alarm(5); +#ifdef POSIX + if (mkfifo(nam, 0777)) +#else + if (mknod(nam, S_IFIFO|0777, 0)) +#endif + exit(1); + close(0); + if (open(nam, O_RDWR | O_NONBLOCK)) + exit(1); + if (write(0, "TEST", 4) == -1) + exit(1); + +#else + +#include +#include +#include + +main() +{ + int s1, s2, s3, l; + struct sockaddr_un a; + + (void)alarm(5); + if ((s1 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + exit(1); + a.sun_family = AF_UNIX; + strcpy(a.sun_path, nam); + (void) unlink(nam); + if (bind(s1, (struct sockaddr *) &a, strlen(nam)+2) == -1) + exit(1); + if (listen(s1, 2)) + exit(1); + if (fork() == 0) + { + if ((s2 = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) + kill(getppid(), 3); + (void)connect(s2, (struct sockaddr *)&a, strlen(nam) + 2); + if (write(s2, "HELLO", 5) == -1) + kill(getppid(), 3); + exit(0); + } + l = sizeof(a); + close(0); + if (accept(s1, (struct sockaddr *)&a, &l)) + exit(1); +#endif + + + l = 1; + if (select(1, &l, 0, 0, 0) == -1) + exit(1); + if (select(1, &l, &l, 0, 0) != 2) + exit(1); + exit(0); +} +],AC_NOTE(- select is ok), +AC_NOTE(- it is not usable) AC_DEFINE(SELECT_BROKEN)) + +dnl +dnl **** termcap or terminfo **** +dnl +AC_CHECKING(for tgetent) +olibs="$LIBS" +LIBS="-lcurses $olibs" +AC_COMPILE_CHECK(libcurses,,[ +#ifdef __hpux +__sorry_hpux_libcurses_is_totally_broken_in_10_10(); +#else +tgetent((char *)0, (char *)0); +#endif +],, +LIBS="-ltermcap $olibs" +AC_COMPILE_CHECK(libtermcap,,tgetent((char *)0, (char *)0);,, +LIBS="-ltermlib $olibs" +AC_COMPILE_CHECK(libtermlib,,tgetent((char *)0, (char *)0);,, +AC_ERROR(!!! no tgetent - no screen)))) + +AC_TEST_PROGRAM([ +main() +{ + exit(strcmp(tgoto("%p1%d", 0, 1), "1") ? 0 : 1); +}], AC_NOTE(- you use the termcap database), +AC_NOTE(- you use the terminfo database) AC_DEFINE(TERMINFO)) +AC_COMPILE_CHECK(ospeed,extern short ospeed;,ospeed=5;,,AC_DEFINE(NEED_OSPEED)) + +dnl +dnl **** PTY specific things **** +dnl +AC_CHECKING(for /dev/ptc) +if test -r /dev/ptc; then +AC_DEFINE(HAVE_DEV_PTC) +fi + +AC_CHECKING(for ptyranges) +if test -d /dev/ptym ; then +pdir='/dev/ptym' +else +pdir='/dev' +fi +ptys=`echo $pdir/pty??` +if test "$ptys" != "$pdir/pty??" ; then +p0=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\).$/\1/g' | sort -u | tr -d '\012'` +p1=`echo $ptys | tr ' ' '\012' | sed -e 's/^.*\(.\)$/\1/g' | sort -u | tr -d '\012'` +AC_DEFINE_UNQUOTED(PTYRANGE0,\"$p0\") +AC_DEFINE_UNQUOTED(PTYRANGE1,\"$p1\") +fi + +dnl **** pty mode/group handling **** +dnl +dnl support provided by Luke Mewburn , 931222 +AC_CHECKING(default tty permissions/group) +rm -f conftest_grp +AC_TEST_PROGRAM([ +#include +#include +#include +main() +{ + struct stat sb; + char *x,*ttyname(); + int om, m; + FILE *fp; + + if (!(x = ttyname(0))) exit(1); + if (stat(x, &sb)) exit(1); + om = sb.st_mode; + if (om & 002) exit(0); + m = system("mesg y"); + if (m == -1 || m == 127) exit(1); + if (stat(x, &sb)) exit(1); + m = sb.st_mode; + if (chmod(x, om)) exit(1); + if (m & 002) exit(0); + if (sb.st_gid == getgid()) exit(1); + if (!(fp=fopen("conftest_grp", "w"))) + exit(1); + fprintf(fp, "%d\n", sb.st_gid); + fclose(fp); + exit(0); +} +],[ + if test -f conftest_grp; then + ptygrp=`cat conftest_grp` + AC_NOTE(- pty mode: 0620, group: $ptygrp) + AC_DEFINE(PTYMODE, 0620) + AC_DEFINE_UNQUOTED(PTYGROUP,$ptygrp) + else + AC_NOTE(- ptys are world accessable) + fi +], + AC_NOTE(- can't determine - assume ptys are world accessable) +) +rm -f conftest_grp + +dnl +dnl **** utmp handling **** +dnl +dnl linux has a void pututline, grrr, gcc will error when evaluating it. +AC_COMPILE_CHECK(getutent, [#include /* to get time_t on SCO */ +#include +#if defined(SVR4) && !defined(DGUX) +#include +#define utmp utmpx +#else +#include +#endif +#ifdef __hpux +#define pututline _pututline +#endif +], +[int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), +olibs="$LIBS" +LIBS="$LIBS -lgen" +AC_COMPILE_CHECK(getutent with -lgen, [#include +#include +#if defined(SVR4) && !defined(DGUX) +#include +#define utmp utmpx +#else +#include +#endif +#ifdef __hpux +#define pututline _pututline +#endif +], +[int x = DEAD_PROCESS; struct utmp *y = pututline((struct utmp *)0); getutent();], AC_DEFINE(GETUTENT), LIBS="$olibs") +) +AC_COMPILE_CHECK(ut_host, [#include +#include +#if defined(SVR4) && !defined(DGUX) +#include +#define utmp utmpx +#else +#include +#endif +],[struct utmp u; u.ut_host[0] = 0;], AC_DEFINE(UTHOST)) + + +dnl +dnl **** loadav **** +dnl +AC_CHECKING(for libutil(s)) +test -f /usr/lib/libutils.a && LIBS="$LIBS -lutils" +test -f /usr/lib/libutil.a && LIBS="$LIBS -lutil" + +AC_COMPILE_CHECK(getloadavg, , [getloadavg((double *)0, 0);], +AC_DEFINE(LOADAV_GETLOADAVG) load=1, +if test -f /usr/lib/libkvm.a ; then +olibs="$LIBS" +LIBS="$LIBS -lkvm" +AC_COMPILE_CHECK(getloadavg with -lkvm, , [getloadavg((double *)0, 0);], +AC_DEFINE(LOADAV_GETLOADAVG) load=1, LIBS="$olibs") +fi +) + +if test -z "$load" ; then +AC_PROGRAM_EGREP(yes, +[#if defined(NeXT) || defined(apollo) || defined(linux) + yes +#endif +], load=1) +fi +if test -z "$load" ; then +AC_CHECKING(for kernelfile) +for core in /unix /vmunix /dynix /hp-ux /xelos /dev/ksyms /kernel/unix /kernel/genunix /unicos /mach /netbsd /386bsd /dgux /bsd /stand/vmunix; do + if test -f $core || test -c $core; then + break + fi +done +if test ! -f $core && test ! -c $core ; then + AC_NOTE(- no kernelfile found) +else + AC_NOTE(- using kernelfile '$core') + AC_DEFINE_UNQUOTED(LOADAV_UNIX,\"$core\") + AC_HEADER_CHECK(nlist.h, + [AC_DEFINE(NLIST_STRUCT) + AC_COMPILE_CHECK(n_un in struct nlist, [#include ], + [struct nlist n; n.n_un.n_name = 0;], + AC_DEFINE(NLIST_NAME_UNION))]) + + AC_CHECKING(for nlist declaration) + AC_PROGRAM_EGREP([nlist(( | )( | )*.*\(|\()],[ +#ifdef NLIST_STRUCT +# include +#else +# include +#endif +],AC_DEFINE(NLIST_DECLARED)) + + AC_CHECKING(for avenrun symbol) + for av in avenrun _avenrun _Loadavg ; do + AC_TEST_PROGRAM([ +#include +#ifdef NLIST_STRUCT +#include +#else +#include +#endif + +#ifdef __sgi +# if _MIPS_SZLONG == 64 +# define nlist nlist64 +# endif +#endif + +struct nlist nl[2]; + +main() +{ +#if !defined(_AUX_SOURCE) && !defined(AUX) +# ifdef NLIST_NAME_UNION + nl[0].n_un.n_name = "$av"; +# else + nl[0].n_name = "$av"; +# endif +#else + strncpy(nl[0].n_name, "$av", sizeof(nl[0].n_name)); +#endif + nlist(LOADAV_UNIX, nl); + if (nl[0].n_value == 0) + exit(1); + exit(0); +} + ],avensym=$av;break) + done + if test -z "$avensym" ; then + AC_NOTE(- no avenrun symbol found) + else + AC_NOTE(- using avenrun symbol '$avensym') + AC_DEFINE_UNQUOTED(LOADAV_AVENRUN,\"$avensym\") + load=1 + fi +fi +fi + +AC_PROGRAM_SOURCE([ +#include +#include +],[ +#if ((defined(hp300) && !defined(__hpux)) || defined(sun) || (defined(ultrix) && defined(mips)) || defined(_SEQUENT_) || defined(sgi) || defined(SVR4) || defined(sony_news) || defined(__alpha) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) || defined(m88k)) +loadtype=long +# if defined(apollo) || defined(_IBMR2) || defined(_AUX_SOURCE) || defined(AUX) +loadscale=65536 +# else +# if defined(FSCALE) && !defined(__osf__) +# undef FSCALE +loadscale=FSCALE +# else +# ifdef sgi +loadscale=1024 +loadtype=int +# else +# if defined(MIPS) || defined(SVR4) || defined(m88k) +loadscale=256 +# else /* not MIPS */ +loadscale=1000 /* our default value */ +# endif /* MIPS */ +# endif /* sgi */ +# endif /* not FSCALE */ +# endif /* not apollo */ +#else +loadtype=double +loadscale=1 +#endif +#ifdef alliant +loadnum=4 +#else +loadnum=3 +#endif +]) + +if test -n "$load" ; then AC_DEFINE(LOADAV) fi +if test -n "$loadtype" ; then AC_DEFINE_UNQUOTED(LOADAV_TYPE,$loadtype) fi +if test -n "$loadnum" ; then AC_DEFINE_UNQUOTED(LOADAV_NUM,$loadnum) fi +if test -n "$loadscale" ; then AC_DEFINE_UNQUOTED(LOADAV_SCALE,$loadscale) fi + + +dnl +dnl **** signal handling **** +dnl +if test -n "$posix" ; then + +dnl POSIX has reliable signals with void return type. +AC_NOTE(assuming posix signal definition) +AC_DEFINE(SIGVOID) + +else + +AC_COMPILE_CHECK([return type of signal handlers], +[#include +#include +#ifdef signal +#undef signal +#endif +extern void (*signal ()) ();], [int i;], AC_DEFINE(SIGVOID)) +AC_COMPILE_CHECK(sigset, [ +#include +#include +], [ +#ifdef SIGVOID +sigset(0, (void (*)())0); +#else +sigset(0, (int (*)())0); +#endif +], AC_DEFINE(USESIGSET)) +AC_CHECKING(signal implementation) +AC_TEST_PROGRAM([ +#include +#include + +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif +#ifdef USESIGSET +#define signal sigset +#endif + +int got; + +#ifdef SIGVOID +void +#endif +hand() +{ + got++; +} + +main() +{ + /* on hpux we use sigvec to get bsd signals */ +#ifdef __hpux + (void)signal(SIGCLD, hand); + kill(getpid(), SIGCLD); + kill(getpid(), SIGCLD); + if (got < 2) + exit(1); +#endif + exit(0); +} +],,AC_DEFINE(SYSVSIGS)) + +fi + +dnl +dnl **** libraries **** +dnl + +AC_CHECKING(for crypt and sec libraries) +test -f /lib/libcrypt_d.a || test -f /usr/lib/libcrypt_d.a && LIBS="$LIBS -lcrypt_d" +test -f /lib/libcrypt.a || test -f /usr/lib/libcrypt.a && LIBS="$LIBS -lcrypt" +test -f /lib/libsec.a || test -f /usr/lib/libsec.a && LIBS="$LIBS -lsec" +test -f /lib/libshadow.a || test -f /usr/lib/libshadow.a && LIBS="$LIBS -lshadow" + +oldlibs="$LIBS" +LIBS="$LIBS -lsun" +AC_COMPILE_CHECK(IRIX sun library,,,,LIBS="$oldlibs") + + +dnl +dnl **** misc things **** +dnl +AC_COMPILE_CHECK(wait union,[#include +#include +],[ + union wait x; + int y; +#ifdef WEXITSTATUS + y = WEXITSTATUS(x); +#endif +],AC_DEFINE(BSDWAIT)) + +if test -z "$butterfly"; then +AC_CHECKING(for termio or termios) +AC_TEST_CPP([#include ], AC_DEFINE(TERMIO), +if test -n "$posix"; then +AC_TEST_CPP([#include ], AC_DEFINE(TERMIO)) +fi +) +fi + +dnl AC_HEADER_CHECK(shadow.h, AC_DEFINE(SHADOWPW)) +AC_COMPILE_CHECK(getspnam, [#include ], [getspnam("x");], + AC_DEFINE(SHADOWPW)) + +AC_COMPILE_CHECK(getttyent, , [getttyent();], AC_DEFINE(GETTTYENT)) + +AC_CHECKING(whether memcpy/memmove/bcopy handles overlapping arguments) +AC_TEST_PROGRAM([ +main() { + char buf[10]; + strcpy(buf, "abcdefghi"); + bcopy(buf, buf + 2, 3); + if (strncmp(buf, "ababcf", 6)) + exit(1); + strcpy(buf, "abcdefghi"); + bcopy(buf + 2, buf, 3); + if (strncmp(buf, "cdedef", 6)) + exit(1); + exit(0); /* libc version works properly. */ +}], AC_DEFINE(USEBCOPY)) + +AC_TEST_PROGRAM([ +#define bcopy(s,d,l) memmove(d,s,l) +main() { + char buf[10]; + strcpy(buf, "abcdefghi"); + bcopy(buf, buf + 2, 3); + if (strncmp(buf, "ababcf", 6)) + exit(1); + strcpy(buf, "abcdefghi"); + bcopy(buf + 2, buf, 3); + if (strncmp(buf, "cdedef", 6)) + exit(1); + exit(0); /* libc version works properly. */ +}], AC_DEFINE(USEMEMMOVE)) + + +AC_TEST_PROGRAM([ +#define bcopy(s,d,l) memcpy(d,s,l) +main() { + char buf[10]; + strcpy(buf, "abcdefghi"); + bcopy(buf, buf + 2, 3); + if (strncmp(buf, "ababcf", 6)) + exit(1); + strcpy(buf, "abcdefghi"); + bcopy(buf + 2, buf, 3); + if (strncmp(buf, "cdedef", 6)) + exit(1); + exit(0); /* libc version works properly. */ +}], AC_DEFINE(USEMEMCPY)) + +AC_CHECKING(for long file names) +(echo 1 > /tmp/conftest9012345) 2>/dev/null +(echo 2 > /tmp/conftest9012346) 2>/dev/null +val=`cat /tmp/conftest9012345 2>/dev/null` +if test -f /tmp/conftest9012345 && test "$val" = 1; then : +else AC_DEFINE(NAME_MAX, 14) +fi +rm -f /tmp/conftest* + +AC_COMPILE_CHECK(vsprintf, [#include +#include ], [vsprintf();], AC_DEFINE(USEVARARGS)) + +AC_DIR_HEADER +AC_XENIX_DIR + +AC_COMPILE_CHECK(setenv, , [setenv((char *)0,(char *)0);unsetenv((char *)0);], AC_DEFINE(USESETENV), +AC_COMPILE_CHECK(putenv, , [putenv((char *)0);unsetenv((char *)0);], , +AC_DEFINE(NEEDPUTENV) +)) + +AC_COMPILE_CHECK(rename, , [rename(0,0);], , AC_DEFINE(NEED_RENAME)) +AC_COMPILE_CHECK(_exit, , [_exit(0);], AC_DEFINE(HAVE__EXIT)) +AC_COMPILE_CHECK(lstat, , [lstat(0,0);], AC_DEFINE(HAVE_LSTAT)) +AC_COMPILE_CHECK(strerror, ,[strerror(0);], AC_DEFINE(HAVE_STRERROR)) + +dnl +dnl **** the end **** +dnl +dnl Ptx bug workaround -- insert -lc after -ltermcap +test -n "$seqptx" && LIBS="-ltermcap -lc -lsocket -linet -lsec -lseq" + +AC_TEST_PROGRAM(main(){exit(0);},,AC_ERROR(Can't run the compiler - internal error. Sorry.)) +if test -n "$prefix"; then +AC_DEFINE_UNQUOTED(ETCSCREENRC,\"$prefix/etc/screenrc\") +fi + +AC_OUTPUT(Makefile doc/Makefile) + +# a hook for preserving undef directive in config.h +if test -z "$no_create" ; then +mv config.h conftest +sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h +rm -f conftest +fi +cat >> config.status << EOF +mv config.h conftest +sed -e 's@^\(.*\)defin.\( .*\) .*/\*\(.*KEEP_UNDEF_HERE\)@\1undef\2 /\*\3@' < conftest > config.h +rm -f conftest +EOF + +echo "" +if test -z "$AWK"; then +echo "!!! Since you have no awk you must copy the files 'comm.h.dist'" +echo "!!! and 'term.h.dist' to 'comm.h' and 'term.h'." +echo "!!! Do _not_ change the user configuration section in config.h!" +echo "Please check the pathnames in the Makefile." +else +echo "Now please check the pathnames in the Makefile and the user" +echo "configuration section in config.h." +fi +echo "Then type 'make' to make screen. Good luck." +echo "" diff --git a/display.c b/display.c new file mode 100644 index 0000000..e4cdb1c --- /dev/null +++ b/display.c @@ -0,0 +1,1937 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + */ + +#include "rcs.h" +RCS_ID("$Id: display.c,v 1.16 1994/05/31 12:31:50 mlschroe Exp $ FAU") + + +#include +#include + +#include "config.h" +#include "screen.h" +#include "extern.h" + +static void CountChars __P((int)); +static void PutChar __P((int)); +static int BlankResize __P((int, int)); + + +extern struct win *windows; + +extern int use_hardstatus; +extern int MsgMinWait; +extern int Z0width, Z1width; +extern char *blank, *null; +extern struct mline mline_blank, mline_null; +extern struct mchar mchar_null, mchar_blank, mchar_so; + +/* + * tputs needs this to calculate the padding + */ +#ifndef NEED_OSPEED +extern +#endif /* NEED_OSPEED */ +short ospeed; + + +struct display *display, *displays; + +#ifndef MULTI +struct display TheDisplay; +#endif + +/* + * The default values + */ +int defobuflimit = OBUF_MAX; +#ifdef AUTO_NUKE +int defautonuke = 0; +#endif + +/* + * Default layer management + */ + +void +DefProcess(bufp, lenp) +char **bufp; +int *lenp; +{ + *bufp += *lenp; + *lenp = 0; +} + +void +DefRedisplayLine(y, xs, xe, isblank) +int y, xs, xe, isblank; +{ + if (isblank == 0 && y >= 0) + DefClearLine(y, xs, xe); +} + +void +DefClearLine(y, xs, xe) +int y, xs, xe; +{ + DisplayLine(&mline_null, &mline_blank, y, xs, xe); +} + +/*ARGSUSED*/ +int +DefRewrite(y, xs, xe, doit) +int y, xs, xe, doit; +{ + return EXPENSIVE; +} + +void +DefSetCursor() +{ + GotoPos(0, 0); +} + +/*ARGSUSED*/ +int +DefResize(wi, he) +int wi, he; +{ + return -1; +} + +void +DefRestore() +{ + InsertMode(0); + ChangeScrollRegion(0, D_height - 1); + KeypadMode(0); + CursorkeysMode(0); + CursorVisibility(0); + SetRendition(&mchar_null); + SetFlow(FLOW_NOW); +} + +/* + * Blank layer management + */ + +struct LayFuncs BlankLf = +{ + DefProcess, + 0, + DefRedisplayLine, + DefClearLine, + DefRewrite, + DefSetCursor, + BlankResize, + DefRestore +}; + +struct layer BlankLayer = +{ + 0, + 0, + &BlankLf, + 0 +}; + +/*ARGSUSED*/ +static int +BlankResize(wi, he) +int wi, he; +{ + return 0; +} + + +/* + * Generate new display + */ + +struct display * +MakeDisplay(uname, utty, term, fd, pid, Mode) +char *uname, *utty, *term; +int fd, pid; +struct mode *Mode; +{ + struct user **u; + + if (!*(u = FindUserPtr(uname)) && UserAdd(uname, (char *)0, u)) + return 0; /* could not find or add user */ + +#ifdef MULTI + if ((display = (struct display *)malloc(sizeof(*display))) == 0) + return 0; + bzero((char *) display, sizeof(*display)); +#else + if (displays) + return 0; + display = &TheDisplay; +#endif + display->d_next = displays; + displays = display; + D_flow = 1; + D_nonblock = 0; + D_userfd = fd; + D_OldMode = *Mode; + Resize_obuf(); /* Allocate memory for buffer */ + D_obufmax = defobuflimit; +#ifdef AUTO_NUKE + D_auto_nuke = defautonuke; +#endif + D_obufp = D_obuf; + D_printfd = -1; + D_userpid = pid; +#if defined(POSIX) || defined(TERMIO) +# ifdef POSIX + switch (cfgetospeed(&D_OldMode.tio)) +# else + switch (D_OldMode.tio.c_cflag & CBAUD) +# endif + { +#ifdef B0 + case B0: D_dospeed = 0; break; +#endif +#ifdef B50 + case B50: D_dospeed = 1; break; +#endif +#ifdef B75 + case B75: D_dospeed = 2; break; +#endif +#ifdef B110 + case B110: D_dospeed = 3; break; +#endif +#ifdef B134 + case B134: D_dospeed = 4; break; +#endif +#ifdef B150 + case B150: D_dospeed = 5; break; +#endif +#ifdef B200 + case B200: D_dospeed = 6; break; +#endif +#ifdef B300 + case B300: D_dospeed = 7; break; +#endif +#ifdef B600 + case B600: D_dospeed = 8; break; +#endif +#ifdef B1200 + case B1200: D_dospeed = 9; break; +#endif +#ifdef B1800 + case B1800: D_dospeed = 10; break; +#endif +#ifdef B2400 + case B2400: D_dospeed = 11; break; +#endif +#ifdef B4800 + case B4800: D_dospeed = 12; break; +#endif +#ifdef B9600 + case B9600: D_dospeed = 13; break; +#endif +#ifdef EXTA + case EXTA: D_dospeed = 14; break; +#endif +#ifdef EXTB + case EXTB: D_dospeed = 15; break; +#endif +#ifdef B57600 + case B57600: D_dospeed = 16; break; +#endif +#ifdef B115200 + case B115200: D_dospeed = 17; break; +#endif + default: ; + } +#else /* POSIX || TERMIO */ + D_dospeed = (short) D_OldMode.m_ttyb.sg_ospeed; +#endif /* POSIX || TERMIO */ + debug1("New displays ospeed = %d\n", D_dospeed); + strcpy(D_usertty, utty); + strcpy(D_termname, term); + + D_user = *u; + D_lay = &BlankLayer; + D_layfn = BlankLayer.l_layfn; + return display; +} + +void +FreeDisplay() +{ + struct win *p; +#ifdef MULTI + struct display *d, **dp; +#endif + + FreeTransTable(); + freetty(); + if (D_tentry) + free(D_tentry); + D_tentry = 0; + D_tcinited = 0; +#ifdef MULTI + for (dp = &displays; (d = *dp) ; dp = &d->d_next) + if (d == display) + break; + ASSERT(d); + if (D_status_lastmsg) + free(D_status_lastmsg); + if (D_obuf) + free(D_obuf); + *dp = display->d_next; + free((char *)display); +#else /* MULTI */ + ASSERT(display == displays); + ASSERT(display == &TheDisplay); + displays = 0; +#endif /* MULTI */ + for (p = windows; p; p = p->w_next) + { + if (p->w_display == display) + p->w_display = 0; + if (p->w_pdisplay == display) + p->w_pdisplay = 0; + } + display = 0; +} + +/* + * if the adaptflag is on, we keep the size of this display, else + * we may try to restore our old window sizes. + */ +void +InitTerm(adapt) +int adapt; +{ + ASSERT(display); + ASSERT(D_tcinited); + D_top = D_bot = -1; + PutStr(D_TI); + PutStr(D_IS); + /* Check for toggle */ + if (D_IM && strcmp(D_IM, D_EI)) + PutStr(D_EI); + D_insert = 0; + /* Check for toggle */ +#ifdef MAPKEYS + PutStr(D_KS); + PutStr(D_CCS); +#else + if (D_KS && strcmp(D_KS, D_KE)) + PutStr(D_KE); + if (D_CCS && strcmp(D_CCS, D_CCE)) + PutStr(D_CCE); +#endif + D_keypad = 0; + D_cursorkeys = 0; + PutStr(D_ME); + PutStr(D_EA); + PutStr(D_CE0); + D_rend = mchar_null; + D_atyp = 0; + if (adapt == 0) + ResizeDisplay(D_defwidth, D_defheight); + ChangeScrollRegion(0, D_height - 1); + D_x = D_y = 0; + Flush(); + ClearDisplay(); + debug1("we %swant to adapt all our windows to the display\n", + (adapt) ? "" : "don't "); + /* In case the size was changed by a init sequence */ + CheckScreenSize((adapt) ? 2 : 0); +} + +void +FinitTerm() +{ + ASSERT(display); + if (D_tcinited) + { + ResizeDisplay(D_defwidth, D_defheight); + DefRestore(); + SetRendition(&mchar_null); +#ifdef MAPKEYS + PutStr(D_KE); + PutStr(D_CCE); +#endif + if (D_hstatus) + PutStr(D_DS); + D_x = D_y = -1; + GotoPos(0, D_height - 1); + AddChar('\n'); + PutStr(D_TE); + } + Flush(); +} + + +void +INSERTCHAR(c) +int c; +{ + ASSERT(display); + if (!D_insert && D_x < D_width - 1) + { + if (D_IC || D_CIC) + { + if (D_IC) + PutStr(D_IC); + else + CPutStr(D_CIC, 1); + RAW_PUTCHAR(c); + return; + } + InsertMode(1); + if (!D_insert) + { + RefreshLine(D_y, D_x, D_width-1, 0); + return; + } + } + RAW_PUTCHAR(c); +} + +void +PUTCHAR(c) +int c; +{ + ASSERT(display); + if (D_insert && D_x < D_width - 1) + InsertMode(0); + RAW_PUTCHAR(c); +} + +void +PUTCHARLP(c) +int c; +{ + if (D_x < D_width - 1) + { + if (D_insert) + InsertMode(0); + RAW_PUTCHAR(c); + return; + } + if (D_CLP || D_y != D_bot) + { + RAW_PUTCHAR(c); + return; + } + D_lp_missing = 1; + D_rend.image = c; + D_lpchar = D_rend; +} + +/* + * RAW_PUTCHAR() is for all text that will be displayed. + * NOTE: charset Nr. 0 has a conversion table, but c1, c2, ... don't. + */ + +void +RAW_PUTCHAR(c) +int c; +{ + ASSERT(display); +#ifdef KANJI + if (D_rend.font == KANJI) + { + int t = c; + if (D_mbcs == 0) + { + D_mbcs = c; + return; + } + if (D_x == D_width - 1) + D_x += D_AM ? 1 : -1; + c = D_mbcs; + c &= 0x7f; + t &= 0x7f; + if (D_kanji == EUC) + { + c |= 0x80; + t |= 0x80; + } + else if (D_kanji == SJIS) + { + t += (c & 1) ? ((t <= 0x5f) ? 0x1f : 0x20) : 0x7e; + c = (c - 0x21) / 2 + ((c < 0x5e) ? 0x81 : 0xc1); + } + D_mbcs = t; + } + else if (D_rend.font == KANA) + { + if (D_kanji == EUC) + { + AddChar(0x8e); /* SS2 */ + c |= 0x80; + } + else if (D_kanji == SJIS) + c |= 0x80; + } + kanjiloop: +#endif + if (D_xtable && D_xtable[(int)(unsigned char)D_rend.font] && D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c]) + AddStr(D_xtable[(int)(unsigned char)D_rend.font][(int)(unsigned char)c]); + else + AddChar(D_rend.font != '0' ? c : D_c0_tab[(int)(unsigned char)c]); + + if (++D_x >= D_width) + { + if (D_AM == 0) + D_x = D_width - 1; + else if (!D_CLP || D_x > D_width) + { + D_x -= D_width; + if (D_y < D_height-1 && D_y != D_bot) + D_y++; + } + } +#ifdef KANJI + if (D_mbcs) + { + c = D_mbcs; + D_mbcs = 0; + goto kanjiloop; + } +#endif +} + +static void +PutChar(c) +int c; +{ + /* this PutChar for ESC-sequences only (AddChar is a macro) */ + AddChar(c); +} + +void +PutStr(s) +char *s; +{ + if (display && s) + { + ospeed = D_dospeed; + tputs(s, 1, PutChar); + } +} + +void +CPutStr(s, c) +char *s; +int c; +{ + if (display && s) + { + ospeed = D_dospeed; + tputs(tgoto(s, 0, c), 1, PutChar); + } +} + + +/* Insert mode is a toggle on some terminals, so we need this hack: + */ +void +InsertMode(on) +int on; +{ + if (display && on != D_insert && D_IM) + { + D_insert = on; + if (D_insert) + PutStr(D_IM); + else + PutStr(D_EI); + } +} + +/* ...and maybe keypad application mode is a toggle, too: + */ +void +KeypadMode(on) +int on; +{ +#ifdef MAPKEYS + if (display) + D_keypad = on; +#else + if (display && D_keypad != on && D_KS) + { + D_keypad = on; + if (D_keypad) + PutStr(D_KS); + else + PutStr(D_KE); + } +#endif +} + +void +CursorkeysMode(on) +int on; +{ +#ifdef MAPKEYS + if (display) + D_cursorkeys = on; +#else + if (display && D_cursorkeys != on && D_CCS) + { + D_cursorkeys = on; + if (D_cursorkeys) + PutStr(D_CCS); + else + PutStr(D_CCE); + } +#endif +} + +void +ReverseVideo(on) +int on; +{ + if (display && D_revvid != on && D_CVR) + { + D_revvid = on; + if (D_revvid) + PutStr(D_CVR); + else + PutStr(D_CVN); + } +} + +void +CursorVisibility(v) +int v; +{ + if (display && D_curvis != v) + { + if (D_curvis) + PutStr(D_VE); /* do this always, just to be safe */ + D_curvis = 0; + if (v == -1 && D_VI) + PutStr(D_VI); + else if (v == 1 && D_VS) + PutStr(D_VS); + else + return; + D_curvis = v; + } +} + +static int StrCost; + +/* ARGSUSED */ +static void +CountChars(c) +int c; +{ + StrCost++; +} + +int +CalcCost(s) +register char *s; +{ + ASSERT(display); + if (!s) + return EXPENSIVE; + StrCost = 0; + ospeed = D_dospeed; + tputs(s, 1, CountChars); + return StrCost; +} + +void +GotoPos(x2, y2) +int x2, y2; +{ + register int dy, dx, x1, y1; + register int costx, costy; + register int m; + register char *s; + int CMcost; + enum move_t xm = M_NONE, ym = M_NONE; + + if (!display) + return; + + x1 = D_x; + y1 = D_y; + + if (x1 == D_width) + if (D_CLP && D_AM) + x1 = -1; /* don't know how the terminal treats this */ + else + x1--; + if (x2 == D_width) + x2--; + dx = x2 - x1; + dy = y2 - y1; + if (dy == 0 && dx == 0) + return; + if (!D_MS) /* Safe to move ? */ + SetRendition(&mchar_null); + if (y1 < 0 /* don't know the y position */ + || (y2 > D_bot && y1 <= D_bot) /* have to cross border */ + || (y2 < D_top && y1 >= D_top)) /* of scrollregion ? */ + { + DoCM: + if (D_HO && !x2 && !y2) + PutStr(D_HO); + else + PutStr(tgoto(D_CM, x2, y2)); + D_x = x2; + D_y = y2; + return; + } + /* Calculate CMcost */ + if (D_HO && !x2 && !y2) + s = D_HO; + else + s = tgoto(D_CM, x2, y2); + CMcost = CalcCost(s); + + /* Calculate the cost to move the cursor to the right x position */ + costx = EXPENSIVE; + if (x1 >= 0) /* relativ x positioning only if we know where we are */ + { + if (dx > 0) + { + if (D_CRI && (dx > 1 || !D_ND)) + { + costx = CalcCost(tgoto(D_CRI, 0, dx)); + xm = M_CRI; + } + if ((m = D_NDcost * dx) < costx) + { + costx = m; + xm = M_RI; + } + /* Speedup: dx <= Rewrite() */ + if (dx < costx && (m = Rewrite(y1, x1, x2, 0)) < costx) + { + costx = m; + xm = M_RW; + } + } + else if (dx < 0) + { + if (D_CLE && (dx < -1 || !D_BC)) + { + costx = CalcCost(tgoto(D_CLE, 0, -dx)); + xm = M_CLE; + } + if ((m = -dx * D_LEcost) < costx) + { + costx = m; + xm = M_LE; + } + } + else + costx = 0; + } + /* Speedup: Rewrite() >= x2 */ + if (x2 + D_CRcost < costx && (m = (x2 ? Rewrite(y1, 0, x2, 0) : 0) + D_CRcost) < costx) + { + costx = m; + xm = M_CR; + } + + /* Check if it is already cheaper to do CM */ + if (costx >= CMcost) + goto DoCM; + + /* Calculate the cost to move the cursor to the right y position */ + costy = EXPENSIVE; + if (dy > 0) + { + if (D_CDO && dy > 1) /* DO & NL are always != 0 */ + { + costy = CalcCost(tgoto(D_CDO, 0, dy)); + ym = M_CDO; + } + if ((m = dy * ((x2 == 0) ? D_NLcost : D_DOcost)) < costy) + { + costy = m; + ym = M_DO; + } + } + else if (dy < 0) + { + if (D_CUP && (dy < -1 || !D_UP)) + { + costy = CalcCost(tgoto(D_CUP, 0, -dy)); + ym = M_CUP; + } + if ((m = -dy * D_UPcost) < costy) + { + costy = m; + ym = M_UP; + } + } + else + costy = 0; + + /* Finally check if it is cheaper to do CM */ + if (costx + costy >= CMcost) + goto DoCM; + + switch (xm) + { + case M_LE: + while (dx++ < 0) + PutStr(D_BC); + break; + case M_CLE: + CPutStr(D_CLE, -dx); + break; + case M_RI: + while (dx-- > 0) + PutStr(D_ND); + break; + case M_CRI: + CPutStr(D_CRI, dx); + break; + case M_CR: + PutStr(D_CR); + D_x = 0; + x1 = 0; + /* FALLTHROUGH */ + case M_RW: + if (x1 < x2) + (void) Rewrite(y1, x1, x2, 1); + break; + default: + break; + } + + switch (ym) + { + case M_UP: + while (dy++ < 0) + PutStr(D_UP); + break; + case M_CUP: + CPutStr(D_CUP, -dy); + break; + case M_DO: + s = (x2 == 0) ? D_NL : D_DO; + while (dy-- > 0) + PutStr(s); + break; + case M_CDO: + CPutStr(D_CDO, dy); + break; + default: + break; + } + D_x = x2; + D_y = y2; +} + +void +ClearDisplay() +{ + ASSERT(display); + Clear(0, 0, 0, D_width - 1, D_width - 1, D_height - 1, 0); +} + +void +Clear(x1, y1, xs, xe, x2, y2, uselayfn) +int x1, y1, xs, xe, x2, y2, uselayfn; +{ + int y, xxe; + + ASSERT(display); + if (x1 == D_width) + x1--; + if (x2 == D_width) + x2--; + if (D_UT) /* Safe to erase ? */ + SetRendition(&mchar_null); + if (D_lp_missing && y1 <= D_bot && xe >= D_width - 1) + { + if (y2 > D_bot || (y2 == D_bot && x2 >= D_width - 1)) + D_lp_missing = 0; + } + if (x2 == D_width - 1 && (xs == 0 || y1 == y2) && xe == D_width - 1 && y2 == D_height - 1) + { +#ifdef AUTO_NUKE + if (x1 == 0 && y1 == 0 && D_auto_nuke) + NukePending(); +#endif + if (x1 == 0 && y1 == 0 && D_CL) + { + PutStr(D_CL); + D_y = D_x = 0; + return; + } + /* + * Workaround a hp700/22 terminal bug. Do not use CD where CE + * is also appropriate. + */ + if (D_CD && (y1 < y2 || !D_CE)) + { + GotoPos(x1, y1); + PutStr(D_CD); + return; + } + } + if (x1 == 0 && xs == 0 && (xe == D_width - 1 || y1 == y2) && y1 == 0 && D_CCD) + { + GotoPos(x1, y1); + PutStr(D_CCD); + return; + } + xxe = xe; + for (y = y1; y <= y2; y++, x1 = xs) + { + if (y == y2) + xxe = x2; + if (x1 == 0 && D_CB && (xxe != D_width - 1 || (D_x == xxe && D_y == y))) + { + GotoPos(xxe, y); + PutStr(D_CB); + continue; + } + if (xxe == D_width - 1 && D_CE) + { + GotoPos(x1, y); + PutStr(D_CE); + continue; + } + if (uselayfn) + ClearLine(y, x1, xxe); + else + DisplayLine(&mline_null, &mline_blank, y, x1, xxe); + } +} + + +/* + * if cur_only > 0, we only redisplay current line, as a full refresh is + * too expensive over a low baud line. + */ +void +Redisplay(cur_only) +int cur_only; +{ + register int i, stop; + + ASSERT(display); + DefRestore(); + ClearDisplay(); + stop = D_height; + i = 0; + if (cur_only > 0 && D_fore) + { + i = stop = D_fore->w_y; + stop++; + } + else + RedisplayLine(-1, 0, D_width - 1, 1); + for (; i < stop; i++) + RedisplayLine(i, 0, D_width - 1, 1); + RefreshStatus(); + Restore(); + SetCursor(); +} + + +void +ScrollH(y, xs, xe, n, oml) +int y, xs, xe, n; +struct mline *oml; +{ + int i; + + if (n == 0) + return; + if (xe != D_width - 1) + { + RefreshLine(y, xs, xe, 0); + /* UpdateLine(oml, y, xs, xe); */ + return; + } + GotoPos(xs, y); + if (D_UT) + SetRendition(&mchar_null); + if (n > 0) + { + if (D_CDC && !(n == 1 && D_DC)) + CPutStr(D_CDC, n); + else if (D_DC) + { + for (i = n; i--; ) + PutStr(D_DC); + } + else + { + RefreshLine(y, xs, xe, 0); + /* UpdateLine(oml, y, xs, xe); */ + return; + } + } + else + { + if (!D_insert) + { + if (D_CIC && !(n == -1 && D_IC)) + CPutStr(D_CIC, -n); + else if (D_IC) + { + for (i = -n; i--; ) + PutStr(D_IC); + } + else if (D_IM) + { + InsertMode(1); + for (i = -n; i--; ) + INSERTCHAR(' '); + } + else + { + /* UpdateLine(oml, y, xs, xe); */ + RefreshLine(y, xs, xe, 0); + return; + } + } + else + { + for (i = -n; i--; ) + INSERTCHAR(' '); + } + } + if (D_lp_missing && y == D_bot) + { + if (n > 0) + FixLP(D_width - 1 - n, y); + D_lp_missing = 0; + } +} + +void +ScrollV(xs, ys, xe, ye, n) +int xs, ys, xe, ye, n; +{ + int i; + int up; + int oldtop, oldbot; + int alok, dlok, aldlfaster; + int missy = 0; + + ASSERT(display); + if (n == 0) + return; + if (n >= ye - ys + 1 || -n >= ye - ys + 1) + { + Clear(xs, ys, xs, xe, xe, ye, 0); + return; + } + if (xs != 0 || xe != D_width - 1) + { + Redisplay(0); + return; + } + + if (D_lp_missing) + { + if (D_bot > ye || D_bot < ys) + missy = D_bot; + else + { + missy = D_bot - n; + if (missy > ye || missy < ys) + D_lp_missing = 0; + } + } + + up = 1; + if (n < 0) + { + up = 0; + n = -n; + } + if (n >= ye - ys + 1) + n = ye - ys + 1; + + oldtop = D_top; + oldbot = D_bot; + if (D_bot != ye) + ChangeScrollRegion(ys, ye); + alok = (D_AL || D_CAL || (ye == D_bot && up)); + dlok = (D_DL || D_CDL || (ye == D_bot && !up)); + if (D_top != ys && !(alok && dlok)) + ChangeScrollRegion(ys, ye); + + if (D_lp_missing && + (oldbot != D_bot || + (oldbot == D_bot && up && D_top == ys && D_bot == ye))) + { + FixLP(D_width - 1, oldbot); + if (oldbot == D_bot) /* have scrolled */ + { + if (--n == 0) + { + ChangeScrollRegion(oldtop, oldbot); + return; + } + } + } + + aldlfaster = (n > 1 && ye == D_bot && ((up && D_CDL) || (!up && D_CAL))); + + if (D_UT) + SetRendition(&mchar_null); + if ((up || D_SR) && D_top == ys && D_bot == ye && !aldlfaster) + { + if (up) + { + GotoPos(0, ye); + while (n-- > 0) + PutStr(D_NL); /* was SF, I think NL is faster */ + } + else + { + GotoPos(0, ys); + while (n-- > 0) + PutStr(D_SR); + } + } + else if (alok && dlok) + { + if (up || ye != D_bot) + { + GotoPos(0, up ? ys : ye+1-n); + if (D_CDL && !(n == 1 && D_DL)) + CPutStr(D_CDL, n); + else + for(i = n; i--; ) + PutStr(D_DL); + } + if (!up || ye != D_bot) + { + GotoPos(0, up ? ye+1-n : ys); + if (D_CAL && !(n == 1 && D_AL)) + CPutStr(D_CAL, n); + else + for(i = n; i--; ) + PutStr(D_AL); + } + } + else + { + Redisplay(0); + return; + } + if (D_lp_missing && missy != D_bot) + FixLP(D_width - 1, missy); + ChangeScrollRegion(oldtop, oldbot); + if (D_lp_missing && missy != D_bot) + FixLP(D_width - 1, missy); +} + +void +SetAttr(new) +register int new; +{ + register int i, j, old, typ; + + if (!display || (old = D_rend.attr) == new) + return; +#if defined(TERMINFO) && defined(USE_SGR) + debug1("USE_SGR defined, sa is %s\n", D_SA ? D_SA : "undefined"); + if (D_SA) + { + char *tparm(); + SetFont(ASCII); + tputs(tparm(D_SA, new & A_SO, new & A_US, new & A_RV, new & A_BL, + new & A_DI, new & A_BD, 0 , 0 , + 0), 1, PutChar); + D_rend.attr = new; + D_atyp = 0; +# ifdef COLOR + if (D_CAF || D_CAB) + D_rend.color = 0; +# endif + return; + } +#endif + typ = D_atyp; + if ((new & old) != old) + { + if ((typ & ATYP_U)) + PutStr(D_UE); + if ((typ & ATYP_S)) + PutStr(D_SE); + if ((typ & ATYP_M)) + { + PutStr(D_ME); +#ifdef COLOR + /* ansi attrib handling: \E[m resets color, too */ + if (D_CAF || D_CAB) + D_rend.color = 0; +#endif + } + old = 0; + typ = 0; + } + old ^= new; + for (i = 0, j = 1; old && i < NATTR; i++, j <<= 1) + { + if ((old & j) == 0) + continue; + old ^= j; + if (D_attrtab[i]) + { + PutStr(D_attrtab[i]); + typ |= D_attrtyp[i]; + } + } + D_rend.attr = new; + D_atyp = typ; +} + +void +SetFont(new) +int new; +{ + if (!display || D_rend.font == new) + return; + D_rend.font = new; +#ifdef KANJI + if ((new == KANJI || new == KANA) && D_kanji) + return; /* all done in RAW_PUTCHAR */ +#endif + if (D_xtable && D_xtable[(int)(unsigned char)new] && + D_xtable[(int)(unsigned char)new][256]) + { + PutStr(D_xtable[(int)(unsigned char)new][256]); + return; + } + + if (!D_CG0 && new != '0') + new = ASCII; + + if (new == ASCII) + PutStr(D_CE0); +#ifdef KANJI + else if (new < ' ') + { + AddStr("\033$"); + AddChar(new + '@'); + } +#endif + else + CPutStr(D_CS0, new); +} + +#ifdef COLOR +void +SetColor(new) +int new; +{ + int of, ob, f, b; + + if (!display || D_rend.color == new) + return; + of = D_rend.color & 0xf; + ob = (D_rend.color >> 4) & 0xf; + f = new & 0xf; + b = (new >> 4) & 0xf; + + if (!D_CAX && ((f == 0 && f != of) || (b == 0 && b != ob))) + { + int oattr; + + oattr = D_rend.attr; + AddStr("\033[m"); + D_rend.attr = 0; + D_rend.color = 0; + of = ob = 0; + SetAttr(oattr); + } + if (D_CAF || D_CAB) + { + if (f != of) + CPutStr(D_CAF, 9 - f); + if (b != ob) + CPutStr(D_CAB, 9 - b); + } + D_rend.color = new; +} +#endif + +void +SetRendition(mc) +struct mchar *mc; +{ + if (!display) + return; + if (D_rend.attr != mc->attr) + SetAttr(mc->attr); +#ifdef COLOR + if (D_rend.color != mc->color) + SetColor(mc->color); +#endif + if (D_rend.font != mc->font) + SetFont(mc->font); +} + +void +SetRenditionMline(ml, x) +struct mline *ml; +int x; +{ + if (!display) + return; + if (D_rend.attr != ml->attr[x]) + SetAttr(ml->attr[x]); +#ifdef COLOR + if (D_rend.color != ml->color[x]) + SetColor(ml->color[x]); +#endif + if (D_rend.font != ml->font[x]) + SetFont(ml->font[x]); +} + +void +MakeStatus(msg) +char *msg; +{ + register char *s, *t; + register int max, ti; + + if (!display) + return; + + if (!D_tcinited) + { + debug("tc not inited, just writing msg\n"); + AddStr(msg); + AddStr("\r\n"); + Flush(); + return; + } + if (!use_hardstatus || !D_HS) + { + max = D_width; + if (D_CLP == 0) + max--; + } + else + max = D_WS; + if (D_status) + { + if (!D_status_bell) + { + ti = time((time_t *) 0) - D_status_time; + if (ti < MsgMinWait) + sleep(MsgMinWait - ti); + } + RemoveStatus(); + } + for (s = t = msg; *s && t - msg < max; ++s) + if (*s == BELL) + PutStr(D_BL); + else if ((unsigned char)*s >= ' ' && *s != 0177) + *t++ = *s; + *t = '\0'; + if (t > msg) + { + if (t - msg >= D_status_buflen) + { + char *buf; + if (D_status_lastmsg) + buf = realloc(D_status_lastmsg, t - msg + 1); + else + buf = malloc(t - msg + 1); + if (buf) + { + D_status_lastmsg = buf; + D_status_buflen = t - msg + 1; + } + } + if (t - msg < D_status_buflen) + strcpy(D_status_lastmsg, msg); + D_status = 1; + D_status_len = t - msg; + D_status_lastx = D_x; + D_status_lasty = D_y; + if (!use_hardstatus || !D_HS) + { + debug1("using STATLINE %d\n", STATLINE); + GotoPos(0, STATLINE); + SetRendition(&mchar_so); + InsertMode(0); + AddStr(msg); + D_x = -1; + } + else + { + debug("using HS\n"); + SetRendition(&mchar_null); + InsertMode(0); + if (D_hstatus) + PutStr(D_DS); + CPutStr(D_TS, 0); + AddStr(msg); + PutStr(D_FS); + D_hstatus = 1; + } + Flush(); + (void) time(&D_status_time); + } +} + +void +RemoveStatus() +{ + struct win *p; + + if (!display) + return; + if (!D_status) + return; + + /* + * UGLY HACK ALERT - this should NOT be in display.c + * We need to find the window that caused an activity or bell + * message, to reenable this function there. + */ + for (p = windows; p; p = p->w_next) + { + if (p->w_display != display) + continue; + if (p->w_monitor == MON_MSG) + { + debug1("RemoveStatus clearing monitor win %d\n", p->w_number); + p->w_monitor = MON_DONE; + } + if (p->w_bell == BELL_MSG) + { + debug1("RemoveStatus clearing bell win %d\n", p->w_number); + p->w_bell = BELL_DONE; + } + } + D_status = 0; + D_status_bell = 0; + if (!use_hardstatus || !D_HS) + { + GotoPos(0, STATLINE); + RefreshLine(STATLINE, 0, D_status_len - 1, 0); + GotoPos(D_status_lastx, D_status_lasty); + } + else + { + /* + SetRendition(&mchar_null); + if (D_hstatus) + PutStr(D_DS); + */ + RefreshStatus(); + } + SetCursor(); +} + +/* + * Refreshes the harstatus of the _window_. Shouldn't be here... + */ + +void +RefreshStatus() +{ + char *buf; + + if (D_HS) + { + SetRendition(&mchar_null); + if (D_hstatus) + PutStr(D_DS); + if (D_fore && D_fore->w_hstatus) + { + buf = MakeWinMsg(D_fore->w_hstatus, D_fore, '\005'); + CPutStr(D_TS, 0); + if (strlen(buf) > D_WS) + AddStrn(buf, D_WS); + else + AddStr(buf); + PutStr(D_FS); + D_hstatus = 1; + } + } + else if (D_fore && D_fore->w_hstatus) + { + buf = MakeWinMsg(D_fore->w_hstatus, D_fore, '\005'); + Msg(0, "%s", buf); + } +} + +void +RefreshLine(y, from, to, isblank) +int y, from, to, isblank; +{ + ASSERT(display); + debug2("RefreshLine %d %d", y, from); + debug2(" %d %d\n", to, isblank); + if (isblank == 0 && D_CE && to == D_width - 1) + { + GotoPos(from, y); + if (D_UT) + SetRendition(&mchar_null); + PutStr(D_CE); + isblank = 1; + } + RedisplayLine(y, from, to, isblank); +} + +void +FixLP(x2, y2) +register int x2, y2; +{ + struct mchar oldrend; + + ASSERT(display); + oldrend = D_rend; + GotoPos(x2, y2); + SetRendition(&D_lpchar); + PUTCHAR(D_lpchar.image); + D_lp_missing = 0; + SetRendition(&oldrend); +} + +void +DisplayLine(oml, ml, y, from, to) +struct mline *oml, *ml; +int from, to, y; +{ + register int x; + int last2flag = 0, delete_lp = 0; + + ASSERT(display); + ASSERT(y >= 0 && y < D_height); + ASSERT(from >= 0 && from < D_width); + ASSERT(to >= 0 && to < D_width); + if (!D_CLP && y == D_bot && to == D_width - 1) + if (D_lp_missing || !cmp_mline(oml, ml, to)) + { + if ((D_IC || D_IM) && from < to) + { + to -= 2; + last2flag = 1; + D_lp_missing = 0; + } + else + { + to--; + delete_lp = (D_CE || D_DC || D_CDC); + D_lp_missing = !cmp_mchar_mline(&mchar_blank, ml, to); + copy_mline2mchar(&D_lpchar, ml, to); + } + } + else + to--; + for (x = from; x <= to; x++) + { + if (x || D_x != D_width || D_y != y - 1) + { + if (x < to || x != D_width - 1 || ml->image[x + 1] == ' ') + if (cmp_mline(oml, ml, x)) + continue; + GotoPos(x, y); + } +#ifdef KANJI + if (badkanji(ml->font, x)) + { + x--; + GotoPos(x, y); + } +#endif + SetRenditionMline(ml, x); + PUTCHAR(ml->image[x]); +#ifdef KANJI + if (ml->font[x] == KANJI) + PUTCHAR(ml->image[++x]); +#endif + } + if (to == D_width - 1 && y < D_height - 1 && ml->image[to + 1] == ' ') + GotoPos(0, y + 1); + if (last2flag) + { + GotoPos(x, y); + SetRenditionMline(ml, x + 1); + PUTCHAR(ml->image[x + 1]); + GotoPos(x, y); + SetRenditionMline(ml, x); + INSERTCHAR(ml->image[x]); + } + else if (delete_lp) + { + if (D_UT) + { + SetRendition(&mchar_null); + } + if (D_DC) + PutStr(D_DC); + else if (D_CDC) + CPutStr(D_CDC, 1); + else if (D_CE) + PutStr(D_CE); + } +} + +void +SetLastPos(x,y) +int x,y; +{ + ASSERT(display); + D_x = x; + D_y = y; +} + +int +ResizeDisplay(wi, he) +int wi, he; +{ + ASSERT(display); + debug2("ResizeDisplay: to (%d,%d).\n", wi, he); + if (D_width == wi && D_height == he) + { + debug("ResizeDisplay: No change\n"); + return 0; + } + if (D_CWS) + { + debug("ResizeDisplay: using WS\n"); + PutStr(tgoto(D_CWS, wi, he)); + ChangeScreenSize(wi, he, 0); + return 0; + } + else if (D_CZ0 && (wi == Z0width || wi == Z1width)) + { + debug("ResizeDisplay: using Z0/Z1\n"); + PutStr(wi == Z0width ? D_CZ0 : D_CZ1); + ChangeScreenSize(wi, D_height, 0); + return (he == D_height) ? 0 : -1; + } + return -1; +} + +void +ChangeScrollRegion(newtop, newbot) +int newtop, newbot; +{ + if (display == 0) + return; + if (D_CS == 0) + { + D_top = 0; + D_bot = D_height - 1; + return; + } + if (D_top == newtop && D_bot == newbot) + return; + debug2("ChangeScrollRegion: (%d - %d)\n", newtop, newbot); + PutStr(tgoto(D_CS, newbot, newtop)); + D_top = newtop; + D_bot = newbot; + D_y = D_x = -1; /* Just in case... */ +} + + +/* + * Layer creation / removal + */ + +int +InitOverlayPage(datasize, lf, block) +int datasize; +struct LayFuncs *lf; +int block; +{ + char *data; + struct layer *newlay; + + RemoveStatus(); + debug3("Entering new layer display %#x D_fore %#x oldlay %#x\n", + (unsigned int)display, (unsigned int)D_fore, (unsigned int)D_lay); + if ((newlay = (struct layer *)malloc(sizeof(struct layer))) == 0) + { + Msg(0, "No memory for layer struct"); + return -1; + } + data = 0; + if (datasize) + { + if ((data = malloc(datasize)) == 0) + { + free((char *)newlay); + Msg(0, "No memory for layer data"); + return -1; + } + bzero(data, datasize); + } + newlay->l_layfn = lf; + newlay->l_block = block | D_lay->l_block; + newlay->l_data = data; + newlay->l_next = D_lay; + if (D_fore) + { + D_fore->w_lay = newlay; /* XXX: CHECK */ + D_fore->w_active = 0; /* XXX: CHECK */ + } + D_lay = newlay; + D_layfn = newlay->l_layfn; + Restore(); + return 0; +} + +void +ExitOverlayPage() +{ + struct layer *oldlay; + + debug3("Exiting layer display %#x fore %#x D_lay %#x\n", + (unsigned int)display, (unsigned int)D_fore, (unsigned int)D_lay); + oldlay = D_lay; + if (oldlay->l_data) + free(oldlay->l_data); + D_lay = oldlay->l_next; + D_layfn = D_lay->l_layfn; + free((char *)oldlay); + if (D_fore) + D_fore->w_lay = D_lay; /* XXX: Is this necessary ? */ + Restore(); + SetCursor(); +} + + +/* + * Output buffering routines + */ + +void +AddStr(str) +char *str; +{ + register char c; + + ASSERT(display); + while ((c = *str++)) + AddChar(c); +} + +void +AddStrn(str, n) +char *str; +int n; +{ + register char c; + + ASSERT(display); + while ((c = *str++) && n-- > 0) + AddChar(c); + while (n-- > 0) + AddChar(' '); +} + +void +Flush() +{ + register int l; + register char *p; + + ASSERT(display); + l = D_obufp - D_obuf; + debug1("Flush(): %d\n", l); + ASSERT(l + D_obuffree == D_obuflen); + if (l == 0) + return; + if (D_userfd < 0) + { + D_obuffree += l; + D_obufp = D_obuf; + return; + } + p = D_obuf; + if (fcntl(D_userfd, F_SETFL, 0)) + debug1("Warning: BLOCK fcntl failed: %d\n", errno); + while (l) + { + register int wr; + wr = write(D_userfd, p, l); + if (wr <= 0) + { + if (errno == EINTR) + continue; + debug1("Writing to display: %d\n", errno); + wr = l; + } + D_obuffree += wr; + p += wr; + l -= wr; + } + D_obuffree += l; + D_obufp = D_obuf; + if (fcntl(D_userfd, F_SETFL, FNBLOCK)) + debug1("Warning: NBLOCK fcntl failed: %d\n", errno); +} + +void +freetty() +{ + if (D_userfd >= 0) + close(D_userfd); + debug1("did freetty %d\n", D_userfd); + D_userfd = -1; + D_obufp = 0; + D_obuffree = 0; + if (D_obuf) + free(D_obuf); + D_obuf = 0; + D_obuflen = 0; +} + +/* + * Asynchronous output routines by + * Tim MacKenzie (tym@dibbler.cs.monash.edu.au) + */ + +void +Resize_obuf() +{ + register int ind; + + ASSERT(display); + if (D_obuflen && D_obuf) + { + ind = D_obufp - D_obuf; + D_obuflen += GRAIN; + D_obuffree += GRAIN; + D_obuf = realloc(D_obuf, D_obuflen); + } + else + { + ind = 0; + D_obuflen = GRAIN; + D_obuffree = GRAIN; + D_obuf = malloc(D_obuflen); + } + if (!D_obuf) + Panic(0, "Out of memory"); + D_obufp = D_obuf + ind; + debug1("ResizeObuf: resized to %d\n", D_obuflen); +} + +#ifdef AUTO_NUKE +void +NukePending() +{/* Nuke pending output in current display, clear screen */ + register int len; + int oldtop = D_top, oldbot = D_bot; + struct mchar oldrend; + int oldkeypad = D_keypad, oldcursorkeys = D_cursorkeys; + int oldcurvis = D_curvis; + + oldrend = D_rend; + len = D_obufp - D_obuf; + debug1("NukePending: nuking %d chars\n", len); + + /* Throw away any output that we can... */ +# ifdef POSIX + tcflush(D_userfd, TCOFLUSH); +# else +# ifdef TCFLSH + (void) ioctl(D_userfd, TCFLSH, (char *) 1); +# endif +# endif + + D_obufp = D_obuf; + D_obuffree += len; + D_top = D_bot = -1; + PutStr(D_TI); + PutStr(D_IS); + /* Turn off all attributes. (Tim MacKenzie) */ + if (D_ME) + PutStr(D_ME); + else + { + PutStr(D_SE); + PutStr(D_UE); + } + /* FIXME: reset color! */ + /* Check for toggle */ + if (D_IM && strcmp(D_IM, D_EI)) + PutStr(D_EI); + D_insert = 0; + /* Check for toggle */ +#ifndef MAPKEYS + if (D_KS && strcmp(D_KS, D_KE)) + PutStr(D_KE); + D_keypad = 0; + if (D_CCS && strcmp(D_CCS, D_CCE)) + PutStr(D_CCE); + D_cursorkeys = 0; +#endif + PutStr(D_CE0); + D_rend = mchar_null; + D_atyp = 0; + PutStr(D_DS); + D_hstatus = 0; + PutStr(D_VE); + D_curvis = 0; + ChangeScrollRegion(oldtop, oldbot); + SetRendition(&oldrend); + KeypadMode(oldkeypad); + CursorkeysMode(oldcursorkeys); + CursorVisibility(oldcurvis); + if (D_CWS) + { + debug("ResizeDisplay: using WS\n"); + PutStr(tgoto(D_CWS, D_width, D_height)); + } + else if (D_CZ0 && (D_width == Z0width || D_width == Z1width)) + { + debug("ResizeDisplay: using Z0/Z1\n"); + PutStr(D_width == Z0width ? D_CZ0 : D_CZ1); + } +} +#endif /* AUTO_NUKE */ + +#ifdef KANJI +int +badkanji(f, x) +char *f; +int x; +{ + int i, j; + if (f[x] != KANJI) + return 0; + for (i = j = 0; i < x; i++) + if (*f++ == KANJI) + j ^= 1; + return j; +} +#endif diff --git a/display.h b/display.h new file mode 100644 index 0000000..87d0944 --- /dev/null +++ b/display.h @@ -0,0 +1,222 @@ +/* Copyright (c) 1993 + * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) + * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) + * Copyright (c) 1987 Oliver Laumann + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program (see the file COPYING); if not, write to the + * Free Software Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * + **************************************************************** + * $Id: display.h,v 1.9 1994/05/31 12:31:54 mlschroe Exp $ FAU + */ + + +#ifdef MAPKEYS +struct kmap +{ + char seq[8]; + char off[8]; + int nr; +}; + +#define KMAP_SEQ ((int)((struct kmap *)0)->seq) +#define KMAP_OFF ((int)((struct kmap *)0)->off) + +#define KMAP_KEYS (T_OCAPS-T_CAPS) +#define KMAP_AKEYS (T_OCAPS-T_CURSOR) +#define KMAP_EXT 50 + +#define KMAP_NOTIMEOUT 0x4000 + +#endif + +struct win; /* forward declaration */ + +struct display +{ + struct display *d_next; /* linked list */ + struct user *d_user; /* user who owns that display */ + struct LayFuncs *d_layfn; /* current layer functions */ + struct layer *d_lay; /* layers on the display */ + struct win *d_fore; /* pointer to fore window */ + struct win *d_other; /* pointer to other window */ + char d_nonblock; /* don't block when d_obufmax reached */ + char d_termname[20 + 1]; /* $TERM */ + char *d_tentry; /* buffer for tgetstr */ + char d_tcinited; /* termcap inited flag */ + int d_width, d_height; /* width/height of the screen */ + int d_defwidth, d_defheight; /* default width/height of windows */ + int d_top, d_bot; /* scrollregion start/end */ + int d_x, d_y; /* cursor position */ + struct mchar d_rend; /* current rendition */ + char d_atyp; /* current attribute types */ +#ifdef KANJI + int d_mbcs; /* saved char for multibytes charset */ + int d_kanji; /* what kanji type the display is */ +#endif + int d_insert; /* insert mode flag */ + int d_keypad; /* application keypad flag */ + int d_cursorkeys; /* application cursorkeys flag */ + int d_revvid; /* reverse video */ + int d_curvis; /* cursor visibility */ + int d_hstatus; /* hardstatus used */ + int d_lp_missing; /* last character on bot line missing */ + struct mchar d_lpchar; /* missing char */ + time_t d_status_time; /* time of status display */ + char d_status; /* is status displayed? */ + char d_status_bell; /* is it only a vbell? */ + int d_status_len; /* length of status line */ + char *d_status_lastmsg; /* last displayed message */ + int d_status_buflen; /* last message buffer len */ + int d_status_lastx; /* position of the cursor */ + int d_status_lasty; /* before status was displayed */ + int d_ESCseen; /* Was the last char an ESC (^a) */ + int d_userpid; /* pid of attacher */ + char d_usertty[MAXPATHLEN]; /* tty we are attached to */ + int d_userfd; /* fd of the tty */ + struct mode d_OldMode; /* tty mode when screen was started */ + struct mode d_NewMode; /* New tty mode */ + int d_flow; /* tty's flow control on/off flag*/ + char *d_obuf; /* output buffer */ + int d_obuflen; /* len of buffer */ + int d_obufmax; /* len where we are blocking the pty */ + char *d_obufp; /* pointer in buffer */ + int d_obuffree; /* free bytes in buffer */ +#ifdef AUTO_NUKE + int d_auto_nuke; /* autonuke flag */ +#endif +#ifdef MAPKEYS + int d_nseqs; /* number of valid mappings */ + char *d_seqp; /* pointer into keymap array */ + int d_seql; /* number of parsed chars */ + int d_seqruns; /* number of select calls */ + int d_dontmap; /* do not map next */ + int d_mapdefault; /* do map next to default */ + struct kmap d_kmaps[KMAP_KEYS+KMAP_EXT]; /* keymaps */ +#endif + union tcu d_tcs[T_N]; /* terminal capabilities */ + char *d_attrtab[NATTR]; /* attrib emulation table */ + char d_attrtyp[NATTR]; /* attrib group table */ + short d_dospeed; /* baudrate of tty */ + char d_c0_tab[256]; /* conversion for C0 */ + char ***d_xtable; /* char translation table */ + int d_UPcost, d_DOcost, d_LEcost, d_NDcost; + int d_CRcost, d_IMcost, d_EIcost, d_NLcost; + int d_printfd; /* fd for vt100 print sequence */ +#ifdef UTMPOK + slot_t d_loginslot; /* offset, where utmp_logintty belongs */ + struct utmp d_utmp_logintty; /* here the original utmp structure is stored */ +# ifdef _SEQUENT_ + char d_loginhost[100+1]; +# endif /* _SEQUENT_ */ +#endif +}; + +#ifdef MULTI +# define DISPLAY(x) display->x +#else +extern struct display TheDisplay; +# define DISPLAY(x) TheDisplay.x +#endif + +#define D_user DISPLAY(d_user) +#define D_username (DISPLAY(d_user) ? DISPLAY(d_user)->u_name : 0) +#define D_layfn DISPLAY(d_layfn) +#define D_lay DISPLAY(d_lay) +#define D_fore DISPLAY(d_fore) +#define D_other DISPLAY(d_other) +#define D_nonblock DISPLAY(d_nonblock) +#define D_termname DISPLAY(d_termname) +#define D_tentry DISPLAY(d_tentry) +#define D_tcinited DISPLAY(d_tcinited) +#define D_width DISPLAY(d_width) +#define D_height DISPLAY(d_height) +#define D_defwidth DISPLAY(d_defwidth) +#define D_defheight DISPLAY(d_defheight) +#define D_top DISPLAY(d_top) +#define D_bot DISPLAY(d_bot) +#define D_x DISPLAY(d_x) +#define D_y DISPLAY(d_y) +#define D_rend DISPLAY(d_rend) +#define D_atyp DISPLAY(d_atyp) +#define D_mbcs DISPLAY(d_mbcs) +#define D_kanji DISPLAY(d_kanji) +#define D_insert DISPLAY(d_insert) +#define D_keypad DISPLAY(d_keypad) +#define D_cursorkeys DISPLAY(d_cursorkeys) +#define D_revvid DISPLAY(d_revvid) +#define D_curvis DISPLAY(d_curvis) +#define D_hstatus DISPLAY(d_hstatus) +#define D_lp_missing DISPLAY(d_lp_missing) +#define D_lpchar DISPLAY(d_lpchar) +#define D_status DISPLAY(d_status) +#define D_status_time DISPLAY(d_status_time) +#define D_status_bell DISPLAY(d_status_bell) +#define D_status_len DISPLAY(d_status_len) +#define D_status_lastmsg DISPLAY(d_status_lastmsg) +#define D_status_buflen DISPLAY(d_status_buflen) +#define D_status_lastx DISPLAY(d_status_lastx) +#define D_status_lasty DISPLAY(d_status_lasty) +#define D_ESCseen DISPLAY(d_ESCseen) +#define D_userpid DISPLAY(d_userpid) +#define D_usertty DISPLAY(d_usertty) +#define D_userfd DISPLAY(d_userfd) +#define D_OldMode DISPLAY(d_OldMode) +#define D_NewMode DISPLAY(d_NewMode) +#define D_flow DISPLAY(d_flow) +#define D_obuf DISPLAY(d_obuf) +#define D_obuflen DISPLAY(d_obuflen) +#define D_obufmax DISPLAY(d_obufmax) +#define D_obufp DISPLAY(d_obufp) +#define D_obuffree DISPLAY(d_obuffree) +#define D_auto_nuke DISPLAY(d_auto_nuke) +#define D_nseqs DISPLAY(d_nseqs) +#define D_seqp DISPLAY(d_seqp) +#define D_seql DISPLAY(d_seql) +#define D_seqruns DISPLAY(d_seqruns) +#define D_dontmap DISPLAY(d_dontmap) +#define D_mapdefault DISPLAY(d_mapdefault) +#define D_kmaps DISPLAY(d_kmaps) +#define D_tcs DISPLAY(d_tcs) +#define D_attrtab DISPLAY(d_attrtab) +#define D_attrtyp DISPLAY(d_attrtyp) +#define D_dospeed DISPLAY(d_dospeed) +#define D_c0_tab DISPLAY(d_c0_tab) +#define D_xtable DISPLAY(d_xtable) +#define D_UPcost DISPLAY(d_UPcost) +#define D_DOcost DISPLAY(d_DOcost) +#define D_LEcost DISPLAY(d_LEcost) +#define D_NDcost DISPLAY(d_NDcost) +#define D_CRcost DISPLAY(d_CRcost) +#define D_IMcost DISPLAY(d_IMcost) +#define D_EIcost DISPLAY(d_EIcost) +#define D_NLcost DISPLAY(d_NLcost) +#define D_printfd DISPLAY(d_printfd) +#define D_loginslot DISPLAY(d_loginslot) +#define D_utmp_logintty DISPLAY(d_utmp_logintty) +#define D_loginhost DISPLAY(d_loginhost) + + +#define GRAIN 4096 /* Allocation grain size for output buffer */ +#define OBUF_MAX 256 /* default for obuflimit */ + +#define OUTPUT_BLOCK_SIZE 256 /* Block size of output to tty */ + +#define AddChar(c) do { \ + if (--D_obuffree == 0) \ + Resize_obuf(); \ + *D_obufp++ = (c); \ +} while (0) + diff --git a/doc/FAQ b/doc/FAQ new file mode 100644 index 0000000..6c9c8af --- /dev/null +++ b/doc/FAQ @@ -0,0 +1,253 @@ + jw 21.10.93 + 05.05.94 + + screen: frequently asked questions -- known problems -- unimplemented bugs +=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + + +Q: Why is it impossible to download a file with Kermit/sz/rz when + screen is running? Do I need to set some special variables? + +A: Screen always interprets control-sequences sent by the + applications and translates/optimizes them for the current + terminal type. Screen always parses the user input for its + escape character (CTRL-A). Both are basic screen features and + cannot be switched off. Even if it were possible to switch + screen into a completely transparent mode, you could never switch + between windows, while kermit/sz/rz is downloading a file. You + must wait til the end as kermit/sz/rz will not transmit your + input during a file transfer and as kermit/sz/rz would be very + confused if screen switched away the window containing the + other kermit/sz/rz. Simply detach your screen session for each + file transfer and start the transfer program only from the shell + where you started screen. + +Q: I am using screen with a YYY terminal, which supports the XXX + graphic language. I am very happy with it, except one thing: I + cannot render graphics into screen windows. + +A: You are out of luck there. Screen provides a fixed set of escape + sequences in order to make it possible to switch terminal types. + Screen has to know exactly what the escape sequences do to the + terminal because it must hold an image in memory. Otherwise + screen could not restore the image if you switch to another + window. Because of this you have to change screens escape + sequence parser (ansi.c) to pass the XXX graphics sequences to + the terminal. Of course the graphics will be lost if you switch + to another window. Screen will only honour graphics sequences + that are demanded by an overwhelming majority. + +Q: For some unknown reason, the fifo in /tmp/screens/S-myname is + gone, and i can't resume my screen session. Is there a way to + recreate the fifo? + +A: Screen checks the fifo/socket whenever it receives a SIGCHLD + signal. If missing, the fifo/socket is recreated then. If screen + is running non set-uid the user can issue a 'kill -CHLD + screenpid' directly (it is -CHILD on some systems). Screenpid is + the process-id of the screen process found in a 'ps -x' listing. + But usually this won't work, as screen should be installed set- + uid root. In this case you will not be able to send it a signal, + but the kernel will. It does so, whenever a child of screen + changes its state. Find the process-id (shellpid below) of the + "least important" shell running inside screen. The try 'kill + -STOP shellpid'. If the fifo/socket does not reappear, destroy + the shell process. You sacrify one shell to save the rest. If + nothing works, please do not forget to remove all processes + running in the lost screen session. + +Q: When you start "screen" a page of text comes up to start you + off. Is there a way to get rid of this text as a command line + argument or by using a switch of some sort. + +A: Just put the following line in your ~/.screenrc: + startup_message off + Many peole ask this, although it is in the man page, too :-) + +Q: Start "screen emacs" and run emacs function suspend-emacs + (ctrl-z). The window containing emacs vanishes. + +A: This is a known bug. Unfortunatly there is no easy fix + because this is specified in the POSIX standard. When a new + window is created Screen opens up a new session because the + window has to get the pty as a controlling terminal (a + session can only have one controlling terminal). With the + setsid() call the process also creates a new process + group. This process group is orphaned, because there is no + process in the session which is not in the process + group. Now if the process group leader (i.e. your program) + gets a TTIN/TTOU/TSTP, POSIX states that the kernel must + send a KILL signal to the process group because there is no + one left to continue the process. Even if screen would + try to restart the program, that would be after it received the + KILL signal which cannot be caught or ignored. + + tromey@klab.caltech.edu (Tom Tromey): I've noticed this exact + same problem. I put this in my .emacs file. It seems to work: + + ;; If running under screen, disable C-z. + (if (and (getenv "STY") (not window-system)) + (global-unset-key "\C-z")) + +Q: Screen gets the terminal size wrong and messes up. + +A: Before you start screen: Check with 'stty -a' what the terminal + driver thinks about rows and columns. Check the environment + variables LINES and COLUMNS. Then from within screen check with + the info command (CTRL-A i) what size screen thinks your terminal + is. If correcting tty driver setting and environment variables + does not help, look up the terminal capability definition. First + the TERMCAP environment variable. If this is not set, look up the + terminals name as defined in the environment variable TERM in + /etc/termcap or in the terminfo database with untic or infocmp. + There may be :li=...: and :co=...: or even :ll=...: entries + (cols#... and lines#... when it's terminfo) defined incorrectly. + Either construct your own TERMCAP environment variables with + correct settings, use screens terminfo/termcap command in your + .screenrc file or have the database corrected by the system + administrator. + +Q: Screen messes up the terminal output when I use my favourite ap- + plication. Setting the terminal size does not help. + +A: Probably you got the termcap/terminfo entries wrong. Fixing this + is a three stage procedure. First, find out if terminfo or + termcap is used. If your system only has /etc/termcap, + but not /usr/lib/terminfo/... then you are using termcap. + Easy. But if your system has both, then it depends how the appli- + cation and how screen were linked. Beware, if your applica- + tion runs on another host via rlogin, telnet or the like, you + should check the terminfo/termcap databases there. If you cannot + tell if terminfo or termcap is used (or you just want to be + save), the do all steps in stage 3 in parallel for both + systems (on all envolved hosts). Second: Understand the basic + rules how screen does its terminal emulation. When screen is + started or reattached, it relies on the TERM environment variable + to correctly reflect the terminal type you have physically + in front of you. And the entry should either exist in the system + terminfo/termcap database or be specified via the TERMCAP en- + vironment variable (if screen is using the termcap system). On + the other end, screen understands one set of control codes. It + relies on the application using these codes. This means applica- + tions that run under screen must be able to adapt their con- + trol codes to screen. The application should use the TERM vari- + able and termcap or terminfo library to find out how to drive + its terminal. When running under screen, the terminal is virtual + and is only defined by the set of control codes that screen + understands. The TERM variable is automatically set to + "screen" and the "screen"-entries should exist in the data- + bases. If your application uses hardcoded control codes rather + than a database, you are on your own. Hint: The codes under- + stood by screen are a superset of the very common definition + named "vt100". Look at the documentation of screen. The + codes are listed there. Third: Have the entry "screen" in- + stalled on all hosts or make sure you can live with "vt100". + Check the codes sent by your application, when the TERM variable + is set to "screen". Do not try to set the TERM variable inside + screen to anything other than "screen" or "vt100" or compati- + ble. Thus your application can drive screen correctly. Also take + care that a good entry is installed for your physical terminal + that screen has to drive. Even if the entry was good enough + for your application to drive the terminal directly, screen may + find flaws, as it tries to use other capabilities while op- + timizing the screen output. The screenrc commands + "termcap" and/or "terminfo" may help to fine-tune capabilities + without calling the supervisor to change the database. + +Q: I cannot configure screen. Sed does not work. + +A: The regular expressions used in our configure scrip are too + complicated for GNU sed version 2.03. In this regard it is bug + compatible with Ultrix 3.1 "sed": GNU sed version 2.03 dumps + core with our configure script. Try an older release. E.g. from + ftp.uni-erlangen.de:/pub/utilities/screen/sed-2.02b.tar.gz + +Q: When reattaching a session from a different Workstation, the + DISPLAY environment variable should be updated. Even ``CTLR-A + : setenv DISPLAY newhost:0'' does not work as expected. + +A: Under unix every process has its own environment. The environ- + ment of the SCREEN process can be changed with the `setenv' com- + mand. This however cannot affect the environment of the + shells or applications already running under screen. Subsequently + spawned processes will reflect the changes. One should be aware + of this problem when running applications from very old shells. + Screen is a means for keeping processes alive. + +Q: About once every 5 times I ran the program, rather than getting + a "screen," I got someone elses IRC output/input. + +A: What probably happened is that an IRC process was left running on + a pseudo tty in such a way that the kernel thought the tty was + available for reallocation. You can fix this behaviour by + applying the SunOS 4.1.x tty jumbo patch (100513-04). + +Q: Screen compiled on SunOS 5.3 cannot reattach a detached session. + +A: You are using /usr/ucb/cc, this compiler is wrong. Actually it + links with a C-library that mis-interprets dirent. Try again + with /opt/SUNWspro/bin/cc! + +Q: The "talk" command does not work when Screen is active. + +A: Talk and several other programs rely on entries in the Utmp- + Database (/etc/utmp). On some systems this Database is world + writable, on others it is not. If it is not, screen must be + installed with the appropriate permissions (user or group s-bit) + just like any program that uses PTYs (rlogin, xterm, ...). When + screen cannot write to utmp, you will see messages on you display + which do not belong to any screen window. + When screen can update utmp, it is not guaranteed that it does as + you expect. First this depends on the config.h file defining + UTMPOK, LOGINDEFAULT, and perhaps CAREFULUTMP. Second it depends + on the screenrc files (system wide and per user), if utmp entries + are done. Third, you can control whether windows are logged in + with screens ``login'' command. + +Q: Seteuid() does not work as expected in AIX. Attempting a multi- + user-attach results in a screen-panic: "seteuid: not owner". + +A: This is not a screen problem. According to Kay Nettle + (pkn@cs.utexas.edu) you need the AIX patch PTF 423674. + +Q: When I type cd directory (any directory or just blank) from + within one of the windows in screen, the whole thing just freezes + up. + +A: You display the current working directory in xterm's title bar, + This may be caused by hardcoded ESC-sequences in the shell prompt + or in an cd alias. In Xterm the coding is + ESC ] n ; string_to_display ^G + where n = 1, 2, 3 selects the location of the displayed string. + Screen misinterprets this as the ansi operating system comment + sequence: + ESC ] osc_string + and waits (according to ansi) for the string terminator + ESC \ + Screen versions after 3.5.12 may provide a workaround. + +Q: Mesg or biff cannot be turned on or off while running screen. + +A: Screen failed to change the owner of the pty it uses. You need to + install screen setuid-root. See the file INSTALL for details. + +Q: The cursor left key deletes the characters instead of just moving the + cursor. A redisplay (^Al) brings everything back. + +A: Your terminal emulator treats the backspace as "destructive". You + can probably change this somewhere in the setup. We can't think + of a reason why anybody would want a destructive backspace, but + if you really must have it, add the lines + termcap 'bc@:bs@' + terminfo 'bc@:bs@' + to your ~/.screenrc (replace with the terminal type your + emulator uses). + +Q: I have an old SysV OS (like Motorola SysV68) and sometimes screen + doesn't reset the attributes correctly. A redisplay (^Al) doesn't + make things better. + +A: The libcurses library has a bug if attributes are cleared with + the special ue/se capabilities. As a workaround (other than upgrading + your system) modify 'rmul' (and 'rmso'?) in screen's terminfo entry: + rmul=\E[m, rmso=\E[m diff --git a/doc/Makefile.in b/doc/Makefile.in new file mode 100644 index 0000000..ce1930b --- /dev/null +++ b/doc/Makefile.in @@ -0,0 +1,54 @@ +# Makefile for Screen documentation + +srcdir = @srcdir@ +VPATH = @srcdir@ + +prefix = /usr/local +mandir = $(prefix)/man +infodir = $(prefix)/info + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MAKEINFO = makeinfo +TEXI2DVI = texi2dvi + +SHELL = /bin/sh + +all: screen.info + +dvi screen.dvi: screen.texinfo mostlyclean + $(TEXI2DVI) $(srcdir)/screen.texinfo + +info screen.info: screen.texinfo + $(MAKEINFO) $(srcdir)/screen.texinfo -o screen.info + +install: installdirs + $(INSTALL_DATA) $(srcdir)/screen.1 $(mandir)/man1/screen.1 + -$(MAKE) screen.info + -if test -f screen.info; then d=.; else d=$(srcdir); fi; \ + if test -f $$d/screen.info; then \ + for f in $$d/screen.info*; do $(INSTALL_DATA) $$f $(infodir);done; \ + if $(SHELL) -c 'install-info --version' >/dev/null 2>&1; then \ + install-info --infodir=$(infodir) $$d/screen.info; \ + else true; fi; \ + fi + +uninstall: + rm -f $(mandir)/man1/screen.1 + rm -f $(infodir)/screen.info* + +installdirs: + $(srcdir)/../etc/mkinstalldirs $(mandir)/man1 $(infodir) + +mostlyclean: + -rm -f *.cp *.cps *.fn *.fns *.ky *.kys *.pg *.tp *.vr + -rm -f *.log *.aux *.toc *~ + +clean distclean clobber: mostlyclean + -rm -f *.dvi + +realclean: clean + -rm -f *.info* + +check installcheck: + diff --git a/doc/fdpat.ps b/doc/fdpat.ps new file mode 100644 index 0000000..6b10099 --- /dev/null +++ b/doc/fdpat.ps @@ -0,0 +1,6501 @@ +%!PS-Adobe-2.0 EPSF-1.2 +%%DocumentFonts: Courier Helvetica-Bold Times-Roman +%%Pages: 1 +%%BoundingBox: 5 34 589 773 +%%EndComments + +/arrowHeight 10 def +/arrowWidth 5 def + +/IdrawDict 53 dict def +IdrawDict begin + +/reencodeISO { +dup dup findfont dup length dict begin +{ 1 index /FID ne { def }{ pop pop } ifelse } forall +/Encoding ISOLatin1Encoding def +currentdict end definefont +} def + +/ISOLatin1Encoding [ +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/space/exclam/quotedbl/numbersign/dollar/percent/ampersand/quoteright +/parenleft/parenright/asterisk/plus/comma/minus/period/slash +/zero/one/two/three/four/five/six/seven/eight/nine/colon/semicolon +/less/equal/greater/question/at/A/B/C/D/E/F/G/H/I/J/K/L/M/N +/O/P/Q/R/S/T/U/V/W/X/Y/Z/bracketleft/backslash/bracketright +/asciicircum/underscore/quoteleft/a/b/c/d/e/f/g/h/i/j/k/l/m +/n/o/p/q/r/s/t/u/v/w/x/y/z/braceleft/bar/braceright/asciitilde +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef/.notdef +/.notdef/dotlessi/grave/acute/circumflex/tilde/macron/breve +/dotaccent/dieresis/.notdef/ring/cedilla/.notdef/hungarumlaut +/ogonek/caron/space/exclamdown/cent/sterling/currency/yen/brokenbar +/section/dieresis/copyright/ordfeminine/guillemotleft/logicalnot +/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior +/acute/mu/paragraph/periodcentered/cedilla/onesuperior/ordmasculine +/guillemotright/onequarter/onehalf/threequarters/questiondown +/Agrave/Aacute/Acircumflex/Atilde/Adieresis/Aring/AE/Ccedilla +/Egrave/Eacute/Ecircumflex/Edieresis/Igrave/Iacute/Icircumflex +/Idieresis/Eth/Ntilde/Ograve/Oacute/Ocircumflex/Otilde/Odieresis +/multiply/Oslash/Ugrave/Uacute/Ucircumflex/Udieresis/Yacute +/Thorn/germandbls/agrave/aacute/acircumflex/atilde/adieresis +/aring/ae/ccedilla/egrave/eacute/ecircumflex/edieresis/igrave +/iacute/icircumflex/idieresis/eth/ntilde/ograve/oacute/ocircumflex +/otilde/odieresis/divide/oslash/ugrave/uacute/ucircumflex/udieresis +/yacute/thorn/ydieresis +] def +/Courier reencodeISO def +/Helvetica-Bold reencodeISO def +/Times-Roman reencodeISO def + +/none null def +/numGraphicParameters 17 def +/stringLimit 65535 def + +/Begin { +save +numGraphicParameters dict begin +} def + +/End { +end +restore +} def + +/SetB { +dup type /nulltype eq { +pop +false /brushRightArrow idef +false /brushLeftArrow idef +true /brushNone idef +} { +/brushDashOffset idef +/brushDashArray idef +0 ne /brushRightArrow idef +0 ne /brushLeftArrow idef +/brushWidth idef +false /brushNone idef +} ifelse +} def + +/SetCFg { +/fgblue idef +/fggreen idef +/fgred idef +} def + +/SetCBg { +/bgblue idef +/bggreen idef +/bgred idef +} def + +/SetF { +/printSize idef +/printFont idef +} def + +/SetP { +dup type /nulltype eq { +pop true /patternNone idef +} { +dup -1 eq { +/patternGrayLevel idef +/patternString idef +} { +/patternGrayLevel idef +} ifelse +false /patternNone idef +} ifelse +} def + +/BSpl { +0 begin +storexyn +newpath +n 1 gt { +0 0 0 0 0 0 1 1 true subspline +n 2 gt { +0 0 0 0 1 1 2 2 false subspline +1 1 n 3 sub { +/i exch def +i 1 sub dup i dup i 1 add dup i 2 add dup false subspline +} for +n 3 sub dup n 2 sub dup n 1 sub dup 2 copy false subspline +} if +n 2 sub dup n 1 sub dup 2 copy 2 copy false subspline +patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if +brushNone not { istroke } if +0 0 1 1 leftarrow +n 2 sub dup n 1 sub dup rightarrow +} if +end +} dup 0 4 dict put def + +/Circ { +newpath +0 360 arc +patternNone not { ifill } if +brushNone not { istroke } if +} def + +/CBSpl { +0 begin +dup 2 gt { +storexyn +newpath +n 1 sub dup 0 0 1 1 2 2 true subspline +1 1 n 3 sub { +/i exch def +i 1 sub dup i dup i 1 add dup i 2 add dup false subspline +} for +n 3 sub dup n 2 sub dup n 1 sub dup 0 0 false subspline +n 2 sub dup n 1 sub dup 0 0 1 1 false subspline +patternNone not { ifill } if +brushNone not { istroke } if +} { +Poly +} ifelse +end +} dup 0 4 dict put def + +/Elli { +0 begin +newpath +4 2 roll +translate +scale +0 0 1 0 360 arc +patternNone not { ifill } if +brushNone not { istroke } if +end +} dup 0 1 dict put def + +/Line { +0 begin +2 storexyn +newpath +x 0 get y 0 get moveto +x 1 get y 1 get lineto +brushNone not { istroke } if +0 0 1 1 leftarrow +0 0 1 1 rightarrow +end +} dup 0 4 dict put def + +/MLine { +0 begin +storexyn +newpath +n 1 gt { +x 0 get y 0 get moveto +1 1 n 1 sub { +/i exch def +x i get y i get lineto +} for +patternNone not brushLeftArrow not brushRightArrow not and and { ifill } if +brushNone not { istroke } if +0 0 1 1 leftarrow +n 2 sub dup n 1 sub dup rightarrow +} if +end +} dup 0 4 dict put def + +/Poly { +3 1 roll +newpath +moveto +-1 add +{ lineto } repeat +closepath +patternNone not { ifill } if +brushNone not { istroke } if +} def + +/Rect { +0 begin +/t exch def +/r exch def +/b exch def +/l exch def +newpath +l b moveto +l t lineto +r t lineto +r b lineto +closepath +patternNone not { ifill } if +brushNone not { istroke } if +end +} dup 0 4 dict put def + +/Text { +ishow +} def + +/idef { +dup where { pop pop pop } { exch def } ifelse +} def + +/ifill { +0 begin +gsave +patternGrayLevel -1 ne { +fgred bgred fgred sub patternGrayLevel mul add +fggreen bggreen fggreen sub patternGrayLevel mul add +fgblue bgblue fgblue sub patternGrayLevel mul add setrgbcolor +eofill +} { +eoclip +originalCTM setmatrix +pathbbox /t exch def /r exch def /b exch def /l exch def +/w r l sub ceiling cvi def +/h t b sub ceiling cvi def +/imageByteWidth w 8 div ceiling cvi def +/imageHeight h def +bgred bggreen bgblue setrgbcolor +eofill +fgred fggreen fgblue setrgbcolor +w 0 gt h 0 gt and { +l b translate w h scale +w h true [w 0 0 h neg 0 h] { patternproc } imagemask +} if +} ifelse +grestore +end +} dup 0 8 dict put def + +/istroke { +gsave +brushDashOffset -1 eq { +[] 0 setdash +1 setgray +} { +brushDashArray brushDashOffset setdash +fgred fggreen fgblue setrgbcolor +} ifelse +brushWidth setlinewidth +originalCTM setmatrix +stroke +grestore +} def + +/ishow { +0 begin +gsave +fgred fggreen fgblue setrgbcolor +printFont printSize scalefont setfont +/descender 0 printFont /FontBBox get 1 get printFont /FontMatrix +get transform exch pop def +/vertoffset 1 printSize sub descender sub def { +0 vertoffset moveto show +/vertoffset vertoffset printSize sub def +} forall +grestore +end +} dup 0 2 dict put def + +/patternproc { +0 begin +/patternByteLength patternString length def +/patternHeight patternByteLength 8 mul sqrt cvi def +/patternWidth patternHeight def +/patternByteWidth patternWidth 8 idiv def +/imageByteMaxLength imageByteWidth imageHeight mul +stringLimit patternByteWidth sub min def +/imageMaxHeight imageByteMaxLength imageByteWidth idiv patternHeight idiv +patternHeight mul patternHeight max def +/imageHeight imageHeight imageMaxHeight sub store +/imageString imageByteWidth imageMaxHeight mul patternByteWidth add string def +0 1 imageMaxHeight 1 sub { +/y exch def +/patternRow y patternByteWidth mul patternByteLength mod def +/patternRowString patternString patternRow patternByteWidth getinterval def +/imageRow y imageByteWidth mul def +0 patternByteWidth imageByteWidth 1 sub { +/x exch def +imageString imageRow x add patternRowString putinterval +} for +} for +imageString +end +} dup 0 12 dict put def + +/min { +dup 3 2 roll dup 4 3 roll lt { exch } if pop +} def + +/max { +dup 3 2 roll dup 4 3 roll gt { exch } if pop +} def + +/midpoint { +0 begin +/y1 exch def +/x1 exch def +/y0 exch def +/x0 exch def +x0 x1 add 2 div +y0 y1 add 2 div +end +} dup 0 4 dict put def + +/thirdpoint { +0 begin +/y1 exch def +/x1 exch def +/y0 exch def +/x0 exch def +x0 2 mul x1 add 3 div +y0 2 mul y1 add 3 div +end +} dup 0 4 dict put def + +/subspline { +0 begin +/movetoNeeded exch def +y exch get /y3 exch def +x exch get /x3 exch def +y exch get /y2 exch def +x exch get /x2 exch def +y exch get /y1 exch def +x exch get /x1 exch def +y exch get /y0 exch def +x exch get /x0 exch def +x1 y1 x2 y2 thirdpoint +/p1y exch def +/p1x exch def +x2 y2 x1 y1 thirdpoint +/p2y exch def +/p2x exch def +x1 y1 x0 y0 thirdpoint +p1x p1y midpoint +/p0y exch def +/p0x exch def +x2 y2 x3 y3 thirdpoint +p2x p2y midpoint +/p3y exch def +/p3x exch def +movetoNeeded { p0x p0y moveto } if +p1x p1y p2x p2y p3x p3y curveto +end +} dup 0 17 dict put def + +/storexyn { +/n exch def +/y n array def +/x n array def +n 1 sub -1 0 { +/i exch def +y i 3 2 roll put +x i 3 2 roll put +} for +} def + +%%EndProlog + +%%BeginIdrawPrologue +/arrowhead { +0 begin +transform originalCTM itransform +/taily exch def +/tailx exch def +transform originalCTM itransform +/tipy exch def +/tipx exch def +/dy tipy taily sub def +/dx tipx tailx sub def +/angle dx 0 ne dy 0 ne or { dy dx atan } { 90 } ifelse def +gsave +originalCTM setmatrix +tipx tipy translate +angle rotate +newpath +arrowHeight neg arrowWidth 2 div moveto +0 0 lineto +arrowHeight neg arrowWidth 2 div neg lineto +patternNone not { +originalCTM setmatrix +/padtip arrowHeight 2 exp 0.25 arrowWidth 2 exp mul add sqrt brushWidth mul +arrowWidth div def +/padtail brushWidth 2 div def +tipx tipy translate +angle rotate +padtip 0 translate +arrowHeight padtip add padtail add arrowHeight div dup scale +arrowheadpath +ifill +} if +brushNone not { +originalCTM setmatrix +tipx tipy translate +angle rotate +arrowheadpath +istroke +} if +grestore +end +} dup 0 9 dict put def + +/arrowheadpath { +newpath +arrowHeight neg arrowWidth 2 div moveto +0 0 lineto +arrowHeight neg arrowWidth 2 div neg lineto +} def + +/leftarrow { +0 begin +y exch get /taily exch def +x exch get /tailx exch def +y exch get /tipy exch def +x exch get /tipx exch def +brushLeftArrow { tipx tipy tailx taily arrowhead } if +end +} dup 0 4 dict put def + +/rightarrow { +0 begin +y exch get /tipy exch def +x exch get /tipx exch def +y exch get /taily exch def +x exch get /tailx exch def +brushRightArrow { tipx tipy tailx taily arrowhead } if +end +} dup 0 4 dict put def + +%%EndIdrawPrologue + +%I Idraw 10 Grid 8.86154 8.86154 + +%%Page: 1 1 + +Begin +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ .959646 0 0 .959646 0 0 ] concat +/originalCTM matrix currentmatrix def + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -23.3333 378.333 ] concat +%I +37 397 764 397 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -23.3333 282.5 ] concat +%I +37 397 764 397 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -24.1667 185.833 ] concat +%I +37 397 764 397 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -23.3333 -5.83331 ] concat +%I +37 397 764 397 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -23.3333 -101.667 ] concat +%I +37 397 764 397 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -23.3333 -197.5 ] concat +%I +37 397 764 397 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -23.3333 392.5 ] concat +%I +37 34 764 34 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 -15.8333 2.5 ] concat +%I +258 963 258 41 Line +%I 1 +End + +Begin %I Line +%I b 65535 +0 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +none SetP %I p n +%I t +[ .833333 -0 -0 .833333 198.833 3 ] concat +%I +258 963 258 41 Line +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 213.667 797 ] concat +%I +[ +(Subshell, error back) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 428 797 ] concat +%I +[ +(Input echo filter) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 22.8333 704.333 ] concat +%I +[ +(Input filter) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 214.833 704.333 ] concat +%I +[ +(Input Filter, error back) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 428.833 704.333 ] concat +%I +[ +(input filter, error echo) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 214 607.5 ] concat +%I +[ +(Output filter) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 428 607.5 ] concat +%I +[ +(Error robot) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 729.966 ] concat +%I +[ +(...) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 57.4667 ] concat +%I +[ +(...) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 57.4667 ] concat +%I +[ +(...) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 57.4667 ] concat +%I +[ +(...) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 45.8332 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 45.8332 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 45.8332 ] concat +%I 2 +55 743 +143 743 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -50.0001 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -50.0001 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -57.5001 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -50.0001 ] concat +%I 2 +55 743 +143 743 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -50.0001 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -50.0001 ] concat +%I 5 +489 760 +471 760 +462 760 +462 752 +462 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 134.167 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 2 +55 743 +143 743 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -145.833 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -153.333 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 0 -671.666 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 -671.666 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 -671.666 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 5 +444 707 +444 760 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 141.667 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 141.667 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 134.167 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 141.667 ] concat +%I 2 +55 743 +143 743 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 141.667 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 729.966 ] concat +%I +[ +(..: .:. .::) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 45.8332 ] concat +%I 2 +55 743 +143 743 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 30.8334 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 45 ] concat +%I 5 +444 707 +444 760 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 141.667 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 141.667 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 141.667 ] concat +%I 2 +55 743 +143 743 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 141.667 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 134.167 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 237.5 ] concat +%I 6 +400 619 +391 619 +365 619 +365 645 +391 645 +489 645 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 141.667 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 633.3 ] concat +%I +[ +(.!.) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 45.8333 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 38.3334 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -237.5 45.8332 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 45.8333 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 633.3 ] concat +%I +[ +(.!!) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 45.8332 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 729.966 ] concat +%I +[ +(..!) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 45.8332 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 45.8332 ] concat +%I 2 +55 743 +143 743 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 45.8334 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 45.8332 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 141.667 ] concat +%I 6 +400 619 +391 619 +365 619 +365 645 +391 645 +489 645 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 45.8333 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 633.3 ] concat +%I +[ +(.!:) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 537.466 ] concat +%I +[ +(.:!) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -236.667 -50.8333 ] concat +%I 5 +444 707 +444 760 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -237.5 45.8333 ] concat +%I 6 +400 619 +391 619 +365 619 +365 645 +391 645 +489 645 +6 BSpl +%I 1 +End + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t u + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 6.10352e-05 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 7.62939e-05 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 0 -95.8334 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 -95.8333 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 -95.8333 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 537.466 ] concat +%I +[ +(!..) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 189.167 -50 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 -57.5 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 -50.8333 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 -50.0001 ] concat +%I 5 +489 760 +471 760 +462 760 +462 752 +462 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -50 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -57.5 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -50.8333 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 176.667 -50 ] concat +%I 5 +444 707 +444 760 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 537.466 ] concat +%I +[ +(!.!) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 22 607.5 ] concat +%I +[ +(Input echo filter, error back) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 21.1667 510.833 ] concat +%I +[ +(Robot) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 441.633 ] concat +%I +[ +(!!.) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -237.5 -145.833 ] concat +%I 5 +489 760 +471 760 +462 760 +462 752 +462 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -237.5 -145.833 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -145.833 ] concat +%I 5 +489 760 +471 760 +462 760 +462 752 +462 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -145.833 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -145.833 ] concat +%I 5 +444 707 +444 760 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 441.633 ] concat +%I +[ +(!!!) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 427.167 510.833 ] concat +%I +[ +(Full robot, error echo) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 -145.833 ] concat +%I 5 +489 760 +471 760 +462 760 +462 752 +462 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 -145.833 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -146.667 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 6 +639 388 +630 388 +586 388 +586 433 +631 433 +728 433 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 5 +684 361 +684 379 +684 388 +675 388 +657 388 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 334.167 ] concat +%I 5 +684 361 +684 379 +684 388 +675 388 +657 388 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 441.633 ] concat +%I +[ +(!!:) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -237.5 -241.667 ] concat +%I 5 +489 760 +471 760 +462 760 +462 752 +462 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -242.5 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 6 +143 273 +134 273 +99 273 +99 309 +134 309 +232 309 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -242.5 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 -191.667 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 0 -191.667 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 -191.667 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 345.8 ] concat +%I +[ +(!:!) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 213.167 510.833 ] concat +%I +[ +(Full robot) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 345.8 ] concat +%I +[ +(!:: !:. !.:) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 213.167 415 ] concat +%I +[ +(Full robot, out & error echo) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -241.667 ] concat +%I 5 +489 760 +471 760 +462 760 +462 752 +462 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 -242.5 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 141.667 ] concat +%I 6 +143 273 +134 273 +99 273 +99 309 +134 309 +232 309 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 -242.5 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -38.3333 -4.16667 ] concat +%I 5 +471 652 +471 661 +471 679 +454 679 +436 679 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 189.167 -242.5 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 -287.5 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 0 -287.5 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 -287.5 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 345.8 ] concat +%I +[ +(:..) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 427.167 415 ] concat +%I +[ +(Output echo filter) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -242.5 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -242.5 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -242.5 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -242.5 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -249.167 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -242.5 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 -383.333 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 0 -383.333 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 -383.333 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -38.3333 -4.16667 ] concat +%I 6 +657 484 +649 484 +622 484 +622 457 +649 457 +657 457 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -339.167 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -339.167 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -345.833 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -339.167 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -451.667 -100.833 ] concat +%I 6 +657 484 +649 484 +622 484 +622 457 +649 457 +657 457 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -236.667 -338.333 ] concat +%I 5 +444 707 +444 752 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 21.1667 415 ] concat +%I +[ +(Full Robot, output echo) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 21.1667 319.167 ] concat +%I +[ +(Output echo filter, error back) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 249.967 ] concat +%I +[ +(:.!) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190 -339.167 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190 -339.167 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 427.167 319.167 ] concat +%I +[ +(Robot, input echo) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 21.1667 223.333 ] concat +%I +[ +(Full robot, input echo) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 427.167 223.333 ] concat +%I +[ +(Full robot, input & output echo) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 213.167 223.333 ] concat +%I +[ +(Full robot, input & error echo) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 213.167 319.167 ] concat +%I +[ +(Full robot, full echo) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 249.967 ] concat +%I +[ +(::: ::. :.:) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 249.967 ] concat +%I +[ +(:!.) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 15 154.133 ] concat +%I +[ +(:!!) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 214.167 154.133 ] concat +%I +[ +(:!:) +] Text +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-helvetica-bold-r-*-140-* +Helvetica-Bold 14 SetF +%I t +[ 1.6 0 0 1.6 428.333 154.133 ] concat +%I +[ +(::!) +] Text +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190 -338.333 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -15.8333 .833333 ] concat +%I 6 +391 353 +382 353 +365 353 +365 336 +382 336 +391 336 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 .833333 ] concat +%I 6 +400 327 +391 327 +356 327 +356 363 +391 363 +489 362 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 .833364 ] concat +%I 2 +489 353 +312 353 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 .833364 ] concat +%I 2 +400 327 +312 327 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -339.167 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -338.333 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 184.167 .833333 ] concat +%I 6 +391 353 +382 353 +365 353 +365 336 +382 336 +391 336 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 176.667 .833364 ] concat +%I 2 +489 353 +312 353 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 -337.5 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -345.833 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -435 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -229.167 -95 ] concat +%I 6 +391 353 +382 353 +365 353 +365 336 +382 336 +391 336 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -236.667 -94.9999 ] concat +%I 2 +489 353 +312 353 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -237.5 -433.333 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3332 -441.667 ] concat +%I 2 +143 734 +55 734 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -236.667 -434.166 ] concat +%I 5 +444 707 +444 752 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190 -435 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190 -434.167 ] concat +%I 5 +188 707 +188 716 +188 725 +179 725 +161 725 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -15.8333 -95 ] concat +%I 6 +391 353 +382 353 +365 353 +365 336 +382 336 +391 336 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -94.9999 ] concat +%I 2 +489 353 +312 353 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 -94.9999 ] concat +%I 2 +400 327 +312 327 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -24.1669 -434.166 ] concat +%I 5 +453 707 +453 752 +453 769 +471 769 +489 769 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 .833333 ] concat +%I 5 +188 415 +188 460 +188 486 +214 486 +233 486 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 -338.333 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 -242.5 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3332 -145.833 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3332 -353.333 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -338.333 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3332 -434.167 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3332 -249.167 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 190.833 -145.833 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390.833 -145.833 ] concat +%I 2 +232 778 +55 778 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 389.167 -435 ] concat +%I 5 +161 743 +179 743 +205 743 +205 716 +205 707 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 183.333 -95 ] concat +%I 6 +391 353 +382 353 +365 353 +365 336 +382 336 +391 336 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 -94.9999 ] concat +%I 2 +489 353 +312 353 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 175.833 -94.9999 ] concat +%I 2 +400 327 +312 327 +2 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 390 -434.167 ] concat +%I 5 +196 707 +196 716 +196 734 +179 734 +161 734 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 176.667 -434.167 ] concat +%I 5 +444 707 +444 760 +444 778 +471 778 +489 778 +5 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 .833333 ] concat +%I 2 +728 247 +551 247 +2 BSpl +%I 1 +End + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 -480 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 0 -480 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 -480 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 199.166 -575.833 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -0.000432014 -575.833 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I Pict +%I b 65535 +1 0 0 [] 0 SetB +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 -214.167 -575.833 ] concat + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 214.167 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +143 716 +161 716 +161 752 +143 752 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 99.8333 758.833 ] concat +%I +[ +(P) +] Text +End + +End %I eop + +Begin %I Pict +%I b u +%I cfg u +%I cbg u +%I f u +%I p u +%I t +[ 1 0 0 1 221.667 -0.000366211 ] concat + +Begin %I Poly +%I b 65535 +2 0 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 -23.3333 141.667 ] concat +%I 4 +223 752 +241 752 +241 787 +223 787 +4 Poly +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 164 788.416 ] concat +%I +[ +(W) +] Text +End + +End %I eop + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f *-times-medium-r-*-140-* +Times-Roman 14 SetF +%I t +[ 1 0 0 1 344.333 725.833 ] concat +%I +[ +(210) +] Text +End + +End %I eop + +Begin %I BSpl +%I b 65535 +1 0 1 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 125 181.667 ] concat +%I 6 +222 -5 +213 -5 +169 -5 +169 39 +240 39 +311 39 +6 BSpl +%I 1 +End + +Begin %I BSpl +%I b 65535 +1 1 0 [] 0 SetB +%I cfg Black +0 0 0 SetCFg +%I cbg White +1 1 1 SetCBg +%I p +1 SetP +%I t +[ .833333 -0 -0 .833333 125 181.667 ] concat +%I 2 +222 39 +134 39 +2 BSpl +%I 1 +End + +Begin %I Text +%I cfg Black +0 0 0 SetCFg +%I f -*-courier-medium-r-normal-*-8-*-*-*-*-*-*-* +Courier 8 SetF +%I t +[ 1 0 0 1 22 797 ] concat +%I +[ +(Subshell) +] Text +End + +End %I eop + +showpage + +%%Trailer + +end diff --git a/doc/install.sh b/doc/install.sh new file mode 100755 index 0000000..8c07c50 --- /dev/null +++ b/doc/install.sh @@ -0,0 +1,119 @@ +#! /bin/sh + +# +# install - install a program, script, or datafile +# This comes from X11R5; it is not part of GNU. +# +# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $ +# +# This script is compatible with the BSD install script, but was written +# from scratch. +# + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" + +instcmd="$mvprog" +chmodcmd="" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +fi + +if [ x"$dst" = x ] +then + echo "install: no destination specified" + exit 1 +fi + + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + +if [ -d $dst ] +then + dst="$dst"/`basename $src` +fi + +# Make a temp file name in the proper directory. + +dstdir=`dirname $dst` +dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + +$doit $instcmd $src $dsttmp + +# and set any options; do chmod last to preserve setuid bits + +if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi +if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi +if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi +if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi + +# Now rename the file to the real destination. + +$doit $rmcmd $dst +$doit $mvcmd $dsttmp $dst + + +exit 0 diff --git a/doc/screen.1 b/doc/screen.1 new file mode 100644 index 0000000..558e314 --- /dev/null +++ b/doc/screen.1 @@ -0,0 +1,3349 @@ +.\" vi:set wm=5 +.TH SCREEN 1 "15 Oct 1995" +.if n .ds Q \&" +.if n .ds U \&" +.if t .ds Q `` +.if t .ds U '' +.UC 4 +.SH NAME +screen \- screen manager with VT100/ANSI terminal emulation + + +.SH SYNOPSIS +.B screen +[ +.B \-\fIoptions\fP +] [ +.B \fIcmd\fP +[ +.B \fIargs\fP +] ] +.br +.B screen \-r +[ [\fIpid.\fP]\fItty\fP[\fI.host\fP] ] +.ta .5i 1.8i + + +.SH DESCRIPTION +.I Screen +is a full-screen window manager that +multiplexes a physical terminal between several processes (typically +interactive shells). +Each virtual terminal provides the functions +of a DEC VT100 terminal and, in addition, several control functions +from the ANSI X3.64 (ISO 6429) and ISO 2022 standards +(e.\|g. insert/delete line and support for multiple character sets). +There is a scrollback history buffer for each virtual terminal and a +copy-and-paste mechanism that allows moving text regions between +windows. +.PP +When +.I screen +is called, it creates a single window with a shell in it (or the specified +command) and then gets out of your way so that you can use the program as you +normally would. +Then, at any time, you can create new (full-screen) windows with other programs +in them (including more shells), kill existing windows, view a list of +windows, turn output logging on and off, copy-and-paste text between +windows, view the scrollback history, switch between windows +in whatever manner you wish, etc. +When a program terminates, +.I screen +(per default) kills the window that contained it. +If this window was in the foreground, the display switches to the previous +window; if none are left, +.I screen +exits. +.PP +Everything you type is sent to the program running in the current window. +The only exception to this is the one keystroke that is used to initiate +a command to the window manager. +By default, each command begins with a control-a (abbreviated C-a from +now on), and is followed by one other keystroke. +The command character and all the key bindings can be fully customized +to be anything you like, though they are always two characters in length. +.PP +The standard way to create a new window is to type \*QC-a c\*U. +This creates a new window running a shell and switches to that +window immediately, regardless of the state of the process running +in the current window. +Similarly, you can create a new window with a custom command in it by +first binding the command to a keystroke (in your .screenrc file or at the +\*QC-a :\*U command line) and +then using it just like the \*QC-a c\*U command. +In addition, new windows can be created by running a command like: +.IP +screen emacs prog.c +.PP +from a shell prompt within a previously created window. +This will not run another copy of +.IR screen , +but will instead supply the command name and its arguments to the window +manager (specified in the $STY environment variable) who will use it to +create the new window. +The above example would start the emacs editor (editing prog.c) and switch +to its window. +.PP +If \*Q/etc/utmp\*U is writable by +.IR screen , +an appropriate record will be written to this file for each window, and +removed when the window is terminated. +This is useful for working with \*Qtalk\*U, \*Qscript\*U, \*Qshutdown\*U, +\*Qrsend\*U, \*Qsccs\*U and other similar programs that use the utmp +file to determine who you are. As long as +.I screen +is active on your terminal, +the terminal's own record is removed from the utmp file. See also \*QC-a L\*U. + + +.SH GETTING STARTED +Before you begin to use +.I screen +you'll need to make sure you have correctly selected your terminal type, +just as you would for any other termcap/terminfo program. +(You can do this by using +.IR tset +for example.) +.PP +If you're impatient and want to get started without doing a lot more reading, +you should remember this one command: \*QC-a ?\*U. +Typing these two characters will display a list of the available +.I screen +commands and their bindings. Each keystroke is discussed in +the section \*QDEFAULT KEY BINDINGS\*U. The manual section \*QCUSTOMIZATION\*U +deals with the contents of your .screenrc. +.PP +If your terminal is a \*Qtrue\*U auto-margin terminal (it doesn't allow +the last position on the screen to be updated without scrolling the +screen) consider to use a version of your terminal's termcap that has +automatic margins turned \fIoff\fP. This will ensure an accurate and +optimal update of the screen in all circumstances. Most terminals +nowadays have \*Qmagic\*U margins (automatic margins plus usable last +column). This is the VT100 style type and perfectly suited for +\fIscreen\fP. +If all you've got is a \*Qtrue\*U auto-margin terminal \fIscreen\fP +will be content to use it, but updating a character put into the last +position on the screen may not be possible until the screen scrolls or +the character is moved into a safe position in some other way. This +delay can be shortened by using a terminal with insert-character +capability. + + +.SH "COMMAND-LINE OPTIONS" +Screen has the following command-line options: +.TP 5 +.B \-a +include \fIall\fP capabilities (with some minor exceptions) in each +window's termcap, even if +.I screen +must redraw parts of the display in order to implement a function. +.TP 5 +.B \-A +Adapt the sizes of all windows to the size of the current terminal. +By default, +.I screen +tries to restore its old window sizes when attaching to resizable terminals +(those with \*QWS\*U in its description, e.g. suncmd or some xterm). +.TP 5 +.BI "\-c " file +override the default configuration file from \*Q$HOME/.screenrc\*U +to \fIfile\fP. +.TP 5 +.BR \-d | \-D " [" \fIpid.tty.host ] +does not start +.IR screen , +but detaches the elsewhere running +.I screen +session. It has the same effect as typing \*QC-a d\*U from +.I screen's +controlling terminal. \fB\-D\fP is the equivalent to the power detach key. +If no session can be detached, this option is ignored. +The combination \*Qscreen \-D \-r\*U can be used to `transport' the elsewhere +running session to this terminal and logout there. +Note: It is a good idea to have the status of your sessions checked by means of +\*Qscreen \-list\*U. +.TP 5 +.BI "\-e " xy +specifies the command character to be \fIx\fP and the character generating a +literal command character to \fIy\fP (when typed after the command character). +The default is \*QC-a\*U and `a', which can be specified as \*Q-e^Aa\*U. +When creating a +.I screen +session, this option sets the default command character. In a multiuser +session all users added will start off with this command character. But +when attaching to an already running session, this option changes only +the command character of the attaching user. +This option is equivalent to either the commands \*Qdefescape\*U or +\*Qescape\*U respectively. +.TP 5 +.BR \-f\fP ", " \-fn ", and " \-fa +turns flow-control on, off, or \*Qautomatic switching mode\*U. +This can also be defined through the \*Qdefflow\*U .screenrc command. +.TP 5 +.BI "\-h " num +Specifies the history scrollback buffer to be \fInum\fP lines high. +.TP 5 +.B \-i +will cause the interrupt key (usually C-c) to interrupt the display +immediately when flow-control is on. +See the \*Qdefflow\*U .screenrc command for details. +The use of this option is discouraged. +.TP 5 +.BR \-l " and " \-ln +turns login mode on or off (for /etc/utmp updating). +This can also be defined through the \*Qdeflogin\*U .screenrc command. +.TP 5 +.BR \-ls " and " \-list +does not start +.IR screen , +but prints a list of +.I pid.tty.host +strings identifying your +.I screen +sessions. +Sessions marked `detached' can be resumed with \*Qscreen -r\*U. Those marked +`attached' are running and have a controlling terminal. Sessions marked as +`dead' should be thoroughly checked and removed. Ask your system administrator +if you are not sure. Remove sessions with the \fB-wipe\fP option. +.TP 5 +.B \-L +tells +.I screen +your auto-margin terminal has a writable last-position on +the screen. +This can also be set in your .screenrc by specifying `LP' in a \*Qtermcap\*U +command. +.TP 5 +.B \-m +causes +.I screen +to ignore the $STY environment variable. With \*Qscreen -m\*U creation of +a new session is enforced, regardless whether +.I screen +is called from within another +.I screen +session or not. +.TP 5 +.B \-O +selects a more optimal output mode for your terminal rather than true VT100 +emulation (only affects auto-margin terminals without `LP'). +This can also be set in your .screenrc by specifying `OP' in a \*Qtermcap\*U +command. +.TP 5 +.BR \-r " [" \fIpid.tty.host ] +resumes a detached +.I screen +session. +No other options (except \*Q-d -r\*U or \*Q-D -r\*U) may be specified, though +an optional prefix of [\fIpid.\fP]\fItty.host\fP +may be needed to distinguish between multiple detached +.I screen +sessions. +.TP 5 +.B \-R +attempts to resume the first detached +.I screen +session it finds. +If successful, all other command-line options are ignored. +If no detached session exists, starts a new session using the specified +options, just as if +.B \-R +had not been specified. The option is set by default if +.I screen +is run as a login-shell. +.TP 5 +.B \-s +sets the default shell to the program specified, instead of the value +in the environment variable $SHELL (or \*Q/bin/sh\*U if not defined). +This can also be defined through the \*Qshell\*U .screenrc command. +.TP 5 +.BI "\-S " sessionname +When creating a new session, this option can be used to specify a +meaningful name for the session. This name identifies the session for +\*Qscreen -list\*U and \*Qscreen -r\*U actions. It substitutes the +default [\fItty.host\fP] suffix. +.TP 5 +.BI "\-t " name +sets the title (a.\|k.\|a.) for the default shell or specified program. +See also the \*Qshelltitle\*U .screenrc command. +.TP 5 +.B \-v +Print version number. +.TP 5 +.B \-wipe +does the same as \*Qscreen -ls\*U, but removes destroyed sessions instead of +marking them as `dead'. +.TP 5 +.B \-x +Attach to a not detached +.I screen +session. (Multi display mode). + + +.SH "DEFAULT KEY BINDINGS" +.ta 12n 26n +As mentioned, each +.I screen +command consists of a +\*QC-a\*U followed by one other character. +For your convenience, all commands that are bound to lower-case letters are +also bound to their control character counterparts (with the exception +of \*QC-a a\*U; see below), thus, \*QC-a c\*U as well as \*QC-a C-c\*U can +be used to create a window. See section \*QCUSTOMIZATION\*U for a description +of the command. +.PP +.TP 26n +The following table shows the default key bindings: +.IP "\fBC-a '\fP" +.PD 0 +.IP "\fBC-a ""\fP (select)" +.PD +Prompt for a window name or number to switch to. +.IP "\fBC-a 0\fP (select 0)" +.PD 0 +.IP "\fB ... \fP ..." +.IP "\fBC-a 9\fP (select 9)" +.PD +Switch to window number 0 \- 9. +.IP "\fBC-a C-a\fP (other)" +Toggle to the window displayed previously. +Note that this binding defaults to the command character typed twice, +unless overridden; for instance, if you use the option \*Q\fB\-e]x\fP\*U, +this command becomes \*Q]]\*U, not \*Q]C-a\*U. +.IP "\fBC-a a\fP (meta)" +Send the command character (C-a) to window. See \fIescape\fP command. +.IP "\fBC-a A\fP (title)" +Allow the user to enter a name for the current window. +.IP "\fBC-a b\fP" +.PD 0 +.IP "\fBC-a C-b\fP (break)" +.PD +Send a break to window. +.IP "\fBC-a B\fP (pow_break)" +Reopen the terminal line and send a break. +.IP "\fBC-a c\fP" +.PD 0 +.IP "\fBC-a C-c\fP (screen)" +.PD +Create a new window with a shell and switch to that window. +.IP "\fBC-a C\fP (clear)" +Clear the screen. +.IP "\fBC-a d\fP" +.PD 0 +.IP "\fBC-a C-d\fP (detach)" +.PD +Detach +.I screen +from this terminal. +.IP "\fBC-a D D\fP (pow_detach)" +Detach and logout. +.IP "\fBC-a f\fP" +.PD 0 +.IP "\fBC-a C-f\fP (flow)" +.PD +Toggle flow \fIon\fP, \fIoff\fP or \fIauto\fP. +.IP "\fBC-a C-g\fP (vbell)" +Toggles +.I screen's +visual bell mode. +.IP "\fBC-a h\fP (hardcopy)" +.PD +Write a hardcopy of the current window to the file \*Qhardcopy.\fIn\fP\*U. +.IP "\fBC-a H\fP (log)" +Begins/ends logging of the current window to the file \*Qscreenlog.\fIn\fP\*U. +.IP "\fBC-a i\fP" +.PD 0 +.IP "\fBC-a C-i\fP (info)" +.PD +Show info about this window. +.IP "\fBC-a k\fP" +.PD 0 +.IP "\fBC-a C-k\fP (kill)" +.PD +Destroy current window. +.IP "\fBC-a l\fP" +.PD 0 +.IP "\fBC-a C-l\fP (redisplay)" +.PD +Fully refresh current window. +.IP "\fBC-a L\fP (login)" +Toggle this windows login slot. Available only if +.I screen +is configured to update the utmp database. +.IP "\fBC-a m\fP" +.PD 0 +.IP "\fBC-a C-m\fP (lastmsg)" +.PD +Repeat the last message displayed in the message line. +.IP "\fBC-a M\fP (monitor)" +Toggles monitoring of the current window. +.IP "\fBC-a space\fP" +.PD 0 +.IP "\fBC-a n\fP" +.IP "\fBC-a C-n\fP (next)" +.PD +Switch to the next window. +.IP "\fBC-a N\fP (number)" +Show the number (and title) of the current window. +.IP "\fBC-a backspace\fP" +.PD 0 +.IP "\fBC-a h\fP" +.IP "\fBC-a p\fP" +.IP "\fBC-a C-p\fP (prev)" +.PD +Switch to the previous window (opposite of \fBC-a n\fP). +.IP "\fBC-a q\fP" +.PD 0 +.IP "\fBC-a C-q\fP (xon)" +.PD +Send a control-q to the current window. +.IP "\fBC-a r\fP" +.PD 0 +.IP "\fBC-a C-r\fP (wrap)" +.PD +Toggle the current window's line-wrap setting (turn the current window's +automatic margins on and off). +.IP "\fBC-a s\fP" +.PD 0 +.IP "\fBC-a C-s\fP (xoff)" +.PD +Send a control-s to the current window. +.IP "\fBC-a t\fP" +.PD 0 +.IP "\fBC-a C-t\fP (time)" +.PD +Show system information. +.IP "\fBC-a v\fP (version)" +.PD +Display the version and compilation date. +.IP "\fBC-a C-v\fP (digraph)" +.PD +Enter digraph. +.IP "\fBC-a w\fP" +.PD 0 +.IP "\fBC-a C-w\fP (windows)" +.PD +Show a list of window. +.IP "\fBC-a W\fP (width)" +Toggle 80/132 columns. +.IP "\fBC-a x\fP" +.PD 0 +.IP "\fBC-a C-x\fP (lockscreen)" +.PD +Lock this terminal. +.IP "\fBC-a z\fP" +.PD 0 +.IP "\fBC-a C-z\fP (suspend)" +.PD +Suspend +.IR screen . +Your system must support BSD-style job-control. +.IP "\fBC-a Z\fP (reset)" +Reset the virtual terminal to its \*Qpower-on\*U values. +.IP "\fBC-a .\fP (dumptermcap)" +Write out a \*Q.termcap\*U file. +.IP "\fBC-a ?\fP (help)" +Show key bindings. +.IP "\fBC-a C-\e\fP (quit)" +Kill all windows and terminate +.IR screen . +.IP "\fBC-a :\fP (colon)" +Enter command line mode. +.IP "\fBC-a [\fP" +.PD 0 +.IP "\fBC-a C-[\fP" +.IP "\fBC-a esc\fP (copy)" +.PD +Enter copy/scrollback mode. +.IP "\fBC-a ]\fP (paste .)" +.PD +Write the contents of the paste buffer to the stdin queue of the +current window. +.IP "\fBC-a {\fP +.PD 0 +.IP "\fBC-a }\fP (history)" +.PD +Copy and paste a previous (command) line. +.IP "\fBC-a >\fP (writebuf)" +Write paste buffer to a file. +.IP "\fBC-a <\fP (readbuf)" +Reads the screen-exchange file into the paste buffer. +.IP "\fBC-a =\fP (removebuf)" +Removes the file used by \fBC-a <\fP and \fPC-a >\fP. +.IP "\fBC-a ,\fP (license)" +Shows where +.I screen +comes from, where it went to and why you can use it. +.IP "\fBC-a _\fP (silence)" +Start/stop monitoring the current window for inactivity. + + +.SH CUSTOMIZATION +The \*Qsocket directory\*U defaults either to $HOME/.screen or simply to +/tmp/screens or preferably to /usr/local/screens chosen at compile-time. If +.I screen +is installed setuid-root, then the administrator +should compile +.I screen +with an adequate (not NFS mounted) socket directory. If +.I screen +is not running setuid-root, the user can specify any mode 777 directory +in the environment variable $SCREENDIR. +.PP +When +.I screen +is invoked, it executes initialization commands from the files +\*Q/usr/local/etc/screenrc\*U and +\*Q.screenrc\*U in the user's home directory. These are the \*Qprogrammer's +defaults\*U that can be overridden in the following ways: for the +global screenrc file +.I screen +searches for the environment variable $SYSSCREENRC (this override feature +may be disabled at compile-time). The user specific +screenrc file is searched in $ISCREENRC, then $SCREENRC, then $HOME/.iscreenrc +and finally defaults to $HOME/.screenrc. The command line option \fB-c\fP takes +precedence over the above user screenrc files. +.PP +Commands in these files are used to set options, bind functions to +keys, and to automatically establish one or more windows at the +beginning of your +.I screen +session. +Commands are listed one per line, with empty lines being ignored. +A command's arguments are separated by tabs or spaces, and may be +surrounded by single or double quotes. +A `#' turns the rest of the line into a comment, except in quotes. +Unintelligible lines are warned about and ignored. +Commands may contain references to environment variables. The +syntax is the shell-like "$VAR " or "${VAR}". Note that this causes +incompatibility with previous +.I screen +versions, as now the '$'-character has to be protected with '\e' if no +variable substitution shall be performed. A string in single-quotes is also +protected from variable substitution. +.PP +Customization can also be done 'on-line'. To enter the command mode type +`C-a :'. Note that commands starting with \*Qdef\*U change default values, +while others change current settings. +.PP +The following commands are available: +.sp +.ne 3 +.BI acladd " usernames" +.PP +Enable users to fully access this screen session. \fIUsernames\fP can be one +user or a comma seperated list of users. This command enables to attach to the +.I screen +session and performs the equivalent of `aclchg \fIusernames\fP +rwx \&"#?\&"'. +executed. To add a user with restricted access, use the `aclchg' command below. +Multi user mode only. +.sp +.ne 3 +.BI aclchg " usernames permbits list" +.PP +Change permissions for a comma seperated list of users. Permission bits are +represented as `r', `w' and `x'. Prefixing `+' grants the permission, `-' +removes it. The third parameter is a comma seperated list of commands and/or +windows (specified either by number or title). The special list `#' refers to +all windows, `?' to all commands. if \fIusernames\fP consists of a single `*', +all known users are affected. +A command can be executed when the user has the `x' bit for it. +The user can type input to a window when he has its `w' bit set and no other +user obtains a writelock for this window. +Other bits are currently ignored. +To withdraw the writelock from another user in window 2: +`aclchg \fIusername\fP -w+w 2'. +To allow readonly access to the session: `aclchg \fIusername\fP +-w \&"#\&"'. As soon as a user's name is known to +.I screen +he can attach to the session and (per default) has full permissions for all +command and windows. Execution permission for the acl commands, `at' and others +should also be removed or the user may be able to regain write permission. +Multi user mode only. +.sp +.ne 3 +.BI acldel " username" +.PP +Remove a user from +.IR screen 's +access control list. If currently attached, all the +user's displays are detached from the session. He cannot attach again. +Multi user mode only. +.sp +.ne 3 +.BI activity " message" +.PP +When any activity occurs in a background window that is being monitored, +.I screen +displays a notification in the message line. +The notification message can be re-defined by means of the \*Qactivity\*U +command. +Each occurrence of `%' in \fImessage\fP is replaced by +the number of the window in which activity has occurred, +and each occurrence of `~' is replaced by the definition for bell +in your termcap (usually an audible bell). +The default message is +.sp + 'Activity in window %' +.sp +Note that monitoring is off for all windows by default, but can be altered +by use of the \*Qmonitor\*U command (C-a M). +.sp +.ne 3 +.BR "allpartial on" | off +.PP +If set to on, only the current cursor line is refreshed on window change. +This affects all windows and is useful for slow terminal lines. The +previous setting of full/partial refresh for each window is restored +with \*Qallpartial off\*U. This is a global flag that immediately takes effect +on all windows overriding the \*Qpartial\*U settings. It does not change the +default redraw behaviour of newly created windows. +.sp +.ne 3 +.BR "at " "[\fIidentifier\fP][" "#\fP|\fP*\fP|\fP%\fP] " +.IR "command " [ args " ... ]" +.PP +Execute a command at other displays or windows as if it had been entered there. +\*QAt\*U changes the context (the `current window' or `current display' +setting) of the command. If the first parameter describes a +non-unique context, the command will be executed multiple times. If the first +parameter is of the form `\fIidentifier\fP*' then identifier is matched against +user names. The command is executed once for each display of the selected +user(s). If the first parameter is of the form `\fIidentifier\fP%' identifier +is matched against displays. Displays are named after the ttys they +attach. The prefix `/dev/' or `/dev/tty' may be omitted from the identifier. +If \fIidentifier\fP has a `#' or nothing appended it is matched against +window numbers and titles. Omitting an identifier in front of the `#', `*' or +`%'-character selects all users, displays or windows because a prefix-match is +performed. Note that on the affected display(s) a short message will describe +what happened. Caution: Permission is checked for the owners or the +affected display(s), not for the initiator of the `at' command. +.sp +.ne 3 +.BR "autodetach on" | off +.PP +Sets whether +.I screen +will automatically detach upon hangup, which +saves all your running programs until they are resumed with a +.B "screen -r" +command. +When turned off, a hangup signal will terminate +.I screen +and all the processes it contains. Autodetach is on by default. +.sp +.ne 3 +.BR "autonuke on" | off +.PP +Sets whether a clear screen sequence should nuke all the output +that has not been written to the terminal. See also +\*Qobuflimit\*U. +.sp +.ne 3 +.BI "bell " message +.PP +When a bell character is sent to a background window, +.I screen +displays a notification in the message line. +The notification message can be re-defined by means of the \*Qbell\*U +command. +Each occurrence of `%' in \fImessage\fP is replaced by +the number of the window to which a bell has been sent, +and each occurrence of `~' is replaced by the definition for bell +in your termcap (usually an audible bell). +The default message is +.sp + 'Bell in window %' +.sp +An empty message can be supplied to the \*Qbell\*U command to suppress +output of a message line (bell ""). +.sp +.ne 3 +.BI "bind " key +.RI [ command " [" args ]] +.PP +Bind a command to a key. +By default, most of the commands provided by +.I screen +are bound to one or more keys as indicated in the \*QDEFAULT KEY BINDINGS\*U +section, e.\|g. the +command to create a new window is bound to \*QC-c\*U and \*Qc\*U. +The \*Qbind\*U command can be used to redefine the key bindings and to +define new bindings. +The \fIkey\fP argument is either a single character, a two-character sequence +of the form \*Q^x\*U (meaning \*QC-x\*U), a backslash followed by an octal +number (specifying the ASCII code of the character), or a backslash followed +by a second character, such as \*Q\e^\*U or \*Q\e\e\*U. +The argument can also be quoted, if you like. +If no further argument is given, any previously established binding +for this key is removed. +The \fIcommand\fP argument can be any command listed in this section. +.PP +Some examples: +.PP +.nf + bind ' ' windows + bind ^f screen telnet foobar + bind \e033 screen -ln -t root -h 1000 9 su +.fi +.PP +would bind the space key to the command that displays a list +of windows (so that the command usually invoked by \*QC-a C-w\*U +would also be available as \*QC-a space\*U), +bind \*QC-f\*U to the command \*Qcreate a window with a TELNET +connection to foobar\*U, and bind \*Qescape\*U to the command +that creates an non-login window with a.\|k.\|a. \*Qroot\*U in slot #9, with +a super-user shell and a scrollback buffer of 1000 lines. +.sp +.ne 3 +.B bindkey +.RB [ -d ] +.RB [ -m ] +.RB [ -a ] +.RB [[ -k | -t ] +.I string +.RI [ "cmd args" ]] +.PP +This command manages screen's input translation tables. Every +entry in one of the tables tells screen how to react if a certain +sequence of characters is encountered. There are three tables: +one that should contain actions programmed by the user, one for +the default actions used for terminal emulation and one for +screen's copy mode to do cursor movement. See section +\*QINPUT TRANSLATION\*U for a list of default key bindings. +.br +If the +.B -d +option is given, bindkey modifies the default table, +.B -m +changes the copy mode table +and with neither option the user table is selected. +The argument +.I string +is the sequence of characters to which an action is bound. This +can either be a fixed string or a termcap keyboard capability +name (selectable with the +.B -k +option). +.br +Some keys on a VT100 terminal can send a different +string if application mode is turned on (e.g the cursor keys). +Such keys have two entries in the translation table. You can +select the application mode entry by specifying the +.B -a +option. +.br +The +.B -t +option tells screen not to do intercharacter timing. One cannot +turn off the timing if a termcap capabilty is used. +.br +.I Cmd +can be any of screen's commands with an arbitrary number of +.IR args . +If +.I cmd +is omitted the keybinding is removed from the table. +.br +Here are some examples of keyboard bindings: +.sp +.nf + bindkey -d +.fi +Show all of the default key bindings. The application mode entries +are marked with [A]. +.sp +.nf + bindkey -k k1 select 1 +.fi +Make the "F1" key switch to window one. +.sp +.nf + bindkey -t foo stuff barfoo +.fi +Make "foo" an abrevation of the word "barfoo". Timeout is disabled +so that users can type slowly. +.sp +.nf + bindkey "\e024" mapdefault +.fi +This keybinding makes \*Q^T\*U an escape character for keybindings. If +you did the above \*Qstuff barfoo\*U binding, you can enter the word +\*Qfoo\*U by typing \*Q^Tfoo\*U. If you want to insert a \*Q^T\*U +you have to press the key twice (i.e. escape the escape binding). +.sp +.nf + bindkey -k F1 command +.fi +Make the F11 (not F1!) key an alternative screen +escape (besides ^A). +.sp +.ne 3 +.B break +.RI [ duration ] +.PP +Send a break signal for \fIduration\fP*0.25 seconds to this window. +Most useful if a character device is +attached to the window rather than a shell process. +.sp +.ne 3 +.B bufferfile +.RI [ exchange-file ] +.PP +Change the filename used for reading and writing with the paste buffer. +If the optional argument to the \*Qbufferfile\*U command is omitted, +the default setting (\*Q/tmp/screen-exchange\*U) is reactivated. +The following example will paste the system's password file into +the +.I screen +window (using the paste buffer, where a copy remains): +.PP +.nf + C-a : bufferfile /etc/passwd + C-a < C-a ] + C-a : bufferfile +.fi +.sp +.ne 3 +.BR "c1 " [ on | off ] +.PP +Change c1 code processing. \*QC1 on\*U tells screen to treat +the input characters between 128 and 159 as control functions. +Such an 8-bit code is normally the same as ESC followed by the +corresponding 7-bit code. The default setting is to process c1 +codes and can be changed with the \*Qdefc1\*U command. +Users with fonts that have usable characters in the +c1 positions may want to turn this off. +.sp +.ne 3 +.BI "charset " set +.PP +Change the current character set slot designation and charset +mapping. The first four character of +.I set +are treated as charset designators while the fifth and sixth +character must be in range '0' to '3' and set the GL/GR charset +mapping. On every position a '.' may be used to indicate that +the corresponding charset/mapping should not be changed +(\fIset\fP is padded to six characters internally by appending '.' +chars). New windows have "BBBB02" as default charset, unless a +\*Qkanji\*U command is active. +.br +The current setting can be viewed with the \*Qinfo\*U command. +.sp +.ne 3 +.B chdir +.RI [ directory ] +.PP +Change the \fIcurrent directory\fP of +.I screen +to the specified directory or, if called without an argument, +to your home directory (the value of the environment variable $HOME). +All windows that are created by means of the \*Qscreen\*U command +from within \*Q.screenrc\*U or by means of \*QC-a : screen ...\*U +or \*QC-a c\*U use this as their default directory. +Without a chdir command, this would be the directory from which +.I screen +was invoked. +Hardcopy and log files are always written to the \fIwindow's\fP default +directory, \fInot\fP the current directory of the process running in the +window. +You can use this command multiple times in your .screenrc to start various +windows in different default directories, but the last chdir value will +affect all the windows you create interactively. +.sp +.ne 3 +.B clear +.PP +Clears the current window and saves its image to the scrollback buffer. +.sp +.ne 3 +.B colon +.PP +Allows you to enter \*Q.screenrc\*U command lines. Useful +for on-the-fly modification of key bindings, +specific window creation and changing settings. Note that the \*Qset\*U +keyword no longer exists! Usually commands affect the current window rather +than default settings for future windows. Change defaults with commands +starting with 'def...'. + +If you consider this as the `Ex command mode' of +.IR screen , +you may regard \*QC-a esc\*U (copy mode) as its `Vi command mode'. +.sp +.ne 3 +.B command +.PP +This command has the same effect as typing the screen escape +character (^A). It is probably only useful for key bindings. +See also \*Qbindkey\*U. +.sp +.ne 3 +.BR "console " [ on | off ] +.PP +Grabs or ungrabs the machines console output to a window. +.sp +.ne 3 +.B copy +.PP +Enter copy/scrollback mode. This allows you to copy text from the current +window and its history into the paste buffer. In this mode a vi-like +`full screen editor' is active: +.br +.IR "Movement keys" : +.br +.in +4n +.ti -2n +\fBh\fP, \fBj\fP, \fBk\fP, \fBl\fP move the cursor line by line or +column by column. +.br +.ti -2n +\fB0\fP, \fB^\fP and \fB$\fP move to the leftmost column, to the first or last +non-whitespace character on the line. +.br +.ti -2n +\fBH\fP, \fBM\fP and \fBL\fP move the cursor to the leftmost column +of the top, center or bottom line of the window. +.br +.ti -2n +\fB+\fP and \fB\-\fP positions one line up and down. +.br +.ti -2n +\fBG\fP moves to the specified absolute line (default: end of buffer). +.br +.ti -2n +\fB|\fP moves to the specified absolute column. +.br +.ti -2n +\fBw\fP, \fBb\fP, \fBe\fP move the cursor word by word. +.br +.ti -2n +\fBC-u\fP and \fBC-d\fP scroll the display up/down by the specified amount of +lines while preserving the cursor position. (Default: half screen-full). +.br +.ti -2n +\fBC-b\fP and \fBC-f\fP scroll the display up/down a full screen. +.br +.ti -2n +\fBg\fP moves to the beginning of the buffer. +.br +.ti -2n +\fB%\fP jumps to the specified percentage of the buffer. +.br +.ti -4n + +.IR Note : +.br +Emacs style movement keys can be customized by a .screenrc command. +(E.\|g. markkeys "h=^B:l=^F:$=^E") There is no simple method for a full +emacs-style keymap, as this involves multi-character codes. + +.br +.ti -4n +.IR Marking : +.br +The copy range is specified by setting two marks. The text between these marks +will be highlighted. Press +.br +.ti -2n +\fBspace\fP to set the first or second mark +respectively. +.br +.ti -2n +\fBY\fP and \fBy\fP used to mark one whole line or to mark from +start of line. +.br +.ti -2n +\fBW\fP marks exactly one word. +.br +.ti -4n +.IR "Repeat count" : +.br +Any of these commands can be prefixed with a repeat count number by pressing +digits +.br +.ti -2n +\fB0\fP..\fB9\fP which +is taken as a repeat count. +.br +Example: \*QC-a C-[ H 10 j 5 Y\*U will copy lines +11 to 15 into the paste buffer. +.br +.ti -4n +.IR Searching : +.ti -2n +\fB/\fP \fIVi\fP-like search forward. +.ti -2n +\fB?\fP \fIVi\fP-like search backward. +.ti -2n +\fBC-a s\fP \fIEmacs\fP style incremental search forward. +.ti -2n +\fBC-r\fP \fIEmacs\fP style reverse i-search. +.ti -4n +.IR Specials : +.br +There are however some keys that act differently than in +.IR vi . +.I Vi +does not allow one to yank rectangular blocks of text, but +.I screen +does. Press +.br +.ti -2n +\fBc\fP or \fBC\fP to set the left or right margin respectively. If no repeat count is +given, both default to the current cursor position. +.br +Example: Try this on a rather full text screen: +\*QC-a [ M 20 l SPACE c 10 l 5 j C SPACE\*U. + +This moves one to the middle line of the screen, moves in 20 columns left, +marks the beginning of the paste buffer, sets the left column, moves 5 columns +down, sets the right column, and then marks the end of +the paste buffer. Now try: +.br +\*QC-a [ M 20 l SPACE 10 l 5 j SPACE\*U + +and notice the difference in the amount of text copied. +.br +.ti -2n +\fBJ\fP joins lines. It toggles between +3 modes: lines separated by a newline character (012), lines glued seamless, +lines separated by a single whitespace. Note that you can prepend the newline +character with a carriage return character, by issuing a \*Qcrlf on\*U. +.br +.ti -2n +\fBv\fP is for all the +.I vi +users with \*Q:set numbers\*U \- it toggles the left margin between column 9 +and 1. Press +.br +.ti -2n +\fBa\fP before the final space key to toggle in append mode. Thus +the contents of the paste buffer will not be overwritten, but is appended to. +.br +.ti -2n +\fBA\fP toggles in append mode and sets a (second) mark. +.br +.ti -2n +\fB>\fP sets the (second) mark and writes the contents of the paste buffer to +the screen-exchange file (/tmp/screen-exchange per default) once copy-mode is +finished. +.br +This example demonstrates how to dump the whole scrollback buffer +to that file: \*QC-A [ g SPACE G $ >\*U. +.br +.ti -2n +\fBC-g\fP gives information about the current line and column. +.br +.ti -2n +\fBx\fP exchanges the first mark and the current cursor position. You +can use this to adjust an already placed mark. +.br +.ti -2n +\fB@\fP does nothing. Does not even exit copy mode. +.br +.ti -2n +All keys not described here exit copy mode. +.in -4n +.sp +.ne 3 +.B copy_reg +.RI [ key ] +.PP +No longer exists, use \*Qreadreg\*U instead. +.sp +.ne 3 +.BR "crlf on" | off +.PP +This affects the copying of text regions with the `C-a [' command. If it is set +to `on', lines will be separated by the two character sequence `CR' - `LF'. +Otherwise (default) only `LF' is used. +.sp +.ne 3 +.BR "debug on" | off +.PP +Turns runtime debugging on or off. If +.I screen +has been compiled with option -DDEBUG debugging available and is turned on per +default. Note that this command only affects debugging output from the main +\*QSCREEN\*U process. +.sp +.ne 3 +.BR "defc1 on" | off +.PP +Same as the \fBc1\fP command except that the default setting for new +windows is changed. Initial setting is `on'. +.sp +.ne 3 +.BR "defautonuke on" | off +.PP +Same as the \fBautonuke\fP command except that the default setting for new displays is changed. Initial setting is `off'. +Note that you can use the special `AN' terminal capability if you +want to have a dependency on the terminal type. +.sp +.ne 3 +.BR "defcharset " [ \fIset ] +.PP +Like the \fBcharset\fP command except that the default setting for +new windows is changed. Shows current default if called without +argument. +.sp +.ne 3 +.BI "defescape " xy +.PP +Set the default command characters. This is equivalent to the +\*Qescape\*U except that it is useful multiuser sessions only. In a +multiuser session \*Qescape\*U changes the command character of the +calling user, where \*Qdefescape\*U changes the default command +characters for users that will be added later. +.sp +.ne 3 +.BR "defflow on" | off | auto +.RB [ interrupt ] +.PP +Same as the \fBflow\fP command except that the default setting for new windows +is changed. Initial setting is `auto'. +Specifying \*Qdefflow auto interrupt\*U is the same as the command-line options +.B \-fa +and +.BR \-i . +.sp +.ne 3 +.BR "defgr on" | off +.PP +Same as the \fBgr\fP command except that the default setting for new +windows is changed. Initial setting is `off'. +.sp +.ne 3 +.BR "defhstatus " [ \fIstatus ] +.PP +The hardstatus line that all new windows will get is set to +.I status\fR. +This command is useful to make the hardstatus of every window +display the window number or title or the like. +.I Status +may contain the same directives as in the window messages, but +the directive escape character is '^E' (octal 005) instead of '%'. +This was done to make a misinterpretion of program generated +hardstatus lines impossible. +If the parameter +.I status +is omitted, the current default string is displayed. +Per default the hardstatus line of new windows is empty. +.sp +.ne 3 +.BR "defkanji jis" | sjis | euc +.PP +Same as the \fBkanji\fP command except that the default setting for new +windows is changed. Initial setting is `off', i.e. `jis'. +.sp +.ne 3 +.BR "deflogin on" | off +.PP +Same as the \fBlogin\fP command except that the default setting for new windows +is changed. This is initialized with `on' as distributed (see config.h.in). +.sp +.ne 3 +.BI "defmode " mode +.PP +The mode of each newly allocated pseudo-tty is set to \fImode\fP. +\fIMode\fP is an octal number. +When no \*Qdefmode\*U command is given, mode 0622 is used. +.sp +.ne 3 +.BR "defmonitor on" | off +.PP +Same as the \fBmonitor\fP command except that the default setting for new +windows is changed. Initial setting is `off'. +.sp +.ne 3 +.BI "defobuflimit " limit +.PP +Same as the \fBobuflimit\fP command except that the default setting for new displays is changed. Initial setting is 256 bytes. +Note that you can use the special 'OL' terminal capability if you +want to have a dependency on the terminal type. +.sp +.ne 3 +.BI "defscrollback " num +.PP +Same as the \fBscrollback\fP command except that the default setting for new +windows is changed. Initial setting is 100. +.sp +.ne 3 +.BR "defwrap on" | off +.PP +Same as the \fBwrap\fP command except that the default setting for new +windows is changed. Initially line-wrap is on and can be toggled with the +\*Qwrap\*U command (\*QC-a r\*U) or by means of "C-a : wrap on|off". +.sp +.ne 3 +.BR "defwritelock on" | off | auto +.PP +Same as the \fBwritelock\fP command except that the default setting for new +windows is changed. Initially writelocks will operate in automatic mode. +.sp +.ne 3 +.BR "defzombie " [\fIkeys\fP] +.PP +Synonym to the \fBzombie\fP command. Both currently change the default. +See there. +.sp +.ne 3 +.B detach +.PP +Detach the +.I screen +session (disconnect it from the terminal and put it into the background). +This returns you to the shell where you invoked +.IR screen . +A detached +.I screen +can be resumed by invoking +.I screen +with the +.B \-r +option. (See also section \*QCOMMAND-LINE OPTIONS\*U.) +.sp +.ne 3 +.BR "digraph " [ \fIpreset ] +.PP +This command prompts the user for a digraph sequence. The next +two characters typed are looked up in a builtin table and the +resulting character is inserted in the input stream. For example, +if the user enters 'a"', an a-umlaut will be inserted. If the +first character entered is a 0 (zero), +.I screen +will treat the following charcters (up to three) as an octal +number instead. The optional argument +.I preset +is treated as user input, thus one can create an \*Qumlaut\*U key. +For example the command "bindkey ^K digraph '"'" enables the user +to generate an a-umlaut by typing CTRL-K a. +.sp +.ne 3 +.B dumptermcap +.PP +Write the termcap entry for the virtual terminal optimized for the currently +active window to the file \*Q.termcap\*U in the user's +\*Q$HOME/.screen\*U directory (or wherever +.I screen +stores its sockets. See the \*QFILES\*U section below). +This termcap entry is identical to the value of the environment variable +$TERMCAP that is set up by +.I screen +for each window. For terminfo based systems you will need to run a converter +like +.IR captoinfo +and then compile the entry with +.IR tic . +.sp +.ne 3 +.BR "echo " [ -n ] +.I message +.PP +The echo command may be used to annoy +.I screen +users with a 'message of the +day'. Typically installed in a global /local/etc/screenrc. See also +\*Qsleep\*U. +Echo is also useful for online checking of environment variables. +.sp +.ne 3 +.BI "escape " xy +.PP +Set the command character to \fIx\fP and the character generating a literal +command character to \fIy\fP (just like in the \-e option). +Each argument is either a single character, a two-character sequence +of the form \*Q^x\*U (meaning \*QC-x\*U), a backslash followed by an octal +number (specifying the ASCII code of the character), or a backslash followed +by a second character, such as \*Q\e^\*U or \*Q\e\e\*U. +The default is \*Q^Aa\*U. +.sp +.ne 3 +.B exec +.RI [[ fdpat ] +.IR "newcommand " [ "args ..." ]] +.PP +Run a subprocess (newcommand) in the current window. The flow of data between +newcommand's stdin/stdout/stderr, the process already running (shell) and +screen itself (window) is controlled by the filedescriptor pattern fdpat. +This pattern is basically a three character sequence representing stdin, stdout +and stderr of newcommand. A dot (.) connects the file descriptor +to +.IR screen . +An exclamation mark (!) causes the file +descriptor to be connected to the already running process. A colon (:) combines +both. +User input will go to newcommand unless newcommand requests the old process' +output (fdpats first character is `!' or `:') or a pipe (|) is added to +the end of fdpat. +.br +Invoking `exec' without arguments shows name and arguments of the currently +running subprocess in this window. +.br +When a subprocess is running the `kill' command will affect it instead of the +windows process. +.br +Refer to the postscript file `fdpat.ips' for a confusing illustration +of all 21 possible combinations. Each drawing shows the digits 2,1,0 +representing the three file descriptors of newcommand. The box marked +`W' is usual pty that has the application-process on its slave side. +The box marked `P' is the secondary pty that now has +.I screen +at its master side. +.sp +Abbreviations: +.br +Whitespace between the word `exec' and fdpat and the command +can be omitted. Trailing dots and a fdpat consisting only of dots can be +omitted. A simple `|' is synonymous for the pattern `!..|'; the word exec can +be omitted here and can always be replaced by `!'. +.sp +Examples: +.IP +exec ... /bin/sh +.br +exec /bin/sh +.br +!/bin/sh +.PP +Creates another shell in the same window, while the original shell is still +running. Output of both shells is displayed and user input is sent to the new +/bin/sh. +.IP +exec !.. stty 19200 +.br +exec ! stty 19200 +.br +!!stty 19200 +.PP +Set the speed of the window's tty. If your stty command operates on stdout, then +add another `!'. +.IP +exec !..| less +.br +|less +.PP +This adds a pager to the window output. The special character `|' is needed to +give the user control over the pager although it gets its input from the +window's process. This works, because +.I less +listens on stderr (a behavior that +.I screen +would not expect without the `|') +when its stdin is not a tty. +.I Less +versions newer than 177 fail miserably here; good old +.I pg +still works. +.IP +!:sed -n s/.*Error.*/\e007/p +.PP +Sends window output to both, the user and the sed command. The sed inserts an +additional bell character (oct. 007) to the window output seen by +.IR screen . +This will cause "Bell in window x" messages, whenever the string "Error" +appears in the window. +.sp +.ne 3 +.B flow +.RB [ on | off | "auto\fR]\fP" +.PP +Sets the flow-control mode for this window. +Without parameters it cycles the current window's flow-control setting from +"automatic" to "on" to "off". +See the discussion on \*QFLOW-CONTROL\*U later on in this document for full +details and note, that this is subject to change in future releases. +Default is set by `defflow'. +.sp +.ne 3 +.BR "gr " [ on | off ] +.PP +Turn GR charset switching on/off. Whenever screens sees an input +char with an 8th bit set, it will use the charset stored in the +GR slot and print the character with the 8th bit stripped. The +default (see also \*Qdefgr\*U) is not to process GR switching because +otherwise the ISO88591 charset would not work. +.sp +.ne 3 +.B hardcopy +.PP +Writes out the currently displayed image to a file \fIhardcopy.n\fP +in the window's default directory, where \fIn\fP is the number +of the current window. +This either appends or overwrites the file if it exists. See below. +.sp +.ne 3 +.BR "hardcopy_append on" | off +.PP +If set to "on", +.I screen +will append to the "hardcopy.n" files created by the command \*QC-a h\*U, +otherwise these files are overwritten each time. +Default is `off'. +.sp +.ne 3 +.BI "hardcopydir "directory +.PP +Defines a directory where hardcopy files will be placed. If unset, hardcopys +are dumped in +.IR screen 's +current working directory. +.sp +.ne 3 +.BR "hardstatus " [ on | off ] +.PP +Toggles the use of the terminal's hardware status line. If "on", +.I screen +will use this facility to display one line messages. Otherwise these messages +are overlayed in reverse video mode at the display line. Note that the +hardstatus feature can only be used if the termcap/terminfo capabilities +"hs", "ts", "fs" and "ds" are set properly. Default is `on' whenever the "hs" +capability is present. +.sp +.ne 3 +.BR "height " [ \fIlines\fP ] +.PP +Set the display height to a specified number of lines. When no argument +is given it toggles between 24 and 42 lines display. +.sp +.ne 3 +.B help +.PP +Not really a online help, but +displays a help screen showing you all the key bindings. +The first pages list all the internal commands followed by their current +bindings. +Subsequent pages will display the custom commands, one command per key. +Press space when you're done reading each page, or return to exit early. +All other characters are ignored. +See also \*QDEFAULT KEY BINDINGS\*U section. +.sp +.ne 3 +.B history +.PP +Usually users work with a shell that allows easy access to previous commands. +For example csh has the command \*Q!!\*U to repeat the last command executed. +.I Screen +allows you to have a primitive way of re-calling \*Qthe command that +started ...\*U: You just type the first letter of that command, then hit +`C-a {' and +.I screen +tries to find a previous line that matches with the `prompt character' +to the left of the cursor. This line is pasted into this window's input queue. +Thus you have a crude command history (made up by the visible window and its +scrollback buffer). +.sp +.ne 3 +.B info +.PP +Uses the message line to display some information about the current window: +the cursor position in the form \*Q(column,row)\*U starting with \*Q(1,1)\*U, +the terminal width and height plus the size of the scrollback buffer in lines, +like in \*U(80,24)+50\*U, various flag settings (flow-control, insert mode, +origin mode, wrap mode, application-keypad mode, output logging, activity +monitoring and redraw (`+' indicates enabled, `\-' not)), +the currently active character set (\fIG0\fP, \fIG1\fP, \fIG2\fP, +or \fIG3\fP), and in square brackets the terminal character sets that are +currently designated as \fIG0\fP through \fIG3\fP. +For system information use the \*Qtime\*U command. +.sp +.ne 3 +.BR ins_reg " [" \fIkey ] +.PP +No longer exists, use \*Qpaste\*U instead. +.sp +.ne 3 +.B kanji +.BR jis | euc | sjis +.RB [ jis | euc | sjis\fR] +.PP +Tell screen how to process kanji input/output. The first argument +sets the kanji type of the current window. Each window can emulate +a different type. The optional second parameter tells screen +how to write the kanji codes to the connected terminal. The preferred +method of setting the display type is to use the \*QKJ\*U termcap +entry. +See also \*Qdefkanji\*U, which changes the default setting of a new +window. +.sp +.ne 3 +.B kill +.PP +Kill current window. +.br +If there is an `exec' command running then it is killed. Otherwise the process +(shell) running in the window receives a HANGUP condition, the window structure +is removed and +.I screen +switches to the previously displayed window. +When the last window is destroyed, +.I screen +exits. +Note: +.I Emacs +users should keep this command in mind, when killing a line. +It is recommended not to use \*QC-a\*U as the +.I screen +escape key or to rebind kill to \*QC-a K\*U. +.sp +.ne 3 +.B lastmsg +.PP +Redisplay the last contents of the message/status line. +Useful if you're typing when a message appears, because the message goes +away when you press a key (unless your terminal has a hardware status line). +Refer to the commands \*Qmsgwait\*U and \*Qmsgminwait\*U for fine tuning. +.sp +.ne 3 +.B license +.PP +Display the disclaimer page. This is done whenever +.I screen +is started without options, which should be often enough. See also +the \*Qstartup_message\*U command. +.sp +.ne 3 +.B lockscreen +.PP +Lock this display. +Call a screenlock program (/local/bin/lck or /usr/bin/lock or a builtin if no +other is available). Screen does not accept any command keys until this program +terminates. Meanwhile processes in the windows may continue, as the windows +are in the `detached' state. The screenlock program may be changed through the +environment variable $LOCKPRG (which must be set in the shell from which +.I screen +is started) and is executed with the user's uid and gid. +.sp +.ne 3 +.BR "log " [ on | off ] +.PP +Start/stop writing output of the current window to a file +\*Qscreenlog.\fIn\fP\*U in the window's default directory, where \fIn\fP +is the number of the current window. This filename can be changed with +the `logfile' command. If no parameter is given, the state +of logging is toggled. The session log is appended to the previous contents +of the file if it already exists. The current contents and the contents +of the scrollback history are not included in the session log. +Default is `off'. +.sp +.ne 3 +.BI "logfile " filename +.PP +Defines the name the logfiles will get. The default is +\*Qscreenlog.%n\*U. +.sp +.ne 3 +.BR "login " [ on | off ] +.PP +Adds or removes the entry in the utmp database file for the current window. +This controls if the window is `logged in'. +When no parameter is given, the login state of the window is toggled. +Additionally to that toggle, it is convenient having a `log in' and a `log out' +key. E.\|g. `bind I login on' and `bind O login off' will map these +keys to be C-a I and C-a O. +The default setting (in config.h.in) should be \*Qon\*U for a +.I screen +that runs under suid-root. +Use the \*Qdeflogin\*U command to change the default login state for new +windows. Both commands are only present when +.I screen +has been compiled with utmp support. +.sp +.ne 3 +.B mapdefault +.PP +Tell screen that the next input character should only be looked up +in the default bindkey table. See also \*Qbindkey\*U. +.sp +.ne 3 +.B mapnotnext +.PP +Like mapdefault, but don't even look in the default bindkey table. +.sp +.ne 3 +.B maptimeout +.RI [ timo ] +.PP +Set the intercharacter timer for input sequence detection to a timeout +of +.I timo +ms. The default timeout is 300ms. Maptimeout with no arguments shows +the current setting. +See also \*Qbindkey\*U. +.sp +.ne 3 +.BI "markkeys " string +.PP +This is a method of changing the keymap used for copy/history mode. +The string is made up of \fIoldchar\fP=\fInewchar\fP pairs which are +separated by `:'. Example: The string \*QB=^B:F=^F\*U will change the +keys `C-b' and `C-f' to the vi style binding (scroll up/down fill page). +This happens to be the default binding for `B' and `F'. +The command \*Qmarkkeys h=^B:l=^F:$=^E\*U would set the mode for an emacs-style +binding. +.sp +.ne 3 +.B meta +.PP +Insert the command character (C-a) in the current window's input stream. +.sp +.ne 3 +.BR "monitor " [ on | off ] +.PP +Toggles activity monitoring of windows. +When monitoring is turned on and an affected window is switched into the +background, you will receive the activity notification message in the +status line at the first sign of output and the window will also be marked +with an `@' in the window-status display. +Monitoring is initially off for all windows. +.sp +.ne 3 +.BI "msgminwait " sec +.PP +Defines the time +.I screen +delays a new message when one message is currently displayed. +The default is 1 second. +.sp +.ne 3 +.BI "msgwait " sec +.PP +Defines the time a message is displayed if +.I screen +is not disturbed by other activity. The default is 5 seconds. +.sp +.ne 3 +.BR "multiuser on" | off +.PP +Switch between singleuser and multiuser mode. Standard +.I screen +operation is singleuser. In multiuser mode the commands `acladd', +`aclchg' and `acldel' +can be used to enable (and disable) other users accessing this screen. +.sp +.ne 3 +.BR "nethack on" | off +.PP +Changes the kind of error messages used by +.IR screen . +When you are familiar with the game \*Qnethack\*U, you may enjoy the +nethack-style messages which will often blur the facts a little, but are +much funnier to read. Anyway, standard messages often tend to be unclear as +well. +.br +This option is only +available if +.I screen +was compiled with the NETHACK flag defined. The +default setting is then determined by the presence of the environment +variable $NETHACKOPTIONS. +.sp +.ne 3 +.B next +.PP +Switch to the next window. +This command can be used repeatedly to cycle through the list of windows. +.sp +.ne 3 +.BR "number " [ \fIn ] +.PP +Change the current windows number. If the given number \fIn\fP is already +used by another window, both windows exchange their numbers. If no argument is +specified, the current window number (and title) is shown. +.sp +.ne 3 +.BR "obuflimit " [ \fIlimit ] +.PP +If the output buffer contains more bytes than the specified limit, no +more data will be +read from the windows. The default value is 256. If you have a fast +display (like xterm), you can set it to some higher value. If no +argument is specified, the current setting is displayed. +.sp +.ne 3 +.B other +.PP +Switch to the window displayed previously. +.sp +.ne 3 +.BR "partial on" | off +.PP +Defines whether the display should be refreshed (as with \fIredisplay\fP) after +switching to the current window. This command only affects the current window. +To immediately affect all windows use the \fIallpartial\fP command. +Default is `off', of course. This default is fixed, as there is currently no +\fIdefpartial\fP command. +.sp +.ne 3 +.BR "password " [ \fIcrypted_pw ] +.PP +Present a crypted password in your \*Q.screenrc\*U file and +.I screen +will ask +for it, whenever someone attempts to resume a detached. This is useful +if you have privileged programs running under +.I screen +and you want to protect your session from reattach attempts by another user +masquerading as your uid (i.e. any superuser.) +If no crypted password is specified, +.I screen +prompts twice for typing a +password and places its encryption in the paste buffer. +Default is `none', this disables password checking. +.sp +.ne 3 +.BR paste +.RI [ registers " [" dest_reg ]] +.PP +Write the (concatenated) contents of the specified registers to the stdin queue +of the current window. The register '.' is treated as the +paste buffer. If no parameter is given the user is prompted for a single +register to paste. +The paste buffer can be filled with the \fIcopy\fP, \fIhistory\fP and +\fIreadbuf\fP commands. +Other registers can be filled with the \fIregister\fP, \fIreadreg\fP and +\fIpaste\fP commands. +If \fIpaste\fP is called with a second argument, the contents of the specified +registers is pasted into the named destination register rather than +the window. If '.' is used as the second argument, the displays paste buffer is +the destination. +Note, that \*Qpaste\*U uses a wide variety of resources: Whenever a second +argument is specified no current window is needed. When the source specification +only contains registers (not the paste buffer) then there need not be a current +display (terminal attached), as the registers are a global resource. The +paste buffer exists once for every user. +.sp +.ne 3 +.BR "pastefont " [ on | off ] +.PP +Tell screen to include font information in the paste buffer. The +default is not to do so. This command is especially usefull for +multi character fonts like kanji. +.sp +.ne 3 +.B pow_break +.PP +Reopen the window's terminal line and send a break condition. See `break'. +.sp +.ne 3 +.B pow_detach +.PP +Power detach. +Mainly the same as \fIdetach\fP, but also sends a HANGUP signal to +the parent process of +.IR screen . +CAUTION: This will result in a logout, when +.I screen +was started from your login shell. +.sp +.ne 3 +.BI "pow_detach_msg " message +.PP +The \fImessage\fP specified here is output whenever a `Power detach' was +performed. It may be used as a replacement for a logout message or to reset +baud rate, etc. +.sp +.ne 3 +.B prev +.PP +Switch to the window with the next lower number. +This command can be used repeatedly to cycle through the list of windows. +.sp +.ne 3 +.B printcmd +.RI [ cmd ] +.PP +If +.I cmd +is not an empty string, screen will not use the terminal capabilities +\*Qpo/pf\*U if it detects an ansi print sequence +.BR "ESC [ 5 i" , +but pipe the output into +.IR cmd . +This should normally be a command like \*Qlpr\*U or +\*Q'cat > /tmp/scrprint'\*U. +.B printcmd +without a command displays the current setting. +The ansi sequence +.B "ESC \e" +ends printing and closes the pipe. +.br +Warning: Be careful with this command! If other user have write +access to your terminal, they will be able to fire off print commands. +.sp +.ne 3 +.BR process " [" \fIkey ] +.PP +Stuff the contents of the specified register into \fIscreen\fP's +input queue. If no argument is given you are prompted for a +register name. The text is parsed as if it had been typed in from the user's +keyboard. This command can be used to bind multiple actions to a single key. +.sp +.ne 3 +.B quit +.PP +Kill all windows and terminate +.IR screen . +Note that on VT100-style terminals the keys C-4 and C-\e are identical. +This makes the default bindings dangerous: +Be careful not to type C-a C-4 when selecting window no. 4. +Use the empty bind command (as in \*Qbind '^\e'\*U) to remove a key binding. +.sp +.ne 3 +.B readbuf +.PP +Reads the contents of the current screen-exchange file into the paste buffer. +See also \*Qbufferfile\*U command. +.sp +.ne 3 +.B readreg +.RI [ register " [" filename ]] +.PP +Does one of two things, dependent on number of arguments: with zero or one +arguments it it duplicates the paste buffer contents into the register specified +or entered at the prompt. With two arguments it reads the contents of the named +file into the register, just as \fIreadbuf\fP reads the screen-exchange file +into the paste buffer. +The following example will paste the system's password file into +the screen window (using register p, where a copy remains): +.PP +.nf + C-a : readreg p /etc/passwd + C-a : paste p +.fi +.sp +.ne 3 +.B redisplay +.PP +Redisplay the current window. Needed to get a full redisplay when in +partial redraw mode. +.sp +.ne 3 +.BI "register " "key string" +.PP +Save the specified \fIstring\fP to the register \fIkey\fP. See also the +\*Qpaste\*U command. +.sp +.ne 3 +.B "removebuf" +.PP +Unlinks the screen-exchange file used by the commands \*Qwritebuf\*U and +\*Qreadbuf\*U. +.sp +.ne 3 +.B "reset" +.PP +Reset the virtual terminal to its \*Qpower-on\*U values. Useful when strange +settings (like scroll regions or graphics character set) are left over from +an application. +.sp +.ne 3 +.B "screen \fP[\fI-opts\fP] [\fIn\fP] [\fIcmd\fP [\fIargs\fP]]" +.PP +Establish a new window. +The flow-control options (\fB\-f\fP, \fB\-fn\fP and \fB\-fa\fP), +title (a.\|k.\|a.) option (\fB\-t\fP), login options (\fB-l\fP and \fB-ln\fP) +, terminal type option (\fB-T \fP) and scrollback option (\fB-h\fP ) +may be specified for each command. +If an optional number \fIn\fP in the range 0..9 is given, the window +number \fIn\fP is assigned to the newly created window (or, if this +number is already in-use, the next available number). +If a command is specified after \*Qscreen\*U, this command (with the given +arguments) is started in the window; otherwise, a shell is created. +Thus, if your \*Q.screenrc\*U contains the lines +.sp +.nf + # example for .screenrc: + screen 1 + screen -fn -t foobar 2 telnet foobar +.fi +.sp +.I screen +creates a shell window (in window #1) and a window with a TELNET connection +to the machine foobar (with no flow-control using the title \*Qfoobar\*U +in window #2). Note, that unlike previous versions of +.I screen +no additional default window is created when \*Qscreen\*U commands are +included in your \*Q.screenrc\*U file. When the initialization is completed, +.I screen +switches to the last window specified in your .screenrc file or, if none, +opens a default window #0. +.sp +.ne 3 +.B "scrollback \fP\fInum\fP" +.PP +Set the size of the scrollback buffer for the current windows to \fInum\fP +lines. The default scrollback is 100 lines. +See also the \*Qdefscrollback\*U command and use \*QC-a i\*U to view the +current setting. +.sp +.ne 3 +.BR "select " [ \fIn ] +.PP +Switch to the window with the number \fIn\fP. +If no window number is specified, you get prompted for an +identifier. This can be title (alphanumeric window name) or a number. +When a new window is established, the first available number +is assigned to this window. +Thus, the first window can be activated by \*Qselect 0\*U (there can be no more +than 10 windows present simultaneously unless +.I screen +was compiled with a higher MAXWIN setting). +.sp +.ne +.BR "sessionname " [ \fIname ] +.PP +Rename the current session. Note, that for \*Qscreen -list\*U the +name shows up with the process-id prepended. If the argument \*Qname\*U +is omitted, the name of this session is displayed. Caution: The $STY +environment variables still reflects the old name. This may result in +confusion. +The default is constructed from the tty and host names. +.sp +.ne 3 +.B "setenv " +.RI [ var " [" string ]] +.PP +Set the environment variable \fIvar\fP to value \fIstring\fP. +If only \fIvar\fP is specified, the user will be prompted to enter a value. +If no parameters are specified, the user will be prompted for both variable +and value. The environment is inherited by all subsequently forked shells. +.sp +.ne 3 +.B "shell \fIcommand\fP" +.PP +Set the command to be used to create a new shell. +This overrides the value of the environment variable $SHELL. +This is useful if you'd like to run a tty-enhancer which is expecting to +execute the program specified in $SHELL. If the command begins with +a '-' character, the shell will be started as a login-shell. +.sp +.ne 3 +.B "shelltitle \fItitle\fP" +.PP +Set the title for all shells created during startup or by +the C-A C-c command. +For details about what a title is, see the discussion +entitled \*QTITLES (naming windows)\*U. +.sp +.ne 3 +.BR "silence " [ on | off "|\fIsec\fP]" +.PP +Toggles silence monitoring of windows. +When silence is turned on and an affected window is switched into the +background, you will receive the silence notification message in the +status line after a specified period of inactivity (silence). The default +timeout can be changed with the `silencewait' command or by specifying a +number of seconds instead of `on' or `off'. +Silence is initially off for all windows. +.sp +.ne 3 +.BI "silencewait " sec +.PP +Define the time that all windows monitored for silence should wait before +displaying a message. Default 30 seconds. +.sp +.ne +.B "sleep \fP\fInum\fP" +.PP +This command will pause the execution of a .screenrc file for \fInum\fP seconds. +Keyboard activity will end the sleep. +It may be used to give users a chance to read the messages output by \*Qecho\*U. +.sp +.ne 3 +.B "slowpaste \fIusec\fP" +.PP +Define the speed at which text is inserted by the paste ("C-a ]") command. +If the slowpaste value is nonzero text is written character by character. +.I screen +will make a pause of \fIusec\fP milliseconds after each single character write +to allow the application to process its input. Only use slowpaste if your +underlying system exposes flow control problems while pasting large amounts of +text. +.sp +.ne 3 +.B sorendition +.RB [ "\fIattr\fR " [ \fIcolor ]] +.PP +Change the way screen does highlighting for text marking and printing +messages. +.I Attr +is a hexadecimal number and describes the attributes (inverse, +underline, ...) the text will get. +.I Color +is a 2 digit number and changes the +forground/background of the highlighted text. +Some knowledge of screen's internal character representation is +needed to make the characters appear in the desired way. The default +is currently 10 99 (standout, default colors). +.sp +.ne 3 +.B "startup_message on\fP|\fBoff" +.PP +Select whether you want to see the copyright notice during startup. +Default is `on', as you probably noticed. +.sp +.ne 3 +.B stuff +.I string +.PP +Stuff the string +.I string +in the input buffer of the current window. +This is like the \*Qpaste\*U command but with much less overhead. +You cannot paste +large buffers with the \*stuff\*U command. It is most useful for key +bindings. See also \*Qbindkey\*U. +.sp +.ne 3 +.B "suspend" +.PP +Suspend +.IR screen . +The windows are in the `detached' state, while +.IR screen +is suspended. This feature relies on the shell being able to do job control. +.sp +.ne 3 +.B "term \fIterm\fP" +.PP +In each window's environment +.I screen +opens, the $TERM variable is set to \*Qscreen\*U by default. +But when no description for \*Qscreen\*U is installed in the local termcap +or terminfo data base, you set $TERM to \- say \- +\*Qvt100\*U. This won't do much harm, as +.I screen +is VT100/ANSI compatible. +The use of the \*Qterm\*U command is discouraged for non-default purpose. +That is, one may want to specify special $TERM settings (e.g. vt100) for the +next \*Qscreen rlogin othermachine\*U command. Use the command \*Qscreen -T vt100 +rlogin othermachine\*U rather than setting and resetting the default. +.sp +.ne 3 +.BI termcap " term terminal-tweaks" +.RI [ window-tweaks ] +.br +.BI terminfo " term terminal-tweaks" +.RI [ window-tweaks ] +.br +.BI termcapinfo " term terminal-tweaks" +.RI [ window-tweaks ] +.PP +Use this command to modify your terminal's termcap entry without going through +all the hassles involved in creating a custom termcap entry. +Plus, you can optionally customize the termcap generated for the windows. +If your system works with terminfo-database rather than with +termcap, +.I screen +will understand the `terminfo' command, which has the same effects as +the `termcap' command. Two separate commands are provided, as there are subtle +syntactic differences, e.g. when parameter interpolation (using `%') is +required. Note that termcap names of the capabilities have to be used +with the `terminfo' command. +.br +In many cases, where the arguments are valid in both terminfo and termcap +syntax, you can use the command `termcapinfo', which is just a shorthand +for a pair of `termcap' and `terminfo' commands with identical arguments. +.PP +The first argument specifies which terminal(s) should be affected by this +definition. +You can specify multiple terminal names by separating them with `|'s. +Use `*' to match all terminals and `vt*' to match all terminals that begin +with \*Qvt\*U. +.PP +Each \fItweak\fP argument contains one or more termcap defines (separated +by `:'s) to be inserted at the start of the appropriate termcap entry, +enhancing it or overriding existing values. +The first tweak modifies your terminal's termcap, and contains definitions +that your terminal uses to perform certain functions. +Specify a null string to leave this unchanged (e.\|g. ''). +The second (optional) tweak modifies all the window termcaps, and should +contain definitions that +.I screen +understands (see the \*QVIRTUAL TERMINAL\*U +section). +.PP +Some examples: +.IP +termcap xterm* LP:hs@ +.PP +Informs +.I screen +that all terminals that begin with `xterm' have firm auto-margins that +allow the last position on the screen to be updated (LP), but they don't +really have a status line (no 'hs' \- append `@' to turn entries off). +Note that we assume `LP' for all terminal names that start with \*Qvt\*U, +but only if you don't specify a termcap command for that terminal. +.IP +termcap vt* LP +.br +termcap vt102|vt220 Z0=\eE[?3h:Z1=\eE[?3l +.PP +Specifies the firm-margined `LP' capability for all terminals that begin with +`vt', and the second line will also add the escape-sequences to switch +into (Z0) and back out of (Z1) 132-character-per-line mode if this is +a VT102 or VT220. +(You must specify Z0 and Z1 in your termcap to use the width-changing +commands.) +.IP +termcap vt100 "" l0=PF1:l1=PF2:l2=PF3:l3=PF4 +.PP +This leaves your vt100 termcap alone and adds the function key labels to +each window's termcap entry. +.IP +termcap h19|z19 am@:im=\eE@:ei=\eEO dc=\eE[P +.PP +Takes a h19 or z19 termcap and turns off auto-margins (am@) and enables the +insert mode (im) and end-insert (ei) capabilities (the `@' in the `im' +string is after the `=', so it is part of the string). +Having the `im' and `ei' definitions put into your terminal's termcap will +cause +.I screen +to automatically advertise the character-insert capability in +each window's termcap. +Each window will also get the delete-character capability (dc) added to its +termcap, which +.I screen +will translate into a line-update for the terminal +(we're pretending it doesn't support character deletion). +.PP +If you would like to fully specify each window's termcap entry, you should +instead set the $SCREENCAP variable prior to running +.IR screen . +See the discussion on the \*QVIRTUAL TERMINAL\*U in this manual, and the termcap(5) +man page for more information on termcap definitions. +.sp +.ne 3 +.B time +.PP +Uses the message line to display the time of day, the host name, and the load +averages over 1, 5, and 15 minutes (if this is available on your system). +For window specific information use \*Qinfo\*U. +.sp +.ne 3 +.BR "title " [ \fIwindowalias ] +.PP +Set the name of the current window to \fIwindowalias\fP. If no name is +specified, +.I screen +prompts for one. This command was known as `aka' in previous +releases. +.sp +.ne 3 +.BI "unsetenv " var +.PP +Unset an environment variable. +.sp +.ne 3 +.BR "vbell on" | off +.PP +If your terminal does not support +a visual bell, a `vbell-message' is displayed in the status line. +Sets the visual bell setting for this window. If your terminal does not support +a visual bell, a `vbell-message' is displayed in the status line. +Refer to the termcap variable `vb' (terminfo: 'flash'). +.sp +.ne 3 +.BI "vbell_msg " message +.PP +Sets the visual bell message. \fImessage\fP is printed to the status line if +the window receives a bell character (^G) and vbell is set to \*Qon\*U. +The default message is \*QWuff, Wuff!!\*U. +.sp +.ne 3 +.BI "vbellwait " sec +.PP +Define a delay in seconds after each display of +.IR screen 's +visual bell message. The default is 1 second. +.sp +.ne 3 +.B version +.PP +Print the current version and the compile date in the status line. +.sp +.ne 3 +.BI "wall " "message" +.PP +Write a message to all displays. The message will appear in the terminal's +status line. +.sp +.ne 3 +.BR "width " [ \fInum ] +.PP +Toggle the window width between 80 and 132 columns or set it to \fInum\fP +columns if an argument is specified. +This requires a capable terminal and the termcap entries \*QZ0\*U and \*QZ1\*U. +See the \*Qtermcap\*U command for more information. +.sp +.ne 3 +.B windows +.PP +Uses the message line to display a list of all the windows. +Each window is listed by number with the name of process that has been +started in the window (or its title); +the current window is marked with a `*'; +the previous window is marked with a `-'; +all the windows that are \*Qlogged in\*U are marked with a `$'; +a background window that has received a bell is marked with a `!'; +a background window that is being monitored and has had activity occur +is marked with an `@'; +a window which has output logging turned on is marked with `(L)'; +windows occupied by other users are marked with `&'; +windows in the zombie state are marked with `Z'. +If this list is too long to fit on the terminal's status line only the +portion around the current window is displayed. +.sp +.ne 3 +.BR "wrap " [ on | off ] +.PP +Sets the line-wrap setting for the current window. +When line-wrap is on, the second consecutive printable character output at +the last column of a line will wrap to the start of the following line. +As an added feature, backspace (^H) will also wrap through the left margin +to the previous line. +Default is `on'. +.sp +.ne 3 +.B writebuf +.PP +Writes the contents of the paste buffer to a public accessible screen-exchange +file. This is thought of as a primitive means of communication between +.I screen +users on the same host. The filename can be set with the \fIbufferfile\fP +command and defaults to \*Q/tmp/screen-exchange\*U. +.sp +.ne 3 +.BR "writelock " [ on | "off\fR|\fBauto\fR]" +.PP +In addition to access control lists, not all users may be able to write to +the same window at once. Per default, writelock is in `auto' mode and +grants exclusive input permission to the user who is the first to switch +to the particular window. When he leaves the window, other users may obtain +the writelock (automatically). The writelock of the current window is disabled +by the command \*Qwritelock off\*U. If the user issues the command +\*Qwritelock on\*U he keeps the exclusive write permission while switching +to other windows. +.sp +.ne 3 +.B xoff +.br +.B xon +.PP +Insert a CTRL-s / CTRL-q character to the stdin queue of the +current window. +.sp +.ne 3 +.BR "zombie " [\fIkeys\fP] +.br +.BR "defzombie " [\fIkeys\fP] +.PP +Per default +.I screen +windows are removed from the window list as soon as +the windows process (e.g. shell) exits. When a string of two keys is +specified to the zombie command, `dead' windows will remain in the list. +The \fBkill\fP kommand may be used to remove such a window. Pressing the +first key in the dead window has the same effect. When pressing the second +key, screen will attempt to resurrect the window. The process that was +initially running in the window will be launched again. Calling \fBzombie\fP +without parameters will clear the zombie setting, thus making windows disappear +when their process exits. + +As the zombie-setting is manipulated globally for all windows, this command +should only be called \fBdefzombie\fP. Until we need this as a per window +setting, the commands \fBzombie\fP and \fBdefzombie\fP are synonymous. + +.SH "THE MESSAGE LINE" +.I Screen +displays informational messages and other diagnostics in a \fImessage line\fP. +While this line is distributed to appear at the bottom of the screen, +it can be defined to appear at the top of the screen during compilation. +If your terminal has a status line defined in its termcap, +.I screen +will use this for displaying its messages, otherwise a line of the +current screen will +be temporarily overwritten and output will be momentarily interrupted. The +message line is automatically removed after a few seconds delay, but it +can also be removed early (on terminals without a status line) by beginning +to type. +.PP +The message line facility can be used by an application running in +the current window by means of the ANSI \fIPrivacy message\fP +control sequence. +For instance, from within the shell, try something like: +.IP +echo '^Hello world from window '$WINDOW'\e\e' +.PP +where '' is an \fIescape\fP, '^' is a literal up-arrow, +and '\e\e' turns into a single backslash. + + +.SH "FLOW-CONTROL" +Each window has a flow-control setting that determines how +.I screen +deals with +the XON and XOFF characters (and perhaps the interrupt character). +When flow-control is turned off, +.I screen +ignores the XON and XOFF characters, +which allows the user to send them to the current program by simply typing +them (useful for the \fIemacs\fP editor, for instance). +The trade-off is that it will take longer for output from a \*Qnormal\*U +program to pause in response to an XOFF. +With flow-control turned on, XON and XOFF characters are used to immediately +pause the output of the current window. +You can still send these characters to the current program, but you must use +the appropriate two-character +.I screen +commands (typically \*QC-a q\*U (xon) +and \*QC-a s\*U (xoff)). +The xon/xoff commands are also useful for typing C-s and C-q past a terminal +that intercepts these characters. +.PP +Each window has an initial flow-control value set with either the +.B \-f +option or the \*Qdefflow\*U .screenrc command. Per default the windows +are set to automatic flow-switching. +It can then be toggled between the three states 'fixed on', 'fixed off' and +'automatic' interactively with the \*Qflow\*U command bound to "C-a f". +.PP +The automatic flow-switching mode deals with +flow control using the TIOCPKT mode (like \*Qrlogin\*U does). If +the tty driver does not support TIOCPKT, +.I screen +tries to find out +the right mode based on the current setting of the application +keypad \- when it is enabled, flow-control is turned off and visa versa. +Of course, you can still manipulate flow-control manually when needed. +.PP +If you're running with flow-control enabled and find that pressing the +interrupt key (usually C-c) does not interrupt the display until another +6-8 lines have scrolled by, try running +.I screen +with the \*Qinterrupt\*U +option (add the \*Qinterrupt\*U flag to the \*Qflow\*U command in +your .screenrc, or use the +.B \-i +command-line option). +This causes the output that +.I screen +has accumulated from the interrupted program to be flushed. +One disadvantage is that the virtual terminal's memory contains the +non-flushed version of the output, which in rare cases can cause +minor inaccuracies in the output. +For example, if you switch screens and return, or update the screen +with \*QC-a l\*U you would see the version of the output you would +have gotten without \*Qinterrupt\*U being on. +Also, you might need to turn off flow-control (or use auto-flow mode to turn +it off automatically) when running a program that expects you to type the +interrupt character as input, as it is possible to interrupt +the output of the virtual terminal to your physical terminal when flow-control +is enabled. +If this happens, a simple refresh of the screen with \*QC-a l\*U will +restore it. +Give each mode a try, and use whichever mode you find more comfortable. + + +.SH "TITLES (naming windows)" +You can customize each window's name in the window display (viewed with the +\*Qwindows\*U command (C-a w)) by setting it with one of +the title commands. +Normally the name displayed is the actual command name of the program +created in the window. +However, it is sometimes useful to distinguish various programs of the same +name or to change the name on-the-fly to reflect the current state of +the window. +.PP +The default name for all shell windows can be set with the \*Qshelltitle\*U +command in the .screenrc file, while all other windows are created with +a \*Qscreen\*U command and thus can have their name set with the +.B \-t +option. +Interactively, there is the title-string escape-sequence +(k\fIname\fP\e) and the \*Qtitle\*U command (C-a A). +The former can be output from an application to control the window's name +under software control, and the latter will prompt for a name when typed. +You can also bind pre-defined names to keys with the \*Qtitle\*U command +to set things quickly without prompting. +.PP +Finally, +.I screen +has a shell-specific heuristic that is enabled by setting the window's name +to \*Q\fIsearch|name\fP\*U and arranging to have a null title escape-sequence +output as a part of your prompt. +The \fIsearch\fP portion specifies an end-of-prompt search string, while +the \fIname\fP portion specifies the default shell name for the window. +If the \fIname\fP ends in a `:' +.I screen +will add what it believes to be the current command running in the window +to the end of the window's shell name (e.\|g. \*Q\fIname:cmd\fP\*U). +Otherwise the current command name supersedes the shell name while it is +running. +.PP +Here's how it works: you must modify your shell prompt to output a null +title-escape-sequence (k\e) as a part of your prompt. +The last part of your prompt must be the same as the string you specified +for the \fIsearch\fP portion of the title. +Once this is set up, +.I screen +will use the title-escape-sequence to clear the previous command name and +get ready for the next command. +Then, when a newline is received from the shell, a search is made for the +end of the prompt. +If found, it will grab the first word after the matched string and use it +as the command name. +If the command name begins with either '!', '%', or '^' +.I screen +will use the first word on the following line (if found) in preference to +the just-found name. +This helps csh users get better command names when using job control or +history recall commands. +.PP +Here's some .screenrc examples: +.IP +screen -t top 2 nice top +.PP +Adding this line to your .screenrc would start a nice-d version of the +\*Qtop\*U command in window 2 named \*Qtop\*U rather than \*Qnice\*U. +.sp +.nf + shelltitle '> |csh' + screen 1 +.fi +.sp +These commands would start a shell with the given shelltitle. +The title specified is an auto-title that would expect the prompt and +the typed command to look something like the following: +.IP +/usr/joe/src/dir> trn +.PP +(it looks after the '> ' for the command name). +The window status would show the name \*Qtrn\*U while the command was +running, and revert to \*Qcsh\*U upon completion. +.IP +bind R screen -t '% |root:' su +.PP +Having this command in your .screenrc would bind the key +sequence \*QC-a R\*U to the \*Qsu\*U command and give it an +auto-title name of \*Qroot:\*U. +For this auto-title to work, the screen could look something +like this: +.sp +.nf + % !em + emacs file.c +.fi +.sp +Here the user typed the csh history command \*Q!em\*U which ran the +previously entered \*Qemacs\*U command. +The window status would show \*Qroot:emacs\*U during the execution +of the command, and revert to simply \*Qroot:\*U at its completion. +.PP +.nf + bind o title + bind E title "" + bind u title (unknown) +.fi +.sp +The first binding doesn't have any arguments, so it would prompt you +for a title. when you type \*QC-a o\*U. +The second binding would clear an auto-title's current setting (C-a E). +The third binding would set the current window's title to \*Q(unknown)\*U +(C-a u). +.PP +One thing to keep in mind when adding a null title-escape-sequence to +your prompt is that some shells (like the csh) count all the non-control +characters as part of the prompt's length. +If these invisible characters aren't a multiple of 8 then backspacing over +a tab will result in an incorrect display. +One way to get around this is to use a prompt like this: +.IP +set prompt='^[[0000m^[k^[\e% ' +.PP +The escape-sequence \*Q[0000m\*U not only normalizes the character +attributes, but all the zeros round the length of the invisible characters +up to 8. +Bash users will probably want to echo the escape sequence in the +PROMPT_COMMAND: +.IP +PROMPT_COMMAND='echo -n -e "\e033k\e033\e134"' +.PP +(I used \*Q\134\*U to output a `\e' because of a bug in bash v1.04). + + +.SH "THE VIRTUAL TERMINAL" +Each window in a +.I screen +session emulates a VT100 terminal, with some extra functions added. The +VT100 emulator is hardcoded, no other terminal types can be emulated. +.br +Usually +.I screen +tries to emulate as much of the VT100/ANSI standard +as possible. But if your terminal lacks certain capabilities, +the emulation may not be complete. In these cases +.I screen +has to tell the applications that some of the features +are missing. This is no problem on machines using termcap, +because +.I screen +can use the $TERMCAP variable to +customize the standard +.I screen +termcap. +.PP +But if you do a +rlogin on another machine or your machine supports only +terminfo this method fails. Because of this, +.I screen +offers a way to deal with these cases. +Here is how it works: +.PP +When +.I screen +tries to figure out a terminal name for itself, +it first looks +for an entry named \*Qscreen.\*U, where is +the contents of your $TERM variable. +If no such entry exists, +.I screen +tries \*Qscreen\*U (or \*Qscreen-w\*U if the terminal is wide +(132 cols or more)). +If even this entry cannot be found, \*Qvt100\*U is used as a +substitute. +.PP +The idea is that if you have a terminal which doesn't +support an important feature (e.g. delete char or clear to EOS) +you can build a new termcap/terminfo entry for +.I screen +(named \*Qscreen.\*U) in which this capability +has been disabled. If this entry is installed on your +machines you are able to do +a rlogin and still keep the correct termcap/terminfo entry. +The terminal name is put in the $TERM variable +of all new windows. +.I Screen +also sets the $TERMCAP variable reflecting the capabilities +of the virtual terminal emulated. Notice that, however, on machines +using the terminfo database this variable has no effect. +Furthermore, the variable $WINDOW is set to the window number +of each window. +.PP +The actual set of capabilities supported by the virtual terminal +depends on the capabilities supported by the physical terminal. +If, for instance, the physical terminal does not support underscore mode, +.I screen +does not put the `us' and `ue' capabilities into the window's $TERMCAP +variable, accordingly. +However, a minimum number of capabilities must be supported by a +terminal in order to run +.IR screen ; +namely scrolling, clear screen, and direct cursor addressing +(in addition, +.I screen +does not run on hardcopy terminals or on terminals that over-strike). +.PP +Also, you can customize the $TERMCAP value used by +.I screen +by using the \*Qtermcap\*U .screenrc command, or +by defining the variable $SCREENCAP prior to startup. +When the is latter defined, its value will be copied verbatim into each +window's $TERMCAP variable. +This can either be the full terminal definition, or a filename where the +terminal \*Qscreen\*U (and/or \*Qscreen-w\*U) is defined. +.PP +Note that +.I screen +honors the \*Qterminfo\*U .screenrc command if the system uses the +terminfo database rather than termcap. +.PP +When the boolean `G0' capability is present in the termcap entry +for the terminal on which +.I screen +has been called, the terminal emulation of +.I screen +supports multiple character sets. +This allows an application to make use of, for instance, +the VT100 graphics character set or national character sets. +The following control functions from ISO 2022 are supported: +\fIlock shift G0\fP (\fISI\fP), \fIlock shift G1\fP (\fISO\fP), +\fIlock shift G2\fP, \fIlock shift G3\fP, \fIsingle shift G2\fP, +and \fIsingle shift G3\fP. +When a virtual terminal is created or reset, the ASCII character +set is designated as \fIG0\fP through \fIG3\fP. +When the `G0' capability is present, +.I screen +evaluates the capabilities +`S0', `E0', and `C0' if present. `S0' is the sequence the terminal uses +to enable and start the graphics character set rather than \fISI\fP. +`E0' is the corresponding replacement for \fISO\fP. `C0' gives a character +by character translation string that is used during semi-graphics mode. This +string is built like the `acsc' terminfo capability. +.PP +When the `po' and `pf' capabilities are present in the terminal's +termcap entry, applications running in a +.I screen +window can send output to the printer port of the terminal. +This allows a user to have an application in one window +sending output to a printer connected to the terminal, while all +other windows are still active (the printer port is enabled +and disabled again for each chunk of output). +As a side-effect, programs running in different windows can +send output to the printer simultaneously. +Data sent to the printer is not displayed in the window. +.PP +.I Screen +maintains a hardstatus line for every window. If a window +gets selected, the display's hardstatus will be updated to match +the window's hardstatus line. If the display has no hardstatus +the line will be displayed as a standard screen message. +The hardstatus line can be changed with the ANSI Application +Program Command (APC): \*QESC_ESC\e\*U. As a convenience +for xterm users the sequence \*QESC]0..2;^G\*U is +also accepted. +.PP +Some capabilities are only put into the $TERMCAP +variable of the virtual terminal if they can be efficiently +implemented by the physical terminal. +For instance, `dl' (delete line) is only put into the $TERMCAP +variable if the terminal supports either delete line itself or +scrolling regions. Note that this may provoke confusion, when +the session is reattached on a different terminal, as the value +of $TERMCAP cannot be modified by parent processes. +.PP +The following is a list of control sequences recognized by +.IR screen . +\*Q(V)\*U and \*Q(A)\*U indicate VT100-specific and ANSI- or +ISO-specific functions, respectively. +.PP +.ta 22n +.TP 27 +.B "ESC E" +Next Line +.TP 27 +.B "ESC D" +Index +.TP 27 +.B "ESC M" +Reverse Index +.TP 27 +.B "ESC H" +Horizontal Tab Set +.TP 27 +.B "ESC Z" +Send VT100 Identification String +.TP 27 +.BR "ESC 7" " (V)" +Save Cursor and Attributes +.TP 27 +.BR "ESC 8" " (V)" +Restore Cursor and Attributes +.TP 27 +.BR "ESC [s" " (A)" +Save Cursor and Attributes +.TP 27 +.BR "ESC [u" " (A)" +Restore Cursor and Attributes +.TP 27 +.B "ESC c" +Reset to Initial State +.TP 27 +.B "ESC g" +Visual Bell +.TP 27 +.B "ESC \fPPn\fB p" +Cursor Visibility (97801) +.TP 27 +\h'\w'ESC 'u'Pn = \fB6\fP +Invisible +.TP 27 +\h'\w'ESC Pn = 'u'\fB7\fP +Visible +.TP 27 +.BR "ESC =" " (V)" +Application Keypad Mode +.TP 27 +.BR "ESC >" " (V)" +Numeric Keypad Mode +.TP 27 +.BR "ESC # 8" " (V)" +Fill Screen with E's +.TP 27 +.BR "ESC \e" " (A)" +String Terminator +.TP 27 +.BR "ESC ^" " (A)" +Privacy Message String (Message Line) +.TP 27 +.B "ESC !" +Global Message String (Message Line) +.TP 27 +.B "ESC k" +A.\|k.\|a. Definition String +.TP 27 +.BR "ESC P" " (A)" +Device Control String. +Outputs a string directly to the host +terminal without interpretation. +.TP 27 +.BR "ESC _" " (A)" +Application Program Command (Hardstatus) +.TP 27 +.BR "ESC ]" " (A)" +Operating System Command (Hardstatus, xterm title hack) +.TP 27 +.BR "Control-N" " (A)" +Lock Shift G1 (SO) +.TP 27 +.BR "Control-O" " (A)" +Lock Shift G0 (SI) +.TP 27 +.BR "ESC n" " (A)" +Lock Shift G2 +.TP 27 +.BR "ESC o" " (A)" +Lock Shift G3 +.TP 27 +.BR "ESC N" " (A)" +Single Shift G2 +.TP 27 +.BR "ESC O" " (A)" +Single Shift G3 +.TP 27 +.BR "ESC ( \fPPcs" " (A)" +Designate character set as G0 +.TP 27 +.BR "ESC ) \fPPcs" " (A)" +Designate character set as G1 +.TP 27 +.BR "ESC * \fPPcs" " (A)" +Designate character set as G2 +.TP 27 +.BR "ESC + \fPPcs" " (A)" +Designate character set as G3 +.TP 27 +.B "ESC [ \fPPn\fB ; \fPPn\fB H" +Direct Cursor Addressing +.TP 27 +.B "ESC [ \fPPn\fB ; \fPPn\fB f" +Direct Cursor Addressing +.TP 27 +.B "ESC [ \fPPn\fB J" +Erase in Display +.TP 27 +\h'\w'ESC [ 'u'Pn = None or \fB0\fP +From Cursor to End of Screen +.TP 27 +\h'\w'ESC [ Pn = 'u'\fB1\fP +From Beginning of Screen to Cursor +.TP 27 +\h'\w'ESC [ Pn = 'u'\fB2\fP +Entire Screen +.TP 27 +.B "ESC [ \fPPn\fB K" +Erase in Line +.TP 27 +\h'\w'ESC [ 'u'Pn = None or \fB0\fP +From Cursor to End of Line +.TP 27 +\h'\w'ESC [ Pn = 'u'\fB1\fP +From Beginning of Line to Cursor +.TP 27 +\h'\w'ESC [ Pn = 'u'\fB2\fP +Entire Line +.TP 27 +.B "ESC [ \fPPn\fB A" +Cursor Up +.TP 27 +.B "ESC [ \fPPn\fB B" +Cursor Down +.TP 27 +.B "ESC [ \fPPn\fB C" +Cursor Right +.TP 27 +.B "ESC [ \fPPn\fB D" +Cursor Left +.TP 27 +.B "ESC [ \fPPs\fB ;\fP...\fB; \fPPs\fB m" +Select Graphic Rendition +.TP 27 +\h'\w'ESC [ 'u'Ps = None or \fB0\fP +Default Rendition +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB1\fP +Bold +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB2\fP (A) +Faint +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB3\fP (A) +\fIStandout\fP Mode (ANSI: Italicized) +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB4\fP +Underlined +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB5\fP +Blinking +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB7\fP +Negative Image +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB22\fP (A) +Normal Intensity +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB23\fP (A) +\fIStandout\fP Mode off (ANSI: Italicized off) +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB24\fP (A) +Not Underlined +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB25\fP (A) +Not Blinking +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB27\fP (A) +Positive Image +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB30\fP (A) +Foreground Black +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB31\fP (A) +Foreground Red +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB32\fP (A) +Foreground Green +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB33\fP (A) +Foreground Yellow +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB34\fP (A) +Foreground Blue +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB35\fP (A) +Foreground Magenta +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB36\fP (A) +Foreground Cyan +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB37\fP (A) +Foreground White +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB39\fP (A) +Foreground Default +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB40\fP (A) +Background Black +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB...\fP +... +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB49\fP (A) +Background Default +.TP 27 +.B "ESC [ \fPPn\fB g" +Tab Clear +.TP 27 +\h'\w'ESC [ 'u'Pn = None or \fB0\fP +Clear Tab at Current Position +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB3\fP +Clear All Tabs +.TP 27 +.BR "ESC [ \fPPn\fB ; \fPPn\fB r" " (V)" +Set Scrolling Region +.TP 27 +.BR "ESC [ \fPPn\fB I" " (A)" +Horizontal Tab +.TP 27 +.BR "ESC [ \fPPn\fB Z" " (A)" +Backward Tab +.TP 27 +.BR "ESC [ \fPPn\fB L" " (A)" +Insert Line +.TP 27 +.BR "ESC [ \fPPn\fB M" " (A)" +Delete Line +.TP 27 +.BR "ESC [ \fPPn\fB @" " (A)" +Insert Character +.TP 27 +.BR "ESC [ \fPPn\fB P" " (A)" +Delete Character +.TP 27 +.B "ESC [ \fPPn\fB S" +Scroll Scrolling Region Up +.TP 27 +.B "ESC [ \fPPn\fB T" +Scroll Scrolling Region Down +.TP 27 +.B "ESC [ \fPPs\fB ;\fP...\fB; \fPPs\fB h" +Set Mode +.TP 27 +.B "ESC [ \fPPs\fB ;\fP...\fB; \fPPs\fB l" +Reset Mode +.TP 27 +\h'\w'ESC [ 'u'Ps = \fB4\fP (A) +Insert Mode +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB20\fP (A) +\fIAutomatic Linefeed\fP Mode +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB34\fP +Normal Cursor Visibility +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB?1\fP (V) +Application Cursor Keys +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB?3\fP (V) +Change Terminal Width to 132 columns +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB?5\fP (V) +Reverse Video +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB?6\fP (V) +\fIOrigin\fP Mode +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB?7\fP (V) +\fIWrap\fP Mode +.TP 27 +\h'\w'ESC [ Ps = 'u'\fB?25\fP (V) +Visible Cursor +.TP 27 +.BR "ESC [ 5 i" " (A)" +Start relay to printer (ANSI Media Copy) +.TP 27 +.BR "ESC [ 4 i" " (A)" +Stop relay to printer (ANSI Media Copy) +.TP 27 +.B "ESC [ 8 ; \fPPh\fB ; \fPPw\fB t" +Resize the window to `Ph' lines and `Pw' columns (SunView special) +.TP 27 +.B "ESC [ c" +Send VT100 Identification String +.TP 27 +.B "ESC [ x" +Send Terminal Parameter Report +.TP 27 +.B "ESC [ > c" +Send VT220 Secondary Device Attributes String +.TP 27 +.B "ESC [ 6 n" +Send Cursor Position Report + + +.SH "INPUT TRANSLATION" +In order to do a full VT100 emulation \fIscreen\fP has to detect +that a sequence of characters in the input stream was generated +by a keypress on the user's keyboard and insert the VT100 +style escape sequence. \fIScreen\fP has a very flexible way of doing +this by making it posible to map arbitrary commands on arbitrary +sequences of characters. For standard VT100 emulation the command +will always insert a string in the input buffer of the window +(see also command \fBstuff\fP in the command table). +Because the sequences generated by a keypress can +change after a reattach from a different terminal type, it is +possible to bind commands to the termcap name of the keys. +\fIScreen\fP will insert the correct binding after each +reattach. See the \fBbindkey\fP command for further details on the +syntax and examples. +.PP +Here is the table of the default key bindings. (A) means that the +command is executed if the keyboard is switched into application +mode. +.PP +.ta 18n 34n 50n +.nf +Key name Termcap name Command +\l'54n' +.ta 22n 34n 50n +Cursor up ku stuff \e033[A + stuff \e033OA (A) +Cursor down kd stuff \e033[B + stuff \e033OB (A) +Cursor right kr stuff \e033[C + stuff \e033OC (A) +Cursor left kl stuff \e033[D + stuff \e033OD (A) +Function key 0 k0 stuff \e033[10~ +Function key 1 k1 stuff \e033OP +Function key 2 k2 stuff \e033OQ +Function key 3 k3 stuff \e033OR +Function key 4 k4 stuff \e033OS +Function key 5 k5 stuff \e033[15~ +Function key 6 k6 stuff \e033[17~ +Function key 7 k7 stuff \e033[18~ +Function key 8 k8 stuff \e033[19~ +Function key 9 k9 stuff \e033[20~ +Function key 10 k; stuff \e033[21~ +Function key 11 F1 stuff \e033[22~ +Function key 12 F2 stuff \e033[23~ +Backspace kb stuff \e010 +Home kh stuff \e033[1~ +End kH stuff \e033[4~ +Insert kI stuff \e033[2~ +Delete kD stuff \e033[3~ +Page up kP stuff \e033[5~ +Page down kN stuff \e033[6~ +Keypad 0 f0 stuff 0 + stuff \e033Op (A) +Keypad 1 f1 stuff 1 + stuff \e033Oq (A) +Keypad 2 f2 stuff 2 + stuff \e033Or (A) +Keypad 3 f3 stuff 3 + stuff \e033Os (A) +Keypad 4 f4 stuff 4 + stuff \e033Ot (A) +Keypad 5 f5 stuff 5 + stuff \e033Ou (A) +Keypad 6 f6 stuff 6 + stuff \e033Ov (A) +Keypad 7 f7 stuff 7 + stuff \e033Ow (A) +Keypad 8 f8 stuff 8 + stuff \e033Ox (A) +Keypad 9 f9 stuff 9 + stuff \e033Oy (A) +Keypad + f+ stuff + + stuff \e033Ok (A) +Keypad - f- stuff - + stuff \e033Om (A) +Keypad * f* stuff * + stuff \e033Oj (A) +Keypad / f/ stuff / + stuff \e033Oo (A) +Keypad = fq stuff = + stuff \e033OX (A) +Keypad . f. stuff . + stuff \e033On (A) +Keypad , f, stuff , + stuff \e033Ol (A) +Keypad enter fe stuff \e015 + stuff \e033OM (A) +.fi + + +.SH SPECIAL TERMINAL CAPABILITIES +The following table describes all terminal capabilities +that are recognized by \fIscreen\fP and are not in the +termcap(5) manual. +You can place these capabilities in your termcap entries (in +`/etc/termcap') or use them with the commands `termcap', `terminfo' and +`termcapinfo' in your screenrc files. It is often not possible to place +these capabilities in the terminfo database. +.PP +.ta 5n +.TP 13 +.BI LP " (bool)" +Terminal has VT100 style margins (`magic margins'). Note that +this capability is obsolete because \fIscreen\fP uses the standard 'xn' +instead. +.TP 13 +.BI Z0 " (str)" +Change width to 132 columns. +.TP 13 +.BI Z1 " (str)" +Change width to 80 columns. +.TP 13 +.BI WS " (str)" +Resize display. This capability has the desired width and height as +arguments. \fISunView(tm)\fP example: '\eE[8;%d;%dt'. +.TP 13 +.BI NF " (bool)" +Terminal doesn't need flow control. Send ^S and ^Q direct to +the application. Same as 'flow off'. The opposite of this +capability is 'nx'. +.TP 13 +.BI G0 " (bool)" +Terminal can deal with ISO 2022 font selection sequences. +.TP 13 +.BI S0 " (str)" +Switch charset 'G0' to the specified charset. Default +is '\eE(%.'. +.TP 13 +.BI E0 " (str)" +Switch charset 'G0' back to standard charset. Default +is '\eE(B'. +.TP 13 +.BI C0 " (str)" +Use the string as a conversion table for font '0'. See +the 'ac' capability for more details. +.TP 13 +.BI CS " (str)" +Switch cursorkeys to application mode. +.TP 13 +.BI CE " (str)" +Switch cursorkeys back to normal mode. +.TP 13 +.BI AN " (bool)" +Turn on autonuke. See the 'autonuke' command for more details. +.TP 13 +.BI OL " (num)" +Set the output buffer limit. See the 'obuflimit' command for more details. +.TP 13 +.BI KJ " (str)" +Set the kanji type of the terminal. Valid strings are \*Qjis\*U, +\*Qeuc\*U and \*Qsjis\*U. +.TP 13 +.BI AF " (str)" +Change character forground color in an ANSI conform way. This +capability will almost always be set to '\eE[3%dm' ('\eE[3%p1%dm' +on terminfo machines). +.TP 13 +.BI AB " (str)" +Same as 'AF', but change background color. +.TP 13 +.BI AX " (bool)" +Does understand ANSI set default fg/bg color (\eE[39m / \eE[49m). +.TP 13 +.BI XC " (str)" +Describe a translation of characters to strings depending on the +current font. More details follow in the next section. + +.SH CHARACTER TRANSLATION +\fIScreen\fP has a powerful mechanism to translate characters to arbitrary +strings depending on the current font and terminal type. +Use this feature if you want to work with a common standard character +set (say ISO8851-latin1) even on terminals that scatter the more +unusual characters over several national language font pages. + +Syntax: +.nf + \fBXC=\fP\fI\fP{\fB,,\fP\fI\fP} + \fI\fP := \fI