/* File: vms_export_symbol.c
 *
 * Some programs need special environment variables deported as DCL
 * DCL symbols.
 */

/* Copyright (C) 2014 Free Software Foundation, Inc.

GNU Make is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3 of the License, or (at your option) any later
version.

GNU Make is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program.  If not, see <http://www.gnu.org/licenses/>.  */


/* Per copyright assignment agreement with the Free Software Foundation
   this software may be available under under other license agreements
   and copyrights. */


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

#include <descrip.h>
#include <stsdef.h>
#include <ssdef.h>
#include <unixlib.h>
#include <libclidef.h>

#pragma member_alignment save
#pragma nomember_alignment longword
struct item_list_3
{
  unsigned short len;
  unsigned short code;
  void * bufadr;
  unsigned short * retlen;
};


#pragma member_alignment

int
LIB$GET_SYMBOL (const struct dsc$descriptor_s * symbol,
                struct dsc$descriptor_s * value,
                unsigned short * value_len,
                const unsigned long * table);

int
LIB$SET_SYMBOL (const struct dsc$descriptor_s * symbol,
                const struct dsc$descriptor_s * value,
                const unsigned long * table);

int
LIB$DELETE_SYMBOL (const struct dsc$descriptor_s * symbol,
                   const unsigned long * table);

#define MAX_DCL_SYMBOL_LEN (255)
#if __CRTL_VER >= 70302000 && !defined(__VAX)
# define MAX_DCL_SYMBOL_VALUE (8192)
#else
# define MAX_DCL_SYMBOL_VALUE (1024)
#endif

struct dcl_symbol
{
  struct dcl_symbol * link;
  struct dsc$descriptor_s name_desc;
  struct dsc$descriptor_s value_desc;
  char name[MAX_DCL_SYMBOL_LEN + 1];    /* + 1 byte for null terminator */
  char value[MAX_DCL_SYMBOL_VALUE +1];  /* + 1 byte for null terminator */
  char pad[3]; /* Pad structure to longword allignment */
};

static struct dcl_symbol * vms_dcl_symbol_head = NULL;

/* Restore symbol state to original condition. */
static unsigned long
clear_dcl_symbol (struct dcl_symbol * symbol)
{

  const unsigned long symtbl = LIB$K_CLI_LOCAL_SYM;
  int status;

  if (symbol->value_desc.dsc$w_length == (unsigned short)-1)
    status = LIB$DELETE_SYMBOL (&symbol->name_desc, &symtbl);
  else
    status = LIB$SET_SYMBOL (&symbol->name_desc,
                             &symbol->value_desc, &symtbl);
  return status;
}


/* Restore all exported symbols to their original conditions */
static void
clear_exported_symbols (void)
{

  struct dcl_symbol * symbol;

  symbol = vms_dcl_symbol_head;

  /* Walk the list of symbols.  This is done durring exit,
   * so no need to free memory.
   */
  while (symbol != NULL)
  {
    clear_dcl_symbol (symbol);
    symbol = symbol->link;
  }

}


/* Restore the symbol back to the original value
 * symbol name is either a plain name or of the form "symbol=name" where
 * the name portion is ignored.
 */
void
vms_restore_symbol (const char * string)
{

  struct dcl_symbol * symbol;
  char name[MAX_DCL_SYMBOL_LEN + 1];
  int status;
  char * value;
  int name_len;

  symbol = vms_dcl_symbol_head;

  /* Isolate the name from the value */
  value = strchr (string, '=');
  if (value != NULL)
    {
      /* Copy the name from the string */
      name_len = (value - string);
    }
  else
    name_len = strlen (string);

  if (name_len > MAX_DCL_SYMBOL_LEN)
    name_len = MAX_DCL_SYMBOL_LEN;

  strncpy (name, string, name_len);
  name[name_len] = 0;

  /* Walk the list of symbols.  The saved symbol is not freed
   * symbols are likely to be overwritten multiple times, so this
   * saves time in saving them each time.
   */
  while (symbol != NULL)
    {
      int result;
      result = strcmp (symbol->name, name);
      if (result == 0)
        {
          clear_dcl_symbol (symbol);
          break;
        }
      symbol = symbol->link;
    }
}

