/* vms.c -- target dependent functions for OpenVMS
 * This is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, see the file COPYING.
 *
 * This file was written by Karl-Jose Filler <pla_jfi@pki-nbg.philips.de>
 * and updated by Jean-loup Gailly.   Additional updates on 5-Nov-2001 by 
 * Stephen Hoffman, OpenVMS Engineering.
 */

#include <descrip.h>
#include <lib$routines.h>
#include <rms.h>
#include <stdio.h>
#include <stdlib.h>
#include <stsdef.h>
#include "gzip.h"

static char **vms_argv = NULL;

static int max_files = 1000;

int find_file_c(inp,out,out_len,context)
    char *inp;
    char *out;
    int   out_len;
    int  *context;
    {
    struct	dsc$descriptor in_desc,out_desc;
    int		status;
    int         i;
  
    in_desc.dsc$a_pointer = inp;
    in_desc.dsc$w_length = strlen(inp);
    in_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
    in_desc.dsc$b_class   = DSC$K_CLASS_S;
  
    out_desc.dsc$a_pointer = out;
    out_desc.dsc$w_length  = out_len;
    out_desc.dsc$b_dtype   = DSC$K_DTYPE_T;
    out_desc.dsc$b_class   = DSC$K_CLASS_S;
  
    *out = '\0';
    status = lib$find_file(&in_desc,&out_desc,context);
    if ($VMS_STATUS_SUCCESS(status))
        {
        for (i = 0; i < out_len; i++ )
            {
            if ( out_desc.dsc$a_pointer[i] == ' ' ) 
                {
                out_desc.dsc$a_pointer[i] = '\0';
                break;
                }
            }
        }
  
    return status;
    }
void 
vms_expand_args(old_argc, argv)
    int *old_argc;
    char **argv[];
    {
    int	    i;
    int	    new_argc = 0;
    int	    context = 0;
    int     status;
    char    buf[NAM$C_MAXRSS], *p;
    
    vms_argv = (char**)xmalloc((max_files+1)*sizeof(char*));

    vms_argv[new_argc++] = **argv;

    for (i=1; i < *old_argc; i++) 
        {
	if (*argv[0][i] == '-') 
            {
            /* 
             * Leading hyphen implies this is a command switch ...
             */
	    if (new_argc < max_files) 
                {
		vms_argv[new_argc++] = argv[0][i];
	        }
	    }
        else 
            {
            context = 0;
            /*
             * Other leading character implies this is a filename ...
             */
	    if (!$VMS_STATUS_SUCCESS(
               find_file_c(argv[0][i], buf, NAM$C_MAXRSS, &context))) 
                {
		/* 
	         * If we can't find the file, forward this along to gzip
		 */
		if (new_argc < max_files) 
                    {
		    vms_argv[new_argc++] = argv[0][i];
		    }
	        }
            else 
                {
		/* 
	         *  Expand the filename
		 */
		p = (char*)xmalloc(strlen(buf)+1);
		strcpy(p, buf);
		if (new_argc < max_files) 
                    {
		    vms_argv[new_argc++] = p;
	            }
		while ($VMS_STATUS_SUCCESS(
                    find_file_c(argv[0][i], buf, NAM$C_MAXRSS, &context))) 
                    {
		    p = (char*)xmalloc(strlen(buf)+1);
		    strcpy(p, buf);
		    if (new_argc < max_files) 
                        {
			vms_argv[new_argc++] = p;
		        }
		    }
	        }
	    }

        /*
         *  if we had to scan for files, free the context block now ... 
         *  (If we don't, we can accumulate wildcard context blocks.)
         */
        if ( context )
            status = lib$find_file_end( &context );

        }

    if (new_argc <= max_files) 
        {
	*old_argc = new_argc;
	vms_argv[new_argc] = NULL;
	*argv = vms_argv;
        } 
    else 
        {
	free(vms_argv); /* the expanded file names should also be freed ... */
	vms_argv = NULL;
	max_files = new_argc + 1;
	vms_expand_args(old_argc, argv);
        }

    return;
    }

