+++ /dev/null
-/*
- * usystem.c -- X-free, but Unix-like code for XBoard front end
- *
- * Copyright 1991 by Digital Equipment Corporation, Maynard,
- * Massachusetts.
- *
- * Enhancements Copyright 1992-2001, 2002, 2003, 2004, 2005, 2006,
- * 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Free
- * Software Foundation, Inc.
- *
- * The following terms apply to Digital Equipment Corporation's copyright
- * interest in XBoard:
- * ------------------------------------------------------------------------
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of Digital not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
- * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
- * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
- * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
- * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
- * SOFTWARE.
- * ------------------------------------------------------------------------
- *
- * The following terms apply to the enhanced version of XBoard
- * distributed by the Free Software Foundation:
- * ------------------------------------------------------------------------
- *
- * GNU XBoard 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 3 of the License, or (at
- * your option) any later version.
- *
- * GNU XBoard 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, see http://www.gnu.org/licenses/. *
- *
- *------------------------------------------------------------------------
- ** See the file ChangeLog for a revision history. */
-
-#include "config.h"
-
-#include <stdio.h>
-#include <ctype.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <pwd.h>
-#include <math.h>
-
-#if !OMIT_SOCKETS
-# if HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-# include <netinet/in.h>
-# include <netdb.h>
-# else /* not HAVE_SYS_SOCKET_H */
-# if HAVE_LAN_SOCKET_H
-# include <lan/socket.h>
-# include <lan/in.h>
-# include <lan/netdb.h>
-# else /* not HAVE_LAN_SOCKET_H */
-# define OMIT_SOCKETS 1
-# endif /* not HAVE_LAN_SOCKET_H */
-# endif /* not HAVE_SYS_SOCKET_H */
-#endif /* !OMIT_SOCKETS */
-
-#if STDC_HEADERS
-# include <stdlib.h>
-# include <string.h>
-#else /* not STDC_HEADERS */
-extern char *getenv();
-# if HAVE_STRING_H
-# include <string.h>
-# else /* not HAVE_STRING_H */
-# include <strings.h>
-# endif /* not HAVE_STRING_H */
-#endif /* not STDC_HEADERS */
-
-#if HAVE_SYS_FCNTL_H
-# include <sys/fcntl.h>
-#else /* not HAVE_SYS_FCNTL_H */
-# if HAVE_FCNTL_H
-# include <fcntl.h>
-# endif /* HAVE_FCNTL_H */
-#endif /* not HAVE_SYS_FCNTL_H */
-
-#if HAVE_SYS_SYSTEMINFO_H
-# include <sys/systeminfo.h>
-#endif /* HAVE_SYS_SYSTEMINFO_H */
-
-#if TIME_WITH_SYS_TIME
-# include <sys/time.h>
-# include <time.h>
-#else
-# if HAVE_SYS_TIME_H
-# include <sys/time.h>
-# else
-# include <time.h>
-# endif
-#endif
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#if HAVE_SYS_WAIT_H
-# include <sys/wait.h>
-#endif
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-# define HAVE_DIR_STRUCT
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# define HAVE_DIR_STRUCT
-# endif
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# define HAVE_DIR_STRUCT
-# endif
-# if HAVE_NDIR_H
-# include <ndir.h>
-# define HAVE_DIR_STRUCT
-# endif
-#endif
-
-#if ENABLE_NLS
-#include <locale.h>
-#endif
-
-// [HGM] bitmaps: put before incuding the bitmaps / pixmaps, to know how many piece types there are.
-#include "common.h"
-
-#include "frontend.h"
-#include "backend.h"
-#include "childio.h"
-#include "menus.h"
-#include "usystem.h"
-#include "gettext.h"
-
-
-#ifdef __EMX__
-#ifndef HAVE_USLEEP
-#define HAVE_USLEEP
-#endif
-#define usleep(t) _sleep2(((t)+500)/1000)
-#endif
-
-#ifdef ENABLE_NLS
-# define _(s) gettext (s)
-# define N_(s) gettext_noop (s)
-#else
-# define _(s) (s)
-# define N_(s) s
-#endif
-
-static int get_term_width P(());
-
-static char *cnames[9] = { "black", "red", "green", "yellow", "blue",
- "magenta", "cyan", "white" };
-TextColors textColors[(int)NColorClasses];
-
-/* String is: "fg, bg, attr". Which is 0, 1, 2 */
-static int
-parse_color (char *str, int which)
-{
- char *p, buf[100], *d;
- int i;
-
- if (strlen(str) > 99) /* watch bounds on buf */
- return -1;
-
- p = str;
- d = buf;
- for (i=0; i<which; ++i) {
- p = strchr(p, ',');
- if (!p)
- return -1;
- ++p;
- }
-
- /* Could be looking at something like:
- black, , 1
- .. in which case we want to stop on a comma also */
- while (*p && *p != ',' && !isalpha(*p) && !isdigit(*p))
- ++p;
-
- if (*p == ',') {
- return -1; /* Use default for empty field */
- }
-
- if (which == 2 || isdigit(*p))
- return atoi(p);
-
- while (*p && isalpha(*p))
- *(d++) = *(p++);
-
- *d = 0;
-
- for (i=0; i<8; ++i) {
- if (!StrCaseCmp(buf, cnames[i]))
- return which? (i+40) : (i+30);
- }
- if (!StrCaseCmp(buf, "default")) return -1;
-
- fprintf(stderr, _("%s: unrecognized color %s\n"), programName, buf);
- return -2;
-}
-
-static int
-parse_cpair (ColorClass cc, char *str)
-{
- if ((textColors[(int)cc].fg=parse_color(str, 0)) == -2) {
- fprintf(stderr, _("%s: can't parse foreground color in '%s'\n"),
- programName, str);
- return -1;
- }
-
- /* bg and attr are optional */
- textColors[(int)cc].bg = parse_color(str, 1);
- if ((textColors[(int)cc].attr = parse_color(str, 2)) < 0) {
- textColors[(int)cc].attr = 0;
- }
- return 0;
-}
-
-void
-ParseIcsTextColors ()
-{ // [HGM] tken out of main(), so it can be called from ICS-Options dialog
- if (parse_cpair(ColorShout, appData.colorShout) < 0 ||
- parse_cpair(ColorSShout, appData.colorSShout) < 0 ||
- parse_cpair(ColorChannel1, appData.colorChannel1) < 0 ||
- parse_cpair(ColorChannel, appData.colorChannel) < 0 ||
- parse_cpair(ColorKibitz, appData.colorKibitz) < 0 ||
- parse_cpair(ColorTell, appData.colorTell) < 0 ||
- parse_cpair(ColorChallenge, appData.colorChallenge) < 0 ||
- parse_cpair(ColorRequest, appData.colorRequest) < 0 ||
- parse_cpair(ColorSeek, appData.colorSeek) < 0 ||
- parse_cpair(ColorNormal, appData.colorNormal) < 0)
- {
- if (appData.colorize) {
- fprintf(stderr,
- _("%s: can't parse color names; disabling colorization\n"),
- programName);
- }
- appData.colorize = FALSE;
- }
- textColors[ColorNone].fg = textColors[ColorNone].bg = -1;
- textColors[ColorNone].attr = 0;
- SetTextColor(cnames, textColors[ColorNormal].fg - 30, textColors[ColorNormal].bg - 40, -2); // kludge to announce background color to front-end
-}
-
-char *oldICSInteractionTitle;
-
-void
-ShutDownFrontEnd ()
-{
- if (appData.icsActive && oldICSInteractionTitle != NULL) {
- DisplayIcsInteractionTitle(oldICSInteractionTitle);
- }
- if (saveSettingsOnExit) SaveSettings(settingsFileName);
- unlink(gameCopyFilename);
- unlink(gamePasteFilename);
- EchoOn();
-}
-
-void
-RunCommand (char *buf)
-{
- system(buf);
-}
-
-void
-Colorize (ColorClass cc, int continuation)
-{
- char buf[MSG_SIZ];
- int count, outCount, error;
-
- SetTextColor(cnames, textColors[(int)cc].fg - 30, textColors[(int)cc].bg - 40, textColors[(int)cc].attr); // for GTK widget
-
- if (textColors[(int)cc].bg > 0) {
- if (textColors[(int)cc].fg > 0) {
- snprintf(buf, MSG_SIZ, "\033[0;%d;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].fg, textColors[(int)cc].bg);
- } else {
- snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].bg);
- }
- } else {
- if (textColors[(int)cc].fg > 0) {
- snprintf(buf, MSG_SIZ, "\033[0;%d;%dm", textColors[(int)cc].attr,
- textColors[(int)cc].fg);
- } else {
- snprintf(buf, MSG_SIZ, "\033[0;%dm", textColors[(int)cc].attr);
- }
- }
- count = strlen(buf);
- outCount = OutputToProcess(NoProc, buf, count, &error);
- if (outCount < count) {
- DisplayFatalError(_("Error writing to display"), error, 1);
- }
-
- if (continuation) return;
- PlaySoundForColor(cc);
-}
-
-char *
-UserName ()
-{
- return getpwuid(getuid())->pw_name;
-}
-
-char *
-ExpandPathName (char *path)
-{
- static char static_buf[4*MSG_SIZ];
- char *d, *s, buf[4*MSG_SIZ];
- struct passwd *pwd;
-
- s = path;
- d = static_buf;
-
- while (*s && isspace(*s))
- ++s;
-
- if (!*s) {
- *d = 0;
- return static_buf;
- }
-
- if (*s == '~') {
- if(s[1] == '~') { // use ~~ for XBoard's private data directory
- snprintf(d, 4*MSG_SIZ, "%s%s", dataDir, s+2);
- } else
- if (*(s+1) == '/') {
- safeStrCpy(d, getpwuid(getuid())->pw_dir, 4*MSG_SIZ );
- strcat(d, s+1);
- }
- else {
- safeStrCpy(buf, s+1, sizeof(buf)/sizeof(buf[0]) );
- { char *p; if(p = strchr(buf, '/')) *p = 0; }
- pwd = getpwnam(buf);
- if (!pwd)
- {
- fprintf(stderr, _("ERROR: Unknown user %s (in path %s)\n"),
- buf, path);
- return NULL;
- }
- safeStrCpy(d, pwd->pw_dir, 4*MSG_SIZ );
- strcat(d, strchr(s+1, '/'));
- }
- }
- else
- safeStrCpy(d, s, 4*MSG_SIZ );
-
- return static_buf;
-}
-
-int
-MySearchPath (char *installDir, char *name, char *fullname)
-{ // just append installDir and name. Perhaps ExpandPath should be used here?
- name = ExpandPathName(name);
- if(name && name[0] == '/')
- safeStrCpy(fullname, name, MSG_SIZ );
- else {
- sprintf(fullname, "%s%c%s", installDir, '/', name);
- }
- return 1;
-}
-
-int
-MyGetFullPathName (char *name, char *fullname)
-{ // should use ExpandPath?
- name = ExpandPathName(name);
- safeStrCpy(fullname, name, MSG_SIZ );
- return 1;
-}
-
-char *
-HostName ()
-{
- static char host_name[MSG_SIZ];
-
-#if HAVE_GETHOSTNAME
- gethostname(host_name, MSG_SIZ);
- return host_name;
-#else /* not HAVE_GETHOSTNAME */
-# if HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H
- sysinfo(SI_HOSTNAME, host_name, MSG_SIZ);
- return host_name;
-# else /* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
- return "localhost";
-# endif/* not (HAVE_SYSINFO && HAVE_SYS_SYSTEMINFO_H) */
-#endif /* not HAVE_GETHOSTNAME */
-}
-
-
-int
-StartChildProcess (char *cmdLine, char *dir, ProcRef *pr)
-{
- char *argv[64], *p;
- int i, pid;
- int to_prog[2], from_prog[2];
- ChildProc *cp;
- char buf[MSG_SIZ];
-
- if (appData.debugMode) {
- fprintf(debugFP, "StartChildProcess (dir=\"%s\") %s\n",dir, cmdLine);
- }
-
- /* We do NOT feed the cmdLine to the shell; we just
- parse it into blank-separated arguments in the
- most simple-minded way possible.
- */
- i = 0;
- safeStrCpy(buf, cmdLine, sizeof(buf)/sizeof(buf[0]) );
- p = buf;
- for (;;) {
- while(*p == ' ') p++;
- argv[i++] = p;
- if(*p == '"' || *p == '\'')
- p = strchr(++argv[i-1], *p);
- else p = strchr(p, ' ');
- if (p == NULL) break;
- *p++ = NULLCHAR;
- }
- argv[i] = NULL;
-
- SetUpChildIO(to_prog, from_prog);
-
- if ((pid = fork()) == 0) {
- /* Child process */
- // [HGM] PSWBTM: made order resistant against case where fd of created pipe was 0 or 1
- close(to_prog[1]); // first close the unused pipe ends
- close(from_prog[0]);
- dup2(to_prog[0], 0); // to_prog was created first, nd is the only one to use 0 or 1
- dup2(from_prog[1], 1);
- if(to_prog[0] >= 2) close(to_prog[0]); // if 0 or 1, the dup2 already cosed the original
- close(from_prog[1]); // and closing again loses one of the pipes!
- if(fileno(stderr) >= 2) // better safe than sorry...
- dup2(1, fileno(stderr)); /* force stderr to the pipe */
-
- if (dir[0] != NULLCHAR && chdir(dir) != 0) {
- perror(dir);
- exit(1);
- }
-
- nice(appData.niceEngines); // [HGM] nice: adjust priority of engine proc
-
- execvp(argv[0], argv);
-
- /* If we get here, exec failed */
- perror(argv[0]);
- exit(1);
- }
-
- /* Parent process */
- close(to_prog[0]);
- close(from_prog[1]);
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPReal;
- cp->pid = pid;
- cp->fdFrom = from_prog[0];
- cp->fdTo = to_prog[1];
- *pr = (ProcRef) cp;
- return 0;
-}
-
-// [HGM] kill: implement the 'hard killing' of AS's Winboard_x
-static int pid;
-
-static RETSIGTYPE
-AlarmCallBack (int n)
-{
- kill(pid, SIGKILL); // kill forcefully
- return;
-}
-
-void
-DestroyChildProcess (ProcRef pr, int signalType)
-{
- ChildProc *cp = (ChildProc *) pr;
-
- if (cp->kind != CPReal) return;
- cp->kind = CPNone;
- if (signalType & 1) {
- kill(cp->pid, signalType == 9 ? SIGKILL : SIGTERM); // [HGM] kill: for 9 hard-kill immediately
- }
- signal(SIGALRM, AlarmCallBack);
- pid = cp->pid;
- if(signalType & 4) alarm(1 + appData.delayAfterQuit); // [HGM] kill: schedule hard kill if so requested
- /* Process is exiting either because of the kill or because of
- a quit command sent by the backend; either way, wait for it to die.
- */
- wait((int *) 0);
- alarm(0); // cancel alarm if still pending
- close(cp->fdFrom);
- close(cp->fdTo);
-}
-
-char *
-BufferCommandOutput (char *command, int size)
-{
- char *res = (char *) calloc(1, size);
- if(res) {
- int count;
- FILE *f;
-#if 0
- ChildProc *pr;
- StartChildProcess(command, ".", (ProcRef) &pr); // run command in daughter process
- f = fdopen(pr->fdFrom, "r");
- count = fread(res, 1, size-1, f); // read its output
- fclose(f);
- DestroyChildProcess((ProcRef) pr, 9);
- free(pr);
-#else
- f = popen(command, "r");
- if(!f) return res;
- count = fread(res, 1, size-1, f); // read its output
- pclose(f);
-#endif
- res[count > 0 ? count : 0] = NULLCHAR;
- }
- return res; // return buffer with output
-}
-
-void
-InterruptChildProcess (ProcRef pr)
-{
- ChildProc *cp = (ChildProc *) pr;
-
- if (cp->kind != CPReal) return;
- (void) kill(cp->pid, SIGINT); /* stop it thinking */
-}
-
-int
-OpenTelnet (char *host, char *port, ProcRef *pr)
-{
- char cmdLine[MSG_SIZ];
-
- if (port[0] == NULLCHAR) {
- snprintf(cmdLine, sizeof(cmdLine), "%s %s", appData.telnetProgram, host);
- } else {
- snprintf(cmdLine, sizeof(cmdLine), "%s %s %s", appData.telnetProgram, host, port);
- }
- return StartChildProcess(cmdLine, "", pr);
-}
-
-int
-OpenTCP (char *host, char *port, ProcRef *pr)
-{
-#if OMIT_SOCKETS
- DisplayFatalError(_("Socket support is not configured in"), 0, 2);
-#else /* !OMIT_SOCKETS */
- struct addrinfo hints;
- struct addrinfo *ais, *ai;
- int error;
- int s=0;
- ChildProc *cp;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
-
- error = getaddrinfo(host, port, &hints, &ais);
- if (error != 0) {
- /* a getaddrinfo error is not an errno, so can't return it */
- fprintf(debugFP, "getaddrinfo(%s, %s): %s\n",
- host, port, gai_strerror(error));
- return ENOENT;
- }
-
- for (ai = ais; ai != NULL; ai = ai->ai_next) {
- if ((s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol)) < 0) {
- error = errno;
- continue;
- }
- if (connect(s, ai->ai_addr, ai->ai_addrlen) < 0) {
- error = errno;
- continue;
- }
- error = 0;
- break;
- }
- freeaddrinfo(ais);
-
- if (error != 0) {
- return error;
- }
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPSock;
- cp->pid = 0;
- cp->fdFrom = s;
- cp->fdTo = s;
- *pr = (ProcRef) cp;
-#endif /* !OMIT_SOCKETS */
-
- return 0;
-}
-
-int
-OpenCommPort (char *name, ProcRef *pr)
-{
- int fd;
- ChildProc *cp;
-
- fd = open(name, 2, 0);
- if (fd < 0) return errno;
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPComm;
- cp->pid = 0;
- cp->fdFrom = fd;
- cp->fdTo = fd;
- *pr = (ProcRef) cp;
-
- return 0;
-}
-
-int
-OpenLoopback (ProcRef *pr)
-{
- ChildProc *cp;
- int to[2], from[2];
-
- SetUpChildIO(to, from);
-
- cp = (ChildProc *) calloc(1, sizeof(ChildProc));
- cp->kind = CPLoop;
- cp->pid = 0;
- cp->fdFrom = to[0]; /* note not from[0]; we are doing a loopback */
- cp->fdTo = to[1];
- *pr = (ProcRef) cp;
-
- return 0;
-}
-
-int
-OpenRcmd (char *host, char *user, char *cmd, ProcRef *pr)
-{
- DisplayFatalError(_("internal rcmd not implemented for Unix"), 0, 1);
- return -1;
-}
-
-Boolean stdoutClosed = FALSE;
-
-int
-OutputToProcess (ProcRef pr, char *message, int count, int *outError)
-{
- static int line = 0;
- ChildProc *cp = (ChildProc *) pr;
- int outCount = count;
-
- if (pr == NoProc)
- {
- if (appData.noJoin || !appData.useInternalWrap) {
- if(!stdoutClosed) outCount = fwrite(message, 1, count, stdout);
- } else
- {
- int width = get_term_width();
- int len = wrap(NULL, message, count, width, &line);
- char *msg = malloc(len);
- int dbgchk;
-
- if (!msg)
- outCount = fwrite(message, 1, count, stdout);
- else
- {
- dbgchk = wrap(msg, message, count, width, &line);
- if (dbgchk != len && appData.debugMode)
- fprintf(debugFP, "wrap(): dbgchk(%d) != len(%d)\n", dbgchk, len);
- outCount = fwrite(msg, 1, dbgchk, stdout);
- free(msg);
- }
- }
- if(*message != '\033') ConsoleWrite(message, count);
- }
- else
- outCount = write(cp->fdTo, message, count);
-
- if (outCount == -1)
- *outError = errno;
- else
- *outError = 0;
-
- return outCount;
-}
-
-/* Output message to process, with "ms" milliseconds of delay
- between each character. This is needed when sending the logon
- script to ICC, which for some reason doesn't like the
- instantaneous send. */
-int
-OutputToProcessDelayed (ProcRef pr, char *message, int count, int *outError, long msdelay)
-{
- ChildProc *cp = (ChildProc *) pr;
- int outCount = 0;
- int r;
-
- while (count--) {
- r = write(cp->fdTo, message++, 1);
- if (r == -1) {
- *outError = errno;
- return outCount;
- }
- ++outCount;
- if (msdelay >= 0)
- TimeDelay(msdelay);
- }
-
- return outCount;
-}
-
-int
-ICSInitScript ()
-{
- /* try to open the icsLogon script, either in the location given
- * or in the users HOME directory
- */
-
- FILE *f;
- char buf[MSG_SIZ];
- char *homedir;
-
- f = fopen(appData.icsLogon, "r");
- if (f == NULL)
- {
- homedir = getenv("HOME");
- if (homedir != NULL)
- {
- safeStrCpy(buf, homedir, sizeof(buf)/sizeof(buf[0]) );
- strncat(buf, "/", MSG_SIZ - strlen(buf) - 1);
- strncat(buf, appData.icsLogon, MSG_SIZ - strlen(buf) - 1);
- f = fopen(buf, "r");
- }
- }
-
- if (f != NULL) {
- ProcessICSInitScript(f);
- return TRUE;
- } else
- printf("Warning: Couldn't open icsLogon file (checked %s and %s).\n", appData.icsLogon, buf);
-
- return FALSE;
-}
-
-void
-ResetFrontEnd ()
-{
- CommentPopDown();
- TagsPopDown();
- return;
-}
-
-#include <sys/ioctl.h>
-static int
-get_term_width ()
-{
- int fd, default_width;
-
- fd = STDIN_FILENO;
- default_width = 79; // this is FICS default anyway...
-
-#if !defined(TIOCGWINSZ) && defined(TIOCGSIZE)
- struct ttysize win;
- if (!ioctl(fd, TIOCGSIZE, &win))
- default_width = win.ts_cols;
-#elif defined(TIOCGWINSZ)
- struct winsize win;
- if (!ioctl(fd, TIOCGWINSZ, &win))
- default_width = win.ws_col;
-#endif
- return default_width;
-}
-
-void
-update_ics_width ()
-{
- static int old_width = 0;
- int new_width = get_term_width();
-
- if (old_width != new_width)
- ics_printf("set width %d\n", new_width);
- old_width = new_width;
-}
-
-void
-NotifyFrontendLogin ()
-{
- update_ics_width();
-}