/* VMS archive wrapper.
   Copyright (C) 2011-2022 Free Software Foundation, Inc.
   Contributed by AdaCore.

This file is part of GCC.

GCC 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, or (at your option)
any later version.

GCC 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 GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include <errno.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "libiberty.h"

#define FATAL_EXIT_CODE (44 | 0x10000000)

/* Librarian arguments.  */
static int lib_arg_max = 0;
static const char **lib_args;
static int lib_arg_index = -1;

/* Set for r/c/x/v command.  */
static int replace_mode = 0;
static int create_mode = 0;
static int extract_mode = 0;
static int verbose_mode = 0;

static char modecmd[32];
static char libname[256];

#define TEMP_FILE "arXXXXXX"
#define TEMP_FILE_LEN (sizeof(TEMP_FILE) - 1)
#define SUFFIX ".com"
#define SUFFIX_LEN (sizeof(SUFFIX) - 1)

static char *to_host_file_spec (char *filespec);
static int is_regular_file (char *name);

#ifdef VMS
static char new_host_filespec [255];
static char filename_buff [256];

static int
translate_unix (char *name, int type)
{
  strcpy (filename_buff, name);
  return 0;
}
#endif

static char *
to_host_file_spec (char *filespec)
{
#ifdef VMS
  if (strchr (filespec, ']') || strchr (filespec, ':'))
    return filespec;
  else
    {
      strcpy (filename_buff, filespec);
      decc$to_vms (filespec, translate_unix, 1, 1);
      strcpy (new_host_filespec, filename_buff);
      return new_host_filespec;
    }
#else
  return filespec;
#endif
}

/* Check to see if the file named in NAME is a regular file, i.e. not a
   directory.  */

static int
is_regular_file (char *name)
{
  int ret;
  struct stat statbuf;

  ret = stat (name, &statbuf);
  return !ret && S_ISREG (statbuf.st_mode);
}

/* Add the argument contained in STR to the list of arguments to pass to the
   archiver.  */

static void
addarg (const char *str)
{
  if (++lib_arg_index >= lib_arg_max)
    {
      lib_arg_max += 1000;
      lib_args = XRESIZEVEC (const char *, lib_args, lib_arg_max);
    }

  lib_args[lib_arg_index] = str;
}

static void
usage (void)
{
  printf ("usage: ar -r [-cv] archive file...\n");
  printf ("       ar -c [-rv] archive file...\n");
  printf ("       ar -x [-v] archive [module...]\n");
}

