Blame vms/vms_cli.c

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