xconsole.c revision 38cd97f3
1c7484f1fSmrg/* 2c7484f1fSmrg * $Xorg: xconsole.c,v 1.5 2001/02/09 02:05:40 xorgcvs Exp $ 3c7484f1fSmrg * 4c7484f1fSmrgCopyright 1990, 1998 The Open Group 5c7484f1fSmrg 6c7484f1fSmrgPermission to use, copy, modify, distribute, and sell this software and its 7c7484f1fSmrgdocumentation for any purpose is hereby granted without fee, provided that 8c7484f1fSmrgthe above copyright notice appear in all copies and that both that 9c7484f1fSmrgcopyright notice and this permission notice appear in supporting 10c7484f1fSmrgdocumentation. 11c7484f1fSmrg 12c7484f1fSmrgThe above copyright notice and this permission notice shall be included in 13c7484f1fSmrgall copies or substantial portions of the Software. 14c7484f1fSmrg 15c7484f1fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16c7484f1fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17c7484f1fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18c7484f1fSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19c7484f1fSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20c7484f1fSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21c7484f1fSmrg 22c7484f1fSmrgExcept as contained in this notice, the name of The Open Group shall not be 23c7484f1fSmrgused in advertising or otherwise to promote the sale, use or other dealings 24c7484f1fSmrgin this Software without prior written authorization from The Open Group. 25c7484f1fSmrg * 26c7484f1fSmrg * Author: Keith Packard, MIT X Consortium 27c7484f1fSmrg */ 28c7484f1fSmrg 29c7484f1fSmrg/* $XFree86: xc/programs/xconsole/xconsole.c,v 3.31tsi Exp $ */ 30c7484f1fSmrg 31c7484f1fSmrg#ifdef HAVE_CONFIG_H 32c7484f1fSmrg#include "config.h" 33c7484f1fSmrg#endif 34c7484f1fSmrg 35c7484f1fSmrg#include <X11/Intrinsic.h> 36c7484f1fSmrg#include <X11/StringDefs.h> 37c7484f1fSmrg#include <X11/Xatom.h> 38c7484f1fSmrg 39c7484f1fSmrg#include <X11/Xmu/Atoms.h> 40c7484f1fSmrg#include <X11/Xmu/StdSel.h> 41c7484f1fSmrg#include <X11/Xmu/SysUtil.h> 42c7484f1fSmrg 43c7484f1fSmrg#include <X11/Xaw/Form.h> 44c7484f1fSmrg#include <X11/Xaw/Label.h> 45c7484f1fSmrg#include <X11/Xaw/Command.h> 46c7484f1fSmrg#include <X11/Xaw/AsciiText.h> 47c7484f1fSmrg#include <X11/Xaw/Dialog.h> 48c7484f1fSmrg#include <X11/Xaw/Cardinals.h> 49c7484f1fSmrg#include <X11/Xaw/Paned.h> 50c7484f1fSmrg#include <X11/Xaw/Box.h> 51c7484f1fSmrg 52c7484f1fSmrgextern char *_XawTextGetSTRING(TextWidget ctx, XawTextPosition left, 53c7484f1fSmrg XawTextPosition right); 54c7484f1fSmrg 55c7484f1fSmrg#include <X11/Xos.h> 56c7484f1fSmrg#include <X11/Xfuncs.h> 57c7484f1fSmrg#include <sys/stat.h> 58c7484f1fSmrg#ifndef _POSIX_SOURCE 59c7484f1fSmrg#define _POSIX_SOURCE 60c7484f1fSmrg#include <stdio.h> 61c7484f1fSmrg#undef _POSIX_SOURCE 62c7484f1fSmrg#else 63c7484f1fSmrg#include <stdio.h> 64c7484f1fSmrg#endif 65c7484f1fSmrg#include <X11/Shell.h> 66c7484f1fSmrg#include <ctype.h> 67c7484f1fSmrg#include <stdlib.h> 68c7484f1fSmrg#ifdef HAS_OPENPTY 69c7484f1fSmrg# ifdef HAS_UTIL_H 70c7484f1fSmrg# include <util.h> 71c7484f1fSmrg# endif 72c7484f1fSmrg# ifdef HAS_PTY_H 73c7484f1fSmrg# include <pty.h> 74c7484f1fSmrg# endif 75c7484f1fSmrg#endif 76c7484f1fSmrg 77c7484f1fSmrg/* Fix ISC brain damage. When using gcc fdopen isn't declared in <stdio.h>. */ 78c7484f1fSmrg#if defined(ISC) && __STDC__ && !defined(ISC30) 79c7484f1fSmrgextern FILE *fdopen(int, char const *); 80c7484f1fSmrg#endif 81c7484f1fSmrg 82c7484f1fSmrgstatic void inputReady(XtPointer w, int *source, XtInputId *id); 83c7484f1fSmrgstatic long TextLength(Widget w); 84c7484f1fSmrgstatic void TextReplace(Widget w, int start, int end, XawTextBlock *block); 85c7484f1fSmrgstatic void TextAppend(Widget w, char *s, int len); 86c7484f1fSmrgstatic void TextInsert(Widget w, char *s, int len); 87c7484f1fSmrgstatic Bool ExceededMaxLines(Widget w); 88c7484f1fSmrgstatic void ScrollLine(Widget w); 89c7484f1fSmrg 90c7484f1fSmrgstatic Widget top, text; 91c7484f1fSmrg 92c7484f1fSmrgstatic XtInputId input_id; 93c7484f1fSmrg 94c7484f1fSmrgstatic FILE *input; 95c7484f1fSmrgstatic Boolean regularFile = FALSE; 96c7484f1fSmrg 97c7484f1fSmrgstatic Boolean notified; 98c7484f1fSmrgstatic Boolean iconified; 99c7484f1fSmrg 100c7484f1fSmrgstatic Atom wm_delete_window; 101c7484f1fSmrgstatic Atom mit_console; 102c7484f1fSmrg 103c7484f1fSmrg#define MIT_CONSOLE_LEN 12 104c7484f1fSmrg#define MIT_CONSOLE "MIT_CONSOLE_" 105c7484f1fSmrgstatic char mit_console_name[255 + MIT_CONSOLE_LEN + 1] = MIT_CONSOLE; 106c7484f1fSmrg 107c7484f1fSmrgstatic struct _app_resources { 108c7484f1fSmrg char *file; 109c7484f1fSmrg Boolean stripNonprint; 110c7484f1fSmrg Boolean notify; 111c7484f1fSmrg Boolean daemon; 112c7484f1fSmrg Boolean verbose; 113c7484f1fSmrg Boolean exitOnFail; 114c7484f1fSmrg int saveLines; 115c7484f1fSmrg} app_resources; 116c7484f1fSmrg 117c7484f1fSmrg#define Offset(field) XtOffsetOf(struct _app_resources, field) 118c7484f1fSmrg 119c7484f1fSmrgstatic XtResource resources[] = { 120c7484f1fSmrg {"file", "File", XtRString, sizeof (char *), 121c7484f1fSmrg Offset (file), XtRString, "console" }, 122c7484f1fSmrg {"notify", "Notify", XtRBoolean, sizeof (Boolean), 123c7484f1fSmrg Offset (notify), XtRImmediate, (XtPointer)True }, 124c7484f1fSmrg {"stripNonprint", "StripNonprint", XtRBoolean, sizeof (Boolean), 125c7484f1fSmrg Offset (stripNonprint), XtRImmediate, (XtPointer)True }, 126c7484f1fSmrg {"daemon", "Daemon", XtRBoolean, sizeof (Boolean), 127c7484f1fSmrg Offset (daemon), XtRImmediate, (XtPointer)False}, 128c7484f1fSmrg {"verbose", "Verbose", XtRBoolean, sizeof (Boolean), 129c7484f1fSmrg Offset (verbose),XtRImmediate, (XtPointer)False}, 130c7484f1fSmrg {"exitOnFail", "ExitOnFail", XtRBoolean, sizeof (Boolean), 131c7484f1fSmrg Offset (exitOnFail),XtRImmediate, (XtPointer)False}, 132c7484f1fSmrg {"saveLines", "SaveLines", XtRInt, sizeof (int), 133c7484f1fSmrg Offset (saveLines), XtRImmediate, (XtPointer) 0 }, 134c7484f1fSmrg}; 135c7484f1fSmrg 136c7484f1fSmrg#undef Offset 137c7484f1fSmrg 138c7484f1fSmrgstatic XrmOptionDescRec options[] = { 139c7484f1fSmrg {"-file", "*file", XrmoptionSepArg, NULL}, 140c7484f1fSmrg {"-notify", "*notify", XrmoptionNoArg, "TRUE"}, 141c7484f1fSmrg {"-nonotify", "*notify", XrmoptionNoArg, "FALSE"}, 142c7484f1fSmrg {"-daemon", "*daemon", XrmoptionNoArg, "TRUE"}, 143c7484f1fSmrg {"-verbose", "*verbose", XrmoptionNoArg, "TRUE"}, 144c7484f1fSmrg {"-exitOnFail", "*exitOnFail", XrmoptionNoArg, "TRUE"}, 145c7484f1fSmrg {"-saveLines", "*saveLines", XrmoptionSepArg, NULL}, 146c7484f1fSmrg}; 147c7484f1fSmrg 148c7484f1fSmrg#ifdef ultrix 149c7484f1fSmrg#define USE_FILE 150c7484f1fSmrg#define FILE_NAME "/dev/xcons" 151c7484f1fSmrg#endif 152c7484f1fSmrg 153c7484f1fSmrg#ifdef __UNIXOS2__ 154c7484f1fSmrg#define USE_FILE 155c7484f1fSmrg#define FILE_NAME "/dev/console$" 156c7484f1fSmrg#define INCL_DOSFILEMGR 157c7484f1fSmrg#define INCL_DOSDEVIOCTL 158c7484f1fSmrg#include <os2.h> 159c7484f1fSmrg#endif 160c7484f1fSmrg 161c7484f1fSmrg#ifdef linux 162c7484f1fSmrg#define USE_FILE 163c7484f1fSmrg#define FILE_NAME "/dev/xconsole" 164c7484f1fSmrg# if defined (__GLIBC__) && ((__GLIBC__ > 2) || (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1)) 165c7484f1fSmrg/* 166c7484f1fSmrg * Linux distribution based on glibc 2.1 and higher should use 167c7484f1fSmrg * devpts. This is the fallback if open file FILE_NAME fails. 168c7484f1fSmrg * <werner@suse.de> 169c7484f1fSmrg */ 170c7484f1fSmrg# define USE_PTS 171c7484f1fSmrg# endif 172c7484f1fSmrg#endif 173c7484f1fSmrg 174c7484f1fSmrg#if defined(_AIX) 175c7484f1fSmrg# define USE_PTS 176c7484f1fSmrg#endif 177c7484f1fSmrg 178c7484f1fSmrg#if !defined (USE_FILE) || defined (linux) 179c7484f1fSmrg# include <sys/ioctl.h> 180c7484f1fSmrg# ifdef hpux 181c7484f1fSmrg# include <termios.h> 182c7484f1fSmrg# endif 183c7484f1fSmrg# if defined (SVR4) || defined (USE_PTS) 184c7484f1fSmrg# include <termios.h> 185c7484f1fSmrg# include <sys/stropts.h> /* for I_PUSH */ 186c7484f1fSmrg# ifdef sun 187c7484f1fSmrg# include <sys/strredir.h> 188c7484f1fSmrg# endif 189c7484f1fSmrg# endif 190c7484f1fSmrg# if defined(TIOCCONS) || defined(SRIOCSREDIR) || defined(Lynx) 191c7484f1fSmrg# define USE_PTY 192c7484f1fSmrgstatic int tty_fd, pty_fd; 193c7484f1fSmrgstatic char ttydev[64], ptydev[64]; 194c7484f1fSmrg# endif 195c7484f1fSmrg#endif 196c7484f1fSmrg 197c7484f1fSmrg#if (defined(SVR4) && !defined(sun)) || (defined(SYSV) && defined(i386)) 198c7484f1fSmrg#define USE_OSM 199c7484f1fSmrg#include <signal.h> 200c7484f1fSmrg#endif 201c7484f1fSmrg 202c7484f1fSmrg#ifdef USE_PTY 203c7484f1fSmrgstatic int get_pty(int *pty, int *tty, char *ttydev, char *ptydev); 204c7484f1fSmrg#endif 205c7484f1fSmrg 206c7484f1fSmrg#ifdef USE_OSM 207c7484f1fSmrgstatic FILE *osm_pipe(void); 208c7484f1fSmrgstatic int child_pid; 209c7484f1fSmrg#endif 210c7484f1fSmrg 211c7484f1fSmrg/* Copied from xterm/ptyx.h */ 212c7484f1fSmrg#ifndef PTYCHAR1 213c7484f1fSmrg#ifdef __hpux 214c7484f1fSmrg#define PTYCHAR1 "zyxwvutsrqp" 215c7484f1fSmrg#else /* !__hpux */ 216c7484f1fSmrg#ifdef __UNIXOS2__ 217c7484f1fSmrg#define PTYCHAR1 "pq" 218c7484f1fSmrg#else 219c7484f1fSmrg#define PTYCHAR1 "pqrstuvwxyzPQRSTUVWXYZ" 220c7484f1fSmrg#endif /* !__UNIXOS2__ */ 221c7484f1fSmrg#endif /* !__hpux */ 222c7484f1fSmrg#endif /* !PTYCHAR1 */ 223c7484f1fSmrg 224c7484f1fSmrg#ifndef PTYCHAR2 225c7484f1fSmrg#ifdef __hpux 226c7484f1fSmrg#define PTYCHAR2 "fedcba9876543210" 227c7484f1fSmrg#else /* !__hpux */ 228c7484f1fSmrg#ifdef __FreeBSD__ 229c7484f1fSmrg#define PTYCHAR2 "0123456789abcdefghijklmnopqrstuv" 230c7484f1fSmrg#else /* !__FreeBSD__ */ 231c7484f1fSmrg#define PTYCHAR2 "0123456789abcdef" 232c7484f1fSmrg#endif /* !__FreeBSD__ */ 233c7484f1fSmrg#endif /* !__hpux */ 234c7484f1fSmrg#endif /* !PTYCHAR2 */ 235c7484f1fSmrg 236c7484f1fSmrg#ifdef Lynx 237c7484f1fSmrgstatic void 238c7484f1fSmrgRestoreConsole(void) 239c7484f1fSmrg{ 240c7484f1fSmrg int fd; 241c7484f1fSmrg if ((fd = open("/dev/con", O_RDONLY)) >= 0) 242c7484f1fSmrg newconsole(fd); 243c7484f1fSmrg} 244c7484f1fSmrg#endif 245c7484f1fSmrg 246c7484f1fSmrgstatic void 247c7484f1fSmrgOpenConsole(void) 248c7484f1fSmrg{ 249c7484f1fSmrg input = 0; 250c7484f1fSmrg if (app_resources.file) 251c7484f1fSmrg { 252c7484f1fSmrg if (!strcmp (app_resources.file, "console")) 253c7484f1fSmrg { 254c7484f1fSmrg /* must be owner and have read/write permission */ 255c7484f1fSmrg#if !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(Lynx) && !defined(__UNIXOS2__) 256c7484f1fSmrg struct stat sbuf; 257c7484f1fSmrg# if !defined (linux) 258c7484f1fSmrg if (!stat("/dev/console", &sbuf) && 259c7484f1fSmrg (sbuf.st_uid == getuid()) && 260c7484f1fSmrg !access("/dev/console", R_OK|W_OK)) 261c7484f1fSmrg# endif 262c7484f1fSmrg#endif 263c7484f1fSmrg { 264c7484f1fSmrg#ifdef USE_FILE 265c7484f1fSmrg# ifdef linux 266c7484f1fSmrg if (!stat(FILE_NAME, &sbuf)) 267c7484f1fSmrg# endif 268c7484f1fSmrg input = fopen (FILE_NAME, "r"); 269c7484f1fSmrg# ifdef __UNIXOS2__ 270c7484f1fSmrg if (input) 271c7484f1fSmrg { 272c7484f1fSmrg ULONG arg = 1,arglen; 273c7484f1fSmrg APIRET rc; 274c7484f1fSmrg if ((rc=DosDevIOCtl(fileno(input), 0x76,0x4d, 275c7484f1fSmrg &arg, sizeof(arg), &arglen, 276c7484f1fSmrg NULL, 0, NULL)) != 0) 277c7484f1fSmrg { 278c7484f1fSmrg fclose(input); 279c7484f1fSmrg input = 0; 280c7484f1fSmrg } 281c7484f1fSmrg } 282c7484f1fSmrg# endif 283c7484f1fSmrg#endif 284c7484f1fSmrg 285c7484f1fSmrg#ifdef USE_PTY 286c7484f1fSmrg if (!input && get_pty (&pty_fd, &tty_fd, ttydev, ptydev) == 0) 287c7484f1fSmrg { 288c7484f1fSmrg# ifdef TIOCCONS 289c7484f1fSmrg int on = 1; 290c7484f1fSmrg if (ioctl (tty_fd, TIOCCONS, (char *) &on) != -1) 291c7484f1fSmrg input = fdopen (pty_fd, "r"); 292c7484f1fSmrg# else 293c7484f1fSmrg# ifndef Lynx 294c7484f1fSmrg int consfd = open("/dev/console", O_RDONLY); 295c7484f1fSmrg if (consfd >= 0) 296c7484f1fSmrg { 297c7484f1fSmrg if (ioctl(consfd, SRIOCSREDIR, tty_fd) != -1) 298c7484f1fSmrg input = fdopen (pty_fd, "r"); 299c7484f1fSmrg close(consfd); 300c7484f1fSmrg } 301c7484f1fSmrg# else 302c7484f1fSmrg if (newconsole(tty_fd) < 0) 303c7484f1fSmrg perror("newconsole"); 304c7484f1fSmrg else 305c7484f1fSmrg { 306c7484f1fSmrg input = fdopen (pty_fd, "r"); 307c7484f1fSmrg atexit(RestoreConsole); 308c7484f1fSmrg } 309c7484f1fSmrg# endif 310c7484f1fSmrg# endif 311c7484f1fSmrg } 312c7484f1fSmrg#endif /* USE_PTY */ 313c7484f1fSmrg } 314c7484f1fSmrg#ifdef USE_OSM 315c7484f1fSmrg /* Don't have to be owner of /dev/console when using /dev/osm. */ 316c7484f1fSmrg if (!input) 317c7484f1fSmrg input = osm_pipe(); 318c7484f1fSmrg#endif 319c7484f1fSmrg if (input && app_resources.verbose) 320c7484f1fSmrg { 321c7484f1fSmrg char *hostname; 322c7484f1fSmrg TextAppend (text, "Console log for ", 16); 323c7484f1fSmrg hostname = mit_console_name + MIT_CONSOLE_LEN; 324c7484f1fSmrg TextAppend (text, hostname, strlen (hostname)); 325c7484f1fSmrg TextAppend (text, "\n", 1); 326c7484f1fSmrg } 327c7484f1fSmrg } 328c7484f1fSmrg else 329c7484f1fSmrg { 330c7484f1fSmrg struct stat sbuf; 331c7484f1fSmrg 332c7484f1fSmrg regularFile = FALSE; 333c7484f1fSmrg if (access(app_resources.file, R_OK) == 0) 334c7484f1fSmrg { 335c7484f1fSmrg input = fopen (app_resources.file, "r"); 336c7484f1fSmrg if (input) 337c7484f1fSmrg if (!stat(app_resources.file, &sbuf) && 338c7484f1fSmrg S_ISREG( sbuf.st_mode ) ) 339c7484f1fSmrg regularFile = TRUE; 340c7484f1fSmrg } 341c7484f1fSmrg } 342c7484f1fSmrg if (!input) 343c7484f1fSmrg { 344c7484f1fSmrg if (app_resources.exitOnFail) 345c7484f1fSmrg exit(0); 346c7484f1fSmrg TextAppend (text, "Couldn't open ", 14); 347c7484f1fSmrg TextAppend (text, app_resources.file, strlen (app_resources.file)); 348c7484f1fSmrg TextAppend (text, "\n", 1); 349c7484f1fSmrg } 350c7484f1fSmrg } 351c7484f1fSmrg else 352c7484f1fSmrg input = stdin; 353c7484f1fSmrg 354c7484f1fSmrg if (input) 355c7484f1fSmrg { 356c7484f1fSmrg input_id = XtAddInput (fileno (input), (XtPointer) XtInputReadMask, 357c7484f1fSmrg inputReady, (XtPointer) text); 358c7484f1fSmrg } 359c7484f1fSmrg} 360c7484f1fSmrg 361c7484f1fSmrgstatic void 362c7484f1fSmrgCloseConsole (void) 363c7484f1fSmrg{ 364c7484f1fSmrg if (input) 365c7484f1fSmrg { 366c7484f1fSmrg XtRemoveInput (input_id); 367c7484f1fSmrg fclose (input); 368c7484f1fSmrg } 369c7484f1fSmrg#ifdef USE_PTY 370c7484f1fSmrg close (tty_fd); 371c7484f1fSmrg#endif 372c7484f1fSmrg} 373c7484f1fSmrg 374c7484f1fSmrg#ifdef USE_OSM 375c7484f1fSmrgstatic void 376c7484f1fSmrgKillChild(int sig) 377c7484f1fSmrg{ 378c7484f1fSmrg if (child_pid > 0) 379c7484f1fSmrg kill(child_pid, SIGTERM); 380c7484f1fSmrg _exit(0); 381c7484f1fSmrg} 382c7484f1fSmrg#endif 383c7484f1fSmrg 384c7484f1fSmrg/*ARGSUSED*/ 385c7484f1fSmrgstatic void 386c7484f1fSmrgQuit(Widget widget, XEvent *event, String *params, Cardinal *num_params) 387c7484f1fSmrg{ 388c7484f1fSmrg#ifdef USE_OSM 389c7484f1fSmrg if (child_pid > 0) 390c7484f1fSmrg kill(child_pid, SIGTERM); 391c7484f1fSmrg#endif 392c7484f1fSmrg exit (0); 393c7484f1fSmrg} 394c7484f1fSmrg 395c7484f1fSmrg#ifdef USE_OSM 396c7484f1fSmrgstatic int (*ioerror)(Display *); 397c7484f1fSmrg 398c7484f1fSmrgstatic int 399c7484f1fSmrgIOError(Display *dpy) 400c7484f1fSmrg{ 401c7484f1fSmrg if (child_pid > 0) 402c7484f1fSmrg kill(child_pid, SIGTERM); 403c7484f1fSmrg return (*ioerror)(dpy); 404c7484f1fSmrg} 405c7484f1fSmrg#endif 406c7484f1fSmrg 407c7484f1fSmrgstatic void 408c7484f1fSmrgNotify(void) 409c7484f1fSmrg{ 410c7484f1fSmrg Arg arglist[1]; 411c7484f1fSmrg char *oldName; 412c7484f1fSmrg char *newName; 413c7484f1fSmrg 414c7484f1fSmrg if (!iconified || !app_resources.notify || notified) 415c7484f1fSmrg return; 416c7484f1fSmrg XtSetArg (arglist[0], XtNiconName, &oldName); 417c7484f1fSmrg XtGetValues (top, arglist, 1); 418c7484f1fSmrg newName = malloc (strlen (oldName) + 3); 419c7484f1fSmrg if (!newName) 420c7484f1fSmrg return; 421c7484f1fSmrg sprintf (newName, "%s *", oldName); 422c7484f1fSmrg XtSetArg (arglist[0], XtNiconName, newName); 423c7484f1fSmrg XtSetValues (top, arglist, 1); 424c7484f1fSmrg free (newName); 425c7484f1fSmrg notified = True; 426c7484f1fSmrg} 427c7484f1fSmrg 428c7484f1fSmrg/*ARGSUSED*/ 429c7484f1fSmrgstatic void 430c7484f1fSmrgDeiconified(Widget widget, XEvent *event, String *params, Cardinal *num_params) 431c7484f1fSmrg{ 432c7484f1fSmrg Arg arglist[1]; 433c7484f1fSmrg char *oldName; 434c7484f1fSmrg char *newName; 435c7484f1fSmrg int oldlen; 436c7484f1fSmrg 437c7484f1fSmrg iconified = False; 438c7484f1fSmrg if (!app_resources.notify || !notified) 439c7484f1fSmrg return; 440c7484f1fSmrg XtSetArg (arglist[0], XtNiconName, &oldName); 441c7484f1fSmrg XtGetValues (top, arglist, 1); 442c7484f1fSmrg oldlen = strlen (oldName); 443c7484f1fSmrg if (oldlen >= 2) 444c7484f1fSmrg { 445c7484f1fSmrg newName = malloc (oldlen - 1); 446c7484f1fSmrg if (!newName) 447c7484f1fSmrg return; 448c7484f1fSmrg strncpy (newName, oldName, oldlen - 2); 449c7484f1fSmrg newName[oldlen - 2] = '\0'; 450c7484f1fSmrg XtSetArg (arglist[0], XtNiconName, newName); 451c7484f1fSmrg XtSetValues (top, arglist, 1); 452c7484f1fSmrg free (newName); 453c7484f1fSmrg } 454c7484f1fSmrg notified = False; 455c7484f1fSmrg} 456c7484f1fSmrg 457c7484f1fSmrg/*ARGSUSED*/ 458c7484f1fSmrgstatic void 459c7484f1fSmrgIconified(Widget widget, XEvent *event, String *params, Cardinal *num_params) 460c7484f1fSmrg{ 461c7484f1fSmrg iconified = True; 462c7484f1fSmrg} 463c7484f1fSmrg 464c7484f1fSmrg/*ARGSUSED*/ 465c7484f1fSmrgstatic void 466c7484f1fSmrgClear(Widget widget, XEvent *event, String *params, Cardinal *num_params) 467c7484f1fSmrg{ 468c7484f1fSmrg long last; 469c7484f1fSmrg XawTextBlock block; 470c7484f1fSmrg 471c7484f1fSmrg last = TextLength (text); 472c7484f1fSmrg block.ptr = ""; 473c7484f1fSmrg block.firstPos = 0; 474c7484f1fSmrg block.length = 0; 475c7484f1fSmrg block.format = FMT8BIT; 476c7484f1fSmrg TextReplace (text, 0, last, &block); 477c7484f1fSmrg} 478c7484f1fSmrg 479c7484f1fSmrgstatic XtActionsRec actions[] = { 480c7484f1fSmrg { "Quit", Quit }, 481c7484f1fSmrg { "Iconified", Iconified }, 482c7484f1fSmrg { "Deiconified", Deiconified }, 483c7484f1fSmrg { "Clear", Clear }, 484c7484f1fSmrg}; 485c7484f1fSmrg 486c7484f1fSmrgstatic void 487c7484f1fSmrgstripNonprint(char *b) 488c7484f1fSmrg{ 489c7484f1fSmrg char *c; 490c7484f1fSmrg 491c7484f1fSmrg c = b; 492c7484f1fSmrg while (*b) 493c7484f1fSmrg { 494c7484f1fSmrg if (isprint (*b) || (isspace (*b) && *b != '\r')) 495c7484f1fSmrg { 496c7484f1fSmrg if (c != b) 497c7484f1fSmrg *c = *b; 498c7484f1fSmrg ++c; 499c7484f1fSmrg } 500c7484f1fSmrg ++b; 501c7484f1fSmrg } 502c7484f1fSmrg *c = '\0'; 503c7484f1fSmrg} 504c7484f1fSmrg 505c7484f1fSmrgstatic void 506c7484f1fSmrginputReady(XtPointer w, int *source, XtInputId *id) 507c7484f1fSmrg{ 508c7484f1fSmrg char buffer[1025]; 509c7484f1fSmrg int n; 510c7484f1fSmrg 511c7484f1fSmrg n = read (*source, buffer, sizeof (buffer) - 1); 512c7484f1fSmrg if (n <= 0) 513c7484f1fSmrg { 514c7484f1fSmrg if (app_resources.file && regularFile && n == 0) 515c7484f1fSmrg { 516c7484f1fSmrg if (XPending(XtDisplay(w))) 517c7484f1fSmrg return; 518c7484f1fSmrg 519c7484f1fSmrg sleep(1); 520c7484f1fSmrg return; 521c7484f1fSmrg } 522c7484f1fSmrg 523c7484f1fSmrg fclose (input); 524c7484f1fSmrg XtRemoveInput (*id); 525c7484f1fSmrg 526c7484f1fSmrg /* try to reopen if pipe; this can be caused by syslog restart */ 527c7484f1fSmrg if (app_resources.file && !regularFile && n == 0) 528c7484f1fSmrg { 529c7484f1fSmrg OpenConsole(); 530c7484f1fSmrg } 531c7484f1fSmrg } else { 532c7484f1fSmrg Notify(); 533c7484f1fSmrg buffer[n] = '\0'; 534c7484f1fSmrg if (app_resources.stripNonprint) 535c7484f1fSmrg { 536c7484f1fSmrg stripNonprint (buffer); 537c7484f1fSmrg n = strlen (buffer); 538c7484f1fSmrg } 539c7484f1fSmrg 540c7484f1fSmrg TextAppend ((Widget) text, buffer, n); 541c7484f1fSmrg } 542c7484f1fSmrg} 543c7484f1fSmrg 544c7484f1fSmrgstatic Boolean 545c7484f1fSmrgConvertSelection(Widget w, Atom *selection, Atom *target, Atom *type, 546c7484f1fSmrg XtPointer *value, unsigned long *length, int *format) 547c7484f1fSmrg{ 548c7484f1fSmrg Display* d = XtDisplay(w); 549c7484f1fSmrg XSelectionRequestEvent* req = 550c7484f1fSmrg XtGetSelectionRequest(w, *selection, (XtRequestId)NULL); 551c7484f1fSmrg 552c7484f1fSmrg if (*target == XA_TARGETS(d)) 553c7484f1fSmrg { 554c7484f1fSmrg Atom* targetP; 555c7484f1fSmrg Atom* std_targets; 556c7484f1fSmrg unsigned long std_length; 557c7484f1fSmrg XmuConvertStandardSelection(w, req->time, selection, target, type, 558c7484f1fSmrg (XPointer *)&std_targets, &std_length, 559c7484f1fSmrg format); 560c7484f1fSmrg *value = (XtPointer)XtMalloc(sizeof(Atom)*(std_length + 5)); 561c7484f1fSmrg targetP = *(Atom**)value; 562c7484f1fSmrg *targetP++ = XA_STRING; 563c7484f1fSmrg *targetP++ = XA_TEXT(d); 564c7484f1fSmrg *targetP++ = XA_LENGTH(d); 565c7484f1fSmrg *targetP++ = XA_LIST_LENGTH(d); 566c7484f1fSmrg *targetP++ = XA_CHARACTER_POSITION(d); 567c7484f1fSmrg *length = std_length + (targetP - (*(Atom **) value)); 568c7484f1fSmrg memmove( (char*)targetP, (char*)std_targets, sizeof(Atom)*std_length); 569c7484f1fSmrg XtFree((char*)std_targets); 570c7484f1fSmrg *type = XA_ATOM; 571c7484f1fSmrg *format = 32; 572c7484f1fSmrg return True; 573c7484f1fSmrg } 574c7484f1fSmrg 575c7484f1fSmrg if (*target == XA_LIST_LENGTH(d) || 576c7484f1fSmrg *target == XA_LENGTH(d)) 577c7484f1fSmrg { 578c7484f1fSmrg long * temp; 579c7484f1fSmrg 580c7484f1fSmrg temp = (long *) XtMalloc(sizeof(long)); 581c7484f1fSmrg if (*target == XA_LIST_LENGTH(d)) 582c7484f1fSmrg *temp = 1L; 583c7484f1fSmrg else /* *target == XA_LENGTH(d) */ 584c7484f1fSmrg *temp = (long) TextLength (text); 585c7484f1fSmrg 586c7484f1fSmrg *value = (XtPointer) temp; 587c7484f1fSmrg *type = XA_INTEGER; 588c7484f1fSmrg *length = 1L; 589c7484f1fSmrg *format = 32; 590c7484f1fSmrg return True; 591c7484f1fSmrg } 592c7484f1fSmrg 593c7484f1fSmrg if (*target == XA_CHARACTER_POSITION(d)) 594c7484f1fSmrg { 595c7484f1fSmrg long * temp; 596c7484f1fSmrg 597c7484f1fSmrg temp = (long *) XtMalloc(2 * sizeof(long)); 598c7484f1fSmrg temp[0] = (long) 0; 599c7484f1fSmrg temp[1] = TextLength (text); 600c7484f1fSmrg *value = (XtPointer) temp; 601c7484f1fSmrg *type = XA_SPAN(d); 602c7484f1fSmrg *length = 2L; 603c7484f1fSmrg *format = 32; 604c7484f1fSmrg return True; 605c7484f1fSmrg } 606c7484f1fSmrg 607c7484f1fSmrg if (*target == XA_STRING || 608c7484f1fSmrg *target == XA_TEXT(d) || 609c7484f1fSmrg *target == XA_COMPOUND_TEXT(d)) 610c7484f1fSmrg { 611c7484f1fSmrg if (*target == XA_COMPOUND_TEXT(d)) 612c7484f1fSmrg *type = *target; 613c7484f1fSmrg else 614c7484f1fSmrg *type = XA_STRING; 615c7484f1fSmrg *length = TextLength (text); 616c7484f1fSmrg *value = (XtPointer)_XawTextGetSTRING((TextWidget) text, 0, *length); 617c7484f1fSmrg *format = 8; 618c7484f1fSmrg /* 619c7484f1fSmrg * Drop our connection to the file; the new console program 620c7484f1fSmrg * will open as soon as it receives the selection contents; there 621c7484f1fSmrg * is a small window where console output will not be redirected, 622c7484f1fSmrg * but I see no way of avoiding that without having two programs 623c7484f1fSmrg * attempt to redirect console output at the same time, which seems 624c7484f1fSmrg * worse 625c7484f1fSmrg */ 626c7484f1fSmrg CloseConsole (); 627c7484f1fSmrg return True; 628c7484f1fSmrg } 629c7484f1fSmrg 630c7484f1fSmrg if (XmuConvertStandardSelection(w, req->time, selection, target, type, 631c7484f1fSmrg (XPointer *)value, length, format)) 632c7484f1fSmrg return True; 633c7484f1fSmrg 634c7484f1fSmrg return False; 635c7484f1fSmrg} 636c7484f1fSmrg 637c7484f1fSmrgstatic void 638c7484f1fSmrgLoseSelection(Widget w, Atom *selection) 639c7484f1fSmrg{ 640c7484f1fSmrg Quit (w, (XEvent*)NULL, (String*)NULL, (Cardinal*)NULL); 641c7484f1fSmrg} 642c7484f1fSmrg 643c7484f1fSmrg/*ARGSUSED*/ 644c7484f1fSmrgstatic void 645c7484f1fSmrgInsertSelection(Widget w, XtPointer client_data, Atom *selection, Atom *type, 646c7484f1fSmrg XtPointer value, unsigned long *length, int *format) 647c7484f1fSmrg{ 648c7484f1fSmrg if (*type != XT_CONVERT_FAIL) 649c7484f1fSmrg TextInsert (text, (char *) value, *length); 650c7484f1fSmrg XtOwnSelection(top, mit_console, CurrentTime, 651c7484f1fSmrg ConvertSelection, LoseSelection, NULL); 652c7484f1fSmrg OpenConsole (); 653c7484f1fSmrg} 654c7484f1fSmrg 655c7484f1fSmrgint 656c7484f1fSmrgmain(int argc, char *argv[]) 657c7484f1fSmrg{ 658c7484f1fSmrg Arg arglist[10]; 659c7484f1fSmrg Cardinal num_args; 660c7484f1fSmrg 661c7484f1fSmrg XtSetLanguageProc(NULL,NULL,NULL); 662c7484f1fSmrg top = XtInitialize ("xconsole", "XConsole", options, XtNumber (options), 663c7484f1fSmrg &argc, argv); 664c7484f1fSmrg XtGetApplicationResources (top, (XtPointer)&app_resources, resources, 665c7484f1fSmrg XtNumber (resources), NULL, 0); 666c7484f1fSmrg 667c7484f1fSmrg if (app_resources.daemon) 668c7484f1fSmrg if (fork ()) exit (0); 669c7484f1fSmrg XtAddActions (actions, XtNumber (actions)); 670c7484f1fSmrg 671c7484f1fSmrg text = XtCreateManagedWidget ("text", asciiTextWidgetClass, 672c7484f1fSmrg top, NULL, 0); 673c7484f1fSmrg 674c7484f1fSmrg XtRealizeWidget (top); 675c7484f1fSmrg num_args = 0; 676c7484f1fSmrg XtSetArg(arglist[num_args], XtNiconic, &iconified); num_args++; 677c7484f1fSmrg XtGetValues(top, arglist, num_args); 678c7484f1fSmrg if (iconified) 679c7484f1fSmrg Iconified((Widget)NULL, (XEvent*)NULL, (String*)NULL, (Cardinal*)NULL); 680c7484f1fSmrg else 681c7484f1fSmrg Deiconified((Widget)NULL,(XEvent*)NULL,(String*)NULL,(Cardinal*)NULL); 682c7484f1fSmrg wm_delete_window = XInternAtom(XtDisplay(top), "WM_DELETE_WINDOW", 683c7484f1fSmrg False); 684c7484f1fSmrg (void) XSetWMProtocols (XtDisplay(top), XtWindow(top), 685c7484f1fSmrg &wm_delete_window, 1); 686c7484f1fSmrg 687c7484f1fSmrg XmuGetHostname (mit_console_name + MIT_CONSOLE_LEN, 255); 688c7484f1fSmrg 689c7484f1fSmrg mit_console = XInternAtom(XtDisplay(top), mit_console_name, False); 690c7484f1fSmrg 691c7484f1fSmrg if (XGetSelectionOwner (XtDisplay (top), mit_console)) 692c7484f1fSmrg { 693c7484f1fSmrg XtGetSelectionValue(top, mit_console, XA_STRING, InsertSelection, 694c7484f1fSmrg NULL, CurrentTime); 695c7484f1fSmrg } 696c7484f1fSmrg else 697c7484f1fSmrg { 698c7484f1fSmrg XtOwnSelection(top, mit_console, CurrentTime, 699c7484f1fSmrg ConvertSelection, LoseSelection, NULL); 700c7484f1fSmrg OpenConsole (); 701c7484f1fSmrg } 702c7484f1fSmrg#ifdef USE_OSM 703c7484f1fSmrg ioerror = XSetIOErrorHandler(IOError); 704c7484f1fSmrg#endif 705c7484f1fSmrg XtMainLoop (); 706c7484f1fSmrg return 0; 707c7484f1fSmrg} 708c7484f1fSmrg 709c7484f1fSmrgstatic long 710c7484f1fSmrgTextLength(Widget w) 711c7484f1fSmrg{ 712c7484f1fSmrg return XawTextSourceScan (XawTextGetSource (w), 713c7484f1fSmrg (XawTextPosition) 0, 714c7484f1fSmrg XawstAll, XawsdRight, 1, TRUE); 715c7484f1fSmrg} 716c7484f1fSmrg 717c7484f1fSmrgstatic void 718c7484f1fSmrgTextReplace(Widget w, int start, int end, XawTextBlock *block) 719c7484f1fSmrg{ 720c7484f1fSmrg Arg arg; 721c7484f1fSmrg Widget source; 722c7484f1fSmrg XawTextEditType edit_mode; 723c7484f1fSmrg 724c7484f1fSmrg source = XawTextGetSource (w); 725c7484f1fSmrg XtSetArg (arg, XtNeditType, &edit_mode); 726c7484f1fSmrg XtGetValues (source, &arg, ONE); 727c7484f1fSmrg XtSetArg (arg, XtNeditType, XawtextEdit); 728c7484f1fSmrg XtSetValues (source, &arg, ONE); 729c7484f1fSmrg XawTextReplace (w, start, end, block); 730c7484f1fSmrg XtSetArg (arg, XtNeditType, edit_mode); 731c7484f1fSmrg XtSetValues (source, &arg, ONE); 732c7484f1fSmrg} 733c7484f1fSmrg 734c7484f1fSmrgstatic void 735c7484f1fSmrgTextAppend(Widget w, char *s, int len) 736c7484f1fSmrg{ 737c7484f1fSmrg long last, current; 738c7484f1fSmrg XawTextBlock block; 739c7484f1fSmrg 740c7484f1fSmrg current = XawTextGetInsertionPoint (w); 741c7484f1fSmrg last = TextLength (w); 742c7484f1fSmrg block.ptr = s; 743c7484f1fSmrg block.firstPos = 0; 744c7484f1fSmrg block.length = len; 745c7484f1fSmrg block.format = FMT8BIT; 746c7484f1fSmrg /* 747c7484f1fSmrg * If saveLines is 1, just replace the entire contents of the widget 748c7484f1fSmrg * each time, so the test in ExceededMaxLines() isn't fooled. 749c7484f1fSmrg */ 750c7484f1fSmrg if (app_resources.saveLines == 1) 751c7484f1fSmrg TextReplace (w, 0, last, &block); 752c7484f1fSmrg else 753c7484f1fSmrg TextReplace (w, last, last, &block); 754c7484f1fSmrg if (current == last) 755c7484f1fSmrg XawTextSetInsertionPoint (w, last + block.length); 756c7484f1fSmrg if (ExceededMaxLines(w)) 757c7484f1fSmrg ScrollLine(w); 758c7484f1fSmrg} 759c7484f1fSmrg 760c7484f1fSmrgstatic void 761c7484f1fSmrgTextInsert(Widget w, char *s, int len) 762c7484f1fSmrg{ 763c7484f1fSmrg XawTextBlock block; 764c7484f1fSmrg long current; 765c7484f1fSmrg 766c7484f1fSmrg current = XawTextGetInsertionPoint (w); 767c7484f1fSmrg block.ptr = s; 768c7484f1fSmrg block.firstPos = 0; 769c7484f1fSmrg block.length = len; 770c7484f1fSmrg block.format = FMT8BIT; 771c7484f1fSmrg TextReplace (w, 0, 0, &block); 772c7484f1fSmrg if (current == 0) 773c7484f1fSmrg XawTextSetInsertionPoint (w, len); 774c7484f1fSmrg if (ExceededMaxLines(w)) 775c7484f1fSmrg ScrollLine(w); 776c7484f1fSmrg} 777c7484f1fSmrg 778c7484f1fSmrgstatic Bool 779c7484f1fSmrgExceededMaxLines(Widget w) 780c7484f1fSmrg{ 781c7484f1fSmrg XawTextPosition end_of_last_line; 782c7484f1fSmrg Bool retval = False; 783c7484f1fSmrg 784c7484f1fSmrg if (app_resources.saveLines > 0) 785c7484f1fSmrg { 786c7484f1fSmrg /* 787c7484f1fSmrg * XawTextSourceScan() will return the end of the widget if it cannot 788c7484f1fSmrg * find what it is searching for. 789c7484f1fSmrg */ 790c7484f1fSmrg end_of_last_line = XawTextSourceScan (XawTextGetSource (w), 791c7484f1fSmrg (XawTextPosition) 0, 792c7484f1fSmrg XawstEOL, XawsdRight, 793c7484f1fSmrg app_resources.saveLines, TRUE); 794c7484f1fSmrg if (TextLength(w) > end_of_last_line) 795c7484f1fSmrg retval = True; 796c7484f1fSmrg else 797c7484f1fSmrg retval = False; 798c7484f1fSmrg } 799c7484f1fSmrg else 800c7484f1fSmrg retval = False; 801c7484f1fSmrg return retval; 802c7484f1fSmrg} 803c7484f1fSmrg 804c7484f1fSmrgstatic void 805c7484f1fSmrgScrollLine(Widget w) 806c7484f1fSmrg{ 807c7484f1fSmrg XawTextPosition firstnewline; 808c7484f1fSmrg XawTextBlock block; 809c7484f1fSmrg 810c7484f1fSmrg /* 811c7484f1fSmrg * This is pretty inefficient but should work well enough unless the 812c7484f1fSmrg * console device is getting totally spammed. Generally, new lines 813c7484f1fSmrg * only come in one at a time anyway. 814c7484f1fSmrg */ 815c7484f1fSmrg firstnewline = XawTextSourceScan (XawTextGetSource (w), 816c7484f1fSmrg (XawTextPosition) 0, 817c7484f1fSmrg XawstEOL, XawsdRight, 1, TRUE); 818c7484f1fSmrg block.ptr = ""; 819c7484f1fSmrg block.firstPos = 0; 820c7484f1fSmrg block.length = 0; 821c7484f1fSmrg block.format = FMT8BIT; 822c7484f1fSmrg TextReplace (w, 0, firstnewline, &block); 823c7484f1fSmrg} 824c7484f1fSmrg 825c7484f1fSmrg#ifdef USE_PTY 826c7484f1fSmrg/* 827c7484f1fSmrg * This function opens up a pty master and stuffs its value into pty. 828c7484f1fSmrg * If it finds one, it returns a value of 0. If it does not find one, 829c7484f1fSmrg * it returns a value of !0. This routine is designed to be re-entrant, 830c7484f1fSmrg * so that if a pty master is found and later, we find that the slave 831c7484f1fSmrg * has problems, we can re-enter this function and get another one. 832c7484f1fSmrg */ 833c7484f1fSmrg 834c7484f1fSmrgstatic int 835c7484f1fSmrgget_pty(int *pty, int *tty, char *ttydev, char *ptydev) 836c7484f1fSmrg{ 837c7484f1fSmrg#ifdef HAS_OPENPTY 838c7484f1fSmrg if (openpty(pty, tty, NULL, NULL, NULL) == -1) { 839c7484f1fSmrg return 1; 840c7484f1fSmrg } 841c7484f1fSmrg return 0; 842c7484f1fSmrg#elif defined (SVR4) || defined (USE_PTS) 843c7484f1fSmrg#if defined (_AIX) 844c7484f1fSmrg if ((*pty = open ("/dev/ptc", O_RDWR)) < 0) 845c7484f1fSmrg#else 846c7484f1fSmrg if ((*pty = open ("/dev/ptmx", O_RDWR)) < 0) 847c7484f1fSmrg#endif 848c7484f1fSmrg return 1; 849c7484f1fSmrg grantpt(*pty); 850c7484f1fSmrg unlockpt(*pty); 851c7484f1fSmrg strcpy(ttydev, (char *)ptsname(*pty)); 852c7484f1fSmrg if ((*tty = open(ttydev, O_RDWR)) >= 0) 853c7484f1fSmrg { 854c7484f1fSmrg (void)ioctl(*tty, I_PUSH, "ttcompat"); 855c7484f1fSmrg return 0; 856c7484f1fSmrg } 857c7484f1fSmrg if (*pty >= 0) 858c7484f1fSmrg close (*pty); 859c7484f1fSmrg#else /* !SVR4, need lots of code */ 860c7484f1fSmrg#ifdef USE_GET_PSEUDOTTY 861c7484f1fSmrg if ((*pty = getpseudotty (&ttydev, &ptydev)) >= 0 && 862c7484f1fSmrg (*tty = open (ttydev, O_RDWR)) >= 0) 863c7484f1fSmrg return 0; 864c7484f1fSmrg if (*pty >= 0) 865c7484f1fSmrg close (*pty); 866c7484f1fSmrg#else 867c7484f1fSmrg static int devindex, letter = 0; 868c7484f1fSmrg 869c7484f1fSmrg#if defined(umips) && defined (SYSTYPE_SYSV) 870c7484f1fSmrg struct stat fstat_buf; 871c7484f1fSmrg 872c7484f1fSmrg *pty = open ("/dev/ptc", O_RDWR); 873c7484f1fSmrg if (*pty < 0 || (fstat (*pty, &fstat_buf)) < 0) 874c7484f1fSmrg { 875c7484f1fSmrg return(1); 876c7484f1fSmrg } 877c7484f1fSmrg sprintf (ttydev, "/dev/ttyq%d", minor(fstat_buf.st_rdev)); 878c7484f1fSmrg sprintf (ptydev, "/dev/ptyq%d", minor(fstat_buf.st_rdev)); 879c7484f1fSmrg if ((*tty = open (ttydev, O_RDWR)) >= 0) 880c7484f1fSmrg { 881c7484f1fSmrg /* got one! */ 882c7484f1fSmrg return(0); 883c7484f1fSmrg } 884c7484f1fSmrg close (*pty); 885c7484f1fSmrg#else /* not (umips && SYSTYPE_SYSV) */ 886c7484f1fSmrg#ifdef CRAY 887c7484f1fSmrg for (; devindex < 256; devindex++) { 888c7484f1fSmrg sprintf (ttydev, "/dev/ttyp%03d", devindex); 889c7484f1fSmrg sprintf (ptydev, "/dev/pty/%03d", devindex); 890c7484f1fSmrg 891c7484f1fSmrg if ((*pty = open (ptydev, O_RDWR)) >= 0 && 892c7484f1fSmrg (*tty = open (ttydev, O_RDWR)) >= 0) 893c7484f1fSmrg { 894c7484f1fSmrg /* 895c7484f1fSmrg * We need to set things up for our next entry 896c7484f1fSmrg * into this function! 897c7484f1fSmrg */ 898c7484f1fSmrg (void) devindex++; 899c7484f1fSmrg return(0); 900c7484f1fSmrg } 901c7484f1fSmrg if (*pty >= 0) 902c7484f1fSmrg close (*pty); 903c7484f1fSmrg } 904c7484f1fSmrg#else /* !CRAY */ 905c7484f1fSmrg#ifdef sgi 906c7484f1fSmrg { 907c7484f1fSmrg char *slave; 908c7484f1fSmrg slave = _getpty (pty, O_RDWR, 0622, 0); 909c7484f1fSmrg if ((*tty = open (slave, O_RDWR)) != -1) 910c7484f1fSmrg return 0; 911c7484f1fSmrg } 91238cd97f3Ssimonb#else 91338cd97f3Ssimonb#if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) 91438cd97f3Ssimonb return openpty(pty, tty, ttydev, NULL, NULL); 915c7484f1fSmrg#else 916c7484f1fSmrg strcpy (ttydev, "/dev/ttyxx"); 917c7484f1fSmrg strcpy (ptydev, "/dev/ptyxx"); 918c7484f1fSmrg while (PTYCHAR1[letter]) { 919c7484f1fSmrg ttydev [strlen(ttydev) - 2] = ptydev [strlen(ptydev) - 2] = 920c7484f1fSmrg PTYCHAR1 [letter]; 921c7484f1fSmrg 922c7484f1fSmrg while (PTYCHAR2[devindex]) { 923c7484f1fSmrg ttydev [strlen(ttydev) - 1] = ptydev [strlen(ptydev) - 1] = 924c7484f1fSmrg PTYCHAR2 [devindex]; 925c7484f1fSmrg if ((*pty = open (ptydev, O_RDWR)) >= 0 && 926c7484f1fSmrg (*tty = open (ttydev, O_RDWR)) >= 0) 927c7484f1fSmrg { 928c7484f1fSmrg /* 929c7484f1fSmrg * We need to set things up for our next entry 930c7484f1fSmrg * into this function! 931c7484f1fSmrg */ 932c7484f1fSmrg (void) devindex++; 933c7484f1fSmrg return(0); 934c7484f1fSmrg } 935c7484f1fSmrg if (*pty >= 0) 936c7484f1fSmrg close (*pty); 937c7484f1fSmrg devindex++; 938c7484f1fSmrg } 939c7484f1fSmrg devindex = 0; 940c7484f1fSmrg (void) letter++; 941c7484f1fSmrg } 94238cd97f3Ssimonb#endif /* BSD4_4 else not BSD4_4 */ 943c7484f1fSmrg#endif /* sgi else not sgi */ 944c7484f1fSmrg#endif /* CRAY else not CRAY */ 945c7484f1fSmrg#endif /* umips && SYSTYPE_SYSV */ 946c7484f1fSmrg#endif /* USE_GET_PSEUDOTTY */ 947c7484f1fSmrg#endif /* SVR4 */ 948c7484f1fSmrg /* 949c7484f1fSmrg * We were unable to allocate a pty master! Return an error 950c7484f1fSmrg * condition and let our caller terminate cleanly. 951c7484f1fSmrg */ 952c7484f1fSmrg return(1); 953c7484f1fSmrg} 954c7484f1fSmrg#endif 955c7484f1fSmrg 956c7484f1fSmrg#ifdef USE_OSM 957c7484f1fSmrg/* 958c7484f1fSmrg * On SYSV386 there is a special device, /dev/osm, where system messages 959c7484f1fSmrg * are sent. Problem is that we can't perform a select(2) on this device. 960c7484f1fSmrg * So this routine creates a streams-pty where one end reads the device and 961c7484f1fSmrg * sends the output to xconsole. 962c7484f1fSmrg */ 963c7484f1fSmrg 964c7484f1fSmrg#ifdef SCO325 965c7484f1fSmrg#define OSM_DEVICE "/dev/error" 966c7484f1fSmrg#else 967c7484f1fSmrg#ifdef __UNIXWARE__ 968c7484f1fSmrg#define OSM_DEVICE "/dev/osm2" 969c7484f1fSmrg#define NO_READAHEAD 970c7484f1fSmrg#else 971c7484f1fSmrg#define OSM_DEVICE "/dev/osm" 972c7484f1fSmrg#endif 973c7484f1fSmrg#endif 974c7484f1fSmrg 975c7484f1fSmrg#ifdef ISC 976c7484f1fSmrg#define NO_READAHEAD 977c7484f1fSmrg#endif 978c7484f1fSmrg 979c7484f1fSmrgstatic FILE * 980c7484f1fSmrgosm_pipe(void) 981c7484f1fSmrg{ 982c7484f1fSmrg int tty; 983c7484f1fSmrg char ttydev[64]; 984c7484f1fSmrg 985c7484f1fSmrg if (access(OSM_DEVICE, R_OK) < 0) 986c7484f1fSmrg return NULL; 987c7484f1fSmrg#if defined (_AIX) 988c7484f1fSmrg if ((tty = open("/dev/ptc", O_RDWR)) < 0) 989c7484f1fSmrg#else 990c7484f1fSmrg if ((tty = open("/dev/ptmx", O_RDWR)) < 0) 991c7484f1fSmrg#endif 992c7484f1fSmrg return NULL; 993c7484f1fSmrg 994c7484f1fSmrg grantpt(tty); 995c7484f1fSmrg unlockpt(tty); 996c7484f1fSmrg strcpy(ttydev, (char *)ptsname(tty)); 997c7484f1fSmrg 998c7484f1fSmrg if ((child_pid = fork()) == 0) 999c7484f1fSmrg { 1000c7484f1fSmrg int pty, osm, nbytes, skip; 1001c7484f1fSmrg char cbuf[128]; 1002c7484f1fSmrg 1003c7484f1fSmrg skip = 0; 1004c7484f1fSmrg#ifndef NO_READAHEAD 1005c7484f1fSmrg osm = open(OSM_DEVICE, O_RDONLY); 1006c7484f1fSmrg if (osm >= 0) 1007c7484f1fSmrg { 1008c7484f1fSmrg while ((nbytes = read(osm, cbuf, sizeof(cbuf))) > 0) 1009c7484f1fSmrg skip += nbytes; 1010c7484f1fSmrg close(osm); 1011c7484f1fSmrg } 1012c7484f1fSmrg#endif 1013c7484f1fSmrg pty = open(ttydev, O_RDWR); 1014c7484f1fSmrg if (pty < 0) 1015c7484f1fSmrg exit(1); 1016c7484f1fSmrg osm = open(OSM_DEVICE, O_RDONLY); 1017c7484f1fSmrg if (osm < 0) 1018c7484f1fSmrg exit(1); 1019c7484f1fSmrg for (nbytes = 0; skip > 0 && nbytes >= 0; skip -= nbytes) 1020c7484f1fSmrg { 1021c7484f1fSmrg nbytes = skip; 1022c7484f1fSmrg if (nbytes > sizeof(cbuf)) 1023c7484f1fSmrg nbytes = sizeof(cbuf); 1024c7484f1fSmrg nbytes = read(osm, cbuf, nbytes); 1025c7484f1fSmrg } 1026c7484f1fSmrg while ((nbytes = read(osm, cbuf, sizeof(cbuf))) >= 0) 1027c7484f1fSmrg write(pty, cbuf, nbytes); 1028c7484f1fSmrg exit(0); 1029c7484f1fSmrg } 1030c7484f1fSmrg signal(SIGHUP, KillChild); 1031c7484f1fSmrg signal(SIGINT, KillChild); 1032c7484f1fSmrg signal(SIGTERM, KillChild); 1033c7484f1fSmrg return fdopen(tty, "r"); 1034c7484f1fSmrg} 1035c7484f1fSmrg#endif /* USE_OSM */ 1036