home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 5 Edit
/
05-Edit.zip
/
most423.zip
/
sysdep.c
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-07
|
18KB
|
726 lines
/*
* HISTORY
* {1} 19-Mar-91 Henk D. Davids <hdavids@mswe.dnet.ms.philips.nl>
* History started. Added default input file name so you do not
* have to specify name or type if you want it to be *.
* Changes indicated by "-hdd" in comment.
*
* 2. 4/4/91 John E. Davis
* I added code to read the teminal size for unix systems-- at least it
* works on a sun4 (BSD ?). In addition I have also recently added file
* deletion code for both unix and vms.
*/
#ifdef VMS
#include <ssdef.h>
#include <rmsdef.h>
#include <dvidef.h>
#include <jpidef.h>
/* #include <libdef.h> */
#include <descrip.h>
#include <iodef.h>
#include <ttdef.h>
#include <stdlib.h>
/* #include <unixlib.h> */
#endif
#ifdef unix
# include <signal.h>
# ifdef SYSV
# include <sys/types.h>
# include <fcntl.h>
# endif
# include <sys/file.h>
#endif
#include "externs.h"
#include "sysdep.h"
#include "display.h"
#include "window.h"
#ifdef VMS
typedef struct { /* I/O status block */
short i_cond; /* Condition value */
short i_xfer; /* Transfer count */
long i_info; /* Device information */
} iosb;
typedef struct { /* Terminal characteristics */
char t_class; /* Terminal class */
char t_type; /* Terminal type */
short t_width; /* Terminal width in characters */
long t_mandl; /* Terminal's mode and length */
long t_extend; /* Extended terminal characteristics */
} termchar;
short TTY_CHANNEL_GLOBAL;
static int zero = 0;
#else
int TTY_DESCR;
#endif /* VMS */
/*
*
*
* SHELL COMMANDS
*
*/
#ifdef VMS
/* these two from emacs source */
void define_logical_name (char *varname, char *string)
{
static char sstring[200], svarname[200];
struct dsc$descriptor_s strdsc =
{strlen (string), DSC$K_DTYPE_T, DSC$K_CLASS_S, sstring};
struct dsc$descriptor_s envdsc =
{strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, svarname};
struct dsc$descriptor_s lnmdsc =
{7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
strcpy(sstring, string); strcpy(svarname, varname);
LIB$SET_LOGICAL (&envdsc, &strdsc, &lnmdsc, 0, 0);
}
void delete_logical_name (char *varname)
{
struct dsc$descriptor_s envdsc =
{strlen (varname), DSC$K_DTYPE_T, DSC$K_CLASS_S, varname};
struct dsc$descriptor_s lnmdsc =
{7, DSC$K_DTYPE_T, DSC$K_CLASS_S, "LNM$JOB"};
LIB$DELETE_LOGICAL (&envdsc, &lnmdsc);
}
int do_emacs_command()
{
unsigned long pid;
char *pidstr;
if((pidstr = getenv("EMACS_PID")) != NULL)
{
(void) sscanf(pidstr,"%X",&pid);
if (lib$attach(&pid) == SS$_NORMAL) /* we attach to emacs */
return(1);
else
return(0);
/* printf("Can't attach to pid %X\n",pid); */
}
else return(0);
}
unsigned long SHELL_PID = 0;
/* returns 0 on success */
int do_shell_command()
{
/* here we try to attach to the parent otherwise just spawn a new one */
unsigned long parent_pid;
unsigned long status = 0;
char str[80];
$DESCRIPTOR(MOST_$_descr, "MOST > ");
parent_pid = getppid();
if (parent_pid && parent_pid != 0xffffffff)
/* we attach to parent */
status = lib$attach(&parent_pid);
else if (SHELL_PID && SHELL_PID != 0xffffffff)
/* try to attach to previous shell */
status = lib$attach (&SHELL_PID);
if (status != SS$_NORMAL) /* others fail so spawn a new shell */
{
status = 0;
send_string_to_term("Spawning MOST DCL SUBPROCESS (Logout when finished)...");
lib$spawn(0,0,0,0,0,&SHELL_PID,&status,0,0,0,&MOST_$_descr);
/* if we attach back, status may come back unchanged */
if ((status != 0) && (status != SS$_NORMAL))
{
sprintf(str,"Unable to spawn subprocess. Error = %X", status);
message(str,1);
return(0);
}
}
message(" ",0); /* make sure message window is restored */
return(1);
}
#endif /* VMS */
/*
* FILE IO
*
*/
#ifdef VMS
int expand_file_name(char *file,char *expanded_file)
{
unsigned long status;
static int context = 0, len = 0;
static char inputname[255] = "";
$DESCRIPTOR(file_desc,inputname);
$DESCRIPTOR(default_dsc,"SYS$DISK:[]*.*;");
static struct dsc$descriptor_s result =
{0, DSC$K_DTYPE_T, DSC$K_CLASS_D, NULL};
if (strcmp(inputname, file))
{
if (context)
{
lib$find_file_end(&context);
}
context = 0;
strcpy(inputname, file);
len = strlen(inputname);
}
file_desc.dsc$w_length = len;
if (RMS$_NORMAL == lib$find_file(&file_desc,&result,&context,
&default_dsc,0,0,&zero))
{
memcpy(expanded_file, result.dsc$a_pointer, result.dsc$w_length);
expanded_file[result.dsc$w_length] = '\0';
return (1);
}
else
{
expanded_file[0] = '\0'; /* so file comes back as zero width */
return(0);
}
}
#endif /* VMS */
/*
*
*
* Terminal IO
*
*/
#ifdef VMS
/*
* Exit Handler Control Block
*/
static struct argument_block
{
int forward_link;
int (*exit_routine)();
int arg_count;
int *status_address;
int exit_status;
} exit_block
= {
0,
NULL,
1,
&exit_block.exit_status,
0
};
/*
** For deciding whether to request a terminal channel.
*/
static int first_request_for_MostTT_chan = 1;
#endif
#ifdef unix
#ifndef sequent
# include <stdlib.h>
#endif
#include <sys/time.h>
#include <sys/ioctl.h>
#ifndef apollo
# include <unistd.h>
#endif
#if HAS_TERMIOS
# include <termios.h>
#endif
#ifdef __EMX__
# include <termio.h>
#endif
#ifdef SYSV
# include <sys/termio.h>
# include <sys/stream.h>
# include <sys/ptem.h>
# include <sys/tty.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#if !HAS_TERMIOS
struct ttystuff
{
struct tchars t;
struct ltchars lt;
struct sgttyb s;
};
struct ttystuff OLDTTY;
#else
struct termios OLDTTY;
#endif
/* this next works on ultrix for setting termios */
#ifdef TCGETS
#define GET_TERMIOS(fd, x) ioctl(fd, TCGETS, x)
#define SET_TERMIOS(fd, x) ioctl(fd, TCSETS, x)
#else
# if !HAS_TERMIOS
# define X(x,m) &(((struct ttystuff*)(x))->m)
# define GET_TERMIOS(fd, x) \
if(ioctl(fd, TIOCGETC, X(x,t))<0 || \
ioctl(fd, TIOCGLTC, X(x,lt))<0 || \
ioctl(fd, TIOCGETP, X(x,s))<0)exit_error("Can't get terminal info")
# define SET_TERMIOS(fd, x) \
if(ioctl(fd, TIOCSETC, X(x,t))<0 || \
ioctl(fd, TIOCSLTC, X(x,lt))<0 || \
ioctl(fd, TIOCSETP, X(x,s))<0)exit_error("Can't set terminal info")
# else
# define GET_TERMIOS(fd, x) tcgetattr(fd, x)
# define SET_TERMIOS(fd, x) tcsetattr(fd, TCSANOW, x)
# endif
#endif
#endif
#ifdef unix
static void open_term()
{
if ((TTY_DESCR = open("/dev/tty",O_RDONLY)) < 0)
{
exit_error("Unable to open tty.");
}
}
#endif
void init_tty()
{
#ifdef VMS
$DESCRIPTOR ( Term, "SYS$ERROR");
if (first_request_for_MostTT_chan)
{
if (sys$assign ( &Term, &TTY_CHANNEL_GLOBAL, 0, 0 )
!= SS$_NORMAL)
{
fprintf(stderr,"Unable to assign input channel\n");
exit(0);
}
if (NULL == exit_block.exit_routine)
{
reset_tty();
exit_block.exit_routine = reset_tty;
SYS$DCLEXH(&exit_block);
}
first_request_for_MostTT_chan = 0;
}
#else
/* unix */
#if !HAS_TERMIOS
struct ttystuff newtty;
#else
struct termios newtty;
#endif
enable_cursor_keys();
open_term();
GET_TERMIOS(TTY_DESCR, &OLDTTY);
GET_TERMIOS(TTY_DESCR, &newtty);
#if !HAS_TERMIOS
newtty.s.sg_flags &= ~(ECHO);
newtty.s.sg_flags &= ~(CRMOD);
newtty.t.t_eofc = 1;
newtty.t.t_intrc = 255; /* */
newtty.t.t_quitc = 255;
newtty.lt.t_suspc = 255; /* to ignore ^Z */
newtty.lt.t_lnextc = 255;
newtty.s.sg_flags |= CBREAK; /* do I want cbreak or raw????? */
#else
newtty.c_iflag &= ~(ECHO | INLCR | ICRNL);
newtty.c_oflag |= ONLCR; /* map newline to cr/newline on out */
newtty.c_oflag &= ~OCRNL;
newtty.c_cc[VMIN] = 1;
newtty.c_cc[VTIME] = 0;
newtty.c_cc[VEOF] = 1;
newtty.c_lflag = ISIG | NOFLSH;
newtty.c_cc[VINTR] = 255; /* ^G */
newtty.c_cc[VQUIT] = 255;
newtty.c_cc[VSUSP] = 255; /* to ignore ^Z */
#ifdef VSWTCH
newtty.c_cc[VSWTCH] = 255; /* to ignore who knows what */
#endif
#endif /* HAS_TERMIOS */
SET_TERMIOS(TTY_DESCR, &newtty);
/* VMS */
#endif
}
int reset_tty()
{
#ifdef unix
SET_TERMIOS(TTY_DESCR, &OLDTTY);
close(TTY_DESCR);
#endif
return(0);
}
int INPUT_BUFFER_LEN = 0;
char INPUT_BUFFER[80];
char sys_getkey()
{
char c;
#ifndef VMS
if (read(TTY_DESCR, &c, 1) < 0)
{
fprintf(stderr,"getkey(): read failed.\n");
reset_tty();
exit(0);
}
#else
/* VMS */
/* see Guide to Programming VAX/VMS */
int status;
static int trmmsk [2] = { 0, 0 };
short iosb [4];
status = sys$qiow ( 0, TTY_CHANNEL_GLOBAL,
IO$_READVBLK | IO$M_NOECHO | IO$_TTYREADALL,
iosb, 0, 0,
&c, 1, 0, trmmsk, 0, 0 );
#endif /* VMS */
return(c);
}
char getkey()
{
int i;
int ch;
if (!INPUT_BUFFER_LEN)
{
ch = sys_getkey();
ch &= 0x7F;
return(ch);
}
ch = INPUT_BUFFER[0];
INPUT_BUFFER_LEN--;
for (i = 0; i < INPUT_BUFFER_LEN; i++)
{
INPUT_BUFFER[i] = INPUT_BUFFER[i + 1];
}
return(ch);
}
void ungetkey(char ch)
{
int i;
for (i = 0; i < INPUT_BUFFER_LEN; i++)
{
INPUT_BUFFER[i+1] = INPUT_BUFFER[i];
}
INPUT_BUFFER[0] = ch;
INPUT_BUFFER_LEN++;
}
/*
*
* Misc Termial stuff
*
*
*/
/* This is to get the size of the terminal */
void get_term_dimensions(int *cols, int *rows)
{
#ifdef VMS
int status;
iosb iostatus;
$DESCRIPTOR(devnam, "SYS$ERROR");
struct
{
short row_buflen;
short row_itmcod;
int *row_bufadr;
short *row_retlen;
short col_buflen;
short col_itmcod;
int *col_bufadr;
short *col_retlen;
int listend;
} itmlst =
{
sizeof(*rows), DVI$_TT_PAGE, rows, 0,
sizeof(*cols), DVI$_DEVBUFSIZ, cols, 0,
0
};
/* Get current terminal characteristics */
status = sys$getdviw(0, /* Wait on event flag zero */
0, /* Channel to input terminal */
&devnam, /* device name */
&itmlst, /* Item descriptor List */
&iostatus, /* Status after operation */
0, 0, /* No AST service */
0); /* nullarg */
if (status&1)
status = iostatus.i_cond;
/* Jump out if bad status */
if ((status & 1) == 0)
exit(status);
#else /* this may need work on other unix-- works for sun4 */
#ifdef TIOCGWINSZ
struct winsize wind_struct;
ioctl(TTY_DESCR,TIOCGWINSZ,&wind_struct);
*cols = (int) wind_struct.ws_col;
*rows = (int) wind_struct.ws_row;
#ifdef __EMX__
if (*rows <= 0) *rows = 25;
#else
if (*rows <= 0) *rows = 24;
#endif
if (*cols <= 0) *cols = 80;
#else
#ifdef __EMX__
{
int scrsize[2];
_scrsize(scrsize);
*cols = scrsize[0];
*rows = scrsize[1];
}
if (*rows <= 0) *rows = 25;
if (*cols <= 0) *cols = 80;
#else
*rows = 24;
*cols = 80;
#endif
#endif
#endif /* VMS */
}
/* returns 0 on failure, 1 on sucess */
int sys_delete_file(char *filename)
{
#ifdef VMS
return (1 + delete(filename)); /* 0: sucess; -1 failure */
#else /* unix not ready yet */
return(1 + unlink(filename));
#endif
}
/* This routine converts unix type names to vms names */
#ifdef VMS
int locate(char ch, char *string)
{
int i;
char c;
i = 0;
while (c = string[i++], (c != ch) && (c != '\0'));
if (c == ch) return(i); else return (0);
}
char *unix2vms(char *file)
{
int i,device,j,first,last;
static char vms_name[80];
char ch;
if (locate('[',file)) return(file); /* vms_name syntax */
if (!locate('/',file)) return(file); /* vms_name syntax */
/* search for the ':' which means a device is present */
device = locate(':',file);
i = 0;
if (device)
{
while (ch = file[i], i < device) vms_name[i++] = ch;
}
j = i;
/* go from the end looking for a '/' and mark it */
i = strlen(file) - 1;
while(ch = file[i], ch != '/' && i-- >= 0);
if (ch == '/')
{
file[i] = ']';
last = 0;
}
else last = 1;
i = j;
vms_name[j++] = '[';
vms_name[j++] = '.';
first = 0;
while(ch = file[i++], ch != '\0')
{
switch (ch)
{
case '.':
if (last) vms_name[j++] = '.';
if (last) break;
ch = file[i++];
if (ch == '.')
{
if (!first) j--; /* overwrite the dot */
vms_name[j++] = '-';
}
else if (ch == '/'); /* './' combinations-- do nothing */
else if (ch == ']')
{
last = 1;
if (vms_name[j-1] == '.') j--;
vms_name[j++] = ']';
}
else vms_name[j++] = '.';
break;
case '/':
if (first)
{
vms_name[j++] = '.';
}
else
{
first = 1;
/* if '/' is first char or follows a colon do nothing */
if ((i!=1) && (file[i-2] != ':'))
{
vms_name[j++] = '.';
}
else j--; /* overwrite the '.' following '[' */
}
break;
case ']':
last = 1;
if (vms_name[j-1] == '.') j--;
vms_name[j++] = ']';
break;
default:
vms_name[j++] = ch;
}
}
return (vms_name);
}
/*
main(int argc, char **argv)
{
puts(unix2vms(argv[1]));
}
*/
#endif /* VMS */
#include <time.h>
char *get_time()
{
time_t clock;
char *the_time;
clock = time((time_t *) 0);
the_time = (char *) ctime(&clock);
/* returns the form Sun Sep 16 01:03:52 1985\n\0 */
the_time[24] = '\0';
return(the_time);
}
extern int SCREEN_WIDTH;
void set_width(int width, int redraw)
{
#ifdef VMS
short fd;
int status;
iosb iostatus;
static termchar tc; /* Terminal characteristics */
$DESCRIPTOR( devnam, "SYS$ERROR");
#else
#ifdef TIOCSWINSZ
struct winsize wind_struct;
#endif
#endif
/* Switching physical terminal to narrow/wide mode.*/
if(width<=80)
{
width = 80;
narrow_width();
}
else
{
width = 132;
wide_width();
}
SCREEN_WIDTH = width;
#ifdef VMS
/* Assign input to a channel */
status = sys$assign(&devnam, &fd, 0, 0);
if ((status & 1) == 0)
exit(status);
/* Get current terminal characteristics */
status = sys$qiow( /* Queue and wait */
0, /* Wait on event flag zero */
fd, /* Channel to input terminal */
IO$_SENSEMODE, /* Get current characteristic */
&iostatus, /* Status after operation */
0, 0, /* No AST service */
&tc, /* Terminal characteristics buf */
sizeof(tc), /* Size of the buffer */
0, 0, 0, 0); /* P3-P6 unused */
/*set terminal characteristics */
tc.t_width=width;
status = sys$qiow( /* Queue and wait */
0, /* Wait on event flag zero */
fd, /* Channel to input terminal */
IO$_SETMODE, /* Get current characteristic */
&iostatus, /* Status after operation */
0, 0, /* No AST service */
&tc, /* Terminal characteristics buf */
sizeof(tc), /* Size of the buffer */
0, 0, 0, 0); /* P3-P6 unused */
if( (sys$dassgn(fd) & 1)==0)
exit(status);
/* here we redraw the screen, on unix, we assume that the terminal
driver sends the appropriate signal that most catches to redraw so we
do not redraw because it is likely that screen will be redrawn twice */
if (redraw) redraw_display();
#else
#ifdef TIOCSWINSZ
/* this may need work on other unix-- works for sun4 */
ioctl(TTY_DESCR,TIOCGWINSZ,&wind_struct);
wind_struct.ws_col = width;
ioctl(TTY_DESCR,TIOCSWINSZ,&wind_struct);
#endif
#endif /* VMS */
}