Mercurial > emacs
comparison lib-src/emacsclient.c @ 412:3cc2c5136064
Initial revision
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Mon, 02 Sep 1991 20:23:32 +0000 |
parents | |
children | 84799f3f3488 |
comparison
equal
deleted
inserted
replaced
411:cb75ab565260 | 412:3cc2c5136064 |
---|---|
1 /* Client process that communicates with GNU Emacs acting as server. | |
2 Copyright (C) 1986, 1987 Free Software Foundation, Inc. | |
3 | |
4 This file is part of GNU Emacs. | |
5 | |
6 GNU Emacs is free software; you can redistribute it and/or modify | |
7 it under the terms of the GNU General Public License as published by | |
8 the Free Software Foundation; either version 1, or (at your option) | |
9 any later version. | |
10 | |
11 GNU Emacs is distributed in the hope that it will be useful, | |
12 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 GNU General Public License for more details. | |
15 | |
16 You should have received a copy of the GNU General Public License | |
17 along with GNU Emacs; see the file COPYING. If not, write to | |
18 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ | |
19 | |
20 | |
21 #define NO_SHORTNAMES | |
22 #include "../src/config.h" | |
23 #undef read | |
24 #undef write | |
25 #undef open | |
26 #ifdef close | |
27 #undef close | |
28 #endif | |
29 | |
30 | |
31 #if !defined(HAVE_SOCKETS) && !defined(HAVE_SYSVIPC) | |
32 #include <stdio.h> | |
33 | |
34 main (argc, argv) | |
35 int argc; | |
36 char **argv; | |
37 { | |
38 fprintf (stderr, "%s: Sorry, the Emacs server is supported only\n", | |
39 argv[0]); | |
40 fprintf (stderr, "on systems with Berkeley sockets or System V IPC.\n"); | |
41 exit (1); | |
42 } | |
43 | |
44 #else /* HAVE_SOCKETS or HAVE_SYSVIPC */ | |
45 | |
46 #if ! defined (HAVE_SYSVIPC) | |
47 /* BSD code is very different from SYSV IPC code */ | |
48 | |
49 #include <sys/types.h> | |
50 #include <sys/socket.h> | |
51 #include <sys/un.h> | |
52 #include <stdio.h> | |
53 #include <errno.h> | |
54 | |
55 extern int sys_nerr; | |
56 extern char *sys_errlist[]; | |
57 extern int errno; | |
58 | |
59 main (argc, argv) | |
60 int argc; | |
61 char **argv; | |
62 { | |
63 char system_name[32]; | |
64 int s, i; | |
65 FILE *out; | |
66 struct sockaddr_un server; | |
67 char *homedir, *cwd, *str; | |
68 char string[BUFSIZ]; | |
69 | |
70 char *getenv (), *getwd (); | |
71 int geteuid (); | |
72 | |
73 if (argc < 2) | |
74 { | |
75 fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
76 exit (1); | |
77 } | |
78 | |
79 /* | |
80 * Open up an AF_UNIX socket in this person's home directory | |
81 */ | |
82 | |
83 if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) | |
84 { | |
85 fprintf (stderr, "%s: ", argv[0]); | |
86 perror ("socket"); | |
87 exit (1); | |
88 } | |
89 server.sun_family = AF_UNIX; | |
90 #ifndef SERVER_HOME_DIR | |
91 gethostname (system_name, sizeof (system_name)); | |
92 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name); | |
93 | |
94 if (stat (server.sun_path, &statbfr) == -1) | |
95 { | |
96 perror ("stat"); | |
97 exit (1); | |
98 } | |
99 if (statbfr.st_uid != geteuid()) | |
100 { | |
101 fprintf (stderr, "Illegal socket owner\n"); | |
102 exit (1); | |
103 } | |
104 #else | |
105 if ((homedir = getenv ("HOME")) == NULL) | |
106 { | |
107 fprintf (stderr, "%s: No home directory\n", argv[0]); | |
108 exit (1); | |
109 } | |
110 strcpy (server.sun_path, homedir); | |
111 strcat (server.sun_path, "/.emacs_server"); | |
112 #endif | |
113 | |
114 if (connect (s, &server, strlen (server.sun_path) + 2) < 0) | |
115 { | |
116 fprintf (stderr, "%s: ", argv[0]); | |
117 perror ("connect"); | |
118 exit (1); | |
119 } | |
120 if ((out = fdopen (s, "r+")) == NULL) | |
121 { | |
122 fprintf (stderr, "%s: ", argv[0]); | |
123 perror ("fdopen"); | |
124 exit (1); | |
125 } | |
126 | |
127 cwd = getwd (string); | |
128 if (cwd == 0) | |
129 { | |
130 /* getwd puts message in STRING if it fails. */ | |
131 fprintf (stderr, "%s: %s (%s)\n", argv[0], string, | |
132 (errno < sys_nerr) ? sys_errlist[errno] : "unknown error"); | |
133 exit (1); | |
134 } | |
135 | |
136 for (i = 1; i < argc; i++) | |
137 { | |
138 if (*argv[i] == '+') | |
139 { | |
140 char *p = argv[i] + 1; | |
141 while (*p >= '0' && *p <= '9') p++; | |
142 if (*p != 0) | |
143 fprintf (out, "%s/", cwd); | |
144 } | |
145 else if (*argv[i] != '/') | |
146 fprintf (out, "%s/", cwd); | |
147 fprintf (out, "%s ", argv[i]); | |
148 } | |
149 fprintf (out, "\n"); | |
150 fflush (out); | |
151 | |
152 printf ("Waiting for Emacs..."); | |
153 fflush (stdout); | |
154 | |
155 rewind (out); /* re-read the output */ | |
156 str = fgets (string, BUFSIZ, out); | |
157 | |
158 /* Now, wait for an answer and print any messages. */ | |
159 | |
160 while (str = fgets (string, BUFSIZ, out)) | |
161 printf ("%s", str); | |
162 | |
163 exit (0); | |
164 } | |
165 | |
166 #else /* This is the SYSV IPC section */ | |
167 | |
168 #include <sys/types.h> | |
169 #include <sys/ipc.h> | |
170 #include <sys/msg.h> | |
171 #include <stdio.h> | |
172 | |
173 main (argc, argv) | |
174 int argc; | |
175 char **argv; | |
176 { | |
177 int s; | |
178 key_t key; | |
179 struct msgbuf * msgp = | |
180 (struct msgbuf *) malloc (sizeof *msgp + BUFSIZ); | |
181 struct msqid_ds * msg_st; | |
182 char *homedir, buf[BUFSIZ]; | |
183 char gwdirb[BUFSIZ]; | |
184 char *cwd; | |
185 char *temp; | |
186 char *getwd (), *getcwd (), *getenv (); | |
187 | |
188 if (argc < 2) | |
189 { | |
190 fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
191 exit (1); | |
192 } | |
193 | |
194 /* | |
195 * Create a message queue using ~/.emacs_server as the path for ftok | |
196 */ | |
197 if ((homedir = getenv ("HOME")) == NULL) | |
198 { | |
199 fprintf (stderr, "%s: No home directory\n", argv[0]); | |
200 exit (1); | |
201 } | |
202 strcpy (buf, homedir); | |
203 strcat (buf, "/.emacs_server"); | |
204 creat (buf, 0600); | |
205 key = ftok (buf, 1); /* unlikely to be anyone else using it */ | |
206 s = msgget (key, 0600); | |
207 if (s == -1) | |
208 { | |
209 fprintf (stderr, "%s: ", argv[0]); | |
210 perror ("msgget"); | |
211 exit (1); | |
212 } | |
213 | |
214 /* Determine working dir, so we can prefix it to all the arguments. */ | |
215 #ifdef BSD | |
216 temp = getwd (gwdirb); | |
217 #else | |
218 temp = getcwd (gwdirb, sizeof gwdirb); | |
219 #endif | |
220 | |
221 cwd = gwdirb; | |
222 if (temp != 0) | |
223 { | |
224 /* On some systems, cwd can look like `@machine/...'; | |
225 ignore everything before the first slash in such a case. */ | |
226 while (*cwd && *cwd != '/') | |
227 cwd++; | |
228 strcat (cwd, "/"); | |
229 } | |
230 else | |
231 { | |
232 fprintf (stderr, cwd); | |
233 exit (1); | |
234 } | |
235 | |
236 msgp->mtext[0] = 0; | |
237 argc--; argv++; | |
238 while (argc) | |
239 { | |
240 if (*argv[0] == '+') | |
241 { | |
242 char *p = argv[0] + 1; | |
243 while (*p >= '0' && *p <= '9') p++; | |
244 if (*p != 0) | |
245 strcat (msgp->mtext, cwd); | |
246 } | |
247 else if (*argv[0] != '/') | |
248 strcat (msgp->mtext, cwd); | |
249 | |
250 strcat (msgp->mtext, argv[0]); | |
251 strcat (msgp->mtext, " "); | |
252 argv++; argc--; | |
253 } | |
254 strcat (msgp->mtext, "\n"); | |
255 msgp->mtype = 1; | |
256 if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0) | |
257 { | |
258 fprintf (stderr, "%s: ", argv[0]); | |
259 perror ("msgsnd"); | |
260 exit (1); | |
261 } | |
262 /* | |
263 * Now, wait for an answer | |
264 */ | |
265 printf ("Waiting for Emacs..."); | |
266 fflush (stdout); | |
267 | |
268 msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */ | |
269 strcpy (buf, msgp->mtext); | |
270 | |
271 printf ("\n%s\n", buf); | |
272 exit (0); | |
273 } | |
274 | |
275 #endif /* HAVE_SYSVIPC */ | |
276 | |
277 #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */ |