[comp.os.msdos.programmer] clipper, turbo C and read-only databases

U5533129@ucsvc.ucs.unimelb.edu.au (CARDIOLOGY, R.M.H.) (08/16/90)

Are there an tricks to linking Turbo C code with Summer '87 Clipper (apart 
from compiling in large memory model).

I very much want this piece of code to work, so I can provide decent security
on databases on a network.  Is there anything obvious wrong with it?

The program links OK, but falls over under certain conditions (apparantly
when calling the FILE() function, but it's not clear because the problem
goes away if I link in the debugger or put print statements in the code).

(Anyone is welcome to use this code if it can be made to work.)

-------Start of code------

/*
	Open read-only databases with Clipper.
	Peter Summers -	27/4/90

	Sample usage (in a clipper program)

	access="**"
	call _tryreado
	use database
	call _testreado with access
	if access="RO"
	  code
	else  && access="RW"
	  other code
	endif
*/

#include <mem.h>
#include <dos.h>

#define	TRAPPEDVECTOR	0x21
#define SPAREVECTOR	0x60

/*
	Declaration of the new int 21 routine.
*/

void far interrupt	newvector(unsigned BP, unsigned DI, unsigned SI,
				  unsigned DS, unsigned ES, unsigned DX,
				  unsigned CX, unsigned BX, unsigned AX,
				  unsigned IP, unsigned CS, unsigned FLAGS);


/*
	Set up the old interrupt on a spare vector and set interrupt 21
	to point to the new routine.
*/

void tryreado(void)
  {
  setvect(SPAREVECTOR,getvect(TRAPPEDVECTOR));
  setvect(TRAPPEDVECTOR,newvector);
  }


/*
	Tests whether an attempt to open a file as read/write has succeeded,
	in which case the spare vector will have been set to NULL.  Resets
	interrupt 21 to its earlier value and returns a string with first
	two characters "RW" or "RO".  Attempts to write to files opened as
	read only will fail, and the clipper program must prevent them.
*/

void testreado(char *access)
  {
  access[0]='R';
  if (getvect(SPAREVECTOR)==NULL)
    access[1]='W';
  else
    {
    setvect(TRAPPEDVECTOR,getvect(SPAREVECTOR));
    access[1]='O';
    }
  }


/*
	The new interrupt routine.
*/

static void far interrupt	newvector(unsigned BP, unsigned DI, unsigned SI,
					  unsigned DS, unsigned ES, unsigned DX,
					  unsigned CX, unsigned BX, unsigned AX,
					  unsigned IP, unsigned CS, unsigned FLAGS)
  {
  unsigned	oldAX	=AX;

  /*
	Call the old interrupt 21.
  */

  _DI = DI;
  _SI = SI;
  _DS = DS;
  _ES = ES;
  _DX = DX;
  _CX = CX;
  _BX = BX;
  _AX = AX;

  geninterrupt(SPAREVECTOR);

  asm pushf
  asm pop FLAGS
  AX = _AX;
  BX = _BX;
  CX = _CX;
  DX = _DX;
  ES = _ES;
  DS = _DS;
  SI = _SI;
  DI = _DI;

  /*
	If it was an attempt to open a file as read/write, then try again
	as read only if the operation failed, or restore the old interrupt
	21 if it succeeded.
  */

  if ((oldAX & 0xFF03)==0x3D02)
    if (FLAGS & 1)
      {
      /* RW failed, try RO */
      _DI = DI;
      _SI = SI;
      _DS = DS;
      _ES = ES;
      _DX = DX;
      _CX = CX;
      _BX = BX;
      _AX = 0x3D00;

      geninterrupt(SPAREVECTOR);

      asm pushf
      asm pop FLAGS
      AX = _AX;

      /* RO failed too, restore vector so the Clipper program can crash
	 without taking machine down. */

      if (FLAGS & 1)
      	setvect(TRAPPEDVECTOR,getvect(SPAREVECTOR));
      }
    else
      {
      /* RW succeeded, restore the old int 21 routine and set the spare
	 vector to NULL for testreado to test.  */

      setvect(TRAPPEDVECTOR,getvect(SPAREVECTOR));
      setvect(SPAREVECTOR,NULL);
      }
  return;
  }