osglue.c revision ce6676db
1/*
2Copyright 1987, 1998  The Open Group
3
4Permission to use, copy, modify, distribute, and sell this software and its
5documentation for any purpose is hereby granted without fee, provided that
6the above copyright notice appear in all copies and that both that
7copyright notice and this permission notice appear in supporting
8documentation.
9
10The above copyright notice and this permission notice shall be included in
11all copies or substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
16OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
17AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19
20Except as contained in this notice, the name of The Open Group shall not be
21used in advertising or otherwise to promote the sale, use or other dealings
22in this Software without prior written authorization from The Open Group.
23 * Copyright 1990, 1991 Network Computing Devices;
24 * Portions Copyright 1987 by Digital Equipment Corporation
25 *
26 * Permission to use, copy, modify, distribute, and sell this software and its
27 * documentation for any purpose is hereby granted without fee, provided that
28 * the above copyright notice appear in all copies and that both that
29 * copyright notice and this permission notice appear in supporting
30 * documentation, and that the names of Network Computing Devices,
31 * or Digital not be used in advertising or
32 * publicity pertaining to distribution of the software without specific,
33 * written prior permission.  Network Computing Devices, or Digital
34 * make no representations about the
35 * suitability of this software for any purpose.  It is provided "as is"
36 * without express or implied warranty.
37 *
38 * NETWORK COMPUTING DEVICES, AND DIGITAL DISCLAIM ALL WARRANTIES WITH
39 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
40 * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES, OR DIGITAL BE
41 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
42 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
43 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
44 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
45 *
46 */
47
48/*
49 * this is miscellaneous OS specific stuff.
50 *
51 * Catalogue support, alternate servers, and cloneing
52 */
53
54#include "xfs-config.h"
55
56#include <X11/Xtrans/Xtrans.h>
57#include "osstruct.h"
58#include <stdio.h>
59#include <stdlib.h>
60#define  XK_LATIN1
61#include <X11/keysymdef.h>
62#ifdef __UNIXOS2__
63#define _NFILE 256
64#endif
65#include "globals.h"
66#include "osdep.h"
67
68Bool        drone_server = FALSE;
69
70static int  num_alts;
71static AlternateServerPtr alt_servers = (AlternateServerPtr) 0;
72
73/*
74 * XXX
75 *
76 * Catalogue support is absolutely minimal.  Some guts are here, but
77 * we don't actually do anything with them so the only one exported is
78 * 'all'.  Be warned that other parts of the server may incorrectly
79 * assume the catalogue list is global, and will therefore need fixing.
80 *
81 */
82
83static char *catalogue_name = "all";
84
85static Bool			/* stolen from R4 Match() */
86pattern_match(char *pat, int plen, char *string)
87{
88    register int i,
89                l;
90    int         j,
91                m,
92                res;
93    register char cp,
94                cs;
95    int         head,
96                tail;
97
98    head = 0;
99    tail = plen;
100
101    res = -1;
102    for (i = 0; i < head; i++) {
103	cp = pat[i];
104	if (cp == XK_question) {
105	    if (!string[i])
106		return res;
107	    res = 0;
108	} else if (cp != string[i])
109	    return res;
110    }
111    if (head == plen)
112	return (string[head] ? res : 1);
113    l = head;
114    while (++i < tail) {
115	/* we just skipped an asterisk */
116	j = i;
117	m = l;
118	while ((cp = pat[i]) != XK_asterisk) {
119	    if (!(cs = string[l]))
120		return 0;
121	    if ((cp != cs) && (cp != XK_question)) {
122		m++;
123		cp = pat[j];
124		if (cp == XK_asterisk) {
125		    if (!string[m])
126			return 0;
127		} else {
128		    while ((cs = string[m]) != cp) {
129			if (!cs)
130			    return 0;
131			m++;
132		    }
133		}
134		l = m;
135		i = j;
136	    }
137	    l++;
138	    i++;
139	}
140    }
141    m = strlen(&string[l]);
142    j = plen - tail;
143    if (m < j)
144	return 0;
145    l = (l + m) - j;
146    while ((cp = pat[i])) {
147	if ((cp != string[l]) && (cp != XK_question))
148	    return 0;
149	l++;
150	i++;
151    }
152    return 1;
153}
154
155int
156ListCatalogues(char *pattern, int patlen, int maxnames,
157	       char **catalogues, int *len)
158{
159    int         count = 0;
160    char       *catlist = NULL;
161    int         size = 0;
162
163    if (maxnames) {
164	if (pattern_match(pattern, patlen, catalogue_name)) {
165	    size = strlen(catalogue_name);
166	    catlist = (char *) fsalloc(size + 1);
167	    if (!catlist)
168		goto bail;
169	    *catlist = size;
170	    memmove( &catlist[1], catalogue_name, size);
171	    size++;		/* for length */
172	    count++;
173	}
174    }
175bail:
176    *len = size;
177    *catalogues = catlist;
178    return count;
179}
180
181/*
182 * check if catalogue list is valid
183 */
184
185int
186ValidateCatalogues(int *num, char *cats)
187{
188    char       *c = cats;
189    int         i,
190                len;
191
192    for (i = 0; i < *num; i++) {
193	len = *c++;
194	if (strncmp(c, catalogue_name, len)) {
195	    *num = i;		/* return bad entry index */
196	    return FSBadName;
197	}
198	c += len;
199    }
200    return FSSuccess;
201}
202
203int
204SetAlternateServers(char *list)
205{
206    char       *t,
207               *st;
208    AlternateServerPtr alts,
209                a;
210    int         num,
211                i;
212
213    t = list;
214    num = 1;
215    while (*t) {
216	if (*t == ',')
217	    num++;
218	t++;
219    }
220
221    a = alts = (AlternateServerPtr) fsalloc(sizeof(AlternateServerRec) * num);
222    if (!alts)
223	return FSBadAlloc;
224
225    st = t = list;
226    a->namelen = 0;
227    while (*t) {
228	if (*t == ',') {
229	    a->name = (char *) fsalloc(a->namelen);
230	    if (!a->name) {
231		/* XXX  -- leak */
232		return FSBadAlloc;
233	    }
234	    memmove( a->name, st, a->namelen);
235	    a->subset = FALSE;	/* XXX */
236	    a++;
237	    t++;
238	    st = t;
239	    a->namelen = 0;
240	} else {
241	    a->namelen++;
242	    t++;
243	}
244    }
245    a->name = (char *) fsalloc(a->namelen);
246    if (!a->name) {
247	/* XXX  -- leak */
248	return FSBadAlloc;
249    }
250    memmove( a->name, st, a->namelen);
251    a->subset = FALSE;		/* XXX */
252
253    for (i = 0; i < num_alts; i++) {
254	fsfree((char *) alt_servers[i].name);
255    }
256    fsfree((char *) alt_servers);
257    num_alts = num;
258    alt_servers = alts;
259    return FSSuccess;
260}
261
262int
263ListAlternateServers(AlternateServerPtr *svrs)
264{
265    *svrs = alt_servers;
266    return num_alts;
267}
268
269/*
270 * here's some fun stuff.  in order to cleanly handle becoming overloaded,
271 * this allows us to clone ourselves.  the parent keeps the Listen
272 * socket open, and sends it to itself.  the child stops listening,
273 * and becomes a drone, hanging out till it loses all its clients.
274 */
275
276int
277CloneMyself(void)
278{
279    int         child;
280    char        old_listen_arg[256];
281    char	*arg_ptr = old_listen_arg;
282    int         i, j;
283    int         lastfdesc;
284    char	portnum[20];
285
286    assert(!drone_server);	/* a drone shouldn't hit this */
287
288    if (!CloneSelf)
289	return -1;
290
291#ifdef __UNIXOS2__
292    NoticeF("cloning of font server not supported under OS/2!\n");
293    return(-1);
294#endif
295
296    old_listen_arg[0] = '\0';
297
298    lastfdesc = sysconf(_SC_OPEN_MAX) - 1;
299    if ( (lastfdesc < 0) || (lastfdesc > MAXSOCKS)) {
300	lastfdesc = MAXSOCKS;
301    }
302
303    NoticeF("attempting clone...\n");
304    chdir("/");
305    child = fork();
306    if (child == -1) {
307	/* failed to fork */
308	ErrorF("clone failed to fork()\n");
309	return -1;
310    }
311    /*
312     * Note:  they still share the same process group, and killing the parent
313     * will take out all the kids as well.  this is considered a feature (at
314     * least until i'm convinced otherwise)
315     */
316    if (child == 0) {
317	StopListening();
318	NoticeF("clone: child becoming drone\n");
319	drone_server = TRUE;
320	return 1;
321    } else {			/* parent */
322	NoticeF("clone: parent revitalizing as %s\n", progname);
323	CloseErrors();
324	/* XXX should we close stdio as well? */
325	for (i = 3; i < lastfdesc; i++)
326	{
327	    for (j = 0; j < ListenTransCount; j++)
328		if (ListenTransFds[j] == i)
329		    break;
330
331	    if (j >= ListenTransCount)
332		(void) close(i);
333	}
334
335	for (i = 0; i < ListenTransCount; i++)
336	{
337	    int trans_id, fd;
338	    char *port;
339
340	    if (!_FontTransGetReopenInfo (ListenTransConns[i],
341		&trans_id, &fd, &port))
342		continue;
343
344	    sprintf (arg_ptr, "%d/%d/%s", trans_id, fd, port);
345	    arg_ptr += strlen (arg_ptr);
346	    free (port);
347
348	    if (i < ListenTransCount - 1)
349	    {
350		strcat (arg_ptr, ",");
351		arg_ptr++;
352	    }
353	}
354
355	sprintf (portnum, "%d", ListenPort);
356	if (*old_listen_arg != '\0')
357	    execlp(progname, progname,
358		   "-ls", old_listen_arg,
359		   "-cf", configfilename,
360		   "-port", portnum,
361		   (void *)NULL);
362
363	InitErrors();		/* reopen errors, since we don't want to lose
364				 * this */
365	Error("clone failed");
366	FatalError("failed to clone self\n");
367    }
368    /* NOTREACHED */
369    return 0;
370}
371