parsedpy.c revision 2852888e
1/*
2 *
3 * parse_displayname - utility routine for splitting up display name strings
4 *
5 *
6Copyright 1989, 1998  The Open Group
7
8Permission to use, copy, modify, distribute, and sell this software and its
9documentation for any purpose is hereby granted without fee, provided that
10the above copyright notice appear in all copies and that both that
11copyright notice and this permission notice appear in supporting
12documentation.
13
14The above copyright notice and this permission notice shall be included in
15all copies or substantial portions of the Software.
16
17THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
20OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24Except as contained in this notice, the name of The Open Group shall not be
25used in advertising or otherwise to promote the sale, use or other dealings
26in this Software without prior written authorization from The Open Group.
27 * *
28 * Author:  Jim Fulton, MIT X Consortium
29 */
30
31#ifdef HAVE_CONFIG_H
32#include "config.h"
33#endif
34
35#include <stdio.h>			/* for NULL */
36#include <ctype.h>			/* for isascii() and isdigit() */
37#include <X11/Xos.h>			/* for strchr() and string routines */
38#include <X11/Xlib.h>			/* for Family contants */
39#ifdef hpux
40#include <sys/utsname.h>		/* for struct utsname */
41#endif
42#include <X11/Xauth.h>			/* for FamilyLocal */
43#include <X11/Xmu/SysUtil.h>
44
45#if defined(UNIXCONN) || defined(LOCALCONN)
46#define UNIX_CONNECTION "unix"
47#define UNIX_CONNECTION_LENGTH 4
48#endif
49
50#include <stdlib.h>
51#include "xauth.h"
52
53/*
54 * private utility routines
55 */
56
57char *
58copystring (char *src, int len)
59{
60    char *cp;
61
62    if (!src && len != 0) return NULL;
63    cp = malloc (len + 1);
64    if (cp) {
65	if (src) strncpy (cp, src, len);
66	cp[len] = '\0';
67    }
68    return cp;
69}
70
71
72char *
73get_local_hostname (char *buf, int maxlen)
74{
75    buf[0] = '\0';
76    (void) XmuGetHostname (buf, maxlen);
77    return (buf[0] ? buf : NULL);
78}
79
80#ifndef UNIXCONN
81static char *
82copyhostname (void)
83{
84    char buf[256];
85
86    return (get_local_hostname (buf, sizeof buf) ?
87	    copystring (buf, strlen (buf)) : NULL);
88}
89#endif
90
91/*
92 * parse_displayname - display a display string up into its component parts
93 */
94Bool
95parse_displayname (char *displayname,
96		   int *familyp,	/* return */
97		   char **hostp,	/* return */
98		   int *dpynump,	/* return */
99		   int *scrnump,	/* return */
100		   char **restp)	/* return */
101{
102    char *ptr;				/* work variables */
103    int len;				/* work variable */
104    int family = -1;			/* value to be returned */
105    char *host = NULL;			/* must free if set and error return */
106    int dpynum = -1;			/* value to be returned */
107    int scrnum = 0;			/* value to be returned */
108    char *rest = NULL;			/* must free if set and error return */
109    Bool dnet = False;			/* if true then using DECnet */
110
111					/* check the name */
112    if (!displayname || !displayname[0]) return False;
113
114					/* must have at least :number */
115    ptr = strrchr(displayname, ':');
116    if (!ptr || !ptr[1]) return False;
117    if ((ptr != displayname) && (*(ptr - 1) == ':')) {
118	ptr--;
119	dnet = True;
120    }
121
122
123    /*
124     * get the host string; if none is given, use the most effiecient path
125     */
126
127    len = (ptr - displayname);	/* length of host name */
128    if (len == 0) {			/* choose most efficient path */
129#if defined(UNIXCONN) || defined(LOCALCONN)
130	host = copystring (UNIX_CONNECTION, UNIX_CONNECTION_LENGTH);
131	family = FamilyLocal;
132#else
133	if (dnet) {
134	    host = copystring ("0", 1);
135	    family = FamilyDECnet;
136	} else {
137	    host = copyhostname ();
138	    family = FamilyInternet;
139	}
140#endif
141    } else if (!dnet && (*displayname == '[') && (*(ptr - 1) == ']')) {
142	/* Allow RFC2732-like [<IPv6NumericAddress>]:display syntax */
143	family = FamilyInternet6;
144	host = copystring (displayname + 1, len - 2);
145    } else {
146	host = copystring (displayname, len);
147	if (dnet) {
148	    family = dnet;
149	} else {
150#if defined(UNIXCONN) || defined(LOCALCONN)
151	    if (host && strcmp (host, UNIX_CONNECTION) == 0)
152	      family = FamilyLocal;
153	    else
154#endif
155	      family = FamilyInternet;
156	}
157    }
158
159    if (!host) return False;
160
161    if(strncmp (host, "/tmp/launch", 11) == 0) {
162        family = FamilyLocal;
163    }
164
165    /*
166     * get the display number; we know that there is something after the
167     * colon (or colons) from above.  note that host is now set and must
168     * be freed if there is an error.
169     */
170
171    if (dnet) ptr++;			/* skip the extra DECnet colon */
172    ptr++;				/* move to start of display num */
173    {
174	register char *cp;
175
176	for (cp = ptr; *cp && isascii(*cp) && isdigit(*cp); cp++) ;
177	len = (cp - ptr);
178					/* check present and valid follow */
179	if (len == 0 || (*cp && *cp != '.')) {
180	    free (host);
181	    return False;
182	}
183
184	dpynum = atoi (ptr);		/* it will handle num. as well */
185	ptr = cp;
186    }
187
188    /*
189     * now get screen number if given; ptr may point to nul at this point
190     */
191    if (ptr[0] == '.') {
192	register char *cp;
193
194	ptr++;
195	for (cp = ptr; *cp && isascii(*cp) && isdigit(*cp); cp++) ;
196	len = (cp - ptr);
197	if (len == 0 || (*cp && *cp != '.')) {	/* all prop name */
198	    free (host);
199	    return False;
200	}
201
202	scrnum = atoi (ptr);		/* it will handle num. as well */
203	ptr = cp;
204    }
205
206    /*
207     * and finally, get any additional stuff that might be following the
208     * the screen number; ptr must point to a period if there is anything
209     */
210
211    if (ptr[0] == '.') {
212	ptr++;
213	len = strlen (ptr);
214	if (len > 0) {
215	    rest = copystring (ptr, len);
216	    if (!rest) {
217		free (host);
218		return False;
219	    }
220	}
221    }
222
223    /*
224     * and we are done!
225     */
226
227    *familyp = family;
228    *hostp = host;
229    *dpynump = dpynum;
230    *scrnump = scrnum;
231    *restp = rest;
232    return True;
233}
234
235
236