main() { int retlen=0; $DESCRIPTOR(p, "p1"); char c[80]; struct dsc$descriptor o; o.dsc$a_pointer=c; o.dsc$w_length=80; memset (c, 0, 80); int sts = cli$present(&p); if (sts&1) { sts = lib$get_foreign(&o, 0, &retlen, 0); o.dsc$w_length=retlen; char * ostr = strchr(o.dsc$a_pointer, ' '); int olen = ostr - (char *)o.dsc$a_pointer; if (0==strncasecmp(o.dsc$a_pointer, "install", olen)) { memset(o.dsc$a_pointer, 32, olen); } o.dsc$a_pointer+=olen+1; o.dsc$w_length-=olen+1; printf("o is %s\n",o.dsc$a_pointer); fflush(stdout); int sts = cli$dcl_parse(&o, &sysman_parse, 0, 0, 0); if (sts&1) cli$dispatch(0); return 1; } while(!do_ret) { printf("SYSMAN> "); fflush(stdout); char command_str[256]; int len = read (0, command_str, 255); struct dsc$descriptor command_line; command_line.dsc$a_pointer = command_str; command_line.dsc$w_length = len; extern int hexmode; hexmode = 1; // temp workaround int sts = cli$dcl_parse(&command_line, sysman_parse, 0, 0, 0); hexmode = 0; if (sts&1) cli$dispatch(0); } }
/* **++ ** ROUTINE: main ** ** FUNCTIONAL DESCRIPTION: ** ** Main program. Fetches the command from the command line, ** uses CLI$ routines to parse it, then starts the build process. ** ** RETURNS: cond_value, longword (unsigned), write only, by value ** ** PROTOTYPE: ** ** main ** ** IMPLICIT INPUTS: See global definitions at module head. ** ** IMPLICIT OUTPUTS: See global definitions at module head. ** ** COMPLETION CODES: ** ** SS$_NORMAL, MMK__ALLOK : normal successful completion. ** ** SIDE EFFECTS: None. ** **-- */ unsigned int main (void) { DESCRIP cmdstr; char Output_File[256], tmp[256]; $DESCRIPTOR(cmdname, "MMKC "); unsigned int status; int i; /* ** Initialize the globals */ temporary_symbols = 0; for (i = 0; i < MMK_K_SYMTABLE_SIZE; i++) { INIT_QUEUE(global_symbols.symlist[i]); INIT_QUEUE(local_symbols.symlist[i]); INIT_QUEUE(cmdline_symbols.symlist[i]); INIT_QUEUE(builtin_symbols.symlist[i]); } INIT_QUEUE(rules); INIT_QUEUE(dependencies); INIT_QUEUE(dep_internal); INIT_QUEUE(dep_deferred); INIT_QUEUE(suffixes); INIT_QUEUE(do_first); INIT_QUEUE(do_last); exit_status = SS$_NORMAL; ignore = override_silent = override_ignore = symbol_override = 0; skip_intermediates = 0; /* ** Fetch and parse command string */ INIT_DYNDESC(cmdstr); status = lib$get_foreign(&cmdstr); str$prefix(&cmdstr, &cmdname); status = cli$dcl_parse(&cmdstr, MMK_COMPILE_RULES_CLD, lib$get_input, lib$get_input); if (!OK(status)) return (status | STS$M_INHIB_MSG); /* ** Get the command parameters and qualifiers */ Output_File[0] = '\0'; if (cli_present("OUTPUT") == CLI$_PRESENT) { cli_get_value("OUTPUT", Output_File, sizeof(Output_File)); } status = cli_get_value("RULES_FILE", tmp, sizeof(tmp)); if (!OK(status)) return status | STS$M_INHIB_MSG; Read_Description(tmp, "SYS$DISK:[].MMS", 1); if (OK(exit_status)) Generate_Structures(tmp, Output_File); return exit_status | STS$M_INHIB_MSG; }
/* CLI$DCL_PARSE to parse it using specified tables */ U_Long Cli_Parse_Command( const void *cmd_tables, const char *cmd_verb ) { struct { short len, code; void *adr; } fscn[2]; struct { char rqtype, rqindx, rqflags, rqstat; unsigned :32; Dsc rdesc; unsigned :32; unsigned :32; unsigned :32; } cmd; U_Long sts; int ltmp; char longbuf[8200]; (void)lib$establish(lib$sig_to_ret); memset(&cmd, 0, sizeof cmd); cmd.rqtype = CLI$K_GETCMD; /* command line minus the verb */ sts = sys$cli(&cmd, (void *)0, (void *)0); /* get actual command line */ if (vmswork(sts)) { /* ok => cli available & verb wasn't "RUN" */ /* invoked via symbol => have command line (which might be empty) */ /* [might also be invoked via mcr or dcl; that's ok] */ if (cmd.rqstat == CLI$K_VERB_MCR) { /* need to strip image name from MCR invocation */ memset(fscn, 0, sizeof fscn); fscn[0].code = FSCN$_FILESPEC; /* full file specification */ (void)sys$filescan(&cmd.rdesc, fscn, (long *)0); cmd.rdesc.len -= fscn[0].len; /* shrink size */ cmd.rdesc.adr += fscn[0].len; /* advance ptr */ } /* prepend verb and then parse the command line */ strcat(strcpy(longbuf, cmd_verb), " "), ltmp = strlen(longbuf); if (cmd.rdesc.len + ltmp > sizeof longbuf) cmd.rdesc.len = sizeof longbuf - ltmp; strncpy(&longbuf[ltmp], cmd.rdesc.adr, cmd.rdesc.len); cmd.rdesc.len += ltmp, cmd.rdesc.adr = longbuf; sts = cli$dcl_parse(&cmd.rdesc, cmd_tables); } return sts; }
license_adm() { int cli$dispatch() ; int4 stat0 ; int4 stat1 ; int4 fl= 0 ; char *ln[2]= { LADB,LAFILE } ; char buf[256] ; unsigned short len ; bool rep; $DESCRIPTOR (prompt,"LMA> ") ; $DESCRIPTOR (dbuf,buf) ; stat0= lib$get_foreign(&dbuf,0,&len,&fl); rep = (len==0); do { stat1= cli$dcl_parse(&dbuf,&la_cmnd,&lib$get_input,&lib$get_input,&prompt); if (stat1==CLI$_NORMAL) stat0= cli$dispatch(ln); if (stat0!=RMS$_EOF && rep) stat0= lib$get_foreign(&dbuf,&prompt,&len,&fl); } while (stat0!=RMS$_EOF && rep); return SS$_NORMAL; }
main(int argc, char *argv[]) { long sts ; int i; char str[256] ; int key_id ; unsigned short res_len ; $DESCRIPTOR ( device_desc , "sys$input" ); $DESCRIPTOR ( outdevice_desc , "sys$output" ); $DESCRIPTOR ( prompt_desc , "tlog> " ); struct dsc$descriptor_s str_desc = {sizeof(str)-1,DSC$K_DTYPE_T, DSC$K_CLASS_S, }; str_desc.dsc$a_pointer = str; /* avanti */ /* If arguments, treat them as a command and then exit */ if ( argc >= 2 ) { str[0] = 0; for ( i = 1; i < argc; i++) { if ( i != 1) strcat( str, " "); strcat( str, argv[i]); } sts = cli$dcl_parse ( &str_desc , tlog_cld, 0, 0 , 0 ) ; /* send the command to the rtn associated */ if ( sts == CLI$_NORMAL ) sts = cli$dispatch(); sutil_msg( sts); exit(sts); } /* init input */ sts = smg$create_virtual_keyboard ( &key_id , &device_desc , 0 ,0, 0 ); while ( 1 ) { /* get and parse the command */ /* get input */ sts = smg$read_composed_line ( &key_id , 0, &str_desc , &prompt_desc , &res_len); if ( res_len == 0) continue; if ( !(sts && 1 ) ) lib$signal (sts ) ; str[res_len] = 0 ; sts = cli$dcl_parse ( &str_desc , tlog_cld, 0, 0 , 0 ) ; /* send the command to the rtn associated */ if ( sts == CLI$_NORMAL ) { sts = cli$dispatch ( ) ; sutil_msg( sts); } } }
unsigned long vms_zip_cmdline (int *argc_p, char ***argv_p) { /* ** Routine: vms_zip_cmdline ** ** Function: ** ** Parse the DCL command line and create a fake argv array to be ** handed off to Zip. ** ** NOTE: the argv[] is built as we go, so all the parameters are ** checked in the appropriate order!! ** ** Formal parameters: ** ** argc_p - Address of int to receive the new argc ** argv_p - Address of char ** to receive the argv address ** ** Calling sequence: ** ** status = vms_zip_cmdline (&argc, &argv); ** ** Returns: ** ** SS$_NORMAL - Success. ** SS$_INSFMEM - A malloc() or realloc() failed ** SS$_ABORT - Bad time value ** */ register unsigned long status; char options[48]; char *the_cmd_line; /* buffer for argv strings */ unsigned long cmdl_size; /* allocated size of buffer */ unsigned long cmdl_len; /* used size of buffer */ char *ptr; int x, len; int new_argc; char **new_argv; struct dsc$descriptor_d work_str; struct dsc$descriptor_d foreign_cmdline; init_dyndesc(work_str); init_dyndesc(foreign_cmdline); /* ** See if the program was invoked by the CLI (SET COMMAND) or by ** a foreign command definition. Check for /YYZ_ZIP, which is a ** valid default qualifier solely for this test. */ show_VMSCLI_help = TRUE; status = check_cli(&cli_yyz); if (!(status & 1)) { lib$get_foreign(&foreign_cmdline); /* ** If nothing was returned or the first character is a "-", then ** assume it's a UNIX-style command and return. */ if (foreign_cmdline.dsc$w_length == 0) return (SS$_NORMAL); if ((*(foreign_cmdline.dsc$a_pointer) == '-') || ((foreign_cmdline.dsc$w_length > 1) && (*(foreign_cmdline.dsc$a_pointer) == '"') && (*(foreign_cmdline.dsc$a_pointer + 1) == '-'))) { show_VMSCLI_help = FALSE; return (SS$_NORMAL); } str$concat(&work_str, &zip_command, &foreign_cmdline); status = cli$dcl_parse(&work_str, &zip_clitable, lib$get_input, lib$get_input, 0); if (!(status & 1)) return (status); } /* ** There's always going to be a new_argv[] because of the image name. */ if ((the_cmd_line = (char *) malloc(cmdl_size = ARGBSIZE_UNIT)) == NULL) return (SS$_INSFMEM); strcpy(the_cmd_line, "zip"); cmdl_len = sizeof("zip"); /* ** First, check to see if any of the regular options were specified. */ options[0] = '-'; ptr = &options[1]; /* Point to temporary buffer */ /* ** Delete the specified files from the zip file? */ status = cli$present(&cli_delete); if (status & 1) *ptr++ = 'd'; /* ** Freshen (only changed files). */ status = cli$present(&cli_freshen); if (status & 1) *ptr++ = 'f'; /* ** Delete the files once they've been added to the zip file. */ status = cli$present(&cli_move); if (status & 1) *ptr++ = 'm'; /* ** Add changed and new files. */ status = cli$present(&cli_update); if (status & 1) *ptr++ = 'u'; /* ** Check for the compression level (-0 through -9). */ status = cli$present(&cli_level); if (status & 1) { unsigned long binval; status = cli$get_value(&cli_level, &work_str); status = ots$cvt_tu_l(&work_str, &binval); if (!(status & 1) || (binval > 9)) { return (SS$_ABORT); } *ptr++ = binval + '0'; } /* ** Adjust offsets of zip archive entries. */ status = cli$present(&cli_adjust); if (status & 1) *ptr++ = 'A'; /* ** Add comments? */ status = cli$present(&cli_comments); if (status & 1) { /* while ((status = cli$get_value(&cli_comments, &work_str)) & 1) { if (strncmp(work_str.dsc$a_pointer,"ZIP",3) == 0) *ptr++ = 'z'; if (strncmp(work_str.dsc$a_pointer,"FIL",3) == 0) *ptr++ = 'c'; } */ if ((status = cli$present(&cli_comment_zipfile)) & 1) *ptr++ = 'z'; if ((status = cli$present(&cli_comment_files)) & 1) *ptr++ = 'c'; } /* ** Do not add/modify directory entries. */ status = cli$present(&cli_dirnames); if (!(status & 1)) *ptr++ = 'D'; /* ** Encrypt? */ status = cli$present(&cli_encrypt); if (status & 1) if ((status = cli$get_value(&cli_encrypt, &work_str)) & 1) { x = cmdl_len; cmdl_len += work_str.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-P"); strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } else { *ptr++ = 'e'; } /* ** Fix the zip archive structure. */ status = cli$present(&cli_fix_archive); if (status & 1) { *ptr++ = 'F'; if ((status = cli$present(&cli_fix_full)) & 1) { *ptr++ = 'F'; } } /* ** Append (allow growing of existing zip file). */ status = cli$present(&cli_append); if (status & 1) *ptr++ = 'g'; /* ** Show the help. */ status = cli$present(&cli_help); if (status & 1) *ptr++ = 'h'; /* ** Junk path names (directory specs). */ status = cli$present(&cli_junk); if (status & 1) *ptr++ = 'j'; /* ** Simulate zip file made by PKZIP. */ status = cli$present(&cli_pkzip); if (status & 1) *ptr++ = 'k'; /* ** Translate end-of-line. */ status = cli$present(&cli_translate_eol); if (status & 1) { *ptr++ = 'l'; if ((status = cli$present(&cli_transl_eol_crlf)) & 1) { *ptr++ = 'l'; } } /* ** Show the software license. */ status = cli$present(&cli_license); if (status & 1) *ptr++ = 'L'; /* ** Set zip file time to time of latest file in it. */ status = cli$present(&cli_latest); if (status & 1) *ptr++ = 'o'; /* ** Store full path (default). */ status = cli$present(&cli_full_path); if (status == CLI$_PRESENT) *ptr++ = 'p'; else if (status == CLI$_NEGATED) *ptr++ = 'j'; /* ** Junk Zipfile prefix (SFX stub etc.). */ status = cli$present(&cli_unsfx); if (status & 1) *ptr++ = 'J'; /* ** Recurse through subdirectories. */ status = cli$present(&cli_recurse); if (status & 1) { if ((status = cli$present(&cli_recurse_fnames)) & 1) *ptr++ = 'R'; else *ptr++ = 'r'; } /* ** Be verbose. */ status = cli$present(&cli_verbose); if (status & 1) { int i; int verbo = 0; /* /VERBOSE */ if ((status = cli$present(&cli_verbose_command)) & 1) { /* /VERBOSE = COMMAND */ verbose_command = 1; } /* Note that any or all of the following options may be specified, and the maximum one is used. */ if ((status = cli$present(&cli_verbose_normal)) & 1) /* /VERBOSE [ = NORMAL ] */ verbo = 1; if ((status = cli$present(&cli_verbose_more)) & 1) /* /VERBOSE = MORE */ verbo = 2; if ((status = cli$present(&cli_verbose_debug)) & 1) { /* /VERBOSE = DEBUG */ verbo = 3; } for (i = 0; i < verbo; i++) *ptr++ = 'v'; } /* ** Quiet mode. ** (Quiet mode is processed after verbose, because a "-v" modifier ** resets "noisy" to 1.) */ status = cli$present(&cli_quiet); if (status & 1) *ptr++ = 'q'; /* ** Suppress creation of any extra field. */ status = cli$present(&cli_extra_fields); if (!(status & 1)) *ptr++ = 'X'; /* ** Save the VMS file attributes (and all allocated blocks?). */ status = cli$present(&cli_vms); if (status & 1) { /* /VMS */ *ptr++ = 'V'; if ((status = cli$present(&cli_vms_all)) & 1) { /* /VMS = ALL */ *ptr++ = 'V'; } } /* ** Keep the VMS version number as part of the file name when stored. */ status = cli$present(&cli_keep_version); if (status & 1) *ptr++ = 'w'; /* ** `Batch' processing: read filenames to archive from stdin ** or the specified file. */ status = cli$present(&cli_batch); if (status & 1) { status = cli$get_value(&cli_batch, &work_str); if (status & 1) { work_str.dsc$a_pointer[work_str.dsc$w_length] = '\0'; if ((stdin = freopen(work_str.dsc$a_pointer, "r", stdin)) == NULL) { sprintf(errbuf, "could not open list file: %s", work_str.dsc$a_pointer); ziperr(ZE_PARMS, errbuf); } } *ptr++ = '@'; } /* ** Now copy the final options string to the_cmd_line. */ len = ptr - &options[0]; if (len > 1) { options[len] = '\0'; x = cmdl_len; cmdl_len += len + 1; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], options); } /* ** ** OK. We've done all the regular options, so check for -b (temporary ** file path), -t (exclude before time), -n (special suffixes), zipfile, ** files to zip, and exclude list. ** */ status = cli$present(&cli_temp_path); if (status & 1) { status = cli$get_value(&cli_temp_path, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-b"); strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Demand that all input files exist (and wildcards match something). */ #define OPT_MM "-MM" /* Input file specs must exist. */ status = cli$present(&cli_must_match); if (status & 1) { x = cmdl_len; cmdl_len += strlen( OPT_MM)+ 1; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy( &the_cmd_line[ x], OPT_MM); } /* ** Handle "-t mmddyyyy". */ status = cli$present(&cli_since); if (status & 1) { char since_time[9]; status = get_time(&cli_since, &since_time[0]); if (!(status & 1)) return (status); /* ** Now let's add the option "-t mmddyyyy" to the new command line. */ x = cmdl_len; cmdl_len += (3 + 9); CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-t"); strcpy(&the_cmd_line[x+3], since_time); } /* ** Handle "-tt mmddyyyy". */ status = cli$present(&cli_before); if (status & 1) { char before_time[9]; status = get_time(&cli_before, &before_time[0]); if (!(status & 1)) return (status); /* ** Now let's add the option "-tt mmddyyyy" to the new command line. */ x = cmdl_len; cmdl_len += (4 + 9); CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-tt"); strcpy(&the_cmd_line[x+4], before_time); } /* ** Handle "-n suffix:suffix:...". (File types to store only.) */ status = cli$present(&cli_store_types); if (status & 1) { x = cmdl_len; cmdl_len += 3; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-n"); status = get_list(&cli_store_types, &foreign_cmdline, ':', &the_cmd_line, &cmdl_size, &cmdl_len); if (!(status & 1)) return (status); } /* ** Now get the specified zip file name. */ status = cli$present(&cli_zipfile); if (status & 1) { status = cli$get_value(&cli_zipfile, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 1; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strncpy(&the_cmd_line[x], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Run through the list of input files. */ status = cli$present(&cli_infile); if (status & 1) { status = get_list(&cli_infile, &foreign_cmdline, '\0', &the_cmd_line, &cmdl_size, &cmdl_len); if (!(status & 1)) return (status); } /* ** List file containing exclude patterns present? ("*****@*****.**") */ status = cli$present(&cli_exlist); if (status & 1) { status = cli$get_value(&cli_exlist, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strncpy(&the_cmd_line[x], "-x@", 3); strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Any files to exclude? ("-x file file") */ status = cli$present(&cli_exclude); if (status & 1) { x = cmdl_len; cmdl_len += 3; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-x"); status = get_list(&cli_exclude, &foreign_cmdline, '\0', &the_cmd_line, &cmdl_size, &cmdl_len); if (!(status & 1)) return (status); } /* ** List file containing include patterns present? ("*****@*****.**") */ status = cli$present(&cli_inlist); if (status & 1) { status = cli$get_value(&cli_inlist, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strncpy(&the_cmd_line[x], "-i@", 3); strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Any files to include? ("-i file file") */ status = cli$present(&cli_include); if (status & 1) { x = cmdl_len; cmdl_len += 3; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-i"); status = get_list(&cli_exclude, &foreign_cmdline, '\0', &the_cmd_line, &cmdl_size, &cmdl_len); if (!(status & 1)) return (status); } /* ** We have finished collecting the strings for the argv vector, ** release unused space. */ if ((the_cmd_line = (char *) realloc(the_cmd_line, cmdl_len)) == NULL) return (SS$_INSFMEM); /* ** Now that we've built our new UNIX-like command line, count the ** number of args and build an argv array. */ for (new_argc = 0, x = 0; x < cmdl_len; x++) if (the_cmd_line[x] == '\0') new_argc++; /* ** Allocate memory for the new argv[]. The last element of argv[] ** is supposed to be NULL, so allocate enough for new_argc+1. */ if ((new_argv = (char **) calloc(new_argc+1, sizeof(char *))) == NULL) return (SS$_INSFMEM); /* ** For each option, store the address in new_argv[] and convert the ** separating blanks to nulls so each argv[] string is terminated. */ for (ptr = the_cmd_line, x = 0; x < new_argc; x++) { new_argv[x] = ptr; ptr += strlen(ptr) + 1; } new_argv[new_argc] = NULL; #if defined(TEST) || defined(DEBUG) printf("new_argc = %d\n", new_argc); for (x = 0; x < new_argc; x++) printf("new_argv[%d] = %s\n", x, new_argv[x]); #endif /* TEST || DEBUG */ /* Show the complete UNIX command line, if requested. */ if (verbose_command != 0) { printf( " UNIX command line args (argc = %d):\n", new_argc); for (x = 0; x < new_argc; x++) printf( "%s\n", new_argv[ x]); printf( "\n"); } /* ** All finished. Return the new argc and argv[] addresses to Zip. */ *argc_p = new_argc; *argv_p = new_argv; return (SS$_NORMAL); }
parse_vms_args(int *argc, char **argv[]) { static char command[S_LENGTH], value_template[S_LENGTH]; static char qual_template[S_LENGTH]; char verb[] = "VARG "; char *vms_arg[MAX_ARGS]; char *unix_arg[MAX_ARGS]; char *unix_narg[MAX_ARGS]; char *vms_key[MAX_ARGS]; char *unix_key[MAX_ARGS]; char *separator[MAX_ARGS]; char *pattern[MAX_ARGS]; char *outverb, *arg_symbol, *image_name; char foreign_image[S_LENGTH]; int flags[MAX_ARGS], action_flags; int nvargs, u_length, l_element, index; char arg_string[S_LENGTH], arg_element[S_LENGTH]; static char value[S_LENGTH]; char *special_chars; char default_special[] = "!@#^&()=+\'\"/?,"; $DESCRIPTOR(command_desc, command); $DESCRIPTOR(qual_desc, ""); $DESCRIPTOR(value_desc, value); int i, length, status, i_length, arg_count, q_length; static char command_args[S_LENGTH]; $DESCRIPTOR(command_arg_desc, command_args); extern VARG_CLD; static char *newargv[MAX_ARGS]; int affirm_flag, negative_flag, keywords_flag, separator_flag; int date_flag, append_flag, present, more_flag, multivalue, help_flag; int vmsarg_mapping(); /* Get the VMS -> Unix mapping definitions from the routine generated by the GEN_MAPPING utility. */ vmsarg_mapping(&nvargs, vms_arg, unix_arg, unix_narg, vms_key, unix_key, separator, flags, pattern, &outverb, &action_flags, &arg_symbol, &image_name ); /* Get the original command line from the foreign command utility. */ length = 0; /* RTL only writes word */ lib$get_foreign(&command_arg_desc, 0, &length); command_args[length] = 0; /* add NULL terminator */ /* Check to see if any of the exising arguments start with a "-" character. if so, assume he's already using Unix style arguments so we don't have to do anything. Only do this if the Unix_Arg bit is set in the action flags. */ if ((action_flags & VARGACT_M_UNIXARG)) { for (i = 1; i <= *argc - 1; i++) if ((*argv) [i][0] == '-') { /* He's using Unix style args. */ if ((action_flags & VARGACT_M_RETURN)) { return 1; /* back out quietly */ } else { status = varg_do_exit(action_flags, arg_symbol, command_args, image_name, outverb); sys$exit(status); /* exit with DCL stuff done */ } } } /* Catenate verb and arguments into the command string for DCL to parse. */ strcpy(command, verb); strcat(command, command_args); command_desc.dsc$w_length = strlen(verb) + strlen(command_args); /* Pass it to the DCL parser for its approval. */ status = cli$dcl_parse(&command_desc, &VARG_CLD); if ((status & 1) != 1) sys$exit (status); /* Now that DCL is happy, we go through all the defined VMS qualifiers and parameters to check if they are present or defaulted. */ arg_count = 0; /* so far so good */ for (i = 1; i <= nvargs; i++) { /* Set The various flags for this qualifier. */ affirm_flag = (VARG_M_AFFIRM & flags[i]) != 0; negative_flag = (VARG_M_NEGATIVE & flags[i]) != 0; keywords_flag = (VARG_M_KEYWORDS & flags[i]) != 0; separator_flag = (VARG_M_SEPARATOR & flags[i]) != 0; date_flag = (VARG_M_DATE & flags[i]) != 0; append_flag = (VARG_M_APPEND & flags[i]) != 0; help_flag = (VARG_M_HELP & flags[i]) != 0; /* Check if the qualifier or parameter is present */ qual_desc.dsc$w_length = strlen(vms_arg[i]); qual_desc.dsc$a_pointer = vms_arg[i]; present = cli$present(&qual_desc) & 1; /* if the qualifier is present, and there is a positive translation, then replace the VMS qualifier by its Unix equivalent. Note that if the Unix equivalent starts with a '$', then it is a parameter and we omit the qualifier name, only putting in the value. */ qual_template[0] = 0; /* zero string initially */ if (present && affirm_flag) { if (unix_arg[i][0] != '$') strcpy(qual_template, unix_arg[i]); } if (!(present & 1) && negative_flag) /* NOT present AND negative_flag */ { strcpy(qual_template, unix_narg[i]); } /* Get the first value (if any). We may have to catenate this with the qualifier keyword, or build up multiple values in a single argv element. */ if (present) { value_desc.dsc$w_length = QUAL_LENGTH; status = cli$get_value(&qual_desc, &value_desc, &length); if ((status & 1) != 1) length = 0; value[length] = 0; /* NULL terminator */ more_flag = status == CLI$_COMMA; } else { length = 0; } /* if the /APPEND qualifier was used, then the qualifier and its value are in the same argv element. */ if (append_flag) { strcpy(value_template, qual_template); } else { /* Allocate a fresh argv element and load the Unix keyword into it. */ q_length = strlen(qual_template); if (q_length != 0) { Increment(arg_count); newargv[arg_count] = malloc(q_length + 1); if (newargv[arg_count] == NULL) sys$exit(LIB$_INSVIRMEM); strcpy(newargv[arg_count], qual_template); } } multivalue = more_flag; /* Get all the various values and either append them with appropriate separators to the current template, or load them in successive argv elements. */ while (affirm_flag && (length != 0)) { /* if a keyword list is involved, get the corresponding field from the Unix equivalent. */ if (keywords_flag) { index = varg_get_index(value, vms_key[i]); varg_set_index(value, unix_key[i], index); } /* if the /DATE qualifier was present, we interpret the value as a VMS date/time specification, and convert it to the equivalent Unix type string. */ if (date_flag) varg_convert_date(value, pattern[i]); /* Add the current value to the template so far. Add a separator character if we need one. */ strcat(value_template, value); if (separator_flag) { if (more_flag) strcat(value_template, separator[i]); } else { /* Each value should have its own argv element. */ Increment(arg_count); newargv[arg_count] = malloc(strlen(value_template) + 1); if (newargv[arg_count] == NULL) sys$exit(LIB$_INSVIRMEM); strcpy(newargv[arg_count], value_template); value_template[0] = 0; } /* Get the next value from the DCL parser. */ value_desc.dsc$w_length = QUAL_LENGTH; /* reset string */ status = cli$get_value(&qual_desc, &value_desc, &length); if ((status & 1) != 1) length = 0; value[length] = 0; more_flag = status == CLI$_COMMA; } /* All the values are in for this qualifier - if there were being stacked up then load them all into an argv element. */ if (separator_flag & multivalue) { Increment(arg_count); newargv[arg_count] = malloc(strlen(value_template) + 1); if (newargv[arg_count] == NULL) sys$exit(LIB$_INSVIRMEM); strcpy(newargv[arg_count], value_template); value_template[0] = 0; } /* Check to see if this is a HELP directive. if so, then the help library name is stored in pattern[i] and the initial help string in unix_arg[i] */ if ((present &1) && help_flag) { varg_do_help(pattern[i], unix_arg[i]); } /* And around for the next qualifier. */ } /* We've built the argument vector. Now lets find out what we're supposed to do with it. */ if ((action_flags & VARGACT_M_RETURN)) { /* We should return the result to the caller. Set the corresponding argc & argv variables in the caller to point at these. Make sure the new argv contains the same [0] element as the old one (program name). */ *argc = arg_count + 1; newargv[0] = (*argv)[0]; *argv = newargv; return 1; } /* We must convert the argv elements into an arg string. */ arg_string[0] = 0; special_chars = default_special; for (i = 1; i <= arg_count; i++) { varg_protect_string(newargv[i], arg_element, action_flags, special_chars); strcat(arg_string, arg_element); if (i != arg_count) strcat(arg_string, " "); } status = varg_do_exit(action_flags, arg_symbol, arg_string, image_name, outverb); /* if we got this far then exit to DCL. */ sys$exit(status); }