Mercurial > hg > xemacs-beta
annotate lib-src/gnuslib.c @ 5574:d4f334808463
Support inlining labels, bytecomp.el.
lisp/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea@parhasard.net>
* bytecomp.el (byte-compile-initial-macro-environment):
Add #'declare to this, so it doesn't need to rely on
#'cl-compiling file to determine when we're byte-compiling.
Update #'labels to support declaring labels inline, as Common Lisp
requires.
* bytecomp.el (byte-compile-function-form):
Don't error if FUNCTION is quoting a non-lambda, non-symbol, just
return it.
* cl-extra.el (cl-macroexpand-all):
If a label name has been quoted, expand to the label placeholder
quoted with 'function. This allows the byte compiler to
distinguish between uses of the placeholder as data and uses in
contexts where it should be inlined.
* cl-macs.el:
* cl-macs.el (cl-do-proclaim):
When proclaming something as inline, if it is bound as a label,
don't modify the symbol's plist; instead, treat the first element
of its placeholder constant vector as a place to store compile
information.
* cl-macs.el (declare):
Leave processing declarations while compiling to the
implementation of #'declare in
byte-compile-initial-macro-environment.
tests/ChangeLog addition:
2011-10-02 Aidan Kehoe <kehoea@parhasard.net>
* automated/lisp-tests.el:
* automated/lisp-tests.el (+):
Test #'labels and inlining.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 02 Oct 2011 15:32:16 +0100 |
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 */ |