GnuCOBOL  2.0
A free COBOL compiler
isrecover.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 struct RCV_HDL {
23  struct RCV_HDL *psnext;
24  struct RCV_HDL *psprev;
25  int ipid;
26  int ihandle;
28 };
29 
30 struct STRANS {
31  struct STRANS *psnext;
32  struct STRANS *psprev;
33  int ipid;
34  int iignoreme; /* If 1, isrecover will NOT process this one */
35 };
36 
37 static int ivbrecvmode = RECOV_C; /* Sets isrecover mode */
38 static struct STRANS *pstranshead = NULL;
39 static struct SLOGHDR *psvblogheader;
40 static struct RCV_HDL *psrecoverhandle[VB_MAX_FILES + 1];
41 static char *clclbuffer = NULL;
42 static char *cvbrtransbuffer = NULL;
43 
44 /* Local functions */
45 
46 static int
48 {
49  struct STRANS *pstrans = pstranshead;
50  int ipid;
51 
52  ipid = inl_ldint (psvblogheader->cpid);
53  while (pstrans && pstrans->ipid != ipid) {
54  pstrans = pstrans->psnext;
55  }
56  if (!pstrans) {
57  return EBADLOG;
58  }
59  if (pstrans->psnext) {
60  pstrans->psnext->psprev = pstrans->psprev;
61  }
62  if (pstrans->psprev) {
63  pstrans->psprev->psnext = pstrans->psnext;
64  } else {
65  pstranshead = pstrans->psnext;
66  }
67  vvbfree (pstrans);
68  return 0;
69 }
70 
71 static int
73 {
74  while (pstranshead) {
75  inl_stint (pstranshead->ipid, psvblogheader->cpid);
76  ircvrollback ();
77  }
78  return 0;
79 }
80 
81 static void
82 vcloseall (void)
83 {
84  struct DICTINFO *psvbptr;
85  int iloop;
86 
87  for (iloop = 0; iloop <= VB_MAX_FILES; iloop++) {
88  psvbptr = psvbfile[iloop];
89  if (psvbptr && psvbptr->iisopen == 0) {
90  isclose (iloop);
91  }
92  }
93 }
94 
95 static int
96 igetrcvhandle (const int ihandle, const int ipid)
97 {
98  struct RCV_HDL *psrcvhdl = psrecoverhandle[ihandle];
99 
100  while (psrcvhdl && psrcvhdl->ipid != ipid) {
101  psrcvhdl = psrcvhdl->psnext;
102  }
103  if (psrcvhdl && psrcvhdl->ipid == ipid) {
104  return psrcvhdl->ihandle;
105  }
106  return -1;
107 }
108 
109 static int
110 ircvchecktrans (const int ilength, const int ipid)
111 {
112  off_t tlength;
113  off_t tlength2;
114  off_t trcvsaveoffset;
115  int ifound = 0, iresult = 0;
116 
117  tlength = ilength;
118  trcvsaveoffset = tvblseek (ivblogfilehandle, (off_t)0, SEEK_CUR);
119  if (!clclbuffer) {
121  }
122  psvblogheader = (struct SLOGHDR *)(clclbuffer - INTSIZE);
123  while (!ifound) {
124  tlength2 = tvbread (ivblogfilehandle, clclbuffer, (size_t) tlength);
125  if (tlength2 != tlength && tlength2 != tlength - INTSIZE) {
126  break;
127  }
128  if (inl_ldint (psvblogheader->cpid) == ipid) {
129  if (!memcmp (psvblogheader->coperation, VBL_COMMIT, 2)) {
130  ifound = 1;
131  } else if (!memcmp (psvblogheader->coperation, VBL_BEGIN, 2)) {
132  ifound = 1;
133  if (ivbrecvmode & RECOV_VB) {
134  iresult = 1;
135  }
136  } else if (!memcmp (psvblogheader->coperation, VBL_ROLLBACK, 2)) {
137  ifound = 1;
138  iresult = 1;
139  }
140  }
141  if (tlength2 == tlength - INTSIZE) {
142  break;
143  }
144  tlength = inl_ldint (clclbuffer + tlength - INTSIZE);
145  }
146 
147  psvblogheader = (struct SLOGHDR *)(cvbrtransbuffer - INTSIZE);
148  tvblseek (ivblogfilehandle, trcvsaveoffset, SEEK_SET);
149  return iresult;
150 }
151 
152 static int
153 iignore (const int ipid)
154 {
155  struct STRANS *pstrans = pstranshead;
156 
157  while (pstrans && pstrans->ipid != ipid) {
158  pstrans = pstrans->psnext;
159  }
160  if (pstrans && pstrans->ipid == ipid) {
161  return pstrans->iignoreme;
162  }
163  return 0;
164 }
165 
166 static int
167 ircvbuild (char *pcbuffer)
168 {
169  char *pcfilename;
170  int ihandle, iloop, imode, imaxrowlen, ipid;
171  struct keydesc skeydesc;
172 
173  imode = inl_ldint (pcbuffer);
174  ipid = inl_ldint (psvblogheader->cpid);
175  if (iignore (ipid)) {
176  return 0;
177  }
178  isreclen = inl_ldint (pcbuffer + INTSIZE);
179  imaxrowlen = inl_ldint (pcbuffer + (INTSIZE * 2));
180  skeydesc.k_flags = inl_ldint (pcbuffer + (INTSIZE * 3));
181  skeydesc.k_nparts = inl_ldint (pcbuffer + (INTSIZE * 4));
182  pcbuffer += (INTSIZE * 6);
183  for (iloop = 0; iloop < skeydesc.k_nparts; iloop++) {
184  skeydesc.k_part[iloop].kp_start = inl_ldint (pcbuffer + (iloop * 3 * INTSIZE));
185  skeydesc.k_part[iloop].kp_leng =
186  inl_ldint (pcbuffer + INTSIZE + (iloop * 3 * INTSIZE));
187  skeydesc.k_part[iloop].kp_type =
188  inl_ldint (pcbuffer + (INTSIZE * 2) + +(iloop * 3 * INTSIZE));
189  }
190  pcfilename = pcbuffer + (skeydesc.k_nparts * 3 * INTSIZE);
191  ihandle = isbuild (pcfilename, imaxrowlen, &skeydesc, imode);
192  imode = iserrno; /* Save any error result */
193  if (ihandle != -1) {
194  isclose (ihandle);
195  }
196  return imode;
197 }
198 
199 static int
200 ircvbegin (char *pcbuffer, const int ilength)
201 {
202  struct STRANS *pstrans = pstranshead;
203  int ipid;
204 
205  ipid = inl_ldint (psvblogheader->cpid);
206  while (pstrans && pstrans->ipid != ipid) {
207  pstrans = pstrans->psnext;
208  }
209  if (pstrans) {
210  ircvrollback ();
211  }
212  pstrans = pvvbmalloc (sizeof (struct STRANS));
213  if (!pstrans) {
214  return ENOMEM;
215  }
216  pstrans->psprev = NULL;
217  pstrans->psnext = pstranshead;
218  if (pstranshead) {
219  pstranshead->psprev = pstrans;
220  }
221  pstranshead = pstrans;
222  pstrans->ipid = ipid;
223  pstrans->iignoreme = ircvchecktrans (ilength, ipid);
224  return 0;
225 }
226 
227 static int
228 ircvcreateindex (char *pcbuffer)
229 {
230  int ihandle, iloop, ipid, isaveerror = 0;
231  struct keydesc skeydesc;
232 
233  ihandle = inl_ldint (pcbuffer);
234  ipid = inl_ldint (psvblogheader->cpid);
235  if (iignore (ipid)) {
236  return 0;
237  }
238  ihandle = igetrcvhandle (ihandle, ipid);
239  if (ihandle == -1) {
240  return ENOTOPEN;
241  }
242  skeydesc.k_flags = inl_ldint (pcbuffer + INTSIZE);
243  skeydesc.k_nparts = inl_ldint (pcbuffer + (INTSIZE * 2));
244  pcbuffer += (INTSIZE * 4);
245  for (iloop = 0; iloop < skeydesc.k_nparts; iloop++) {
246  skeydesc.k_part[iloop].kp_start = inl_ldint (pcbuffer + (iloop * 3 * INTSIZE));
247  skeydesc.k_part[iloop].kp_leng =
248  inl_ldint (pcbuffer + INTSIZE + (iloop * 3 * INTSIZE));
249  skeydesc.k_part[iloop].kp_type =
250  inl_ldint (pcbuffer + (INTSIZE * 2) + +(iloop * 3 * INTSIZE));
251  }
252  /* Promote the file open lock to EXCLUSIVE */
253  iserrno = ivbfileopenlock (ihandle, 2);
254  if (iserrno) {
255  return iserrno;
256  }
257  psvbfile[ihandle]->iopenmode |= ISEXCLLOCK;
258  if (isaddindex (ihandle, &skeydesc)) {
259  isaveerror = iserrno;
260  }
261  /* Demote the file open lock back to SHARED */
262  psvbfile[ihandle]->iopenmode &= ~ISEXCLLOCK;
263  ivbfileopenlock (ihandle, 0);
264  ivbfileopenlock (ihandle, 1);
265  return isaveerror;
266 }
267 
268 static int
269 ircvcluster (char *pcbuffer)
270 {
271  int ipid;
272 
273  ipid = inl_ldint (psvblogheader->cpid);
274  if (iignore (ipid)) {
275  return 0;
276  }
277 /* RXW
278  fprintf (stderr, "ircvcluster not yet implemented!\n");
279 */
280  return 0;
281 }
282 
283 static int
284 ircvcommit (char *pcbuffer)
285 {
286  struct RCV_HDL *psrcv;
287  struct STRANS *pstrans = pstranshead;
288  int iloop, ipid;
289 
290  ipid = inl_ldint (psvblogheader->cpid);
291  while (pstrans && pstrans->ipid != ipid) {
292  pstrans = pstrans->psnext;
293  }
294  if (!pstrans) {
295  return EBADLOG;
296  }
297  if (pstrans->psnext) {
298  pstrans->psnext->psprev = pstrans->psprev;
299  }
300  if (pstrans->psprev) {
301  pstrans->psprev->psnext = pstrans->psnext;
302  } else {
303  pstranshead = pstrans->psnext;
304  }
305  vvbfree (pstrans);
306  for (iloop = 0; iloop <= VB_MAX_FILES; iloop++) {
307  if (!psrecoverhandle[iloop]) {
308  continue;
309  }
310  for (psrcv = psrecoverhandle[iloop]; psrcv; psrcv = psrcv->psnext) {
311  if (psrcv->itranslock) {
312  isrelease (psrcv->ihandle);
313  }
314  }
315  }
316  return 0;
317 }
318 
319 static int
320 ircvdelete (char *pcbuffer)
321 {
322  char *pcrow;
323  off_t trownumber;
324  int ihandle, ipid;
325 
326  ihandle = inl_ldint (pcbuffer);
327  ipid = inl_ldint (psvblogheader->cpid);
328  if (iignore (ipid)) {
329  return 0;
330  }
331  ihandle = igetrcvhandle (ihandle, ipid);
332  if (ihandle == -1) {
333  return ENOTOPEN;
334  }
335  trownumber = inl_ldquad (pcbuffer + INTSIZE);
336  pcrow = pcbuffer + INTSIZE + QUADSIZE + INTSIZE;
337  isdelrec (ihandle, trownumber);
338  return iserrno;
339 }
340 
341 static int
342 ircvdeleteindex (char *pcbuffer)
343 {
344  int ihandle, iloop, ipid, isaveerror = 0;
345  struct keydesc skeydesc;
346 
347  ihandle = inl_ldint (pcbuffer);
348  ipid = inl_ldint (psvblogheader->cpid);
349  if (iignore (ipid)) {
350  return 0;
351  }
352  ihandle = igetrcvhandle (ihandle, ipid);
353  if (ihandle == -1) {
354  return ENOTOPEN;
355  }
356  skeydesc.k_flags = inl_ldint (pcbuffer + INTSIZE);
357  skeydesc.k_nparts = inl_ldint (pcbuffer + (INTSIZE * 2));
358  pcbuffer += (INTSIZE * 4);
359  for (iloop = 0; iloop < skeydesc.k_nparts; iloop++) {
360  skeydesc.k_part[iloop].kp_start = inl_ldint (pcbuffer + (iloop * 3 * INTSIZE));
361  skeydesc.k_part[iloop].kp_leng =
362  inl_ldint (pcbuffer + INTSIZE + (iloop * 3 * INTSIZE));
363  skeydesc.k_part[iloop].kp_type =
364  inl_ldint (pcbuffer + (INTSIZE * 2) + +(iloop * 3 * INTSIZE));
365  }
366  /* Promote the file open lock to EXCLUSIVE */
367  iserrno = ivbfileopenlock (ihandle, 2);
368  if (iserrno) {
369  return iserrno;
370  }
371  psvbfile[ihandle]->iopenmode |= ISEXCLLOCK;
372  if (isdelindex (ihandle, &skeydesc)) {
373  isaveerror = iserrno;
374  }
375  /* Demote the file open lock back to SHARED */
376  psvbfile[ihandle]->iopenmode &= ~ISEXCLLOCK;
377  ivbfileopenlock (ihandle, 0);
378  ivbfileopenlock (ihandle, 1);
379  return isaveerror;
380 }
381 
382 static int
383 ircvfileerase (char *pcbuffer)
384 {
385  int ipid;
386 
387  ipid = inl_ldint (psvblogheader->cpid);
388  if (iignore (ipid)) {
389  return 0;
390  }
391  iserase (pcbuffer);
392  return iserrno;
393 }
394 
395 static int
396 ircvfileclose (char *pcbuffer)
397 {
398  struct RCV_HDL *psrcv;
399  int ihandle, ivarlenflag, ipid;
400 
401  ihandle = inl_ldint (pcbuffer);
402  ivarlenflag = inl_ldint (pcbuffer + INTSIZE);
403  ipid = inl_ldint (psvblogheader->cpid);
404  if (iignore (ipid)) {
405  return 0;
406  }
407  psrcv = psrecoverhandle[ihandle];
408  while (psrcv && psrcv->ipid != ipid) {
409  psrcv = psrcv->psnext;
410  }
411  if (!psrcv || psrcv->ipid != ipid) {
412  return ENOTOPEN; /* It wasn't open! */
413  }
414  iserrno = 0;
415  isclose (psrcv->ihandle);
416  if (psrcv->psprev) {
417  psrcv->psprev->psnext = psrcv->psnext;
418  } else {
419  psrecoverhandle[ihandle] = psrcv->psnext;
420  }
421  if (psrcv->psnext) {
422  psrcv->psnext->psprev = psrcv->psprev;
423  }
424 
425  return iserrno;
426 }
427 
428 static int
429 ircvfileopen (char *pcbuffer)
430 {
431  struct RCV_HDL *psrcv;
432  int ihandle, ivarlenflag, ipid;
433 
434  ihandle = inl_ldint (pcbuffer);
435  ivarlenflag = inl_ldint (pcbuffer + INTSIZE);
436  ipid = inl_ldint (psvblogheader->cpid);
437  if (iignore (ipid)) {
438  return 0;
439  }
440  if (igetrcvhandle (ihandle, ipid) != -1) {
441  return ENOTOPEN; /* It was already open! */
442  }
443  psrcv = pvvbmalloc (sizeof (struct RCV_HDL));
444  if (psrcv == NULL) {
445  return ENOMEM; /* Oops */
446  }
447  psrcv->ihandle = isopen (pcbuffer + INTSIZE + INTSIZE,
448  ISINOUT | ISMANULOCK | (ivarlenflag ? ISVARLEN : ISFIXLEN));
449  psrcv->ipid = ipid;
450  if (psrcv->ihandle < 0) {
451  vvbfree (psrcv);
452  return iserrno;
453  }
454  psrcv->psprev = NULL;
455  psrcv->psnext = psrecoverhandle[ihandle];
456  if (psrecoverhandle[ihandle]) {
457  psrecoverhandle[ihandle]->psprev = psrcv;
458  }
459  psrecoverhandle[ihandle] = psrcv;
460  return 0;
461 }
462 
463 static int
464 ircvinsert (char *pcbuffer)
465 {
466  char *pcrow;
467  off_t trownumber;
468  int ihandle, ipid;
469 
470  ihandle = inl_ldint (pcbuffer);
471  ipid = inl_ldint (psvblogheader->cpid);
472  if (iignore (ipid)) {
473  return 0;
474  }
475  ihandle = igetrcvhandle (ihandle, ipid);
476  if (ihandle == -1) {
477  return ENOTOPEN;
478  }
479  trownumber = inl_ldquad (pcbuffer + INTSIZE);
480  isreclen = inl_ldint (pcbuffer + INTSIZE + QUADSIZE);
481  pcrow = pcbuffer + INTSIZE + QUADSIZE + INTSIZE;
482  if (ivbenter (ihandle, 1, 0)) {
483  return iserrno;
484  }
485  psvbfile[ihandle]->iisdictlocked |= 0x02;
486  if (ivbforcedataallocate (ihandle, trownumber)) {
487  return EDUPL;
488  }
489  if (ivbwriterow (ihandle, pcrow, trownumber)) {
490  return iserrno;
491  }
492  ivbexit (ihandle);
493  return iserrno;
494 }
495 
496 /* NEEDS TESTING! */
497 static int
498 ircvfilerename (char *pcbuffer)
499 {
500  char *pcoldname, *pcnewname;
501  int ioldnamelength, ipid;
502 
503  ipid = inl_ldint (psvblogheader->cpid);
504  if (iignore (ipid)) {
505  return 0;
506  }
507  ioldnamelength = inl_ldint (pcbuffer);
508  pcoldname = pcbuffer + INTSIZE + INTSIZE;
509  pcnewname = pcbuffer + INTSIZE + INTSIZE + ioldnamelength;
510  isrename (pcoldname, pcnewname);
511  return iserrno;
512 }
513 
514 static int
515 ircvsetunique (char *pcbuffer)
516 {
517  off_t tuniqueid;
518  int ihandle, ipid;
519 
520  ihandle = inl_ldint (pcbuffer);
521  ipid = inl_ldint (psvblogheader->cpid);
522  if (iignore (ipid)) {
523  return 0;
524  }
525  ihandle = igetrcvhandle (ihandle, ipid);
526  if (ihandle == -1) {
527  return ENOTOPEN;
528  }
529  tuniqueid = inl_ldquad (pcbuffer + INTSIZE);
530  issetunique (ihandle, tuniqueid);
531  return iserrno;
532 }
533 
534 static int
535 ircvuniqueid (char *pcbuffer)
536 {
537  off_t tuniqueid;
538  int ihandle, ipid;
539 
540  ihandle = inl_ldint (pcbuffer);
541  ipid = inl_ldint (psvblogheader->cpid);
542  if (iignore (ipid)) {
543  return 0;
544  }
545  ihandle = igetrcvhandle (ihandle, ipid);
546  if (ihandle == -1) {
547  return ENOTOPEN;
548  }
549  tuniqueid = inl_ldquad (pcbuffer + INTSIZE);
550  if (tuniqueid != inl_ldquad (psvbfile[ihandle]->sdictnode.cuniqueid)) {
551  return EBADFILE;
552  }
553  isuniqueid (ihandle, &tuniqueid);
554  return 0;
555 }
556 
557 static int
558 ircvupdate (char *pcbuffer)
559 {
560  char *pcrow;
561  off_t trownumber;
562  int ihandle, ipid;
563 
564  ihandle = inl_ldint (pcbuffer);
565  ipid = inl_ldint (psvblogheader->cpid);
566  if (iignore (ipid)) {
567  return 0;
568  }
569  ihandle = igetrcvhandle (ihandle, ipid);
570  if (ihandle == -1) {
571  return ENOTOPEN;
572  }
573  trownumber = inl_ldquad (pcbuffer + INTSIZE);
574  isreclen = inl_ldint (pcbuffer + INTSIZE + QUADSIZE);
575  pcrow = pcbuffer + INTSIZE + QUADSIZE + INTSIZE + INTSIZE + isreclen;
576  isreclen = inl_ldint (pcbuffer + INTSIZE + QUADSIZE + INTSIZE);
577  isrewrec (ihandle, trownumber, pcrow);
578  return iserrno;
579 }
580 
581 /* Global functions */
582 
583 int
585 {
586  char *pcbuffer;
587  off_t tlength, tlength2, toffset;
588  int iloop, isaveerror;
589 
590  /* Initialize by stating that *ALL* tables must be closed! */
591  for (iloop = 0; iloop <= VB_MAX_FILES; iloop++) {
592  if (psvbfile[iloop]) {
593  iserrno = ETOOMANY;
594  return -1;
595  }
596  }
598  for (iloop = 0; iloop <= VB_MAX_FILES; iloop++) {
599  psrecoverhandle[iloop] = NULL;
600  }
601  /* Begin by reading the header of the first transaction */
602  iserrno = EBADFILE;
603  if (tvblseek (ivblogfilehandle, (off_t)0, SEEK_SET) != 0) {
604  return -1;
605  }
607  if (!cvbrtransbuffer) {
608  iserrno = EBADMEM;
609  return -1;
610  }
611  psvblogheader = (struct SLOGHDR *)(cvbrtransbuffer - INTSIZE);
612  if (tvbread (ivblogfilehandle, cvbrtransbuffer, INTSIZE) != INTSIZE) {
613  return 0; /* Nothing to do if the file is empty */
614  }
615  toffset = 0;
616  tlength = inl_ldint (cvbrtransbuffer);
617  /* Now, recurse forwards */
618  while (1) {
619  tlength2 = tvbread (ivblogfilehandle, cvbrtransbuffer, tlength);
620  iserrno = EBADFILE;
621  if (tlength2 != tlength && tlength2 != tlength - INTSIZE) {
622  break;
623  }
624  pcbuffer = cvbrtransbuffer - INTSIZE + sizeof (struct SLOGHDR);
625  if (!memcmp (psvblogheader->coperation, VBL_BUILD, 2)) {
626  iserrno = ircvbuild (pcbuffer);
627  } else if (!memcmp (psvblogheader->coperation, VBL_BEGIN, 2)) {
628  iserrno = ircvbegin (pcbuffer,
629  inl_ldint (cvbrtransbuffer + tlength - INTSIZE));
630  } else if (!memcmp (psvblogheader->coperation, VBL_CREINDEX, 2)) {
631  iserrno = ircvcreateindex (pcbuffer);
632  } else if (!memcmp (psvblogheader->coperation, VBL_CLUSTER, 2)) {
633  iserrno = ircvcluster (pcbuffer);
634  } else if (!memcmp (psvblogheader->coperation, VBL_COMMIT, 2)) {
635  iserrno = ircvcommit (pcbuffer);
636  } else if (!memcmp (psvblogheader->coperation, VBL_DELETE, 2)) {
637  iserrno = ircvdelete (pcbuffer);
638  } else if (!memcmp (psvblogheader->coperation, VBL_DELINDEX, 2)) {
639  iserrno = ircvdeleteindex (pcbuffer);
640  } else if (!memcmp (psvblogheader->coperation, VBL_FILEERASE, 2)) {
641  iserrno = ircvfileerase (pcbuffer);
642  } else if (!memcmp (psvblogheader->coperation, VBL_FILECLOSE, 2)) {
643  iserrno = ircvfileclose (pcbuffer);
644  } else if (!memcmp (psvblogheader->coperation, VBL_FILEOPEN, 2)) {
645  iserrno = ircvfileopen (pcbuffer);
646  } else if (!memcmp (psvblogheader->coperation, VBL_INSERT, 2)) {
647  iserrno = ircvinsert (pcbuffer);
648  } else if (!memcmp (psvblogheader->coperation, VBL_RENAME, 2)) {
649  iserrno = ircvfilerename (pcbuffer);
650  } else if (!memcmp (psvblogheader->coperation, VBL_ROLLBACK, 2)) {
651  iserrno = ircvrollback ();
652  } else if (!memcmp (psvblogheader->coperation, VBL_SETUNIQUE, 2)) {
653  iserrno = ircvsetunique (pcbuffer);
654  } else if (!memcmp (psvblogheader->coperation, VBL_UNIQUEID, 2)) {
655  iserrno = ircvuniqueid (pcbuffer);
656  } else if (!memcmp (psvblogheader->coperation, VBL_UPDATE, 2)) {
657  iserrno = ircvupdate (pcbuffer);
658  }
659  if (iserrno) {
660  break;
661  }
662  toffset += tlength2;
663  if (tlength2 == tlength - INTSIZE) {
664  break;
665  }
666  tlength = inl_ldint (cvbrtransbuffer + tlength - INTSIZE);
667  }
668  isaveerror = iserrno;
669  /* We now rollback any transactions that were never 'closed' */
670  iserrno = irollbackall ();
671  if (!isaveerror) {
672  isaveerror = iserrno;
673  }
674  vcloseall ();
675  iserrno = isaveerror;
677  if (iserrno) {
678  return -1;
679  }
680  return 0;
681 }
int isdelindex(const int ihandle, struct keydesc *pskeydesc)
Definition: isbuild.c:644
int ipid
Definition: isrecover.c:33
int ivbforcedataallocate(const int ihandle, const off_t trownumber)
Definition: vbindexio.c:355
static struct RCV_HDL * psrecoverhandle[128+1]
Definition: isrecover.c:40
static int ircvbegin(char *pcbuffer, const int ilength)
Definition: isrecover.c:200
#define VBL_FILEOPEN
Definition: isinternal.h:477
static int inl_ldint(void *pclocation)
Definition: isinternal.h:170
int ihandle
Definition: isrecover.c:26
#define VBL_UPDATE
Definition: isinternal.h:483
#define VBL_COMMIT
Definition: isinternal.h:472
#define VBL_BUILD
Definition: isinternal.h:468
static int ircvfilerename(char *pcbuffer)
Definition: isrecover.c:498
int isrewrec(const int ihandle, const long long trownumber, char *pcrow)
Definition: isrewrite.c:298
int isrename(char *pcoldname, char *pcnewname)
Definition: ishelper.c:168
int isuniqueid(const int ihandle, long long *ptuniqueid)
Definition: ishelper.c:226
struct RCV_HDL * psprev
Definition: isrecover.c:24
static int ircvchecktrans(const int ilength, const int ipid)
Definition: isrecover.c:110
#define RECOV_C
Definition: isinternal.h:301
int isdelrec(const int ihandle, long long trownumber)
Definition: isdelete.c:189
static int ircvfileerase(char *pcbuffer)
Definition: isrecover.c:383
int isreclen
Definition: vbmemio.c:29
static void vcloseall(void)
Definition: isrecover.c:82
static int ircvdeleteindex(char *pcbuffer)
Definition: isrecover.c:342
static struct SLOGHDR * psvblogheader
Definition: isrecover.c:39
#define VBRECOVER
Definition: isinternal.h:311
int iignoreme
Definition: isrecover.c:34
int iserase(char *pcfilename)
Definition: ishelper.c:36
static int ircvdelete(char *pcbuffer)
Definition: isrecover.c:320
int ipid
Definition: isrecover.c:25
#define VBL_DELETE
Definition: isinternal.h:473
#define RECOV_VB
Definition: isinternal.h:302
int ivbenter(const int ihandle, const unsigned int imodifying, const unsigned int ispecial)
Definition: vblocking.c:178
#define VBL_UNIQUEID
Definition: isinternal.h:482
void vvbfree(void *mptr)
Definition: vbmemio.c:59
static int ircvcreateindex(char *pcbuffer)
Definition: isrecover.c:228
static int ircvcommit(char *pcbuffer)
Definition: isrecover.c:284
static int ivbrecvmode
Definition: isrecover.c:37
int itranslock
Definition: isrecover.c:27
int iisopen
Definition: isinternal.h:407
#define VBL_DELINDEX
Definition: isinternal.h:474
static int ircvupdate(char *pcbuffer)
Definition: isrecover.c:558
static int ircvuniqueid(char *pcbuffer)
Definition: isrecover.c:535
static void inl_stint(int ivalue, void *pclocation)
Definition: isinternal.h:190
struct STRANS * psprev
Definition: isrecover.c:32
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
static int ircvcluster(char *pcbuffer)
Definition: isrecover.c:269
#define VBL_CREINDEX
Definition: isinternal.h:470
#define VBL_FILEERASE
Definition: isinternal.h:475
static struct STRANS * pstranshead
Definition: isrecover.c:38
int ivbwriterow(const int ihandle, char *pcrow, const off_t trownumber)
Definition: iswrite.c:85
#define VB_MAX_FILES
Definition: isinternal.h:120
void * pvvbmalloc(const size_t size)
Definition: vbmemio.c:45
#define VBL_ROLLBACK
Definition: isinternal.h:480
static int ircvfileclose(char *pcbuffer)
Definition: isrecover.c:396
int ivbfileopenlock(const int ihandle, const int imode)
Definition: vblocking.c:380
struct DICTINFO * psvbfile[128+1]
Definition: vblowlevel.c:23
#define QUADSIZE
Definition: isinternal.h:108
char coperation[2]
Definition: isinternal.h:487
int issetunique(const int ihandle, const long long tuniqueid)
Definition: ishelper.c:195
int isaddindex(const int ihandle, struct keydesc *pskeydesc)
Definition: isbuild.c:577
char cpid[2]
Definition: isinternal.h:488
static int ircvfileopen(char *pcbuffer)
Definition: isrecover.c:429
int ivbexit(const int ihandle)
Definition: vblocking.c:290
static int ircvinsert(char *pcbuffer)
Definition: isrecover.c:464
static int igetrcvhandle(const int ihandle, const int ipid)
Definition: isrecover.c:96
static int ircvsetunique(char *pcbuffer)
Definition: isrecover.c:515
#define VBL_INSERT
Definition: isinternal.h:478
static int ircvrollback(void)
Definition: isrecover.c:47
int iopenmode
Definition: isinternal.h:412
static int iignore(const int ipid)
Definition: isrecover.c:153
int isclose(const int ihandle)
Definition: isopen.c:182
#define VBL_CLUSTER
Definition: isinternal.h:471
static char * cvbrtransbuffer
Definition: isrecover.c:42
static char * clclbuffer
Definition: isrecover.c:41
struct STRANS * psnext
Definition: isrecover.c:31
int isbuild(const char *pcfilename, const int imaxrowlength, struct keydesc *pskey, int imode)
Definition: isbuild.c:310
ssize_t tvbread(const int ihandle, void *pvbuffer, const size_t tcount)
Definition: vblowlevel.c:117
#define VBL_FILECLOSE
Definition: isinternal.h:476
#define VBL_BEGIN
Definition: isinternal.h:469
#define MAX_BUFFER_LENGTH
Definition: isinternal.h:291
int ivblogfilehandle
Definition: istrans.c:24
static int irollbackall(void)
Definition: isrecover.c:72
int isrecover()
Definition: isrecover.c:584
#define VBL_RENAME
Definition: isinternal.h:479
#define VBL_SETUNIQUE
Definition: isinternal.h:481
static off_t inl_ldquad(void *pclocation)
Definition: isinternal.h:238
int isrelease(const int ihandle)
Definition: ishelper.c:126
static int ircvbuild(char *pcbuffer)
Definition: isrecover.c:167
int iserrno
Definition: vbmemio.c:27
int ivbintrans
Definition: istrans.c:23
struct RCV_HDL * psnext
Definition: isrecover.c:23
off_t tvblseek(const int ihandle, off_t toffset, const int iwhence)
Definition: vblowlevel.c:107