X-Git-Url: http://winboard.nl/cgi-bin?a=blobdiff_plain;f=usystem.c;fp=usystem.c;h=0000000000000000000000000000000000000000;hb=b10966961672512a212cc61192d0b08cf91c4c0c;hp=743c701c8c12744bf9c02280329fab83f52fbaa2;hpb=e147dd97d26b46902200491dbe0a8755266555d3;p=xboard.git diff --git a/usystem.c b/usystem.c deleted file mode 100644 index 743c701..0000000 --- a/usystem.c +++ /dev/null @@ -1,810 +0,0 @@ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include - -#if !OMIT_SOCKETS -# if HAVE_SYS_SOCKET_H -# include -# include -# include -# else /* not HAVE_SYS_SOCKET_H */ -# if HAVE_LAN_SOCKET_H -# include -# include -# include -# 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 -# include -#else /* not STDC_HEADERS */ -extern char *getenv(); -# if HAVE_STRING_H -# include -# else /* not HAVE_STRING_H */ -# include -# endif /* not HAVE_STRING_H */ -#endif /* not STDC_HEADERS */ - -#if HAVE_SYS_FCNTL_H -# include -#else /* not HAVE_SYS_FCNTL_H */ -# if HAVE_FCNTL_H -# include -# endif /* HAVE_FCNTL_H */ -#endif /* not HAVE_SYS_FCNTL_H */ - -#if HAVE_SYS_SYSTEMINFO_H -# include -#endif /* HAVE_SYS_SYSTEMINFO_H */ - -#if TIME_WITH_SYS_TIME -# include -# include -#else -# if HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - -#if HAVE_UNISTD_H -# include -#endif - -#if HAVE_SYS_WAIT_H -# include -#endif - -#if HAVE_DIRENT_H -# include -# 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 -# define HAVE_DIR_STRUCT -# endif -# if HAVE_SYS_DIR_H -# include -# define HAVE_DIR_STRUCT -# endif -# if HAVE_NDIR_H -# include -# define HAVE_DIR_STRUCT -# endif -#endif - -#if ENABLE_NLS -#include -#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 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 -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(); -}