Lines Matching +full:mode +full:- +full:recovery

1 /*-
42 * Recovery code.
45 * paths of a b+tree file and a mail recovery file. The former is the file
48 * simple states of recovery are:
51 * the b+tree file exists and is mode 700, the mail recovery
54 * the b+tree file exists and is mode 600, the mail recovery
58 * file descriptor for the mail recovery file.
60 * To find out if a recovery file/backing file pair are in use, try to get
61 * a lock on the recovery file.
72 * haven't yet failed at setting up or doing recovery.
74 * To preserve a recovery file/backing file pair, set the F_RCV_NORM bit.
78 * If the EXF file descriptor (rcv_fd) is not -1, it is closed.
81 * the DB package can use it for on-disk caching and/or to snapshot the
82 * file. When the file is first modified, the mail recovery file is created,
89 * The recovery mail file contains normal mail headers, with two additional
91 * X-vi-data: <file|path>;<base64 encoded path>
95 * Btree files are named "vi.XXXXXX" and recovery files are named
99 #define VI_DHEADER "X-vi-data:"
109 * rcv_tmp --
110 * Build a file name that will be used as the recovery file.
123 * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER. in rcv_tmp()
126 * If the recovery directory doesn't exist, try and create it. As in rcv_tmp()
127 * the recovery files are themselves protected from reading/writing in rcv_tmp()
129 * would have permission to remove other user's recovery files. If in rcv_tmp()
145 if ((fd = rcv_mktemp(sp, path, dp)) == -1) { in rcv_tmp()
152 ep->rcv_path = path; in rcv_tmp()
165 * rcv_init --
166 * Force the file to be snapshotted for recovery.
176 ep = sp->ep; in rcv_init()
189 if (ep->rcv_mpath == NULL) { in rcv_init()
199 sp->gp->scr_busy(sp, in rcv_init()
200 "057|Copying file for recovery...", BUSY_ON); in rcv_init()
201 if (ep->db->sync(ep->db, R_RECNOSYNC)) { in rcv_init()
202 msgq_str(sp, M_SYSERR, ep->rcv_path, in rcv_init()
204 sp->gp->scr_busy(sp, NULL, BUSY_OFF); in rcv_init()
207 sp->gp->scr_busy(sp, NULL, BUSY_OFF); in rcv_init()
211 (void)chmod(ep->rcv_path, S_IRUSR | S_IWUSR); in rcv_init()
223 * rcv_sync --
240 ep = sp->ep; in rcv_sync()
246 if (ep->db->sync(ep->db, R_RECNOSYNC)) { in rcv_sync()
249 ep->rcv_path, "060|File backup failed: %s"); in rcv_sync()
259 rcv_email(sp, ep->rcv_mpath); in rcv_sync()
265 * the recovery information, i.e. it's like the user re-edited the in rcv_sync()
267 * recovery file, it's simpler than exiting and reopening all of the in rcv_sync()
281 if ((fd = rcv_mktemp(sp, buf, dp)) == -1) { in rcv_sync()
285 sp->gp->scr_busy(sp, in rcv_sync()
286 "061|Copying file for recovery...", BUSY_ON); in rcv_sync()
287 if (rcv_copy(sp, fd, ep->rcv_path) || in rcv_sync()
294 sp->gp->scr_busy(sp, NULL, BUSY_OFF); in rcv_sync()
308 * rcv_mailfile --
336 gp = sp->gp; in rcv_mailfile()
350 if ((fd = rcv_mktemp(sp, mpath, dp)) == -1) { in rcv_mailfile()
367 ep = sp->ep; in rcv_mailfile()
369 msgq(sp, M_SYSERR, "063|Unable to lock recovery file"); in rcv_mailfile()
372 ep->rcv_fd = dup(fd); in rcv_mailfile()
373 ep->rcv_mpath = mpath; in rcv_mailfile()
374 cp_path = ep->rcv_path; in rcv_mailfile()
377 t = sp->frp->name; in rcv_mailfile()
401 "From: root@", host, " (Nvi recovery program)", in rcv_mailfile()
402 "To: ", pw->pw_name, "@", host, in rcv_mailfile()
416 "On ", ctime(&now), ", the user ", pw->pw_name, in rcv_mailfile()
418 host, ", when it was saved for recovery. ", in rcv_mailfile()
420 "to this file using the -r option to ", getprogname(), ":\n\n\t", in rcv_mailfile()
421 getprogname(), " -r ", qt); in rcv_mailfile()
424 if (len == -1) { in rcv_mailfile()
434 for (t1 = buf; len > 0; len -= t2 - t1, t1 = t2) { in rcv_mailfile()
437 t2 = t1 + (len - 1); in rcv_mailfile()
443 if (t2 - t1 <= FMTCOLS) in rcv_mailfile()
447 for (t3 = t2; t2 > t1; --t2) in rcv_mailfile()
449 if (t2 - t1 <= FMTCOLS) in rcv_mailfile()
459 if (fwrite(t1, 1, t2 - t1, fp) != t2 - t1) { in rcv_mailfile()
472 werr: msgq(sp, M_SYSERR, "065|Recovery file"); in rcv_mailfile()
479 ep->rcv_fd = -1; in rcv_mailfile()
490 * rcv_list --
507 /* Open the recovery directory for reading. */ in rcv_list()
518 if (strncmp(dp->d_name, "recover.", 8)) in rcv_list()
522 if ((fp = fopen(dp->d_name, "r")) == NULL) in rcv_list()
530 * should permit recovery anyway. If this is wrong, in rcv_list()
548 msgq_str(sp, M_ERR, dp->d_name, in rcv_list()
549 "066|%s: malformed recovery file"); in rcv_list()
563 * If the file doesn't exist, it's an orphaned recovery file, in rcv_list()
573 (void)unlink(dp->d_name); in rcv_list()
595 * rcv_read --
623 name = frp->name;
624 sv_fd = -1;
627 if (strncmp(dp->d_name, "recover.", 8))
629 if ((recpath = join(rp, dp->d_name)) == NULL) {
645 * should permit recovery anyway. If this is wrong,
665 msgq_str(sp, M_ERR, dp->d_name,
666 "067|%s: malformed recovery file");
681 * If the file doesn't exist, it's an orphaned recovery file,
691 (void)unlink(dp->d_name);
726 if (sv_fd != -1)
756 * file_init() is going to set ep->rcv_path.
771 ep = sp->ep;
772 ep->rcv_mpath = recp;
773 ep->rcv_fd = sv_fd;
783 * rcv_copy --
784 * Copy a recovery file.
792 if ((rfd = open(fname, O_RDONLY, 0)) == -1)
795 for (off = 0; nr; nr -= nw, off += nw)
806 * rcv_mktemp --
814 if ((fd = mkstemp(path)) == -1)
820 * rcv_email --
828 if (asprintf(&buf, _PATH_SENDMAIL " -odb -t < %s", fname) == -1) {
838 * rcv_dlnwrite --
839 * Encode a string into an X-vi-data line and write it.
855 len, bp + dlen + 1, blen)) == -1)
861 FMTCOLS - (int)sizeof(VI_DHEADER), bp)) < 0)
863 plen -= (int)sizeof(VI_DHEADER) + 1;
864 for (p = bp, xlen -= plen; xlen > 0; xlen -= plen) {
866 if ((plen = fprintf(fp, " %.*s\n", FMTCOLS - 1, p)) < 0)
868 plen -= 2;
877 return (-1);
881 * rcv_dlnread --
882 * Read an X-vi-data line and decode it.
899 if (strncmp(buf, VI_DHEADER, sizeof(VI_DHEADER) - 1)) {
906 len = strlen(buf) - sizeof(VI_DHEADER) + 1;
908 (void)memcpy(bp, buf + sizeof(VI_DHEADER) - 1, len);
916 p = bp + len - off;
925 dlen = src - p;
927 len -= src - bp;
934 (u_char *)data, len / 4 * 3 + 1))) == -1) {
951 return (-1);