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