Back to index

im-sdk  12.3.91
Classes | Defines | Typedefs | Enumerations | Functions | Variables
watchdog.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <locale.h>
#include <nl_types.h>
#include <X11/Intrinsic.h>
#include <X11/Xlibint.h>
#include <X11/StringDefs.h>
#include <X11/Xatom.h>
#include "watchdog.h"

Go to the source code of this file.

Classes

struct  _RmDatabase

Defines

#define HTT_CLASS_NAME   "Iiimx"
#define PATH_MAX   1024
#define OPENWINHOME   "/usr/openwin"
#define OPENWIN_MOTIF_PRELOAD_ENV   "LD_PRELOAD=/usr/dt/lib/libXm.so.3"
#define IMDIR   IIIMLIBDIR
#define NL_HTT_SETD   3
#define nl_msg(msg_num, msg)   (msg)
#define OPENWIN_PATH   1

Typedefs

typedef struct _RmDatabase RmDatabase

Enumerations

enum  ServerStatus { RmServerActive = 1, RmServerReset = 2, RmServerKilled = 3 }

Functions

static void start_htt_server (int *, char *argv[])
static void start_htt_props (int *, char *argv[])
static void start_iiimd (int *, char **argv)
static Bool build_dir (const char *, mode_t)
static char * build_uds_filename (Widget)
static char * build_vardir_dirname (void)
static char ** build_iiimd_arg (char *, char *)
static void proc_exit (int)
static void clean_up (int)
static void parse_command (int, char **)
static char * build_cmdline_db (Widget toplevel, char *argv[], int argc, Bool replace_mode)
static char * get_home_dir (char *buf)
static char * get_host (char *buf, int max_len)
int main (int argc, argv)
int check_openwin_path (char *prg, char *oppath, char *result)
int search_program (char *prg, char *path)
void start_htt_server (int *htt_server_pid, argv)
void start_htt_props (int *htt_props_pid, argv)
static void usage (void)

Variables

static char * htt_props_path = "htt_props"
static ServerStatus Server_Status = RmServerActive
static int htt_server_pid
static int htt_props_pid
static int iiimd_pid
static Atom htt_atom
static Atom server_atom
static Atom props_atom
static Atom resource_atom
static Atom cmdline_atom
static Atom htt_server_reset_atom
static Atom htt_watchdog_atom
static Atom class_atom
static Display * display
static Window httw_id
static Bool spawn_props = True
static char ** htt_server_arg
static char ** htt_props_arg
static char ** iiimd_arg
static int htt_server_killed = 0
static RmDatabase my_rdb
static XtResource rdb_items []
static XrmOptionDescRec rdb_options []
static int NUM_RDB_OPTIONS = XtNumber(rdb_options)

Class Documentation

struct _RmDatabase

Definition at line 47 of file ResourceDB.hh.

Class Members
unsigned long background
char * conv_keys
Bool disable_status_area
char * fontset
unsigned long foreground
Bool has_decoration
Bool has_lookup_title
Bool has_root_title
char * hotkey_string
char * htt_server_name
char * if_name
char * lookup_bg_str
int lookup_columns
char * lookup_fg_str
char * lookup_label
char * lookup_place
char * lookup_policy
char * lookup_position
int lookup_rows
char * lookup_title
char * lookup_window
char * port_number
char * preedit_move
Bool preedit_usearrow
Bool respond_to_sm
char * root_display
char * root_geom
char * root_layout
char * root_place
char * root_position
char * root_status_geom
char * root_title
Bool start_iiimd
Bool start_props
Bool static_event_flow
int status_max_width
char * status_place
char * status_position
Bool support_iiimp
Bool support_ximp40
char * udsfile
Bool use_default_colors
Bool use_iiim_props
char * vardir

Define Documentation

#define HTT_CLASS_NAME   "Iiimx"

Definition at line 65 of file watchdog.c.

#define IMDIR   IIIMLIBDIR

Definition at line 84 of file watchdog.c.

#define NL_HTT_SETD   3

Definition at line 100 of file watchdog.c.

#define nl_msg (   msg_num,
  msg 
)    (msg)

Definition at line 117 of file watchdog.c.

#define OPENWIN_MOTIF_PRELOAD_ENV   "LD_PRELOAD=/usr/dt/lib/libXm.so.3"

Definition at line 82 of file watchdog.c.

#define OPENWIN_PATH   1

Definition at line 724 of file watchdog.c.

#define OPENWINHOME   "/usr/openwin"

Definition at line 80 of file watchdog.c.

#define PATH_MAX   1024

Definition at line 76 of file watchdog.c.


Typedef Documentation

typedef struct _RmDatabase RmDatabase

Enumeration Type Documentation

Enumerator:
RmServerActive 
RmServerReset 
RmServerKilled 

Definition at line 102 of file watchdog.c.


Function Documentation

static char * build_cmdline_db ( Widget  toplevel,
char *  argv[],
int  argc,
Bool  replace_mode 
) [static]

Definition at line 1022 of file watchdog.c.

