summaryrefslogtreecommitdiff
path: root/app/xfs/os
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 14:43:48 +0000
committerMatthieu Herrb <matthieu@cvs.openbsd.org>2006-11-26 14:43:48 +0000
commit022ad3d01558dbc1a59aefd36cd80afbf034d415 (patch)
tree7809beb94b49355c5b5d9d9abe4c1ccea5669463 /app/xfs/os
parent5a94fa48c7f977f6ae8745a7bb15a8be696be655 (diff)
Importing from X.Org indiviual releases
Diffstat (limited to 'app/xfs/os')
-rw-r--r--app/xfs/os/access.c145
-rw-r--r--app/xfs/os/config.c669
-rw-r--r--app/xfs/os/config.h69
-rw-r--r--app/xfs/os/configstr.h62
-rw-r--r--app/xfs/os/connection.c567
-rw-r--r--app/xfs/os/daemon.c138
-rw-r--r--app/xfs/os/error.c210
-rw-r--r--app/xfs/os/io.c706
-rw-r--r--app/xfs/os/osdep.h134
-rw-r--r--app/xfs/os/osglue.c384
-rw-r--r--app/xfs/os/osinit.c64
-rw-r--r--app/xfs/os/utils.c575
-rw-r--r--app/xfs/os/waitfor.c231
-rw-r--r--app/xfs/os/xfstrans.c33
14 files changed, 3987 insertions, 0 deletions
diff --git a/app/xfs/os/access.c b/app/xfs/os/access.c
new file mode 100644
index 000000000..c50072848
--- /dev/null
+++ b/app/xfs/os/access.c
@@ -0,0 +1,145 @@
+/* $Xorg: access.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR 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.
+ */
+/* $XFree86: xc/programs/xfs/os/access.c,v 3.7tsi Exp $ */
+
+#include <X11/Xos.h>
+#ifndef Lynx
+#include <sys/param.h>
+#include <sys/socket.h>
+#else
+#include <socket.h>
+#endif
+#include <netdb.h>
+#include <netinet/in.h>
+#include "clientstr.h"
+#include "misc.h"
+#include "site.h"
+#include "accstr.h"
+#include "osdep.h"
+#include "osstruct.h"
+#include "accstr.h"
+
+long MaxClients = DEFAULT_CLIENT_LIMIT;
+
+void
+AccessSetConnectionLimit(int num)
+{
+ num++; /* take serverClient into account */
+ if (num > MAXSOCKS) {
+ ErrorF("Client limit of %d too high; using default of %d\n",
+ num, DEFAULT_CLIENT_LIMIT);
+ return;
+ }
+ MaxClients = num;
+}
+
+#ifdef NOTDEF
+/*
+ * XXX
+ *
+ * needs massive amounts of OS-dependent work (big surprise)
+ * needs IPv6 support as well
+ */
+int
+GetHostAddress(HostAddress *addr)
+{
+ char hname[64];
+ struct hostent *hp;
+
+ addr->addr_len = sizeof(struct in_addr);
+ addr->address = (pointer) fsalloc(addr->addr_len);
+ if (!addr->address)
+ return FSBadAlloc;
+ addr->type = HOST_AF_INET;
+ gethostname(hname, sizeof(hname));
+ hp = gethostbyname(hname);
+ if (hp) {
+ memmove( (char *) addr->address, (char *) hp->h_addr, addr->addr_len);
+ } else {
+ fsfree((char *) addr->address);
+ return FSBadName;
+ }
+ return FSSuccess;
+}
+#endif
+
+/* ARGSUSED */
+int
+CheckClientAuthorization(
+ ClientPtr client,
+ AuthPtr client_auth,
+ int *accept,
+ int *index,
+ int *size,
+ char **auth_data)
+{
+ OsCommPtr oc;
+ int i;
+
+ /* now that it's connected, zero the connect time
+ so it doesn't get killed */
+ oc = (OsCommPtr)client->osPrivate;
+ oc->conn_time = 0;
+
+ *size = 0;
+ *accept = AuthSuccess;
+
+ client->auth_generation++;
+
+#define AUTH1_NAME "hp-hostname-1"
+#define AUTH2_NAME "hp-printername-1"
+ for (i = 0; i < *index; i++)
+ if ((client_auth[i].namelen == sizeof(AUTH1_NAME) &&
+ !strcmp(client_auth[i].name, AUTH1_NAME)) ||
+ (client_auth[i].namelen == sizeof(AUTH2_NAME) &&
+ !strcmp(client_auth[i].name, AUTH2_NAME))) break;
+ if (i == *index)
+ i = 0;
+ else
+ i++;
+ *index = i;
+ return FSSuccess;
+}
diff --git a/app/xfs/os/config.c b/app/xfs/os/config.c
new file mode 100644
index 000000000..e5dbc4801
--- /dev/null
+++ b/app/xfs/os/config.c
@@ -0,0 +1,669 @@
+/* $Xorg: config.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR 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.
+ *
+ * $NCDXorg: @(#)config.c,v 4.6 1991/07/09 14:08:09 lemke Exp $
+ *
+ */
+/* $XFree86: xc/programs/xfs/os/config.c,v 3.15 2002/05/31 18:46:12 dawes Exp $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <X11/Xtrans/Xtrans.h>
+#include <X11/Xos.h>
+#include "misc.h"
+#include "configstr.h"
+#include "osdep.h"
+#include "globals.h"
+#include "access.h"
+#include "difsutils.h"
+#ifdef FONTCACHE
+#include <X11/extensions/fontcacheP.h>
+#endif
+#include <X11/fonts/fontutil.h>
+#include "difs.h"
+
+extern int portFromCmdline;
+
+static char *font_catalogue = NULL;
+
+static char *config_set_int(ConfigOptionPtr parm, char *val);
+static char *config_set_bool(ConfigOptionPtr parm, char *val);
+static char *config_set_catalogue(ConfigOptionPtr parm, char *val);
+static char *config_set_glyph_caching_mode(ConfigOptionPtr parm, char *val);
+static char *config_set_list(ConfigOptionPtr parm, char *val);
+static char *config_set_file(ConfigOptionPtr parm, char *val);
+static char *config_set_resolutions(ConfigOptionPtr parm, char *val);
+static char *config_set_ignored_transports(ConfigOptionPtr parm, char *val);
+static char *config_set_snf_format(ConfigOptionPtr parm, char *val);
+
+/* these need to be in lower case and alphabetical order so a
+ * binary search lookup can be used
+ */
+static ConfigOptionRec config_options[] = {
+ {"alternate-servers", config_set_list},
+#ifdef FONTCACHE
+ {"cache-balance", config_set_int},
+ {"cache-hi-mark", config_set_int},
+ {"cache-low-mark", config_set_int},
+#endif
+ {"catalogue", config_set_catalogue},
+ {"client-limit", config_set_int},
+ {"clone-self", config_set_bool},
+ {"default-point-size", config_set_int},
+ {"default-resolutions", config_set_resolutions},
+ {"deferglyphs", config_set_glyph_caching_mode},
+ {"error-file", config_set_file},
+ {"no-listen", config_set_ignored_transports},
+ {"port", config_set_int},
+ {"server-number", config_set_int},
+ {"snf-format", config_set_snf_format},
+ {"trusted-clients", config_set_list},
+ {"use-syslog", config_set_bool},
+ {(char *) 0, 0},
+};
+
+char *ConfigErrors[] = {
+ "",
+ "CONFIG: insufficient memory to load configuration file \"%s\"\n",
+ "CONFIG: can't open configuration file \"%s\"\n",
+ "CONFIG: error reading configuration file \"%s\"\n",
+ "CONFIG: bad value \"%s\" for parameter \"%s\"\n",
+ "CONFIG: unknown parameter \"%s\"\n",
+ "CONFIG: missing '=' after parameter \"%s\"\n",
+ "CONFIG: value out of range for parameter \"%s\"\n",
+ "CONFIG: syntax error near parameter \"%s\"\n",
+ "CONFIG: missing value for parameter \"%s\"\n",
+ "CONFIG: extra value for parameter \"%s\"\n",
+};
+
+#define iseol(c) ((c) == '\n' || (c) == '\r' || (c) == '\f')
+#define skip_whitespace(c) while(isspace(*(c)) || *(c) == ',') (c)++;
+#define skip_val(c) while(!isspace(*(c)) && *(c) != ',' && *(c) != '\0')\
+ (c) ++;
+#define skip_list_val(c) while(!isspace(*(c)) && *(c) != '\0')\
+ (c) ++;
+#define blank_comment(c) while (!iseol(*(c)) && *(c) != '\0') \
+ *(c)++= ' ';
+
+static char *
+next_assign(char *c)
+{
+ int nesting = 0;
+
+ while (*c != '\0') {
+ if (*c == '(')
+ nesting++;
+ else if (*c == ')')
+ nesting--;
+ else if (*c == '=' && nesting == 0)
+ return c;
+ c++;
+ }
+ return (char *) 0;
+}
+
+static void
+strip_comments(char *data)
+{
+ char *c;
+
+ c = data;
+ while ((c = strchr(c, '#')) != NULL) {
+ if (c == data || *(c - 1) != '\\') {
+ blank_comment(c);
+ } else {
+ c++;
+ }
+ }
+}
+
+static ConfigOptionPtr
+match_param_name(char *name)
+{
+ int pos,
+ rc,
+ low,
+ high;
+
+ low = 0;
+ high = sizeof(config_options) / sizeof(ConfigOptionRec) - 2;
+ pos = high >> 1;
+
+ while (low <= high) {
+ rc = strcmp(name, config_options[pos].parm_name);
+ if (rc == 0) {
+ return &config_options[pos];
+ } else if (rc < 0) {
+ high = pos - 1;
+ } else {
+ low = pos + 1;
+ }
+ pos = ((high + low) >> 1);
+ }
+ return 0;
+}
+
+static int
+parse_config(char *data)
+{
+ char *c,
+ *val = NULL,
+ *next_eq,
+ *consumed,
+ *p;
+ char param_name[64];
+ Bool equals_missing;
+ ConfigOptionPtr param;
+
+ c = data;
+ skip_whitespace(c);
+
+ while (*c != '\0') {
+ equals_missing = FALSE;
+
+ /* get parm name in lower case */
+ p = c;
+ while (isalnum(*c) || *c == '-') {
+ if (isupper(*c))
+ *c = tolower(*c);
+ c++;
+ }
+ memmove( param_name, p, min(sizeof(param_name), (int) (c - p)));
+ param_name[(int) (c - p)] = '\0';
+
+ /* check for junk */
+ if (!isspace(*c) && *c != '=') {
+ ErrorF(ConfigErrors[CONFIG_ERR_SYNTAX], param_name);
+ /* eat garbage */
+ while (!isspace(*c) && *c != '=' && *c != '\0')
+ c++;
+ }
+ skip_whitespace(c);
+ if (*c != '=') {
+ ErrorF(ConfigErrors[CONFIG_ERR_NOEQUALS], param_name);
+ equals_missing = TRUE;
+ } else {
+ c++;
+ }
+
+ skip_whitespace(c);
+
+ /* find next assignment to guess where the value ends */
+ if ((next_eq = next_assign(c)) != NULL) {
+ /* back up over whitespace */
+ for (val = next_eq - 1; val >= c &&
+ (isspace(*val) || *val == ',');
+ val--);
+
+ /* back over parm name */
+ for (; val >= c && (isalnum(*val) || *val == '-'); val--);
+
+ if (val <= c) {
+ /* no value, ignore */
+ ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name);
+ continue;
+ }
+ *val = '\0';
+ } else if (*c == '\0') {
+ /* no value, ignore */
+ ErrorF(ConfigErrors[CONFIG_ERR_NOVALUE], param_name);
+ continue;
+ }
+ /* match parm name */
+ if (equals_missing) {
+ equals_missing = FALSE;
+ } else if ((param = match_param_name(param_name)) == NULL) {
+ ErrorF(ConfigErrors[CONFIG_ERR_UNKNOWN], param_name);
+ } else {
+ consumed = (param->set_func) (param, c);
+
+ skip_whitespace(consumed);
+ if (*consumed != '\0') {
+ ErrorF(ConfigErrors[CONFIG_ERR_EXTRAVALUE],
+ param_name);
+ }
+ }
+
+ if (next_eq != NULL)
+ c = val + 1;
+ else /* last setting */
+ break;
+ }
+ return FSSuccess;
+}
+
+/*
+ * handles anything that should be set once the file is parsed
+ */
+void
+SetConfigValues(void)
+{
+ int err,
+ num;
+
+ err = SetFontCatalogue(font_catalogue, &num);
+ if (err != FSSuccess) {
+ FatalError("element #%d (starting at 0) of font path is bad or has a bad font:\n\"%s\"\n",
+ num, font_catalogue);
+ }
+ InitErrors();
+ fsfree((char *) font_catalogue);
+ font_catalogue = NULL;
+}
+
+#ifdef __UNIXOS2__
+char *__XFSRedirRoot(char *fname)
+{
+ static char redirname[300]; /* enough for long filenames */
+ char *root;
+
+ /* if name does not start with /, assume it is not root-based */
+ if (fname==0 || !(fname[0]=='/' || fname[0]=='\\'))
+ return fname;
+
+ root = (char*)getenv("X11ROOT");
+ if (root==0 ||
+ (fname[1]==':' && isalpha(fname[0])) ||
+ ((strlen(fname)+strlen(root)+2) > 300))
+ return fname;
+ sprintf(redirname,"%s%s",root,fname);
+ return redirname;
+}
+#endif
+
+int
+ReadConfigFile(char *filename)
+{
+ FILE *fp;
+ int ret;
+ int len;
+ char *data;
+
+ data = (char *) fsalloc(CONFIG_MAX_FILESIZE);
+ if (!data) {
+ ErrorF(ConfigErrors[CONFIG_ERR_MEMORY], filename);
+ return FSBadAlloc;
+ }
+#ifdef __UNIXOS2__
+ filename = __XFSRedirRoot(filename);
+#endif
+ if ((fp = fopen(filename, "r")) == NULL) {
+ fsfree(data);
+ ErrorF(ConfigErrors[CONFIG_ERR_OPEN], filename);
+ return FSBadName;
+ }
+ ret = fread(data, sizeof(char), CONFIG_MAX_FILESIZE, fp);
+ if (ret <= 0) {
+ fsfree(data);
+ (void) fclose(fp);
+ ErrorF(ConfigErrors[CONFIG_ERR_READ], filename);
+ return FSBadName;
+ }
+ len = ftell(fp);
+ len = min(len, CONFIG_MAX_FILESIZE);
+ data[len] = '\0'; /* NULL terminate the data */
+
+ (void) fclose(fp);
+
+ strip_comments(data);
+ ret = parse_config(data);
+
+ fsfree(data);
+
+ return ret;
+}
+
+struct nameVal {
+ char *name;
+ int val;
+};
+
+static char *
+config_parse_nameVal (
+ char *c,
+ int *ret,
+ int *pval,
+ struct nameVal *name_val)
+{
+ char *start,
+ t;
+ int i,
+ len;
+
+ start = c;
+ skip_val(c);
+ t = *c;
+ *c = '\0';
+ len = c - start;
+
+ for (i = 0; name_val[i].name; i++) {
+ if (!strncmpnocase(start, name_val[i].name, len)) {
+ *pval = name_val[i].val;
+ *ret = 0;
+ *c = t;
+ return c;
+ }
+ }
+ ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start);
+ *c = t;
+ *ret = -1;
+ return c;
+}
+
+static char *
+config_parse_bool (
+ char *c,
+ int *ret,
+ Bool *pval)
+{
+ static struct nameVal bool_val[] = {
+ { "yes", TRUE },
+ { "on", TRUE },
+ { "1", TRUE },
+ { "true", TRUE },
+ { "no", FALSE },
+ { "off", FALSE },
+ { "0", FALSE },
+ { "false", FALSE },
+ { (char *) 0, 0 },
+ };
+ return config_parse_nameVal (c, ret, pval, bool_val);
+}
+
+static char *
+config_parse_int(
+ char *c,
+ int *ret,
+ int *pval)
+{
+ char *start,
+ t;
+
+ start = c;
+ while (*c != '\0' && !isspace(*c) && *c != ',') {
+ if (!isdigit(*c)) { /* error */
+ skip_val(c);
+ t = *c;
+ *c = '\0';
+ ErrorF(ConfigErrors[CONFIG_ERR_VALUE], start);
+ *ret = -1;
+ *c = t;
+ return c;
+ }
+ c++;
+ }
+ t = *c;
+ *c = '\0';
+ *ret = 0;
+ *pval = atoi(start);
+ *c = t;
+ return c;
+}
+
+
+/* config option sets */
+/* these have to know how to do the real work and tweak the proper things */
+static char *
+config_set_int(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ int ival,
+ ret;
+
+ val = config_parse_int(val, &ret, &ival);
+ if (ret == -1)
+ return val;
+
+ /* now do individual attribute checks */
+ if (!strcmp(parm->parm_name, "port") && !portFromCmdline) {
+ ListenPort = ival;
+ } else if (!strcmp(parm->parm_name, "client-limit")) {
+ AccessSetConnectionLimit(ival);
+ } else if (!strcmp(parm->parm_name, "default-point-size")) {
+ SetDefaultPointSize(ival);
+ }
+#ifdef FONTCACHE
+ else if (!strcmp(parm->parm_name, "cache-balance")) {
+ cacheSettings.balance = ival;
+ } else if (!strcmp(parm->parm_name, "cache-hi-mark")) {
+ cacheSettings.himark = ival * 1024;
+ } else if (!strcmp(parm->parm_name, "cache-low-mark")) {
+ cacheSettings.lowmark = ival * 1024;
+ }
+#endif
+ return val;
+}
+
+static char *
+config_set_bool(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ int
+ ret;
+ Bool bval;
+
+ val = config_parse_bool(val, &ret, &bval);
+ if (ret == -1)
+ return val;
+
+ /* now do individual attribute checks */
+ if (!strcmp(parm->parm_name, "use-syslog")) {
+ UseSyslog = bval;
+ } else if (!strcmp(parm->parm_name, "clone-self")) {
+ CloneSelf = bval;
+ }
+ return val;
+}
+
+static char *
+config_set_file(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ char *start = val,
+ t;
+
+ skip_val(val);
+ t = *val;
+ *val = '\0';
+ if (!strcmp(parm->parm_name, "error-file")) {
+#ifndef __UNIXOS2__
+ memmove( ErrorFile, start, val - start + 1);
+#else
+ strcpy( ErrorFile, __XFSRedirRoot(start));
+#endif
+ }
+ *val = t;
+ return val;
+}
+
+static char *
+config_set_catalogue(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ char *b;
+
+ if (!strcmp(parm->parm_name, "catalogue")) {
+ /* stash it for later */
+ fsfree((char *) font_catalogue); /* dump any previous one */
+ b = font_catalogue = (char *) fsalloc(strlen(val) + 1);
+ if (!font_catalogue)
+ FatalError("insufficent memory for font catalogue\n");
+ while (*val) { /* remove all the gunk */
+ if (!isspace(*val)) {
+ *b++ = *val;
+ }
+ val++;
+ }
+ *b = '\0';
+ }
+ return val;
+}
+
+static char *
+config_set_list(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ char *start = val,
+ t;
+
+ skip_list_val(val);
+ t = *val;
+ *val = '\0';
+ if (!strcmp(parm->parm_name, "alternate-servers")) {
+ SetAlternateServers(start);
+ }
+ *val = t;
+ return val;
+}
+
+static char *
+config_set_ignored_transports(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ char *start = val,
+ t;
+
+ skip_list_val(val);
+ t = *val;
+ *val = '\0';
+ _FontTransNoListen(start);
+ *val = t;
+ return val;
+}
+
+static char *
+config_set_glyph_caching_mode(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ char *start = val,
+ t;
+
+ skip_list_val(val);
+ t = *val;
+ *val = '\0';
+ if (!strcmp(parm->parm_name, "deferglyphs")) {
+ ParseGlyphCachingMode(start);
+ }
+ *val = t;
+ return val;
+}
+
+static char *
+config_set_resolutions(
+ ConfigOptionPtr parm,
+ char *val)
+{
+ char *start = val,
+ t;
+ int err;
+
+ skip_list_val(val);
+ t = *val;
+ *val = '\0';
+ if (!strcmp(parm->parm_name, "default-resolutions")) {
+ err = SetDefaultResolutions(start);
+ if (err != FSSuccess) {
+ FatalError("bogus resolution list \"%s\"\n", start);
+ }
+ }
+ *val = t;
+ return val;
+}
+
+
+static char *
+config_parse_endian(
+ char *c,
+ int *ret,
+ int *pval)
+{
+ static struct nameVal endian_val[] = {
+ { "lsb", LSBFirst },
+ { "little", LSBFirst },
+ { "lsbfirst", LSBFirst },
+ { "msb", MSBFirst },
+ { "big", MSBFirst },
+ { "msbfirst", MSBFirst },
+ { (char *) 0, 0 },
+ };
+ return config_parse_nameVal (c, ret, pval, endian_val);
+}
+
+/* ARGSUSED */
+static char *
+config_set_snf_format (
+ ConfigOptionPtr parm,
+ char *val)
+{
+ int bit, byte, glyph, scan;
+ int ret;
+
+ val = config_parse_endian (val, &ret, &bit);
+ if (ret == -1)
+ return val;
+ skip_whitespace (val);
+ val = config_parse_endian (val, &ret, &byte);
+ if (ret == -1)
+ return val;
+ skip_whitespace (val);
+ val = config_parse_int (val, &ret, &glyph);
+ if (ret == -1)
+ return val;
+ skip_whitespace (val);
+ val = config_parse_int (val, &ret, &scan);
+ if (ret == -1)
+ return val;
+ SnfSetFormat (bit, byte, glyph, scan);
+ return val;
+}
diff --git a/app/xfs/os/config.h b/app/xfs/os/config.h
new file mode 100644
index 000000000..ba6db45cb
--- /dev/null
+++ b/app/xfs/os/config.h
@@ -0,0 +1,69 @@
+/* $Xorg: config.h,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR 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.
+ *
+ * @(#)config.h 4.1 91/05/02
+ *
+ */
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+/* max size in bytes of config file */
+#define CONFIG_MAX_FILESIZE 32767
+
+/* error codes */
+/* these should be in the same order as the error strings in config.c */
+#define CONFIG_ERR_MEMORY 1
+#define CONFIG_ERR_OPEN 2
+#define CONFIG_ERR_READ 3
+#define CONFIG_ERR_VALUE 4
+#define CONFIG_ERR_UNKNOWN 5
+#define CONFIG_ERR_NOEQUALS 6
+#define CONFIG_ERR_RANGE 7
+#define CONFIG_ERR_SYNTAX 8
+#define CONFIG_ERR_NOVALUE 9
+#define CONFIG_ERR_EXTRAVALUE 10
+#endif /* _CONFIG_H_ */
diff --git a/app/xfs/os/configstr.h b/app/xfs/os/configstr.h
new file mode 100644
index 000000000..9c1a8afa1
--- /dev/null
+++ b/app/xfs/os/configstr.h
@@ -0,0 +1,62 @@
+/* $Xorg: configstr.h,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, DIGITAL OR MIT 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.
+ *
+ * @(#)configstr.h 4.1 91/05/02
+ *
+ */
+/* $XFree86: xc/programs/xfs/os/configstr.h,v 1.4 2001/01/17 23:45:32 dawes Exp $ */
+#ifndef _CONFIGSTR_H_
+#define _CONFIGSTR_H_
+#include "config.h"
+
+typedef struct _config_options ConfigOptionRec, *ConfigOptionPtr;
+
+struct _config_options {
+ char *parm_name;
+ char *(*set_func) (ConfigOptionPtr, char *);
+};
+
+#endif /* _CONFIGSTR_H_ */
diff --git a/app/xfs/os/connection.c b/app/xfs/os/connection.c
new file mode 100644
index 000000000..2035312c7
--- /dev/null
+++ b/app/xfs/os/connection.c
@@ -0,0 +1,567 @@
+/* $Xorg: connection.c,v 1.5 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+ * handles connections
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR 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.
+ */
+/*
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR 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.
+ */
+/* $XFree86: xc/programs/xfs/os/connection.c,v 3.25tsi Exp $ */
+
+#include <stdlib.h>
+#include <X11/Xtrans/Xtrans.h>
+#include <stdlib.h>
+#include "misc.h"
+#include <stdio.h>
+#include <errno.h>
+#include <X11/Xos.h>
+#ifndef Lynx
+#include <sys/param.h>
+#include <sys/socket.h>
+#ifndef __UNIXOS2__
+#include <sys/uio.h>
+#endif
+#else
+#include <socket.h>
+#include <uio.h>
+#endif
+#include <signal.h>
+
+#include <X11/fonts/FS.h>
+#include <X11/fonts/FSproto.h>
+#include "clientstr.h"
+#include "X11/Xpoll.h"
+#include "osdep.h"
+#include "globals.h"
+#include "osstruct.h"
+#include "servermd.h"
+#include "dispatch.h"
+#include "fsevents.h"
+
+#ifdef __UNIXOS2__
+#define _NFILE OPEN_MAX
+#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t)
+#endif
+
+
+int ListenPort = DEFAULT_FS_PORT; /* port to listen on */
+int lastfdesc;
+
+fd_set WellKnownConnections;
+fd_set AllSockets;
+fd_set AllClients;
+fd_set LastSelectMask;
+fd_set ClientsWithInput;
+fd_set ClientsWriteBlocked;
+fd_set OutputPending;
+long OutputBufferSize = BUFSIZE;
+
+Bool NewOutputPending;
+Bool AnyClientsWriteBlocked;
+
+int ConnectionTranslation[MAXSOCKS];
+
+XtransConnInfo *ListenTransConns = NULL;
+int *ListenTransFds = NULL;
+int ListenTransCount;
+
+
+static void error_conn_max(XtransConnInfo trans_conn);
+static void close_fd(OsCommPtr oc);
+
+
+static XtransConnInfo
+lookup_trans_conn (int fd)
+{
+ if (ListenTransFds)
+ {
+ int i;
+ for (i = 0; i < ListenTransCount; i++)
+ if (ListenTransFds[i] == fd)
+ return ListenTransConns[i];
+ }
+
+ return (NULL);
+}
+
+void
+StopListening(void)
+{
+ int i;
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ FD_CLR (ListenTransFds[i], &AllSockets);
+ _FontTransCloseForCloning (ListenTransConns[i]);
+ }
+
+ free ((char *) ListenTransFds);
+ free ((char *) ListenTransConns);
+
+ ListenTransFds = NULL;
+ ListenTransConns = NULL;
+}
+
+/*
+ * creates the sockets for listening to clients
+ *
+ * only called when server first started
+ */
+void
+CreateSockets(int old_listen_count, OldListenRec *old_listen)
+{
+ int i;
+
+ FD_ZERO(&AllSockets);
+ FD_ZERO(&AllClients);
+ FD_ZERO(&LastSelectMask);
+ FD_ZERO(&ClientsWithInput);
+ FD_ZERO(&WellKnownConnections);
+
+ for (i = 0; i < MAXSOCKS; i++)
+ ConnectionTranslation[i] = 0;
+
+#ifdef XNO_SYSCONF /* should only be on FreeBSD 1.x and NetBSD 0.x */
+#undef _SC_OPEN_MAX
+#endif
+#ifdef _SC_OPEN_MAX
+ lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
+#else
+#if defined(hpux) || defined(__UNIXOS2__)
+ lastfdesc = _NFILE - 1;
+#else
+ lastfdesc = getdtablesize() - 1;
+#endif /* hpux */
+#endif
+
+ if (lastfdesc > MAXSOCKS) {
+ lastfdesc = MAXSOCKS;
+ }
+
+ if (old_listen_count > 0) {
+
+ /*
+ * The font server cloned itself. Re-use previously opened
+ * transports for listening.
+ */
+
+ ListenTransConns = (XtransConnInfo *) malloc (
+ old_listen_count * sizeof (XtransConnInfo));
+
+ ListenTransFds = (int *) malloc (old_listen_count * sizeof (int));
+
+ ListenTransCount = 0;
+
+ for (i = 0; i < old_listen_count; i++)
+ {
+ char portnum[10];
+
+ if (old_listen[i].portnum != ListenPort)
+ continue; /* this should never happen */
+ else
+ sprintf (portnum, "%d", old_listen[i].portnum);
+
+ if ((ListenTransConns[ListenTransCount] =
+ _FontTransReopenCOTSServer (old_listen[i].trans_id,
+ old_listen[i].fd, portnum)) != NULL)
+ {
+ ListenTransFds[ListenTransCount] = old_listen[i].fd;
+ FD_SET (old_listen[i].fd, &WellKnownConnections);
+
+ NoticeF("reusing existing file descriptor %d\n",
+ old_listen[i].fd);
+
+ ListenTransCount++;
+ }
+ }
+ } else {
+ char port[20];
+ int partial;
+
+ sprintf (port, "%d", ListenPort);
+
+ if ((_FontTransMakeAllCOTSServerListeners (port, &partial,
+ &ListenTransCount, &ListenTransConns) >= 0) &&
+ (ListenTransCount >= 1))
+ {
+ ListenTransFds = (int *) malloc (ListenTransCount * sizeof (int));
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ int fd = _FontTransGetConnectionNumber (ListenTransConns[i]);
+
+ ListenTransFds[i] = fd;
+ FD_SET (fd, &WellKnownConnections);
+ }
+ }
+ }
+
+ if (! XFD_ANYSET(&WellKnownConnections))
+ FatalError("cannot establish any listening sockets\n");
+
+ /* set up all the signal handlers */
+ signal(SIGPIPE, SIG_IGN);
+ signal(SIGHUP, AutoResetServer);
+ signal(SIGINT, GiveUp);
+ signal(SIGTERM, GiveUp);
+ signal(SIGUSR1, ServerReconfig);
+ signal(SIGUSR2, ServerCacheFlush);
+ signal(SIGCHLD, CleanupChild);
+
+ XFD_COPYSET (&WellKnownConnections, &AllSockets);
+}
+
+/*
+ * called when server cycles
+ */
+void
+ResetSockets(void)
+{
+}
+
+void
+CloseSockets(void)
+{
+ int i;
+
+ for (i = 0; i < ListenTransCount; i++)
+ _FontTransClose (ListenTransConns[i]);
+}
+
+/*
+ * accepts new connections
+ */
+void
+MakeNewConnections(void)
+{
+ fd_mask readyconnections;
+ int curconn;
+ int newconn;
+ long connect_time;
+ int i;
+ ClientPtr client;
+ OsCommPtr oc;
+ fd_set tmask;
+
+ XFD_ANDSET (&tmask, &LastSelectMask, &WellKnownConnections);
+ readyconnections = tmask.fds_bits[0];
+ if (!readyconnections)
+ return;
+ connect_time = GetTimeInMillis();
+
+ /* kill off stragglers */
+ for (i = MINCLIENT; i < currentMaxClients; i++) {
+ if ((client = clients[i]) != NullClient) {
+ oc = (OsCommPtr) client->osPrivate;
+ if ((oc && (oc->conn_time != 0) &&
+ (connect_time - oc->conn_time) >= TimeOutValue) ||
+ ((client->noClientException != FSSuccess) &&
+ (client->clientGone != CLIENT_GONE)))
+ CloseDownClient(client);
+ }
+ }
+
+ while (readyconnections) {
+ XtransConnInfo trans_conn, new_trans_conn;
+ int status;
+
+ curconn = ffs(readyconnections) - 1;
+ readyconnections &= ~(1 << curconn);
+
+ if ((trans_conn = lookup_trans_conn (curconn)) == NULL)
+ continue;
+
+ if ((new_trans_conn = _FontTransAccept (trans_conn, &status)) == NULL)
+ continue;
+
+ newconn = _FontTransGetConnectionNumber (new_trans_conn);
+
+ _FontTransSetOption(new_trans_conn, TRANS_NONBLOCKING, 1);
+
+ oc = (OsCommPtr) fsalloc(sizeof(OsCommRec));
+ if (!oc) {
+ fsfree(oc);
+ error_conn_max(new_trans_conn);
+ _FontTransClose(new_trans_conn);
+ continue;
+ }
+ FD_SET(newconn, &AllClients);
+ FD_SET(newconn, &AllSockets);
+ oc->fd = newconn;
+ oc->trans_conn = new_trans_conn;
+ oc->input = (ConnectionInputPtr) NULL;
+ oc->output = (ConnectionOutputPtr) NULL;
+ oc->conn_time = connect_time;
+
+ if ((newconn < lastfdesc) &&
+ (client = NextAvailableClient((pointer) oc))) {
+ ConnectionTranslation[newconn] = client->index;
+ } else {
+ error_conn_max(new_trans_conn);
+ close_fd(oc);
+ }
+ }
+}
+
+#define NOROOM "maximum number of clients reached"
+
+static void
+error_conn_max(XtransConnInfo trans_conn)
+{
+ int fd = _FontTransGetConnectionNumber (trans_conn);
+ fsConnSetup conn;
+ char pad[3];
+ char byteOrder = 0;
+ int whichbyte = 1;
+ struct timeval waittime;
+ fd_set mask;
+
+
+ waittime.tv_usec = BOTIMEOUT / MILLI_PER_SECOND;
+ waittime.tv_usec = (BOTIMEOUT % MILLI_PER_SECOND) *
+ (1000000 / MILLI_PER_SECOND);
+ FD_ZERO(&mask);
+ FD_SET(fd, &mask);
+ (void) Select(fd + 1, &mask, NULL, NULL, &waittime);
+ /* try to read the byteorder of the connection */
+ (void) _FontTransRead(trans_conn, &byteOrder, 1);
+ if ((byteOrder == 'l') || (byteOrder == 'B')) {
+ int num_alts;
+ AlternateServerPtr altservers,
+ as;
+ int i,
+ altlen = 0;
+
+ num_alts = ListAlternateServers(&altservers);
+ conn.status = AuthDenied;
+ conn.major_version = FS_PROTOCOL;
+ conn.minor_version = FS_PROTOCOL_MINOR;
+ conn.num_alternates = num_alts;
+ for (i = 0, as = altservers; i < num_alts; i++, as++) {
+ altlen += (2 + as->namelen + 3) >> 2;
+ }
+ conn.alternate_len = altlen;
+ /* blow off the auth info */
+ conn.auth_index = 0;
+ conn.auth_len = 0;
+
+ if (((*(char *) &whichbyte) && (byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (byteOrder == 'l'))) {
+ conn.status = lswaps(conn.status);
+ conn.major_version = lswaps(conn.major_version);
+ conn.minor_version = lswaps(conn.minor_version);
+ conn.alternate_len = lswaps(conn.alternate_len);
+ }
+ (void) _FontTransWrite(trans_conn,
+ (char *) &conn, SIZEOF(fsConnSetup));
+ /* dump alternates */
+ for (i = 0, as = altservers; i < num_alts; i++, as++) {
+ (void) _FontTransWrite(trans_conn,
+ (char *) as, 2); /* XXX */
+ (void) _FontTransWrite(trans_conn,
+ (char *) as->name, as->namelen);
+ altlen = 2 + as->namelen;
+ /* pad it */
+ if (altlen & 3)
+ (void) _FontTransWrite(trans_conn,
+ (char *) pad, ((4 - (altlen & 3)) & 3));
+ }
+ }
+}
+
+static void
+close_fd(OsCommPtr oc)
+{
+ int fd = oc->fd;
+
+ if (oc->trans_conn)
+ _FontTransClose(oc->trans_conn);
+ FreeOsBuffers(oc);
+ FD_CLR(fd, &AllSockets);
+ FD_CLR(fd, &AllClients);
+ FD_CLR(fd, &ClientsWithInput);
+ FD_CLR(fd, &ClientsWriteBlocked);
+ if (!XFD_ANYSET(&ClientsWriteBlocked))
+ AnyClientsWriteBlocked = FALSE;
+ FD_CLR(fd, &OutputPending);
+ fsfree(oc);
+}
+
+void
+CheckConnections(void)
+{
+ fd_set mask;
+ fd_set tmask;
+ int curclient;
+ int i;
+ struct timeval notime;
+ int r;
+
+ notime.tv_sec = 0;
+ notime.tv_usec = 0;
+
+ XFD_COPYSET(&AllClients, &mask);
+ for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) {
+ while (mask.fds_bits[i]) {
+ curclient = ffs(mask.fds_bits[i]) - 1 + (i << 5);
+ FD_ZERO(&tmask);
+ FD_SET(curclient, &tmask);
+ r = Select(curclient + 1, &tmask, NULL, NULL, &notime);
+ if (r < 0)
+ CloseDownClient(clients[ConnectionTranslation[curclient]]);
+ FD_CLR(curclient, &mask);
+ }
+ }
+}
+
+void
+CloseDownConnection(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+
+ if (oc->output && oc->output->count)
+ FlushClient(client, oc, (char *) NULL, 0, 0);
+ ConnectionTranslation[oc->fd] = 0;
+ close_fd(oc);
+ client->osPrivate = (pointer) NULL;
+}
+
+
+/****************
+ * IgnoreClient
+ * Removes one client from input masks.
+ * Must have cooresponding call to AttendClient.
+ ****************/
+
+static fd_set IgnoredClientsWithInput;
+
+void
+IgnoreClient(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+ int connection = oc->fd;
+
+ if (FD_ISSET(connection, &ClientsWithInput))
+ FD_SET(connection, &IgnoredClientsWithInput);
+ else
+ FD_CLR(connection, &IgnoredClientsWithInput);
+ FD_CLR(connection, &ClientsWithInput);
+ FD_CLR(connection, &AllSockets);
+ FD_CLR(connection, &AllClients);
+ FD_CLR(connection, &LastSelectMask);
+ isItTimeToYield = TRUE;
+}
+
+/****************
+ * AttendClient
+ * Adds one client back into the input masks.
+ ****************/
+
+void
+AttendClient(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+ int connection = oc->fd;
+
+ FD_SET(connection, &AllClients);
+ FD_SET(connection, &AllSockets);
+ FD_SET(connection, &LastSelectMask);
+ if (FD_ISSET(connection, &IgnoredClientsWithInput))
+ FD_SET(connection, &ClientsWithInput);
+}
+
+/*
+ * figure out which clients need to be toasted
+ */
+void
+ReapAnyOldClients(void)
+{
+ int i;
+ long cur_time = GetTimeInMillis();
+ ClientPtr client;
+
+#ifdef DEBUG
+ fprintf(stderr, "looking for clients to reap\n");
+#endif
+
+ for (i = MINCLIENT; i < currentMaxClients; i++) {
+ client = clients[i];
+ if (client) {
+ if ((cur_time - client->last_request_time) >= ReapClientTime) {
+ if (client->clientGone == CLIENT_AGED) {
+ client->clientGone = CLIENT_TIMED_OUT;
+
+#ifdef DEBUG
+ fprintf(stderr, "reaping client #%d\n", i);
+#endif
+
+ CloseDownClient(client);
+ } else {
+ client->clientGone = CLIENT_AGED;
+ SendKeepAliveEvent(client);
+ }
+ }
+ }
+ }
+}
diff --git a/app/xfs/os/daemon.c b/app/xfs/os/daemon.c
new file mode 100644
index 000000000..2b23de328
--- /dev/null
+++ b/app/xfs/os/daemon.c
@@ -0,0 +1,138 @@
+/*
+
+Copyright (c) 1988 X Consortium
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be included
+in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of the X Consortium shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the X Consortium.
+
+*/
+/* $XFree86: xc/programs/xfs/os/daemon.c,v 1.12 2002/10/20 21:42:50 tsi Exp $ */
+
+#include <X11/Xos.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#if defined(USG)
+# include <termios.h>
+#else
+# include <sys/ioctl.h>
+#endif
+#ifdef hpux
+# include <sys/ptyio.h>
+#endif
+
+#ifdef X_NOT_POSIX
+# define Pid_t int
+#else
+# define Pid_t pid_t
+#endif
+
+#include "os.h"
+
+#if defined(__GLIBC__) || defined(CSRG_BASED)
+#define HAS_DAEMON
+#endif
+
+#ifndef X_NOT_POSIX
+#define HAS_SETSID
+#endif
+
+#ifndef HAS_SETSID
+
+#define setsid() MySetsid()
+
+static Pid_t
+MySetsid(void)
+{
+#if defined(TIOCNOTTY) || defined(TCCLRCTTY) || defined(TIOCTTY)
+ int fd;
+#endif
+ int stat;
+
+ fd = open("/dev/tty", O_RDWR);
+ if (fd >= 0) {
+#if defined(USG) && defined(TCCLRCTTY)
+ int zero = 0;
+ (void) ioctl (fd, TCCLRCTTY, &zero);
+#elif (defined(SYSV) || defined(SVR4)) && defined(TIOCTTY)
+ int zero = 0;
+ (void) ioctl (i, TIOCTTY, &zero);
+#elif defined(TIOCNOTTY)
+ (void) ioctl (i, TIOCNOTTY, (char *) 0); /* detach, BSD style */
+#endif
+ close(fd);
+ }
+
+#if defined(SYSV) || defined(__QNXNTO__)
+ return setpgrp();
+#else
+ return setpgid(0, getpid());
+#endif
+}
+
+#endif /* !HAS_SETSID */
+
+
+/* detach */
+void
+BecomeDaemon ()
+{
+ /* If our C library has the daemon() function, just use it. */
+#ifdef HAS_DAEMON
+ daemon (0, 0);
+#else
+
+ switch (fork()) {
+ case -1:
+ /* error */
+ FatalError("daemon fork failed, %s\n", strerror(errno));
+ break;
+ case 0:
+ /* child */
+ break;
+ default:
+ /* parent */
+ exit(0);
+ }
+
+ if (setsid() == -1)
+ FatalError("setting session id for daemon failed: %s\n",
+ strerror(errno));
+
+ chdir("/");
+
+ close (0);
+ close (1);
+ close (2);
+
+ /*
+ * Set up the standard file descriptors.
+ */
+ (void) open ("/dev/null", O_RDWR);
+ (void) dup2 (0, 1);
+ (void) dup2 (0, 2);
+
+#endif /* HAS_DAEMON */
+}
diff --git a/app/xfs/os/error.c b/app/xfs/os/error.c
new file mode 100644
index 000000000..8c72a657c
--- /dev/null
+++ b/app/xfs/os/error.c
@@ -0,0 +1,210 @@
+/* $Xorg: error.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+ * error message handling
+ */
+/*
+Copyright 1994, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR 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.
+ */
+/* $XFree86: error.c,v 1.11 2002/10/15 01:45:03 dawes Exp $ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <X11/Xos.h>
+
+#ifndef X_NOT_POSIX
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif
+#endif
+#ifndef PATH_MAX
+#include <sys/param.h>
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif
+
+#ifdef USE_SYSLOG
+#include <syslog.h>
+#endif
+
+#include <errno.h>
+
+#include "misc.h"
+
+extern char *progname;
+
+Bool UseSyslog;
+#ifdef USE_SYSLOG
+Bool log_open = FALSE;
+#endif
+char ErrorFile[PATH_MAX];
+static char CurrentErrorFile[PATH_MAX];
+
+static void
+abort_server(void)
+{
+ fflush(stderr);
+
+#ifdef SABER
+ saber_stop();
+#else
+ _exit(1);
+#endif
+}
+
+void
+InitErrors(void)
+{
+ int i;
+
+#ifdef USE_SYSLOG
+ if (UseSyslog && !log_open) {
+ openlog("xfs", LOG_PID, LOG_DAEMON);
+ log_open = TRUE;
+ return;
+ }
+#endif
+
+ if (ErrorFile[0] && strcmp(CurrentErrorFile, ErrorFile) != 0) {
+ i = creat(ErrorFile, 0666);
+ if (i != -1) {
+ dup2(i, 2);
+ close(i);
+ } else {
+ ErrorF("can't open error file \"%s\"\n", ErrorFile);
+ }
+ strncpy(CurrentErrorFile, ErrorFile, sizeof CurrentErrorFile);
+ }
+}
+
+void
+CloseErrors(void)
+{
+#ifdef USE_SYSLOG
+ if (UseSyslog) {
+ closelog();
+ log_open = FALSE;
+ return;
+ }
+#endif
+}
+
+void
+Error(char *str)
+{
+#ifdef USE_SYSLOG
+ if (UseSyslog) {
+ syslog(LOG_ERR, "%s: %s", str, strerror(errno));
+ return;
+ }
+#endif
+ perror(str);
+}
+
+/*
+ * used for informational messages
+ */
+void
+NoticeF(char *f, ...)
+{
+ /* XXX should Notices just be ignored if not using syslog? */
+ va_list args;
+ va_start(args, f);
+#ifdef USE_SYSLOG
+ if (UseSyslog) {
+ vsyslog(LOG_NOTICE, f, args);
+ return;
+ }
+#else
+ fprintf(stderr, "%s notice: ", progname);
+ vfprintf(stderr, f, args);
+#endif /* USE_SYSLOG */
+ va_end(args);
+}
+
+/*
+ * used for non-fatal error messages
+ */
+void
+ErrorF(char * f, ...)
+{
+ va_list args;
+ va_start(args, f);
+#ifdef USE_SYSLOG
+ if (UseSyslog) {
+ vsyslog(LOG_WARNING, f, args);
+ return;
+ }
+#else
+ fprintf(stderr, "%s error: ", progname);
+ vfprintf(stderr, f, args);
+#endif
+ va_end(args);
+}
+
+void
+FatalError(char * f, ...)
+{
+ va_list args;
+ va_start(args, f);
+#ifdef USE_SYSLOG
+ if (UseSyslog) {
+ vsyslog(LOG_ERR, f, args);
+ return;
+ }
+#else
+ fprintf(stderr, "%s fatal error: ", progname);
+ vfprintf(stderr, f, args);
+#endif
+ va_end(args);
+ abort_server();
+ /* NOTREACHED */
+}
diff --git a/app/xfs/os/io.c b/app/xfs/os/io.c
new file mode 100644
index 000000000..a5603e24f
--- /dev/null
+++ b/app/xfs/os/io.c
@@ -0,0 +1,706 @@
+/* $Xorg: io.c,v 1.5 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+ * i/o functions
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR 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.
+ */
+/* $XFree86: xc/programs/xfs/os/io.c,v 3.18 2001/12/14 20:01:41 dawes Exp $ */
+
+#include <X11/Xtrans/Xtrans.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/types.h>
+#ifndef Lynx
+#include <sys/param.h>
+#ifndef __UNIXOS2__
+#include <sys/uio.h>
+#endif
+#else
+#include <uio.h>
+#endif
+
+#include <X11/fonts/FSproto.h>
+#include "clientstr.h"
+#include "X11/Xpoll.h"
+#include "osdep.h"
+#include "globals.h"
+#include "dispatch.h"
+
+
+/* check for both EAGAIN and EWOULDBLOCK, because some supposedly POSIX
+ * systems are broken and return EWOULDBLOCK when they should return EAGAIN
+ */
+
+#if defined(EAGAIN) && defined(EWOULDBLOCK)
+#define ETEST(err) (err == EAGAIN || err == EWOULDBLOCK)
+#else
+
+#ifdef EAGAIN
+#define ETEST(err) (err == EAGAIN)
+#else
+#define ETEST(err) (err == EWOULDBLOCK)
+#endif
+
+#endif
+
+
+extern fd_set ClientsWithInput;
+extern fd_set ClientsWriteBlocked;
+extern fd_set OutputPending;
+
+extern long OutputBufferSize;
+
+extern int ConnectionTranslation[];
+
+extern Bool AnyClientsWriteBlocked;
+extern Bool NewOutputPending;
+
+static int timesThisConnection = 0;
+static ConnectionInputPtr FreeInputs = (ConnectionInputPtr) NULL;
+static ConnectionOutputPtr FreeOutputs = (ConnectionOutputPtr) NULL;
+static OsCommPtr AvailableInput = (OsCommPtr) NULL;
+
+static ConnectionInputPtr AllocateInputBuffer(void);
+static ConnectionOutputPtr AllocateOutputBuffer(void);
+
+
+#define MAX_TIMES_PER 10
+
+#define yield_control() \
+ { isItTimeToYield = TRUE; \
+ timesThisConnection = 0; }
+
+#define yield_control_no_input() \
+ { yield_control(); \
+ FD_CLR(fd, &ClientsWithInput); }
+
+#define yield_control_death() \
+ { timesThisConnection = 0; }
+
+#define request_length(req, client) \
+ ((int)((client)->swapped ? lswaps((req)->length) : (req)->length) << 2)
+
+int
+ReadRequest(ClientPtr client)
+{
+ OsCommPtr oc;
+ ConnectionInputPtr oci;
+ fsReq *request;
+ int fd,
+ result,
+ gotnow,
+ needed = 0;
+
+ if (client == NULL)
+ return -1;
+ oc = (OsCommPtr) client->osPrivate;
+ if (oc == NULL)
+ return -1;
+ oci = oc->input;
+ fd = oc->fd;
+ if (oci != NULL && fd < 0)
+ return -1;
+
+ if (AvailableInput) {
+ if (AvailableInput != oc) {
+ ConnectionInputPtr aci = AvailableInput->input;
+
+ if (aci->size > BUFWATERMARK) {
+ fsfree(aci->buffer);
+ fsfree(aci);
+ } else {
+ aci->next = FreeInputs;
+ FreeInputs = aci;
+ }
+ AvailableInput->input = (ConnectionInputPtr) NULL;
+ }
+ AvailableInput = (OsCommPtr) NULL;
+ }
+ if (!oci) {
+ if ((oci = FreeInputs ) != (ConnectionInputPtr) 0) {
+ FreeInputs = oci->next;
+ } else if (!(oci = AllocateInputBuffer())) {
+ yield_control_death();
+ return -1;
+ }
+ oc->input = oci;
+ }
+ oci->bufptr += oci->lenLastReq;
+
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+
+#ifdef WORD64
+ /* need 8-byte alignment */
+ if ((oci->bufptr - oci->buffer) & 7 && gotnow > 0)
+ {
+ memmove( oci->buffer, oci->bufptr, gotnow);
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = gotnow;
+ }
+#endif
+
+ request = (fsReq *) oci->bufptr;
+
+ /* not enough for a request */
+ if ((gotnow < SIZEOF(fsReq)) ||
+ (gotnow < (needed = request_length(request, client)))) {
+ oci->lenLastReq = 0;
+ if ((gotnow < SIZEOF(fsReq)) || needed == 0)
+ needed = SIZEOF(fsReq);
+ else if (needed > MAXBUFSIZE) {
+ yield_control_death();
+ return -1;
+ }
+ /* see if we need to shift up a partial request so the rest can fit */
+ if ((gotnow == 0) ||
+ ((oci->bufptr - oci->buffer + needed) > oci->size))
+ {
+ if ((gotnow > 0) && (oci->bufptr != oci->buffer))
+ memmove( oci->buffer, oci->bufptr, gotnow);
+ /* grow buffer if necessary */
+ if (needed > oci->size) {
+ char *ibuf;
+
+ ibuf = (char *) fsrealloc(oci->buffer, needed);
+ if (!ibuf) {
+ yield_control_death();
+ return -1;
+ }
+ oci->size = needed;
+ oci->buffer = ibuf;
+ }
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = gotnow;
+ }
+ /* fill 'er up */
+ if (oc->trans_conn == NULL) {
+ yield_control_death();
+ return -1;
+ }
+ result = _FontTransRead(oc->trans_conn, oci->buffer + oci->bufcnt,
+ oci->size - oci->bufcnt);
+ if (result <= 0) {
+#if !(defined(SVR4) && defined(i386) && !defined(sun))
+ if ((result < 0) && ETEST(errno)) {
+ yield_control_no_input();
+ return 0;
+ } else
+#endif
+ {
+
+ yield_control_death();
+ return -1;
+ }
+ }
+ oci->bufcnt += result;
+ gotnow += result;
+
+ /* free up space after huge requests */
+ if ((oci->size > BUFWATERMARK) &&
+ (oci->bufcnt < BUFSIZE) && (needed < BUFSIZE)) {
+ char *ibuf;
+
+ ibuf = (char *) fsrealloc(oci->buffer, BUFSIZE);
+ if (ibuf) {
+ oci->size = BUFSIZE;
+ oci->buffer = ibuf;
+ oci->bufptr = ibuf + oci->bufcnt - gotnow;
+ }
+ }
+ request = (fsReq *) oci->bufptr;
+ if ((gotnow < SIZEOF(fsReq)) ||
+ (gotnow < (needed = request_length(request, client)))) {
+ yield_control_no_input();
+ return 0;
+ }
+ }
+ if (needed == 0)
+ needed = SIZEOF(fsReq);
+ oci->lenLastReq = needed;
+ /*
+ * Check to see if client has at least one whole request in the buffer. If
+ * there is only a partial request, treat like buffer is empty so that
+ * select() will be called again and other clients can get into the queue.
+ */
+
+ if (gotnow >= needed + SIZEOF(fsReq)) {
+ request = (fsReq *) (oci->bufptr + needed);
+ if (gotnow >= needed + request_length(request, client))
+ FD_SET(fd, &ClientsWithInput);
+ else
+ yield_control_no_input();
+ } else {
+ if (gotnow == needed)
+ AvailableInput = oc;
+ yield_control_no_input();
+ }
+
+ if (++timesThisConnection >= MAX_TIMES_PER)
+ yield_control();
+
+ client->requestBuffer = (pointer) oci->bufptr;
+ return needed;
+}
+
+Bool
+InsertFakeRequest(ClientPtr client, char *data, int count)
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+ ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ fsReq *request;
+ int gotnow,
+ moveup;
+
+ if (AvailableInput) {
+ if (AvailableInput != oc) {
+ register ConnectionInputPtr aci = AvailableInput->input;
+
+ if (aci->size > BUFWATERMARK) {
+ fsfree(aci->buffer);
+ fsfree(aci);
+ } else {
+ aci->next = FreeInputs;
+ FreeInputs = aci;
+ }
+ AvailableInput->input = (ConnectionInputPtr) NULL;
+ }
+ AvailableInput = (OsCommPtr) NULL;
+ }
+ if (!oci) {
+ if ((oci = FreeInputs) != (ConnectionInputPtr) 0)
+ FreeInputs = oci->next;
+ else if (!(oci = AllocateInputBuffer()))
+ return FALSE;
+ oc->input = oci;
+
+ }
+ oci->bufptr += oci->lenLastReq;
+ oci->lenLastReq = 0;
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if ((gotnow + count) > oci->size) {
+ char *ibuf;
+
+ ibuf = (char *) fsrealloc(oci->buffer, gotnow + count);
+ if (!ibuf)
+ return FALSE;
+ oci->size = gotnow + count;
+ oci->buffer = ibuf;
+ oci->bufptr = ibuf + oci->bufcnt - gotnow;
+ }
+ moveup = count - (oci->bufptr - oci->buffer);
+ if (moveup > 0) {
+ if (gotnow > 0)
+ memmove( oci->bufptr + moveup, oci->bufptr, gotnow);
+ oci->bufptr += moveup;
+ oci->bufcnt += moveup;
+ }
+ memmove( oci->bufptr - count, data, count);
+ oci->bufptr -= count;
+ request = (fsReq *) oci->bufptr;
+ gotnow += count;
+ if ((gotnow >= SIZEOF(fsReq)) &&
+ (gotnow >= request_length(request, client)))
+ FD_SET(fd, &ClientsWithInput);
+ else
+ yield_control_no_input();
+ return TRUE;
+}
+
+void
+ResetCurrentRequest(ClientPtr client)
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+ ConnectionInputPtr oci = oc->input;
+ int fd = oc->fd;
+ fsReq *request;
+ int gotnow;
+
+ if (AvailableInput == oc)
+ AvailableInput = (OsCommPtr) NULL;
+ oci->lenLastReq = 0;
+ request = (fsReq *) oci->bufptr;
+ gotnow = oci->bufcnt + oci->buffer - oci->bufptr;
+ if ((gotnow >= SIZEOF(fsReq)) &&
+ (gotnow >= request_length(request, client))) {
+ FD_SET(fd, &ClientsWithInput);
+ yield_control();
+ } else {
+ yield_control_no_input();
+ }
+}
+
+int
+FlushClient(
+ ClientPtr client,
+ OsCommPtr oc,
+ char *extraBuf,
+ int extraCount,
+ int padsize)
+{
+ ConnectionOutputPtr oco = oc->output;
+ int fd = oc->fd;
+ struct iovec iov[3];
+ char padBuffer[3];
+ long written;
+ long notWritten;
+ long todo;
+
+ if (!oco)
+ return 0;
+ written = 0;
+ notWritten = oco->count + extraCount + padsize;
+ todo = notWritten;
+ while (notWritten) {
+ long before = written;
+ long remain = todo;
+ int i = 0;
+ long len;
+
+ /*-
+ * You could be very general here and have "in" and "out" iovecs and
+ * write a loop without using a macro, but what the heck. This
+ * translates to:
+ *
+ * how much of this piece is new?
+ * if more new then we are trying this time, clamp
+ * if nothing new
+ * then bump down amount already written, for next piece
+ * else put new stuff in iovec, will need all of next piece
+ *
+ * Note that todo had better be at least 1 or else we'll end up
+ * writing 0 iovecs.
+ */
+
+#define InsertIOV(pointer, length) \
+ len = (length) - before; \
+ if (len > remain) \
+ len = remain; \
+ if (len <= 0) { \
+ before = (-len); \
+ } else { \
+ iov[i].iov_len = len; \
+ iov[i].iov_base = (pointer) + before; \
+ i++; \
+ remain -= len; \
+ before = 0; \
+ }
+
+ InsertIOV((char *) oco->buf, oco->count);
+ InsertIOV(extraBuf, extraCount);
+ InsertIOV(padBuffer, padsize);
+
+ errno = 0;
+ if (oc->trans_conn && (len = _FontTransWritev(oc->trans_conn, iov, i)) >= 0) {
+ written += len;
+ notWritten -= len;
+ todo = notWritten;
+ } else if (ETEST(errno)
+#ifdef SUNSYSV /* check for another brain-damaged OS bug */
+ || (errno == 0)
+#endif
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ || ((errno == EMSGSIZE) && (todo == 1))
+#endif
+ )
+ {
+ FD_SET(fd, &ClientsWriteBlocked);
+ AnyClientsWriteBlocked = TRUE;
+
+ if (written < oco->count) {
+ if (written > 0) {
+ oco->count -= written;
+ memmove( (char *) oco->buf, (char *) oco->buf + written,
+ oco->count);
+ written = 0;
+ }
+ } else {
+ written -= oco->count;
+ oco->count = 0;
+ }
+
+ /* grow buffer if necessary */
+ if (notWritten > oco->size) {
+ unsigned char *obuf;
+
+ obuf = (unsigned char *) fsrealloc(oco->buf,
+ notWritten + OutputBufferSize);
+ if (!obuf) {
+ if (oc->trans_conn)
+ _FontTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ MarkClientException(client);
+ oco->count = 0;
+ return -1;
+ }
+ oco->size = notWritten + OutputBufferSize;
+ oco->buf = obuf;
+ }
+ if ((len = extraCount - written) > 0) {
+ memmove( (char *) oco->buf + oco->count,
+ extraBuf + written, len);
+ }
+ oco->count = notWritten;
+ return extraCount;
+ }
+#ifdef EMSGSIZE /* check for another brain-damaged OS bug */
+ else if (errno == EMSGSIZE)
+ {
+ todo >>= 1;
+ }
+#endif
+ else
+ {
+ if (oc->trans_conn)
+ _FontTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ MarkClientException(client);
+ oco->count = 0;
+ return -1;
+ }
+ }
+
+ /* everything was flushed */
+ oco->count = 0;
+
+ /* clear the write block if it was set */
+ if (AnyClientsWriteBlocked) {
+ FD_CLR(fd, &ClientsWriteBlocked);
+ if (!XFD_ANYSET(&ClientsWriteBlocked))
+ AnyClientsWriteBlocked = FALSE;
+ }
+ if (oco->size > BUFWATERMARK) {
+ fsfree(oco->buf);
+ fsfree(oco);
+ } else {
+ oco->next = FreeOutputs;
+ FreeOutputs = oco;
+ }
+ oc->output = (ConnectionOutputPtr) NULL;
+
+ return extraCount;
+}
+
+void
+FlushAllOutput(void)
+{
+ int index, base;
+ fd_mask mask;
+ OsCommPtr oc;
+ ClientPtr client;
+
+ if (!NewOutputPending)
+ return;
+
+ NewOutputPending = FALSE;
+
+ for (base = 0; base < howmany(XFD_SETSIZE, NFDBITS); base++) {
+ mask = OutputPending.fds_bits[base];
+ OutputPending.fds_bits[base] = 0;
+ while (mask) {
+ index = ffs(mask) - 1;
+ mask &= ~lowbit(mask);
+ if ((index = ConnectionTranslation[(base << 5) + index]) == 0)
+ continue;
+ client = clients[index];
+ if (client->clientGone == CLIENT_GONE)
+ continue;
+ oc = (OsCommPtr) client->osPrivate;
+ if (FD_ISSET(oc->fd, &ClientsWithInput)) {
+ FD_SET(oc->fd, &OutputPending);
+ NewOutputPending = TRUE;
+ } else {
+ (void) FlushClient(client, oc, (char *) NULL, 0, 0);
+ }
+ }
+ }
+}
+
+/*
+ * returns number of bytes written
+ */
+static int
+write_to_client_internal(ClientPtr client, int count, char *buf, int padBytes)
+{
+ OsCommPtr oc = (OsCommPtr) client->osPrivate;
+ ConnectionOutputPtr oco = oc->output;
+
+ if (!count)
+ return 0;
+
+ if (!oco) {
+ if ((oco = FreeOutputs) != (ConnectionOutputPtr) 0) {
+ FreeOutputs = oco->next;
+ } else if (!(oco = AllocateOutputBuffer())) {
+ _FontTransClose(oc->trans_conn);
+ oc->trans_conn = NULL;
+ MarkClientException(client);
+ return -1;
+ }
+ oc->output = oco;
+ }
+ if (oco->count + count + padBytes > oco->size) {
+ FD_CLR(oc->fd, &OutputPending);
+ NewOutputPending = FALSE;
+ return FlushClient(client, oc, buf, count, padBytes);
+ }
+ NewOutputPending = TRUE;
+ FD_SET(oc->fd, &OutputPending);
+ memmove( (char *) oco->buf + oco->count, buf, count);
+ oco->count += count + padBytes;
+
+ return count;
+}
+
+void
+WriteToClientUnpadded(ClientPtr client, int count, char *buf)
+{
+ write_to_client_internal(client, count, buf, 0);
+}
+
+static int padlength[4] = {0, 3, 2, 1};
+
+void
+WriteToClient(ClientPtr client, int count, char *buf)
+{
+ int flag = 0;
+ if (NULL == buf) {
+ flag = -1;
+ buf = (char *)fsalloc(count); memset(buf, 0, count);
+ }
+ write_to_client_internal(client, count, buf, padlength[count & 3]);
+ if (flag)
+ fsfree(buf);
+}
+
+static ConnectionInputPtr
+AllocateInputBuffer(void)
+{
+ register ConnectionInputPtr oci;
+
+ oci = (ConnectionInputPtr) fsalloc(sizeof(ConnectionInput));
+ if (!oci)
+ return (ConnectionInputPtr) NULL;
+ oci->buffer = (char *) fsalloc(BUFSIZE);
+ if (!oci->buffer) {
+ fsfree(oci);
+ return (ConnectionInputPtr) NULL;
+ }
+ oci->next = 0;
+ oci->size = BUFSIZE;
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = 0;
+ oci->lenLastReq = 0;
+ return oci;
+}
+
+static ConnectionOutputPtr
+AllocateOutputBuffer(void)
+{
+ register ConnectionOutputPtr oco;
+
+ oco = (ConnectionOutputPtr) fsalloc(sizeof(ConnectionOutput));
+ if (!oco)
+ return (ConnectionOutputPtr) NULL;
+ oco->buf = (unsigned char *) fsalloc(BUFSIZE);
+ if (!oco->buf) {
+ fsfree(oco);
+ return (ConnectionOutputPtr) NULL;
+ }
+ oco->size = BUFSIZE;
+ oco->count = 0;
+ return oco;
+}
+
+
+void
+FreeOsBuffers(OsCommPtr oc)
+{
+ register ConnectionInputPtr oci;
+ register ConnectionOutputPtr oco;
+
+ if (AvailableInput == oc)
+ AvailableInput = (OsCommPtr) NULL;
+ if ((oci = oc->input) != (ConnectionInputPtr) 0) {
+ if (FreeInputs) {
+ fsfree(oci->buffer);
+ fsfree(oci);
+ } else {
+ FreeInputs = oci;
+ oci->next = (ConnectionInputPtr) NULL;
+ oci->bufptr = oci->buffer;
+ oci->bufcnt = 0;
+ oci->lenLastReq = 0;
+ }
+ }
+ if ((oco = oc->output) != (ConnectionOutputPtr) 0) {
+ if (FreeOutputs) {
+ fsfree(oco->buf);
+ fsfree(oco);
+ } else {
+ FreeOutputs = oco;
+ oco->next = (ConnectionOutputPtr) NULL;
+ oco->count = 0;
+ }
+ }
+}
+
+void
+ResetOsBuffers(void)
+{
+ register ConnectionInputPtr oci;
+ register ConnectionOutputPtr oco;
+
+ while ((oci = FreeInputs) != (ConnectionInputPtr) 0) {
+ FreeInputs = oci->next;
+ fsfree(oci->buffer);
+ fsfree(oci);
+ }
+ while ((oco = FreeOutputs) != (ConnectionOutputPtr) 0) {
+ FreeOutputs = oco->next;
+ fsfree(oco->buf);
+ fsfree(oco);
+ }
+}
diff --git a/app/xfs/os/osdep.h b/app/xfs/os/osdep.h
new file mode 100644
index 000000000..4b07b283e
--- /dev/null
+++ b/app/xfs/os/osdep.h
@@ -0,0 +1,134 @@
+/* $Xorg: osdep.h,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR 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.
+ *
+ * @(#)osdep.h 4.1 5/2/91
+ *
+ */
+/* $XFree86: xc/programs/xfs/os/osdep.h,v 3.11 2001/12/14 20:01:41 dawes Exp $ */
+
+#ifndef _OSDEP_H_
+#define _OSDEP_H_
+
+#define BOTIMEOUT 200 /* in milliseconds */
+#define BUFSIZE 4096
+#define BUFWATERMARK 8192
+#define MAXBUFSIZE (1 << 15)
+
+#ifndef sgi /* SGI defines OPEN_MAX in a useless way */
+#ifndef X_NOT_POSIX
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif
+#endif
+#endif
+
+#ifndef OPEN_MAX
+#if defined(__UNIXOS2__) || defined(__QNX__)
+#define OPEN_MAX 256
+#else
+#ifdef SVR4
+#define OPEN_MAX 128
+#else
+#include <sys/param.h>
+#ifdef __GNU__
+#define OPEN_MAX (sysconf(_SC_OPEN_MAX))
+#endif /*__GNU__*/
+#ifndef OPEN_MAX
+#ifdef SCO325
+#define OPEN_MAX (sysconf(_SC_OPEN_MAX))
+#else
+#if defined(NOFILE) && !defined(NOFILES_MAX)
+#define OPEN_MAX NOFILE
+#else
+#define OPEN_MAX NOFILES_MAX
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+
+#if defined(__GNU__) || defined(SCO325)
+#define MAXSOCKS 128
+#else /*__GNU__*/
+#if OPEN_MAX <= 128 /* 128 is value of MAXCLIENTS */
+#define MAXSOCKS (OPEN_MAX - 1)
+#else
+#define MAXSOCKS 128
+#endif
+#endif /*__GNU__*/
+
+#include <stddef.h>
+
+typedef struct _connectionInput {
+ struct _connectionInput *next;
+ char *buffer; /* contains current client input */
+ char *bufptr; /* pointer to current start of data */
+ int bufcnt; /* count of bytes in buffer */
+ int lenLastReq;
+ int size;
+} ConnectionInput, *ConnectionInputPtr;
+
+typedef struct _connectionOutput {
+ struct _connectionOutput *next;
+ int size;
+ unsigned char *buf;
+ int count;
+} ConnectionOutput, *ConnectionOutputPtr;
+
+typedef struct _osComm {
+ int fd;
+ ConnectionInputPtr input;
+ ConnectionOutputPtr output;
+ long conn_time; /* timestamp if not established, else 0 */
+ struct _XtransConnInfo *trans_conn; /* transport connection object */
+} OsCommRec, *OsCommPtr;
+
+#endif /* _OSDEP_H_ */
diff --git a/app/xfs/os/osglue.c b/app/xfs/os/osglue.c
new file mode 100644
index 000000000..e1e9ef239
--- /dev/null
+++ b/app/xfs/os/osglue.c
@@ -0,0 +1,384 @@
+/* $Xorg: osglue.c,v 1.4 2001/02/09 02:05:44 xorgcvs Exp $ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR 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.
+ *
+ * $NCDXorg: @(#)osglue.c,v 4.6 1991/07/09 14:07:30 lemke Exp $
+ *
+ */
+/* $XFree86: xc/programs/xfs/os/osglue.c,v 3.18 2002/10/15 01:45:03 dawes Exp $ */
+
+/*
+ * this is miscellaneous OS specific stuff.
+ *
+ * Catalogue support, alternate servers, and cloneing
+ */
+
+#include <X11/Xtrans/Xtrans.h>
+#include "osstruct.h"
+#include <stdio.h>
+#include <stdlib.h>
+#define XK_LATIN1
+#include <X11/keysymdef.h>
+#ifdef __UNIXOS2__
+#define _NFILE 256
+#endif
+
+Bool drone_server = FALSE;
+extern char *progname;
+extern char *configfilename;
+
+static int num_alts;
+static AlternateServerPtr alt_servers = (AlternateServerPtr) 0;
+
+extern XtransConnInfo *ListenTransConns;
+extern int *ListenTransFds;
+extern int ListenTransCount;
+
+/*
+ * XXX
+ *
+ * Catalogue support is absolutely minimal. Some guts are here, but
+ * we don't actually do anything with them so the only one exported is
+ * 'all'. Be warned that other parts of the server may incorrectly
+ * assume the catalogue list is global, and will therefore need fixing.
+ *
+ */
+
+static char *catalogue_name = "all";
+
+static Bool /* stolen from R4 Match() */
+pattern_match(char *pat, int plen, char *string)
+{
+ register int i,
+ l;
+ int j,
+ m,
+ res;
+ register char cp,
+ cs;
+ int head,
+ tail;
+
+ head = 0;
+ tail = plen;
+
+ res = -1;
+ for (i = 0; i < head; i++) {
+ cp = pat[i];
+ if (cp == XK_question) {
+ if (!string[i])
+ return res;
+ res = 0;
+ } else if (cp != string[i])
+ return res;
+ }
+ if (head == plen)
+ return (string[head] ? res : 1);
+ l = head;
+ while (++i < tail) {
+ /* we just skipped an asterisk */
+ j = i;
+ m = l;
+ while ((cp = pat[i]) != XK_asterisk) {
+ if (!(cs = string[l]))
+ return 0;
+ if ((cp != cs) && (cp != XK_question)) {
+ m++;
+ cp = pat[j];
+ if (cp == XK_asterisk) {
+ if (!string[m])
+ return 0;
+ } else {
+ while ((cs = string[m]) != cp) {
+ if (!cs)
+ return 0;
+ m++;
+ }
+ }
+ l = m;
+ i = j;
+ }
+ l++;
+ i++;
+ }
+ }
+ m = strlen(&string[l]);
+ j = plen - tail;
+ if (m < j)
+ return 0;
+ l = (l + m) - j;
+ while ((cp = pat[i])) {
+ if ((cp != string[l]) && (cp != XK_question))
+ return 0;
+ l++;
+ i++;
+ }
+ return 1;
+}
+
+int
+ListCatalogues(char *pattern, int patlen, int maxnames,
+ char **catalogues, int *len)
+{
+ int count = 0;
+ char *catlist = NULL;
+ int size = 0;
+
+ if (maxnames) {
+ if (pattern_match(pattern, patlen, catalogue_name)) {
+ size = strlen(catalogue_name);
+ catlist = (char *) fsalloc(size + 1);
+ if (!catlist)
+ goto bail;
+ *catlist = size;
+ memmove( &catlist[1], catalogue_name, size);
+ size++; /* for length */
+ count++;
+ }
+ }
+bail:
+ *len = size;
+ *catalogues = catlist;
+ return count;
+}
+
+/*
+ * check if catalogue list is valid
+ */
+
+int
+ValidateCatalogues(int *num, char *cats)
+{
+ char *c = cats;
+ int i,
+ len;
+
+ for (i = 0; i < *num; i++) {
+ len = *c++;
+ if (strncmp(c, catalogue_name, len)) {
+ *num = i; /* return bad entry index */
+ return FSBadName;
+ }
+ c += len;
+ }
+ return FSSuccess;
+}
+
+int
+SetAlternateServers(char *list)
+{
+ char *t,
+ *st;
+ AlternateServerPtr alts,
+ a;
+ int num,
+ i;
+
+ t = list;
+ num = 1;
+ while (*t) {
+ if (*t == ',')
+ num++;
+ t++;
+ }
+
+ a = alts = (AlternateServerPtr) fsalloc(sizeof(AlternateServerRec) * num);
+ if (!alts)
+ return FSBadAlloc;
+
+ st = t = list;
+ a->namelen = 0;
+ while (*t) {
+ if (*t == ',') {
+ a->name = (char *) fsalloc(a->namelen);
+ if (!a->name) {
+ /* XXX -- leak */
+ return FSBadAlloc;
+ }
+ memmove( a->name, st, a->namelen);
+ a->subset = FALSE; /* XXX */
+ a++;
+ t++;
+ st = t;
+ a->namelen = 0;
+ } else {
+ a->namelen++;
+ t++;
+ }
+ }
+ a->name = (char *) fsalloc(a->namelen);
+ if (!a->name) {
+ /* XXX -- leak */
+ return FSBadAlloc;
+ }
+ memmove( a->name, st, a->namelen);
+ a->subset = FALSE; /* XXX */
+
+ for (i = 0; i < num_alts; i++) {
+ fsfree((char *) alt_servers[i].name);
+ }
+ fsfree((char *) alt_servers);
+ num_alts = num;
+ alt_servers = alts;
+ return FSSuccess;
+}
+
+int
+ListAlternateServers(AlternateServerPtr *svrs)
+{
+ *svrs = alt_servers;
+ return num_alts;
+}
+
+/*
+ * here's some fun stuff. in order to cleanly handle becoming overloaded,
+ * this allows us to clone ourselves. the parent keeps the Listen
+ * socket open, and sends it to itself. the child stops listening,
+ * and becomes a drone, hanging out till it loses all its clients.
+ */
+
+int
+CloneMyself(void)
+{
+ int child;
+ char old_listen_arg[256];
+ char *arg_ptr = old_listen_arg;
+ int i, j;
+ int lastfdesc;
+ char portnum[20];
+
+ assert(!drone_server); /* a drone shouldn't hit this */
+
+ if (!CloneSelf)
+ return -1;
+
+#ifdef __UNIXOS2__
+ NoticeF("cloning of font server not supported under OS/2!\n");
+ return(-1);
+#endif
+
+ old_listen_arg[0] = '\0';
+
+#ifdef XNO_SYSCONF /* should only be on FreeBSD 1.x and NetBSD 0.x */
+#undef _SC_OPEN_MAX
+#endif
+#ifdef _SC_OPEN_MAX
+ lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
+#else
+#if defined(hpux) || defined(__UNIXOS2__)
+ lastfdesc = _NFILE - 1;
+#else
+ lastfdesc = getdtablesize() - 1;
+#endif /* hpux */
+#endif
+
+ NoticeF("attempting clone...\n");
+ chdir("/");
+ child = fork();
+ if (child == -1) {
+ /* failed to fork */
+ ErrorF("clone failed to fork()\n");
+ return -1;
+ }
+ /*
+ * Note: they still share the same process group, and killing the parent
+ * will take out all the kids as well. this is considered a feature (at
+ * least until i'm convinced otherwise)
+ */
+ if (child == 0) {
+ StopListening();
+ NoticeF("clone: child becoming drone\n");
+ drone_server = TRUE;
+ return 1;
+ } else { /* parent */
+ NoticeF("clone: parent revitalizing as %s\n", progname);
+ CloseErrors();
+ /* XXX should we close stdio as well? */
+ for (i = 3; i < lastfdesc; i++)
+ {
+ for (j = 0; j < ListenTransCount; j++)
+ if (ListenTransFds[j] == i)
+ break;
+
+ if (j >= ListenTransCount)
+ (void) close(i);
+ }
+
+ for (i = 0; i < ListenTransCount; i++)
+ {
+ int trans_id, fd;
+ char *port;
+
+ if (!_FontTransGetReopenInfo (ListenTransConns[i],
+ &trans_id, &fd, &port))
+ continue;
+
+ sprintf (arg_ptr, "%d/%d/%s", trans_id, fd, port);
+ arg_ptr += strlen (arg_ptr);
+ free (port);
+
+ if (i < ListenTransCount - 1)
+ {
+ strcat (arg_ptr, ",");
+ arg_ptr++;
+ }
+ }
+
+ sprintf (portnum, "%d", ListenPort);
+ if (*old_listen_arg != '\0')
+ execlp(progname, progname,
+ "-ls", old_listen_arg,
+ "-cf", configfilename,
+ "-port", portnum,
+ (void *)NULL);
+
+ InitErrors(); /* reopen errors, since we don't want to lose
+ * this */
+ Error("clone failed");
+ FatalError("failed to clone self\n");
+ }
+ /* NOTREACHED */
+ return 0;
+}
diff --git a/app/xfs/os/osinit.c b/app/xfs/os/osinit.c
new file mode 100644
index 000000000..a12bb002d
--- /dev/null
+++ b/app/xfs/os/osinit.c
@@ -0,0 +1,64 @@
+/* $Xorg: osinit.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */
+/*
+ * os init code
+ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR 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.
+ *
+ * @(#)osinit.c 4.3 5/7/91
+ *
+ */
+/* $XFree86: xc/programs/xfs/os/osinit.c,v 1.4 2001/01/17 23:45:33 dawes Exp $ */
+
+#include "os.h"
+
+extern long LastReapTime;
+
+void
+OsInit(void)
+{
+ LastReapTime = GetTimeInMillis();
+ OsInitAllocator ();
+}
diff --git a/app/xfs/os/utils.c b/app/xfs/os/utils.c
new file mode 100644
index 000000000..fcc1c2a06
--- /dev/null
+++ b/app/xfs/os/utils.c
@@ -0,0 +1,575 @@
+/* $Xorg: utils.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */
+/*
+ * misc os utilities
+ */
+/*
+
+Copyright 1990, 1991, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices, or Digital
+ * not be used in advertising or publicity pertaining to distribution
+ * of the software without specific, written prior permission.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES,
+ * OR 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.
+ */
+/* $XFree86: xc/programs/xfs/os/utils.c,v 3.20 2002/10/15 01:45:03 dawes Exp $ */
+
+#include <stdio.h>
+#include <X11/Xos.h>
+#include <stdlib.h>
+#include "misc.h"
+#include "globals.h"
+#include <signal.h>
+#ifdef MEMBUG
+#include <util/memleak/memleak.h>
+#endif
+#include <sys/wait.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <errno.h>
+#include <string.h>
+
+#ifndef X_NOT_POSIX
+#ifdef _POSIX_SOURCE
+#include <limits.h>
+#else
+#define _POSIX_SOURCE
+#include <limits.h>
+#undef _POSIX_SOURCE
+#endif
+#endif /* X_NOT_POSIX */
+#ifndef PATH_MAX
+#include <sys/param.h>
+#ifndef PATH_MAX
+#ifdef MAXPATHLEN
+#define PATH_MAX MAXPATHLEN
+#else
+#define PATH_MAX 1024
+#endif
+#endif
+#endif /* PATH_MAX */
+
+#if defined(X_NOT_POSIX) && (defined(SYSV) || defined(SVR4))
+#define SIGNALS_RESET_WHEN_CAUGHT
+#endif
+
+#include <stdlib.h>
+
+extern char *configfilename;
+static Bool dropPriv = FALSE; /* whether or not to drop root privileges */
+#ifdef DEFAULT_DAEMON
+static Bool becomeDaemon = TRUE; /* whether to become a daemon or not */
+#else
+static Bool becomeDaemon = FALSE; /* whether to become a daemon or not */
+#endif
+static const char *userId = NULL;
+char *progname;
+Bool CloneSelf;
+Bool portFromCmdline = FALSE;
+
+OldListenRec *OldListen = NULL;
+int OldListenCount = 0;
+
+#ifdef STDERR_FILENO
+# define WRITES write(STDERR_FILENO, s, strlen(s))
+#else
+# define WRITES write(fileno(stderr), s, strlen(s))
+#endif
+
+static char *pidFile = XFSPIDDIR "/xfs.pid";
+static int pidFd;
+static FILE *pidFilePtr;
+static int StorePid (void);
+
+/* ARGSUSED */
+SIGVAL
+AutoResetServer(int n)
+{
+ int olderrno = errno;
+
+#ifdef DEBUG
+ WRITES("got a reset signal\n");
+#endif
+
+ dispatchException |= DE_RESET;
+ isItTimeToYield = TRUE;
+
+#ifdef SIGNALS_RESET_WHEN_CAUGHT
+ signal(SIGHUP, AutoResetServer);
+#endif
+ errno = olderrno;
+}
+
+/* ARGSUSED */
+SIGVAL
+GiveUp(int n)
+{
+ int olderrno = errno;
+#ifdef DEBUG
+ WRITES("got a TERM signal\n");
+#endif
+
+ dispatchException |= DE_TERMINATE;
+ isItTimeToYield = TRUE;
+ errno = olderrno;
+}
+
+/* ARGSUSED */
+SIGVAL
+ServerReconfig(int n)
+{
+ int olderrno = errno;
+
+#ifdef DEBUG
+ WRITES("got a re-config signal\n");
+#endif
+
+ dispatchException |= DE_RECONFIG;
+ isItTimeToYield = TRUE;
+
+#ifdef SIGNALS_RESET_WHEN_CAUGHT
+ signal(SIGUSR1, ServerReconfig);
+#endif
+ errno = olderrno;
+}
+
+/* ARGSUSED */
+SIGVAL
+ServerCacheFlush(int n)
+{
+ int olderrno = errno;
+
+#ifdef DEBUG
+ WRITES("got a flush signal\n");
+#endif
+
+ dispatchException |= DE_FLUSH;
+ isItTimeToYield = TRUE;
+
+#ifdef SIGNALS_RESET_WHEN_CAUGHT
+ signal(SIGUSR2, ServerCacheFlush);
+#endif
+ errno = olderrno;
+}
+
+/* ARGSUSED */
+SIGVAL
+CleanupChild(int n)
+{
+ int olderrno = errno;
+
+#ifdef DEBUG
+ WRITES("got a child signal\n");
+#endif
+
+ wait(NULL);
+
+#ifdef SIGNALS_RESET_WHEN_CAUGHT
+ signal(SIGCHLD, CleanupChild);
+#endif
+ errno = olderrno;
+}
+
+long
+GetTimeInMillis(void)
+{
+ struct timeval tp;
+
+ X_GETTIMEOFDAY(&tp);
+ return ((tp.tv_sec * 1000) + (tp.tv_usec / 1000));
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: %s [-config config_file] [-port tcp_port] [-droppriv] [-daemon] [-nodaemon] [-user user_name] [-ls listen_socket]\n",
+ progname);
+ exit(1);
+}
+
+void
+OsInitAllocator (void)
+{
+#ifdef MEMBUG
+ CheckMemory ();
+#endif
+}
+
+
+/*
+ * The '-ls' option is used for cloning the font server.
+ *
+ * We expect a single string of the form...
+ *
+ * transport_id/fd/portnum[,transport_id/fd/portnum]...
+ *
+ * [] denotes optional and ... denotes repitition.
+ *
+ * The string must be _exactly_ in the above format.
+ */
+
+void
+ProcessLSoption (char *str)
+{
+ char *ptr = str;
+ char *slash;
+ char number[20];
+ int count = 0;
+ int len, i;
+
+ while (*ptr != '\0')
+ {
+ if (*ptr == ',')
+ count++;
+ ptr++;
+ }
+
+ OldListenCount = count + 1;
+ OldListen = (OldListenRec *) malloc (
+ OldListenCount * sizeof (OldListenRec));
+ if (OldListen == NULL) {
+ fprintf(stderr, "ProcessLSoption: malloc error\n");
+ exit(1);
+ }
+ ptr = str;
+
+ for (i = 0; i < OldListenCount; i++)
+ {
+ slash = (char *) strchr (ptr, '/');
+ if (slash == NULL) {
+ usage();
+ }
+ len = slash - ptr;
+ strncpy (number, ptr, len);
+ number[len] = '\0';
+ OldListen[i].trans_id = atoi (number);
+
+ ptr = slash + 1;
+
+ slash = (char *) strchr (ptr, '/');
+ if (slash == NULL) {
+ usage();
+ }
+ len = slash - ptr;
+ strncpy (number, ptr, len);
+ number[len] = '\0';
+ OldListen[i].fd = atoi (number);
+
+ ptr = slash + 1;
+
+ if (i == OldListenCount - 1)
+ OldListen[i].portnum = atoi (ptr);
+ else
+ {
+ char *comma = (char *) strchr (ptr, ',');
+ if (comma == NULL) {
+ usage();
+ }
+ len = comma - ptr;
+ strncpy (number, ptr, len);
+ number[len] = '\0';
+ OldListen[i].portnum = atoi (number);
+
+ ptr = comma + 1;
+ }
+ }
+}
+
+
+
+/* ARGSUSED */
+void
+ProcessCmdLine(int argc, char **argv)
+{
+ int i;
+
+ progname = argv[0];
+ for (i = 1; i < argc; i++) {
+ if (!strcmp(argv[i], "-port")) {
+ if (argv[i + 1]) {
+ ListenPort = atoi(argv[++i]);
+ portFromCmdline = TRUE;
+ } else
+ usage();
+ } else if (!strcmp(argv[i], "-ls")) {
+ if (argv[i + 1])
+ ProcessLSoption (argv[++i]);
+ else
+ usage();
+ } else if (!strcmp(argv[i], "-droppriv")) {
+ dropPriv = TRUE;
+ } else if (!strcmp(argv[i], "-daemon")) {
+ becomeDaemon = TRUE;
+ } else if (!strcmp(argv[i], "-nodaemon")) {
+ becomeDaemon = FALSE;
+ } else if (!strcmp(argv[i], "-user")) {
+ if (argv[i + 1])
+ userId = argv[++i];
+ else
+ usage();
+ } else if (!strcmp(argv[i], "-cf") || !strcmp(argv[i], "-config")) {
+ if (argv[i + 1])
+ configfilename = argv[++i];
+ else
+ usage();
+ }
+#ifdef MEMBUG
+ else if ( strcmp( argv[i], "-alloc") == 0)
+ {
+ extern unsigned long MemoryFail;
+ if(++i < argc)
+ MemoryFail = atoi(argv[i]);
+ else
+ usage ();
+ }
+#endif
+ else
+ usage();
+ }
+}
+
+
+#ifndef SPECIAL_MALLOC
+
+unsigned long Must_have_memory;
+
+#ifdef MEMBUG
+#define MEM_FAIL_SCALE 100000
+unsigned long MemoryFail;
+
+#endif
+
+/* FSalloc -- FS's internal memory allocator. Why does it return unsigned
+ * int * instead of the more common char *? Well, if you read K&R you'll
+ * see they say that alloc must return a pointer "suitable for conversion"
+ * to whatever type you really want. In a full-blown generic allocator
+ * there's no way to solve the alignment problems without potentially
+ * wasting lots of space. But we have a more limited problem. We know
+ * we're only ever returning pointers to structures which will have to
+ * be long word aligned. So we are making a stronger guarantee. It might
+ * have made sense to make FSalloc return char * to conform with people's
+ * expectations of malloc, but this makes lint happier.
+ */
+
+pointer
+FSalloc (unsigned long amount)
+{
+ register pointer ptr;
+
+ if ((long)amount < 0)
+ return 0;
+ if (amount == 0)
+ amount++;
+ /* aligned extra on long word boundary */
+ amount = (amount + 3) & ~3;
+#ifdef MEMBUG
+ if (!Must_have_memory && MemoryFail &&
+ ((random() % MEM_FAIL_SCALE) < MemoryFail))
+ return 0;
+ if (ptr = (pointer)fmalloc(amount))
+ return ptr;
+#else
+ if ((ptr = (pointer)malloc(amount)) != 0)
+ return ptr;
+#endif
+ if (Must_have_memory)
+ FatalError("out of memory\n");
+ return 0;
+}
+
+/*****************
+ * FScalloc
+ *****************/
+
+pointer
+FScalloc (unsigned long amount)
+{
+ pointer ret;
+
+ ret = FSalloc (amount);
+ if (ret)
+ bzero ((char *) ret, (int) amount);
+ return ret;
+}
+
+/*****************
+ * FSrealloc
+ *****************/
+
+pointer
+FSrealloc (pointer ptr, unsigned long amount)
+{
+#ifdef MEMBUG
+ if (!Must_have_memory && MemoryFail &&
+ ((random() % MEM_FAIL_SCALE) < MemoryFail))
+ return 0;
+ ptr = (pointer)frealloc((char *) ptr, amount);
+ if (ptr)
+ return ptr;
+#else
+ if ((long)amount <= 0)
+ {
+ if (ptr && !amount)
+ free(ptr);
+ return 0;
+ }
+ amount = (amount + 3) & ~3;
+ if (ptr)
+ ptr = (pointer)realloc((char *)ptr, amount);
+ else
+ ptr = (pointer)malloc(amount);
+ if (ptr)
+ return ptr;
+#endif
+ if (Must_have_memory)
+ FatalError("out of memory\n");
+ return 0;
+}
+
+/*****************
+ * FSfree
+ * calls free
+ *****************/
+
+void
+FSfree(pointer ptr)
+{
+#ifdef MEMBUG
+ if (ptr)
+ ffree((char *)ptr);
+#else
+ if (ptr)
+ free((char *)ptr);
+#endif
+}
+
+#endif /* SPECIAL_MALLOC */
+
+
+void
+SetUserId(void)
+{
+ /* become xfs user (or other specified on command line) if possible */
+ if ((geteuid() == 0) && (dropPriv || userId)) {
+ const char *user;
+ struct passwd *pwent;
+
+ if (!userId)
+ user = "xfs";
+ else
+ user = userId;
+ pwent = getpwnam(user);
+ if (pwent) {
+ if (setgid(pwent->pw_gid)) {
+ FatalError("fatal: couldn't set groupid to xfs user's group\n");
+ }
+#ifndef QNX4
+#ifndef __CYGWIN__
+ if (setgroups(0, NULL)) {
+ FatalError("fatal: couldn't drop supplementary groups\n");
+ }
+#endif
+ if (initgroups(user, pwent->pw_gid)) {
+ FatalError("fatal: couldn't init supplementary groups\n");
+ }
+#endif /* QNX4 */
+ if (setuid(pwent->pw_uid)) {
+ FatalError("fatal: couldn't set userid to %s user\n", user);
+ }
+ }
+ } else if (dropPriv || userId) {
+ FatalError("fatal: -droppriv or -user flag specified, but xfs not run as root\n");
+ }
+}
+
+
+void
+SetDaemonState(void)
+{
+ int oldpid;
+
+ if (becomeDaemon) {
+ BecomeDaemon();
+ if ((oldpid = StorePid ())) {
+ if (oldpid == -1)
+ ErrorF ("error opening process-id file %s\n", pidFile);
+ else
+ ErrorF ("process-id file %s indicates another xfs is "
+ "running (pid %d); exiting\n", pidFile, oldpid);
+ exit(1);
+ }
+ }
+}
+
+
+static int
+StorePid (void)
+{
+ int oldpid;
+
+ if (pidFile[0] != '\0') {
+ pidFd = open (pidFile, O_RDWR);
+ if (pidFd == -1 && errno == ENOENT)
+ pidFd = open (pidFile, O_RDWR|O_CREAT, 0666);
+ if (pidFd == -1 || !(pidFilePtr = fdopen (pidFd, "r+")))
+ {
+ ErrorF ("cannot open process-id file %s: %s\n", pidFile,
+ strerror (errno));
+ return -1;
+ }
+ if (fscanf (pidFilePtr, "%d\n", &oldpid) != 1)
+ oldpid = -1;
+ if (fseek (pidFilePtr, 0L, SEEK_SET) == -1)
+ {
+ ErrorF ("cannot seek process-id file %s: %s\n", pidFile,
+ strerror (errno));
+ return -1;
+ }
+ if (fprintf (pidFilePtr, "%5ld\n", (long) getpid ()) != 6)
+ {
+ ErrorF ("cannot write to process-id file %s: %s\n", pidFile,
+ strerror (errno));
+ return -1;
+ }
+ (void) fflush (pidFilePtr);
+ (void) fclose (pidFilePtr);
+ }
+ return 0;
+}
diff --git a/app/xfs/os/waitfor.c b/app/xfs/os/waitfor.c
new file mode 100644
index 000000000..09e30c87c
--- /dev/null
+++ b/app/xfs/os/waitfor.c
@@ -0,0 +1,231 @@
+/* $Xorg: waitfor.c,v 1.4 2001/02/09 02:05:45 xorgcvs Exp $ */
+/*
+ * waits for input
+ */
+/*
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+ * Copyright 1990, 1991 Network Computing Devices;
+ * Portions Copyright 1987 by Digital Equipment Corporation
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 names of Network Computing Devices,
+ * or Digital not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. Network Computing Devices, or Digital
+ * make no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR 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.
+ *
+ * $NCDXorg: @(#)waitfor.c,v 4.5 1991/06/24 11:59:20 lemke Exp $
+ *
+ */
+/* $XFree86: xc/programs/xfs/os/waitfor.c,v 3.15 2001/12/14 20:01:41 dawes Exp $ */
+
+#include <X11/Xos.h> /* strings, time, etc */
+
+#include <stdio.h>
+#include <errno.h>
+#if !defined(Lynx)
+#include <sys/param.h>
+#endif
+
+#include "clientstr.h"
+#include "globals.h"
+#include "X11/Xpoll.h"
+#include "osdep.h"
+#include "os.h"
+
+#ifdef __UNIXOS2__
+#define select(n,r,w,x,t) os2PseudoSelect(n,r,w,x,t)
+#endif
+
+extern WorkQueuePtr workQueue;
+
+
+extern fd_set WellKnownConnections;
+extern fd_set LastSelectMask;
+extern fd_set WriteMask;
+extern fd_set ClientsWithInput;
+extern fd_set ClientsWriteBlocked;
+extern fd_set AllSockets;
+extern fd_set AllClients;
+extern fd_set OutputPending;
+
+extern Bool AnyClientsWriteBlocked;
+extern Bool NewOutputPending;
+
+extern int ConnectionTranslation[];
+
+long LastReapTime;
+
+/*
+ * wait_for_something
+ *
+ * server suspends until
+ * - data from clients
+ * - new client connects
+ * - room to write data to clients
+ */
+
+int
+WaitForSomething(int *pClientsReady)
+{
+ struct timeval *wt,
+ waittime;
+ fd_set clientsReadable;
+ fd_set clientsWriteable;
+ long curclient;
+ int selecterr;
+ long current_time = 0;
+ long timeout;
+ int nready,
+ i;
+
+ while (1) {
+ /* handle the work Q */
+ if (workQueue)
+ ProcessWorkQueue();
+
+ if (XFD_ANYSET(&ClientsWithInput)) {
+ XFD_COPYSET(&ClientsWithInput, &clientsReadable);
+ break;
+ }
+ /*
+ * deal with KeepAlive timeouts. if this seems to costly, SIGALRM
+ * could be used, but its more dangerous since some it could catch us
+ * at an inopportune moment (like inside un-reentrant malloc()).
+ */
+ current_time = GetTimeInMillis();
+ timeout = current_time - LastReapTime;
+ if (timeout > ReapClientTime) {
+ ReapAnyOldClients();
+ LastReapTime = current_time;
+ timeout = ReapClientTime;
+ }
+ timeout = ReapClientTime - timeout;
+ waittime.tv_sec = timeout / MILLI_PER_SECOND;
+ waittime.tv_usec = (timeout % MILLI_PER_SECOND) *
+ (1000000 / MILLI_PER_SECOND);
+ wt = &waittime;
+
+ XFD_COPYSET(&AllSockets, &LastSelectMask);
+
+ BlockHandler(&wt, (pointer) &LastSelectMask);
+ if (NewOutputPending)
+ FlushAllOutput();
+
+ if (AnyClientsWriteBlocked) {
+ XFD_COPYSET(&ClientsWriteBlocked, &clientsWriteable);
+ i = Select(MAXSOCKS, &LastSelectMask, &clientsWriteable, NULL, wt);
+ } else {
+ i = Select(MAXSOCKS, &LastSelectMask, NULL, NULL, wt);
+ }
+ selecterr = errno;
+
+ WakeupHandler(i, (unsigned long *) &LastSelectMask);
+ if (i <= 0) { /* error or timeout */
+ FD_ZERO(&clientsWriteable);
+ if (i < 0) {
+ if (selecterr == EBADF) { /* somebody disconnected */
+ CheckConnections();
+ } else if (selecterr != EINTR) {
+ ErrorF("WaitForSomething: select(): errno %d\n", selecterr);
+ } else {
+ /*
+ * must have been broken by a signal. go deal with any
+ * exception flags
+ */
+ return 0;
+ }
+ } else { /* must have timed out */
+ ReapAnyOldClients();
+ LastReapTime = GetTimeInMillis();
+ }
+ } else {
+ if (AnyClientsWriteBlocked && XFD_ANYSET(&clientsWriteable)) {
+ NewOutputPending = TRUE;
+ XFD_ORSET(&OutputPending, &clientsWriteable, &OutputPending);
+ XFD_UNSET(&ClientsWriteBlocked, &clientsWriteable);
+ if (!XFD_ANYSET(&ClientsWriteBlocked))
+ AnyClientsWriteBlocked = FALSE;
+ }
+ XFD_ANDSET(&clientsReadable, &LastSelectMask, &AllClients);
+ if (LastSelectMask.fds_bits[0] & WellKnownConnections.fds_bits[0])
+ MakeNewConnections();
+ if (XFD_ANYSET(&clientsReadable))
+ break;
+
+ }
+ }
+ nready = 0;
+
+ if (XFD_ANYSET(&clientsReadable)) {
+ ClientPtr client;
+ int conn;
+
+ if (current_time) /* may not have been set */
+ current_time = GetTimeInMillis();
+ for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++) {
+ while (clientsReadable.fds_bits[i]) {
+ curclient = ffs(clientsReadable.fds_bits[i]) - 1;
+ conn = ConnectionTranslation[curclient + (i << 5)];
+ clientsReadable.fds_bits[i] &= ~(((fd_mask)1L) << curclient);
+ client = clients[conn];
+ if (!client)
+ continue;
+ pClientsReady[nready++] = conn;
+ client->last_request_time = current_time;
+ client->clientGone = CLIENT_ALIVE;
+ }
+ }
+ }
+ return nready;
+}
+
+#if 0
+/*
+ * This is not always a macro
+ */
+int
+ANYSET(long *src)
+{
+ int i;
+
+ for (i = 0; i < howmany(XFD_SETSIZE, NFDBITS); i++)
+ if (src[i])
+ return (1);
+ return (0);
+}
+
+#endif
diff --git a/app/xfs/os/xfstrans.c b/app/xfs/os/xfstrans.c
new file mode 100644
index 000000000..0ee846473
--- /dev/null
+++ b/app/xfs/os/xfstrans.c
@@ -0,0 +1,33 @@
+/*
+ * $Id: xfstrans.c,v 1.1 2006/11/26 14:43:47 matthieu Exp $
+ *
+ * Copyright © 2003 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, 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 Keith Packard not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Keith Packard makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL KEITH PACKARD 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define FONT_t
+#define TRANS_REOPEN
+#define TRANS_SERVER
+
+#include <X11/Xtrans/transport.c>