Blame vms/vms_cli.c

Packit 575503
/* vms_cli.c -- interface to CLI$xxx routines for fetching command line components
Packit 575503
Packit 575503
   Copyright (C) 1991-1993, 2003, 2011, 2014, 2016
Packit 575503
   the Free Software Foundation, Inc.
Packit 575503
Packit 575503
   This program is free software; you can redistribute it and/or modify
Packit 575503
   it under the terms of the GNU General Public License as published by
Packit 575503
   the Free Software Foundation; either version 2, or (at your option)
Packit 575503
   any later version.
Packit 575503
Packit 575503
   This program is distributed in the hope that it will be useful,
Packit 575503
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 575503
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 575503
   GNU General Public License for more details.
Packit 575503
Packit 575503
   You should have received a copy of the GNU General Public License
Packit 575503
   along with this program; if not, write to the Free Software Foundation,
Packit 575503
   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
Packit 575503
Packit 575503
Packit 575503
/*
Packit 575503
 * vms_cli.c - command line interface routines.
Packit 575503
 *							Pat Rankin, Nov'89
Packit 575503
 *	Routines called from vms_gawk.c for DCL parsing.
Packit 575503
 */
Packit 575503
Packit 575503
#include "config.h"	/* in case we want to suppress 'const' &c */
Packit 575503
#include "vms.h"
Packit 575503
#ifndef _STRING_H
Packit 575503
#include <string.h>
Packit 575503
#endif
Packit 575503
Packit 575503
extern U_Long CLI$PRESENT(const struct dsc$descriptor_s *);
Packit 575503
extern U_Long CLI$GET_VALUE(const struct dsc$descriptor_s *,
Packit 575503
                            struct dsc$descriptor_s *, short *);
Packit 575503
extern U_Long CLI$DCL_PARSE(const struct dsc$descriptor_s *, const void *, ...);
Packit 575503
extern U_Long SYS$CLI(void *, ...);
Packit 575503
extern U_Long SYS$FILESCAN(const struct dsc$descriptor_s *, void *, long *);
Packit 575503
extern void  *LIB$ESTABLISH(U_Long (*handler)(void *, void *));
Packit 575503
extern U_Long LIB$SIG_TO_RET(void *, void *);	/* condition handler */
Packit 575503
Packit 575503
/* Cli_Present() - call CLI$PRESENT to determine whether a parameter or     */
Packit 575503
/*		  qualifier is present on the [already parsed] command line */
Packit 575503
U_Long
Packit 575503
Cli_Present( const char *item )
Packit 575503
{
Packit 575503
    struct dsc$descriptor_s item_dsc;
Packit 575503
    (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
Packit 575503
Packit 575503
    item_dsc.dsc$w_length = strlen(item_dsc.dsc$a_pointer = (char *)item);
Packit 575503
    item_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
Packit 575503
    item_dsc.dsc$b_class = DSC$K_CLASS_S;
Packit 575503
    return CLI$PRESENT(&item_dsc);
Packit 575503
}
Packit 575503
Packit 575503
/* Cli_Get_Value() - call CLI$GET_VALUE to retreive the value of a */
Packit 575503
/*		    parameter or qualifier from the command line   */
Packit 575503
U_Long
Packit 575503
Cli_Get_Value( const char *item, char *result, int size )
Packit 575503
{
Packit 575503
    struct dsc$descriptor_s item_dsc, res_dsc;
Packit 575503
    U_Long sts;
Packit 575503
    short len = 0;
Packit 575503
    (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
Packit 575503
Packit 575503
    item_dsc.dsc$w_length = strlen(item_dsc.dsc$a_pointer = (char *)item);
Packit 575503
    item_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
Packit 575503
    item_dsc.dsc$b_class = DSC$K_CLASS_S;
Packit 575503
    res_dsc.dsc$w_length = size;
Packit 575503
    res_dsc.dsc$a_pointer = result;
Packit 575503
    res_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
Packit 575503
    res_dsc.dsc$b_class = DSC$K_CLASS_S;
Packit 575503
    sts = CLI$GET_VALUE(&item_dsc, &res_dsc, &len;;
Packit 575503
    result[len] = '\0';
Packit 575503
    return sts;
Packit 575503
}
Packit 575503
Packit 575503
/* Cli_Parse_Command() - use the $CLI system service (undocumented) to	 */
Packit 575503
/*			retreive the actual command line (which might be */
Packit 575503
/*			"run prog" or "mcr prog [params]") and then call */
Packit 575503
/*			CLI$DCL_PARSE to parse it using specified tables */
Packit 575503
U_Long
Packit 575503
Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb )
Packit 575503
{
Packit 575503
    struct { short len, code; void *adr; } fscn[2];
Packit 575503
    struct { char rqtype, rqindx, rqflags, rqstat; unsigned :32;
Packit 575503
	     struct dsc$descriptor_s rdesc;
Packit 575503
             unsigned :32; unsigned :32; unsigned :32; } cmd;
Packit 575503
    U_Long sts;
Packit 575503
    int    ltmp;
Packit 575503
    char   longbuf[8200];
Packit 575503
    (void)LIB$ESTABLISH(LIB$SIG_TO_RET);
Packit 575503
Packit 575503
    memset(&cmd, 0, sizeof cmd);
Packit 575503
    cmd.rqtype = CLI$K_GETCMD;		/* command line minus the verb */
Packit 575503
    sts = SYS$CLI(&cmd, (void *)0, (void *)0);	/* get actual command line */
Packit 575503
Packit 575503
    if (vmswork(sts)) {		/* ok => cli available & verb wasn't "RUN" */
Packit 575503
	/* invoked via symbol => have command line (which might be empty) */
Packit 575503
	/*    [might also be invoked via mcr or dcl; that's ok]		  */
Packit 575503
	if (cmd.rqstat == CLI$K_VERB_MCR) {
Packit 575503
	    /* need to strip image name from MCR invocation   */
Packit 575503
	    memset(fscn, 0, sizeof fscn);
Packit 575503
	    fscn[0].code = FSCN$_FILESPEC;	/* full file specification */
Packit 575503
	    (void)SYS$FILESCAN(&cmd.rdesc, fscn, (long *)0);
Packit 575503
	    cmd.rdesc.dsc$w_length -= fscn[0].len;	/* shrink size */
Packit 575503
	    cmd.rdesc.dsc$a_pointer += fscn[0].len;	/* advance ptr */
Packit 575503
	}
Packit 575503
	/* prepend verb and then parse the command line */
Packit 575503
	strcat(strcpy(longbuf, cmd_verb), " "),  ltmp = strlen(longbuf);
Packit 575503
	if (cmd.rdesc.dsc$w_length + ltmp > sizeof longbuf)
Packit 575503
	    cmd.rdesc.dsc$w_length = sizeof longbuf - ltmp;
Packit 575503
	strncpy(&longbuf[ltmp],
Packit 575503
                cmd.rdesc.dsc$a_pointer, cmd.rdesc.dsc$w_length);
Packit 575503
	cmd.rdesc.dsc$w_length += ltmp,	cmd.rdesc.dsc$a_pointer = longbuf;
Packit 575503
	sts = CLI$DCL_PARSE(&cmd.rdesc, cmd_tables);
Packit 575503
    }
Packit 575503
Packit 575503
    return sts;
Packit 575503
}