GnuCOBOL  2.0
A free COBOL compiler
isbuild.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2003 Trevor van Bremen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 2.1,
7  * or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; see the file COPYING.LIB. If
16  * not, write to the Free Software Foundation, 51 Franklin Street, Fifth Floor
17  * Boston, MA 02110-1301 USA
18  */
19 
20 #include "isinternal.h"
21 
22 /* Local functions */
23 
24 static int
25 iaddkeydescriptor (const int ihandle, struct keydesc *pskeydesc)
26 {
27  struct DICTINFO *psvbptr;
28  char *pcdstptr;
29  off_t theadnode, tnodenumber = 0, tnewnode;
30  int iloop, ilenkeyuncomp = 0, ilenkeydesc, inodeused;
31  char ckeydesc[INTSIZE + QUADSIZE + 1 + (NPARTS * ((INTSIZE * 2) + 1))];
32  char cvbnodetmp[VB_NODE_MAX];
33  char cvbnodetmp2[VB_NODE_MAX];
34 
35  psvbptr = psvbfile[ihandle];
36  pcdstptr = ckeydesc + INTSIZE;
37  /*
38  * Step 1:
39  * Create a new 'root node' for the new index
40  */
41  tnewnode = tvbnodecountgetnext (ihandle);
42  if (tnewnode == -1) {
43  return -1;
44  }
45  memset (cvbnodetmp, 0, VB_NODE_MAX);
46 #if ISAMMODE == 1
47  inl_stint (INTSIZE + QUADSIZE, cvbnodetmp);
48  inl_stquad ((off_t)1, cvbnodetmp + INTSIZE);
49 #else
50  inl_stint (INTSIZE, cvbnodetmp);
51 #endif
52  iserrno = ivbblockwrite (ihandle, 1, tnewnode, cvbnodetmp);
53  if (iserrno) {
54  return -1;
55  }
56  /*
57  * Step 2:
58  * Append the new key description to the keydesc list
59  */
60  theadnode = inl_ldquad (psvbptr->sdictnode.cnodekeydesc);
61  if (theadnode < 1) {
62  return -1;
63  }
64  while (theadnode) {
65  tnodenumber = theadnode;
66  iserrno = ivbblockread (ihandle, 1, tnodenumber, cvbnodetmp);
67  if (iserrno) {
68  return -1;
69  }
70  theadnode = inl_ldquad (cvbnodetmp + INTSIZE);
71  }
72  inl_stquad (tnewnode, pcdstptr);
73  pcdstptr += QUADSIZE;
74  *pcdstptr = pskeydesc->k_flags / 2;
75  pcdstptr++;
76  for (iloop = 0; iloop < pskeydesc->k_nparts; iloop++) {
77  ilenkeyuncomp += pskeydesc->k_part[iloop].kp_leng;
78  inl_stint (pskeydesc->k_part[iloop].kp_leng, pcdstptr);
79  if (iloop == 0 && pskeydesc->k_flags & ISDUPS) {
80  *pcdstptr |= 0x80;
81  }
82  pcdstptr += INTSIZE;
83  inl_stint (pskeydesc->k_part[iloop].kp_start, pcdstptr);
84  pcdstptr += INTSIZE;
85  *pcdstptr = pskeydesc->k_part[iloop].kp_type;
86  pcdstptr++;
87  }
88  inodeused = inl_ldint (cvbnodetmp);
89  ilenkeydesc = pcdstptr - ckeydesc;
90  inl_stint (ilenkeydesc, ckeydesc);
91  if (psvbptr->inodesize - (inodeused + 4) < ilenkeydesc) {
92  tnewnode = tvbnodecountgetnext (ihandle);
93  if (tnewnode == -1) {
94  return -1;
95  }
96  memset (cvbnodetmp2, 0, VB_NODE_MAX);
97  inl_stint (INTSIZE + QUADSIZE + ilenkeydesc, cvbnodetmp2);
98  memcpy (cvbnodetmp2 + INTSIZE + QUADSIZE, ckeydesc, (size_t)ilenkeydesc);
99  iserrno = ivbblockwrite (ihandle, 1, tnewnode, cvbnodetmp2);
100  if (iserrno) {
101  return -1;
102  }
103  inl_stquad (tnewnode, cvbnodetmp + INTSIZE);
104  iserrno = ivbblockwrite (ihandle, 1, tnodenumber, cvbnodetmp);
105  if (iserrno) {
106  return -1;
107  }
108  return 0;
109  }
110  inl_stint (inodeused + ilenkeydesc, cvbnodetmp);
111  pskeydesc->k_len = ilenkeyuncomp;
112  pskeydesc->k_rootnode = tnewnode;
113  memcpy (cvbnodetmp + inodeused, ckeydesc, (size_t)ilenkeydesc);
114  iserrno = ivbblockwrite (ihandle, 1, tnodenumber, cvbnodetmp);
115  if (iserrno) {
116  return -1;
117  }
118  return 0;
119 }
120 
121 static off_t
122 tdelkeydescriptor (const int ihandle, struct keydesc *pskeydesc, const int ikeynumber)
123 {
124  struct DICTINFO *psvbptr;
125  char *pcsrcptr;
126  off_t theadnode;
127  int iloop = 0;
128  int inodeused;
129  int n;
130  char cvbnodetmp[VB_NODE_MAX];
131 
132  psvbptr = psvbfile[ihandle];
133  iserrno = EBADFILE;
134  theadnode = inl_ldquad (psvbptr->sdictnode.cnodekeydesc);
135  while (1) {
136  if (!theadnode) {
137  return -1;
138  }
139  memset (cvbnodetmp, 0, VB_NODE_MAX);
140  iserrno = ivbblockread (ihandle, 1, theadnode, cvbnodetmp);
141  if (iserrno) {
142  return -1;
143  }
144  pcsrcptr = cvbnodetmp + INTSIZE + QUADSIZE;
145  inodeused = inl_ldint (cvbnodetmp);
146  while (pcsrcptr - cvbnodetmp < inodeused) {
147  if (iloop < ikeynumber) {
148  iloop++;
149  pcsrcptr += inl_ldint (pcsrcptr);
150  continue;
151  }
152  n = inl_ldint (pcsrcptr);
153  inodeused -= n;
154  inl_stint (inodeused, cvbnodetmp);
155  memcpy (pcsrcptr, pcsrcptr + n,
156  (size_t)(psvbptr->inodesize - (pcsrcptr - cvbnodetmp +
157  n)));
158  iserrno = ivbblockwrite (ihandle, 1, theadnode, cvbnodetmp);
159  if (iserrno) {
160  return -1;
161  }
162  return psvbptr->pskeydesc[ikeynumber]->k_rootnode;
163  }
164  theadnode = inl_ldquad (cvbnodetmp + INTSIZE);
165  }
166  return -1; /* Just to keep the compiler happy :) */
167 }
168 
169 static int
170 idelnodes (const int ihandle, const int ikeynumber, off_t trootnode)
171 {
172  struct DICTINFO *psvbptr;
173  char *pcsrcptr;
174  struct keydesc *pskeydesc;
175  int iduplicate, ikeylength, icomplength = 0;
176  int inodeused, iresult = 0;
177  char clclnode[VB_NODE_MAX];
178 
179  psvbptr = psvbfile[ihandle];
180  pskeydesc = psvbptr->pskeydesc[ikeynumber];
181  iresult = ivbblockread (ihandle, 1, trootnode, clclnode);
182  if (iresult) {
183  return iresult;
184  }
185  /* Recurse for non-leaf nodes */
186  if (*(clclnode + psvbptr->inodesize - 2)) {
187  inodeused = inl_ldint (clclnode);
188 #if ISAMMODE == 1
189  pcsrcptr = clclnode + INTSIZE + QUADSIZE;
190 #else
191  pcsrcptr = clclnode + INTSIZE;
192 #endif
193  iduplicate = 0;
194  while (pcsrcptr - clclnode < inodeused) {
195  if (iduplicate) {
196  if (!(*(pcsrcptr + QUADSIZE) & 0x80)) {
197  iduplicate = 0;
198  }
199  *(pcsrcptr + QUADSIZE) &= ~0x80;
200  iresult = idelnodes (ihandle, ikeynumber, inl_ldquad (pcsrcptr + QUADSIZE)); /* Eeek, recursion :) */
201  if (iresult) {
202  return iresult;
203  }
204  pcsrcptr += (QUADSIZE * 2);
205  }
206  ikeylength = pskeydesc->k_len;
207  if (pskeydesc->k_flags & LCOMPRESS) {
208 #if ISAMMODE == 1
209  icomplength = inl_ldint (pcsrcptr);
210  pcsrcptr += INTSIZE;
211  ikeylength -= (icomplength - 2);
212 #else
213  icomplength = *(pcsrcptr);
214  pcsrcptr++;
215  ikeylength -= (icomplength - 1);
216 #endif
217  }
218  if (pskeydesc->k_flags & TCOMPRESS) {
219 #if ISAMMODE == 1
220  icomplength = inl_ldint (pcsrcptr);
221  pcsrcptr += INTSIZE;
222  ikeylength -= (icomplength - 2);
223 #else
224  icomplength = *pcsrcptr;
225  pcsrcptr++;
226  ikeylength -= (icomplength - 1);
227 #endif
228  }
229  pcsrcptr += ikeylength;
230  if (pskeydesc->k_flags & ISDUPS) {
231  pcsrcptr += QUADSIZE;
232  if (*pcsrcptr & 0x80) {
233  iduplicate = 1;
234  }
235  }
236  iresult = idelnodes (ihandle, ikeynumber, inl_ldquad (pcsrcptr)); /* Eeek, recursion :) */
237  if (iresult) {
238  return iresult;
239  }
240  pcsrcptr += QUADSIZE;
241  }
242  }
243  iresult = ivbnodefree (ihandle, trootnode);
244  return iresult;
245 }
246 
247 static int
248 imakekeysfromdata (const int ihandle, const int ikeynumber)
249 {
250  struct DICTINFO *psvbptr;
251  struct VBKEY *pskey;
252  off_t tdupnumber, tloop;
253  int ideleted, iresult;
254  unsigned char ckeyvalue[VB_MAX_KEYLEN];
255 
256  psvbptr = psvbfile[ihandle];
257  /* Don't have to insert if the key is a NULL key! */
258  if (psvbptr->pskeydesc[ikeynumber]->k_nparts == 0) {
259  return 0;
260  }
261 
262  for (tloop = 1; tloop < inl_ldquad (psvbptr->sdictnode.cdatacount); tloop++) {
263  /*
264  * Step 1:
265  * Read in the existing data row (Just the min rowlength)
266  */
267  iserrno = ivbdataread (ihandle, psvbptr->ppcrowbuffer,
268  &ideleted, tloop);
269  if (iserrno) {
270  return -1;
271  }
272  if (ideleted) {
273  continue;
274  }
275  /*
276  * Step 2:
277  * Check the index for a potential ISNODUPS error (EDUPL)
278  * Also, calculate the duplicate number as needed
279  */
280  vvbmakekey (psvbptr->pskeydesc[ikeynumber], psvbptr->ppcrowbuffer, ckeyvalue);
281  iresult = ivbkeysearch (ihandle, ISGREAT, ikeynumber, 0, ckeyvalue, (off_t)0);
282  tdupnumber = 0;
283  if (iresult >= 0 && !ivbkeyload (ihandle, ikeynumber, ISPREV, 0, &pskey)
284  && !memcmp (pskey->ckey, ckeyvalue,
285  (size_t)psvbptr->pskeydesc[ikeynumber]->k_len)) {
286  iserrno = EDUPL;
287  if (psvbptr->pskeydesc[ikeynumber]->k_flags & ISDUPS) {
288  tdupnumber = pskey->tdupnumber + 1;
289  } else {
290  return -1;
291  }
292  }
293 
294  /*
295  * Step 3:
296  * Perform the actual insertion into the index
297  */
298  iresult = ivbkeyinsert (ihandle, NULL, ikeynumber, ckeyvalue, tloop,
299  tdupnumber, NULL);
300  if (iresult) {
301  return iresult;
302  }
303  }
304  return 0;
305 }
306 
307 /* Global functions */
308 
309 int
310 isbuild (const char *pcfilename, const int imaxrowlength, struct keydesc *pskey, int imode)
311 {
312  char *pctemp;
313  struct DICTINFO *psvbptr;
314  int iflags, ihandle, iloop, iminrowlength;
315  struct stat sstat;
316  char cvbnodetmp[VB_NODE_MAX];
317  char tmpfname[1024];
318 
319  /* STEP 1: Sanity checks */
320  if (imode & ISVARLEN) {
321  iminrowlength = isreclen;
322  } else {
323  iminrowlength = imaxrowlength;
324  }
325  iflags = imode & 0x03;
326  if (iflags == 3) {
327  /* Cannot be BOTH ISOUTPUT and ISINOUT */
328  iserrno = EBADARG;
329  return -1;
330  }
331  if (strlen (pcfilename) > sizeof(tmpfname) - 5) {
332  iserrno = EFNAME;
333  return -1;
334  }
335  if (pskey == NULL) {
336  iserrno = EBADARG;
337  return -1;
338  }
339 
340  /* Sanity checks passed (so far) */
341  for (ihandle = 0; ihandle <= ivbmaxusedhandle; ihandle++) {
342  if (psvbfile[ihandle] != NULL) {
343  if (!strcmp (psvbfile[ihandle]->cfilename, pcfilename)) {
344  isclose (ihandle);
345  ivbclose3 (ihandle);
346  break;
347  }
348  }
349  }
350  for (ihandle = 0; ; ihandle++) {
351  if (ihandle > ivbmaxusedhandle) {
353  iserrno = ETOOMANY;
354  return -1;
355  }
356  ivbmaxusedhandle = ihandle;
357  break;
358  }
359  if (psvbfile[ihandle] == NULL) {
360  break;
361  }
362  }
363  psvbfile[ihandle] = pvvbmalloc (sizeof (struct DICTINFO));
364  psvbptr = psvbfile[ihandle];
365  if (psvbptr == NULL) {
366  errno = EBADMEM;
367  goto build_err;
368  }
369  psvbptr->cfilename = strdup (pcfilename);
370  if (psvbptr->cfilename == NULL) {
371  errno = EBADMEM;
372  goto build_err;
373  }
375  if (psvbptr->ppcrowbuffer == NULL) {
376  errno = EBADMEM;
377  goto build_err;
378  }
379  iserrno = EBADARG;
380  psvbptr->iminrowlength = iminrowlength;
381  psvbptr->imaxrowlength = imaxrowlength;
382  psvbptr->pskeydesc[0] = pvvbmalloc (sizeof (struct keydesc));
383  if (psvbptr->pskeydesc[0] == NULL) {
384  errno = EBADMEM;
385  goto build_err;
386  }
387  memcpy (psvbptr->pskeydesc[0], pskey, sizeof (struct keydesc));
388  if (ivbcheckkey (ihandle, pskey, 0, iminrowlength, 1)) {
389  return -1;
390  }
391  sprintf (tmpfname, "%s.dat", pcfilename);
392  if (!stat (tmpfname, &sstat)) {
393  errno = EEXIST;
394  goto build_err;
395  }
396  sprintf (tmpfname, "%s.idx", pcfilename);
397  if (!stat (tmpfname, &sstat)) {
398  errno = EEXIST;
399  goto build_err;
400  }
401  psvbptr->iindexhandle = ivbopen (tmpfname, O_RDWR | O_CREAT | O_BINARY, 0660);
402  if (psvbptr->iindexhandle < 0) {
403  goto build_err;
404  }
405  sprintf (tmpfname, "%s.dat", pcfilename);
406  psvbptr->idatahandle = ivbopen (tmpfname, O_RDWR | O_CREAT | O_BINARY, 0660);
407  if (psvbptr->idatahandle < 0) {
408  ivbclose (psvbptr->iindexhandle); /* Ignore ret */
409  goto build_err;
410  }
411  psvbptr->inkeys = 1;
412  psvbptr->inodesize = MAX_NODE_LENGTH;
413  psvbptr->iopenmode = imode;
414  psvbptr->iisdictlocked |= 0x01;
415 
416  /* Setup root (dictionary) node (Node 1) */
417  memset (cvbnodetmp, 0, VB_NODE_MAX);
418  memset ((void *)&psvbptr->sdictnode, 0, sizeof (struct DICTNODE));
419 #if ISAMMODE == 1
420  psvbptr->sdictnode.cvalidation[0] = 'V';
421  psvbptr->sdictnode.cvalidation[1] = 'B';
422  psvbptr->sdictnode.crsvdperkey = 0x08;
423 #else
424  psvbptr->sdictnode.cvalidation[0] = 0xfe;
425  psvbptr->sdictnode.cvalidation[1] = 0x53;
426  psvbptr->sdictnode.crsvdperkey = 0x04;
427 #endif
428  psvbptr->sdictnode.cheaderrsvd = 0x02;
429  psvbptr->sdictnode.cfooterrsvd = 0x02;
430  psvbptr->sdictnode.crfu1 = 0x04;
431  inl_stint (psvbptr->inodesize - 1, psvbptr->sdictnode.cnodesize);
432  inl_stint (1, psvbptr->sdictnode.cindexcount);
433  inl_stint (0x0704, psvbptr->sdictnode.crfu2);
434  inl_stint (iminrowlength, psvbptr->sdictnode.cminrowlength);
435  inl_stquad ((off_t)2, psvbptr->sdictnode.cnodekeydesc);
436  inl_stquad ((off_t)0, psvbptr->sdictnode.cdatafree);
437  inl_stquad ((off_t)0, psvbptr->sdictnode.cnodefree);
438  inl_stquad ((off_t)0, psvbptr->sdictnode.cdatacount);
439  if (pskey->k_nparts) {
440  inl_stquad (3, psvbptr->sdictnode.cnodecount);
441  } else {
442  inl_stquad (2, psvbptr->sdictnode.cnodecount);
443  }
444  inl_stquad ((off_t)1, psvbptr->sdictnode.ctransnumber);
445  inl_stquad ((off_t)1, psvbptr->sdictnode.cuniqueid);
446  inl_stquad ((off_t)0, psvbptr->sdictnode.cnodeaudit);
447  inl_stint (0x0008, psvbptr->sdictnode.clockmethod);
448  if (imode & ISVARLEN) {
449  inl_stint (imaxrowlength, psvbptr->sdictnode.cmaxrowlength);
450  } else {
451  inl_stint (0, psvbptr->sdictnode.cmaxrowlength);
452  }
453  memcpy (cvbnodetmp, &psvbptr->sdictnode, sizeof (struct DICTNODE));
454  if (ivbblockwrite (ihandle, 1, (off_t) 1, cvbnodetmp)) {
455  ivbclose (psvbptr->iindexhandle); /* Ignore ret */
456  ivbclose (psvbptr->idatahandle); /* Ignore ret */
457  if (psvbptr->cfilename) {
458  free (psvbptr->cfilename);
459  }
460  if (psvbptr->ppcrowbuffer) {
461  free (psvbptr->ppcrowbuffer);
462  }
463  if (psvbptr->pskeydesc[0]) {
464  free (psvbptr->pskeydesc[0]);
465  }
466  vvbfree (psvbptr);
467  psvbfile[ihandle] = NULL;
468  return -1;
469  }
470 
471  /* Setup first keydesc node (Node 2) */
472  memset (cvbnodetmp, 0, VB_NODE_MAX);
473  pctemp = cvbnodetmp;
474  pctemp += INTSIZE;
475  inl_stquad ((off_t)0, pctemp); /* Next keydesc node */
476  pctemp += QUADSIZE;
477  /* keydesc length */
478  inl_stint (INTSIZE + QUADSIZE + 1 + (((INTSIZE * 2) + 1) * pskey->k_nparts), pctemp);
479  pctemp += INTSIZE;
480  if (pskey->k_nparts) {
481  inl_stquad ((off_t)3, pctemp); /* Root node for this key */
482  } else {
483  inl_stquad ((off_t)0, pctemp); /* Root node for this key */
484  }
485  pctemp += QUADSIZE;
486  *pctemp = pskey->k_flags / 2; /* Compression / Dups flags */
487  pctemp++;
488  for (iloop = 0; iloop < pskey->k_nparts; iloop++) {
489  inl_stint (pskey->k_part[iloop].kp_leng, pctemp); /* Length */
490  if (iloop == 0 && pskey->k_flags & 1) {
491  *pctemp |= 0x80;
492  }
493  pctemp += INTSIZE;
494  inl_stint (pskey->k_part[iloop].kp_start, pctemp); /* Offset */
495  pctemp += INTSIZE;
496  *pctemp = pskey->k_part[iloop].kp_type; /* Type */
497  pctemp++;
498  }
499  inl_stint (pctemp - cvbnodetmp, cvbnodetmp); /* Length used */
500  inl_stint (0xff7e, cvbnodetmp + psvbptr->inodesize - 3);
501  if (ivbblockwrite (ihandle, 1, (off_t) 2, cvbnodetmp)) {
502  ivbclose (psvbptr->iindexhandle); /* Ignore ret */
503  ivbclose (psvbptr->idatahandle); /* Ignore ret */
504  if (psvbptr->cfilename) {
505  free (psvbptr->cfilename);
506  }
507  if (psvbptr->ppcrowbuffer) {
508  free (psvbptr->ppcrowbuffer);
509  }
510  if (psvbptr->pskeydesc[0]) {
511  free (psvbptr->pskeydesc[0]);
512  }
513  vvbfree (psvbptr);
514  psvbfile[ihandle] = NULL;
515  return -1;
516  }
517 
518  if (pskey->k_nparts) {
519  /* Setup key root node (Node 3) */
520  memset (cvbnodetmp, 0, VB_NODE_MAX);
521 #if ISAMMODE == 1
522  inl_stint (INTSIZE + QUADSIZE, cvbnodetmp);
523  inl_stquad ((off_t)1, cvbnodetmp + INTSIZE); /* Transaction number */
524 #else
525  inl_stint (INTSIZE, cvbnodetmp);
526 #endif
527  if (ivbblockwrite (ihandle, 1, (off_t) 3, cvbnodetmp)) {
528  ivbclose (psvbptr->iindexhandle); /* Ignore ret */
529  ivbclose (psvbptr->idatahandle); /* Ignore ret */
530  if (psvbptr->cfilename) {
531  free (psvbptr->cfilename);
532  }
533  if (psvbptr->ppcrowbuffer) {
534  free (psvbptr->ppcrowbuffer);
535  }
536  if (psvbptr->pskeydesc[0]) {
537  free (psvbptr->pskeydesc[0]);
538  }
539  vvbfree (psvbptr);
540  psvbfile[ihandle] = NULL;
541  return -1;
542  }
543  }
544 
545  psvbptr->iisopen = 0; /* Mark it as FULLY open */
546  if (imode & ISEXCLLOCK) {
547  ivbfileopenlock (ihandle, 2);
548  } else {
549  ivbfileopenlock (ihandle, 1);
550  }
551  isclose (ihandle);
552 /* RXW - something wrong with close/open and iisopen here */
553 /* Really close - Why ? */
554  ivbclose3 (ihandle);
555  iserrno = 0;
556  ivbtransbuild (pcfilename, iminrowlength, imaxrowlength, pskey, imode);
557  return isopen (pcfilename, imode);
558 build_err:
559  if (psvbfile[ihandle] != NULL) {
560  if (psvbfile[ihandle]->cfilename) {
561  free (psvbfile[ihandle]->cfilename);
562  }
563  if (psvbfile[ihandle]->ppcrowbuffer) {
564  free (psvbfile[ihandle]->ppcrowbuffer);
565  }
566  if (psvbfile[ihandle]->pskeydesc[0]) {
567  free (psvbfile[ihandle]->pskeydesc[0]);
568  }
569  vvbfree (psvbfile[ihandle]);
570  }
571  psvbfile[ihandle] = NULL;
572  iserrno = errno;
573  return -1;
574 }
575 
576 int
577 isaddindex (const int ihandle, struct keydesc *pskeydesc)
578 {
579  struct DICTINFO *psvbptr;
580  int iresult, ikeynumber;
581 
582  if (ivbenter (ihandle, 1, 0)) {
583  return -1;
584  }
585 
586  iresult = -1;
587  iserrno = ENOTEXCL;
588  psvbptr = psvbfile[ihandle];
589  if (!(psvbptr->iopenmode & ISEXCLLOCK)) {
590  goto addindexexit;
591  }
592  iserrno = EKEXISTS;
593  ikeynumber = ivbcheckkey (ihandle, pskeydesc, 1, 0, 0);
594  if (ikeynumber == -1) {
595  goto addindexexit;
596  }
597  ikeynumber = iaddkeydescriptor (ihandle, pskeydesc);
598  if (ikeynumber) {
599  goto addindexexit;
600  }
601  psvbptr->iisdictlocked |= 0x02;
602  ikeynumber = ivbcheckkey (ihandle, pskeydesc, 1, 0, 0);
603  if (ikeynumber < 0) {
604  goto addindexexit;
605  }
606  for (ikeynumber = 0; ikeynumber < MAXSUBS && psvbptr->pskeydesc[ikeynumber];
607  ikeynumber++) ;
608  iserrno = ETOOMANY;
609  if (ikeynumber >= MAXSUBS) {
610  goto addindexexit;
611  }
612  ikeynumber = psvbptr->inkeys;
613  psvbptr->pskeydesc[ikeynumber] = pvvbmalloc (sizeof (struct keydesc));
614  psvbptr->inkeys++;
615  inl_stint (psvbptr->inkeys, psvbptr->sdictnode.cindexcount);
616  iserrno = errno;
617  if (!psvbptr->pskeydesc[ikeynumber]) {
618  goto addindexexit;
619  }
620  memcpy (psvbptr->pskeydesc[ikeynumber], pskeydesc, sizeof (struct keydesc));
621  if (imakekeysfromdata (ihandle, ikeynumber)) {
622 /* BUG - Handle this better! */
623  iresult = iserrno;
624  ivbexit (ihandle);
625  isdelindex (ihandle, pskeydesc);
626  iserrno = iresult;
627  goto addindexexit;
628  }
629  iserrno = 0;
630  iresult = ivbtranscreateindex (ihandle, pskeydesc);
631 
632 addindexexit:
633 /* RXW
634  iresult |= ivbforceexit (ihandle);
635 */
636  iresult |= ivbexit (ihandle);
637  if (iresult) {
638  return -1;
639  }
640  return 0;
641 }
642 
643 int
644 isdelindex (const int ihandle, struct keydesc *pskeydesc)
645 {
646  struct DICTINFO *psvbptr;
647  off_t trootnode;
648  int iresult = -1, ikeynumber, iloop;
649 
650  if (ivbenter (ihandle, 1, 0)) {
651  return -1;
652  }
653 
654  psvbptr = psvbfile[ihandle];
655  if (!(psvbptr->iopenmode & ISEXCLLOCK)) {
656  iserrno = ENOTEXCL;
657  goto delindexexit;
658  }
659  ikeynumber = ivbcheckkey (ihandle, pskeydesc, 2, 0, 0);
660  if (ikeynumber == -1) {
661  iserrno = EKEXISTS;
662  goto delindexexit;
663  }
664  if (!ikeynumber) {
665  iserrno = EPRIMKEY;
666  goto delindexexit;
667  }
668  trootnode = tdelkeydescriptor (ihandle, pskeydesc, ikeynumber);
669  if (trootnode < 1) {
670  goto delindexexit;
671  }
672  if (idelnodes (ihandle, ikeynumber, trootnode)) {
673  goto delindexexit;
674  }
675  vvbfree (psvbptr->pskeydesc[ikeynumber]);
676  vvbtreeallfree (ihandle, ikeynumber, psvbptr->pstree[ikeynumber]);
677  vvbkeyunmalloc (ihandle, ikeynumber);
678  for (iloop = ikeynumber; iloop < MAXSUBS; iloop++) {
679  psvbptr->pskeydesc[iloop] = psvbptr->pskeydesc[iloop + 1];
680  psvbptr->pstree[iloop] = psvbptr->pstree[iloop + 1];
681  psvbptr->pskeyfree[iloop] = psvbptr->pskeyfree[iloop + 1];
682  psvbptr->pskeycurr[iloop] = psvbptr->pskeycurr[iloop + 1];
683  }
684  psvbptr->pskeydesc[MAXSUBS - 1] = NULL;
685  psvbptr->pstree[MAXSUBS - 1] = NULL;
686  psvbptr->pskeyfree[MAXSUBS - 1] = NULL;
687  psvbptr->pskeycurr[MAXSUBS - 1] = NULL;
688  psvbptr->inkeys--;
689  inl_stint (psvbptr->inkeys, psvbptr->sdictnode.cindexcount);
690  psvbptr->iisdictlocked |= 0x02;
691  iresult = ivbtransdeleteindex (ihandle, pskeydesc);
692 
693 delindexexit:
694 /* RXW
695  iresult |= ivbforceexit (ihandle);
696 */
697  iresult |= ivbexit (ihandle);
698  return iresult;
699 }
int isdelindex(const int ihandle, struct keydesc *pskeydesc)
Definition: isbuild.c:644
int ivbopen(const char *pcfilename, const int iflags, const mode_t tmode)
Definition: vblowlevel.c:32
int inkeys
Definition: isinternal.h:400
int imaxrowlength
Definition: isinternal.h:404
static int inl_ldint(void *pclocation)
Definition: isinternal.h:170
char cfooterrsvd
Definition: isinternal.h:362
int ivbkeysearch(const int ihandle, const int imode, const int ikeynumber, int ilength, unsigned char *pckeyvalue, off_t tdupnumber)
Definition: vbkeysio.c:372
int ivbblockread(const int ihandle, const int iisindex, const off_t tblocknumber, char *cbuffer)
Definition: vblowlevel.c:137
int ivbcheckkey(const int ihandle, struct keydesc *pskey, const int imode, int irowlength, const int iisbuild)
Definition: isread.c:124
unsigned char ckey[1]
Definition: isinternal.h:334
int isreclen
Definition: vbmemio.c:29
char clockmethod[2]
Definition: isinternal.h:380
static int imakekeysfromdata(const int ihandle, const int ikeynumber)
Definition: isbuild.c:248
char cminrowlength[2]
Definition: isinternal.h:369
char crfu2[2]
Definition: isinternal.h:367
int ivbtranscreateindex(const int ihandle, struct keydesc *pskeydesc)
Definition: istrans.c:648
int iindexhandle
Definition: isinternal.h:406
char cuniqueid[8]
Definition: isinternal.h:378
int ivbenter(const int ihandle, const unsigned int imodifying, const unsigned int ispecial)
Definition: vblocking.c:178
char cnodeaudit[8]
Definition: isinternal.h:379
int ivbkeyload(const int ihandle, const int ikeynumber, const int imode, const int isetcurr, struct VBKEY **ppskey)
Definition: vbkeysio.c:503
char cnodekeydesc[8]
Definition: isinternal.h:370
void vvbfree(void *mptr)
Definition: vbmemio.c:59
int iminrowlength
Definition: isinternal.h:403
static int iaddkeydescriptor(const int ihandle, struct keydesc *pskeydesc)
Definition: isbuild.c:25
#define O_BINARY
Definition: fileio.c:90
char * cfilename
Definition: isinternal.h:422
void ivbclose3(const int ihandle)
Definition: isopen.c:125
char crfu1
Definition: isinternal.h:364
int ivbmaxusedhandle
Definition: vblocking.c:26
char cdatacount[8]
Definition: isinternal.h:375
#define VB_NODE_MAX
Definition: isinternal.h:288
int iisopen
Definition: isinternal.h:407
static void inl_stint(int ivalue, void *pclocation)
Definition: isinternal.h:190
int ivbtransdeleteindex(const int ihandle, struct keydesc *pskeydesc)
Definition: istrans.c:734
unsigned char iisdictlocked
Definition: isinternal.h:427
int isopen(const char *pcfilename, int imode)
Definition: isopen.c:270
EC ARGUMENT EC EC BOUND EC BOUND EC BOUND EC BOUND TABLE EC DATA EC DATA EC DATA PTR NULL
Definition: exception.def:95
char cvalidation[2]
Definition: isinternal.h:360
struct VBKEY * pskeyfree[32]
Definition: isinternal.h:447
#define MAX_NODE_LENGTH
Definition: isinternal.h:283
struct VBKEY * pskeycurr[32]
Definition: isinternal.h:448
struct DICTNODE sdictnode
Definition: isinternal.h:444
char cnodecount[8]
Definition: isinternal.h:376
void vvbmakekey(const struct keydesc *pskeydesc, char *pcrow_buffer, unsigned char *pckeyvalue)
Definition: vbkeysio.c:212
#define VB_MAX_FILES
Definition: isinternal.h:120
int ivbdataread(const int ihandle, char *pcbuffer, int *pideletedrow, const off_t trownumber)
Definition: vbdataio.c:493
void * pvvbmalloc(const size_t size)
Definition: vbmemio.c:45
int ivbfileopenlock(const int ihandle, const int imode)
Definition: vblocking.c:380
static int idelnodes(const int ihandle, const int ikeynumber, off_t trootnode)
Definition: isbuild.c:170
char crsvdperkey
Definition: isinternal.h:363
char cmaxrowlength[2]
Definition: isinternal.h:382
char cnodesize[2]
Definition: isinternal.h:365
struct DICTINFO * psvbfile[128+1]
Definition: vblowlevel.c:23
#define QUADSIZE
Definition: isinternal.h:108
off_t tvbnodecountgetnext(const int ihandle)
Definition: vbindexio.c:48
int isaddindex(const int ihandle, struct keydesc *pskeydesc)
Definition: isbuild.c:577
int ivbtransbuild(const char *pcfilename, const int iminrowlen, const int imaxrowlen, struct keydesc *pskeydesc, const int imode)
Definition: istrans.c:599
char cnodefree[8]
Definition: isinternal.h:374
char ctransnumber[8]
Definition: isinternal.h:377
off_t tdupnumber
Definition: isinternal.h:329
char cindexcount[2]
Definition: isinternal.h:366
int ivbnodefree(const int ihandle, const off_t tnodenumber)
Definition: vbindexio.c:67
int ivbclose(const int ihandle)
Definition: vblowlevel.c:93
int ivbkeyinsert(const int ihandle, struct VBTREE *pstree, const int ikeynumber, unsigned char *pckeyvalue, off_t trownode, off_t tdupnumber, struct VBTREE *pschild)
Definition: vbkeysio.c:727
char cdatafree[8]
Definition: isinternal.h:373
int ivbexit(const int ihandle)
Definition: vblocking.c:290
int iopenmode
Definition: isinternal.h:412
int ivbblockwrite(const int ihandle, const int iisindex, const off_t tblocknumber, const char *cbuffer)
Definition: vblowlevel.c:167
static off_t tdelkeydescriptor(const int ihandle, struct keydesc *pskeydesc, const int ikeynumber)
Definition: isbuild.c:122
int isclose(const int ihandle)
Definition: isopen.c:182
void vvbtreeallfree(const int ihandle, const int ikeynumber, struct VBTREE *pstree)
Definition: vbmemio.c:105
int isbuild(const char *pcfilename, const int imaxrowlength, struct keydesc *pskey, int imode)
Definition: isbuild.c:310
#define MAX_RESERVED_LENGTH
Definition: isinternal.h:290
static void inl_stquad(off_t tvalue, void *pclocation)
Definition: isinternal.h:260
struct VBTREE * pstree[32]
Definition: isinternal.h:446
char cheaderrsvd
Definition: isinternal.h:361
static char * cvbnodetmp
Definition: ischeck.c:25
struct keydesc * pskeydesc[32]
Definition: isinternal.h:445
static off_t inl_ldquad(void *pclocation)
Definition: isinternal.h:238
int idatahandle
Definition: isinternal.h:405
char * ppcrowbuffer
Definition: isinternal.h:423
int iserrno
Definition: vbmemio.c:27
int inodesize
Definition: isinternal.h:402
void vvbkeyunmalloc(const int ihandle, const int ikeynumber)
Definition: vbmemio.c:196
#define MAXSUBS
Definition: isinternal.h:119