Mercurial > hg > xemacs-beta
annotate lib-src/gnuslib.c @ 5821:e34c3557e14e
Avoid commands defined in packages in some tests.
Packages may not be available at make check time.
| author | Stephen J. Turnbull <stephen@xemacs.org> |
|---|---|
| date | Sun, 19 Oct 2014 17:54:46 +0900 |
| parents | 3cc7470ea71c |
| children |
| rev | line source |
|---|---|
| 428 | 1 /* -*-C-*- |
| 613 | 2 Common library code for the XEmacs server and client. |
| 428 | 3 |
| 5420 | 4 |
|
5290
e6508b64ee08
More permission consistency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
3556
diff
changeset
|
5 |
| 613 | 6 This file is part of XEmacs. |
| 428 | 7 |
|
5406
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
8 XEmacs is free software: you can redistribute it and/or modify it |
|
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
9 under the terms of the GNU General Public License as published by the |
|
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
10 Free Software Foundation, either version 3 of the License, or (at your |
|
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
11 option) any later version. |
| 428 | 12 |
|
5406
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT |
|
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
16 for more details. |
|
5290
e6508b64ee08
More permission consistency.
Stephen J. Turnbull <stephen@xemacs.org>
parents:
3556
diff
changeset
|
17 |
|
5406
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
18 You should have received a copy of the GNU General Public License |
|
061f4f90f874
Convert lib-src/ to GPLv3.
Mike Sperber <sperber@deinprogramm.de>
parents:
3556
diff
changeset
|
19 along with XEmacs. If not, see <http://www.gnu.org/licenses/>. |
| 428 | 20 |
| 21 Copyright (C) 1989 Free Software Foundation, Inc. | |
| 22 | |
| 23 Author: Andy Norman (ange@hplb.hpl.hp.com), based on | |
| 24 'etc/server.c' and 'etc/emacsclient.c' from the 18.52 GNU | |
| 25 Emacs distribution. | |
| 26 | |
| 27 Please mail bugs and suggestions to the author at the above address. | |
| 28 */ | |
| 29 | |
| 30 /* HISTORY | |
| 31 * 11-Nov-1990 bristor@simba | |
| 32 * Added EOT stuff. | |
| 33 */ | |
| 34 | |
| 35 /* | |
| 36 * This file incorporates new features added by Bob Weiner <weiner@mot.com>, | |
| 37 * Darrell Kindred <dkindred@cmu.edu> and Arup Mukherjee <arup@cmu.edu>. | |
| 38 * Please see the note at the end of the README file for details. | |
| 39 * | |
| 40 * (If gnuserv came bundled with your emacs, the README file is probably | |
| 41 * ../etc/gnuserv.README relative to the directory containing this file) | |
| 42 */ | |
| 43 | |
| 44 #if 0 | |
| 45 static char rcsid [] = "!Header: gnuslib.c,v 2.4 95/02/16 11:57:37 arup alpha !"; | |
| 46 #endif | |
| 47 | |
| 48 #include "gnuserv.h" | |
| 49 #include <errno.h> | |
| 50 | |
| 51 #ifdef SYSV_IPC | |
| 52 static int connect_to_ipc_server (void); | |
| 53 #endif | |
| 54 #ifdef UNIX_DOMAIN_SOCKETS | |
| 55 static int connect_to_unix_server (void); | |
| 56 #endif | |
| 57 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 458 | 58 static int connect_to_internet_server (char *serverhost, unsigned short port); |
| 428 | 59 #endif |
| 60 | |
| 61 /* On some systems, e.g. DGUX, inet_addr returns a 'struct in_addr'. */ | |
| 62 #ifdef HAVE_BROKEN_INET_ADDR | |
| 63 # define IN_ADDR struct in_addr | |
| 64 # define NUMERIC_ADDR_ERROR (numeric_addr.s_addr == -1) | |
| 65 #else | |
| 66 # if (LONGBITS > 32) | |
| 67 # define IN_ADDR unsigned int | |
| 68 # else | |
| 69 # define IN_ADDR unsigned long | |
| 70 # endif | |
| 71 # define NUMERIC_ADDR_ERROR (numeric_addr == (IN_ADDR) -1) | |
| 72 #endif | |
| 73 | |
| 74 #include <stdlib.h> | |
| 75 #include <stdio.h> | |
| 76 #include <sys/types.h> | |
| 77 #include <sys/stat.h> | |
| 78 #ifdef HAVE_UNISTD_H | |
| 79 #include <unistd.h> | |
| 80 #endif /* HAVE_UNISTD_H */ | |
| 81 #ifdef HAVE_STRING_H | |
| 82 #include <string.h> | |
| 83 #endif /* HAVE_STRING_H */ | |
| 84 | |
| 85 #include <arpa/inet.h> | |
| 86 | |
| 87 char *tmpdir = NULL; | |
| 88 | |
| 89 char *progname = NULL; | |
| 90 | |
| 440 | 91 int |
| 92 make_connection (char *hostarg, int portarg, int *s) | |
| 428 | 93 { |
| 94 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 95 char *ptr; | |
| 96 if (hostarg == NULL) | |
| 97 hostarg = getenv("GNU_HOST"); | |
| 98 if (portarg == 0 && (ptr=getenv("GNU_PORT")) != NULL) | |
| 99 portarg = atoi(ptr); | |
| 100 #endif | |
| 101 | |
| 102 if (hostarg != NULL) { | |
| 103 /* hostname was given explicitly, via cmd line arg or GNU_HOST, | |
| 104 * so obey it. */ | |
| 105 #ifdef UNIX_DOMAIN_SOCKETS | |
| 106 if (!strcmp(hostarg, "unix")) { | |
| 107 *s = connect_to_unix_server(); | |
| 108 return (int) CONN_UNIX; | |
| 109 } | |
| 110 #endif /* UNIX_DOMAIN_SOCKETS */ | |
| 111 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 112 *s = connect_to_internet_server(hostarg, portarg); | |
| 113 return (int) CONN_INTERNET; | |
| 114 #endif | |
| 115 #ifdef SYSV_IPC | |
| 116 return -1; /* hostarg should always be NULL for SYSV_IPC */ | |
| 117 #endif | |
| 118 } else { | |
| 119 /* no hostname given. Use unix-domain/sysv-ipc, or | |
| 120 * internet-domain connection to local host if they're not available. */ | |
| 121 #if defined(UNIX_DOMAIN_SOCKETS) | |
| 122 *s = connect_to_unix_server(); | |
| 123 return (int) CONN_UNIX; | |
| 124 #elif defined(SYSV_IPC) | |
| 125 *s = connect_to_ipc_server(); | |
| 126 return (int) CONN_IPC; | |
| 127 #elif defined(INTERNET_DOMAIN_SOCKETS) | |
| 128 { | |
| 129 char localhost[HOSTNAMSZ]; | |
| 130 gethostname(localhost,HOSTNAMSZ); /* use this host by default */ | |
| 131 *s = connect_to_internet_server(localhost, portarg); | |
| 132 return (int) CONN_INTERNET; | |
| 133 } | |
| 134 #endif /* IPC type */ | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 #ifdef SYSV_IPC | |
| 139 /* | |
| 140 connect_to_ipc_server -- establish connection with server process via SYSV IPC | |
| 141 Returns msqid for server if successful. | |
| 142 */ | |
| 440 | 143 static int |
| 144 connect_to_ipc_server (void) | |
| 428 | 145 { |
| 146 int s; /* connected msqid */ | |
| 147 key_t key; /* message key */ | |
| 148 char buf[GSERV_BUFSZ+1]; /* buffer for filename */ | |
| 149 | |
| 150 sprintf(buf,"%s/gsrv%d",tmpdir,(int)geteuid()); | |
| 151 creat(buf,0600); | |
| 152 if ((key = ftok(buf,1)) == -1) { | |
| 153 perror(progname); | |
| 154 fprintf(stderr, "%s: unable to get ipc key from %s\n", | |
| 155 progname, buf); | |
| 156 exit(1); | |
| 157 } | |
| 158 | |
| 159 if ((s = msgget(key,0600)) == -1) { | |
| 160 perror(progname); | |
| 161 fprintf(stderr,"%s: unable to access msg queue\n",progname); | |
| 162 exit(1); | |
| 163 }; /* if */ | |
| 164 | |
| 165 return(s); | |
| 166 | |
| 167 } /* connect_to_ipc_server */ | |
| 168 | |
| 169 | |
| 170 /* | |
| 171 disconnect_from_ipc_server -- inform the server that sending has finished, | |
| 172 and wait for its reply. | |
| 173 */ | |
| 440 | 174 void |
| 175 disconnect_from_ipc_server (int s, struct msgbuf *msgp, int echo) | |
| 428 | 176 { |
| 177 int len; /* length of received message */ | |
| 178 | |
| 179 send_string(s,EOT_STR); /* EOT terminates this message */ | |
| 180 msgp->mtype = 1; | |
| 181 | |
| 182 if(msgsnd(s,msgp,strlen(msgp->mtext)+1,0) < 0) { | |
| 183 perror(progname); | |
| 184 fprintf(stderr,"%s: unable to send message to server\n",progname); | |
| 185 exit(1); | |
| 186 }; /* if */ | |
| 187 | |
| 188 if((len = msgrcv(s,msgp,GSERV_BUFSZ,getpid(),0)) < 0) { | |
| 189 perror(progname); | |
| 190 fprintf(stderr,"%s: unable to receive message from server\n",progname); | |
| 191 exit(1); | |
| 192 }; /* if */ | |
| 193 | |
| 194 if (echo) { | |
| 195 msgp->mtext[len] = '\0'; /* string terminate message */ | |
| 196 fputs(msgp->mtext, stdout); | |
| 197 if (msgp->mtext[len-1] != '\n') putchar ('\n'); | |
| 198 }; /* if */ | |
| 199 | |
| 200 } /* disconnect_from_ipc_server */ | |
| 201 #endif /* SYSV_IPC */ | |
| 202 | |
| 203 | |
| 204 #if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS) | |
| 205 /* | |
| 206 send_string -- send string to socket. | |
| 207 */ | |
| 440 | 208 void |
| 442 | 209 send_string (int s, const char *msg) |
| 428 | 210 { |
| 211 #if 0 | |
| 212 if (send(s,msg,strlen(msg),0) < 0) { | |
| 213 perror(progname); | |
| 214 fprintf(stderr,"%s: unable to send\n",progname); | |
| 215 exit(1); | |
| 216 }; /* if */ | |
| 217 #else | |
| 218 int len, left=strlen(msg); | |
| 219 while (left > 0) { | |
| 220 if ((len=write(s,msg,min2(left,GSERV_BUFSZ))) < 0) { | |
| 221 /* XEmacs addition: robertl@arnet.com */ | |
| 222 if (errno == EPIPE) { | |
| 223 return ; | |
| 224 } | |
| 225 perror(progname); | |
| 226 fprintf(stderr,"%s: unable to send\n",progname); | |
| 227 exit(1); | |
| 228 }; /* if */ | |
| 229 left -= len; | |
| 230 msg += len; | |
| 231 }; /* while */ | |
| 232 #endif | |
| 233 } /* send_string */ | |
| 234 | |
| 235 /* | |
| 236 read_line -- read a \n terminated line from a socket | |
| 237 */ | |
| 440 | 238 int |
| 239 read_line (int s, char *dest) | |
| 428 | 240 { |
| 241 int length; | |
| 242 int offset=0; | |
| 243 char buffer[GSERV_BUFSZ+1]; | |
| 244 | |
| 245 while ((length=read(s,buffer+offset,1)>0) && buffer[offset]!='\n' | |
| 246 && buffer[offset] != EOT_CHR) { | |
| 247 offset += length; | |
| 248 if (offset >= GSERV_BUFSZ) | |
| 249 break; | |
| 250 } | |
| 251 buffer[offset] = '\0'; | |
| 252 strcpy(dest,buffer); | |
| 253 return 1; | |
| 254 } /* read_line */ | |
| 255 #endif /* INTERNET_DOMAIN_SOCKETS || UNIX_DOMAIN_SOCKETS */ | |
| 256 | |
| 257 | |
| 258 #ifdef UNIX_DOMAIN_SOCKETS | |
| 259 /* | |
| 260 connect_to_unix_server -- establish connection with server process via a unix- | |
| 261 domain socket. Returns socket descriptor for server | |
| 262 if successful. | |
| 263 */ | |
| 440 | 264 static int |
| 265 connect_to_unix_server (void) | |
| 428 | 266 { |
| 267 int s; /* connected socket descriptor */ | |
| 268 struct sockaddr_un server; /* for unix connections */ | |
|
5518
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
269 char *ctus_tmpdir = tmpdir; |
| 428 | 270 |
|
5518
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
271 do |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
272 { |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
273 if ((s = socket(AF_UNIX,SOCK_STREAM,0)) < 0) { |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
274 perror(progname); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
275 fprintf(stderr,"%s: unable to create socket\n",progname); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
276 exit(1); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
277 }; /* if */ |
| 428 | 278 |
|
5518
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
279 server.sun_family = AF_UNIX; |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
280 |
| 428 | 281 #ifdef HIDE_UNIX_SOCKET |
|
5518
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
282 sprintf(server.sun_path,"%s/gsrvdir%d/gsrv", ctus_tmpdir, |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
283 (int)geteuid()); |
| 428 | 284 #else /* HIDE_UNIX_SOCKET */ |
|
5518
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
285 sprintf(server.sun_path,"%s/gsrv%d", ctus_tmpdir, |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
286 (int)geteuid()); |
| 428 | 287 #endif /* HIDE_UNIX_SOCKET */ |
|
5518
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
288 if (connect(s,(struct sockaddr *)&server,strlen(server.sun_path)+2) < 0) { |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
289 #ifndef WIN32_NATIVE |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
290 #ifdef USE_TMPDIR |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
291 if (0 != strcmp (ctus_tmpdir, "/tmp")) |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
292 { |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
293 /* Try again; the server may have no environment value for |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
294 TMPDIR, or it may have been compiled without USE_TMPDIR, and |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
295 in both those cases it's useful to retry with /tmp. |
| 428 | 296 |
|
5518
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
297 In the case where the server was compiled with USE_TMPDIR and |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
298 it has a value for TMPDIR distinct from ours, we have no way of |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
299 working out what that value is, so it's appropriate to give |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
300 up. */ |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
301 close (s); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
302 ctus_tmpdir = "/tmp"; |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
303 continue; |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
304 } |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
305 #endif /* USE_TMPDIR */ |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
306 #endif /* !WIN32_NATIVE */ |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
307 perror(progname); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
308 fprintf(stderr,"%s: %s: unable to connect to local\n", progname, |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
309 server.sun_path); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
310 exit(1); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
311 }; /* if */ |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
312 |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
313 return(s); |
|
3cc7470ea71c
gnuclient: if TMPDIR was set and connect failed, try again with /tmp
Aidan Kehoe <kehoea@parhasard.net>
parents:
5420
diff
changeset
|
314 } while (1); |
| 428 | 315 |
| 316 } /* connect_to_unix_server */ | |
| 317 #endif /* UNIX_DOMAIN_SOCKETS */ | |
| 318 | |
| 319 | |
| 320 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 321 /* | |
| 322 internet_addr -- return the internet addr of the hostname or | |
| 323 internet address passed. Return -1 on error. | |
| 324 */ | |
| 440 | 325 int |
| 326 internet_addr (char *host) | |
| 428 | 327 { |
| 328 struct hostent *hp; /* pointer to host info for remote host */ | |
| 329 IN_ADDR numeric_addr; /* host address */ | |
| 330 | |
| 331 numeric_addr = inet_addr(host); | |
| 332 if (!NUMERIC_ADDR_ERROR) | |
| 333 return numeric_addr; | |
| 334 else if ((hp = gethostbyname(host)) != NULL) | |
| 335 return ((struct in_addr *)(hp->h_addr))->s_addr; | |
| 336 else | |
| 337 return -1; | |
| 338 | |
| 339 } /* internet_addr */ | |
| 340 | |
| 341 #ifdef AUTH_MAGIC_COOKIE | |
| 342 # include <X11/X.h> | |
| 343 # include <X11/Xauth.h> | |
| 344 | |
| 345 static Xauth *server_xauth = NULL; | |
| 346 #endif | |
| 347 | |
| 348 /* | |
| 349 connect_to_internet_server -- establish connection with server process via | |
| 350 an internet domain socket. Returns socket | |
| 351 descriptor for server if successful. | |
| 352 */ | |
| 440 | 353 static int |
| 458 | 354 connect_to_internet_server (char *serverhost, unsigned short port) |
| 428 | 355 { |
| 356 int s; /* connected socket descriptor */ | |
| 357 struct servent *sp; /* pointer to service information */ | |
| 358 struct sockaddr_in peeraddr_in; /* for peer socket address */ | |
| 359 char buf[512]; /* temporary buffer */ | |
| 360 | |
| 361 /* clear out address structures */ | |
| 362 memset((char *)&peeraddr_in,0,sizeof(struct sockaddr_in)); | |
| 363 | |
| 364 /* Set up the peer address to which we will connect. */ | |
| 365 peeraddr_in.sin_family = AF_INET; | |
| 366 | |
| 367 /* look up the server host's internet address */ | |
| 647 | 368 if ((peeraddr_in.sin_addr.s_addr = internet_addr (serverhost)) == |
| 369 (unsigned int) -1) | |
| 370 { | |
| 371 fprintf (stderr, "%s: unable to find %s in /etc/hosts or from YP\n", | |
| 372 progname, serverhost); | |
| 373 exit(1); | |
| 374 } | |
| 428 | 375 |
| 376 if (port == 0) { | |
| 377 if ((sp = getservbyname ("gnuserv","tcp")) == NULL) | |
| 378 peeraddr_in.sin_port = htons(DEFAULT_PORT+getuid()); | |
| 379 else | |
| 380 peeraddr_in.sin_port = sp->s_port; | |
| 381 } /* if */ | |
| 382 else | |
| 383 peeraddr_in.sin_port = htons(port); | |
| 384 | |
| 385 /* Create the socket. */ | |
| 386 if ((s = socket (AF_INET,SOCK_STREAM, 0))== -1) { | |
| 387 perror(progname); | |
| 388 fprintf(stderr,"%s: unable to create socket\n",progname); | |
| 389 exit(1); | |
| 390 }; /* if */ | |
| 391 | |
| 392 /* Try to connect to the remote server at the address | |
| 393 * which was just built into peeraddr. | |
| 394 */ | |
| 395 if (connect(s, (struct sockaddr *)&peeraddr_in, | |
| 396 sizeof(struct sockaddr_in)) == -1) { | |
| 397 perror(progname); | |
| 398 fprintf(stderr, "%s: unable to connect to remote\n",progname); | |
| 399 exit(1); | |
| 400 }; /* if */ | |
| 401 | |
| 402 #ifdef AUTH_MAGIC_COOKIE | |
| 403 | |
| 404 /* send credentials using MIT-MAGIC-COOKIE-1 protocol */ | |
| 405 | |
| 406 server_xauth = | |
| 407 XauGetAuthByAddr(FamilyInternet, | |
| 408 sizeof(peeraddr_in.sin_addr.s_addr), | |
| 409 (char *) &peeraddr_in.sin_addr.s_addr, | |
| 410 strlen(MCOOKIE_SCREEN), MCOOKIE_SCREEN, | |
| 411 strlen(MCOOKIE_X_NAME), MCOOKIE_X_NAME); | |
| 412 | |
| 413 if (server_xauth && server_xauth->data) { | |
| 414 sprintf(buf, "%s\n%d\n", MCOOKIE_NAME, server_xauth->data_length); | |
| 415 write (s, buf, strlen(buf)); | |
| 416 write (s, server_xauth->data, server_xauth->data_length); | |
| 417 | |
| 418 return (s); | |
| 419 } | |
| 420 | |
| 421 #endif /* AUTH_MAGIC_COOKIE */ | |
| 422 | |
| 423 sprintf (buf, "%s\n", DEFAUTH_NAME); | |
| 424 write (s, buf, strlen(buf)); | |
| 425 | |
| 426 return(s); | |
| 427 | |
| 428 } /* connect_to_internet_server */ | |
| 429 #endif /* INTERNET_DOMAIN_SOCKETS */ | |
| 430 | |
| 431 | |
| 432 #if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS) | |
| 433 /* | |
| 434 disconnect_from_server -- inform the server that sending has finished, and wait for | |
| 435 its reply. | |
| 436 */ | |
| 440 | 437 void |
| 438 disconnect_from_server (int s, int echo) | |
| 428 | 439 { |
| 440 #if 0 | |
| 441 char buffer[REPLYSIZ+1]; | |
| 442 #else | |
| 443 char buffer[GSERV_BUFSZ+1]; | |
| 444 #endif | |
| 445 int add_newline = 1; | |
| 446 int length; | |
| 447 | |
| 448 send_string(s,EOT_STR); /* make sure server gets string */ | |
| 449 | |
| 3556 | 450 #ifndef _SCO_DS |
| 428 | 451 /* |
| 3556 | 452 * There used to be a comment here complaining about ancient Linux |
| 453 * versions. It is no longer relevant. I don't know why _SCO_DS is | |
| 454 * verboten here, as the original comment did not say. | |
| 428 | 455 */ |
| 456 | |
| 457 if (shutdown(s,1) == -1) { | |
| 458 perror(progname); | |
| 459 fprintf(stderr, "%s: unable to shutdown socket\n",progname); | |
| 460 exit(1); | |
| 461 }; /* if */ | |
| 462 #endif | |
| 463 | |
| 464 #if 0 | |
| 465 while((length = recv(s,buffer,REPLYSIZ,0)) > 0) { | |
| 466 buffer[length] = '\0'; | |
| 467 if (echo) fputs(buffer,stdout); | |
| 468 add_newline = (buffer[length-1] != '\n'); | |
| 469 }; /* while */ | |
| 470 #else | |
| 471 while ((length = read(s,buffer,GSERV_BUFSZ)) > 0 || | |
| 472 (length == -1 && errno == EINTR)) { | |
| 3556 | 473 if (length > 0) { |
| 428 | 474 buffer[length] = '\0'; |
| 475 if (echo) { | |
| 476 fputs(buffer,stdout); | |
| 477 add_newline = (buffer[length-1] != '\n'); | |
| 478 }; /* if */ | |
| 479 }; /* if */ | |
| 480 }; /* while */ | |
| 481 #endif | |
| 482 | |
| 483 if (echo && add_newline) putchar('\n'); | |
| 484 | |
| 485 if(length < 0) { | |
| 486 perror(progname); | |
| 487 fprintf(stderr,"%s: unable to read the reply from the server\n",progname); | |
| 488 exit(1); | |
| 489 }; /* if */ | |
| 490 | |
| 491 } /* disconnect_from_server */ | |
| 492 #endif /* INTERNET_DOMAIN_SOCKETS || UNIX_DOMAIN_SOCKETS */ |
