Article 112521 of comp.os.vms:
It appears that the file I posted had some 'extra characters' added to
it.  Below is the source file, cut/pasted into the Netscape news editor
(before I used attach file).

Sorry about the mess up.
-- 
-----------------------------------------------------------------------
Brian J. McCarthy                  | mailto:mccarthy@hndymn.zko.dec.com
Digital Equipment Corp. Nashua, NH | DEC CRTL/DEC C++ Class Libraries
-----------------------------------------------------------------------
---------------------------- cut here -------------------------------
/* -*- Mode:C; tab-width: 8 -*-
 * remote.c --- remote control of Netscape Navigator for Unix and
OpenVMS
 * version 1.1.3, for Netscape Navigator 1.1 and newer.
 *
 * Copyright © 1996 Netscape Communications Corporation, all rights
reserved.
 * Created: Jamie Zawinski <jwz@netscape.com>, 24-Dec-94.
 *
 * Permission to use, copy, modify, distribute, and sell this software
and its
 * documentation for any purpose is hereby granted without fee, provided
that
 * the above copyright notice appear in all copies and that both that
 * copyright notice and this permission notice appear in supporting
 * documentation.  No representations are made about the suitability of
this
 * software for any purpose.  It is provided "as is" without express or
 * implied warranty.
 *
 * To compile (UNIX):
 *
 *    cc -o netscape-remote remote.c -DSTANDALONE -lXmu -lX11
 *
 * To use (UNIX):
 *
 *    netscape-remote -help
 *
 * To compile: (OpenVMS Alpha)
 *    cc /define=standalone netscape_remote/prefi=all
 *    link netscape_remote,sys$input:/opt
 *    sys$share:decw$xlibshr/share
 *    sys$share:decw$xmulibshr/share
 *    <ctrl/z>
 *
 * To compile: (OpenVMS VAX)
 *   cc /define=standalone netscape_remote/prefi=all/stand=vaxc
 *   link netscape_remote,sys$input:/opt
 *   sys$share:decw$xlibshr/share
 *   sys$share:decw$xmulibshr/share
 *  <ctrl/z>
 *
 * To use (OpenVMS):
 *
 *   $ NETSCAPE_REMOTE :== $SYS$DISK:[]NETSCAPE_REMOTE.EXE
 *                       OR on V6.2 systems and greater:
 *   $ DEFINE DCL$PATH SYS$DISK:[]
 *
 *   $ netscape_remote -help
 *
 * Documentation for the protocol which this code implements may be
found at:
 *
 *    http://home.netscape.com/newsref/std/x-remote.html
 *
 * Bugs and commentary to x_cbug@netscape.com.
 *
 * Modified by:
 *
 *   x.x                mccarthy@hndymn.zko.dec.com             Oct,
1996
 *      - Added support and comments for compiling on OpenVMS platforms.
 *      - Added check for number of command options == 0 before trying
to
 *        execute commands (resulted in locked window and access
violation)
 *      - Added WARN_VERSION define (I don't care if its running
something
 *        besides 1.1, hell 3.0 is out the door now)
 *      - Changed exit() calls (most of them) to use EXIT_SUCCESS or
 *        EXIT_FAILURE
 *      - Added call to get icon name to make sure the message
 *        was being sent to the browser and not the news or
 *        mail windows (which caused a new browser window
 *        to be displayed).
 *      - Added help for -sync option
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#ifdef __VMS
#if __VMS_VER >= 70000000
#include <strings.h>            /* strcasecmp */
#else
#define strcasecmp my_strcasecmp
#include <types.h>
static const u_char charmap[] = {
  #if __VMS_VER >= 70000000
#include <strings.h>            /* strcasecmp */
#else
#define strcasecmp my_strcasecmp
#include <types.h>
static const u_char charmap[] = {
        '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007',
        '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017',
        '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027',
        '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037',
        '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047',
        '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057',
        '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067',
        '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077',
        '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
        '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
        '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
        '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137',
        '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147',
        '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157',
        '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167',
        '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177',
        '\200', '\201', '\202', '\203', '\204', '\205', '\206', '\207',
        '\210', '\211', '\212', '\213', '\214', '\215', '\216', '\217',
        '\220', '\221', '\222', '\223', '\224', '\225', '\226', '\227',
        '\230', '\231', '\232', '\233', '\234', '\235', '\236', '\237',
        '\240', '\241', '\242', '\243', '\244', '\245', '\246', '\247',
        '\250', '\251', '\252', '\253', '\254', '\255', '\256', '\257',
        '\260', '\261', '\262', '\263', '\264', '\265', '\266', '\267',
        '\270', '\271', '\272', '\273', '\274', '\275', '\276', '\277',
        '\300', '\301', '\302', '\303', '\304', '\305', '\306', '\307',
        '\310', '\311', '\312', '\313', '\314', '\315', '\316', '\317',
        '\320', '\321', '\322', '\323', '\324', '\325', '\326', '\327',
        '\330', '\331', '\332', '\333', '\334', '\335', '\336', '\337',
        '\340', '\341', '\342', '\343', '\344', '\345', '\346', '\347',
        '\350', '\351', '\352', '\353', '\354', '\355', '\356', '\357',
        '\360', '\361', '\362', '\363', '\364', '\365', '\366', '\367',
        '\370', '\371', '\372', '\373', '\374', '\375', '\376', '\377',
};

typedef char * __wide_char_ptr;
typedef const char * __wide_const_char_ptr;
typedef unsigned char   __u_char;
typedef __u_char * __wide_u_char_ptr;
typedef const __u_char * __wide_const_u_char_ptr;

int
my_strcasecmp(__wide_const_char_ptr s1, __wide_const_char_ptr s2)
{
register __wide_const_u_char_ptr cm = charmap,
   us1 = (const u_char *)s1,
   us2 = (const u_char *)s2;

   while (cm[*us1] == cm[*us2++])
        if (*us1++ == '\0')
           return (0);
   return (cm[*us1] - cm[*--us2]);
}

#endif          /* vms version less than 7.0 */
#endif

#include <X11/Xlib.h>
#include <X11/Xatom.h>
#ifndef __VMS
#include <X11/Xmu/WinUtil.h>    /* for XmuClientWindow() */
#else
/* bring header right in line */
/* xmuclientwindow() exists in decw$xmulibshrr5 and decw$xmulibshr */
/* so be sure to add that to your linker options file */
/*
 * $XConsortium: WinUtil.h,v 1.3 89/09/22 12:10:20 jim Exp $
 *
 * Copyright 1988 by the Massachusetts Institute of Technology
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose and without fee is hereby granted,
provided
 * that the above copyright notice appear in all copies and that both
that
 * copyright notice and this permission notice appear in supporting
 * documentation, and that the name of M.I.T. not be used in advertising
 * or publicity pertaining to distribution of the software without
specific,
 * written prior permission. M.I.T. makes no representations about the
 * suitability of this software for any purpose.  It is provided "as is"
 * without express or implied warranty.
 *
 * The X Window System is a Trademark of MIT.
 *
 * The interfaces described by this header file are for miscellaneous
utilities
 * and are not part of the Xlib standard.
 */

#ifndef _XMU_WINDOWUTIL_H_
#define _XMU_WINDOWUTIL_H_

extern Window XmuClientWindow();
extern Bool XmuUpdateMapHints();
extern Screen *XmuScreenOfWindow();

#endif /* _XMU_WINDOWUTIL_H_ */

#endif


/* vroot.h is a header file which lets a client get along with `virtual
root'
   window managers like swm, tvtwm, olvwm, etc.  If you don't have this
header
   file, you can find it at
"http://home.netscape.com/newsref/std/vroot.h".
   If you don't care about supporting virtual root window managers, you
can
   comment this line out.
 */
#ifndef __VMS
#include "vroot.h"
#endif

#ifdef STANDALONE
 static const char *progname = 0;
 static const char *expected_mozilla_version = "1.1";
#else  /* !STANDALONE */
 extern const char *progname;
 extern const char *expected_mozilla_version;
#endif /* !STANDALONE */

#define MOZILLA_VERSION_PROP   "_MOZILLA_VERSION"
#define MOZILLA_LOCK_PROP      "_MOZILLA_LOCK"
#define MOZILLA_COMMAND_PROP   "_MOZILLA_COMMAND"
#define MOZILLA_RESPONSE_PROP  "_MOZILLA_RESPONSE"
static Atom XA_MOZILLA_VERSION  = 0;
static Atom XA_MOZILLA_LOCK     = 0;
static Atom XA_MOZILLA_COMMAND  = 0;
static Atom XA_MOZILLA_RESPONSE = 0;

static void
mozilla_remote_init_atoms (Display *dpy)
{
  if (! XA_MOZILLA_VERSION)
    XA_MOZILLA_VERSION = XInternAtom (dpy, MOZILLA_VERSION_PROP, False);
  if (! XA_MOZILLA_LOCK)
    XA_MOZILLA_LOCK = XInternAtom (dpy, MOZILLA_LOCK_PROP, False);
  if (! XA_MOZILLA_COMMAND)
    XA_MOZILLA_COMMAND = XInternAtom (dpy, MOZILLA_COMMAND_PROP, False);
  if (! XA_MOZILLA_RESPONSE)
    XA_MOZILLA_RESPONSE = XInternAtom (dpy, MOZILLA_RESPONSE_PROP,
False);
}

static Window
mozilla_remote_find_window (Display *dpy)
{
  int i;
  Window root = RootWindowOfScreen (DefaultScreenOfDisplay (dpy));
  Window root2, parent, *kids;
  unsigned int nkids;
  Window result = 0;
  Window tenative = 0;
  Window non_netscape = 0;
  unsigned char *tenative_version = 0;

  if (! XQueryTree (dpy, root, &root2, &parent, &kids, &nkids))
    {
      fprintf (stderr, "%s: XQueryTree failed on display %s\n",
progname,
               DisplayString (dpy));
      exit (2);
    }

  /* root != root2 is possible with virtual root WMs. */

  if (! (kids && nkids))
    {
      fprintf (stderr, "%s: root window has no children on display
%s\n",
               progname, DisplayString (dpy));
      exit (2);
    }

  for (i = nkids-1; i >= 0; i--) {
    Atom type;
    int format;
    unsigned long nitems, bytesafter;
    unsigned char *version = 0;
    char *icon_name = 0;
    Window w = XmuClientWindow (dpy, kids[i]);
    int status = XGetWindowProperty (dpy, w, XA_MOZILLA_VERSION,
                                       0, (65536 / sizeof (long)),
                                       False, XA_STRING,
                                       &type, &format, &nitems,
&bytesafter,
                                       &version);
    if (! version)
      /* Didn't get the XA_MOZILLA_VERSION atom back */
      continue;

    if (XGetIconName (dpy, w, &icon_name) ) {
      if (strncmp (icon_name, "Netscape:", strlen("Netscape:")) != 0) {
        /*
        ** If the icon name is not Netscape, skip it
        ** it could be "News" or "Mail" or some other window
        ** that Netscape created, store away its value though,
        ** because if we don't find a Netscape browser window
        ** around, this window will do.
        */
        non_netscape = w;
        XFree (icon_name);
        continue;
      } else {
        /* The icon name started with Netscape */
        XFree (icon_name);
      }
    } /* end of check for getting icon name */

    if (strcmp ((char *) version, expected_mozilla_version) &&
              !tenative) {
      tenative = w;
      tenative_version = version;
      continue;
    }
    XFree (version);
    if (status == Success && type != None) {
      result = w;
      break;
    }
  } /* End of loop for all the children */

  if (result && tenative) {
      fprintf (stderr,
               "%s: warning: \nboth version %s (0x%x) and version\n"
               "\t%s (0x%x) are running.\n  Using version %s.\n",
               progname, tenative_version, (unsigned int) tenative,
               expected_mozilla_version, (unsigned int) result,
               expected_mozilla_version);
      XFree (tenative_version);
      return result;
  } else {
    if (tenative) {
#ifdef WARN_VERSION
        fprintf (stderr,
               "%s: warning: expected version %s but found version\n"
            continue;
      } else {
        /* The icon name started with Netscape */
        XFree (icon_name);
      }
    } /* end of check for getting icon name */

    if (strcmp ((char *) version, expected_mozilla_version) &&
              !tenative) {
      tenative = w;
      tenative_version = version;
      continue;
    }
    XFree (version);
    if (status == Success && type != None) {
      result = w;
      break;
    }
  } /* End of loop for all the children */

  if (result && tenative) {
      fprintf (stderr,
               "%s: warning: \nboth version %s (0x%x) and version\n"
               "\t%s (0x%x) are running.\n  Using version %s.\n",
               progname, tenative_version, (unsigned int) tenative,
               expected_mozilla_version, (unsigned int) result,
               expected_mozilla_version);
      XFree (tenative_version);
      return result;
  } else {
    if (tenative) {
#ifdef WARN_VERSION
        fprintf (stderr,
               "%s: warning: expected version %s but found version\n"
               "\t%s (0x%x) instead.\n",
               progname, expected_mozilla_version,
               tenative_version, (unsigned int) tenative);
#endif
      XFree (tenative_version);
      return tenative;
    } else {
      if (result) {
        return result;
      } else {
        if (non_netscape) {
          /*
          ** Found a non-browser window, sending
          ** the command to that window will
          ** have the desired effect.
          */
          return non_netscape;
        } else {
          fprintf (stderr, "%s: netscape not running on display %s\n",
progname,
               DisplayString (dpy));
          exit (EXIT_SUCCESS);
        }
      }
    }
  }
}

static void
mozilla_remote_check_window (Display *dpy, Window window)
{
  Atom type;
  int format;
  unsigned long nitems, bytesafter;
  unsigned char *version = 0;
  int status = XGetWindowProperty (dpy, window, XA_MOZILLA_VERSION,
                                   0, (65536 / sizeof (long)),
                                   False, XA_STRING,
                                   &type, &format, &nitems, &bytesafter,
                                   &version);
  if (status != Success || !version)
    {
      fprintf (stderr, "%s: window 0x%x is not a Netscape window.\n",
               progname, (unsigned int) window);
      exit (6);
    }
  else if (strcmp ((char *) version, expected  int status = XGetWindowProperty (dpy, window, XA_MOZILLA_VERSION,
                                   0, (65536 / sizeof (long)),
                                   False, XA_STRING,
                                   &type, &format, &nitems, &bytesafter,
                                   &version);
  if (status != Success || !version)
    {
      fprintf (stderr, "%s: window 0x%x is not a Netscape window.\n",
               progname, (unsigned int) window);
      exit (6);
    }
  else if (strcmp ((char *) version, expected_mozilla_version))
    {
#ifdef WARN_VERSION
      fprintf (stderr,
               "%s: warning: window 0x%x is Netscape version %s;\n"
               "\texpected version %s.\n",
               progname, (unsigned int) window,
               version, expected_mozilla_version);
#endif
    }
  XFree (version);
}


static char *lock_data = 0;

static void
mozilla_remote_obtain_lock (Display *dpy, Window window)
{
  Bool locked = False;
  Bool waited = False;

  if (! lock_data)
    {
      lock_data = (char *) malloc (255);
      sprintf (lock_data, "pid%d@", getpid ());
      if (gethostname (lock_data + strlen (lock_data), 100))
        {
          perror ("gethostname");
          exit (EXIT_FAILURE);
        }
    }

  do
    {
      int result;
      Atom actual_type;
      int actual_format;
      unsigned long nitems, bytes_after;
      unsigned char *data = 0;

      XGrabServer (dpy);   /* ################################# DANGER!
*/

      result = XGetWindowProperty (dpy, window, XA_MOZILLA_LOCK,
                                   0, (65536 / sizeof (long)),
                                   False, /* don't delete */
                                   XA_STRING,
                                   &actual_type, &actual_format,
                                   &nitems, &bytes_after,
                                   &data);
      if (result != Success || actual_type == None)
        {
          /* It's not now locked - lock it. */
#ifdef DEBUG_PROPS
          fprintf (stderr, "%s: (writing " MOZILLA_LOCK_PROP
                   " \"%s\" to 0x%x)\n",
                   progname, lock_data, (unsigned int) window);
#endif
          XChangeProperty (dpy, window, XA_MOZILLA_LOCK, XA_STRING, 8,
                           PropModeReplace, (unsigned char *) lock_data,
                           strlen (lock_data));
          locked = True;
        }

      XUngrabServer (dpy); /* ################################# danger
over */
      XSync (dpy, False);

      if (! locked)
        {
          /* We tried to grab the lock this time, and failed because
someone
             else is holding it already.  So, wait for a PropertyDelete
event
             to come in, and try again. */

          fprintf (stderr, "%s: window 0x%x is locked by %s;
waiting...\n",
                   progname, (unsigned int) window, data);
          waited = True;

          while (1)
            {
              XEvent event;
              XNextEvent (dpy, &event);
              if (event.xany.type == DestroyNotify &&
                  event.xdestroywindow.window == window)
                {
                  fprintf (stderr, "%s: window 0x%x unexpectedly
destroyed.\n",
                           progname, (unsigned int) window);
                  exit (6);
                }
              else if (event.xany.type == PropertyNotify &&
                       event.xproperty.state == PropertyDelete &&
                       event.xproperty.window == window &&
                       event.xproperty.atom == XA_MOZILLA_LOCK)
                {
                  /* Ok!  Someone deleted their lock, so now we can try
                     again. */
#ifdef DEBUG_PROPS
                  fprintf (stderr, "%s: (0x%x unlocked, trying
again...)\n",
                           progname, (unsigned int) window);
#endif
                  break;
                }
            }
        }
      if (data)
        XFree (data);
    }
  while (! locked);

  if (waited)
    fprintf (stderr, "%s: obtained lock.\n", progname);
}


static void
mozilla_remote_free_lock (Display *dpy, Window window)
{
  int result;
  Atom actual_type;
  int actual_format;
  unsigned long nitems, bytes_after;
  unsigned char *data = 0;

#ifdef DEBUG_PROPS
          fprintf (stderr, "%s: (deleting " MOZILLA_LOCK_PROP
                   " \"%s\" from 0x%x)\n",
                   progname, lock_data, (unsigned int) window);
#endif

  result = XGetWindowProperty (dpy, window, XA_MOZILLA_LOCK,
                               0, (65536 / sizeof (long)),
                               True, /* atomic delete after */
                               XA_STRING,
                               &actual_type, &actual_format,
                               &nitems, &bytes_after,
                               &data);
  if (result != Success)
    {
      fprintf (stderr, "%s: unable to read and delete "
MOZILLA_LOCK_PROP
               " property\n",
               progname);
      return;
    }
  else if (!data || !*data)
    {
      fprintf (stderr, "%s: invalid data on " MOZILLA_LOCK_PROP
               " of window 0x%x.\n",
               progname, (unsigned int) window);
      return;
    }
  else if (strcmp ((char *) data, lock_data))
    {
      fprintf (stderr, "%s: " MOZILLA_LOCK_PROP
               " was stolen!  Expected \"%s\", saw \"%s\"!\n",
               progname, lock_data, data);
      return;
    }

  if (data)
    XFree (data);
}


static int
mozilla_remote_command (Display *dpy, Window window, const char
*command,
                        Bool raise_p)
{
  int result;
  Bool done = False;
  char *new_command = 0;

  /* The -noraise option is implemented by passing a "noraise" argument
     to each command to which it should apply.
   */
  if (! raise_p)
    {
      char *close;
      new_command = (char *) malloc (strlen (command) + 20);
      strcpy (new_command, command);
      close = strrchr (new_command, ')');
      if (close)
        strcpy (close, ", noraise)");
      else
        strcat (new_command, "(noraise)");
      command = new_command;
    }

#ifdef DEBUG_PROPS
  fprintf (stderr, "%s: (writing " MOZILLA_COMMAND_PROP " \"%s\" to
0x%x)\n",
           progname, command, (unsigned int) window);
#endif

  XChangeProperty (dpy, window, XA_MOZILLA_COMMAND, XA_STRING, 8,
                   PropModeReplace, (unsigned char *) command,
                   strlen (command));

  while (!done)
    {
      XEvent event;
      XNextEvent (dpy, &event);
      if (event.xany.type == DestroyNotify &&
          event.xdestroywindow.window == window)
        {
          /* Print to warn user...*/
          fprintf (stderr, "%s: window 0x%x was destroyed.\n",
                   progname, (unsigned int) window);
          result = 6;
          goto DONE;
        }
      else if (event.xany.type == PropertyNotify &&
               event.xproperty.state == PropertyNewValue &&
               event.xproperty.window == window &&
               event.xproperty.atom == XA_MOZILLA_RESPONSE)
        {
          Atom actual_type;
          int actual_format;
          unsigned long nitems, bytes_after;
          unsigned char *data = 0;

          result = XGetWindowProperty (dpy, window, XA_MOZILLA_RESPONSE,
                                       0, (65536 / sizeof (long)),
                                       True, /* atomic delete after */
                                       XA_STRING,
                                       &actual_type, &actual_format,
                                       &nitems, &bytes_after,
                                       &data);
#ifdef DEBUG_PROPS
          if (result == Success && data && *data)
            {
              fprintf (stderr, "%s: (server sent " MOZILLA_RESPONSE_PROP
                       " \"%s\" to 0x%x.)\n",
                       progname, data, (unsigned int) window);
            }
#endif

          if (result != Success)
            {
              fprintf (stderr, "%s: failed reading "
MOZILLA_RESPONSE_PROP
                       " from window 0x%0x.\n",
                       progname, (unsigned int) window);
              result = 6;
              done = True;
            }
          else if (!data || strlen((char *) data) < 5)
            {
              fprintf (stderr, "%s: invalid data on "
MOZILLA_RESPONSE_PROP
                       " property of window 0x%0x.\n",
                       progname, (unsigned int) window);
              result = 6;
              done = True;
            }
          else if (*data == '1')        /* positive preliminary reply */
            {
              fprintf (stderr, "%s: %s\n", progname, data + 4);
              /* keep going */
              done = False;
            }
#if 1
          else if (!strncmp ((char *)data, "200", 3)) /* positive
completion */
            {
              result = 0;
              done = True;
            }
#endif
          else if (*data == '2')                /* positive completion
*/
            {
              fprintf (stderr, "%s: %s\n", progname, data + 4);
              result = 0;
              done = True;
            }
          else if (*data == '3')        /* positive intermediate reply
*/
            {
              fprintf (stderr, "%s: internal error: "
                       "server wants more information?  (%s)\n",
                       progname, data);
              result = 3;
              done = True;
            }
          else if (*data == '4' ||      /* transient negative completion
*/
                   *data == '5')        /* permanent negative completion
*/
            {
              fprintf (stderr, "%s: %s\n", progname, data + 4);
              result = (*data -*/
                   *data == '5')        /* permanent negative completion
*/
            {
              fprintf (stderr, "%s: %s\n", progname, data + 4);
              result = (*data - '0');
              done = True;
            }
          else
            {
              fprintf (stderr,
                       "%s: unrecognised " MOZILLA_RESPONSE_PROP
                       " from window 0x%x: %s\n",
                       progname, (unsigned int) window, data);
              result = 6;
              done = True;
            }

          if (data)
            XFree (data);
        }
#ifdef DEBUG_PROPS
      else if (event.xany.type == PropertyNotify &&
               event.xproperty.window == window &&
               event.xproperty.state == PropertyDelete &&
               event.xproperty.atom == XA_MOZILLA_COMMAND)
        {
          fprintf (stderr, "%s: (server 0x%x has accepted "
                   MOZILLA_COMMAND_PROP ".)\n",
                   progname, (unsigned int) window);
        }
#endif /* DEBUG_PROPS */
    }

 DONE:

  if (new_command)
    free (new_command);

  return result;
}

int
mozilla_remote_commands (Display *dpy, Window window, char **commands)
{
  Bool raise_p = True;
  int status = 0;

  mozilla_remote_init_atoms (dpy);

  if (window == 0)
    window = mozilla_remote_find_window (dpy);
  else
    mozilla_remote_check_window (dpy, window);

  XSelectInput (dpy, window, (PropertyChangeMask|StructureNotifyMask));

  mozilla_remote_obtain_lock (dpy, window);

  while (*commands)
    {
      if (!strcmp (*commands, "-raise"))
        raise_p = True;
      else if (!strcmp (*commands, "-noraise"))
        raise_p = False;
      else
        status = mozilla_remote_command (dpy, window, *commands,
raise_p);

      if (status != 0)
        break;
      commands++;
    }

  /* When status = 6, it means the window has been destroyed */
  /* It is invalid to free the lock when window is destroyed. */

  if ( status != 6 )
    mozilla_remote_free_lock (dpy, window);

  return status;
}


#ifdef STANDALONE

static void
usage (void)
{
  fprintf (stderr, "usage: %s [ options ... ]\n\
       where options include:\n\
\n\
       -help                     to show this message.\n\
       -display <dpy>            to specify the X server to use.\n\
       -remote <remote-command>  to execute a command in an
already-running\n\
                                 Netscape process.  See \n\
                          
http://home.netscape.com/newsref/std/x-remote.html\n\
                                 list of valid commands.\n\
       -id <window-id>           the id of an X window to which the
-remote\n\
                                 commands should be sent; if
unspecified,\n\
                                 the first window found will be used.\n\
       -sync\n\
       -synchronize              Calls XSynchronize () after opening
the\n\
                                 display\n\
       -raise                    whether following -remote commands
should\n\
                                 cause the window to raise itself to the
top\n\
                                 (this is the default.)\n\
       -noraise                  the opposite of -raise: following
-remote\n\
                                 commands will not auto-raise the
window.\n\
",
           progname);
}


void
main (int argc, char **argv)
{
  Display *dpy;
  char *dpy_string = 0;
  char **remote_commands = 0;
  int remote_command_count = 0;
  int remote_command_size = 0;
  unsigned long remote_window = 0;
  Bool sync_p = False;
  int i;

  progname = strrchr (argv[0], '/');
  if (progname)
    progname++;
  else
    progname = argv[0];

  /* Hack the -help and -version arguments before opening the display.
*/
  for (i = 1; i < argc; i++)
    {
      if (!strcasecmp (argv [i], "-h") ||
          !strcasecmp (argv [i], "-help"))
        {
          usage ();
          exit (EXIT_SUCCESS);
        }
      else if (!strcmp (argv [i], "-d") ||
               !strcmp (argv [i], "-dpy") ||
               !strcmp (argv [i], "-disp") ||
               !strcmp (argv [i], "-display"))
        {
          i++;
          dpy_string = argv [i];
        }
      else if (!strcmp (argv [i], "-sync") ||
               !strcmp (argv [i], "-synchronize"))
        {
          sync_p = True;
        }
      else if (!strcmp (argv [i], "-remote"))
        {
          if (remote_command_count == remote_command_size)
            {
              remote_command_size += 20;
              remote_commands =
                (remote_commands
                 ? realloc (remote_commands,
                            remote_command_size * sizeof (char *))
                 : calloc (remote_command_size, sizeof (char *)));
            }
          i++;
          if (!argv[i] || *argv[i] == '-' || *argv[i] == 0)
            {
              fprintf (stderr, "%s: invalid `-remote' option \"%s\"\n",
                       progname, argv[i] ? argv[i] : "");
              usage ();
              exit (EXIT_FAILURE);
            }
          remote_commands [remote_command_count++] = argv[i];
        }
      else if (!strcmp (argv [i], "-raise") ||
               !strcmp (argv [i], "-noraise"))
        {
          char *r = argv [i];
          if (remote_command_count == remote_command_size)
            {
              remote_command_size += 20;
              remote_commands =
                (remote_commands
                 ? realloc (remote_commands,
                            remote_command_size * sizeof (char *))
                 : calloc (remote_command_size, sizeof (char *)));
            }
          remote_commands [remote_command_count++] = r;
        }
      else if (!strcmp (argv [i], "-id"))
        {
          char c;
          if (remote_command_count > 0)
            {
              fprintf (stderr,
                "%s: the `-id' option must preceed all `-remote'
options.\n",
                       progname);
              usage ();
              exit (EXIT_FAILURE);
            }
          else if (remote_window != 0)
            {
              fprintf (stderr, "%s: only one `-id' option may be
used.\n",
                       progname);
              usage ();
              exit (EXIT_FAILURE);
            }
          i++;
          if (argv[i] &&
              1 == sscanf (argv[i], " %ld %c", &remote_window, &c))
            ;
          else if (argv[i] &&
                   1 == sscanf (argv[i], " 0x%lx %c", &remote_window,
&c))
            ;
          else
            {
              fprintf (stderr, "%s: invalid `-id' option \"%s\"\n",
                       progname, argv[i] ? argv[i] : "");
              usage ();
              exit (EXIT_FAILURE);
            }
        }
    }

    if ( remote_command_count == 0)  {
        fprintf (stderr, "No options on command line\n");
        usage ();
        exit (EXIT_FAILURE);
    }

  dpy = XOpenDisplay (dpy_string);
  if (! dpy)
    exit (EXIT_FAILURE);

  if (sync_p)
    XSynchronize (dpy, True);

  exit (mozilla_remote_commands (dpy, (Window) remote_window,
                                 remote_commands));
}

#endif /* STANDALONE */


---------------------------- end ------------------------------------