int
vms_export_dcl_symbol (const char * name, const char * value)
{

  struct dcl_symbol * symbol;
  struct dcl_symbol * next;
  struct dcl_symbol * link;
  int found;
  const unsigned long symtbl = LIB$K_CLI_LOCAL_SYM;
  struct dsc$descriptor_s value_desc;
  int string_len;
  int status;
  char new_value[MAX_DCL_SYMBOL_VALUE + 1];
  char * dollarp;

  next = vms_dcl_symbol_head;
  link = vms_dcl_symbol_head;

  /* Is symbol already exported? */
  found = 0;
  while ((found == 0) && (link != NULL))
    {
      int x;
      found = !strncasecmp (link->name, name, MAX_DCL_SYMBOL_LEN);
      if (found)
        symbol = link;
      next = link;
      link = link->link;
    }

  /* New symbol, set it up */
  if (found == 0)
    {
      symbol = malloc (sizeof (struct dcl_symbol));
      if (symbol == NULL)
        return SS$_INSFMEM;

      /* Construct the symbol descriptor, used for both saving
       * the old symbol and creating the new symbol.
       */
      symbol->name_desc.dsc$w_length = strlen (name);
      if (symbol->name_desc.dsc$w_length > MAX_DCL_SYMBOL_LEN)
        symbol->name_desc.dsc$w_length = MAX_DCL_SYMBOL_LEN;

      strncpy (symbol->name, name, symbol->name_desc.dsc$w_length);
      symbol->name[symbol->name_desc.dsc$w_length] = 0;
      symbol->name_desc.dsc$a_pointer = symbol->name;
      symbol->name_desc.dsc$b_dtype = DSC$K_DTYPE_T;
      symbol->name_desc.dsc$b_class = DSC$K_CLASS_S;

      /* construct the value descriptor, used only for saving
       * the old symbol.
       */
      symbol->value_desc.dsc$a_pointer = symbol->value;
      symbol->value_desc.dsc$w_length = MAX_DCL_SYMBOL_VALUE;
      symbol->value_desc.dsc$b_dtype = DSC$K_DTYPE_T;
      symbol->value_desc.dsc$b_class = DSC$K_CLASS_S;
    }

  if (found == 0)
    {
      unsigned long old_symtbl;
      unsigned short value_len;

      /* Look up the symbol */
      status = LIB$GET_SYMBOL (&symbol->name_desc, &symbol->value_desc,
                               &value_len, &old_symtbl);
      if (!$VMS_STATUS_SUCCESS (status))
        value_len = (unsigned short)-1;
      else if (old_symtbl != symtbl)
        value_len = (unsigned short)-1;

      symbol->value_desc.dsc$w_length = value_len;

      /* Store it away */
      if (value_len != (unsigned short) -1)
        symbol->value[value_len] = 0;

      /* Make sure atexit scheduled */
      if (vms_dcl_symbol_head == NULL)
        {
          vms_dcl_symbol_head = symbol;
          atexit (clear_exported_symbols);
        }
      else
        {
          /* Extend the chain */
          next->link = symbol;
        }
    }

  /* Create or replace a symbol */
  value_desc.dsc$a_pointer = new_value;
  string_len = strlen (value);
  if (string_len > MAX_DCL_SYMBOL_VALUE)
    string_len = MAX_DCL_SYMBOL_VALUE;

  strncpy (new_value, value, string_len);
  new_value[string_len] = 0;

  /* Special handling for GNU Make.  GNU Make doubles the dollar signs
   * in environment variables read in from getenv().  Make exports symbols
   * with the dollar signs already doubled.  So all $$ must be converted
   * back to $.
   * If the first $ is not doubled, then do not convert at all.
   */
  dollarp = strchr (new_value, '$');
  while (dollarp && dollarp[1] == '$')
    {
      int left;
      dollarp++;
      left = string_len - (dollarp - new_value - 1);
      string_len--;
      if (left > 0)
        {
          memmove (dollarp, &dollarp[1], left);
          dollarp = strchr (&dollarp[1], '$');
        }
      else
        {
          /* Ended with $$, simple case */
          dollarp[1] = 0;
          break;
        }
    }
  value_desc.dsc$w_length = string_len;
  value_desc.dsc$b_dtype = DSC$K_DTYPE_T;
  value_desc.dsc$b_class = DSC$K_CLASS_S;
  status = LIB$SET_SYMBOL (&symbol->name_desc, &value_desc, &symtbl);
  return status;
}

