|
|
1.1 root 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 "fp.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: private void
27: recinit()
28: {
29: char buf[128];
30:
31: #ifdef MAC
32: swritef(buf, "%s/%s", HomeDir, p_tempfile);
33: #else
34: swritef(buf, "%s/%s", TmpFilePath, p_tempfile);
35: #endif
36: recfname = copystr(buf);
37: recfname = mktemp(recfname);
38: rec_fd = creat(recfname, 0644);
39: if (rec_fd == -1) {
40: complain("Cannot create \"%s\"; recovery disabled.", recfname);
41: return;
42: }
43: /* initialize the record IO */
44: rec_out = fd_open(recfname, F_WRITE|F_LOCKED, rec_fd, iobuff, LBSIZE);
45:
46: /* Initialize the record header. */
47: Header.Uid = getuid();
48: Header.Pid = getpid();
49: Header.UpdTime = 0L;
50: Header.Nbuffers = 0;
51: (void) write(rec_fd, (char *) &Header, sizeof Header);
52: }
53:
54: void
55: recclose()
56: {
57: if (rec_fd == -1)
58: return;
59: (void) close(rec_fd);
60: rec_fd = -1;
61: (void) unlink(recfname);
62: }
63:
64: private void
65: putaddr(addr, p)
66: daddr addr;
67: register File *p;
68: {
69: register char *cp = (char *) &addr;
70: register int nchars = sizeof (daddr);
71:
72: while (--nchars >= 0)
73: jputc(*cp++ & 0377, p);
74: }
75:
76: private void
77: putn(cp, nbytes)
78: register char *cp;
79: register size_t nbytes;
80: {
81: while (nbytes-- > 0)
82: jputc(*cp++ & 0377, rec_out);
83: }
84:
85: /* Write out the line pointers for buffer B. */
86:
87: private void
88: dmppntrs(b)
89: register Buffer *b;
90: {
91: register Line *lp;
92:
93: for (lp = b->b_first; lp != 0; lp = lp->l_next)
94: putaddr(lp->l_dline, rec_out);
95: }
96:
97: /* dump the buffer info and then the actual line pointers. */
98:
99: private void
100: dmp_buf_header(b)
101: register Buffer *b;
102: {
103: struct rec_entry record;
104: register Line *lp;
105: register int nlines = 0;
106:
107: for (lp = b->b_first; lp != 0; lp = lp->l_next, nlines++)
108: if (lp == b->b_dot)
109: record.r_dotline = nlines;
110: strcpy(record.r_fname, b->b_fname ? b->b_fname : NullStr);
111: strcpy(record.r_bname, b->b_name);
112: record.r_nlines = nlines;
113: record.r_dotchar = b->b_char;
114: putn((char *) &record, sizeof record);
115: }
116:
117: /* Goes through all the buffers and syncs them to the disk. */
118:
119: int SyncFreq = 50;
120:
121: void
122: SyncRec()
123: {
124: register Buffer *b;
125: static int beenhere = NO;
126:
127: if (beenhere == NO) {
128: beenhere = YES;
129: recinit(); /* Init recover file. */
130: }
131: if (rec_fd == -1)
132: return;
133: lseek(rec_fd, 0L, L_SET);
134: (void) time(&Header.UpdTime);
135: Header.Nbuffers = 0;
136: for (b = world; b != 0; b = b->b_next)
137: if (b->b_type == B_SCRATCH || !IsModified(b))
138: continue;
139: else
140: Header.Nbuffers += 1;
141: Header.FreePtr = DFree;
142: putn((char *) &Header, sizeof Header);
143: if (Header.Nbuffers != 0) {
144: lsave(); /* this makes things really right */
145: SyncTmp();
146: for (b = world; b != 0; b = b->b_next)
147: if (b->b_type == B_SCRATCH || !IsModified(b))
148: continue;
149: else
150: dmp_buf_header(b);
151: for (b = world; b != 0; b = b->b_next)
152: if (b->b_type == B_SCRATCH || !IsModified(b))
153: continue;
154: else
155: dmppntrs(b);
156: }
157: flush(rec_out);
158: }
159:
160: /* Full Recover. What we have to do is go find the name of the tmp
161: file data/rec pair and use those instead of the ones we would have
162: created eventually. The rec file has a list of buffers, and then
163: the actual pointers. Stored for each buffer is the buffer name,
164: the file name, the number of lines, the current line, the current
165: character. The current modes do not need saving as they will be
166: saved when the file name is set. If a process was running in a
167: buffer, it will be lost. */
168:
169: void
170: FullRecover()
171: {
172: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.