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 ;
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:
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: }
Defined functions
defined in line
97; used 1 times
putn
defined in line
74; used 2 times
Defined variables
defined in line
24; used 13 times
Defined macros
L_SET
defined in line
21; used 2 times