/* export a DCL symbol using a string in the same syntax as putenv */
int
vms_putenv_symbol (const char * string)
{

  char name[MAX_DCL_SYMBOL_LEN + 1];
  int status;
  char * value;
  int name_len;

  /* Isolate the name from the value */
  value = strchr (string, '=');
  if (value == NULL)
    {
      errno = EINVAL;
      return -1;
    }

  /* Copy the name from the string */
  name_len = (value - string);
  if (name_len > MAX_DCL_SYMBOL_LEN)
    name_len = MAX_DCL_SYMBOL_LEN;

  strncpy (name, string, name_len);
  name[name_len] = 0;

  /* Skip past the "=" */
  value++;

  /* Export the symbol */
  status = vms_export_dcl_symbol (name, value);

  /* Convert the error to Unix format */
  if (!$VMS_STATUS_SUCCESS (status))
    {
      errno = EVMSERR;
      vaxc$errno = status;
      return -1;
    }
  return 0;
}

#if __CRTL_VER >= 70301000
# define transpath_parm transpath
#else
static char transpath[MAX_DCL_SYMBOL_VALUE];
#endif

/* Helper callback routine for converting Unix paths to VMS */
static int
to_vms_action (char * vms_spec, int flag, char * transpath_parm)
{
  strncpy (transpath, vms_spec, MAX_DCL_SYMBOL_VALUE - 1);
  transpath[MAX_DCL_SYMBOL_VALUE - 1] = 0;
  return 0;
}

#ifdef __DECC
# pragma message save
  /* Undocumented extra parameter use triggers a ptrmismatch warning */
# pragma message disable ptrmismatch
#endif

/* Create a foreign command only visible to children */
int
create_foreign_command (const char * command, const char * image)
{
  char vms_command[MAX_DCL_SYMBOL_VALUE + 1];
  int status;

  vms_command[0] = '$';
  vms_command[1] = 0;
  if (image[0] == '/')
    {
#if __CRTL_VER >= 70301000
      /* Current decc$to_vms is reentrant */
      decc$to_vms (image, to_vms_action, 0, 1, &vms_command[1]);
#else
      /* Older decc$to_vms is not reentrant */
      decc$to_vms (image, to_vms_action, 0, 1);
      strncpy (&vms_command[1], transpath, MAX_DCL_SYMBOL_VALUE - 1);
      vms_command[MAX_DCL_SYMBOL_VALUE] = 0;
#endif
    }
  else
    {
      strncpy (&vms_command[1], image, MAX_DCL_SYMBOL_VALUE - 1);
      vms_command[MAX_DCL_SYMBOL_VALUE] = 0;
    }
  status = vms_export_dcl_symbol (command, vms_command);

  return status;
}
#ifdef __DECC
# pragma message restore
#endif


#ifdef DEBUG