int
main (int argc, char *argv[])
{
  int i, nexti, iarg;
  FILE *comfile;
  int comfd;
  int outlen, maxoutlen = 4000;
  char temp_filename[] = TEMP_FILE SUFFIX;
  char command[256];
  int status;

  if (argc < 2)
    {
      fprintf (stderr, "ar: no command or archive\n");
      exit (FATAL_EXIT_CODE);
    }

  if (argv[1][0] != '-')
    {
      int arglen = strlen (argv[1]);

      /* Compatibility mode.  */
      for (i = 0; i < arglen; i++)
	{
	  if (argv[1][i] == 'r')
	    {
	      replace_mode = 1;
	    }
	  else if (argv[1][i] == 'c')
	    {
	      create_mode = 1;
	    }
	  else if (argv[1][i] == 'x')
	    {
	      extract_mode = 1;
	    }
	  else if (argv[1][i] == 'v')
	    {
	      verbose_mode = 1;
	    }
          else
            {
              fprintf (stderr, "ar: unknown command '%c'\n", argv[1][i]);
              exit (FATAL_EXIT_CODE);
            }
	}
      nexti = 2;
    }
  else
    {
      /* Option mode.  */
      nexti = 1;
      for (i = 1; i < argc; i++)
	{
	  if (argv[i][0] != '-')
	    {
	      nexti = i;
	      break;
	    }
	  else if (strcmp (argv[i], "-r") == 0)
	    {
	      replace_mode = 1;
	    }
	  else if (strcmp (argv[i], "-c") == 0)
	    {
	      create_mode = 1;
	    }
	  else if (strcmp (argv[i], "-x") == 0)
	    {
	      extract_mode = 1;
	    }
	  else if (strcmp (argv[i], "-v") == 0)
	    {
	      verbose_mode = 1;
	    }
	  else if (strcmp (argv[i], "--help") == 0)
	    {
              usage ();
              exit (EXIT_SUCCESS);
	    }
          else
            {
              fprintf (stderr, "ar: unknown option %s\n", argv[i]);
              exit (FATAL_EXIT_CODE);
            }
	}
    }

  if (extract_mode)
    {
      do
        {
          char *lname = argv[nexti];
          int lnamelen;

          /* Next argument is the archive name.  */
          if (is_regular_file (lname))
            {
              addarg (xstrdup (to_host_file_spec (lname)));
              break;
            }

          /* If not found, try with .olb instead of .a.  */
          lnamelen = strlen (lname);

	  if (lnamelen > 2
              && strcmp (&lname [lnamelen - 2], ".a") == 0)
	    {
	      char *nlibname;

	      nlibname = (char *)alloca (lnamelen + 3);
	      strcpy (nlibname, lname);
	      strcpy (&nlibname [lnamelen - 2], ".olb");
	      if (is_regular_file (nlibname))
                {
                  addarg (xstrdup (to_host_file_spec (nlibname)));
                  break;
                }
            }

          fprintf (stderr, "ar: file '%s' doesn't exist\n", lname);
          exit (FATAL_EXIT_CODE);
	} while (0);
    }
  else
    strcpy (libname, to_host_file_spec (argv[nexti]));

  nexti++;

  /* Build command mode.  */
  if (replace_mode)
    {
      strcat (modecmd, "/replace");

      if (!is_regular_file (libname) || !replace_mode)
        {
          /* Really create if the archive doesn't exist.  */
          strcat (modecmd, "/create");
        }
    }
  else if (extract_mode)
    {
      if (nexti == argc)
        {
          /* Extract all.  */
          strcat (modecmd, "/extract=(*");
        }
      else
        strcat (modecmd, "/extract=(");
    }

  /* Add files.  */
  for (i = nexti; i < argc; i++)
    {
      if (extract_mode)
        {
          /* Convert to module name (remove extension) and quote it.  */
          char *module = argv[i];
          int module_len = strlen (module);
          char *newarg = (char *)xmalloc (module_len + 3);
          int l;

          newarg[0] = '"';
          memcpy (newarg + 1, module, module_len);

          l = 1 + module_len;
          if (module_len > 4
              && strcmp (&module[module_len - 4], ".obj") == 0)
            l -= 4;

          newarg[l] = '"';
          newarg[l + 1] = 0;

          addarg (newarg);
        }
      else
        {
          /* Add the filename.  */
          addarg (xstrdup (to_host_file_spec (argv[i])));
        }
    }

  if (extract_mode)
    addarg (")");

  /* Create the command file name.  */
  strcpy (temp_filename, TEMP_FILE SUFFIX);
  comfd = mkstemps (temp_filename, SUFFIX_LEN);
  comfile = fdopen (comfd, "w");

  /* Write the command file.
     We need to split to command into severals ones if it is too long.  */
  outlen = 0;
  for (iarg = 0; iarg <= lib_arg_index; iarg++)
    {
      if (outlen == 0)
        {
          fprintf (comfile, "$ library %s %s -\n", modecmd, libname);
          if (create_mode && iarg == 0)
            strcpy (modecmd, "/replace");
        }

      fprintf (comfile, "%s", lib_args [iarg]);
      outlen += strlen (lib_args [iarg]) + 2;

      if (outlen > maxoutlen || iarg == lib_arg_index)
        {
          /* Will write a new command.  */
          fprintf (comfile, "\n");
          outlen = 0;
        }
      else
        {
          /* Continuation line.  */
          fprintf (comfile, ",-\n");
        }
    }

  fclose (comfile);

  sprintf (command, "@%s", temp_filename);

  status = system (command);

  remove (temp_filename);

  exit (status);
}
