|
|
1.1 root 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(BSD) && !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 /* BSD or HAVE_SYSVIPC */
45:
46: #if defined(BSD) && ! 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: #include <sys/stat.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: struct stat statbfr;
71:
72: char *getenv (), *getwd ();
73:
74: if (argc < 2)
75: {
76: fprintf (stderr, "Usage: %s 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
92: gethostname (system_name, sizeof (system_name));
93: sprintf (server.sun_path, "/tmp/esrv%d-%s", geteuid (), system_name);
94:
95: if (stat (server.sun_path, &statbfr) == -1)
96: {
97: perror ("stat");
98: exit (1);
99: }
100: if (statbfr.st_uid != geteuid())
101: {
102: fprintf (stderr, "Illegal socket owner\n");
103: exit (1);
104: }
105: #else
106: if ((homedir = getenv ("HOME")) == NULL)
107: {
108: fprintf (stderr, "%s: No home directory\n", argv[0]);
109: exit (1);
110: }
111: strcpy (server.sun_path, homedir);
112: strcat (server.sun_path, "/.emacs_server");
113: #endif
114:
115: if (connect (s, &server, strlen (server.sun_path) + 2) < 0)
116: {
117: fprintf (stderr, "%s: ", argv[0]);
118: perror ("connect");
119: exit (1);
120: }
121: if ((out = fdopen (s, "r+")) == NULL)
122: {
123: fprintf (stderr, "%s: ", argv[0]);
124: perror ("fdopen");
125: exit (1);
126: }
127:
128: cwd = getwd (string);
129: if (cwd == 0)
130: {
131: /* getwd puts message in STRING if it fails. */
132: fprintf (stderr, "%s: %s (%s)\n", argv[0], string,
133: (errno < sys_nerr) ? sys_errlist[errno] : "unknown error");
134: exit (1);
135: }
136:
137: for (i = 1; i < argc; i++)
138: {
139: if (*argv[i] == '+')
140: {
141: char *p = argv[i] + 1;
142: while (*p >= '0' && *p <= '9') p++;
143: if (*p != 0)
144: fprintf (out, "%s/", cwd);
145: }
146: else if (*argv[i] != '/')
147: fprintf (out, "%s/", cwd);
148: fprintf (out, "%s ", argv[i]);
149: }
150: fprintf (out, "\n");
151: fflush (out);
152:
153: printf ("Waiting for Emacs...");
154: fflush (stdout);
155:
156: rewind (out); /* re-read the output */
157: str = fgets (string, BUFSIZ, out);
158:
159: /* Now, wait for an answer and print any messages. */
160:
161: while (str = fgets (string, BUFSIZ, out))
162: printf ("%s", str);
163:
164: exit (0);
165: }
166:
167: #else /* This is the SYSV IPC section */
168:
169: #include <sys/types.h>
170: #include <sys/ipc.h>
171: #include <sys/msg.h>
172: #include <stdio.h>
173:
174: main (argc, argv)
175: int argc;
176: char **argv;
177: {
178: int s;
179: key_t key;
180: struct msgbuf * msgp =
181: (struct msgbuf *) malloc (sizeof *msgp + BUFSIZ);
182: struct msqid_ds * msg_st;
183: char *homedir, buf[BUFSIZ];
184: char gwdirb[BUFSIZ];
185: char *cwd;
186: char *temp;
187: char *getwd (), *getcwd (), *getenv ();
188:
189: if (argc < 2)
190: {
191: fprintf (stderr, "Usage: %s filename\n", argv[0]);
192: exit (1);
193: }
194:
195: /*
196: * Create a message queue using ~/.emacs_server as the path for ftok
197: */
198: if ((homedir = getenv ("HOME")) == NULL)
199: {
200: fprintf (stderr, "%s: No home directory\n", argv[0]);
201: exit (1);
202: }
203: strcpy (buf, homedir);
204: strcat (buf, "/.emacs_server");
205: creat (buf, 0600);
206: key = ftok (buf, 1); /* unlikely to be anyone else using it */
207: s = msgget (key, 0600 | IPC_CREAT);
208: if (s == -1)
209: {
210: fprintf (stderr, "%s: ", argv[0]);
211: perror ("msgget");
212: exit (1);
213: }
214:
215: /* Determine working dir, so we can prefix it to all the arguments. */
216: #ifdef BSD
217: temp = getwd (gwdirb);
218: #else
219: temp = getcwd (gwdirb, sizeof gwdirb);
220: #endif
221:
222: cwd = gwdirb;
223: if (temp != 0)
224: {
225: /* On some systems, cwd can look like `@machine/...';
226: ignore everything before the first slash in such a case. */
227: while (*cwd && *cwd != '/')
228: cwd++;
229: strcat (cwd, "/");
230: }
231: else
232: {
233: fprintf (stderr, cwd);
234: exit (1);
235: }
236:
237: msgp->mtext[0] = 0;
238: argc--; argv++;
239: while (argc)
240: {
241: if (*argv[0] == '+')
242: {
243: char *p = argv[0] + 1;
244: while (*p >= '0' && *p <= '9') p++;
245: if (*p != 0)
246: strcat (msgp->mtext, cwd);
247: }
248: else if (*argv[0] != '/')
249: strcat (msgp->mtext, cwd);
250:
251: strcat (msgp->mtext, argv[0]);
252: strcat (msgp->mtext, " ");
253: argv++; argc--;
254: }
255: strcat (msgp->mtext, "\n");
256: msgp->mtype = 1;
257: if (msgsnd (s, msgp, strlen (msgp->mtext)+1, 0) < 0)
258: {
259: fprintf (stderr, "%s: ", argv[0]);
260: perror ("msgsnd");
261: exit (1);
262: }
263: /*
264: * Now, wait for an answer
265: */
266: printf ("Waiting for Emacs...");
267: fflush (stdout);
268:
269: msgrcv (s, msgp, BUFSIZ, getpid (), 0); /* wait for anything back */
270: strcpy (buf, msgp->mtext);
271:
272: printf ("\n%s\n", buf);
273: exit (0);
274: }
275:
276: #endif /* HAVE_SYSVIPC */
277:
278: #endif /* BSD or HAVE_SYSVIPC */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.