Mercurial > emacs
comparison lib-src/emacsclient.c @ 27474:ed3668c0295a
(socket_status): New function.
(main): if $LOGNAME or $USER exist and differ from our euid, look
for a socket based on the UID associated with the name.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Fri, 28 Jan 2000 15:02:20 +0000 |
parents | 4161adef5fd3 |
children | 71ff4d0af84f |
comparison
equal
deleted
inserted
replaced
27473:2c8128604a57 | 27474:ed3668c0295a |
---|---|
1 /* Client process that communicates with GNU Emacs acting as server. | 1 /* Client process that communicates with GNU Emacs acting as server. |
2 Copyright (C) 1986, 1987, 1994, 1999 Free Software Foundation, Inc. | 2 Copyright (C) 1986, 1987, 1994, 1999, 2000 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GNU Emacs. | 4 This file is part of GNU Emacs. |
5 | 5 |
6 GNU Emacs is free software; you can redistribute it and/or modify | 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 | 7 it under the terms of the GNU General Public License as published by |
26 #include <stdio.h> | 26 #include <stdio.h> |
27 #include <getopt.h> | 27 #include <getopt.h> |
28 #ifdef HAVE_UNISTD_H | 28 #ifdef HAVE_UNISTD_H |
29 #include <unistd.h> | 29 #include <unistd.h> |
30 #endif | 30 #endif |
31 | |
32 #ifdef VMS | |
33 # include "vms-pwd.h" | |
34 #else | |
35 # include <pwd.h> | |
36 #endif /* not VMS */ | |
31 | 37 |
32 char *getenv (), *getwd (); | 38 char *getenv (), *getwd (); |
33 char *getcwd (); | 39 char *getcwd (); |
34 | 40 |
35 /* This is defined with -D from the compilation command, | 41 /* This is defined with -D from the compilation command, |
215 #include <errno.h> | 221 #include <errno.h> |
216 | 222 |
217 extern char *strerror (); | 223 extern char *strerror (); |
218 extern int errno; | 224 extern int errno; |
219 | 225 |
226 /* Three possibilities: | |
227 2 - can't be `stat'ed (sets errno) | |
228 1 - isn't owned by us | |
229 0 - success: none of the above */ | |
230 | |
231 static int | |
232 socket_status (socket_name) | |
233 char *socket_name; | |
234 { | |
235 struct stat statbfr; | |
236 | |
237 if (stat (socket_name, &statbfr) == -1) | |
238 return 2; | |
239 | |
240 if (statbfr.st_uid != geteuid ()) | |
241 return 1; | |
242 | |
243 return 0; | |
244 } | |
245 | |
220 int | 246 int |
221 main (argc, argv) | 247 main (argc, argv) |
222 int argc; | 248 int argc; |
223 char **argv; | 249 char **argv; |
224 { | 250 { |
270 } | 296 } |
271 | 297 |
272 #ifndef SERVER_HOME_DIR | 298 #ifndef SERVER_HOME_DIR |
273 { | 299 { |
274 struct stat statbfr; | 300 struct stat statbfr; |
301 int sock_status = 0; | |
275 | 302 |
276 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name); | 303 sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name); |
277 | 304 |
278 if (stat (server.sun_path, &statbfr) == -1) | 305 /* See if the socket exists, and if it's owned by us. */ |
306 sock_status = socket_status (server.sun_path); | |
307 if (sock_status) | |
279 { | 308 { |
280 if (errno == ENOENT) | 309 /* Failing that, see if LOGNAME or USER exist and differ from |
281 fprintf (stderr, | 310 our euid. If so, look for a socket based on the UID |
282 "%s: can't find socket; have you started the server?\n", | 311 associated with the name. This is reminiscent of the logic |
283 argv[0]); | 312 that init_editfns uses to set the global Vuser_full_name. */ |
284 else | 313 |
285 fprintf (stderr, "%s: can't stat %s: %s\n", | 314 char *user_name = (char *) getenv ("LOGNAME"); |
286 argv[0], server.sun_path, strerror (errno)); | 315 if (!user_name) |
287 fail (argc, argv); | 316 user_name = (char *) getenv ("USER"); |
317 | |
318 if (user_name) | |
319 { | |
320 struct passwd *pw = getpwnam (user_name); | |
321 if (pw && (pw->pw_uid != geteuid ())) | |
322 { | |
323 /* We're running under su, apparently. */ | |
324 sprintf (server.sun_path, "/tmp/esrv%d-%s", | |
325 pw->pw_uid, system_name); | |
326 sock_status = socket_status (server.sun_path); | |
327 } | |
328 } | |
288 } | 329 } |
289 if (statbfr.st_uid != geteuid ()) | 330 |
290 { | 331 switch (sock_status) |
291 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); | 332 { |
292 fail (argc, argv); | 333 case 1: |
293 } | 334 /* There's a socket, but it isn't owned by us. This is OK if |
335 we are root. */ | |
336 if (0 != geteuid ()) | |
337 { | |
338 fprintf (stderr, "%s: Invalid socket owner\n", argv[0]); | |
339 fail (argc, argv); | |
340 } | |
341 break; | |
342 | |
343 case 2: | |
344 /* `stat' failed */ | |
345 if (errno == ENOENT) | |
346 fprintf (stderr, | |
347 "%s: can't find socket; have you started the server?\n", | |
348 argv[0]); | |
349 else | |
350 fprintf (stderr, "%s: can't stat %s: %s\n", | |
351 argv[0], server.sun_path, strerror (errno)); | |
352 fail (argc, argv); | |
353 break; | |
354 } | |
294 } | 355 } |
295 #else | 356 #else |
296 if ((homedir = getenv ("HOME")) == NULL) | 357 if ((homedir = getenv ("HOME")) == NULL) |
297 { | 358 { |
298 fprintf (stderr, "%s: No home directory\n", argv[0]); | 359 fprintf (stderr, "%s: No home directory\n", argv[0]); |