|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* gawkmisc.vms --- miscellanious gawk routines that are OS specific.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* Copyright (C) 1986, 1988, 1989, 1991-1996, 2003, 2011, 2014
|
|
Packit |
575503 |
* the Free Software Foundation, Inc.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* This file is part of GAWK, the GNU implementation of the
|
|
Packit |
575503 |
* AWK Progamming Language.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* GAWK 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 3 of the License, or
|
|
Packit |
575503 |
* (at your option) any later version.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* GAWK 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
|
|
Packit |
575503 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include <stdio.h>
|
|
Packit |
575503 |
#include <string.h>
|
|
Packit |
575503 |
#include <ctype.h>
|
|
Packit |
575503 |
#include <stdlib.h>
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#include <descrip.h>
|
|
Packit |
575503 |
#include <dvidef.h>
|
|
Packit |
575503 |
#include <efndef.h>
|
|
Packit |
575503 |
#include <fscndef.h>
|
|
Packit |
575503 |
#include <stsdef.h>
|
|
Packit |
575503 |
#include <time.h>
|
|
Packit |
575503 |
#include <lnmdef.h>
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#pragma member_alignment save
|
|
Packit |
575503 |
#pragma nomember_alignment longword
|
|
Packit |
575503 |
struct item_list_3 {
|
|
Packit |
575503 |
unsigned short len;
|
|
Packit |
575503 |
unsigned short code;
|
|
Packit |
575503 |
void * bufadr;
|
|
Packit |
575503 |
unsigned short * retlen;
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
struct filescan_itmlst_2 {
|
|
Packit |
575503 |
unsigned short length;
|
|
Packit |
575503 |
unsigned short itmcode;
|
|
Packit |
575503 |
char * component;
|
|
Packit |
575503 |
};
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#pragma member_alignment
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int SYS$GETDVIW(
|
|
Packit |
575503 |
unsigned long efn,
|
|
Packit |
575503 |
unsigned short chan,
|
|
Packit |
575503 |
const struct dsc$descriptor_s * devnam,
|
|
Packit |
575503 |
const struct item_list_3 * itmlst,
|
|
Packit |
575503 |
void * iosb,
|
|
Packit |
575503 |
void (* astadr)(unsigned long),
|
|
Packit |
575503 |
unsigned long astprm,
|
|
Packit |
575503 |
void * nullarg);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int SYS$FILESCAN(
|
|
Packit |
575503 |
const struct dsc$descriptor_s * srcstr,
|
|
Packit |
575503 |
struct filescan_itmlst_2 * valuelist,
|
|
Packit |
575503 |
unsigned long * fldflags,
|
|
Packit |
575503 |
struct dsc$descriptor_s *auxout,
|
|
Packit |
575503 |
unsigned short * retlen);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int SYS$TRNLNM(
|
|
Packit |
575503 |
const unsigned long * attr,
|
|
Packit |
575503 |
const struct dsc$descriptor_s * table_dsc,
|
|
Packit |
575503 |
struct dsc$descriptor_s * name_dsc,
|
|
Packit |
575503 |
const unsigned char * acmode,
|
|
Packit |
575503 |
const struct item_list_3 * item_list);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
char quote = '\'';
|
|
Packit |
575503 |
char *defpath = DEFPATH;
|
|
Packit |
575503 |
char *deflibpath = DEFLIBPATH;
|
|
Packit |
575503 |
char envsep = ',';
|
|
Packit |
575503 |
#define VMS_NAME_LEN 255
|
|
Packit |
575503 |
static char vms_name[VMS_NAME_LEN+1];
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Take all the fun out of simply looking up a logical name */
|
|
Packit |
575503 |
static int sys_trnlnm
|
|
Packit |
575503 |
(const char * logname,
|
|
Packit |
575503 |
char * value,
|
|
Packit |
575503 |
int value_len)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
const $DESCRIPTOR(table_dsc, "LNM$FILE_DEV");
|
|
Packit |
575503 |
const unsigned long attr = LNM$M_CASE_BLIND;
|
|
Packit |
575503 |
struct dsc$descriptor_s name_dsc;
|
|
Packit |
575503 |
int status;
|
|
Packit |
575503 |
unsigned short result;
|
|
Packit |
575503 |
struct item_list_3 itlst[2];
|
|
Packit |
575503 |
|
|
Packit |
575503 |
itlst[0].len = value_len;
|
|
Packit |
575503 |
itlst[0].code = LNM$_STRING;
|
|
Packit |
575503 |
itlst[0].bufadr = value;
|
|
Packit |
575503 |
itlst[0].retlen = &result;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
itlst[1].len = 0;
|
|
Packit |
575503 |
itlst[1].code = 0;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
name_dsc.dsc$w_length = strlen(logname);
|
|
Packit |
575503 |
name_dsc.dsc$a_pointer = (char *)logname;
|
|
Packit |
575503 |
name_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
Packit |
575503 |
name_dsc.dsc$b_class = DSC$K_CLASS_S;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
status = SYS$TRNLNM(&attr, &table_dsc, &name_dsc, 0, itlst);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if ($VMS_STATUS_SUCCESS(status)) {
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Null terminate and return the string */
|
|
Packit |
575503 |
value[result] = '\0';
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return status;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* gawk_name --- pull out the "gawk" part from how the OS called us */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* You would not think that this should be a such a problem, but
|
|
Packit |
575503 |
* VMS extended file specifications are tricky to parse, and we have
|
|
Packit |
575503 |
* to tell the difference between a CRTL generated argv[0] and a
|
|
Packit |
575503 |
* passed exec() argv[0] and handle both cases.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
char *
|
|
Packit |
575503 |
gawk_name(filespec)
|
|
Packit |
575503 |
const char *filespec;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
int status;
|
|
Packit |
575503 |
int result;
|
|
Packit |
575503 |
char * shell;
|
|
Packit |
575503 |
int lcname = 0;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* If the path name starts with a /, then it is an absolute path
|
|
Packit |
575503 |
* that may have been generated by the CRTL instead of the command
|
|
Packit |
575503 |
* name. If it is the device name between the slashes, then this
|
|
Packit |
575503 |
* was likely from the run command and needs to be fixed up.
|
|
Packit |
575503 |
* If the DECC$POSIX_COMPLIANT_PATHNAMES is set to 2, then it is
|
|
Packit |
575503 |
* the DISK$VOLUME that will be present, and it will still need to
|
|
Packit |
575503 |
* be fixed.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
result = 0;
|
|
Packit |
575503 |
if (filespec[0] == '/') {
|
|
Packit |
575503 |
char * nextslash;
|
|
Packit |
575503 |
int length;
|
|
Packit |
575503 |
struct item_list_3 itemlist[3];
|
|
Packit |
575503 |
unsigned short dvi_iosb[4];
|
|
Packit |
575503 |
char alldevnam[64];
|
|
Packit |
575503 |
unsigned short alldevnam_len;
|
|
Packit |
575503 |
struct dsc$descriptor_s devname_dsc;
|
|
Packit |
575503 |
char diskvolnam[256];
|
|
Packit |
575503 |
unsigned short diskvolnam_len;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Get some information about the disk */
|
|
Packit |
575503 |
/*--------------------------------------*/
|
|
Packit |
575503 |
itemlist[0].len = (sizeof alldevnam) - 1;
|
|
Packit |
575503 |
itemlist[0].code = DVI$_ALLDEVNAM;
|
|
Packit |
575503 |
itemlist[0].bufadr = alldevnam;
|
|
Packit |
575503 |
itemlist[0].retlen = &alldevnam_len;
|
|
Packit |
575503 |
itemlist[1].len = (sizeof diskvolnam) - 1 - 5;
|
|
Packit |
575503 |
itemlist[1].code = DVI$_VOLNAM;
|
|
Packit |
575503 |
itemlist[1].bufadr = &diskvolnam[5];
|
|
Packit |
575503 |
itemlist[1].retlen = &diskvolnam_len;
|
|
Packit |
575503 |
itemlist[2].len = 0;
|
|
Packit |
575503 |
itemlist[2].code = 0;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Add the prefix for the volume name. */
|
|
Packit |
575503 |
/* SYS$GETDVI will append the volume name to this */
|
|
Packit |
575503 |
strcpy(diskvolnam,"DISK$");
|
|
Packit |
575503 |
|
|
Packit |
575503 |
nextslash = strchr(&filespec[1], '/');
|
|
Packit |
575503 |
if (nextslash != NULL) {
|
|
Packit |
575503 |
length = nextslash - filespec - 1;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* DECC requires a cast here */
|
|
Packit |
575503 |
devname_dsc.dsc$a_pointer = (char *)&filespec[1];
|
|
Packit |
575503 |
devname_dsc.dsc$w_length = length;
|
|
Packit |
575503 |
devname_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
Packit |
575503 |
devname_dsc.dsc$b_class = DSC$K_CLASS_S;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
status = SYS$GETDVIW(
|
|
Packit |
575503 |
EFN$C_ENF,
|
|
Packit |
575503 |
0,
|
|
Packit |
575503 |
&devname_dsc,
|
|
Packit |
575503 |
itemlist,
|
|
Packit |
575503 |
dvi_iosb,
|
|
Packit |
575503 |
NULL, 0, 0);
|
|
Packit |
575503 |
if (!$VMS_STATUS_SUCCESS(status)) {
|
|
Packit |
575503 |
/* If the sys$getdviw fails, then this path
|
|
Packit |
575503 |
* was passed by an exec() program and not
|
|
Packit |
575503 |
* from DCL, so do nothing.
|
|
Packit |
575503 |
* An example is "/tmp/program" where tmp:
|
|
Packit |
575503 |
* does not exist
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
result = 0;
|
|
Packit |
575503 |
} else if (!$VMS_STATUS_SUCCESS(dvi_iosb[0])) {
|
|
Packit |
575503 |
result = 0;
|
|
Packit |
575503 |
} else {
|
|
Packit |
575503 |
char * devnam;
|
|
Packit |
575503 |
int devnam_len;
|
|
Packit |
575503 |
char argv_dev[64];
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Null terminate the returned alldevnam */
|
|
Packit |
575503 |
alldevnam[alldevnam_len] = 0;
|
|
Packit |
575503 |
devnam = alldevnam;
|
|
Packit |
575503 |
devnam_len = alldevnam_len;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Need to skip past any leading underscore */
|
|
Packit |
575503 |
if (devnam[0] == '_') {
|
|
Packit |
575503 |
devnam++;
|
|
Packit |
575503 |
devnam_len--;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* And remove the trailing colon */
|
|
Packit |
575503 |
if (devnam[devnam_len - 1] == ':') {
|
|
Packit |
575503 |
devnam_len--;
|
|
Packit |
575503 |
devnam[devnam_len] = 0;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Null terminate the returned volnam */
|
|
Packit |
575503 |
diskvolnam_len += 5;
|
|
Packit |
575503 |
diskvolnam[diskvolnam_len] = 0;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Check first for normal CRTL behavior */
|
|
Packit |
575503 |
if (devnam_len == length) {
|
|
Packit |
575503 |
strncpy(vms_name, &filespec[1], length);
|
|
Packit |
575503 |
vms_name[length] = 0;
|
|
Packit |
575503 |
result = (strcasecmp(devnam, vms_name) == 0);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* If we have not got a match check for
|
|
Packit |
575503 |
* POSIX Compliant behavior. To be more
|
|
Packit |
575503 |
* accurate, we could also check to see
|
|
Packit |
575503 |
* if that feature is active.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
if ((result == 0) &&
|
|
Packit |
575503 |
(diskvolnam_len == length)) {
|
|
Packit |
575503 |
int cmp;
|
|
Packit |
575503 |
strncpy(vms_name, &filespec[1], length);
|
|
Packit |
575503 |
vms_name[length] = 0;
|
|
Packit |
575503 |
cmp = strcasecmp(diskvolnam, vms_name);
|
|
Packit |
575503 |
result = (cmp == 0);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
} else {
|
|
Packit |
575503 |
/* The path did not start with a slash, so it could be VMS
|
|
Packit |
575503 |
* format. If it is vms format, it has a volume/device in
|
|
Packit |
575503 |
* it as it must be an absolute path
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
struct dsc$descriptor_s path_desc;
|
|
Packit |
575503 |
int status;
|
|
Packit |
575503 |
unsigned long field_flags;
|
|
Packit |
575503 |
struct filescan_itmlst_2 item_list[5];
|
|
Packit |
575503 |
char * volume;
|
|
Packit |
575503 |
char * name;
|
|
Packit |
575503 |
int name_len;
|
|
Packit |
575503 |
char * ext;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* DECC requires a cast here */
|
|
Packit |
575503 |
path_desc.dsc$a_pointer = (char *)filespec;
|
|
Packit |
575503 |
path_desc.dsc$w_length = strlen(filespec);
|
|
Packit |
575503 |
path_desc.dsc$b_dtype = DSC$K_DTYPE_T;
|
|
Packit |
575503 |
path_desc.dsc$b_class = DSC$K_CLASS_S;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Don't actually need to initialize anything buf itmcode */
|
|
Packit |
575503 |
/* I just do not like uninitialized input values */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Sanity check, this must be the same length as input */
|
|
Packit |
575503 |
item_list[0].itmcode = FSCN$_FILESPEC;
|
|
Packit |
575503 |
item_list[0].length = 0;
|
|
Packit |
575503 |
item_list[0].component = NULL;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* If the device is present, then it if a VMS spec */
|
|
Packit |
575503 |
item_list[1].itmcode = FSCN$_DEVICE;
|
|
Packit |
575503 |
item_list[1].length = 0;
|
|
Packit |
575503 |
item_list[1].component = NULL;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* we need the program name and type */
|
|
Packit |
575503 |
item_list[2].itmcode = FSCN$_NAME;
|
|
Packit |
575503 |
item_list[2].length = 0;
|
|
Packit |
575503 |
item_list[2].component = NULL;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
item_list[3].itmcode = FSCN$_TYPE;
|
|
Packit |
575503 |
item_list[3].length = 0;
|
|
Packit |
575503 |
item_list[3].component = NULL;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* End the list */
|
|
Packit |
575503 |
item_list[4].itmcode = 0;
|
|
Packit |
575503 |
item_list[4].length = 0;
|
|
Packit |
575503 |
item_list[4].component = NULL;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
status = SYS$FILESCAN(
|
|
Packit |
575503 |
(const struct dsc$descriptor_s *)&path_desc,
|
|
Packit |
575503 |
item_list, &field_flags, NULL, NULL);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if ($VMS_STATUS_SUCCESS(status) &&
|
|
Packit |
575503 |
(item_list[0].length == path_desc.dsc$w_length) &&
|
|
Packit |
575503 |
(item_list[1].length != 0)) {
|
|
Packit |
575503 |
|
|
Packit |
575503 |
char * dollar;
|
|
Packit |
575503 |
int keep_ext;
|
|
Packit |
575503 |
int i;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* We need the filescan to be successful,
|
|
Packit |
575503 |
* same length as input, and a volume to be present.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* We will assume that we only get to this path on
|
|
Packit |
575503 |
* a version of VMS that does not support the EFS
|
|
Packit |
575503 |
* character set.
|
|
Packit |
575503 |
*
|
|
Packit |
575503 |
* There may be a xxx$ prefix on the image name.
|
|
Packit |
575503 |
* Linux programs do not handle that well, so
|
|
Packit |
575503 |
* strip the prefix.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
name = item_list[2].component;
|
|
Packit |
575503 |
name_len = item_list[2].length;
|
|
Packit |
575503 |
dollar = strrchr(name, '$');
|
|
Packit |
575503 |
if (dollar != NULL) {
|
|
Packit |
575503 |
dollar++;
|
|
Packit |
575503 |
name_len = name_len - (dollar - name);
|
|
Packit |
575503 |
name = dollar;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
strncpy(vms_name, name, name_len);
|
|
Packit |
575503 |
vms_name[name_len] = 0;
|
|
Packit |
575503 |
result = 1;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* We only keep the extension if it is not ".exe" */
|
|
Packit |
575503 |
keep_ext = 0;
|
|
Packit |
575503 |
ext = item_list[3].component;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (item_list[3].length != 1) {
|
|
Packit |
575503 |
if (item_list[3].length != 4) {
|
|
Packit |
575503 |
keep_ext = 1;
|
|
Packit |
575503 |
} else {
|
|
Packit |
575503 |
int x;
|
|
Packit |
575503 |
x = strncmp(ext, ".exe", 4);
|
|
Packit |
575503 |
if (x != 0) {
|
|
Packit |
575503 |
keep_ext = 1;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (keep_ext == 1) {
|
|
Packit |
575503 |
strncpy(&vms_name[name_len],
|
|
Packit |
575503 |
ext, item_list[3].length);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (result) {
|
|
Packit |
575503 |
char * lastslash;
|
|
Packit |
575503 |
char * dollar;
|
|
Packit |
575503 |
char * dotexe;
|
|
Packit |
575503 |
char * lastdot;
|
|
Packit |
575503 |
char * extension;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* This means it is probably the name from a DCL command
|
|
Packit |
575503 |
* Find the last slash which separates the file from the
|
|
Packit |
575503 |
* path.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
lastslash = strrchr(filespec, '/');
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (lastslash != NULL) {
|
|
Packit |
575503 |
int i;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
lastslash++;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* There may be a xxx$ prefix on the image name. */
|
|
Packit |
575503 |
/* Linux programs do not handle that well, so */
|
|
Packit |
575503 |
/* strip the prefix */
|
|
Packit |
575503 |
dollar = strrchr(lastslash, '$');
|
|
Packit |
575503 |
|
|
Packit |
575503 |
if (dollar != NULL) {
|
|
Packit |
575503 |
dollar++;
|
|
Packit |
575503 |
lastslash = dollar;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
strcpy(vms_name, lastslash);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* In UNIX mode + EFS character set, there should
|
|
Packit |
575503 |
* not be a version present, as it is not possible
|
|
Packit |
575503 |
* when parsing to tell if it is a version or part
|
|
Packit |
575503 |
* of the UNIX filename as UNIX programs use numeric
|
|
Packit |
575503 |
* extensions for many reasons.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
|
|
Packit |
575503 |
lastdot = strrchr(vms_name, '.');
|
|
Packit |
575503 |
if (lastdot != NULL) {
|
|
Packit |
575503 |
int i;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
i = 1;
|
|
Packit |
575503 |
while (isdigit(lastdot[i])) {
|
|
Packit |
575503 |
i++;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
if (lastdot[i] == 0) {
|
|
Packit |
575503 |
*lastdot = 0;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Find the .exe on the name (case insenstive)
|
|
Packit |
575503 |
* and toss it
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
dotexe = strrchr(vms_name, '.');
|
|
Packit |
575503 |
if (dotexe != NULL) {
|
|
Packit |
575503 |
if ((dotexe[1] == 'e' || dotexe[1] == 'E') &&
|
|
Packit |
575503 |
(dotexe[2] == 'x' || dotexe[2] == 'X') &&
|
|
Packit |
575503 |
(dotexe[3] == 'e' || dotexe[3] == 'E') &&
|
|
Packit |
575503 |
(dotexe[4] == 0)) {
|
|
Packit |
575503 |
|
|
Packit |
575503 |
*dotexe = 0;
|
|
Packit |
575503 |
} else {
|
|
Packit |
575503 |
/* Also need to handle a null
|
|
Packit |
575503 |
* extension because of a CRTL bug.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
if (dotexe[1] == 0) {
|
|
Packit |
575503 |
*dotexe = 0;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
} else {
|
|
Packit |
575503 |
/* No changes needed */
|
|
Packit |
575503 |
strncpy(vms_name, filespec, VMS_NAME_LEN);
|
|
Packit |
575503 |
vms_name[VMS_NAME_LEN] = 0;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* The above fixes up the name, but for the DCL shell
|
|
Packit |
575503 |
* may leave it in upper case, which messes up the self tests.
|
|
Packit |
575503 |
* force it to lower case here.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
shell = getenv("SHELL");
|
|
Packit |
575503 |
if (shell != NULL) {
|
|
Packit |
575503 |
if (strcmp(shell, "DCL") == 0) {
|
|
Packit |
575503 |
lcname = 1;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
} else {
|
|
Packit |
575503 |
lcname = 1;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
if (lcname == 1) {
|
|
Packit |
575503 |
int i = 0;
|
|
Packit |
575503 |
while (vms_name[i] != 0) {
|
|
Packit |
575503 |
vms_name[i] = tolower(vms_name[i]);
|
|
Packit |
575503 |
i++;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
return vms_name;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_arg_fixup --- fixup the command line */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
void
|
|
Packit |
575503 |
os_arg_fixup(argcp, argvp)
|
|
Packit |
575503 |
int *argcp;
|
|
Packit |
575503 |
char ***argvp;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
char *tz_rule;
|
|
Packit |
575503 |
int status;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
(void) vms_arg_fixup(argcp, argvp);
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* Fix up the time zone */
|
|
Packit |
575503 |
/* For some reason it gets trashed */
|
|
Packit |
575503 |
tz_rule = malloc(1024);
|
|
Packit |
575503 |
status = sys_trnlnm("TZ", tz_rule, 1024);
|
|
Packit |
575503 |
if ($VMS_STATUS_SUCCESS(status)) {
|
|
Packit |
575503 |
setenv("TZ", tz_rule, 1);
|
|
Packit |
575503 |
} else {
|
|
Packit |
575503 |
status = sys_trnlnm("SYS$TIMEZONE_RULE", tz_rule, 1024);
|
|
Packit |
575503 |
if ($VMS_STATUS_SUCCESS(status)) {
|
|
Packit |
575503 |
setenv("TZ", tz_rule, 1);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
free(tz_rule);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_devopen --- open special per-OS devices */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
os_devopen(name, flag)
|
|
Packit |
575503 |
const char *name;
|
|
Packit |
575503 |
int flag;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
return vms_devopen(name, flag);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* optimal_bufsize --- determine optimal buffer size */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
size_t
|
|
Packit |
575503 |
optimal_bufsize(fd, stb)
|
|
Packit |
575503 |
int fd;
|
|
Packit |
575503 |
struct stat *stb;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* force all members to zero in case OS doesn't use all of them. */
|
|
Packit |
575503 |
memset(stb, '\0', sizeof(struct stat));
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/*
|
|
Packit |
575503 |
* These values correspond with the RMS multi-block count used by
|
|
Packit |
575503 |
* vms_open() in vms/vms_misc.c.
|
|
Packit |
575503 |
*/
|
|
Packit |
575503 |
if (isatty(fd) > 0)
|
|
Packit |
575503 |
return BUFSIZ;
|
|
Packit |
575503 |
else if (fstat(fd, stb) < 0)
|
|
Packit |
575503 |
return 8*512; /* conservative in case of DECnet access */
|
|
Packit |
575503 |
else
|
|
Packit |
575503 |
return 32*512;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* ispath --- return true if path has directory components */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
ispath(file)
|
|
Packit |
575503 |
const char *file;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
for (; *file; file++) {
|
|
Packit |
575503 |
switch (*file) {
|
|
Packit |
575503 |
case ':':
|
|
Packit |
575503 |
case ']':
|
|
Packit |
575503 |
case '>':
|
|
Packit |
575503 |
case '/':
|
|
Packit |
575503 |
return 1;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
return 0;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* isdirpunct --- return true if char is a directory separator */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
isdirpunct(c)
|
|
Packit |
575503 |
int c;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
return (strchr(":]>/", c) != NULL);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_close_on_exec --- set close on exec flag, print warning if fails */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
void
|
|
Packit |
575503 |
os_close_on_exec(fd, name, what, dir)
|
|
Packit |
575503 |
int fd;
|
|
Packit |
575503 |
const char *name, *what, *dir;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
/* no-op */
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_isdir --- is this an fd on a directory? */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
#if ! defined(S_ISDIR) && defined(S_IFDIR)
|
|
Packit |
575503 |
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
os_isdir(fd)
|
|
Packit |
575503 |
int fd;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
struct stat sbuf;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode));
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_isreadable --- fd can be read from */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
os_isreadable(const awk_input_buf_t *iobuf, bool *isdir)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
*isdir = false;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
switch (iobuf->sbuf.st_mode & S_IFMT) {
|
|
Packit |
575503 |
case S_IFREG:
|
|
Packit |
575503 |
case S_IFCHR: /* ttys, /dev/null, .. */
|
|
Packit |
575503 |
#ifdef S_IFSOCK
|
|
Packit |
575503 |
case S_IFSOCK:
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
#ifdef S_IFIFO
|
|
Packit |
575503 |
case S_IFIFO:
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
return true;
|
|
Packit |
575503 |
case S_IFDIR:
|
|
Packit |
575503 |
*isdir = true;
|
|
Packit |
575503 |
/* fall through */
|
|
Packit |
575503 |
default:
|
|
Packit |
575503 |
return false;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_is_setuid --- true if running setuid root */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
os_is_setuid()
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
return 0;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_setbinmode --- set binary mode on file */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
os_setbinmode (fd, mode)
|
|
Packit |
575503 |
int fd, mode;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
return 0;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* os_restore_mode --- restore the original mode of the console device */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
void
|
|
Packit |
575503 |
os_restore_mode (fd)
|
|
Packit |
575503 |
int fd;
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
/* no-op */
|
|
Packit |
575503 |
return;
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
/* files_are_same --- deal with VMS struct stat */
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
files_are_same(char *newfile, SRCFILE *oldfile)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
struct stat st, *f1, *f2;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
f1 = &st;
|
|
Packit |
575503 |
if (stat(newfile, f1) != 0) return 0;
|
|
Packit |
575503 |
|
|
Packit |
575503 |
f2 = &oldfile->sbuf;
|
|
Packit |
575503 |
/* compare device string */
|
|
Packit |
575503 |
#ifdef _USE_STD_STAT
|
|
Packit |
575503 |
return (f1->st_dev == f2->st_dev
|
|
Packit |
575503 |
/* and 48-bit file id cookie */
|
|
Packit |
575503 |
&& f1->st_ino == f2->st_ino);
|
|
Packit |
575503 |
#else
|
|
Packit |
575503 |
return (strcmp(f1->st_dev, f2->st_dev) == 0
|
|
Packit |
575503 |
/* and 48-bit file id cookie stored in 3 short ints */
|
|
Packit |
575503 |
&& f1->st_ino[0] == f2->st_ino[0]
|
|
Packit |
575503 |
&& f1->st_ino[1] == f2->st_ino[1]
|
|
Packit |
575503 |
&& f1->st_ino[2] == f2->st_ino[2]);
|
|
Packit |
575503 |
#endif
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
int
|
|
Packit |
575503 |
os_isatty(int fd)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
return (isatty(fd) > 0);
|
|
Packit |
575503 |
}
|
|
Packit |
575503 |
|
|
Packit |
575503 |
void
|
|
Packit |
575503 |
init_sockets(void)
|
|
Packit |
575503 |
{
|
|
Packit |
575503 |
}
|