Blame vms/gawkmisc.vms

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
}