home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume14 / jove4.9 / part01 / rec.c < prev    next >
C/C++ Source or Header  |  1988-04-25  |  4KB  |  170 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "io.h"
  10. #include "rec.h"
  11.  
  12. #ifndef MAC
  13. #    include <sys/file.h>
  14. #endif
  15.  
  16. private int    rec_fd = -1;
  17. private char    *recfname;
  18. private File    *rec_out;
  19.  
  20. #ifndef L_SET
  21. #    define L_SET 0
  22. #endif
  23.  
  24. private struct rec_head    Header;
  25.  
  26. recinit()
  27. {
  28.     char    buf[128];
  29.  
  30. #ifdef MAC
  31.     sprintf(buf, "%s/%s", HomeDir, p_tempfile);
  32. #else
  33.     sprintf(buf, "%s/%s", TmpFilePath, p_tempfile);
  34. #endif
  35.     recfname = copystr(buf);
  36.     recfname = mktemp(recfname);
  37.     rec_fd = creat(recfname, 0644);
  38.     if (rec_fd == -1) {
  39.         complain("Cannot create \"%s\"; recovery disabled.", recfname);
  40.         return;
  41.     }
  42.     /* initialize the record IO */
  43.     rec_out = fd_open(recfname, F_WRITE|F_LOCKED, rec_fd, iobuff, LBSIZE);
  44.  
  45.     /* Initialize the record header. */
  46.     Header.Uid = getuid();
  47.     Header.Pid = getpid();
  48.     Header.UpdTime = 0L;
  49.     Header.Nbuffers = 0;
  50.     (void) write(rec_fd, (char *) &Header, sizeof Header);
  51. }
  52.  
  53. recclose()
  54. {
  55.     if (rec_fd == -1)
  56.         return;
  57.     (void) close(rec_fd);
  58.     rec_fd = -1;
  59.     (void) unlink(recfname);
  60. }
  61.  
  62. private
  63. putaddr(addr, p)
  64. disk_line    addr;
  65. register File    *p;
  66. {
  67.     register char    *cp = (char *) &addr;
  68.     register int    nchars = sizeof (disk_line);
  69.  
  70.     while (--nchars >= 0)
  71.         putc(*cp++ & 0377, p);
  72. }
  73.  
  74. private
  75. putn(cp, nbytes)
  76. register char    *cp;
  77. register int    nbytes;
  78. {
  79.     while (--nbytes >= 0)
  80.         putc(*cp++ & 0377, rec_out);
  81. }
  82.  
  83. /* Write out the line pointers for buffer B. */
  84.  
  85. private
  86. dmppntrs(b)
  87. register Buffer    *b;
  88. {
  89.     register Line    *lp;
  90.  
  91.     for (lp = b->b_first; lp != 0; lp = lp->l_next)
  92.         putaddr(lp->l_dline, rec_out);
  93. }
  94.  
  95. /* dump the buffer info and then the actual line pointers. */
  96.  
  97. private
  98. dmp_buf_header(b)
  99. register Buffer    *b;
  100. {
  101.     struct rec_entry    record;
  102.     register Line    *lp;
  103.     register int    nlines = 0;
  104.  
  105.     for (lp = b->b_first; lp != 0; lp = lp->l_next, nlines++)
  106.         if (lp == b->b_dot)
  107.             record.r_dotline = nlines;
  108.     strcpy(record.r_fname, b->b_fname ? b->b_fname : NullStr);
  109.     strcpy(record.r_bname, b->b_name);
  110.     record.r_nlines = nlines;
  111.     record.r_dotchar = b->b_char;
  112.     putn((char *) &record, sizeof record);
  113. }
  114.  
  115. /* Goes through all the buffers and syncs them to the disk. */
  116.  
  117. int    SyncFreq = 50;
  118.  
  119. SyncRec()
  120. {
  121.     extern disk_line    DFree;
  122.     register Buffer    *b;
  123.     static int    beenhere = NO;
  124.  
  125.     if (beenhere == NO) {
  126.         recinit();    /* Init recover file. */
  127.         beenhere = YES;
  128.     }
  129.     if (rec_fd == -1)
  130.         return;
  131.     lseek(rec_fd, 0L, L_SET);
  132.     (void) time(&Header.UpdTime);
  133.     Header.Nbuffers = 0;
  134.     for (b = world; b != 0; b = b->b_next)
  135.         if (b->b_type == B_SCRATCH || !IsModified(b))
  136.             continue;
  137.         else
  138.             Header.Nbuffers += 1;
  139.     Header.FreePtr = DFree;
  140.     putn((char *) &Header, sizeof Header);
  141.     if (Header.Nbuffers != 0) {
  142.         lsave();    /* this makes things really right */
  143.         SyncTmp();
  144.         for (b = world; b != 0; b = b->b_next)
  145.             if (b->b_type == B_SCRATCH || !IsModified(b))
  146.                 continue;
  147.             else
  148.                 dmp_buf_header(b);
  149.         for (b = world; b != 0; b = b->b_next)
  150.             if (b->b_type == B_SCRATCH || !IsModified(b))
  151.                 continue;
  152.             else
  153.                 dmppntrs(b);
  154.     }
  155.     flush(rec_out);
  156. }
  157.  
  158. /* Full Recover.  What we have to do is go find the name of the tmp
  159.    file data/rec pair and use those instead of the ones we would have
  160.    created eventually.  The rec file has a list of buffers, and then
  161.    the actual pointers.  Stored for each buffer is the buffer name,
  162.    the file name, the number of lines, the current line, the current
  163.    character.  The current modes do not need saving as they will be
  164.    saved when the file name is set.  If a process was running in a
  165.    buffer, it will be lost. */
  166.  
  167. FullRecover()
  168. {
  169. }
  170.