librcv.c
上传用户:dgyhgb
上传日期:2007-01-07
资源大小:676k
文件大小:18k
源码类别:

SQL Server

开发平台:

Unix_Linux

  1. /*  librcv.c  - Crash Recovery Utility Library 
  2.  *              Kernel of GNU SQL-server. Recovery utilities     
  3.  *
  4.  *  This file is a part of GNU SQL Server
  5.  *
  6.  *  Copyright (c) 1996, 1997, Free Software Foundation, Inc
  7.  *  Developed at the Institute of System Programming
  8.  *  This file is written by  Vera Ponomarenko
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 2 of the License, or
  13.  *  (at your option) any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23.  *
  24.  *  Contacts:   gss@ispras.ru
  25.  *
  26.  */
  27. /* $Id: librcv.c,v 1.247 1997/04/15 11:46:20 vera Exp $ */
  28. #include "setup_os.h"
  29. #if STDC_HEADERS
  30. #include <sys/types.h>
  31. #include <sys/stat.h>
  32. #endif
  33. #if HAVE_UNISTD_H
  34. #include <unistd.h>
  35. #endif
  36. #include <assert.h>
  37. #if HAVE_DIRENT_H
  38. # include <dirent.h>
  39. # define NAMLEN(dirent) strlen((dirent)->d_name)
  40. #else
  41. # define dirent direct
  42. # define NAMLEN(dirent) (dirent)->d_namlen
  43. # if HAVE_SYS_NDIR_H
  44. #  include <sys/ndir.h>
  45. # endif
  46. # if HAVE_SYS_DIR_H
  47. #  include <sys/dir.h>
  48. # endif
  49. # if HAVE_NDIR_H
  50. #  include <ndir.h>
  51. # endif
  52. #endif
  53. #if HAVE_FCNTL_H
  54. #include <fcntl.h>
  55. #endif
  56. #if HAVE_SYS_IPC_H
  57. #include <sys/ipc.h>
  58. #endif
  59. #if HAVE_SYS_MSG_H
  60. #include <sys/msg.h>
  61. #endif
  62. #if HAVE_SYS_SHM_H
  63. #include <sys/shm.h>
  64. #endif
  65. #if HAVE_SYS_WAIT_H
  66. # include <sys/wait.h>
  67. #endif
  68. #ifndef WEXITSTATUS
  69. # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
  70. #endif
  71. #ifndef WIFEXITED
  72. # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
  73. #endif
  74. #include "destrn.h"
  75. #include "strml.h"
  76. #include "puprcv.h"
  77. #include "fdclrcv.h"
  78. #include "f1f2decl.h"
  79. /**************************************************************/
  80. extern i4_t msqidl, msqidm, msqidb;
  81. extern i4_t fdcurlj;
  82. char ljpage[RPAGE];
  83. u2_t pagenum;
  84. extern i4_t N_AT_SEG;
  85. extern COST cost;
  86. extern struct ADREC bllj;
  87. extern struct d_r_t *firstrel;
  88. extern struct ADBL admj;
  89. extern char *pbufmj;
  90. extern char *pbuflj;
  91. extern struct ldesind **TAB_IFAM;
  92. extern i4_t TIFAM_SZ;
  93. extern i4_t idtr;
  94. extern struct ADBL adlj;
  95. extern struct ADREC blmj;
  96. extern char *bufmj;
  97. extern unsigned ljmsize;
  98. extern u2_t trnum;
  99. extern struct ADREC blmj;
  100. extern i4_t minidnt;
  101. #define adfsize sizeof(struct ADF)
  102. static void
  103. rllbck_tr (i4_t fd, i4_t cidtr, struct ADBL cadlj)
  104. {
  105.   register char *a, type;
  106.   i4_t newidtr;
  107.   u2_t blsz;
  108.   char *pnt, mas[RPAGE];
  109.   for (; (blsz = LJ_prev (fd, &cadlj, &pnt, mas)) > 0;)
  110.     {
  111.       a = pnt;
  112.       type = *a++;
  113.       if (type == EOTLJ || type == GRLBLJ)
  114. continue;
  115.       newidtr = t4bunpack (a);
  116.       a += size4b;
  117.       if (newidtr == cidtr)
  118. {
  119.   cadlj.npage = t2bunpack (a);
  120.   a += size2b;
  121.   cadlj.cm = t2bunpack (a);
  122.   a += size2b;
  123.   backactn (blsz, a, type);
  124.   break;
  125. }
  126.     }
  127.   idtr = cidtr;
  128.   r_tr (cadlj);
  129. }
  130. static void
  131. rollb_nftr(i4_t fd, struct ADBL cadlj, char *a, u2_t n)
  132. {
  133.   u2_t i, NFTRANS;
  134.   i4_t cidtr;
  135.   NFTRANS = n / size4b;
  136.   for (i = 0; i < NFTRANS; i++, a += size4b)
  137.     {
  138.       cidtr = t4bunpack (a);
  139.       rllbck_tr (fd, cidtr, cadlj);
  140.     }
  141. }
  142. static void
  143. frwrd_mtn (struct ADBL cadlj)
  144. {
  145.   char *a, type;
  146.   u2_t blsz;
  147.   char *pnt, mas[RPAGE];
  148.   
  149.   for (; (blsz = LJ_next (fdcurlj, &cadlj, &pnt, mas)) > 0;)
  150.     { /*The motion forward */
  151.       a = pnt;
  152.       type = *a++;
  153.       if (type == CPRLJ)
  154.         continue;
  155.       if (type == EOTLJ)
  156. {
  157.   getmint (a, blsz - size1b);
  158.   continue;
  159. }
  160.       if (type == GRLBLJ)
  161. {
  162.   adlj = cadlj;
  163.   blsz = LJ_prev (fdcurlj, &adlj, &pnt, mas);
  164.   a = pnt;
  165.   type = *a++;
  166.   if (type != EOTLJ)
  167.     fprintf (stderr, "Serious error! LIBRCV.frwrd_mtn: type |= EOTLJ (=%d) before GRLBLJn", type);
  168.   rollb_nftr (fdcurlj, adlj, a, blsz - size1b);
  169.   continue;
  170. }
  171.       idtr = t4bunpack (a);
  172.       forward_action (a + size4b, type, blsz - ljmsize);
  173.     }
  174. }
  175. struct ADBL 
  176. frwdmtn (void)
  177. {
  178.   struct ADBL cadlj;
  179.   read_page (fdcurlj, 1, ljpage);
  180.   cadlj.npage = 1;
  181.   cadlj.cm = RTPAGE;
  182.   frwrd_mtn (cadlj);
  183.   return (adlj);    /* use adlj because cadlj doesn't change */
  184.                     /* in frwrd_mnt but adlj   */  
  185. }
  186. static struct d_r_t *
  187. cr_rd(struct id_rel *idr)
  188. {
  189.   char *a, *asp;
  190.   struct A pg;
  191.   struct d_r_t *desrel;
  192.   u2_t *ai;
  193.   unsigned char t;
  194.   asp = getpg (&pg, idr->urn.segnum, idr->pagenum, 's');
  195.   ai = (u2_t *) (asp + phsize) + idr->index;
  196.   a = asp + *ai;
  197.   t = *a & MSKCORT;
  198.   if (t == IND)
  199.     { /* indirect reference */
  200.       u2_t pn2, ind2;
  201.       char *asp = NULL;
  202.       ind2 = t2bunpack (a + 1);
  203.       pn2 = t2bunpack (a + 1 + size2b);
  204.       putpg (&pg, 'n');
  205.       while ((asp = getpg (&pg, pg.p_sn, pn2, 's')) == NULL);
  206.       ai = (u2_t *) (asp + phsize) + ind2;
  207.       a = asp + *ai;
  208.       assert ((*a & CREM) != 0 && *ai != 0);
  209.     }
  210.   desrel = crtfrd (idr, a);
  211.   putpg (&pg, 'n');
  212.   return (desrel);
  213. }
  214. u2_t
  215. LJ_next (i4_t fd, struct ADBL *adj, char **pnt, char *mas)
  216. {
  217.   u2_t N, offbeg, n, blsz, off, n1;
  218.   char *a, *beg_of_record;
  219.   
  220.   N = adj->npage;
  221.   offbeg = adj->cm;
  222.   if (pagenum != N)
  223.     read_page (fd, N, ljpage);
  224.   a = ljpage + size4b;
  225.   off = t2bunpack (a);
  226.   a += size2b;
  227.   if (off == offbeg && *a == 0)
  228.     return (0);
  229.   a = ljpage + offbeg;
  230.   if (offbeg + RTBLK > RPAGE)
  231.     { /* the top-block places in two pages*/
  232.       char buff[size2b];
  233.       n = RPAGE - offbeg;
  234.       bcopy (a, buff, n);
  235.       N++;
  236.       read_page (fd, N, ljpage);
  237.       n1 = RTBLK - n; 
  238.       bcopy (ljpage + RTPAGE, buff + n, n1);
  239.       blsz = t2bunpack (buff);
  240.       n = RTPAGE + n1;
  241.       beg_of_record = ljpage + n;
  242.     }
  243.   else
  244.     { /* the top-block places in (N)-page */
  245.       blsz = t2bunpack (a);
  246.       beg_of_record = a + RTBLK;
  247.       n = offbeg + RTBLK;
  248.     }
  249.   if (n + blsz > RPAGE)
  250.     { /* block-record places in two page*/
  251.       n = RPAGE - n;
  252.       bcopy(beg_of_record, mas, n);
  253.       N++;
  254.       read_page (fd, N, ljpage);
  255.       n1 = blsz - n;
  256.       bcopy (ljpage + RTPAGE, mas + n, n1);
  257.       *pnt = mas;
  258.       n = RTPAGE + n1;
  259.     }
  260.   else
  261.     {
  262.       *pnt = beg_of_record;
  263.       n += blsz;
  264.     }
  265.   if (n + RTBLK > RPAGE)
  266.     { /* the endtop-block places in two pages*/
  267.       N++;
  268.       offbeg = RTPAGE + RTBLK - (RTBLK - n);
  269.     }
  270.   else
  271.     offbeg = n + RTBLK;
  272.   adj->npage = N;
  273.   adj->cm = offbeg;
  274.   return (blsz);
  275. }
  276. static void
  277. rollback_action (char *a)
  278. {
  279.   char type;
  280.   struct ADBL cadlj;
  281.   struct ADREC bllj;
  282.   
  283.   cadlj.npage = t2bunpack (a);
  284.   a += size2b;
  285.   cadlj.cm = t2bunpack (a);
  286.   a += size2b;
  287.   rcv_LJ_GETREC (&bllj, &cadlj);
  288.   a = bllj.block;
  289.   type = *a++;
  290.   backactn (bllj.razm, a + size4b + 2 * size2b, type);
  291. }
  292. void
  293. forward_action (char *a, char type, u2_t n)
  294. {
  295.   u2_t pn, ind, pnr, indr;
  296.   u2_t sn;
  297.   i4_t rn, ordrn;
  298.   struct d_r_t *desrel;
  299.   struct des_tid tid;
  300.   struct id_rel idr;
  301.   if (type == RLBLJ || type == RLBLJ_AS_OP)
  302.     rollback_action (a);
  303.   a += 2 * size2b;
  304.   sn = idr.urn.segnum = t2bunpack (a);
  305.   assert (sn != 0);
  306.   a += size2b;
  307.   rn = idr.urn.obnum = t4bunpack (a);
  308.   a += size4b;
  309.   idr.pagenum = pnr = t2bunpack (a);
  310.   a += size2b;
  311.   idr.index = indr = t2bunpack (a);
  312.   a += size2b;
  313.   tid.tpn = t2bunpack (a);
  314.   a += size2b;
  315.   tid.tindex = t2bunpack (a);
  316.   a += size2b;
  317.   pn = tid.tpn;
  318.   ind = tid.tindex;
  319.   if (rn != RDRNUM)
  320.     {
  321.       for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist)
  322.         if (desrel->desrbd.relnum == rn)
  323.           break;
  324.       if (desrel == NULL)
  325.         desrel = cr_rd (&idr);
  326.     }
  327.   else
  328.     desrel = NULL;
  329.   if (type == DELLJ)
  330.     redo_dltn (sn, desrel, rn, &tid, n, a);
  331.   else if (type == INSLJ)
  332.     {
  333.       struct des_tid newtid;
  334.       newtid = ordins (sn, rn, a, n, 'n');
  335.       if (newtid.tpn != pn || newtid.tindex != ind)
  336.         fprintf (stderr, "LIBRCV.frwrd_mtn: Serious error! tids don't matched pn=%dn",
  337.                  pn);
  338.       if (rn != RDRNUM)
  339.         proind (ordindi, desrel, desrel->desrbd.indnum, a, &tid);
  340.       else
  341.         {
  342.           ordrn = t4bunpack (a + scscal (a));
  343.           idr.urn.obnum = ordrn;
  344.           desrel = crtfrd (&idr, a);
  345.         }
  346.     }
  347.   else if (type == CRILJ)
  348.     redo_cind (a, n, sn, pnr, indr, &tid);
  349.   else
  350.     { /* The modification */
  351.       u2_t corsize;
  352.       struct des_tid ref_tid;
  353.       corsize = get_placement (sn, &tid, &ref_tid);
  354.       n -= corsize;
  355.       ordmod (sn, rn, &tid, &ref_tid, corsize, a + corsize, n);
  356.       if (rn != RDRNUM)
  357.         mproind (desrel, desrel->desrbd.indnum, a, a + corsize, &tid);
  358.       else
  359.         {
  360.           ordrn = t4bunpack (a + scscal (a));
  361.           desrel = firstrel;
  362.           for (; desrel->desrbd.relnum != ordrn; desrel = desrel->drlist);
  363.           if (desrel == NULL)
  364.             perror ("LIBRCV.frwrd_mtn: The correspondent desrel is absentn");
  365.           
  366.           if (type == DLILJ) /*nead to delete an index */
  367.             redo_dind (desrel, a + corsize);
  368.           else if (type == ADFLJ)
  369.             { /*nead to add fields */
  370.               struct d_r_bd drbd;
  371.               u2_t fn;
  372.               a += scscal (a) + corsize;
  373.               drbdunpack (&drbd, a);
  374.               fn = drbd.fieldnum;
  375.               desrel->desrbd.fieldnum = fn;
  376.               dfunpack (desrel, fn * rfsize, a + drbdsize);
  377.             }
  378.         }
  379.     }
  380. }
  381. void
  382. getmint (char *a, u2_t  n)
  383. {
  384.   register u2_t i, NFTRANS;
  385.   i4_t cidtr;
  386.   NFTRANS = n / size4b;
  387.   if (NFTRANS == 0)
  388.     return;
  389.   minidnt = t4bunpack (a);
  390.   a += size4b;
  391.   for (i = 1; i < NFTRANS; i++, a += size4b)
  392.     {
  393.       cidtr = t4bunpack (a);
  394.       if (cidtr < minidnt)
  395. minidnt = cidtr;
  396.     }
  397. }
  398. void
  399. r_tr (struct ADBL cadlj)
  400. {
  401.   char *a, type;
  402.   struct ADREC bllj;
  403.   while ( cadlj.cm != 0 )
  404.     {
  405.       rcv_LJ_GETREC (&bllj, &cadlj);
  406.       a = bllj.block;
  407.       type = *a++;
  408.       a += size4b;
  409.       cadlj.npage = t2bunpack (a);
  410.       a += size2b;
  411.       cadlj.cm = t2bunpack (a);
  412.       a += size2b;
  413.       backactn (bllj.razm, a, type);
  414.     }
  415. }
  416. struct ADBL 
  417. bmtn_feot (i4_t fd, struct ADBL cadlj)
  418.     /* The motion back to the first EOTLJ */
  419. {
  420.   char *a, type;
  421.   i4_t prnftr = 0;
  422.   struct ADBL ladlj;
  423.   u2_t blsz;
  424.   char *pnt, mas[RPAGE];
  425.   ladlj = cadlj;
  426.   while ((blsz = LJ_prev (fd, &cadlj, &pnt, mas)) > 0)
  427.     {
  428.       a = pnt;
  429.       type = *a++;
  430.       if (type == GRLBLJ)
  431. {
  432.   ladlj = cadlj;
  433.   prnftr = 1;
  434.   continue;
  435. }
  436.       if (type == EOTLJ)
  437. {
  438.   getmint (a, blsz - size1b);
  439.   if (prnftr == 0)
  440.     rollb_nftr (fd, cadlj, a, blsz - size1b);
  441.   break;
  442. }
  443.       idtr = t4bunpack (a);
  444.       backactn (blsz, a + size4b + 2 * size2b, type);
  445.       ladlj = cadlj;
  446.     }
  447.   return (ladlj);
  448. }
  449. void
  450. backactn (u2_t blsz, char * a, char type)
  451. {
  452.   u2_t sn, pn, ind, pnr, indr;
  453.   i2_t n;
  454.   struct d_r_t *desrel;
  455.   struct des_tid tid;
  456.   i4_t rn;
  457.   struct id_rel idr;
  458.   if (type == RLBLJ || type == CPRLJ || type == RLBLJ_AS_OP)
  459.     return;
  460.   sn = idr.urn.segnum = t2bunpack (a);
  461.   assert (sn != 0);
  462.   a += size2b;
  463.   rn = idr.urn.obnum = t4bunpack (a);
  464.   a += size4b;
  465.   idr.pagenum = pnr = t2bunpack (a);
  466.   a += size2b;
  467.   idr.index = indr = t2bunpack (a);
  468.   a += size2b;
  469.   tid.tpn = t2bunpack (a);
  470.   a += size2b;
  471.   tid.tindex = t2bunpack (a);
  472.   a += size2b;
  473.   pn = tid.tpn;
  474.   ind = tid.tindex;
  475.   if (rn != RDRNUM)
  476.     {
  477.       for (desrel = firstrel; desrel != NULL; desrel = desrel->drlist)
  478. if (desrel->desrbd.relnum == rn)
  479.   break;
  480.       if (desrel == NULL)
  481. desrel = cr_rd (&idr);
  482.     }
  483.   else 
  484.     desrel = NULL;
  485.   n = blsz - ljmsize;
  486.   if (type == DELLJ)
  487.     {
  488.       redo_insrtn (sn, desrel, rn, &tid, n, a);
  489.     }
  490.   else if (type == INSLJ)
  491.     {
  492.       redo_dltn (sn, desrel, rn, &tid, n, a);
  493.     }
  494.   else if (type == DLILJ)
  495.     { /*nead to create an index */
  496.       redo_cind (a, n, sn, pnr, indr, &tid);
  497.     }
  498.   else
  499.     { /* The modification */
  500.       u2_t corsize;
  501.       struct des_tid ref_tid;
  502.       
  503.       corsize = get_placement (sn, &tid, &ref_tid);
  504.       n -= corsize;
  505.       ordmod (sn, rn, &tid, &ref_tid, corsize, a, n);
  506.       if (rn != RDRNUM)
  507. {
  508.   mproind (desrel, desrel->desrbd.indnum, a + n, a, &tid);
  509. }
  510.       else
  511. {
  512.           i4_t ordrn;
  513.   ordrn = t4bunpack (a + scscal(a));
  514.           idr.urn.obnum = ordrn;
  515.   desrel = firstrel;
  516.   for (; desrel->desrbd.relnum != ordrn; desrel = desrel->drlist);
  517.   if (desrel == NULL)
  518.     crtfrd (&idr, a);
  519.   if (type == CRILJ)
  520.     { /* nead to delete an index */
  521.       redo_dind (desrel, a);
  522.     }
  523.   else if (type == ADFLJ)
  524.     { /*nead to delete fields */
  525.               struct d_r_bd drbd;
  526.       a++;
  527.       drbdunpack (&drbd, a);
  528.       desrel->desrbd.fieldnum = drbd.fieldnum;
  529.     }
  530. }
  531.     }
  532. }
  533. u2_t
  534. LJ_prev (i4_t fd, struct ADBL *adj, char **pnt, char *mas)
  535. {
  536.   u2_t N, n, blsz, n1;
  537.   char *end_of_record;
  538.   
  539.   N = adj->npage;
  540.   n = adj->cm;
  541.   if (n == RTPAGE && pagenum == 1)
  542.     return (0);
  543.   if (pagenum != N)
  544.     read_page (fd, N, ljpage);
  545.   n -= RTPAGE;
  546.   if (n < RTBLK)
  547.     { /* the endtop-block places in two pages*/
  548.       char buff[RTBLK];
  549.       n1 = RTBLK - n;
  550.       bcopy (ljpage + RTPAGE, buff + n1, n);
  551.       N--;
  552.       read_page (fd, N, ljpage);
  553.       end_of_record = ljpage + RPAGE - n1;
  554.       bcopy (end_of_record, buff, n1);
  555.       blsz = t2bunpack (buff);
  556.       n = RPAGE - RTPAGE - n1;
  557.     }
  558.   else
  559.     { /* the top-block places in (N)-page */
  560.       end_of_record = ljpage + n + RTPAGE - RTBLK;
  561.       blsz = t2bunpack (end_of_record);
  562.       n -= RTBLK;
  563.       if (n == 0)
  564.         {
  565.           N--;
  566.           read_page (fd, N, ljpage);
  567.           n = RPAGE - RTPAGE;
  568.           end_of_record = ljpage + RPAGE;
  569.         }
  570.     }
  571.   if (n < blsz)
  572.     { /* block-record places in two pages */
  573.       n1 = blsz - n;
  574.       bcopy (ljpage + RTPAGE, mas + n1, n);
  575.       N--;
  576.       read_page (fd, N, ljpage);
  577.       bcopy (ljpage + RPAGE - n1, mas, n1);
  578.       *pnt = mas;
  579.       n = RPAGE - RTPAGE - n1;
  580.     }
  581.   else
  582.     {
  583.       *pnt = end_of_record - blsz;
  584.       n -= blsz;
  585.       if (n == 0)
  586.         {
  587.           N--;
  588.           n = RPAGE - RTPAGE;
  589.         }
  590.     }
  591.   if (n < RTBLK)
  592.     { /* the endtop-block places in two pages */
  593.       N--;
  594.       n1 = RTBLK - n;
  595.       n = RPAGE - RTPAGE - n1;
  596.     }
  597.   else
  598.     n -= RTBLK;
  599.   adj->npage = N;
  600.   adj->cm = n + RTPAGE;
  601.   return (blsz);
  602. }
  603. static void
  604. write_page(i4_t fd, u2_t N, char *buf)
  605. {
  606.   if (lseek (fd, (i4_t) (RPAGE * (N - 1)), SEEK_SET) < 0)
  607.     {
  608.       perror ("LIBRCV: lseek");
  609.       exit (1);
  610.     }
  611.   if (write (fd, buf, RPAGE) != RPAGE)
  612.     {
  613.       perror ("LIBRCV: read");
  614.       exit (1);
  615.     }
  616. }
  617. static void
  618. do_cont (void)
  619. {
  620.   register char *a;
  621.   i4_t NB;
  622.   NB = t4bunpack (ljpage);
  623.   *(ljpage + size4b + size2b) = SIGN_CONT;
  624.   write_page (fdcurlj, pagenum, ljpage);
  625.   a = ljpage;
  626.   t4bpack (NB, a);
  627.   a += size4b;
  628.   t2bpack (RTPAGE, a);
  629.   a += size2b;
  630.   *a = SIGN_NOCONT;
  631.   pagenum++;
  632. }
  633. static char *
  634. write_topblock(u2_t size, u2_t off, char *a)
  635. {
  636.   if (off + RTBLK > RPAGE)
  637.     { /* the top-block places in two pages*/
  638.       u2_t n, n1;
  639.       char buff[size2b];
  640.       n = RPAGE - off;
  641.       t2bpack (size, buff);
  642.       bcopy (buff, a, n);
  643.       do_cont ();
  644.       a = ljpage + RTPAGE;
  645.       n1 = RTBLK - n;
  646.       bcopy (buff + n, a, n1);
  647.       a += n1;
  648.     }
  649.   else
  650.     { /* the top-block places in (N)-page */
  651.       t2bpack (size, a);
  652.       a += size2b;
  653.     }
  654.   return (a);
  655. }
  656. void
  657. rcv_wmlj (struct ADBL *cadlj)
  658. {
  659.   u2_t off, razm;
  660.   register char *p;
  661.   read_page (fdcurlj, cadlj->npage, ljpage);
  662.   off = cadlj->cm;;
  663.   razm = 1;
  664.   p = write_topblock (razm, off, ljpage + off);
  665.   if (p + razm > ljpage + RPAGE)
  666.     {
  667.       do_cont ();
  668.       p = ljpage + RTPAGE;
  669.     }
  670.   *p++ = (char) GRLBLJ;
  671.   p = write_topblock (razm, p - ljpage, p);
  672.   off = p - ljpage;
  673.   t2bpack (off, ljpage + size4b);
  674.   *(ljpage + size4b + size2b) = SIGN_NOCONT;
  675.   write_page (fdcurlj, pagenum, ljpage);
  676.   ftruncate (fdcurlj, pagenum * RPAGE);
  677. }
  678. void
  679. rcv_LJ_GETREC (struct ADREC *bllj, struct ADBL *pcadlj)
  680. {
  681.   char *p;
  682.   struct msg_buf sbuf;
  683.   sbuf.mtype = GETREC;
  684.   t2bpack (trnum, sbuf.mtext);
  685.   bcopy ((char *) pcadlj, sbuf.mtext, adjsize);
  686.   if (msgsnd (msqidl, (void *) &sbuf, adjsize + size2b, 0) < 0)
  687.     {
  688.       perror ("LIBRCV.msgsnd: LJ GETREC");
  689.       exit (1);
  690.     }
  691.   if (msgrcv (msqidl, (void *) &sbuf, sizeof (struct ADREC), trnum, 0) < 0)
  692.     {
  693.       perror ("LIBRCV.msgrcv: Answer from LJ");
  694.       exit (1);
  695.     }
  696.   p = sbuf.mtext;
  697.   bllj->razm = t2bunpack (p);
  698.   p += size2b;
  699.   bcopy (p, bllj->block, bllj->razm);
  700. }
  701. int
  702. dir_copy (char *dir_from, char *dir_to)
  703. {
  704.   DIR *dp;
  705.   struct dirent *dir;
  706.   i4_t num;
  707.   if ((dp = opendir (dir_from)) == NULL)
  708.     {
  709.       fprintf (stderr, "LIBRCV: %s cannot openn", dir_from);
  710.       exit (1);
  711.     }
  712.   dir = readdir (dp);
  713.   dir = readdir (dp);
  714.   for (num = 0; (dir = readdir (dp)) != NULL; num++)
  715.     {
  716.       if (dir->d_ino == 0)
  717. continue;
  718.       copy (dir->d_name, dir_from, dir_to);
  719.     }
  720.   closedir (dp);
  721.   return (num);
  722. }
  723. void
  724. copy (char *name, char *dir_from, char *dir_to)
  725. {
  726.   i4_t i;
  727.   pid_t pidcp;
  728.   char *args[4], mch[4][1024];
  729.   i4_t status;
  730.   for (i = 0; i < 4; i++)
  731.     args[i] = mch[i];
  732.   if ((pidcp = fork ())< 0)
  733.     {
  734.       perror ("fork cp");
  735.       exit (1);
  736.     }
  737.   if (pidcp == 0)
  738.     {
  739.       args[0] = CP;
  740.       sprintf (args[1], "%s/%s", dir_from, name);
  741.       sprintf (args[2], "%s/%s", dir_to, name);
  742.       args[3] = NULL;
  743.       execvp (*args, args);
  744.       perror ("LIBRCV.copy: CP doesn't exec");
  745.       exit (1);
  746.     }
  747.   while (waitpid (-1, &status, 0) != pidcp);
  748. }
  749. int
  750. LOGJ_FIX (void)
  751. {
  752.   struct msg_buf sbuf;
  753.   sbuf.mtype = BEGFIX;
  754.   if (msgsnd (msqidl, (void *) &sbuf, 0, 0) < 0)
  755.     {
  756.       perror ("LIBRCV.msgsnd: LOGJ->FIX");
  757.       exit (1);
  758.     }
  759.   if (msgrcv (msqidl, (void *) &sbuf, 1, ANSLJ, 0) < 0)
  760.     {
  761.       perror ("LIBRCV.msgrcv: BEGFIX LJ");
  762.       exit (1);
  763.     }
  764.   return ( (i4_t)*sbuf.mtext);
  765. }
  766. /* Read "N"-page from JRN-basefile into buf */
  767. void
  768. read_page(i4_t fd, u2_t N, char *buf)
  769. {
  770.   if (lseek (fd, (i4_t) (RPAGE * (N - 1)), SEEK_SET) < 0)
  771.     {
  772.       perror ("LIBRCV: lseek");
  773.       exit (1);
  774.     }
  775.   if (read (fd, buf, RPAGE) != RPAGE)
  776.     {
  777.       perror ("LIBRCV: read");
  778.       exit (1);
  779.     }
  780.   pagenum = N;
  781. }
  782. void
  783. dubl_segs (void)
  784. {
  785.   dir_copy (DIR_SEGS, DIR_DUB_SEGS);
  786.   dir_copy (DIR_SEGS, DIR_REP_SEGS);
  787. }
  788. void
  789. rcv_ini_lj ()
  790. {
  791.   struct msg_buf sbuf;
  792.   sbuf.mtype = INILJ;
  793.   t2bpack (trnum, sbuf.mtext);
  794.   if (msgsnd (msqidl, (void *) &sbuf, size2b, 0) < 0)
  795.     {
  796.       perror ("LIBRCV.msgsnd: LJ INILOGJ");
  797.       exit (1);
  798.     }
  799.   if (msgrcv (msqidl, (void *) &sbuf, 0, trnum, 0) < 0)
  800.     {
  801.       perror ("LIBRCV.msgrcv: Answer from LJ on INILOGJ");
  802.       exit (1);
  803.     }
  804. }