/*******************************************************************************
Copyright by Telesoft Europe AB 1990, 1991.
Copyright by TeleLOGIC AB 1991, 1992, 1993, 1994.
Copyright by Telelogic AB 1995, 1996, 1997, 1998.
All rights reserved. No part of this document or computer program may be
reproduced, transmitted, transcribed, or translated into any language in
any form by any means without prior written permission of TeleLOGIC Malmoe AB,
in accordance with the terms and conditions stipulated in the agreement/contract
under which the program(s) have been supplied.
Information in this document or computer program is subject to change without
notice.
*******************************************************************************/

/* 

    This program requests an Telelogic TAU service from the command line.
    It requires a Telelogic TAU session to be running.


    The program takes the following parameters:

    argv[1]      : The Telelogic TAU tool providing the service
    argv[2]      : The service of interest
    argv[3], ... : additional parameters to the service, if any.
    argv[argc-1] : optional -notification flag, will not wait for reply if
                   present.

    Tools and services could either be issued symbolically or by their
    identifier. Identifiers and symbolic names are found in itex2.h and sdt.h.

*/


#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#ifndef NULL
#define NULL 0
#endif

#define USING_DLL
#include "post.h"
#undef USING_DLL

#include "itex.h"
#include "itex2.h"
#include "sdt.h"

void OnError (char *str)
{
  printf ("%s %s\n", str, SPErrorString (GetSPerrno ()));
  exit (1);
}


char *handleescape (char *p, int *len)
{
  char *s;
  *len = strlen (p);

  s = p;
  do {
    s = (char *)strstr (s, "\\r");
    if (s && (s > p && (*(s - 1) != '\\') || (s == p))) {
      *s = '\r';
      memmove (s + 1, s + 2, strlen (s + 2) + 1);
      *len = *len - 1;
    }
    else if (NULL != s)
      s = s + 2;
  } while (s);
  
  s = p;
  do {
    s= (char *)strstr(s, "\\n");
    if (s && (s > p && (*(s -1) != '\\') || (s == p))) {
      *s = '\n';
      memmove (s + 1, s + 2, strlen (s + 2) + 1);
      *len = *len - 1;
    }
    else if (s)
      s = s + 2;
  } while (s);
  
  s = p;
  do {
    s = (char *)strstr (s, "\\0");
    if (s && (s> p && (*(s -1) != '\\') || (s == p))) {
      *s = '\0';
      memmove (s + 1, s + 2, strlen (s + 2) + 1);
      *len = *len - 1;
    }
    else if (s)
      s = s + 2;
  } while (s);
  
  do {
    s = (char *)strstr (p, "\\\\");
    if (s) {
      memmove (s+1, s+2, strlen (s + 2) +1);
      *len = *len -1;
    }
  } while (s);
  
  return p;
}


void main (int argc, char ** argv)
{
  int  status;
  
  int  tool;
  int  sendEvent;
  
  int  pid;
  int  replyEvent;
  char *replyMessage;
  void *replyPointer;
  int  len;
  int  notification = 0; /* not notification by default */
  char * rpcmode = ""; /*no extra text by default */
  
  if (argc > 1 && strcmp (argv[1], "-listpm") == 0) {
    /* Get all postmaster! */
    int bufferPid[100];
    char* bufferText[100];
    int noOfPM;
    int i;
    noOfPM = SPFindActivePostMasters (bufferPid, bufferText, 100);
    for (i = 0; i < noOfPM; i++) {
      if (bufferText[i] != NULL) {
        printf ("Pid: %d, Created: %s\n", bufferPid[i], bufferText[i]);
        SPFree (bufferText[i]);
      }
    }
    /* break when ready*/
    exit (0);
  }
  if ( argc > 3 && !strcmp( argv[argc-1], "-notification" ) ) {
    notification = 1;
    rpcmode = "NOTIFICATION";
    argc--; 
    argv[argc] = 0; /* hide this flag to avoid later confusion */
  }
  
  if (argc < 3) {
    printf ("usage: %s <tool> <event> [<data>...] [-notification]\n", argv[0]);
    exit (1);
  }
  
  
  /* Connect to the Postmaster */
  status = SPInit (SET_EXTERN, argv[0], GetSPMList ());
  if (-1 == status)
    OnError("Error connecting to postmaster: ");
  
  
  /* Translate  symbolic tool and service names to identifiers, if any */
  tool = atoi (argv[1]);
  if (0 == tool)
    tool = SPConvert (argv[1]);
  
  sendEvent = atoi (argv[2]);
  if (0 == sendEvent)
    sendEvent = SPConvert (argv[2]);
  
  /* Request the service by issuing the service request message */
  if (argc > 3) {
    char *p;
    int i;
    
    p = (char *)malloc (1);
    *p = '\0';
    for (i = 3; i < argc; i++) {
      p = (char *)realloc (p, strlen(p) + strlen (argv[i]) + 2);
      if (strlen (p) > 0)
        p = (char *)strcat (p, " ");
      p = (char *)strcat (p, argv[i]);
    }
    len = strlen (p);
    p = handleescape (p, &len); 
    if (notification)
      printf ("Sending (%s) %d %d %s\n", rpcmode, tool, sendEvent, p);
    else
      printf ("Sending %d %d %s\n", tool, sendEvent, p);
    status = SPSendToTool (tool, sendEvent, p, len + 1);
    free (p);
  }
  else {
    printf ("Sending (%s) %d %d\n", rpcmode, tool, sendEvent);
    status = SPSendToTool (tool, sendEvent, "", 0);
  }
  if (status != 0)
    OnError ("Error sending to postmaster: ");
  
  
  if ( ! notification ) {
    /* Wait for the service reply message to arrive */
    do {
      status = SPRead (SPWAITFOREVER, &pid, &replyEvent, &replyPointer, &len);
      if (0 != status)
        OnError("Error reading from postmaster: ");
    } while (replyEvent != sendEvent + 100);
    
    if (NULL != replyPointer) {
      replyMessage = (char *)malloc (len + 1);
      memcpy (replyMessage, replyPointer, len);
      replyMessage[len] = '\0';
      SPFree (replyPointer);
    }
    else {
      replyMessage = (char *)malloc (1);
      replyMessage[0] = '\0';
    }
    
    /* Decode reply message */
    printf ("Reply status is ");
    if (sscanf (replyMessage, "%d", &status) != 1)
      status = -12345;
    
    switch (status) {  
    case SDT_OK:      printf ("OK\n"); break;
    case SDT_BUSY:    printf ("Busy, reason: "); break;
    case SDT_ERRSTR:
    case SDT_ERRCODE: printf ("Error, reason: "); break;
      
    default: printf ("Unknown");
    }
    
    if (len > 2 && ' ' == replyMessage[1]) {
      int i;
      for (i = 2; i < len; i++)
        putchar (replyMessage[i]);
      putchar ('\n');
    }
    else if (len > 1)
      printf ("%s\n", replyMessage + 1);
    else
      printf ("\n");
    
    free (replyMessage);
  }  /* if (!notification ) */
  
  /* Notify that we will terminate */
  SPBroadcast (SESTOPNOTIFY, NULL, 0);
  
  /* Disconenct from the postmaster */
  SPExit ();
  exit (status == SDT_OK ? 0 : 1);
}


