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