int
main(int argc, char ** argv, char **env)
{

  char value[MAX_DCL_SYMBOL_VALUE +1];
  int status = 0;
  int putenv_status;
  int vms_status;
  struct dsc$descriptor_s name_desc;
  struct dsc$descriptor_s value_desc;
  const unsigned long symtbl = LIB$K_CLI_LOCAL_SYM;
  unsigned short value_len;
  unsigned long old_symtbl;
  int result;
  const char * vms_command = "vms_export_symbol";
  const char * vms_image = "test_image.exe";
  const char * vms_symbol1 = "test_symbol1";
  const char * value1 = "test_value1";
  const char * vms_symbol2 = "test_symbol2";
  const char * putenv_string = "test_symbol2=value2";
  const char * value2 = "value2";

  /* Test creating a foreign command */
  vms_status = create_foreign_command (vms_command, vms_image);
  if (!$VMS_STATUS_SUCCESS (vms_status))
    {
      printf("Create foreign command failed: %d\n", vms_status);
      status = 1;
    }

  name_desc.dsc$a_pointer = (char *)vms_command;
  name_desc.dsc$w_length = strlen (vms_command);
  name_desc.dsc$b_dtype = DSC$K_DTYPE_T;
  name_desc.dsc$b_class = DSC$K_CLASS_S;

  value_desc.dsc$a_pointer = value;
  value_desc.dsc$w_length = MAX_DCL_SYMBOL_VALUE;
  value_desc.dsc$b_dtype = DSC$K_DTYPE_T;
  value_desc.dsc$b_class = DSC$K_CLASS_S;

  vms_status = LIB$GET_SYMBOL (&name_desc, &value_desc,
                               &value_len, &old_symtbl);
  if (!$VMS_STATUS_SUCCESS (vms_status))
    {
      printf ("lib$get_symbol for command failed: %d\n", vms_status);
      status = 1;
    }

  value[value_len] = 0;
  result = strncasecmp (&value[1], vms_image, value_len - 1);
  if (result != 0)
    {
      printf ("create_foreign_command failed!  expected '%s', got '%s'\n",
              vms_image, &value[1]);
      status = 1;
    }

  /* Test exporting a symbol */
  vms_status = vms_export_dcl_symbol (vms_symbol1, value1);
  if (!$VMS_STATUS_SUCCESS (vms_status))
    {
      printf ("vms_export_dcl_symbol for command failed: %d\n", vms_status);
      status = 1;
    }

  name_desc.dsc$a_pointer = (char *)vms_symbol1;
  name_desc.dsc$w_length = strlen (vms_symbol1);
  vms_status = LIB$GET_SYMBOL(&name_desc, &value_desc,
                              &value_len, &old_symtbl);
  if (!$VMS_STATUS_SUCCESS(vms_status))
    {
      printf ("lib$get_symbol for command failed: %d\n", vms_status);
      status = 1;
    }

  value[value_len] = 0;
  result = strncmp (value, value1, value_len);
  if (result != 0)
    {
      printf ("vms_export_dcl_symbol failed!  expected '%s', got '%s'\n",
              value1, value);
      status = 1;
    }

  /* Test putenv for DCL symbols */
  putenv_status = vms_putenv_symbol (putenv_string);
  if (putenv_status != 0)
    {
      perror ("vms_putenv_symbol");
      status = 1;
    }

  name_desc.dsc$a_pointer = (char *)vms_symbol2;
  name_desc.dsc$w_length = strlen(vms_symbol2);
  vms_status = LIB$GET_SYMBOL (&name_desc, &value_desc,
                               &value_len, &old_symtbl);
  if (!$VMS_STATUS_SUCCESS (vms_status))
    {
      printf ("lib$get_symbol for command failed: %d\n", vms_status);
      status = 1;
    }

  value[value_len] = 0;
  result = strncmp (value, value2, value_len);
  if (result != 0)
  {
    printf ("vms_putenv_symbol failed!  expected '%s', got '%s'\n",
            value2, value);
    status = 1;
  }

  vms_restore_symbol (putenv_string);
  vms_status = LIB$GET_SYMBOL (&name_desc, &value_desc,
                               &value_len, &old_symtbl);
  if ($VMS_STATUS_SUCCESS (vms_status))
    {
      printf ("lib$get_symbol for command succeeded, should have failed\n");
      status = 1;
    }

  exit (status);
}

#endif
