|
|
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.