|
|
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 "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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.