Commit | Line | Data |
---|---|---|
efb859b4 | 1 | /* Client process that communicates with GNU Emacs acting as server. |
46cec291 RS |
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> | |
efb859b4 | 52 | #include <sys/stat.h> |
46cec291 RS |
53 | #include <stdio.h> |
54 | #include <errno.h> | |
55 | ||
56 | extern int sys_nerr; | |
57 | extern char *sys_errlist[]; | |
58 | extern int errno; | |
59 | ||
60 | main (argc, argv) | |
61 | int argc; | |
62 | char **argv; | |
63 | { | |
64 | char system_name[32]; | |
65 | int s, i; | |
66 | FILE *out; | |
67 | struct sockaddr_un server; | |
68 | char *homedir, *cwd, *str; | |
69 | char string[BUFSIZ]; | |
70 | ||
71 | char *getenv (), *getwd (); | |
72 | int geteuid (); | |
73 | ||
74 | if (argc < 2) | |
75 | { | |
76 | fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
77 | exit (1); | |
78 | } | |
79 | ||
80 | /* | |
81 | * Open up an AF_UNIX socket in this person's home directory | |
82 | */ | |
83 | ||
84 | if ((s = socket (AF_UNIX, SOCK_STREAM, 0)) < 0) | |
85 | { | |
86 | fprintf (stderr, "%s: ", argv[0]); | |
87 | perror ("socket"); | |
88 | exit (1); | |
89 | } | |
90 | server.sun_family = AF_UNIX; | |
91 | #ifndef SERVER_HOME_DIR | |
efb859b4 JB |
92 | { |
93 | struct stat statbfr; | |
94 | ||
95 | gethostname (system_name, sizeof (system_name)); | |
96 | sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name); | |
97 | ||
98 | if (stat (server.sun_path, &statbfr) == -1) | |
99 | { | |
c0acc3e1 JB |
100 | if (errno == ENOENT) |
101 | fprintf (stderr, | |
102 | "Can't find socket; have you started the server?\n"); | |
103 | else | |
104 | perror ("stat"); | |
efb859b4 JB |
105 | exit (1); |
106 | } | |
107 | if (statbfr.st_uid != geteuid()) | |
108 | { | |
109 | fprintf (stderr, "Illegal socket owner\n"); | |
110 | exit (1); | |
111 | } | |
112 | } | |
46cec291 RS |
113 | #else |
114 | if ((homedir = getenv ("HOME")) == NULL) | |
115 | { | |
116 | fprintf (stderr, "%s: No home directory\n", argv[0]); | |
117 | exit (1); | |
118 | } | |
119 | strcpy (server.sun_path, homedir); | |
120 | strcat (server.sun_path, "/.emacs_server"); | |
121 | #endif | |
122 | ||
123 | if (connect (s, &server, strlen (server.sun_path) + 2) < 0) | |
124 | { | |
125 | fprintf (stderr, "%s: ", argv[0]); | |
126 | perror ("connect"); | |
127 | exit (1); | |
128 | } | |
129 | if ((out = fdopen (s, "r+")) == NULL) | |
130 | { | |
131 | fprintf (stderr, "%s: ", argv[0]); | |
132 | perror ("fdopen"); | |
133 | exit (1); | |
134 | } | |
135 | ||
136 | cwd = getwd (string); | |
137 | if (cwd == 0) | |
138 | { | |
139 | /* getwd puts message in STRING if it fails. */ | |
140 | fprintf (stderr, "%s: %s (%s)\n", argv[0], string, | |
141 | (errno < sys_nerr) ? sys_errlist[errno] : "unknown error"); | |
142 | exit (1); | |
143 | } | |
144 | ||
145 | for (i = 1; i < argc; i++) | |
146 | { | |
147 | if (*argv[i] == '+') | |
148 | { | |
149 | char *p = argv[i] + 1; | |
150 | while (*p >= '0' && *p <= '9') p++; | |
151 | if (*p != 0) | |
152 | fprintf (out, "%s/", cwd); | |
153 | } | |
154 | else if (*argv[i] != '/') | |
155 | fprintf (out, "%s/", cwd); | |
156 | fprintf (out, "%s ", argv[i]); | |
157 | } | |
158 | fprintf (out, "\n"); | |
159 | fflush (out); | |
160 | ||
161 | printf ("Waiting for Emacs..."); | |
162 | fflush (stdout); | |
163 | ||
164 | rewind (out); /* re-read the output */ | |
165 | str = fgets (string, BUFSIZ, out); | |
166 | ||
167 | /* Now, wait for an answer and print any messages. */ | |
168 | ||
169 | while (str = fgets (string, BUFSIZ, out)) | |
170 | printf ("%s", str); | |
171 | ||
172 | exit (0); | |
173 | } | |
174 | ||
175 | #else /* This is the SYSV IPC section */ | |
176 | ||
177 | #include <sys/types.h> | |
178 | #include <sys/ipc.h> | |
179 | #include <sys/msg.h> | |
180 | #include <stdio.h> | |
181 | ||
182 | main (argc, argv) | |
183 | int argc; | |
184 | char **argv; | |
185 | { | |
186 | int s; | |
187 | key_t key; | |
188 | struct msgbuf * msgp = | |
189 | (struct msgbuf *) malloc (sizeof *msgp + BUFSIZ); | |
190 | struct msqid_ds * msg_st; | |
191 | char *homedir, buf[BUFSIZ]; | |
192 | char gwdirb[BUFSIZ]; | |
193 | char *cwd; | |
194 | char *temp; | |
195 | char *getwd (), *getcwd (), *getenv (); | |
196 | ||
197 | if (argc < 2) | |
198 | { | |
199 | fprintf (stderr, "Usage: %s [+linenumber] filename\n", argv[0]); | |
200 | exit (1); | |
201 | } | |
202 | ||
203 | /* | |
204 | * Create a message queue using ~/.emacs_server as the path for ftok | |
205 | */ | |
206 | if ((homedir = getenv ("HOME")) == NULL) | |
207 | { | |
208 | fprintf (stderr, "%s: No home directory\n", argv[0]); | |
209 | exit (1); | |
210 | } | |
211 | strcpy (buf, homedir); | |
212 | strcat (buf, "/.emacs_server"); | |
213 | creat (buf, 0600); | |
214 | key = ftok (buf, 1); /* unlikely to be anyone else using it */ | |
61a93162 | 215 | s = msgget (key, 0600 | IPC_CREAT); |
46cec291 RS |
216 | if (s == -1) |
217 | { | |
218 | fprintf (stderr, "%s: ", argv[0]); | |
219 | perror ("msgget"); | |
220 | exit (1); | |
221 | } | |
222 | ||
223 | /* Determine working dir, so we can prefix it to all the arguments. */ | |
224 | #ifdef BSD | |
225 | temp = getwd (gwdirb); | |
226 | #else | |
227 | temp = getcwd (gwdirb, sizeof gwdirb); | |
228 | #endif | |
229 | ||
230 | cwd = gwdirb; | |
231 | if (temp != 0) | |
232 | { | |
233 | /* On some systems, cwd can look like `@machine/...'; | |
234 | ignore everything before the first slash in such a case. */ | |
235 | while (*cwd && *cwd != '/') | |
236 | cwd++; | |
237 | strcat (cwd, "/"); | |
238 | } | |
239 | else | |
240 | { | |
241 | fprintf (stderr, cwd); | |
242 | exit (1); | |
243 | } | |
244 | ||
245 | msgp->mtext[0] = 0; | |
246 | argc--; argv++; | |
247 | while (argc) | |
248 | { | |
249 | if (*argv[0] == '+') | |
250 | { | |
251 | char *p = argv[0] + 1; | |
252 | while (*p >= '0' && *p <= '9') p++; | |
253 | if (*p != 0) | |
254 | strcat (msgp->mtext, cwd); | |
255 | } | |
256 | else if (*argv[0] != '/') | |
257 | strcat (msgp->mtext, cwd); | |
258 | ||
259 | strcat (msgp->mtext, argv[0]); | |
260 | strcat (msgp->mtext, " "); | |
261 | argv++; argc--; | |
262 | } | |
263 | strcat (msgp->mtext, "\n"); | |
264 | msgp->mtype = 1; | |
265 | if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0) | |
266 | { | |
267 | fprintf (stderr, "%s: ", argv[0]); | |
268 | perror ("msgsnd"); | |
269 | exit (1); | |
270 | } | |
271 | /* | |
272 | * Now, wait for an answer | |
273 | */ | |
274 | printf ("Waiting for Emacs..."); | |
275 | fflush (stdout); | |
276 | ||
277 | msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */ | |
278 | strcpy (buf, msgp->mtext); | |
279 | ||
280 | printf ("\n%s\n", buf); | |
281 | exit (0); | |
282 | } | |
283 | ||
284 | #endif /* HAVE_SYSVIPC */ | |
285 | ||
286 | #endif /* HAVE_SOCKETS or HAVE_SYSVIPC */ |