Exemplo n.º 1
0
/*
//
//  ISAM - build file cluster
//
*/
int tcob_build_vbidx(struct file_desc *f)
{ 
  int r=0, i=0, ifilehandle, iresult, imode;
  tcb_fileio_vbidx_handle *h;
  struct keydesc *wkeydesc;   

#ifdef DEBUG_FILEISAM_RTS8
     fprintf(stderr, "debug : tcob_build_vbidx 010.040 : f->filename=%s, f->flags.file_isvariable=%d;\n", f->filename, f->flags.file_isvariable);
#endif                                       
  
  h = (tcb_fileio_vbidx_handle *)f->dbp;

  if (f->flags.file_isvariable == 1) {
     imode = ISINOUT+ISVARLEN+ISEXCLLOCK;
     isreclen = f->reclen_min;
  }
  else {
     imode = ISINOUT+ISFIXLEN+ISEXCLLOCK;
  }

  wkeydesc = h->skeydesc;
  /* Define ISAM file - define primary key */  
  ifilehandle = isbuild(f->filename, f->reclen, wkeydesc, imode);
#ifdef DEBUG_FILEISAM_RTS8
  fprintf(stderr, "debug : tcob_build_vbidx 010.060 : f->filename=%s, f->reclen=%d, ifilehandle=%d;\n", f->filename, f->reclen, ifilehandle);
#endif                                       
  if (ifilehandle < 0) {
     r = tcob_eisam2ecob(0);
     return (r);        
  }

  /* Define ISAM file - define secondary keys */  
  for (i=1; i < f->nkeys; i++) {
     wkeydesc = h->skeydesc + i;
     iresult = isaddindex(ifilehandle, wkeydesc);
     if (iresult != 0) {
        r = tcob_eisam2ecob(0);
        iresult = isclose(ifilehandle);
        iserase (f->filename);
        return (r);        
     }
  }

  iresult = isclose(ifilehandle);
  if (iresult != 0) {
     r = tcob_eisam2ecob(0);
     iserase (f->filename);
     return (r);        
  }
  
  h->ifilehandle = ifilehandle;

#ifdef DEBUG_FILEISAM_RTS8
     fprintf(stderr, "debug : tcob_build_vbidx 010.080 : r=%d;\n", r);
#endif                                       

  RETURN_STATUS(r);        
}
Exemplo n.º 2
0
PI_ALLCLOSE()
#endif
{
	register	i, j;
	int		isfd;

	for (i=0;i< PI_MAXOPEN;i++) {
		if ( !pi_fileinfo[i].filepath_sav[0] )	/* if not exist */
			continue;

		isfd = pi_fileinfo[i].isfd_sav;

		if( isclose( isfd ) < 0 )  {
			l_pisamsethyerrno( iserrno );
			return -1;
		}
		pi_fileinfo[i].filepath_sav[0] = '\0';
		pi_fileinfo[i].infpath_sav[0] = '\0';
		pi_fileinfo[i].isfd_sav = -1;
		pi_fileinfo[i].keyname_sav[0] = '\0';
		for (j=0; j<PI_MAXKEY; j++)
			pi_fileinfo[i].pi_keyinfo[j].kname[0]='\0';
	}

	pi_currfd = 0;
	return 0;
}
Exemplo n.º 3
0
/*
//
//  ISAM close
//
*/
int tcob_close_idx(struct file_desc *f) 
{
  int r=0;
  tcb_fileio_vbidx_handle *h;          

#ifdef DEBUG_FILEISAM_RTS0
  fprintf(stderr, "debug : tcob_close_idx : 060.020 : r=%d\n", r); 
#endif                                       

  if (f->dbp == NULL)
     return (99);

  if (f->filename == NULL)
     return (99);
  
  h = (tcb_fileio_vbidx_handle *)f->dbp;

  /* Flush and close VB-ISAM file */
  r = isflush(h->ifilehandle);
  if (r != 0) {
     r = tcob_eisam2ecob(0);
  }
  else {        
     /* Set return code depending on VB iserrno */
     r = isclose(h->ifilehandle);
     if (r != 0) {
        r = tcob_eisam2ecob(0);
     }
     else {
        tcob_remove_file_list(f);
        if (f->filename != NULL);
           free(f->filename);
        tcob_free_vbidx(f);
        f->filename = NULL;
        f->dbp = NULL;
     }
  }

#ifdef DEBUG_FILEISAM_RTS0
  fprintf(stderr, "debug : tcob_close_idx : 060.140 : r=%d\n", r); 
#endif                                       
  
  return r;
}
Exemplo n.º 4
0
/*
//
//  ISAM open - INPUT
//
*/
int tcob_open_input_idx(struct file_desc *f) 
{
  int r=0, imode=0, ifilehandle;
  tcb_fileio_vbidx_handle *h;          
  struct stat st1, st2;

#ifdef DEBUG_FILEISAM_RTS0
  fprintf(stderr, "debug : tcob_open_input_idx : 030.020 : filename=%s;\n", f->filename); 
#endif                                       
  
  h = (tcb_fileio_vbidx_handle *)f->dbp;
  if ((stat(h->fdatname, &st1) == -1 && errno == ENOENT) ||
      (stat(h->fidxname, &st2) == -1 && errno == ENOENT)) 
     return (35);        

  if (f->flags.file_isvariable == 1)
     imode = ISINPUT+ISVARLEN+ISAUTOLOCK;
  else
     imode = ISINPUT+ISFIXLEN+ISAUTOLOCK;

  ifilehandle = isopen(f->filename, imode);
  /* Set return code depending on VB iserrno */
  if (ifilehandle < 0) {
     r = tcob_eisam2ecob(0);
  }

  /* Verify ISAM structures */
  if (r == 0) {
     r = tcob_verify_vbidx(f, ifilehandle);
     if (r != 0) { 
        isclose(ifilehandle);
        r = 99;
     }
  }

  if (r == 0) 
     h->ifilehandle = ifilehandle;
  
#ifdef DEBUG_FILEISAM_RTS0
  fprintf(stderr, "debug : tcob_open_input_idx : 030.140 : iserrno=%d, r=%d\n", iserrno, r); 
#endif                                       

  return r;
}
Exemplo n.º 5
0
int
iserase (char *pcfilename)
{
	int	ihandle;
	char	cbuffer[1024];

	for (ihandle = 0; ihandle <= ivbmaxusedhandle; ihandle++) {
		if (psvbfile[ihandle] != NULL) {
			if (!strcmp (psvbfile[ihandle]->cfilename, pcfilename)) {
				isclose (ihandle);
				ivbclose3 (ihandle);
				break;
			}
		}
	}
	sprintf (cbuffer, "%s.idx", pcfilename);
	unlink (cbuffer);
	sprintf (cbuffer, "%s.dat", pcfilename);
	unlink (cbuffer);
	return ivbtranserase (pcfilename);
}
Exemplo n.º 6
0
int
idxclose (unit *ftnunit, flag idxerr)
{
   if (isclose (ftnunit->isfd) < SUCCESS)
      ierr (idxerr, iserrno, "indexed close");
   if (ftnunit->ufnm) {
      if (ftnunit->udisp & DELETE)
	 if (iserase (ftnunit->ufnm) < SUCCESS)
	    ierr (idxerr, iserrno, "indexed close");
      free (ftnunit->ufnm);
      ftnunit->ufnm = NULL;
   }
   /*
     The following fixes bug #231656.  The pointers involved are initialized
     to zero (both when originally allocated in f_init() and when reallocated
     in map_luno()).  So, if non-zero, the buffers must have been allocated,
     and we should free them.
   */
   if (ftnunit->f77syl) {
    free(ftnunit->f77syl);
    ftnunit->f77syl = NULL;
   }
   if (ftnunit->f77fio_buf) {
    free(ftnunit->f77fio_buf);
    ftnunit->f77fio_buf = NULL;
    ftnunit->f77fio_size = 0;
   }
   if (ftnunit->ukeys) {
    free(ftnunit->ukeys);
    ftnunit->ukeys = NULL;
   }
   ftnunit->ufd = NULL;
   ftnunit->uconn = 0;
   ftnunit->luno = 0;
   ftnunit->ukeyid = -1;
   return SUCCESS;
}
Exemplo n.º 7
0
/**
* Initialize the socket and the Insim connection
* If "struct IS_VER *pack_ver" is set it will contain an IS_VER packet after returning. It's an optional argument
*/
int CInsim::init (char *addr, word port, char *product, char *admin, struct IS_VER *pack_ver, unsigned char prefix, word flags, word interval, word udpport)
{
	// Initialise WinSock
	// Only required on Windows
	#ifdef CIS_WINDOWS
	WSADATA wsadata;
	if (WSAStartup(0x202, &wsadata) == SOCKET_ERROR) {
	  WSACleanup();
	  return -1;
	}
	#endif

	// Create the TCP socket - this defines the type of socket
	sock = socket(AF_INET, SOCK_STREAM, 0);

	// Could we get the socket handle? If not the OS might be too busy or has run out of available socket descriptors
	if (sock == INVALID_SOCKET) {
	  #ifdef CIS_WINDOWS
	  closesocket(sock);
	  WSACleanup();
	  #elif defined CIS_LINUX
	  close(sock);
	  #endif

	  return -1;
	}

	// Resolve the IP address
	struct sockaddr_in saddr;
	memset(&saddr, 0, sizeof(saddr));

	saddr.sin_family = AF_INET;

	struct hostent *hp;
	hp = gethostbyname(addr);

	if (hp != NULL)
	  saddr.sin_addr.s_addr = *((unsigned long*)hp->h_addr);
	else
	  saddr.sin_addr.s_addr = inet_addr(addr);

	// Set the port number in the socket structure - we convert it from host unsigned char order, to network
	saddr.sin_port = htons(port);

	// Now the socket address structure is full, lets try to connect
	if (connect(sock, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
	  #ifdef CIS_WINDOWS
	  closesocket(sock);
	  WSACleanup();
	  #elif defined CIS_LINUX
	  close(sock);
	  #endif

	  return -1;
	}

	// If the user asked for NLP or MCI packets and defined an udpport
	if (udpport > 0) {
		// Create the UDP socket - this defines the type of socket
		sockudp = socket(AF_INET, SOCK_DGRAM, 0);

		// Could we get the socket handle? If not the OS might be too busy or have run out of available socket descriptors
		if (sockudp == INVALID_SOCKET) {
			#ifdef CIS_WINDOWS
			closesocket(sock);
			closesocket(sockudp);
			WSACleanup();
			#elif defined CIS_LINUX
			close(sock);
			close(sockudp);
			#endif
			return -1;
		}

		// Resolve the IP address
		struct sockaddr_in udp_saddr, my_addr;
		memset(&udp_saddr, 0, sizeof(udp_saddr));
		memset(&my_addr, 0, sizeof(my_addr));

		// Bind the UDP socket to my specified udpport and address
		my_addr.sin_family = AF_INET;		 // host unsigned char order
		my_addr.sin_port = htons(udpport);	 // short, network unsigned char order
		my_addr.sin_addr.s_addr = INADDR_ANY;
		memset(my_addr.sin_zero, '\0', sizeof my_addr.sin_zero);

		// don't forget your error checking for bind():
		bind(sockudp, (struct sockaddr *)&my_addr, sizeof my_addr);

		// Set the server address and the connect to it
		udp_saddr.sin_family = AF_INET;

		struct hostent *udp_hp;
		udp_hp = gethostbyname(addr);

		if (udp_hp != NULL)
			udp_saddr.sin_addr.s_addr = *((unsigned long*)udp_hp->h_addr);
		else
			udp_saddr.sin_addr.s_addr = inet_addr(addr);

		// Set the UDP port number in the UDP socket structure - we convert it from host unsigned char order, to network
		udp_saddr.sin_port = htons(port);

		// Connect the UDP using the same address as in the TCP socket
		if (connect(sockudp, (struct sockaddr *) &udp_saddr, sizeof(udp_saddr)) < 0) {
			#ifdef CIS_WINDOWS
			closesocket(sock);
			closesocket(sockudp);
			WSACleanup();
			#elif defined CIS_LINUX
			close(sock);
			close(sockudp);
			#endif
			return -1;
		}

		// We are using UDP!
		using_udp = 1;
	}

	// Ok, so we're connected. First we need to let LFS know we're here by sending the IS_ISI packet
	struct IS_ISI isi_p;
	memset(&isi_p, 0, sizeof(struct IS_ISI));
	isi_p.Size = sizeof(struct IS_ISI);
	isi_p.Type = ISP_ISI;

	if (pack_ver != NULL)			 // We request an ISP_VER if the caller asks for it
		isi_p.ReqI = 1;

	isi_p.Prefix = prefix;
	isi_p.UDPPort = udpport;
	isi_p.Flags = flags;
	isi_p.Interval = interval;
	memcpy(isi_p.IName, product, sizeof(isi_p.IName)-1);
	memcpy(isi_p.Admin, admin, 16);

	// Send the initialization packet
	if(send_packet(&isi_p) < 0) {
		if (using_udp) {
			#ifdef CIS_WINDOWS
			closesocket(sockudp);
			#elif defined CIS_LINUX
			close(sockudp);
			#endif
	}

		#ifdef CIS_WINDOWS
		closesocket(sock);
		WSACleanup();
		#elif defined CIS_LINUX
		close(sock);
		#endif
		return -1;
	}

	// Set the timeout period
	select_timeout.tv_sec = IS_TIMEOUT;
	#ifdef CIS_WINDOWS
	select_timeout.tv_usec = 0;
	#elif defined CIS_LINUX
	select_timeout.tv_nsec = 0;
	#endif

	// If an IS_VER packet was requested
	if (pack_ver != NULL)
	{
		if (next_packet() < 0) {			 // Get next packet, supposed to be an IS_VER
			if (isclose() < 0) {
				if (using_udp) {
					#ifdef CIS_WINDOWS
					closesocket(sockudp);
					#elif defined CIS_LINUX
					close(sockudp);
					#endif
				}

				#ifdef CIS_WINDOWS
				closesocket(sock);
				WSACleanup();
				#elif defined CIS_LINUX
				close(sock);
				#endif
				return -1;
			}
			return -1;
		}

		switch (peek_packet())			  // Check if the packet returned was an IS_VER
		{
			case ISP_VER:					 // It was, get it!
				memcpy(pack_ver, (struct IS_VER*)get_packet(), sizeof(struct IS_VER));
				break;
			default:						  // It wasn't, something went wrong. Quit
				if (isclose() < 0) {
					if (using_udp) {
						#ifdef CIS_WINDOWS
						closesocket(sockudp);
						#elif defined CIS_LINUX
						close(sockudp);
						#endif
					}

					#ifdef CIS_WINDOWS
					closesocket(sock);
					WSACleanup();
					#elif defined CIS_LINUX
					close(sock);
					#endif
				}
				return -1;
		}
	}
	return 0;
}
Exemplo n.º 8
0
int
main (int iArgc, char **ppcArgv)
{
	int	iResult,
		iLoop,
		iLoop2,
		iLoop3,
		iHandle;
	unsigned char
		cRecord [256];
	struct	keydesc
		sKeydesc;
	char	cLogfileName [100],
		cCommand [100];
	char	cFileName [] = "IsamTest";

	memset (&sKeydesc, 0, sizeof (sKeydesc));
	sKeydesc.k_flags = COMPRESS;
	sKeydesc.k_nparts = 1;
	sKeydesc.k_start = 0;
	sKeydesc.k_leng = 2;
	sKeydesc.k_type = CHARTYPE;

	if (iArgc == 1) {
		printf ("Usage:\n\t%s create\nOR\n\t%s <#iterations>\n", ppcArgv [0], ppcArgv [0]);
		exit (1);
	}

	if (iArgc > 1 && strcmp (ppcArgv [1], "create") == 0) {
		iserase (cFileName);
		iHandle = isbuild (cFileName, 255, &sKeydesc, ISINOUT+ISFIXLEN+ISEXCLLOCK);
		if (iHandle < 0) {
			printf ("Error creating database: %d\n", iserrno);
			exit (-1);
		}
		sKeydesc.k_flags |= ISDUPS;
	sKeydesc.k_start = 3;
	sKeydesc.k_leng = 4;
		for (sKeydesc.k_start = 1; sKeydesc.k_start < 2; sKeydesc.k_start++) {
			if (isaddindex (iHandle, &sKeydesc)) {
				printf ("Error %d adding index %d\n", iserrno, sKeydesc.k_start);
			}
		}
		isclose (iHandle);
		sprintf (cLogfileName, "RECOVER");
#ifdef	_WIN32
		sprintf (cCommand, "del /f /q %s", cLogfileName);
#else
		sprintf (cCommand, "rm -f %s; touch %s", cLogfileName, cLogfileName);
#endif
		system (cCommand);
		return (0);
	}
	sprintf (cLogfileName, "RECOVER");
#ifdef	_WIN32
	iResult = open("RECOVER", O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0666);
#else
	iResult = open("RECOVER", O_CREAT | O_TRUNC | O_RDWR, 0666);
#endif
	close(iResult);
	iResult = islogopen (cLogfileName);
	if (iResult < 0) {
		printf ("Error opening log: %d\n", iserrno);
		exit (-1);
	}

/*
	srand (time (NULL));
*/
	srand (9);
	for (iLoop = 0; iLoop < atoi (ppcArgv [1]); iLoop++)
	{
		if (!(iLoop % 100)) {
			printf ("iLoop=%d\n", iLoop);
			fflush(stdout);
		}

		iVBDlCount = 0;
		iVBRdCount = 0;
		iVBUpCount = 0;
		iVBWrCount = 0;
		iResult = isbegin ();
		if (iResult < 0) {
			printf ("Error begin transaction: %d\n", iserrno);
			exit (-1);
		}
		iHandle = isopen (cFileName, ISINOUT+ISFIXLEN+ISTRANS+ISAUTOLOCK);
		if (iHandle < 0) {
			printf ("Error opening database: %d\n", iserrno);
			exit (-1);
		}

		for (iLoop2 = 0; iLoop2 < 100; iLoop2++)
		{
			for (iLoop3 = 0; iLoop3 < 256; iLoop3++) {
				cRecord [iLoop3] = rand () % 256;
			}

			iResult =rand () % 4;
/*
			fprintf(stderr, "I %d\n", iResult);
*/
			switch (iResult) {
			case	0:
				if ((iResult = iswrite (iHandle, (char *) cRecord)) != 0) {
					if (iserrno != EDUPL && iserrno != ELOCKED) {
						printf ("Error writing: %d\n", iserrno);
						goto err;
					}
				} else {
					iVBWrCount++;
				}
				break;

			case	1:
				if ((iResult = isread (iHandle, (char *)cRecord, ISEQUAL)) != 0) {
					if (iserrno == ELOCKED) {
						; /* printf ("Locked during deletion\n"); */
					} else if (iserrno != ENOREC) {
						printf ("Error reading: %d\n", iserrno);
						goto err;
					}
				} else {
					iVBRdCount++;
				}
				break;

			case	2:
				for (iLoop3 = 0; iLoop3 < 256; iLoop3++) {
					cRecord [iLoop3] = rand () % 256;
				}
				if ((iResult = isrewrite (iHandle, (char *)cRecord)) != 0) {
					if (iserrno == ELOCKED) {
						; /* printf ("Locked during rewrite\n"); */
					} else if (iserrno != ENOREC) {
						printf ("Error rewriting: %d\n", iserrno);
						goto err;
					}
				} else {
					iVBUpCount++;
				}
				break;

			case	3:
				if ((iResult = isdelete (iHandle, (char *)cRecord)) != 0) {
					if (iserrno == ELOCKED) {
						; /* printf ("Locked during deletion\n"); */
					} else if (iserrno != ENOREC) {
						printf ("Error deleting: %d\n", iserrno);
						goto err;
					}
				}
				else
					iVBDlCount++;
				break;
			}
		}

		iResult = isflush (iHandle);
		if (iResult < 0) {
			printf ("Error flush: %d\n", iserrno);
			exit (-1);
		}
		iResult = isclose (iHandle);
		if (iResult < 0) {
			printf ("Error closing database: %d\n", iserrno);
			exit (-1);
		}

		iVBDlTotal += iVBDlCount;
		iVBRdTotal += iVBRdCount;
		iVBUpTotal += iVBUpCount;
		iVBWrTotal += iVBWrCount;
		switch (rand () % 2) {
		case	0:
			iVBDlCommit += iVBDlCount;
			iVBRdCommit += iVBRdCount;
			iVBUpCommit += iVBUpCount;
			iVBWrCommit += iVBWrCount;
			iResult = iscommit ();
			if (iResult < 0) {
				printf ("Error commit: %d\n", iserrno);
				exit (-1);
			}
			break;

		case	1:
			iResult = isrollback ();
			if (iResult < 0) {
				if (iserrno == EDUPL || iserrno == ENOREC) {
					printf ("Same BUG (%d) as in C-ISAM!\n", iserrno);
				} else {
					printf ("Error rollback: %d\n", iserrno);
					exit (-1);
				}
			}
			break;
		}
	}
err:
	printf ("                 Total Commited\n");
	printf ("              -------- --------\n");
	printf ("Delete Count: %8d %8d\n", iVBDlTotal, iVBDlCommit);
	printf ("Read   Count: %8d %8d\n", iVBRdTotal, iVBRdCommit);
	printf ("Update Count: %8d %8d\n", iVBUpTotal, iVBUpCommit);
	printf ("Write  Count: %8d %8d\n", iVBWrTotal, iVBWrCommit);
	printf ("              -------- --------\n");
	printf ("OPS OVERALL : %8d %8d\n", (iVBDlTotal + iVBRdTotal + iVBUpTotal + iVBWrTotal), (iVBDlCommit + iVBRdCommit + iVBUpCommit + iVBWrCommit));
	printf ("                       ========\n");
	printf ("ROWS ADDED THIS RUN:   %8d\n", (iVBWrCommit - iVBDlCommit));
	printf ("                       ========\n");
	return (iResult);
}
Exemplo n.º 9
0
int
idxopen (unit *ftnunit, char *name, int create, flag idxerr)
{
   struct dictinfo info;
   int             mode =(ftnunit->ureadonly ? ISINPUT : ISINOUT) +
   (ftnunit->ushared ? ISAUTOLOCK : ISEXCLLOCK);
   register int    i;

   keys = ftnunit->ukeys;
   if (create) {
      if (ftnunit->url == 0)
	 err (idxerr, 153, "indexed open");
      if (ftnunit->unkeys == 0 || keys == NULL)
	 err (idxerr, 161, "indexed open");
      onekey.k_flags = ISNODUPS;
      KEYOFF (0)--;
      KEYEND (0)--;
      dokey (0, ONEKEY);
      if (ftnunit->unkeys == 1) {
	/* DLAI: need to change isbuild 2nd arg to XINT */
	 if ((ftnunit->isfd = isbuild (name, ftnunit->url, &onekey, mode)) < SUCCESS)
	    ierr (idxerr, iserrno, "indexed open");
      } else {
	 if ((ftnunit->isfd =
	      isbuild (name, ftnunit->url, &onekey, ISINOUT + ISEXCLLOCK)) < SUCCESS)
	    ierr (idxerr, iserrno, "indexed open");
	 onekey.k_flags = ISDUPS;
	 for (i = 1; i < ftnunit->unkeys; i++) {
	    KEYOFF (i)--;
	    KEYEND (i)--;
	    dokey (i, ONEKEY);
	    if (isaddindex (ftnunit->isfd, &onekey) < SUCCESS)
	       ierr (idxerr, iserrno, "indexed open");
	 }
	 if (ftnunit->ushared) {
	    if (isclose (ftnunit->isfd) < SUCCESS)
	       ierr (idxerr, iserrno, "indexed open");
	    if ((ftnunit->isfd = isopen (name, mode)) < SUCCESS)
	       ierr (idxerr, iserrno, "indexed open");
	 }
      }
   } else {
      if ((ftnunit->isfd = isopen (name, mode)) < SUCCESS)
	 ierr (idxerr, iserrno, "indexed open");
      if (isindexinfo (ftnunit->isfd, &info, 0) < SUCCESS)
	 ierr (idxerr, iserrno, "indexed open");
      if (ftnunit->unkeys != info.di_nkeys) {
	 if (ftnunit->unkeys) {
	    err (idxerr, 148, "indexed open");
	 } else
	    ftnunit->unkeys = info.di_nkeys;
      }
      if (!keys)
	 keys = (Keyspec *) malloc (sizeof (Keyspec) * info.di_nkeys);
      for (i = 0; i < info.di_nkeys; i++) {
	 if (isindexinfo (ftnunit->isfd, &onekey, i + 1) < SUCCESS)
	    ierr (idxerr, iserrno, "indexed open");
/* LHL 5/4/89
 * To fix bug 4428, problem about trying to open an existing indexed file.
 * This is put here because when the indexed file is created, the keys
 * are being stored like this.  Refer to the above code.
 */
	 KEYOFF (i)--;
	 KEYEND (i)--;
/* end of fix */
	 if (ftnunit->ukeys && dokey (i, NOMATCH)) {
	    err (idxerr, 148, "indexed open");
	 } else
	    dokey (i, UNITKEY);
      }
      ftnunit->url = info.di_recsize;
      ftnunit->ukeys = keys;
   }
   return SUCCESS;
}