summaryrefslogtreecommitdiff
path: root/vms
diff options
context:
space:
mode:
authorArnold D. Robbins <arnold@skeeve.com>2013-12-12 21:00:00 +0200
committerArnold D. Robbins <arnold@skeeve.com>2013-12-12 21:00:00 +0200
commit07296693d0b748f6e6040f988099177d877f1229 (patch)
treef4edce025ad581ab614fec77ffe7af9be8690005 /vms
parent25e276741ea0a8fb6503a4c060610827dac55825 (diff)
downloadgawk-07296693d0b748f6e6040f988099177d877f1229.tar.gz
Further changes.
Diffstat (limited to 'vms')
-rw-r--r--vms/vms_gawk_main_wrapper.c487
1 files changed, 0 insertions, 487 deletions
diff --git a/vms/vms_gawk_main_wrapper.c b/vms/vms_gawk_main_wrapper.c
deleted file mode 100644
index 367f0cc2..00000000
--- a/vms/vms_gawk_main_wrapper.c
+++ /dev/null
@@ -1,487 +0,0 @@
-/* File: vms_gawk_main_wrapper.c
- *
- * This module provides a wrapper around the main() function of a ported
- * program for two functions:
- *
- * 1. Make sure that the argv[0] string is set as close as possible to
- * what the original command was given.
- *
- * 2. Make sure that the posix exit is called.
- *
- * 3. Fixup the timezone information.
- *
- * Copyright 2012, John Malmberg
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
- * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- *
- */
-
-
-#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-#include <stdlib.h>
-
-#include <descrip.h>
-#include <dvidef.h>
-#include <efndef.h>
-#include <fscndef.h>
-#include <stsdef.h>
-#include <time.h>
-#include <lnmdef.h>
-
-
-#pragma member_alignment save
-#pragma nomember_alignment longword
-struct item_list_3 {
- unsigned short len;
- unsigned short code;
- void * bufadr;
- unsigned short * retlen;
-};
-
-struct filescan_itmlst_2 {
- unsigned short length;
- unsigned short itmcode;
- char * component;
-};
-
-#pragma member_alignment
-
-int SYS$GETDVIW
- (unsigned long efn,
- unsigned short chan,
- const struct dsc$descriptor_s * devnam,
- const struct item_list_3 * itmlst,
- void * iosb,
- void (* astadr)(unsigned long),
- unsigned long astprm,
- void * nullarg);
-
-int SYS$FILESCAN
- (const struct dsc$descriptor_s * srcstr,
- struct filescan_itmlst_2 * valuelist,
- unsigned long * fldflags,
- struct dsc$descriptor_s *auxout,
- unsigned short * retlen);
-
-int SYS$TRNLNM(
- const unsigned long * attr,
- const struct dsc$descriptor_s * table_dsc,
- struct dsc$descriptor_s * name_dsc,
- const unsigned char * acmode,
- const struct item_list_3 * item_list);
-
-/* Take all the fun out of simply looking up a logical name */
-static int sys_trnlnm
- (const char * logname,
- char * value,
- int value_len)
-{
- const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV");
- const unsigned long attr = LNM$M_CASE_BLIND;
- struct dsc$descriptor_s name_dsc;
- int status;
- unsigned short result;
- struct item_list_3 itlst[2];
-
- itlst[0].len = value_len;
- itlst[0].code = LNM$_STRING;
- itlst[0].bufadr = value;
- itlst[0].retlen = &result;
-
- itlst[1].len = 0;
- itlst[1].code = 0;
-
- name_dsc.dsc$w_length = strlen(logname);
- name_dsc.dsc$a_pointer = (char *)logname;
- name_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
- name_dsc.dsc$b_class = DSC$K_CLASS_S;
-
- status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst);
-
- if ($VMS_STATUS_SUCCESS(status)) {
-
- /* Null terminate and return the string */
- /*--------------------------------------*/
- value[result] = '\0';
- }
-
- return status;
-}
-
-int original_main(int argc, char ** argv, char **env);
-
-int main(int argc, char ** argv, char **env) {
-int status;
-int result;
-char arg_nam[256];
-char **new_argv;
-char *tz_rule;
-
-#ifdef TEST_MAIN
- printf("original argv[0] = %s\n", argv[0]);
-#endif
-
- new_argv = argv;
- result = 0;
-
- /* If the path name starts with a /, then it is an absolute path */
- /* that may have been generated by the CRTL instead of the command name */
- /* If it is the device name between the slashes, then this was likely */
- /* from the run command and needs to be fixed up. */
- /* If the DECC$POSIX_COMPLIANT_PATHNAMES is set to 2, then it is the */
- /* DISK$VOLUME that will be present, and it will still need to be fixed. */
- if (argv[0][0] == '/') {
- char * nextslash;
- int length;
- struct item_list_3 itemlist[3];
- unsigned short dvi_iosb[4];
- char alldevnam[64];
- unsigned short alldevnam_len;
- struct dsc$descriptor_s devname_dsc;
- char diskvolnam[256];
- unsigned short diskvolnam_len;
-
- /* Get some information about the disk */
- /*--------------------------------------*/
- itemlist[0].len = (sizeof alldevnam) - 1;
- itemlist[0].code = DVI$_ALLDEVNAM;
- itemlist[0].bufadr = alldevnam;
- itemlist[0].retlen = &alldevnam_len;
- itemlist[1].len = (sizeof diskvolnam) - 1 - 5;
- itemlist[1].code = DVI$_VOLNAM;
- itemlist[1].bufadr = &diskvolnam[5];
- itemlist[1].retlen = &diskvolnam_len;
- itemlist[2].len = 0;
- itemlist[2].code = 0;
-
- /* Add the prefix for the volume name. */
- /* SYS$GETDVI will append the volume name to this */
- strcpy(diskvolnam,"DISK$");
-
- nextslash = strchr(&argv[0][1], '/');
- if (nextslash != NULL) {
- length = nextslash - argv[0] - 1;
-
- /* Cast needed for HP C compiler diagnostic */
- devname_dsc.dsc$a_pointer = (char *)&argv[0][1];
- devname_dsc.dsc$w_length = length;
- devname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
- devname_dsc.dsc$b_class = DSC$K_CLASS_S;
-
- status = SYS$GETDVIW
- (EFN$C_ENF,
- 0,
- &devname_dsc,
- itemlist,
- dvi_iosb,
- NULL, 0, 0);
- if (!$VMS_STATUS_SUCCESS(status)) {
- /* If the sys$getdviw fails, then this path was passed by */
- /* An exec() program and not from DCL, so do nothing */
- /* An example is "/tmp/program" where tmp: does not exist */
-#ifdef TEST_MAIN
- printf("sys$getdviw failed with status %d\n", status);
-#endif
- result = 0;
- } else if (!$VMS_STATUS_SUCCESS(dvi_iosb[0])) {
-#ifdef TEST_MAIN
- printf("sys$getdviw failed with iosb %d\n", dvi_iosb[0]);
-#endif
- result = 0;
- } else {
- char * devnam;
- int devnam_len;
- char argv_dev[64];
-
- /* Null terminate the returned alldevnam */
- alldevnam[alldevnam_len] = 0;
- devnam = alldevnam;
- devnam_len = alldevnam_len;
-
- /* Need to skip past any leading underscore */
- if (devnam[0] == '_') {
- devnam++;
- devnam_len--;
- }
-
- /* And remove the trailing colon */
- if (devnam[devnam_len - 1] == ':') {
- devnam_len--;
- devnam[devnam_len] = 0;
- }
-
- /* Null terminate the returned volnam */
- diskvolnam_len += 5;
- diskvolnam[diskvolnam_len] = 0;
-
- /* Check first for normal CRTL behavior */
- if (devnam_len == length) {
- strncpy(arg_nam, &argv[0][1], length);
- arg_nam[length] = 0;
- result = (strcasecmp(devnam, arg_nam) == 0);
- }
-
- /* If we have not got a match check for POSIX Compliant */
- /* behavior. To be more accurate, we could also check */
- /* to see if that feature is active. */
- if ((result == 0) && (diskvolnam_len == length)) {
- strncpy(arg_nam, &argv[0][1], length);
- arg_nam[length] = 0;
- result = (strcasecmp(diskvolnam, arg_nam) == 0);
- }
- }
- }
- } else {
- /* The path did not start with a slash, so it could be VMS format */
- /* If it is vms format, it has a volume/device in it as it must */
- /* be an absolute path */
- struct dsc$descriptor_s path_desc;
- int status;
- unsigned long field_flags;
- struct filescan_itmlst_2 item_list[5];
- char * volume;
- char * name;
- int name_len;
- char * ext;
-
- path_desc.dsc$a_pointer = (char *)argv[0]; /* cast ok */
- path_desc.dsc$w_length = strlen(argv[0]);
- path_desc.dsc$b_dtype = DSC$K_DTYPE_T;
- path_desc.dsc$b_class = DSC$K_CLASS_S;
-
- /* Don't actually need to initialize anything buf itmcode */
- /* I just do not like uninitialized input values */
-
- /* Sanity check, this must be the same length as input */
- item_list[0].itmcode = FSCN$_FILESPEC;
- item_list[0].length = 0;
- item_list[0].component = NULL;
-
- /* If the device is present, then it if a VMS spec */
- item_list[1].itmcode = FSCN$_DEVICE;
- item_list[1].length = 0;
- item_list[1].component = NULL;
-
- /* we need the program name and type */
- item_list[2].itmcode = FSCN$_NAME;
- item_list[2].length = 0;
- item_list[2].component = NULL;
-
- item_list[3].itmcode = FSCN$_TYPE;
- item_list[3].length = 0;
- item_list[3].component = NULL;
-
- /* End the list */
- item_list[4].itmcode = 0;
- item_list[4].length = 0;
- item_list[4].component = NULL;
-
- status = SYS$FILESCAN(
- (const struct dsc$descriptor_s *)&path_desc,
- item_list, &field_flags, NULL, NULL);
-
- if ($VMS_STATUS_SUCCESS(status) &&
- (item_list[0].length == path_desc.dsc$w_length) &&
- (item_list[1].length != 0)) {
-
- char * dollar;
- int keep_ext;
- int i;
-
- /* We need the filescan to be successful, */
- /* same length as input, and a volume to be present */
-
- /* Need a new argv array */
- new_argv = malloc((argc + 1) * (sizeof(char *)));
- new_argv[0] = arg_nam;
- i = 1;
- while (i < argc) {
- new_argv[i] = argv[i];
- i++;
- }
-
- /* We will assume that we only get to this path on a version */
- /* of VMS that does not support the EFS character set */
-
- /* There may be a xxx$ prefix on the image name. Linux */
- /* programs do not handle that well, so strip the prefix */
- name = item_list[2].component;
- name_len = item_list[2].length;
- dollar = strrchr(name, '$');
- if (dollar != NULL) {
- dollar++;
- name_len = name_len - (dollar - name);
- name = dollar;
- }
-
- strncpy(arg_nam, name, name_len);
- arg_nam[name_len] = 0;
-
- /* We only keep the extension if it is not ".exe" */
- keep_ext = 0;
- ext = item_list[3].component;
-
- if (item_list[3].length != 1) {
- if (item_list[3].length != 4) {
- keep_ext = 1;
- } else {
- int x;
- x = strncmp(ext, ".exe", 4);
- if (x != 0) {
- keep_ext = 1;
- }
- }
- }
-
- if (keep_ext == 1) {
- strncpy(&arg_nam[name_len], ext, item_list[3].length);
- }
- }
- }
-
- if (result) {
- char * lastslash;
- char * dollar;
- char * dotexe;
- char * lastdot;
- char * extension;
-
- /* This means it is probably the name from a DCL command */
- /* Find the last slash which separates the file from the */
- /* path. */
- lastslash = strrchr(argv[0], '/');
-
- if (lastslash != NULL) {
- int i;
-
- lastslash++;
-
- /* There may be a xxx$ prefix on the image name. Linux */
- /* programs do not handle that well, so strip the prefix */
- dollar = strrchr(lastslash, '$');
-
- if (dollar != NULL) {
- dollar++;
- lastslash = dollar;
- }
-
- strcpy(arg_nam, lastslash);
-
- /* In UNIX mode + EFS character set, there should not be a */
- /* version present, as it is not possible when parsing to */
- /* tell if it is a version or part of the UNIX filename as */
- /* UNIX programs use numeric extensions for many reasons. */
-
- lastdot = strrchr(arg_nam, '.');
- if (lastdot != NULL) {
- int i;
-
- i = 1;
- while (isdigit(lastdot[i])) {
- i++;
- }
- if (lastdot[i] == 0) {
- *lastdot = 0;
- }
- }
-
- /* Find the .exe on the name (case insenstive) and toss it */
- dotexe = strrchr(arg_nam, '.');
- if (dotexe != NULL) {
- if ((dotexe[1] == 'e' || dotexe[1] == 'E') &&
- (dotexe[2] == 'x' || dotexe[2] == 'X') &&
- (dotexe[3] == 'e' || dotexe[3] == 'E') &&
- (dotexe[4] == 0)) {
-
- *dotexe = 0;
- } else {
- /* Also need to handle a null extension because of a */
- /* CRTL bug. */
- if (dotexe[1] == 0) {
- *dotexe = 0;
- }
- }
- }
-
- /* Need a new argv array */
- new_argv = malloc((argc + 1) * (sizeof(char *)));
- new_argv[0] = arg_nam;
- i = 1;
- while (i < argc) {
- new_argv[i] = argv[i];
- i++;
- }
- new_argv[i] = 0;
-
- } else {
- /* There is no way that the code should ever get here */
- /* As we already verified that the '/' was present */
- fprintf(stderr, "Sanity failure somewhere we lost a '/'\n");
- }
-
- }
-
- /*
- * The vms_main_wrapper fixes up the name, but for the DCL shell
- * may leave it in upper case, which messes up the self tests.
- * force it to lower case here.
- */
- char * shell;
- int lcname = 0;
- shell = getenv("SHELL");
- if (shell != NULL) {
- if (strcmp(shell, "DCL") == 0) {
- lcname = 1;
- }
- } else {
- lcname = 1;
- }
- if (lcname == 1) {
- int i = 0;
- while (new_argv[0][i] != 0) {
- new_argv[0][i] = tolower(new_argv[0][i]);
- i++;
- }
- }
-
- /* Fix up the time zone */
- tz_rule = malloc(1024);
- status = sys_trnlnm("TZ", tz_rule, 1024);
- if ($VMS_STATUS_SUCCESS(status)) {
- setenv("TZ", tz_rule, 1);
- } else {
- status = sys_trnlnm("SYS$TIMEZONE_RULE", tz_rule, 1024);
- if ($VMS_STATUS_SUCCESS(status)) {
- setenv("TZ", tz_rule, 1);
- }
- }
- free(tz_rule);
-
- exit(original_main(argc, new_argv, env));
- return 1; /* Needed to silence compiler diagnostic */
-}
-
-#define main original_main
-
-#ifdef TEST_MAIN
-
-int main(int argc, char ** argv, char **env) {
-
- printf("modified argv[0] = %s\n", argv[0]);
-
- return 0;
-}
-
-#endif