/* @(#)aglvms.c 17.1.1.1 (ES0-DMD) 01/25/02 17:33:36 */ /*=========================================================================== Copyright (C) 1995 European Southern Observatory (ESO) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Massachusetss Ave, Cambridge, MA 02139, USA. Corresponding concerning ESO-MIDAS should be addressed as follows: Internet e-mail: midas@eso.org Postal address: European Southern Observatory Data Management Division Karl-Schwarzschild-Strasse 2 D 85748 Garching bei Muenchen GERMANY ===========================================================================*/ /* @(#)aglvms.c 17.1.1.1 (OAA-ASTRONET) 01/25/02 17:33:36 */ /* * HEADER : aglvms.c - Vers 3.6.000 - Dec 1991 - L. Fini, OAA */ #define MIN(x,y) ((x)<(y))?(x):(y) /*****************************************************************************/ /* Environment dependent features are resolved in this file */ #define AUXLNG 257 #define SS$_NORMAL 1 /*****************************************************************************/ /* AGL_trns (Internal AGL use) */ /* VAX/VMS version */ /* This VMS version uses VMS logical names translation */ /* Translates logical names until no further translation is possible */ /* NOTE: Equivalence name is also forced to lower case and colon is stripped */ /* off */ void AGL_trns(inpname,maxlng,trnslnam) char *inpname; /* Input name */ int maxlng; /* Max output string length */ char *trnslnam; /* Output equivalence name */ { struct dsc$descriptor trnam,wrk; /* Define CHARACTER descriptors */ char auxbuf[AUXLNG]; extern long LIB$SYS_TRNLOG(); long retstat; int cnt; short retlng; char *src, *dst; trnam.dsc$b_class=1; trnam.dsc$w_length=maxlng-1; trnam.dsc$a_pointer=trnslnam; wrk.dsc$b_class=1; wrk.dsc$a_pointer=auxbuf; retlng=MIN(strlen(inpname),AUXLNG); for(cnt=0; cnt<=retlng; cnt++) auxbuf[cnt] = TOUPPER(inpname[cnt]); wrk.dsc$w_length=retlng; do /* Translation loop */ { retstat=LIB$SYS_TRNLOG(&wrk,&retlng,&trnam,NULL,NULL,NULL); cnt=0; src=trnslnam; dst=auxbuf; while(retlng--) { if(isgraph(*src)) { *dst++ = TOLOWER(*src); cnt++; } src++; } wrk.dsc$w_length=cnt; } while(retstat==SS$_NORMAL); src=auxbuf; while( *src == '_' ) { cnt--; src++; } /* strip off leading underscores */ strncpy(trnslnam,src,cnt); src = trnslnam+cnt; *(src)='\0'; src--; /* null terminate */ if(*src == ':') *src = '\0'; /* Drop the terminating colon */ } int AGL_spawn(cmd) char *cmd; { struct dsc$descriptor wrk; /* Define CHARACTER descriptors */ extern long LIB$SPAWN(); long retstat; wrk.dsc$b_class=1; wrk.dsc$a_pointer=cmd; wrk.dsc$w_length = strlen(cmd); retstat = LIB$SPAWN(&wrk,NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL,NULL,NULL,NULL); if(retstat != SS$_NORMAL) return (-1); return 0; } /* Terminal I/O emulator for VAX/VMS */ /* This module is required due to the fact that VAX-C runtime library */ /* doesn't support ioctl. It provides fopen,fclose,fread,fwrite emulated by */ /* VMS System Service calls, in PASSTRHOUGH mode so that it works as usual */ /* Unix calls in RAWMODE. Ioctl is substituted by a dummy entry */ #define IO$M_NOECHO 0x0040 #define IO$M_NOFILTR 0x0200 #define IO$_READVBLK 0x31 #define IO$_TTYREADALL 0x3A #define IO$_WRITEVBLK 0x30 #define IO$M_PURGE 0x0800 #define IO$M_NOFORMAT 0x0100 #define SS$NORMAL 1 #define ERROR (-1) #define RFUNCT (IO$_READVBLK | IO$M_NOECHO | IO$_TTYREADALL) #define RFLUSH (IO$_READVBLK | IO$M_NOECHO | IO$_TTYREADALL | IO$M_PURGE) #define WFUNCT (IO$_WRITEVBLK | IO$M_NOFORMAT ) static short chan[10]= /* This is an internal buffer for I/O. */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; static int rfunct=RFLUSH; /* Read function. with flush the first time */ /***************************************************************************/ /* AGL_fopen */ /* This routine is used to open an i/o channel to a terminal. It must take */ /* into account system specific details. E.g. VMS systems will always open */ /* an I/O channel to be used for subsequent SYS$QIO calls, whereas Unix */ /* systems will probably simply issue a standard fopen call. */ FILE *AGL_fopen (name) char * name; /* Device name (if it is tt, unix and MS-DOS */ /* systems will simply return stdout). VMS */ /* systems will open SYS$OUTPUT */ { int status; static char *sysout = "SYS$OUTPUT"; long SYS$ASSIGN(); struct dsc$descriptor_s descr; char *device; int i; for(i=0;i<10;i++) { /* Search a free slot */ if(chan[i]==(-1)) break; } if(i==10) return(NULL); if(strcmp(name,"tt")==0) { descr.dsc$w_length = strlen (sysout); descr.dsc$a_pointer = sysout; } else { descr.dsc$w_length = strlen (name); descr.dsc$a_pointer = name; } descr.dsc$b_class = DSC$K_CLASS_S; /* string class */ descr.dsc$b_dtype = DSC$K_DTYPE_T; /* ascii type */ status = SYS$ASSIGN (&descr,&chan+i,0,0); /* Assign the channel */ if(status != SS$NORMAL) { chan[i]=(-1); return (NULL); } return ((FILE *)(chan+i)); } /*****************************************************************************/ /* AGL_fread */ /*****************************************************************************/ int AGL_fread (buffer,size,nbytes,dev) char *buffer; /* Output buffer */ int size; /* Dummy argument. Must be equal to 1 */ int nbytes; /* Number of characters to read */ FILE *dev; /* pointer to VMS I/O channel */ { double iosb; int status; short *intchan; intchan = (short*)dev; status = SYS$QIOW(1,*intchan,rfunct,&iosb, 0,0,buffer,nbytes,0,0,0,0); rfunct = RFUNCT; /* Avoid flushing next time you read */ if (status != SS$NORMAL) return (ERROR); return (nbytes); /* WARNING!! IT IS NOT POSSIBLE TO RETURN THE NUMBER OF BYTES ACTUALLY READ */ } /*****************************************************************************/ /* AGL_fwrite */ /*****************************************************************************/ int AGL_fwrite (buffer,size,nbytes,dev) char *buffer; /* Input buffer */ int size; /* Dummy argument. Must be equal to 1 */ int nbytes; /* Number of characters to write */ FILE *dev; /* pointer to VMS I/O channel */ { double iosb; int status,funct; short *intchan; intchan = (short*)dev; funct = WFUNCT; status = SYS$QIOW(1,*intchan,funct,&iosb,0,0,buffer,nbytes,0,0,0,0); if (status != SS$NORMAL) return (ERROR); return (nbytes); } /*****************************************************************************/ /* AGL_fclose */ /*****************************************************************************/ int AGL_fclose (dev) FILE *dev; /* FILE pointer (obtained via AGL_fopen) */ { int status; short *intchan; long SYS$DASSGN(); intchan = (short*)dev; if(*intchan==(-1)) return(-1); status = SYS$DASSGN (*intchan); if (status != SS$NORMAL) return (-1); *intchan=(-1); return (0); } /***************************************************************************/ /* AGL_setraw AGL_reset */ /* These are dummy routines. The terminal I/O is performed in RAW mode */ /* anyway on VMS systems */ int AGL_setraw (filept) FILE * filept; { } void AGL_reset(filept) FILE * filept; { } int AGL_fflush (filept) FILE * filept; { rfunct=RFLUSH; /* Preset flushing on next read */ }