{
  char            filenamebuf[PATH_MAX], *filename = filenamebuf;
  static XrmDatabase cmd_db;
  FILE           *fd;
  char           *type_return[20];
  XrmValue        val_return;
  char           *lang = NULL;
  int             count;
  int             file_size;
  char           *str_return;
  static XrmQuark RmQString;

  static XrmDatabase db;
  char          **pargv;
  int             pargc;
  Bool            res_status;

  pargc = argc;
  pargv = (char **) Xmalloc(sizeof(char *) * pargc);
  for (count = 0; count < pargc; count++) {
    pargv[count] = Xmalloc(strlen(argv[count]) + 1);
    strcpy(pargv[count], argv[count]);
  }


  RmQString = XrmPermStringToQuark(XtRString);
  db = XtDatabase(XtDisplay(toplevel));
  /* Create db from command line options */
  XrmParseCommand(&cmd_db, rdb_options, NUM_RDB_OPTIONS,
                HTT_CLASS_NAME, &pargc, pargv);

  for (count = 0; count < pargc; count++)
    XFree(pargv[count]);
  Xfree(pargv);

  /* try to get locale of the program */
  res_status = XrmGetResource(db, "iiimx*language",
                           "Iiimx*Language", type_return, &val_return);

  if (res_status && (char *) val_return.addr) {
    int             len = strlen((char *) val_return.addr);
    if (len) {
      char            lang_env[256];
      lang = Xmalloc(len + 1);
      strcpy(lang, (char *) val_return.addr);
      setlocale(LC_CTYPE, lang);
      strcpy(lang_env, "LC_CTYPE=");
      strcat(lang_env, lang);
      putenv(lang_env);
    }
  } else
    lang = setlocale(LC_CTYPE, "");

  /* Add options from ~/.httdefaults */
  get_home_dir(filename);
  strcat(filename, ".httdefaults");
  XrmCombineFileDatabase(filename, &cmd_db, False);

  /* Add options from ~/.Xlocale/<lang>/app-defaults/<HTT_CLASS_NAME> */
  get_home_dir(filename);
  strcat(filename, ".Xlocale/");
  strcat(filename, lang);
  strcat(filename, "/app-defaults/");
  strcat(filename, HTT_CLASS_NAME);
  XrmCombineFileDatabase(filename, &cmd_db, replace_mode);

  /* Generate an uniq file name */
  strcpy(filename, "/tmp/HTTXXXXXX");
  mkstemp(filename);
#if 0
  LOG1("resouce file name is %s\n", filename);
#endif

  /* Store the database */
  XrmPutFileDatabase(cmd_db, filename);

  /* If there is no resource the file is empty, or it is not created */
  if ((fd = fopen(filename, "r"))) {
    /* File exists */
    fseek(fd, 0, SEEK_END);
    file_size = ftell(fd);

    str_return = Xmalloc(file_size + 1);
    fseek(fd, 0, SEEK_SET);
    fread(str_return, file_size, 1, fd);
    str_return[file_size] = '\0';
    fclose(fd);
    unlink(filename);
  } else {
    /* File doesn't exist so send empty resource */
    str_return = Xmalloc(1);
    *str_return = '\0';
  }
  return str_return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static Bool build_dir ( const char *  path,
mode_t  mode 
) [static]

Definition at line 852 of file watchdog.c.

{
  struct stat st;
  if (stat(path, &st) < 0) {
    if ((mkdir(path, mode) < 0) || (stat(path, &st) < 0)) {
      return False;
    }
  }
  if ((S_ISDIR(st.st_mode))) {
    return True;
  } else {
    return False;
  }
}

Here is the caller graph for this function:

static char ** build_iiimd_arg ( char *  udsf,
char *  vardir 
) [static]

Definition at line 948 of file watchdog.c.

{
  char **     pargv;
  char **     p;

  pargv = (char **)malloc((sizeof (char *)) * (7));
  p = pargv;

  *(p++) = "iiimd";
  *(p++) = "-nodaemon";
  if (NULL != udsf) {
    *(p++) = "-udsfile";
    *(p++) = udsf;
  }
  if (NULL != vardir) {
    *(p++) = "-vardir";
    *(p++) = vardir;
  }
  *(p++) = NULL;

  return pargv;
}

Here is the caller graph for this function:

static char * build_uds_filename ( Widget  toplevel) [static]

Definition at line 868 of file watchdog.c.

{
  char *             udsf;
  struct passwd *    pw;

  pw = getpwuid(geteuid());
  udsf = (char *)malloc(PATH_MAX);

  if ((NULL == pw) || (NULL == udsf)) {
    endpwent();
    if (NULL != udsf) free(udsf);
    return NULL;
  }

  snprintf(udsf, PATH_MAX, "/tmp/.iiim-%s", pw->pw_name);
  if (False == build_dir(udsf, 0700)){
    endpwent();
    free(udsf);
    return NULL;
  }
  strncat(udsf, "/", PATH_MAX);
  strncat(udsf, DisplayString(XtDisplay(toplevel)), PATH_MAX);

  return udsf;

#if 0
  size_t             len;

  get_home_dir(udsf);

  strncat(udsf, ".iiim", PATH_MAX);
  if (False == build_dir(udsf, 0777)){
      free(udsf);
      return NULL;
  }

  strncat(udsf, "/run", PATH_MAX);
  if (False == build_dir(udsf, 0700)){
      free(udsf);
      return NULL;
  }

  strncat(udsf, "/", PATH_MAX);
  len = strlen(udsf);
  get_host(udsf + len, PATH_MAX - len);
  strncat(udsf, "-", PATH_MAX);
  strncat(udsf, DisplayString(XtDisplay(toplevel)), PATH_MAX);

  return udsf; 
#endif /* 0 */
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char * build_vardir_dirname ( void  ) [static]

Definition at line 921 of file watchdog.c.

{
  char *      vardir;

  vardir = (char *)malloc(PATH_MAX);
  if (NULL == vardir) {
    return NULL;
  }

  get_home_dir(vardir);

  strncat(vardir, ".iiim", PATH_MAX);
  if (False == build_dir(vardir, 0777)){
      free(vardir);
      return NULL;
  }

  strncat(vardir, "/le", PATH_MAX);
  if (False == build_dir(vardir, 0777)){
      free(vardir);
      return NULL;
  }

  return vardir; 
}

Here is the call graph for this function:

Here is the caller graph for this function:

int check_openwin_path ( char *  prg,
char *  oppath,
char *  result 
)

Definition at line 703 of file watchdog.c.

{
  static char suffix[]="/bin/";
  int req;

  if (!oppath) return 0;

  req = strlen(prg) + sizeof(suffix) + 1;

  if (oppath
      && ((strlen(oppath) + sizeof (suffix) + req) < MAXNAMELEN))
    {
      strcpy(result, oppath);
      strcat(result, suffix);
      strcat(result, prg);
      if (access(result, X_OK) == 0) return 1;
    }
  return 0;
}

Here is the caller graph for this function:

void clean_up ( int  unused) [static]

Definition at line 570 of file watchdog.c.

{

  if (my_rdb.start_props) {
    fprintf(stderr,
           nl_msg(NL_HTT_PROPS_STILL_RUNNING,
                 "iiimx : Warning - htt_props is still running use htt_props to kill this server ...\n")
           );
#ifdef SunOS
    sigset(SIGINT, (void (*) (int)) clean_up);
#else
    signal(SIGINT, (void (*) (int)) clean_up);
#endif
    return;
  }
  /*
   * Change server_pid to zero, signal handler sense it that is handled
   * by htt
   */
  htt_server_killed = 1;
  Server_Status = RmServerKilled;
  kill(htt_server_pid, SIGTERM);
  if (my_rdb.start_props)
    kill(htt_props_pid, SIGTERM);
  exit(1);
}

Here is the caller graph for this function:

static char * get_home_dir ( char *  buf) [static]

Definition at line 1120 of file watchdog.c.

                        {
  static char *ptr = NULL;
  int len;

  if (ptr == NULL) {
    uid_t uid;
    struct passwd  *pw;

    if (!(ptr = getenv("HOME"))) {
      if ((ptr = getenv("USER"))) {
       pw = getpwnam(ptr);
      } else {
       uid = getuid();
       pw = getpwuid(uid);
      }
      if (pw) {
       ptr = pw->pw_dir;
      } else {
       ptr = NULL;
       *buf = '\0';
      }
    }
  }
  if (ptr) {
    strcpy(buf, ptr);
  }
  len = strlen(buf);

  if (buf[len - 1] != '/') {
    buf[len] = '/';
    buf[len + 1] = '\0';
  }
  return buf;
}

Here is the caller graph for this function:

static char * get_host ( char *  buf,
int  max_len 
) [static]

Definition at line 1156 of file watchdog.c.

{
  int             len;
  struct utsname  name;

  uname(&name);

  len = strlen(name.nodename);

  if (len >= max_len) {
    len = max_len - 1;
  }
  strncpy(buf, name.nodename, len);
  buf[len] = '\0';

  return buf;
}

Here is the caller graph for this function:

int main ( int  argc,
argv   
)

Definition at line 175 of file watchdog.c.

{
  pid_t           grpid;
  Atom            ret_type;
  int             ret_format;
  unsigned long   nitems, bytes_left;
  char            htt_name[MAXNAMELEN];
  int             screen_no;
  XEvent          ev;
  unsigned long  *tmp; /* must be 'long' to set pid */
  int             i;
  char           *locale;
  char           *cmdline_prop;
  XtAppContext    app;
  Widget          toplevel;
  Atom            htt_save_atom[3];
  int             pid = getpid();
  Atom            host_atom;
  char            hostname_prop[1024];
  Atom            iiim_server_atom;
  char *          uds_filename;
  char *          vardir_dirname;

  setlocale(LC_ALL, "");
#if 0
  htt_message = CreateNLSMessage((char *) 0, NL_HTT_SETD);
#endif

#if 0
  LOG0("watchdog.c:starting htt");
#endif
  /*
   * Setup the signal handlers to monitor htt_server, htt_props
   * abnormal termination
   */
#ifdef SETPGRP_VOID
  grpid = setpgrp();
#else
  grpid = setpgrp(0, 0);
#endif

#ifdef SunOS
  sigset(SIGTERM, clean_up);
  sigset(SIGINT, clean_up);
  sigset(SIGCHLD, proc_exit);
#else
  signal(SIGTERM, clean_up);
  signal(SIGINT, clean_up);
  signal(SIGCHLD, proc_exit);
#endif

#if 0
  LOG0("watchdog.c:Signal handlers set");
#endif
  toplevel = XtVaAppInitialize(&app, HTT_CLASS_NAME,
                            rdb_options, NUM_RDB_OPTIONS,
                            &argc, argv, NULL,
                            NULL);
  XtGetApplicationResources(toplevel, (char *) &my_rdb,
                         rdb_items, XtNumber(rdb_items),
                         0, 0);

  my_rdb.start_props = False;
  my_rdb.respond_to_sm = False;

  /* duplicate again this time to build command line db */
  cmdline_prop = build_cmdline_db(toplevel, argv, argc, False);

  parse_command(argc, argv);

  strcpy(htt_name, HTT_WINDOW_NAME);
  if ((locale = setlocale(LC_CTYPE, NULL)))
    strcat(htt_name, locale);
  else {
    fprintf(stderr,
           nl_msg(NL_HTT_LOCALE_FAIL,
                 "iiimx : Error - locale not supported\n")
           );
    exit(1);
  }

  htt_server_arg = (char **) malloc(sizeof(char *) * (argc + 1));

  htt_props_arg = (char **) malloc(sizeof(char *) * (argc + 3));

  {
    /* htt_server */
    char **pargv = htt_server_arg;
    *pargv++ = my_rdb.htt_server_name;
    for (i = 1; i < argc; i++) {
      *pargv++ = argv[i];
    }
    *pargv = NULL;

    /* htt_props */
    pargv = htt_props_arg;
    *pargv++ = htt_props_path;
    for (i = 1; i < argc; i++) {
      *pargv++ = argv[i];
    }
    *pargv++ = "-lc_basiclocale";
    *pargv++ = locale;
    *pargv = NULL;
  }

  uds_filename = NULL;
  vardir_dirname = NULL;
  if (True == my_rdb.start_iiimd) {
    if (NULL == my_rdb.udsfile) {
      uds_filename = build_uds_filename(toplevel);
    } else {
      uds_filename = my_rdb.udsfile;
    }
    if (NULL == my_rdb.vardir) {
      vardir_dirname = build_vardir_dirname();
    } else {
      vardir_dirname = my_rdb.vardir;
    }
    iiimd_arg = build_iiimd_arg(uds_filename, vardir_dirname);
  }

  /* Obtain display */
  display = XtDisplay(toplevel);
  if (display == NULL) {
    fprintf(stderr,
           nl_msg(NL_HTT_XOPEN_DISPLAY_FAIL,
                 "iiimx : Error - Unable to connect with X server\n"));
    exit(-1);
  }
  /* Create the properties in the display */
  htt_atom = XInternAtom(display, htt_name, False);
  htt_watchdog_atom = XInternAtom(display, HTT_WATCHDOG_PID, False);
  server_atom = XInternAtom(display, HTT_SERVER_PID, False);
  props_atom = XInternAtom(display, HTT_PROPS_PID, False);
  resource_atom = XInternAtom(display, HTT_RESOURCES, False);
  cmdline_atom = XInternAtom(display, HTT_CMDLINE_RESOURCES, False);
  htt_server_reset_atom = XInternAtom(display, HTT_SERVER_RESET, False);
  if (htt_atom == BadAtom)
    fprintf(stderr,
           nl_msg(NL_ATOM_CREATE_FAIL,
                 "iiimx : Warning - Unable to create atom")
           );

  iiim_server_atom = None;
  if (True == my_rdb.start_iiimd) {
    iiim_server_atom = XInternAtom(display, "IIIM_SERVER", False);
  }
  /*
   * If already a version of iiimx is running under same locale , detect
   * it by checking SelectionOwner of HTT_ATOM
   */
  screen_no = DefaultScreen(display);
  httw_id = XGetSelectionOwner(display, htt_atom);
  if (httw_id != None) {
    fprintf(stderr,
           nl_msg(NL_HTT_ALREADY_RUNNING,
                 "iiimx : Error - iiimx is already running...\n")
           );
    exit(-1);
  }
  /* Create the window & make this window as owner of propery htt_atom */
  httw_id = XCreateSimpleWindow(display, RootWindow(display, screen_no),
                            0, 0, 10, 10, 4, 1, 1);

  /* Register WM Protocol */
#if 0
  LOG1("watchdog.c:htt_window_id %x\n", httw_id);
#endif

  htt_save_atom[0] = XInternAtom(display, "_MOTIF_WM_MESSAGES", True);
  htt_save_atom[1] = XInternAtom(display, "WM_DELETE_WINDOW", True);
  htt_save_atom[2] = XInternAtom(display, "WM_SAVE_YOURSELF", True);

  host_atom = XInternAtom(display, "WM_CLIENT_MACHINE", True);
  get_host(hostname_prop, sizeof(hostname_prop));
  XChangeProperty(display, httw_id, host_atom, XA_STRING, 8,
                PropModeReplace, hostname_prop, strlen(hostname_prop));

  class_atom = XInternAtom(display, "WM_CLASS", True);
  XChangeProperty(display, httw_id, class_atom, XA_STRING, 8,
                PropModeReplace, "iiimx", strlen("iiimx"));

  XSetWMProtocols(display, httw_id, (Atom *)&htt_save_atom, 3);

  XSelectInput(display, httw_id, PropertyChangeMask | StructureNotifyMask);
  XSetSelectionOwner(display, htt_atom, httw_id, CurrentTime);

  XChangeProperty(display, httw_id, cmdline_atom, XA_STRING, 8,
                PropModeReplace, cmdline_prop, strlen(cmdline_prop));

  if (True == my_rdb.start_iiimd) {
    char * iiim_server;
    char * iiim_vardir;
    iiim_server = (char *)malloc(PATH_MAX);
    iiim_vardir = (char *)malloc(PATH_MAX);
    snprintf(iiim_server, PATH_MAX, "uds:%s", uds_filename);
    XSetSelectionOwner(display, iiim_server_atom, httw_id, CurrentTime);
    XChangeProperty(display, httw_id, iiim_server_atom, XA_STRING, 8,
                  PropModeReplace, iiim_server, strlen(iiim_server));
    snprintf(iiim_server, PATH_MAX, "IIIM_SERVER=%s,", uds_filename);
    putenv(iiim_server);
    snprintf(iiim_vardir, PATH_MAX, "IIIMD_OPTION_VARDIR=%s", vardir_dirname);
    putenv(iiim_vardir);
    putenv("IIIMD_OPTION_DESKTOP=");
    /* free(iiim_server); */
  }

  XFlush(display);   /* I am not sure it will reach before
                      * htt_server starts so flush explicitly */

  /*
   * Set the PID property and used by htt_props to verify if it is
   * forked from htt
   */
  XChangeProperty(display, httw_id, htt_watchdog_atom, XA_WINDOW, 32,
                PropModeReplace, (unsigned char *)&pid, sizeof(pid));

  /* fork iiimd */
  if (True == my_rdb.start_iiimd) {
    start_iiimd(&iiimd_pid, iiimd_arg);
  }

  /* fork htt_server */
  start_htt_server(&htt_server_pid, htt_server_arg);

  XChangeProperty(display, httw_id, server_atom, XA_WINDOW, 32,
                PropModeReplace,
                (unsigned char *)&htt_server_pid, sizeof(htt_server_pid));
  XFlush(display);


  /* fork htt_props *//* TO DO: conditional fork */
    if (my_rdb.start_props) {
      start_htt_props(&htt_props_pid, htt_props_arg);
      XChangeProperty(display, httw_id, props_atom, XA_WINDOW, 32,
                    PropModeReplace, (unsigned char *)&htt_props_pid,
                    sizeof(htt_props_pid));
      XFlush(display);
    }
    for (;;) {
      XNextEvent(display, &ev);
      switch (ev.type) {
      case PropertyNotify:
       if (ev.xproperty.window == httw_id) {
         if (ev.xproperty.atom == props_atom) {
#if 0
           LOG2("watchdog.c:  property notify event wid = %x atom = %s\n",
               ev.xproperty.window, XGetAtomName(display, ev.xproperty.atom));
#endif
           XGetWindowProperty(display, httw_id,
                            props_atom, 0, 4, False, XA_WINDOW,
                            &ret_type, &ret_format,
                            &nitems, &bytes_left, &tmp);
           if (ret_type == XA_WINDOW) {
             if (*tmp) {
              htt_props_pid = *tmp;
              my_rdb.start_props = 1;
#if 0
              LOG1("watchdog.c:htt_props started pid=%d\n", htt_props_pid);
#endif
             } else {
              my_rdb.start_props = 0;
              htt_props_pid = -1;
              spawn_props = False; /* htt_props spawned by
                                    * htt is killed */
#if 0
              LOG0("watchdog.c:htt_props is killed");
#endif
             }
           }
         } else if (ev.xproperty.atom == server_atom) {
           XGetWindowProperty(display, httw_id,
                            server_atom, 0, 4, False, XA_WINDOW,
                            &ret_type, &ret_format,
                            &nitems, &bytes_left, &tmp);
           if (ret_type == XA_WINDOW)
             if (*tmp) {
              if (htt_server_pid == (*tmp));
              else
                fprintf(stderr,
                       nl_msg(NL_HTT_DUPLAICTED,
                             "iiimx : Warning - Duplicate iiim-xbe %ld\n"),
                       *tmp);
             }
         } else if (ev.xproperty.atom == resource_atom) {
           cmdline_prop = build_cmdline_db(toplevel, argv, argc, False);
           XChangeProperty(display, httw_id, cmdline_atom, XA_STRING,
                         8, PropModeReplace, cmdline_prop,
                         strlen(cmdline_prop) + 1);
           XFlush(display);
           XFree(cmdline_prop);
         } else if (ev.xproperty.atom == htt_server_reset_atom) {
           XGetWindowProperty(display, httw_id, htt_server_reset_atom,
                            0, 4,
                            False, XA_WINDOW, &ret_type, &ret_format,
                            &nitems, &bytes_left, &tmp);
           if (*tmp) {
             htt_server_killed = *tmp;
             /* Kill & start the server */
             Server_Status = RmServerReset;
             kill(htt_server_pid, SIGTERM);
             cmdline_prop = build_cmdline_db(toplevel, argv, argc, True);
             XChangeProperty(display, httw_id, cmdline_atom,
                           XA_STRING, 8,
                           PropModeReplace, cmdline_prop,
                           strlen(cmdline_prop) + 1);
             XFlush(display);
             XFree(cmdline_prop);
             start_htt_server(&htt_server_pid, htt_server_arg);
             XChangeProperty(display, httw_id, server_atom,
                           XA_WINDOW,
                           32, PropModeReplace, (unsigned char *)&htt_server_pid,
                           sizeof(htt_server_pid));
           } else {
             /* Kill the server */
             Server_Status = RmServerKilled;
             kill(htt_server_pid, SIGTERM);
           }

         } else
#ifdef HTT_DEBUG
           fprintf(stderr,
                  "iiimx: Unknown property notify event wid = %x atom = %s\n",
                  ev.xproperty.window,
                  XGetAtomName(display, ev.xproperty.atom))
#endif
           ;
       }
       break;
      case DestroyNotify:
       if (ev.xdestroywindow.window == httw_id) {
         Server_Status = RmServerKilled;
         kill(htt_server_pid, SIGTERM);
         if (my_rdb.start_props)
           kill(htt_props_pid, SIGTERM);
         exit(0);
       } else {
                            /* don't know what to do.... */
       }
      case ClientMessage:{

#if 0
       LOG0("watchdog.c:Client Message");
       LOG1("watchdog.c:Message type %s\n",
            XGetAtomName(display, ev.xclient.message_type));
       LOG1("watchdog.c:format %d\n", ev.xclient.format);
       LOG1("watchdog.c:Client message data %s \n",
            XGetAtomName(display, ev.xclient.data.l[0]));
#endif
                            /* Need to tell htt_server to save its state */
       if ((ev.xclient.format == 32) && (!strncmp(XGetAtomName(display, ev.xclient.message_type), "WM_PROTOCOLS", 12))) {
         if (ev.xclient.data.l[0] == htt_save_atom[1]) {
           char           *res = strdup("DeleteWindow:True");
           XChangeProperty(display, httw_id,
                         resource_atom, XA_STRING,
                         8, PropModeAppend,
                         (unsigned char *) res, strlen(res) + 1);
           free(res);
         }
         if (ev.xclient.data.l[0] == htt_save_atom[2]) {
           char           *res = strdup("SaveState:True");
           XChangeProperty(display, httw_id,
                         resource_atom, XA_STRING,
                         8, PropModeAppend,
                         (unsigned char *) res, strlen(res) + 1);
           free(res);
           if (my_rdb.respond_to_sm)
              if (!spawn_props) {
                /* spawn_props = False means  */
                char          **tmp_argv = (char **) XtMalloc((argc + 1) *
                                                   sizeof(char *));
                int             tmp_argc;
                for (tmp_argc = 0; tmp_argc < argc; tmp_argc++)
                  tmp_argv[tmp_argc] = argv[tmp_argc];
                tmp_argv[tmp_argc] = (char *) XtMalloc(strlen("-so") + 1);
                strcpy(tmp_argv[tmp_argc++], "-so");
                XSetCommand(display, httw_id, tmp_argv, tmp_argc);
                XtFree(tmp_argv[tmp_argc - 1]);
                XtFree((char *)tmp_argv);
              } else
                XSetCommand(display, httw_id, argv, argc);
            else
              XSetCommand(display, httw_id, (char **)0, 0);
              /* Ignore WM_SAVEYOURSELF  msg */
            }
           }
       break;
      }
      }
    }
}

Here is the call graph for this function:

static void parse_command ( int  argc,
char **  argv 
) [static]

Definition at line 1010 of file watchdog.c.

{
  int             i;
  for (i = 1; i < argc; i++) {
    if (!strcmp(argv[i], "-help")) {
      usage();
      exit(0);
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void proc_exit ( int  unused) [static]

Definition at line 598 of file watchdog.c.

{
  int             pid;
  int             wstat;

  for (;;) {
    pid = wait3(&wstat, WNOHANG, (struct rusage *) NULL);
    if (pid == 0)
      return;
    else if (pid == -1)
      return;
    else if (pid == htt_server_pid) {
      if (WIFSTOPPED(wstat)) {
       fprintf(stderr,
              nl_msg(NL_HTT_SUSPENDED,
                     "iiim-xbe has been suspended \n")
              );
      } else if (WIFEXITED(wstat)) {
       switch (Server_Status) {
       case RmServerKilled:
         if (my_rdb.start_props)
           kill(htt_props_pid, SIGTERM);
         exit(1);
         break;      /* Not so useful */
       case RmServerReset:
         /*
          * Don't worry abt it. Watchdog wants
          * to reset htt_server
          */
         break;
       case RmServerActive:
         fprintf(stderr, nl_msg(NL_HTT_SERVER_EXITED_UNKNOWN,
                             "iiimx : Warning - iiim-xbe has been terminated without knowledge of iiimx , restart iiimx again\n"));
         if (my_rdb.start_props)
           kill(htt_props_pid, SIGTERM);
         exit(0);
         break;      /* Not so usefule */
       }
#if 0
       fprintf(stderr,
              nl_msg(NL_HTT_SERVER_DIED,
                     "htt : Warning - htt_server died and recovered\n"));
       start_htt_server(&htt_server_pid, htt_server_arg);
#endif
      } else if (WIFSIGNALED(wstat)) {
       switch (WTERMSIG(wstat)) {
       case SIGTERM:
       case SIGKILL: /* there must be a reason */
         if (!htt_server_killed) {
           /*
            * 4049423: In zh_TW.BIG5 and
            * ja_JP.PCK, htt prints
            * message in garbage when it
            * exits
            * 
            * fprintf(stderr,
            * nl_msg(NL_HTT_SERVER_EXITED
            * , "htt : htt_server has
            * been terminated\n") );
            */
           if (my_rdb.start_props)
             kill(htt_props_pid, SIGTERM);
           exit(0);
         }
         htt_server_killed = 0;
         break;
       case SIGQUIT:
       case SIGILL:
#ifndef       linux
       case SIGEMT:
#endif
       case SIGSEGV:
       case SIGFPE:
       case SIGTRAP:
       case SIGBUS:
#ifndef       linux
       case SIGSYS:
#endif
       case SIGIOT:
         fprintf(stderr,
                nl_msg(NL_HTT_SERVER_DIED,
                      "iiimx : Warning - iiim-xbe died and recovered\n")
                );
         start_htt_server(&htt_server_pid, htt_server_arg);
         break;
       default:
         fprintf(stderr,
                nl_msg(NL_HTT_SERVER_DIED_UNKNOWN,
                      "iiimx : Error - iiim-xbe died. Don't know how to recover\n")
                );
         if (my_rdb.start_props)
           kill(htt_props_pid, SIGTERM);
         exit(1);
       }
      }
    } else if ((my_rdb.start_props) && (pid == htt_props_pid)) {
      /*
       * printf("watchdog: htt_props has died, do
       * something?\n");
       */
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int search_program ( char *  prg,
char *  path 
)

Definition at line 726 of file watchdog.c.

{
  char *basepath;

  if (check_openwin_path(prg, getenv("OPENWINHOME"), path))
    return OPENWIN_PATH;
  if (check_openwin_path(prg, OPENWINHOME, path))
    return OPENWIN_PATH;
    
  basepath = IMDIR;
  if (basepath
      && ((strlen(basepath) + strlen(prg) + 2) < MAXNAMELEN))
    {
      strcpy(path, basepath);
      strcat(path, "/");
      strcat(path, prg);
      if (access(path, X_OK) == 0) return 0;
    }
  return -1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void start_htt_props ( int *  ,
char *  argv[] 
) [static]

Here is the caller graph for this function:

void start_htt_props ( int *  htt_props_pid,
argv   
)

Definition at line 796 of file watchdog.c.

{
  char            pathname[MAXNAMELEN];
  extern int      errno;

  if (search_program(htt_props_path, pathname) < 0)
    {
      perror("htt_props not found\n");
      return;
    }
  *htt_props_pid = fork();
  switch (*htt_props_pid) {
  case -1:
    perror("watchdog:fork\n");
    exit(errno);
  case 0:
    setpgrp();
    if (!my_rdb.respond_to_sm)
      sleep(10);
    execv(pathname, argv);
    perror("execv htt_props failed\n");
  }
}

Here is the call graph for this function:

static void start_htt_server ( int *  ,
char *  argv[] 
) [static]

Here is the caller graph for this function:

void start_htt_server ( int *  htt_server_pid,
argv   
)

Definition at line 748 of file watchdog.c.

{
  char            pathname[MAXNAMELEN];
  extern int      errno;
  int             pid;
  int             flag;

  flag = search_program(my_rdb.htt_server_name, pathname);

  if (flag < 0)
    {
      perror("iiim-xbe not found\n");
      return;
    }

  pid = (*htt_server_pid) = fork();
  switch (*htt_server_pid) {
  case -1:
    perror("watchdog:fork\n");
    exit(errno);
  case 0:
    /*
     * Note: Forked process sleeps for one second (roughly) in
     * order to allow htt to update PID property. It should work
     * most of the cases
     */
    sleep(1);

#ifdef SETPGRP_VOID
    setpgrp();
#else
    setpgrp(0, 0);
#endif

#ifdef SunOS
    if (flag == OPENWIN_PATH) {
      putenv(OPENWIN_MOTIF_PRELOAD_ENV);
    }
#endif
    execv(pathname, argv);
    perror("execv iiim-xbe failed\n");
  }
  Server_Status = RmServerActive;
}

Here is the call graph for this function:

void start_iiimd ( int *  iiimd_pid,
char **  argv 
) [static]

Definition at line 823 of file watchdog.c.

{
  char *      pathname;
  extern int  errno;
  int         pid;

  pathname = "/usr/bin/iiimd";

  pid = (*iiimd_pid) = fork();
  switch (*iiimd_pid) {
  case -1:
    perror("watchdog:fork\n");
    exit(errno);
  case 0:
#ifdef SETPGRP_VOID
    setpgrp();
#else
    setpgrp(0, 0);
#endif

    execv(pathname, argv);
    perror("execv iiimd failed\n");
  }
  sleep(4);
}

Here is the caller graph for this function:

static void usage ( void  ) [static]

Definition at line 972 of file watchdog.c.

            {
  printf(
        nl_msg(NL_HTT_USAGE_1,
              "usage:\n       iiimx [-options ...]\n\nwhere options include:\n")
        );
  printf(
        nl_msg(NL_HTT_USAGE_2,
              "    -help                         print out this message\n")
        );
  printf(
        nl_msg(NL_HTT_USAGE_3,
              "    -display displayname          X server to contact\n")
        );
  printf(
        nl_msg(NL_HTT_USAGE_4,
              "    -xrm file                     additional resource file\n")
        );
#if 0
  printf(
        nl_msg(NL_HTT_USAGE_5,
              "    -so                           server only\n")
        );
  printf(
        nl_msg(NL_HTT_USAGE_5,
              "    -sp                           start htt_props as well\n")
        );
  printf(
        nl_msg(NL_HTT_USAGE_6,
              "    -nosm                         do not respond to session manager\n")
        );
#endif
  printf(
        nl_msg(NL_HTT_USAGE_7,
              "    -xim                          xim server name\n")
        );
}

Variable Documentation

Atom class_atom [static]

Definition at line 122 of file watchdog.c.

Atom cmdline_atom [static]

Definition at line 122 of file watchdog.c.

Display* display [static]

Definition at line 124 of file watchdog.c.

Atom htt_atom [static]

Definition at line 121 of file watchdog.c.

char** htt_props_arg [static]

Definition at line 129 of file watchdog.c.

char* htt_props_path = "htt_props" [static]

Definition at line 98 of file watchdog.c.

int htt_props_pid [static]

Definition at line 119 of file watchdog.c.

char** htt_server_arg [static]

Definition at line 128 of file watchdog.c.

int htt_server_killed = 0 [static]

Definition at line 133 of file watchdog.c.

int htt_server_pid [static]

Definition at line 119 of file watchdog.c.

Atom htt_server_reset_atom [static]

Definition at line 122 of file watchdog.c.

Atom htt_watchdog_atom [static]

Definition at line 122 of file watchdog.c.

Window httw_id [static]

Definition at line 125 of file watchdog.c.

char** iiimd_arg [static]

Definition at line 130 of file watchdog.c.

int iiimd_pid [static]

Definition at line 120 of file watchdog.c.

RmDatabase my_rdb [static]

Definition at line 145 of file watchdog.c.

int NUM_RDB_OPTIONS = XtNumber(rdb_options) [static]

Definition at line 172 of file watchdog.c.

Atom props_atom [static]

Definition at line 121 of file watchdog.c.

XtResource rdb_items[] [static]
Initial value:
 {
  {"inputMethod", "InputMethod", XtRString, sizeof(char *),
   offsetof(RmDatabase, htt_server_name), XtRString, (XPointer)"iiim-xbe"},
  {"startProps", "StartProps", XtRBool, sizeof(Bool),
   offsetof(RmDatabase, start_props), XtRString, (XPointer) "false"},
  {"respondToSM", "RespondToSM", XtRBool, sizeof(Bool),
   offsetof(RmDatabase, respond_to_sm), XtRString, (XPointer) "false"},
  {"startIiimd", "StartIiimd", XtRBool, sizeof(Bool),
   offsetof(RmDatabase, start_iiimd), XtRString, (XPointer) "false"},
  {"udsFile", "UdsFile", XtRString, sizeof (char *),
   offsetof(RmDatabase, udsfile), XtRString, (XPointer) NULL},
  {"varDir", "VarDir", XtRString, sizeof (char *),
   offsetof(RmDatabase, vardir), XtRString, (XPointer) NULL},
}

Definition at line 147 of file watchdog.c.

XrmOptionDescRec rdb_options[] [static]
Initial value:
 {
  {"-xim", "*inputMethod", XrmoptionSepArg, NULL},
  {"-sp", "*startProps", XrmoptionNoArg, (XPointer) "true"},
  {"-so", "*startProps", XrmoptionNoArg, (XPointer) "false"},
  {"-rsm", "*respondToSM", XrmoptionNoArg, (XPointer) "true"},
  {"-iiimd", "*startIiimd", XrmoptionNoArg, (XPointer) "True"},
  {"-udsfile", "*udsFile", XrmoptionSepArg, NULL},
  {"-vardir", "*varDir", XrmoptionSepArg, NULL},
}

Definition at line 162 of file watchdog.c.

Atom resource_atom [static]

Definition at line 121 of file watchdog.c.

Atom server_atom [static]

Definition at line 121 of file watchdog.c.

Definition at line 108 of file watchdog.c.

Bool spawn_props = True [static]

Definition at line 127 of file watchdog.c.