Mercurial > hg > xemacs-beta
annotate lib-src/gnuslib.c @ 2367:ecf1ebac70d8
[xemacs-hg @ 2004-11-04 23:05:23 by ben]
commit mega-patch
configure.in: Turn off -Winline and -Wchar-subscripts.
Use the right set of cflags when compiling modules.
Rewrite ldap configuration to separate the inclusion of lber
(needed in recent Cygwin) from the basic checks for the
needed libraries.
add a function for MAKE_JUNK_C; initially code was added to
generate xemacs.def using this, but it will need to be rewritten.
add an rm -f for junk.c to avoid weird Cygwin bug with cp -f onto
an existing file.
Sort list of auto-detected functions and eliminate unused checks for
stpcpy, setlocale and getwd.
Add autodetection of Cygwin scanf problems
BETA: Rewrite section on configure to indicate what flags are important
and what not.
digest-doc.c, make-dump-id.c, profile.c, sorted-doc.c: Add proper decls for main().
make-msgfile.c: Document that this is old junk.
Move proposal to text.c.
make-msgfile.lex: Move proposal to text.c.
make-mswin-unicode.pl: Convert error-generating code so that the entire message will
be seen as a single unrecognized token.
mule/mule-ccl.el: Update docs.
lispref/mule.texi: Update CCL docs.
ldap/eldap.c: Mule-ize.
Use EXTERNAL_LIST_LOOP_2 instead of deleted EXTERNAL_LIST_LOOP.
* XEmacs 21.5.18 "chestnut" is released.
---------------------------------------------------------------
MULE-RELATED WORK:
---------------------------------------------------------------
---------------------------
byte-char conversion
---------------------------
buffer.c, buffer.h, insdel.c, text.c: Port FSF algorithm for byte-char conversion, replacing broken
previous version. Track the char position of the gap. Add
functions to do char-byte conversion downwards as well as upwards.
Move comments about algorithm workings to internals manual.
---------------------------
work on types
---------------------------
alloc.c, console-x-impl.h, dump-data.c, dump-data.h, dumper.c, dialog-msw.c, dired-msw.c, doc.c, editfns.c, esd.c, event-gtk.h, event-msw.c, events.c, file-coding.c, file-coding.h, fns.c, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-shared.c, glyphs-x.c, glyphs.c, glyphs.h, gui.c, hpplay.c, imgproc.c, intl-win32.c, lrecord.h, lstream.c, keymap.c, lisp.h, libsst.c, linuxplay.c, miscplay.c, miscplay.h, mule-coding.c, nas.c, nt.c, ntheap.c, ntplay.c, objects-msw.c, objects-tty.c, objects-x.c, print.c, process-nt.c, process.c, redisplay.h, select-common.h, select-gtk.c, select-x.c, sgiplay.c, sound.c, sound.h, sunplay.c, sysfile.h, sysdep.c, syswindows.h, text.c, unexnt.c, win32.c, xgccache.c: Further work on types. This creates a full set of types for all
the basic semantics of `char' that I have so far identified, so that
its semantics can always be identified for the purposes of proper
Mule-safe code, and the raw use of `char' always avoided.
(1) More type renaming, for consistency of naming.
Char_ASCII -> Ascbyte
UChar_ASCII -> UAscbyte
Char_Binary -> CBinbyte
UChar_Binary -> Binbyte
SChar_Binary -> SBinbyte
(2) Introduce Rawbyte, CRawbyte, Boolbyte, Chbyte, UChbyte, and
Bitbyte and use them.
(3) New types Itext, Wexttext and Textcount for separating out
the concepts of bytes and textual units (different under UTF-16
and UTF-32, which are potential internal encodings).
(4) qxestr*_c -> qxestr*_ascii.
lisp.h: New; goes with other qxe() functions. #### Maybe goes in a
different section.
lisp.h: Group generic int-type defs together with EMACS_INT defs.
lisp.h: * lisp.h (WEXTTEXT_IS_WIDE)
New defns.
lisp.h: New type to replace places where int occurs as a boolean.
It's signed because occasionally people may want to use -1 as
an error value, and because unsigned ints are viral -- see comments
in the internals manual against using them.
dynarr.c: int -> Bytecount.
---------------------------
Mule-izing
---------------------------
device-x.c: Partially Mule-ize.
dumper.c, dumper.h: Mule-ize. Use Rawbyte. Use stderr_out not printf. Use wext_*().
sysdep.c, syswindows.h, text.c: New Wexttext API for manipulation of external text that may be
Unicode (e.g. startup code under Windows).
emacs.c: Mule-ize. Properly deal with argv in external encoding.
Use wext_*() and Wexttext. Use Rawbyte.
#if 0 some old junk on SCO that is unlikely to be correct.
Rewrite allocation code in run-temacs.
emacs.c, symsinit.h, win32.c: Rename win32 init function and call it even earlier, to
initialize mswindows_9x_p even earlier, for use in startup code
(XEUNICODE_P).
process.c: Use _wenviron not environ under Windows, to get Unicode environment
variables.
event-Xt.c: Mule-ize drag-n-drop related stuff.
dragdrop.c, dragdrop.h, frame-x.c: Mule-ize.
text.h: Add some more stand-in defines for particular kinds of conversion;
use in Mule-ization work in frame-x.c etc.
---------------------------
Freshening
---------------------------
intl-auto-encap-win32.c, intl-auto-encap-win32.h: Regenerate.
---------------------------
Unicode-work
---------------------------
intl-win32.c, syswindows.h: Factor out common options to MultiByteToWideChar and
WideCharToMultiByte. Add convert_unicode_to_multibyte_malloc()
and convert_unicode_to_multibyte_dynarr() and use. Add stuff for
alloca() conversion of multibyte/unicode.
alloc.c: Use dfc_external_data_len() in case of unicode coding system.
alloc.c, mule-charset.c: Don't zero out and reinit charset Unicode tables. This fucks up
dump-time loading. Anyway, either we load them at dump time or
run time, never both.
unicode.c: Dump the blank tables as well.
---------------------------------------------------------------
DOCUMENTATION, MOSTLY MULE-RELATED:
---------------------------------------------------------------
EmacsFrame.c, emodules.c, event-Xt.c, fileio.c, input-method-xlib.c, mule-wnnfns.c, redisplay-gtk.c, redisplay-tty.c, redisplay-x.c, regex.c, sysdep.c: Add comment about Mule work needed.
text.h: Add more documentation describing why DFC routines were not written
to return their value. Add some other DFC documentation.
console-msw.c, console-msw.h: Add pointer to docs in win32.c.
emacs.c: Add comments on sources of doc info.
text.c, charset.h, unicode.c, intl-win32.c, intl-encap-win32.c, text.h, file-coding.c, mule-coding.c: Collect background comments and related to text matters and
internationalization, and proposals for work to be done, in text.c
or Internals manual, stuff related to specific textual API's in
text.h, and stuff related to internal implementation of Unicode
conversion in unicode.c. Put lots of pointers to the comments to
make them easier to find.
s/mingw32.h, s/win32-common.h, s/win32-native.h, s/windowsnt.h, win32.c: Add bunches of new documentation on the different kinds of
builds and environments under Windows and how they work.
Collect this info in win32.c. Add pointers to these docs in
the relevant s/* files.
emacs.c: Document places with long comments.
Remove comment about exiting, move to internals manual, put
in pointer.
event-stream.c: Move docs about event queues and focus to internals manual, put
in pointer.
events.h: Move docs about event stream callbacks to internals manual, put
in pointer.
profile.c, redisplay.c, signal.c: Move documentation to the Internals manual.
process-nt.c: Add pointer to comment in win32-native.el.
lisp.h: Add comments about some comment conventions.
lisp.h: Add comment about the second argument.
device-msw.c, redisplay-msw.c: @@#### comments are out-of-date.
---------------------------------------------------------------
PDUMP WORK (MOTIVATED BY UNICODE CHANGES)
---------------------------------------------------------------
alloc.c, buffer.c, bytecode.c, console-impl.h, console.c, device.c, dumper.c, lrecord.h, elhash.c, emodules.h, events.c, extents.c, frame.c, glyphs.c, glyphs.h, mule-charset.c, mule-coding.c, objects.c, profile.c, rangetab.c, redisplay.c, specifier.c, specifier.h, window.c, lstream.c, file-coding.h, file-coding.c: PDUMP:
Properly implement dump_add_root_block(), which never worked before,
and is necessary for dumping Unicode tables.
Pdump name changes for accuracy:
XD_STRUCT_PTR -> XD_BLOCK_PTR.
XD_STRUCT_ARRAY -> XD_BLOCK_ARRAY.
XD_C_STRING -> XD_ASCII_STRING.
*_structure_* -> *_block_*.
lrecord.h: some comments added about
dump_add_root_block() vs dump_add_root_block_ptr().
extents.c: remove incorrect comment about pdump problems with gap array.
---------------------------------------------------------------
ALLOCATION
---------------------------------------------------------------
abbrev.c, alloc.c, bytecode.c, casefiddle.c, device-msw.c, device-x.c, dired-msw.c, doc.c, doprnt.c, dragdrop.c, editfns.c, emodules.c, file-coding.c, fileio.c, filelock.c, fns.c, glyphs-eimage.c, glyphs-gtk.c, glyphs-msw.c, glyphs-x.c, gui-msw.c, gui-x.c, imgproc.c, intl-win32.c, lread.c, menubar-gtk.c, menubar.c, nt.c, objects-msw.c, objects-x.c, print.c, process-nt.c, process-unix.c, process.c, realpath.c, redisplay.c, search.c, select-common.c, symbols.c, sysdep.c, syswindows.h, text.c, text.h, ui-byhand.c: New macros {alloca,xnew}_{itext,{i,ext,raw,bin,asc}bytes} for
more convenient allocation of these commonly requested items.
Modify functions to use alloca_ibytes, alloca_array, alloca_extbytes,
xnew_ibytes, etc. also XREALLOC_ARRAY, xnew.
alloc.c: Rewrite the allocation functions to factor out repeated code.
Add assertions for freeing dumped data.
lisp.h: Moved down and consolidated with other allocation stuff.
lisp.h, dynarr.c: New functions for allocation that's very efficient when mostly in
LIFO order.
lisp.h, text.c, text.h: Factor out some stuff for general use by alloca()-conversion funs.
text.h, lisp.h: Fill out convenience routines for allocating various kinds of
bytes and put them in lisp.h. Use them in place of xmalloc(),
ALLOCA().
text.h: Fill out the convenience functions so the _MALLOC() kinds match
the alloca() kinds.
---------------------------------------------------------------
ERROR-CHECKING
---------------------------------------------------------------
text.h: Create ASSERT_ASCTEXT_ASCII() and ASSERT_ASCTEXT_ASCII_LEN()
from similar Eistring checkers and change the Eistring checkers to
use them instead.
---------------------------------------------------------------
MACROS IN LISP.H
---------------------------------------------------------------
lisp.h: Redo GCPRO declarations. Create a "base" set of functions that can
be used to generate any kind of gcpro sets -- regular, ngcpro,
nngcpro, private ones used in GC_EXTERNAL_LIST_LOOP_2.
buffer.c, callint.c, chartab.c, console-msw.c, device-x.c, dialog-msw.c, dired.c, extents.c, ui-gtk.c, rangetab.c, nt.c, mule-coding.c, minibuf.c, menubar-msw.c, menubar.c, menubar-gtk.c, lread.c, lisp.h, gutter.c, glyphs.c, glyphs-widget.c, fns.c, fileio.c, file-coding.c, specifier.c: Eliminate EXTERNAL_LIST_LOOP, which does not check for circularities.
Use EXTERNAL_LIST_LOOP_2 instead or EXTERNAL_LIST_LOOP_3
or EXTERNAL_PROPERTY_LIST_LOOP_3 or GC_EXTERNAL_LIST_LOOP_2
(new macro). Removed/redid comments on EXTERNAL_LIST_LOOP.
---------------------------------------------------------------
SPACING FIXES
---------------------------------------------------------------
callint.c, hftctl.c, number-gmp.c, process-unix.c: Spacing fixes.
---------------------------------------------------------------
FIX FOR GEOMETRY PROBLEM IN FIRST FRAME
---------------------------------------------------------------
unicode.c: Add workaround for newlib bug in sscanf() [should be fixed by
release 1.5.12 of Cygwin].
toolbar.c: bug fix for problem of initial frame being 77 chars wide on Windows.
will be overridden by my other ws.
---------------------------------------------------------------
FIX FOR LEAKING PROCESS HANDLES:
---------------------------------------------------------------
process-nt.c: Fixes for leaking handles. Inspired by work done by Adrian Aichner
<adrian@xemacs.org>.
---------------------------------------------------------------
FIX FOR CYGWIN BUG (Unicode-related):
---------------------------------------------------------------
unicode.c: Add workaround for newlib bug in sscanf() [should be fixed by
release 1.5.12 of Cygwin].
---------------------------------------------------------------
WARNING FIXES:
---------------------------------------------------------------
console-stream.c: `reinit' is unused.
compiler.h, event-msw.c, frame-msw.c, intl-encap-win32.c, text.h: Add stuff to deal with ANSI-aliasing warnings I got.
regex.c: Gather includes together to avoid warning.
---------------------------------------------------------------
CHANGES TO INITIALIZATION ROUTINES:
---------------------------------------------------------------
buffer.c, emacs.c, console.c, debug.c, device-x.c, device.c, dragdrop.c, emodules.c, eval.c, event-Xt.c, event-gtk.c, event-msw.c, event-stream.c, event-tty.c, events.c, extents.c, faces.c, file-coding.c, fileio.c, font-lock.c, frame-msw.c, glyphs-widget.c, glyphs.c, gui-x.c, insdel.c, lread.c, lstream.c, menubar-gtk.c, menubar-x.c, minibuf.c, mule-wnnfns.c, objects-msw.c, objects.c, print.c, scrollbar-x.c, search.c, select-x.c, text.c, undo.c, unicode.c, window.c, symsinit.h: Call reinit_*() functions directly from emacs.c, for clarity.
Factor out some redundant init code. Move disallowed stuff
that had crept into vars_of_glyphs() into complex_vars_of_glyphs().
Call init_eval_semi_early() from eval.c not in the middle of
vars_of_() in emacs.c since there should be no order dependency
in the latter calls.
---------------------------------------------------------------
ARMAGEDDON:
---------------------------------------------------------------
alloc.c, emacs.c, lisp.h, print.c: Rename inhibit_non_essential_printing_operations to
inhibit_non_essential_conversion_operations.
text.c: Assert on !inhibit_non_essential_conversion_operations.
console-msw.c, print.c: Don't do conversion in SetConsoleTitle or FindWindow to avoid
problems during armageddon. Put #errors for NON_ASCII_INTERNAL_FORMAT
in places where problems would arise.
---------------------------------------------------------------
CHANGES TO THE BUILD PROCEDURE:
---------------------------------------------------------------
config.h.in, s/cxux.h, s/usg5-4-2.h, m/powerpc.h: Add comment about correct ordering of this file.
Rearrange everything to follow this -- put all #undefs together
and before the s&m files. Add undefs for HAVE_ALLOCA, C_ALLOCA,
BROKEN_ALLOCA_IN_FUNCTION_CALLS, STACK_DIRECTION. Remove unused
HAVE_STPCPY, HAVE_GETWD, HAVE_SETLOCALE.
m/gec63.h: Deleted; totally broken, not used at all, not in FSF.
m/7300.h, m/acorn.h, m/alliant-2800.h, m/alliant.h, m/altos.h, m/amdahl.h, m/apollo.h, m/att3b.h, m/aviion.h, m/celerity.h, m/clipper.h, m/cnvrgnt.h, m/convex.h, m/cydra5.h, m/delta.h, m/delta88k.h, m/dpx2.h, m/elxsi.h, m/ews4800r.h, m/gould.h, m/hp300bsd.h, m/hp800.h, m/hp9000s300.h, m/i860.h, m/ibmps2-aix.h, m/ibmrs6000.h, m/ibmrt-aix.h, m/ibmrt.h, m/intel386.h, m/iris4d.h, m/iris5d.h, m/iris6d.h, m/irist.h, m/isi-ov.h, m/luna88k.h, m/m68k.h, m/masscomp.h, m/mg1.h, m/mips-nec.h, m/mips-siemens.h, m/mips.h, m/news.h, m/nh3000.h, m/nh4000.h, m/ns32000.h, m/orion105.h, m/pfa50.h, m/plexus.h, m/pmax.h, m/powerpc.h, m/pyrmips.h, m/sequent-ptx.h, m/sequent.h, m/sgi-challenge.h, m/symmetry.h, m/tad68k.h, m/tahoe.h, m/targon31.h, m/tekxd88.h, m/template.h, m/tower32.h, m/tower32v3.h, m/ustation.h, m/vax.h, m/wicat.h, m/xps100.h: Delete C_ALLOCA, HAVE_ALLOCA, STACK_DIRECTION,
BROKEN_ALLOCA_IN_FUNCTION_CALLS. All of this is auto-detected.
When in doubt, I followed recent FSF sources, which also have
these things deleted.
| author | ben |
|---|---|
| date | Thu, 04 Nov 2004 23:08:28 +0000 |
| parents | b39c14581166 |
| children | 2161ac78b41e |
| rev | line source |
|---|---|
| 428 | 1 /* -*-C-*- |
| 613 | 2 Common library code for the XEmacs server and client. |
| 428 | 3 |
| 613 | 4 This file is part of XEmacs. |
| 428 | 5 |
| 6 Copying is permitted under those conditions described by the GNU | |
| 7 General Public License. | |
| 8 | |
| 9 Copyright (C) 1989 Free Software Foundation, Inc. | |
| 10 | |
| 11 Author: Andy Norman (ange@hplb.hpl.hp.com), based on | |
| 12 'etc/server.c' and 'etc/emacsclient.c' from the 18.52 GNU | |
| 13 Emacs distribution. | |
| 14 | |
| 15 Please mail bugs and suggestions to the author at the above address. | |
| 16 */ | |
| 17 | |
| 18 /* HISTORY | |
| 19 * 11-Nov-1990 bristor@simba | |
| 20 * Added EOT stuff. | |
| 21 */ | |
| 22 | |
| 23 /* | |
| 24 * This file incorporates new features added by Bob Weiner <weiner@mot.com>, | |
| 25 * Darrell Kindred <dkindred@cmu.edu> and Arup Mukherjee <arup@cmu.edu>. | |
| 26 * Please see the note at the end of the README file for details. | |
| 27 * | |
| 28 * (If gnuserv came bundled with your emacs, the README file is probably | |
| 29 * ../etc/gnuserv.README relative to the directory containing this file) | |
| 30 */ | |
| 31 | |
| 32 #if 0 | |
| 33 static char rcsid [] = "!Header: gnuslib.c,v 2.4 95/02/16 11:57:37 arup alpha !"; | |
| 34 #endif | |
| 35 | |
| 36 #include "gnuserv.h" | |
| 37 #include <errno.h> | |
| 38 | |
| 39 #ifdef SYSV_IPC | |
| 40 static int connect_to_ipc_server (void); | |
| 41 #endif | |
| 42 #ifdef UNIX_DOMAIN_SOCKETS | |
| 43 static int connect_to_unix_server (void); | |
| 44 #endif | |
| 45 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 458 | 46 static int connect_to_internet_server (char *serverhost, unsigned short port); |
| 428 | 47 #endif |
| 48 | |
| 49 /* On some systems, e.g. DGUX, inet_addr returns a 'struct in_addr'. */ | |
| 50 #ifdef HAVE_BROKEN_INET_ADDR | |
| 51 # define IN_ADDR struct in_addr | |
| 52 # define NUMERIC_ADDR_ERROR (numeric_addr.s_addr == -1) | |
| 53 #else | |
| 54 # if (LONGBITS > 32) | |
| 55 # define IN_ADDR unsigned int | |
| 56 # else | |
| 57 # define IN_ADDR unsigned long | |
| 58 # endif | |
| 59 # define NUMERIC_ADDR_ERROR (numeric_addr == (IN_ADDR) -1) | |
| 60 #endif | |
| 61 | |
| 62 #include <stdlib.h> | |
| 63 #include <stdio.h> | |
| 64 #include <sys/types.h> | |
| 65 #include <sys/stat.h> | |
| 66 #ifdef HAVE_UNISTD_H | |
| 67 #include <unistd.h> | |
| 68 #endif /* HAVE_UNISTD_H */ | |
| 69 #ifdef HAVE_STRING_H | |
| 70 #include <string.h> | |
| 71 #endif /* HAVE_STRING_H */ | |
| 72 | |
| 73 #include <arpa/inet.h> | |
| 74 | |
| 75 char *tmpdir = NULL; | |
| 76 | |
| 77 char *progname = NULL; | |
| 78 | |
| 440 | 79 int |
| 80 make_connection (char *hostarg, int portarg, int *s) | |
| 428 | 81 { |
| 82 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 83 char *ptr; | |
| 84 if (hostarg == NULL) | |
| 85 hostarg = getenv("GNU_HOST"); | |
| 86 if (portarg == 0 && (ptr=getenv("GNU_PORT")) != NULL) | |
| 87 portarg = atoi(ptr); | |
| 88 #endif | |
| 89 | |
| 90 if (hostarg != NULL) { | |
| 91 /* hostname was given explicitly, via cmd line arg or GNU_HOST, | |
| 92 * so obey it. */ | |
| 93 #ifdef UNIX_DOMAIN_SOCKETS | |
| 94 if (!strcmp(hostarg, "unix")) { | |
| 95 *s = connect_to_unix_server(); | |
| 96 return (int) CONN_UNIX; | |
| 97 } | |
| 98 #endif /* UNIX_DOMAIN_SOCKETS */ | |
| 99 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 100 *s = connect_to_internet_server(hostarg, portarg); | |
| 101 return (int) CONN_INTERNET; | |
| 102 #endif | |
| 103 #ifdef SYSV_IPC | |
| 104 return -1; /* hostarg should always be NULL for SYSV_IPC */ | |
| 105 #endif | |
| 106 } else { | |
| 107 /* no hostname given. Use unix-domain/sysv-ipc, or | |
| 108 * internet-domain connection to local host if they're not available. */ | |
| 109 #if defined(UNIX_DOMAIN_SOCKETS) | |
| 110 *s = connect_to_unix_server(); | |
| 111 return (int) CONN_UNIX; | |
| 112 #elif defined(SYSV_IPC) | |
| 113 *s = connect_to_ipc_server(); | |
| 114 return (int) CONN_IPC; | |
| 115 #elif defined(INTERNET_DOMAIN_SOCKETS) | |
| 116 { | |
| 117 char localhost[HOSTNAMSZ]; | |
| 118 gethostname(localhost,HOSTNAMSZ); /* use this host by default */ | |
| 119 *s = connect_to_internet_server(localhost, portarg); | |
| 120 return (int) CONN_INTERNET; | |
| 121 } | |
| 122 #endif /* IPC type */ | |
| 123 } | |
| 124 } | |
| 125 | |
| 126 #ifdef SYSV_IPC | |
| 127 /* | |
| 128 connect_to_ipc_server -- establish connection with server process via SYSV IPC | |
| 129 Returns msqid for server if successful. | |
| 130 */ | |
| 440 | 131 static int |
| 132 connect_to_ipc_server (void) | |
| 428 | 133 { |
| 134 int s; /* connected msqid */ | |
| 135 key_t key; /* message key */ | |
| 136 char buf[GSERV_BUFSZ+1]; /* buffer for filename */ | |
| 137 | |
| 138 sprintf(buf,"%s/gsrv%d",tmpdir,(int)geteuid()); | |
| 139 creat(buf,0600); | |
| 140 if ((key = ftok(buf,1)) == -1) { | |
| 141 perror(progname); | |
| 142 fprintf(stderr, "%s: unable to get ipc key from %s\n", | |
| 143 progname, buf); | |
| 144 exit(1); | |
| 145 } | |
| 146 | |
| 147 if ((s = msgget(key,0600)) == -1) { | |
| 148 perror(progname); | |
| 149 fprintf(stderr,"%s: unable to access msg queue\n",progname); | |
| 150 exit(1); | |
| 151 }; /* if */ | |
| 152 | |
| 153 return(s); | |
| 154 | |
| 155 } /* connect_to_ipc_server */ | |
| 156 | |
| 157 | |
| 158 /* | |
| 159 disconnect_from_ipc_server -- inform the server that sending has finished, | |
| 160 and wait for its reply. | |
| 161 */ | |
| 440 | 162 void |
| 163 disconnect_from_ipc_server (int s, struct msgbuf *msgp, int echo) | |
| 428 | 164 { |
| 165 int len; /* length of received message */ | |
| 166 | |
| 167 send_string(s,EOT_STR); /* EOT terminates this message */ | |
| 168 msgp->mtype = 1; | |
| 169 | |
| 170 if(msgsnd(s,msgp,strlen(msgp->mtext)+1,0) < 0) { | |
| 171 perror(progname); | |
| 172 fprintf(stderr,"%s: unable to send message to server\n",progname); | |
| 173 exit(1); | |
| 174 }; /* if */ | |
| 175 | |
| 176 if((len = msgrcv(s,msgp,GSERV_BUFSZ,getpid(),0)) < 0) { | |
| 177 perror(progname); | |
| 178 fprintf(stderr,"%s: unable to receive message from server\n",progname); | |
| 179 exit(1); | |
| 180 }; /* if */ | |
| 181 | |
| 182 if (echo) { | |
| 183 msgp->mtext[len] = '\0'; /* string terminate message */ | |
| 184 fputs(msgp->mtext, stdout); | |
| 185 if (msgp->mtext[len-1] != '\n') putchar ('\n'); | |
| 186 }; /* if */ | |
| 187 | |
| 188 } /* disconnect_from_ipc_server */ | |
| 189 #endif /* SYSV_IPC */ | |
| 190 | |
| 191 | |
| 192 #if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS) | |
| 193 /* | |
| 194 send_string -- send string to socket. | |
| 195 */ | |
| 440 | 196 void |
| 442 | 197 send_string (int s, const char *msg) |
| 428 | 198 { |
| 199 #if 0 | |
| 200 if (send(s,msg,strlen(msg),0) < 0) { | |
| 201 perror(progname); | |
| 202 fprintf(stderr,"%s: unable to send\n",progname); | |
| 203 exit(1); | |
| 204 }; /* if */ | |
| 205 #else | |
| 206 int len, left=strlen(msg); | |
| 207 while (left > 0) { | |
| 208 if ((len=write(s,msg,min2(left,GSERV_BUFSZ))) < 0) { | |
| 209 /* XEmacs addition: robertl@arnet.com */ | |
| 210 if (errno == EPIPE) { | |
| 211 return ; | |
| 212 } | |
| 213 perror(progname); | |
| 214 fprintf(stderr,"%s: unable to send\n",progname); | |
| 215 exit(1); | |
| 216 }; /* if */ | |
| 217 left -= len; | |
| 218 msg += len; | |
| 219 }; /* while */ | |
| 220 #endif | |
| 221 } /* send_string */ | |
| 222 | |
| 223 /* | |
| 224 read_line -- read a \n terminated line from a socket | |
| 225 */ | |
| 440 | 226 int |
| 227 read_line (int s, char *dest) | |
| 428 | 228 { |
| 229 int length; | |
| 230 int offset=0; | |
| 231 char buffer[GSERV_BUFSZ+1]; | |
| 232 | |
| 233 while ((length=read(s,buffer+offset,1)>0) && buffer[offset]!='\n' | |
| 234 && buffer[offset] != EOT_CHR) { | |
| 235 offset += length; | |
| 236 if (offset >= GSERV_BUFSZ) | |
| 237 break; | |
| 238 } | |
| 239 buffer[offset] = '\0'; | |
| 240 strcpy(dest,buffer); | |
| 241 return 1; | |
| 242 } /* read_line */ | |
| 243 #endif /* INTERNET_DOMAIN_SOCKETS || UNIX_DOMAIN_SOCKETS */ | |
| 244 | |
| 245 | |
| 246 #ifdef UNIX_DOMAIN_SOCKETS | |
| 247 /* | |
| 248 connect_to_unix_server -- establish connection with server process via a unix- | |
| 249 domain socket. Returns socket descriptor for server | |
| 250 if successful. | |
| 251 */ | |
| 440 | 252 static int |
| 253 connect_to_unix_server (void) | |
| 428 | 254 { |
| 255 int s; /* connected socket descriptor */ | |
| 256 struct sockaddr_un server; /* for unix connections */ | |
| 257 | |
| 258 if ((s = socket(AF_UNIX,SOCK_STREAM,0)) < 0) { | |
| 259 perror(progname); | |
| 260 fprintf(stderr,"%s: unable to create socket\n",progname); | |
| 261 exit(1); | |
| 262 }; /* if */ | |
| 263 | |
| 264 server.sun_family = AF_UNIX; | |
| 265 #ifdef HIDE_UNIX_SOCKET | |
| 266 sprintf(server.sun_path,"%s/gsrvdir%d/gsrv",tmpdir,(int)geteuid()); | |
| 267 #else /* HIDE_UNIX_SOCKET */ | |
| 268 sprintf(server.sun_path,"%s/gsrv%d",tmpdir,(int)geteuid()); | |
| 269 #endif /* HIDE_UNIX_SOCKET */ | |
| 270 if (connect(s,(struct sockaddr *)&server,strlen(server.sun_path)+2) < 0) { | |
| 271 perror(progname); | |
| 272 fprintf(stderr,"%s: unable to connect to local\n",progname); | |
| 273 exit(1); | |
| 274 }; /* if */ | |
| 275 | |
| 276 return(s); | |
| 277 | |
| 278 } /* connect_to_unix_server */ | |
| 279 #endif /* UNIX_DOMAIN_SOCKETS */ | |
| 280 | |
| 281 | |
| 282 #ifdef INTERNET_DOMAIN_SOCKETS | |
| 283 /* | |
| 284 internet_addr -- return the internet addr of the hostname or | |
| 285 internet address passed. Return -1 on error. | |
| 286 */ | |
| 440 | 287 int |
| 288 internet_addr (char *host) | |
| 428 | 289 { |
| 290 struct hostent *hp; /* pointer to host info for remote host */ | |
| 291 IN_ADDR numeric_addr; /* host address */ | |
| 292 | |
| 293 numeric_addr = inet_addr(host); | |
| 294 if (!NUMERIC_ADDR_ERROR) | |
| 295 return numeric_addr; | |
| 296 else if ((hp = gethostbyname(host)) != NULL) | |
| 297 return ((struct in_addr *)(hp->h_addr))->s_addr; | |
| 298 else | |
| 299 return -1; | |
| 300 | |
| 301 } /* internet_addr */ | |
| 302 | |
| 303 #ifdef AUTH_MAGIC_COOKIE | |
| 304 # include <X11/X.h> | |
| 305 # include <X11/Xauth.h> | |
| 306 | |
| 307 static Xauth *server_xauth = NULL; | |
| 308 #endif | |
| 309 | |
| 310 /* | |
| 311 connect_to_internet_server -- establish connection with server process via | |
| 312 an internet domain socket. Returns socket | |
| 313 descriptor for server if successful. | |
| 314 */ | |
| 440 | 315 static int |
| 458 | 316 connect_to_internet_server (char *serverhost, unsigned short port) |
| 428 | 317 { |
| 318 int s; /* connected socket descriptor */ | |
| 319 struct servent *sp; /* pointer to service information */ | |
| 320 struct sockaddr_in peeraddr_in; /* for peer socket address */ | |
| 321 char buf[512]; /* temporary buffer */ | |
| 322 | |
| 323 /* clear out address structures */ | |
| 324 memset((char *)&peeraddr_in,0,sizeof(struct sockaddr_in)); | |
| 325 | |
| 326 /* Set up the peer address to which we will connect. */ | |
| 327 peeraddr_in.sin_family = AF_INET; | |
| 328 | |
| 329 /* look up the server host's internet address */ | |
| 647 | 330 if ((peeraddr_in.sin_addr.s_addr = internet_addr (serverhost)) == |
| 331 (unsigned int) -1) | |
| 332 { | |
| 333 fprintf (stderr, "%s: unable to find %s in /etc/hosts or from YP\n", | |
| 334 progname, serverhost); | |
| 335 exit(1); | |
| 336 } | |
| 428 | 337 |
| 338 if (port == 0) { | |
| 339 if ((sp = getservbyname ("gnuserv","tcp")) == NULL) | |
| 340 peeraddr_in.sin_port = htons(DEFAULT_PORT+getuid()); | |
| 341 else | |
| 342 peeraddr_in.sin_port = sp->s_port; | |
| 343 } /* if */ | |
| 344 else | |
| 345 peeraddr_in.sin_port = htons(port); | |
| 346 | |
| 347 /* Create the socket. */ | |
| 348 if ((s = socket (AF_INET,SOCK_STREAM, 0))== -1) { | |
| 349 perror(progname); | |
| 350 fprintf(stderr,"%s: unable to create socket\n",progname); | |
| 351 exit(1); | |
| 352 }; /* if */ | |
| 353 | |
| 354 /* Try to connect to the remote server at the address | |
| 355 * which was just built into peeraddr. | |
| 356 */ | |
| 357 if (connect(s, (struct sockaddr *)&peeraddr_in, | |
| 358 sizeof(struct sockaddr_in)) == -1) { | |
| 359 perror(progname); | |
| 360 fprintf(stderr, "%s: unable to connect to remote\n",progname); | |
| 361 exit(1); | |
| 362 }; /* if */ | |
| 363 | |
| 364 #ifdef AUTH_MAGIC_COOKIE | |
| 365 | |
| 366 /* send credentials using MIT-MAGIC-COOKIE-1 protocol */ | |
| 367 | |
| 368 server_xauth = | |
| 369 XauGetAuthByAddr(FamilyInternet, | |
| 370 sizeof(peeraddr_in.sin_addr.s_addr), | |
| 371 (char *) &peeraddr_in.sin_addr.s_addr, | |
| 372 strlen(MCOOKIE_SCREEN), MCOOKIE_SCREEN, | |
| 373 strlen(MCOOKIE_X_NAME), MCOOKIE_X_NAME); | |
| 374 | |
| 375 if (server_xauth && server_xauth->data) { | |
| 376 sprintf(buf, "%s\n%d\n", MCOOKIE_NAME, server_xauth->data_length); | |
| 377 write (s, buf, strlen(buf)); | |
| 378 write (s, server_xauth->data, server_xauth->data_length); | |
| 379 | |
| 380 return (s); | |
| 381 } | |
| 382 | |
| 383 #endif /* AUTH_MAGIC_COOKIE */ | |
| 384 | |
| 385 sprintf (buf, "%s\n", DEFAUTH_NAME); | |
| 386 write (s, buf, strlen(buf)); | |
| 387 | |
| 388 return(s); | |
| 389 | |
| 390 } /* connect_to_internet_server */ | |
| 391 #endif /* INTERNET_DOMAIN_SOCKETS */ | |
| 392 | |
| 393 | |
| 394 #if defined(INTERNET_DOMAIN_SOCKETS) || defined(UNIX_DOMAIN_SOCKETS) | |
| 395 /* | |
| 396 disconnect_from_server -- inform the server that sending has finished, and wait for | |
| 397 its reply. | |
| 398 */ | |
| 440 | 399 void |
| 400 disconnect_from_server (int s, int echo) | |
| 428 | 401 { |
| 402 #if 0 | |
| 403 char buffer[REPLYSIZ+1]; | |
| 404 #else | |
| 405 char buffer[GSERV_BUFSZ+1]; | |
| 406 #endif | |
| 407 int add_newline = 1; | |
| 408 int length; | |
| 409 | |
| 410 send_string(s,EOT_STR); /* make sure server gets string */ | |
| 411 | |
| 412 #if !defined (linux) && !defined (_SCO_DS) | |
| 413 /* | |
| 414 * shutdown is completely hozed under linux. If s is a unix domain socket, | |
| 415 * you'll get EOPNOTSUPP back from it. If s is an internet socket, you get | |
| 416 * a broken pipe when you try to read a bit later. The latter | |
| 417 * problem is fixed for linux versions >= 1.1.46, but the problem | |
| 418 * with unix sockets persists. Sigh. | |
| 419 */ | |
| 420 | |
| 421 if (shutdown(s,1) == -1) { | |
| 422 perror(progname); | |
| 423 fprintf(stderr, "%s: unable to shutdown socket\n",progname); | |
| 424 exit(1); | |
| 425 }; /* if */ | |
| 426 #endif | |
| 427 | |
| 428 #if 0 | |
| 429 while((length = recv(s,buffer,REPLYSIZ,0)) > 0) { | |
| 430 buffer[length] = '\0'; | |
| 431 if (echo) fputs(buffer,stdout); | |
| 432 add_newline = (buffer[length-1] != '\n'); | |
| 433 }; /* while */ | |
| 434 #else | |
| 435 while ((length = read(s,buffer,GSERV_BUFSZ)) > 0 || | |
| 436 (length == -1 && errno == EINTR)) { | |
| 437 if (length) { | |
| 438 buffer[length] = '\0'; | |
| 439 if (echo) { | |
| 440 fputs(buffer,stdout); | |
| 441 add_newline = (buffer[length-1] != '\n'); | |
| 442 }; /* if */ | |
| 443 }; /* if */ | |
| 444 }; /* while */ | |
| 445 #endif | |
| 446 | |
| 447 if (echo && add_newline) putchar('\n'); | |
| 448 | |
| 449 if(length < 0) { | |
| 450 perror(progname); | |
| 451 fprintf(stderr,"%s: unable to read the reply from the server\n",progname); | |
| 452 exit(1); | |
| 453 }; /* if */ | |
| 454 | |
| 455 } /* disconnect_from_server */ | |
| 456 #endif /* INTERNET_DOMAIN_SOCKETS || UNIX_DOMAIN_SOCKETS */ |
