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

/* Copyright (C) 2014-2020 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 alignment */
};

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 during 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
