Remove building with NOCRYPTO option
[minix.git] / external / bsd / nvi / dist / common / log.c
blobfb9df00c64d53169803b4db13a14a74e2f1037ef
1 /* $NetBSD: log.c,v 1.3 2014/01/26 21:43:45 christos Exp $ */
2 /*-
3 * Copyright (c) 1992, 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1992, 1993, 1994, 1995, 1996
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
9 */
11 #include "config.h"
13 #include <sys/cdefs.h>
14 #if 0
15 #ifndef lint
16 static const char sccsid[] = "Id: log.c,v 10.26 2002/03/02 23:12:13 skimo Exp (Berkeley) Date: 2002/03/02 23:12:13 ";
17 #endif /* not lint */
18 #else
19 __RCSID("$NetBSD: log.c,v 1.3 2014/01/26 21:43:45 christos Exp $");
20 #endif
22 #include <sys/types.h>
23 #include <sys/queue.h>
24 #include <sys/stat.h>
26 #include <bitstring.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <limits.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
34 #include "common.h"
35 #include "dbinternal.h"
38 * The log consists of records, each containing a type byte and a variable
39 * length byte string, as follows:
41 * LOG_CURSOR_INIT MARK
42 * LOG_CURSOR_END MARK
43 * LOG_LINE_APPEND_F db_recno_t char *
44 * LOG_LINE_APPEND_B db_recno_t char *
45 * LOG_LINE_DELETE_F db_recno_t char *
46 * LOG_LINE_DELETE_B db_recno_t char *
47 * LOG_LINE_RESET_F db_recno_t char *
48 * LOG_LINE_RESET_B db_recno_t char *
49 * LOG_MARK LMARK
51 * We do before image physical logging. This means that the editor layer
52 * MAY NOT modify records in place, even if simply deleting or overwriting
53 * characters. Since the smallest unit of logging is a line, we're using
54 * up lots of space. This may eventually have to be reduced, probably by
55 * doing logical logging, which is a much cooler database phrase.
57 * The implementation of the historic vi 'u' command, using roll-forward and
58 * roll-back, is simple. Each set of changes has a LOG_CURSOR_INIT record,
59 * followed by a number of other records, followed by a LOG_CURSOR_END record.
60 * LOG_LINE_RESET records come in pairs. The first is a LOG_LINE_RESET_B
61 * record, and is the line before the change. The second is LOG_LINE_RESET_F,
62 * and is the line after the change. Roll-back is done by backing up to the
63 * first LOG_CURSOR_INIT record before a change. Roll-forward is done in a
64 * similar fashion.
66 * The 'U' command is implemented by rolling backward to a LOG_CURSOR_END
67 * record for a line different from the current one. It should be noted that
68 * this means that a subsequent 'u' command will make a change based on the
69 * new position of the log's cursor. This is okay, and, in fact, historic vi
70 * behaved that way.
73 static int vi_log_get __P((SCR *sp, db_recno_t *lnop, size_t *size));
74 static int log_cursor1 __P((SCR *, int));
75 static void log_err __P((SCR *, const char *, int));
76 #if defined(DEBUG) && 0
77 static void log_trace __P((SCR *, const char *, db_recno_t, u_char *));
78 #endif
80 /* Try and restart the log on failure, i.e. if we run out of memory. */
81 #define LOG_ERR { \
82 log_err(sp, __FILE__, __LINE__); \
83 return (1); \
86 /* offset of CHAR_T string in log needs to be aligned on some systems
87 * because it is passed to db_set as a string
89 typedef struct {
90 char data[sizeof(u_char) /* type */ + sizeof(db_recno_t)];
91 CHAR_T str[1];
92 } log_t;
93 #define CHAR_T_OFFSET ((char *)(((log_t*)0)->str) - (char *)0)
96 * log_init --
97 * Initialize the logging subsystem.
99 * PUBLIC: int log_init __P((SCR *, EXF *));
102 log_init(SCR *sp, EXF *ep)
105 * !!!
106 * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER.
108 * Initialize the buffer. The logging subsystem has its own
109 * buffers because the global ones are almost by definition
110 * going to be in use when the log runs.
112 sp->wp->l_lp = NULL;
113 sp->wp->l_len = 0;
114 ep->l_cursor.lno = 1; /* XXX Any valid recno. */
115 ep->l_cursor.cno = 0;
116 ep->l_high = ep->l_cur = 1;
118 if (db_create(&ep->log, 0, 0) != 0 ||
119 db_open(ep->log, NULL, DB_RECNO,
120 DB_CREATE | VI_DB_THREAD, S_IRUSR | S_IWUSR) != 0) {
121 msgq(sp, M_SYSERR, "009|Log file");
122 F_SET(ep, F_NOLOG);
123 return (1);
126 ep->l_win = NULL;
127 /*LOCK_INIT(sp->wp, ep);*/
129 return (0);
133 * log_end --
134 * Close the logging subsystem.
136 * PUBLIC: int log_end __P((SCR *, EXF *));
139 log_end(SCR *sp, EXF *ep)
142 * !!!
143 * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER.
145 /*LOCK_END(sp->wp, ep);*/
146 if (ep->log != NULL) {
147 (void)(ep->log->close)(ep->log, DB_NOSYNC);
148 ep->log = NULL;
150 if (sp->wp->l_lp != NULL) {
151 free(sp->wp->l_lp);
152 sp->wp->l_lp = NULL;
154 sp->wp->l_len = 0;
155 ep->l_cursor.lno = 1; /* XXX Any valid recno. */
156 ep->l_cursor.cno = 0;
157 ep->l_high = ep->l_cur = 1;
158 return (0);
162 * log_cursor --
163 * Log the current cursor position, starting an event.
165 * PUBLIC: int log_cursor __P((SCR *));
168 log_cursor(SCR *sp)
170 EXF *ep;
172 ep = sp->ep;
173 if (F_ISSET(ep, F_NOLOG))
174 return (0);
177 * If any changes were made since the last cursor init,
178 * put out the ending cursor record.
180 if (ep->l_cursor.lno == OOBLNO) {
181 if (ep->l_win && ep->l_win != sp->wp)
182 return 0;
183 ep->l_cursor.lno = sp->lno;
184 ep->l_cursor.cno = sp->cno;
185 ep->l_win = NULL;
186 return (log_cursor1(sp, LOG_CURSOR_END));
188 ep->l_cursor.lno = sp->lno;
189 ep->l_cursor.cno = sp->cno;
190 return (0);
194 * log_cursor1 --
195 * Actually push a cursor record out.
197 static int
198 log_cursor1(SCR *sp, int type)
200 DBT data, key;
201 EXF *ep;
203 ep = sp->ep;
206 if (type == LOG_CURSOR_INIT &&
207 LOCK_TRY(sp->wp, ep))
208 return 1;
211 BINC_RETC(sp, sp->wp->l_lp, sp->wp->l_len, sizeof(u_char) + sizeof(MARK));
212 sp->wp->l_lp[0] = type;
213 memmove(sp->wp->l_lp + sizeof(u_char), &ep->l_cursor, sizeof(MARK));
215 memset(&key, 0, sizeof(key));
216 key.data = &ep->l_cur;
217 key.size = sizeof(db_recno_t);
218 memset(&data, 0, sizeof(data));
219 data.data = sp->wp->l_lp;
220 data.size = sizeof(u_char) + sizeof(MARK);
221 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
222 LOG_ERR;
224 #if defined(DEBUG) && 0
225 vtrace(sp, "%lu: %s: %u/%u\n", ep->l_cur,
226 type == LOG_CURSOR_INIT ? "log_cursor_init" : "log_cursor_end",
227 sp->lno, sp->cno);
228 #endif
229 /* Reset high water mark. */
230 ep->l_high = ++ep->l_cur;
233 if (type == LOG_CURSOR_END)
234 LOCK_UNLOCK(sp->wp, ep);
236 return (0);
240 * log_line --
241 * Log a line change.
243 * PUBLIC: int log_line __P((SCR *, db_recno_t, u_int));
246 log_line(SCR *sp, db_recno_t lno, u_int action)
248 DBT data, key;
249 EXF *ep;
250 size_t len;
251 CHAR_T *lp;
252 db_recno_t lcur;
254 ep = sp->ep;
255 if (F_ISSET(ep, F_NOLOG))
256 return (0);
259 * XXX
261 * Kluge for vi. Clear the EXF undo flag so that the
262 * next 'u' command does a roll-back, regardless.
264 F_CLR(ep, F_UNDO);
266 /* Put out one initial cursor record per set of changes. */
267 if (ep->l_cursor.lno != OOBLNO) {
268 if (log_cursor1(sp, LOG_CURSOR_INIT))
269 return (1);
270 ep->l_cursor.lno = OOBLNO;
271 ep->l_win = sp->wp;
272 } /*else if (ep->l_win != sp->wp) {
273 printf("log_line own: %p, this: %p\n", ep->l_win, sp->wp);
274 return 1;
277 switch (action) {
278 /* newly added for DB4 logging */
279 case LOG_LINE_APPEND_B:
280 case LOG_LINE_DELETE_F:
281 return 0;
285 * Put out the changes. If it's a LOG_LINE_RESET_B call, it's a
286 * special case, avoid the caches. Also, if it fails and it's
287 * line 1, it just means that the user started with an empty file,
288 * so fake an empty length line.
290 if (action == LOG_LINE_RESET_B) {
291 if (db_get(sp, lno, DBG_NOCACHE, &lp, &len)) {
292 static CHAR_T nul = 0;
293 if (lno != 1) {
294 db_err(sp, lno);
295 return (1);
297 len = 0;
298 lp = &nul;
300 } else
301 if (db_get(sp, lno, DBG_FATAL, &lp, &len))
302 return (1);
303 BINC_RETC(sp,
304 sp->wp->l_lp, sp->wp->l_len,
305 len * sizeof(CHAR_T) + CHAR_T_OFFSET);
306 sp->wp->l_lp[0] = action;
307 memmove(sp->wp->l_lp + sizeof(u_char), &lno, sizeof(db_recno_t));
308 MEMMOVEW(sp->wp->l_lp + CHAR_T_OFFSET, lp, len);
310 lcur = ep->l_cur;
311 memset(&key, 0, sizeof(key));
312 key.data = &lcur;
313 key.size = sizeof(db_recno_t);
314 memset(&data, 0, sizeof(data));
315 data.data = sp->wp->l_lp;
316 data.size = len * sizeof(CHAR_T) + CHAR_T_OFFSET;
317 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
318 LOG_ERR;
320 #if defined(DEBUG) && 0
321 switch (action) {
322 case LOG_LINE_APPEND_F:
323 vtrace(sp, "%u: log_line: append_f: %lu {%u}\n",
324 ep->l_cur, lno, len);
325 break;
326 case LOG_LINE_APPEND_B:
327 vtrace(sp, "%u: log_line: append_b: %lu {%u}\n",
328 ep->l_cur, lno, len);
329 break;
330 case LOG_LINE_DELETE_F:
331 vtrace(sp, "%lu: log_line: delete_f: %lu {%u}\n",
332 ep->l_cur, lno, len);
333 break;
334 case LOG_LINE_DELETE_B:
335 vtrace(sp, "%lu: log_line: delete_b: %lu {%u}\n",
336 ep->l_cur, lno, len);
337 break;
338 case LOG_LINE_RESET_F:
339 vtrace(sp, "%lu: log_line: reset_f: %lu {%u}\n",
340 ep->l_cur, lno, len);
341 break;
342 case LOG_LINE_RESET_B:
343 vtrace(sp, "%lu: log_line: reset_b: %lu {%u}\n",
344 ep->l_cur, lno, len);
345 break;
347 #endif
348 /* Reset high water mark. */
349 ep->l_high = ++ep->l_cur;
351 return (0);
355 * log_mark --
356 * Log a mark position. For the log to work, we assume that there
357 * aren't any operations that just put out a log record -- this
358 * would mean that undo operations would only reset marks, and not
359 * cause any other change.
361 * PUBLIC: int log_mark __P((SCR *, LMARK *));
364 log_mark(SCR *sp, LMARK *lmp)
366 DBT data, key;
367 EXF *ep;
369 ep = sp->ep;
370 if (F_ISSET(ep, F_NOLOG))
371 return (0);
373 /* Put out one initial cursor record per set of changes. */
374 if (ep->l_cursor.lno != OOBLNO) {
375 if (log_cursor1(sp, LOG_CURSOR_INIT))
376 return (1);
377 ep->l_cursor.lno = OOBLNO;
378 ep->l_win = sp->wp;
381 BINC_RETC(sp, sp->wp->l_lp,
382 sp->wp->l_len, sizeof(u_char) + sizeof(LMARK));
383 sp->wp->l_lp[0] = LOG_MARK;
384 memmove(sp->wp->l_lp + sizeof(u_char), lmp, sizeof(LMARK));
386 memset(&key, 0, sizeof(key));
387 key.data = &ep->l_cur;
388 key.size = sizeof(db_recno_t);
389 memset(&data, 0, sizeof(data));
390 data.data = sp->wp->l_lp;
391 data.size = sizeof(u_char) + sizeof(LMARK);
392 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
393 LOG_ERR;
395 #if defined(DEBUG) && 0
396 vtrace(sp, "%lu: mark %c: %lu/%u\n",
397 ep->l_cur, lmp->name, lmp->lno, lmp->cno);
398 #endif
399 /* Reset high water mark. */
400 ep->l_high = ++ep->l_cur;
401 return (0);
405 * vi_log_get --
406 * Get a line from the log in log buffer.
408 static int
409 vi_log_get(SCR *sp, db_recno_t *lnop, size_t *size)
411 DBT key, data;
412 size_t nlen;
413 EXF *ep;
415 ep = sp->ep;
417 nlen = 1024;
418 retry:
419 BINC_RETC(sp, sp->wp->l_lp, sp->wp->l_len, nlen);
421 memset(&key, 0, sizeof(key));
422 key.data = lnop; /* Initialize db request. */
423 key.size = sizeof(db_recno_t);
424 memset(&data, 0, sizeof(data));
425 data.data = sp->wp->l_lp;
426 data.ulen = sp->wp->l_len;
427 data.flags = DB_DBT_USERMEM;
428 switch (ep->log->get(ep->log, NULL, &key, &data, 0)) {
429 case ENOMEM:
430 nlen = data.size;
431 goto retry;
432 case 0:
433 *size = data.size;
434 return 0;
435 default:
436 return 1;
441 * Log_backward --
442 * Roll the log backward one operation.
444 * PUBLIC: int log_backward __P((SCR *, MARK *));
447 log_backward(SCR *sp, MARK *rp)
449 EXF *ep;
450 LMARK lm;
451 MARK m;
452 db_recno_t lno;
453 int didop;
454 u_char *p;
455 size_t size;
457 ep = sp->ep;
458 if (F_ISSET(ep, F_NOLOG)) {
459 msgq(sp, M_ERR,
460 "010|Logging not being performed, undo not possible");
461 return (1);
464 if (ep->l_cur == 1) {
465 msgq(sp, M_BERR, "011|No changes to undo");
466 return (1);
469 if (ep->l_win && ep->l_win != sp->wp) {
470 ex_emsg(sp, NULL, EXM_LOCKED);
471 return 1;
473 ep->l_win = sp->wp;
476 F_SET(ep, F_NOLOG); /* Turn off logging. */
478 for (didop = 0;;) {
479 --ep->l_cur;
480 if (vi_log_get(sp, &ep->l_cur, &size))
481 LOG_ERR;
482 #if defined(DEBUG) && 0
483 log_trace(sp, "log_backward", ep->l_cur, data.data);
484 #endif
485 switch (*(p = (u_char *)sp->wp->l_lp)) {
486 case LOG_CURSOR_INIT:
487 if (didop) {
488 memmove(rp, p + sizeof(u_char), sizeof(MARK));
489 F_CLR(ep, F_NOLOG);
490 ep->l_win = NULL;
491 return (0);
493 break;
494 case LOG_CURSOR_END:
495 break;
496 case LOG_LINE_APPEND_F:
497 didop = 1;
498 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
499 if (db_delete(sp, lno))
500 goto err;
501 ++sp->rptlines[L_DELETED];
502 break;
503 case LOG_LINE_DELETE_B:
504 didop = 1;
505 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
506 if (db_insert(sp, lno,
507 (CHAR_T *)(p + CHAR_T_OFFSET),
508 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
509 goto err;
510 ++sp->rptlines[L_ADDED];
511 break;
512 case LOG_LINE_RESET_F:
513 break;
514 case LOG_LINE_RESET_B:
515 didop = 1;
516 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
517 if (db_set(sp, lno,
518 (CHAR_T *)(p + CHAR_T_OFFSET),
519 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
520 goto err;
521 if (sp->rptlchange != lno) {
522 sp->rptlchange = lno;
523 ++sp->rptlines[L_CHANGED];
525 break;
526 case LOG_MARK:
527 didop = 1;
528 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
529 m.lno = lm.lno;
530 m.cno = lm.cno;
531 if (mark_set(sp, lm.name, &m, 0))
532 goto err;
533 break;
534 default:
535 abort();
539 err: F_CLR(ep, F_NOLOG);
540 ep->l_win = NULL;
541 return (1);
545 * Log_setline --
546 * Reset the line to its original appearance.
548 * XXX
549 * There's a bug in this code due to our not logging cursor movements
550 * unless a change was made. If you do a change, move off the line,
551 * then move back on and do a 'U', the line will be restored to the way
552 * it was before the original change.
554 * PUBLIC: int log_setline __P((SCR *));
557 log_setline(SCR *sp)
559 EXF *ep;
560 LMARK lm;
561 MARK m;
562 db_recno_t lno;
563 u_char *p;
564 size_t size;
566 ep = sp->ep;
567 if (F_ISSET(ep, F_NOLOG)) {
568 msgq(sp, M_ERR,
569 "012|Logging not being performed, undo not possible");
570 return (1);
573 if (ep->l_cur == 1)
574 return (1);
576 if (ep->l_win && ep->l_win != sp->wp) {
577 ex_emsg(sp, NULL, EXM_LOCKED);
578 return 1;
580 ep->l_win = sp->wp;
582 F_SET(ep, F_NOLOG); /* Turn off logging. */
584 for (;;) {
585 --ep->l_cur;
586 if (vi_log_get(sp, &ep->l_cur, &size))
587 LOG_ERR;
588 #if defined(DEBUG) && 0
589 log_trace(sp, "log_setline", ep->l_cur, data.data);
590 #endif
591 switch (*(p = (u_char *)sp->wp->l_lp)) {
592 case LOG_CURSOR_INIT:
593 memmove(&m, p + sizeof(u_char), sizeof(MARK));
594 if (m.lno != sp->lno || ep->l_cur == 1) {
595 F_CLR(ep, F_NOLOG);
596 ep->l_win = NULL;
597 return (0);
599 break;
600 case LOG_CURSOR_END:
601 memmove(&m, p + sizeof(u_char), sizeof(MARK));
602 if (m.lno != sp->lno) {
603 ++ep->l_cur;
604 F_CLR(ep, F_NOLOG);
605 ep->l_win = NULL;
606 return (0);
608 break;
609 case LOG_LINE_APPEND_F:
610 case LOG_LINE_DELETE_B:
611 case LOG_LINE_RESET_F:
612 break;
613 case LOG_LINE_RESET_B:
614 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
615 if (lno == sp->lno &&
616 db_set(sp, lno, (CHAR_T *)(p + CHAR_T_OFFSET),
617 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
618 goto err;
619 if (sp->rptlchange != lno) {
620 sp->rptlchange = lno;
621 ++sp->rptlines[L_CHANGED];
623 case LOG_MARK:
624 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
625 m.lno = lm.lno;
626 m.cno = lm.cno;
627 if (mark_set(sp, lm.name, &m, 0))
628 goto err;
629 break;
630 default:
631 abort();
635 err: F_CLR(ep, F_NOLOG);
636 ep->l_win = NULL;
637 return (1);
641 * Log_forward --
642 * Roll the log forward one operation.
644 * PUBLIC: int log_forward __P((SCR *, MARK *));
647 log_forward(SCR *sp, MARK *rp)
649 EXF *ep;
650 LMARK lm;
651 MARK m;
652 db_recno_t lno;
653 int didop;
654 u_char *p;
655 size_t size;
657 ep = sp->ep;
658 if (F_ISSET(ep, F_NOLOG)) {
659 msgq(sp, M_ERR,
660 "013|Logging not being performed, roll-forward not possible");
661 return (1);
664 if (ep->l_cur == ep->l_high) {
665 msgq(sp, M_BERR, "014|No changes to re-do");
666 return (1);
669 if (ep->l_win && ep->l_win != sp->wp) {
670 ex_emsg(sp, NULL, EXM_LOCKED);
671 return 1;
673 ep->l_win = sp->wp;
675 F_SET(ep, F_NOLOG); /* Turn off logging. */
677 for (didop = 0;;) {
678 ++ep->l_cur;
679 if (vi_log_get(sp, &ep->l_cur, &size))
680 LOG_ERR;
681 #if defined(DEBUG) && 0
682 log_trace(sp, "log_forward", ep->l_cur, data.data);
683 #endif
684 switch (*(p = (u_char *)sp->wp->l_lp)) {
685 case LOG_CURSOR_END:
686 if (didop) {
687 ++ep->l_cur;
688 memmove(rp, p + sizeof(u_char), sizeof(MARK));
689 F_CLR(ep, F_NOLOG);
690 ep->l_win = NULL;
691 return (0);
693 break;
694 case LOG_CURSOR_INIT:
695 break;
696 case LOG_LINE_APPEND_F:
697 didop = 1;
698 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
699 if (db_insert(sp, lno,
700 (CHAR_T *)(p + CHAR_T_OFFSET),
701 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
702 goto err;
703 ++sp->rptlines[L_ADDED];
704 break;
705 case LOG_LINE_DELETE_B:
706 didop = 1;
707 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
708 if (db_delete(sp, lno))
709 goto err;
710 ++sp->rptlines[L_DELETED];
711 break;
712 case LOG_LINE_RESET_B:
713 break;
714 case LOG_LINE_RESET_F:
715 didop = 1;
716 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
717 if (db_set(sp, lno,
718 (CHAR_T *)(p + CHAR_T_OFFSET),
719 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
720 goto err;
721 if (sp->rptlchange != lno) {
722 sp->rptlchange = lno;
723 ++sp->rptlines[L_CHANGED];
725 break;
726 case LOG_MARK:
727 didop = 1;
728 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
729 m.lno = lm.lno;
730 m.cno = lm.cno;
731 if (mark_set(sp, lm.name, &m, 0))
732 goto err;
733 break;
734 default:
735 abort();
739 err: F_CLR(ep, F_NOLOG);
740 ep->l_win = NULL;
741 return (1);
745 * log_err --
746 * Try and restart the log on failure, i.e. if we run out of memory.
748 static void
749 log_err(SCR *sp, const char *file, int line)
751 EXF *ep;
753 msgq(sp, M_SYSERR, "015|%s/%d: log put error", tail(file), line);
754 ep = sp->ep;
755 (void)ep->log->close(ep->log, DB_NOSYNC);
756 if (!log_init(sp, ep))
757 msgq(sp, M_ERR, "267|Log restarted");
760 #if defined(DEBUG) && 0
761 static void
762 log_trace(SCR *sp, const char *msg, db_recno_t rno, u_char *p)
764 LMARK lm;
765 MARK m;
766 db_recno_t lno;
768 switch (*p) {
769 case LOG_CURSOR_INIT:
770 memmove(&m, p + sizeof(u_char), sizeof(MARK));
771 vtrace(sp, "%lu: %s: C_INIT: %u/%u\n", rno, msg, m.lno, m.cno);
772 break;
773 case LOG_CURSOR_END:
774 memmove(&m, p + sizeof(u_char), sizeof(MARK));
775 vtrace(sp, "%lu: %s: C_END: %u/%u\n", rno, msg, m.lno, m.cno);
776 break;
777 case LOG_LINE_APPEND_F:
778 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
779 vtrace(sp, "%lu: %s: APPEND_F: %lu\n", rno, msg, lno);
780 break;
781 case LOG_LINE_APPEND_B:
782 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
783 vtrace(sp, "%lu: %s: APPEND_B: %lu\n", rno, msg, lno);
784 break;
785 case LOG_LINE_DELETE_F:
786 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
787 vtrace(sp, "%lu: %s: DELETE_F: %lu\n", rno, msg, lno);
788 break;
789 case LOG_LINE_DELETE_B:
790 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
791 vtrace(sp, "%lu: %s: DELETE_B: %lu\n", rno, msg, lno);
792 break;
793 case LOG_LINE_RESET_F:
794 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
795 vtrace(sp, "%lu: %s: RESET_F: %lu\n", rno, msg, lno);
796 break;
797 case LOG_LINE_RESET_B:
798 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
799 vtrace(sp, "%lu: %s: RESET_B: %lu\n", rno, msg, lno);
800 break;
801 case LOG_MARK:
802 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
803 vtrace(sp,
804 "%lu: %s: MARK: %u/%u\n", rno, msg, lm.lno, lm.cno);
805 break;
806 default:
807 abort();
810 #endif