Mercurial > hg > xemacs-beta
diff lib-src/gnuclient.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | bcdc7deadc19 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib-src/gnuclient.c Mon Aug 13 08:45:50 2007 +0200 @@ -0,0 +1,337 @@ +/* -*-C-*- + Client code to allow local and remote editing of files by XEmacs. + Copyright (C) 1989 Free Software Foundation, Inc. + Copyright (C) 1995 Sun Microsystems, Inc. + +This file is part of XEmacs. + +XEmacs is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +XEmacs is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with XEmacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. + + Author: Andy Norman (ange@hplb.hpl.hp.com), based on + 'etc/emacsclient.c' from the GNU Emacs 18.52 distribution. + + Please mail bugs and suggestions to the author at the above address. +*/ + +/* + * This file incorporates new features added by Bob Weiner <weiner@mot.com>, + * Darrell Kindred <dkindred@cmu.edu> and Arup Mukherjee <arup@cmu.edu>. + * GNUATTACH support added by Ben Wing <wing@xemacs.org>. + * Please see the note at the end of the README file for details. + * + * (If gnuserv came bundled with your emacs, the README file is probably + * ../etc/gnuserv.README relative to the directory containing this file) + */ + +#if 0 +/* Hand-munged RCS header */ +static char rcsid [] = "!Header: gnuclient.c,v 2.2 95/12/12 01:39:21 wing nene !"; +#endif + +#include "gnuserv.h" +#include "getopt.h" + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unistd.h> + +#if !defined(SYSV_IPC) && !defined(UNIX_DOMAIN_SOCKETS) && \ + !defined(INTERNET_DOMAIN_SOCKETS) +main () +{ + fprintf (stderr, "Sorry, the Emacs server is only " + "supported on systems that have\n"); + fprintf (stderr, "Unix Domain sockets, Internet Domain " + "sockets or System V IPC.\n"); + exit (1); +} /* main */ +#else /* SYSV_IPC || UNIX_DOMAIN_SOCKETS || INTERNET_DOMAIN_SOCKETS */ + +static char cwd[MAXPATHLEN+2]; /* current working directory when calculated */ +static char *cp = NULL; /* ptr into valid bit of cwd above */ + + +/* + get_current_working_directory -- return the cwd. +*/ +static char * +get_current_working_directory (void) +{ + if (cp == NULL) + { /* haven't calculated it yet */ +#ifdef BSD + if (getwd (cwd) == 0) +#else /* !BSD */ + if (getcwd (cwd,MAXPATHLEN) == NULL) +#endif /* !BSD */ + { + perror (progname); + fprintf (stderr, "%s: unable to get current working directory\n", + progname); + exit (1); + } /* if */ + + /* on some systems, cwd can look like '@machine/' ... */ + /* ignore everything before the first '/' */ + for (cp = cwd; *cp && *cp != '/'; ++cp) + ; + + } /* if */ + + return cp; + +} /* get_current_working_directory */ + + +/* + filename_expand -- try to convert the given filename into a fully-qualified + pathname. +*/ +static void +filename_expand (char *fullpath, char *filename) + /* fullpath - returned full pathname */ + /* filename - filename to expand */ +{ + int len; + + fullpath[0] = '\0'; + + if (filename[0] && filename[0] != '/') + { /* relative filename */ + strcat (fullpath, get_current_working_directory ()); + len = strlen (fullpath); + + if (len > 0 && fullpath[len-1] == '/') /* trailing slash already? */ + ; /* yep */ + else + strcat (fullpath, "/"); /* nope, append trailing slash */ + } /* if */ + + strcat (fullpath,filename); + +} /* filename_expand */ + +void +main (int argc, char **argv) +{ + int starting_line = 1; /* line to start editing at */ + char command[MAXPATHLEN+50]; /* emacs command buffer */ + char fullpath[MAXPATHLEN+1]; /* full pathname to file */ +#ifndef GNUATTACH + int qflg = 0; /* quick edit, don't wait for + * user to finish */ +#endif + int errflg = 0; /* option error */ + int c; /* char from getopt */ + int s; /* socket / msqid to server */ + int connect_type; /* CONN_UNIX, CONN_INTERNET, or + * CONN_IPC */ +#ifdef INTERNET_DOMAIN_SOCKETS + char *hostarg = NULL; /* remote hostname */ + char thishost[HOSTNAMSZ]; /* this hostname */ + char remotepath[MAXPATHLEN+1]; /* remote pathname */ + int rflg = 0; /* pathname given on cmdline */ + u_short portarg = 0; /* port to server */ + char *ptr; /* return from getenv */ +#endif /* INTERNET_DOMAIN_SOCKETS */ +#ifdef SYSV_IPC + struct msgbuf *msgp; /* message */ +#endif /* SYSV_IPC */ +#ifdef GNUATTACH + char *tty; +#endif + +#ifdef INTERNET_DOMAIN_SOCKETS + memset (remotepath, 0, sizeof (remotepath)); +#endif /* INTERNET_DOMAIN_SOCKETS */ + + progname = argv[0]; + + while ((c = getopt (argc, argv, + +#ifdef INTERNET_DOMAIN_SOCKETS +# ifdef GNUATTACH + "h:p:r" +# else + "h:p:r:q" +# endif +#else /* !INTERNET_DOMAIN_SOCKETS */ +# ifdef GNUATTACH + "" +# else + "q" +# endif +#endif /* !INTERNET_DOMAIN_SOCKETS */ + + )) != EOF) + switch (c) + { +#ifndef GNUATTACH + case 'q': /* quick mode specified */ + qflg++; + break; +#endif + +#ifdef INTERNET_DOMAIN_SOCKETS + case 'h': /* server host name specified */ + hostarg = optarg; + break; + case 'r': /* remote path from server specifed */ + strcpy (remotepath,optarg); + rflg++; + break; + case 'p': /* port number specified */ + portarg = atoi (optarg); + break; +#endif /* INTERNET_DOMAIN_SOCKETS */ + + case '?': + errflg++; + } /* switch */ + + if (errflg) + { + fprintf (stderr, +#ifdef INTERNET_DOMAIN_SOCKETS +# ifdef GNUATTACH + "usage: %s [-h hostname] [-p port] [-r pathname] " + "[[+line] path] ...\n", +# else + "usage: %s [-q] [-h hostname] [-p port] [-r pathname] " + "[[+line] path] ...\n", +# endif +#else /* !INTERNET_DOMAIN_SOCKETS */ +# ifdef GNUATTACH + "usage: %s [[+line] path] ...\n", +# else + "usage: %s [-q] [[+line] path] ...\n", +# endif +#endif /* !INTERNET_DOMAIN_SOCKETS */ + progname); + exit (1); + } /* if */ + +#ifdef GNUATTACH + tty = ttyname (0); + if (!tty) + { + fprintf (stderr, "%s: Not connected to a tty", progname); + exit (1); + } +#endif + +#ifdef INTERNET_DOMAIN_SOCKETS + connect_type = make_connection (hostarg, portarg, &s); +#else + connect_type = make_connection (NULL, (u_short) 0, &s); +#endif + +#ifdef INTERNET_DOMAIN_SOCKETS + if (connect_type == (int) CONN_INTERNET) + { + gethostname (thishost, HOSTNAMSZ); + if (!rflg) + { /* attempt to generate a path + * to this machine */ + if ((ptr = getenv ("GNU_NODE")) != NULL) + /* user specified a path */ + strcpy (remotepath, ptr); + } +#if 0 /* This is really bogus... re-enable it if you must have it! */ +#if defined (hp9000s300) || defined (hp9000s800) + else if (strcmp (thishost,hostarg)) + { /* try /net/thishost */ + strcpy (remotepath, "/net/"); /* (this fails using internet + addresses) */ + strcat (remotepath, thishost); + } +#endif +#endif + } + else + { /* same machines, no need for path */ + remotepath[0] = '\0'; /* default is the empty path */ + } +#endif /* INTERNET_DOMAIN_SOCKETS */ + +#ifdef SYSV_IPC + if ((msgp = (struct msgbuf *) + malloc (sizeof *msgp + GSERV_BUFSZ)) == NULL) + { + fprintf (stderr, "%s: not enough memory for message buffer\n", progname); + exit (1); + } /* if */ + + msgp->mtext[0] = '\0'; /* ready for later strcats */ +#endif /* SYSV_IPC */ + +#ifdef GNUATTACH + ptr = getenv ("TERM"); + if (!ptr) + { + fprintf (stderr, "%s: unknown terminal type\n", progname); + exit (1); + } + sprintf (command, "(server-tty-edit-files \"%s\" \"%s\" '(", tty, ptr); + send_string (s, command); +#else + if (qflg) + { + send_string (s, "(server-edit-files-quickly '("); + } + else + { + send_string (s, "(server-edit-files '("); + } +#endif + + for (; optind < argc; optind++) + { + if (*argv[optind] == '+') + starting_line = atoi (argv[optind]); + else + { + filename_expand (fullpath, argv[optind]); + sprintf (command, "(%d . \"%s%s\")", starting_line, + +#ifdef INTERNET_DOMAIN_SOCKETS + remotepath, +#else /* !INTERNET_DOMAIN_SOCKETS */ + "", +#endif + fullpath); + send_string (s,command); + starting_line = 1; + } /* else */ + } /* for */ + + send_string (s,"))"); + +#ifdef SYSV_IPC + if (connect_type == (int) CONN_IPC) + disconnect_from_ipc_server (s, msgp, FALSE); +#else /* !SYSV_IPC */ + if (connect_type != (int) CONN_IPC) + disconnect_from_server (s, FALSE); +#endif /* !SYSV_IPC */ + + exit (0); + +} /* main */ + +#endif /* SYSV_IPC || UNIX_DOMAIN_SOCKETS || INTERNET_DOMAIN_SOCKETS */