remove generated compile, depcomp, missing and mkinstalldirs
[nvi.git] / common / log.c
blob7071873230e3e4eff35be7dc41526688c70e7ad2
1 /*-
2 * Copyright (c) 1992, 1993, 1994
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 1992, 1993, 1994, 1995, 1996
5 * Keith Bostic. All rights reserved.
7 * See the LICENSE file for redistribution information.
8 */
10 #include "config.h"
12 #ifndef lint
13 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 $";
14 #endif /* not lint */
16 #include <sys/types.h>
17 #include <sys/queue.h>
18 #include <sys/stat.h>
20 #include <bitstring.h>
21 #include <errno.h>
22 #include <fcntl.h>
23 #include <limits.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
28 #include "common.h"
31 * The log consists of records, each containing a type byte and a variable
32 * length byte string, as follows:
34 * LOG_CURSOR_INIT MARK
35 * LOG_CURSOR_END MARK
36 * LOG_LINE_APPEND_F db_recno_t char *
37 * LOG_LINE_APPEND_B db_recno_t char *
38 * LOG_LINE_DELETE_F db_recno_t char *
39 * LOG_LINE_DELETE_B db_recno_t char *
40 * LOG_LINE_RESET_F db_recno_t char *
41 * LOG_LINE_RESET_B db_recno_t char *
42 * LOG_MARK LMARK
44 * We do before image physical logging. This means that the editor layer
45 * MAY NOT modify records in place, even if simply deleting or overwriting
46 * characters. Since the smallest unit of logging is a line, we're using
47 * up lots of space. This may eventually have to be reduced, probably by
48 * doing logical logging, which is a much cooler database phrase.
50 * The implementation of the historic vi 'u' command, using roll-forward and
51 * roll-back, is simple. Each set of changes has a LOG_CURSOR_INIT record,
52 * followed by a number of other records, followed by a LOG_CURSOR_END record.
53 * LOG_LINE_RESET records come in pairs. The first is a LOG_LINE_RESET_B
54 * record, and is the line before the change. The second is LOG_LINE_RESET_F,
55 * and is the line after the change. Roll-back is done by backing up to the
56 * first LOG_CURSOR_INIT record before a change. Roll-forward is done in a
57 * similar fashion.
59 * The 'U' command is implemented by rolling backward to a LOG_CURSOR_END
60 * record for a line different from the current one. It should be noted that
61 * this means that a subsequent 'u' command will make a change based on the
62 * new position of the log's cursor. This is okay, and, in fact, historic vi
63 * behaved that way.
66 static int vi_log_get __P((SCR *sp, db_recno_t *lnop, size_t *size));
67 static int log_cursor1 __P((SCR *, int));
68 static void log_err __P((SCR *, char *, int));
69 #if defined(DEBUG) && 0
70 static void log_trace __P((SCR *, char *, db_recno_t, u_char *));
71 #endif
73 /* Try and restart the log on failure, i.e. if we run out of memory. */
74 #define LOG_ERR { \
75 log_err(sp, __FILE__, __LINE__); \
76 return (1); \
79 /* offset of CHAR_T string in log needs to be aligned on some systems
80 * because it is passed to db_set as a string
82 typedef struct {
83 char data[sizeof(u_char) /* type */ + sizeof(db_recno_t)];
84 CHAR_T str[1];
85 } log_t;
86 #define CHAR_T_OFFSET ((char *)(((log_t*)0)->str) - (char *)0)
89 * log_init --
90 * Initialize the logging subsystem.
92 * PUBLIC: int log_init __P((SCR *, EXF *));
94 int
95 log_init(SCR *sp, EXF *ep)
98 * !!!
99 * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER.
101 * Initialize the buffer. The logging subsystem has its own
102 * buffers because the global ones are almost by definition
103 * going to be in use when the log runs.
105 sp->wp->l_lp = NULL;
106 sp->wp->l_len = 0;
107 ep->l_cursor.lno = 1; /* XXX Any valid recno. */
108 ep->l_cursor.cno = 0;
109 ep->l_high = ep->l_cur = 1;
111 if (db_create(&ep->log, 0, 0) != 0 ||
112 db_open(ep->log, NULL, DB_RECNO,
113 DB_CREATE | VI_DB_THREAD, S_IRUSR | S_IWUSR) != 0) {
114 msgq(sp, M_SYSERR, "009|Log file");
115 F_SET(ep, F_NOLOG);
116 return (1);
119 ep->l_win = NULL;
120 /*LOCK_INIT(sp->wp, ep);*/
122 return (0);
126 * log_end --
127 * Close the logging subsystem.
129 * PUBLIC: int log_end __P((SCR *, EXF *));
132 log_end(SCR *sp, EXF *ep)
135 * !!!
136 * ep MAY NOT BE THE SAME AS sp->ep, DON'T USE THE LATTER.
138 /*LOCK_END(sp->wp, ep);*/
139 if (ep->log != NULL) {
140 (void)(ep->log->close)(ep->log, DB_NOSYNC);
141 ep->log = NULL;
143 if (sp->wp->l_lp != NULL) {
144 free(sp->wp->l_lp);
145 sp->wp->l_lp = NULL;
147 sp->wp->l_len = 0;
148 ep->l_cursor.lno = 1; /* XXX Any valid recno. */
149 ep->l_cursor.cno = 0;
150 ep->l_high = ep->l_cur = 1;
151 return (0);
155 * log_cursor --
156 * Log the current cursor position, starting an event.
158 * PUBLIC: int log_cursor __P((SCR *));
161 log_cursor(SCR *sp)
163 EXF *ep;
165 ep = sp->ep;
166 if (F_ISSET(ep, F_NOLOG))
167 return (0);
170 * If any changes were made since the last cursor init,
171 * put out the ending cursor record.
173 if (ep->l_cursor.lno == OOBLNO) {
174 if (ep->l_win && ep->l_win != sp->wp)
175 return 0;
176 ep->l_cursor.lno = sp->lno;
177 ep->l_cursor.cno = sp->cno;
178 ep->l_win = NULL;
179 return (log_cursor1(sp, LOG_CURSOR_END));
181 ep->l_cursor.lno = sp->lno;
182 ep->l_cursor.cno = sp->cno;
183 return (0);
187 * log_cursor1 --
188 * Actually push a cursor record out.
190 static int
191 log_cursor1(SCR *sp, int type)
193 DBT data, key;
194 EXF *ep;
196 ep = sp->ep;
199 if (type == LOG_CURSOR_INIT &&
200 LOCK_TRY(sp->wp, ep))
201 return 1;
204 BINC_RETC(sp, sp->wp->l_lp, sp->wp->l_len, sizeof(u_char) + sizeof(MARK));
205 sp->wp->l_lp[0] = type;
206 memmove(sp->wp->l_lp + sizeof(u_char), &ep->l_cursor, sizeof(MARK));
208 memset(&key, 0, sizeof(key));
209 key.data = &ep->l_cur;
210 key.size = sizeof(db_recno_t);
211 memset(&data, 0, sizeof(data));
212 data.data = sp->wp->l_lp;
213 data.size = sizeof(u_char) + sizeof(MARK);
214 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
215 LOG_ERR;
217 #if defined(DEBUG) && 0
218 vtrace(sp, "%lu: %s: %u/%u\n", ep->l_cur,
219 type == LOG_CURSOR_INIT ? "log_cursor_init" : "log_cursor_end",
220 sp->lno, sp->cno);
221 #endif
222 /* Reset high water mark. */
223 ep->l_high = ++ep->l_cur;
226 if (type == LOG_CURSOR_END)
227 LOCK_UNLOCK(sp->wp, ep);
229 return (0);
233 * log_line --
234 * Log a line change.
236 * PUBLIC: int log_line __P((SCR *, db_recno_t, u_int));
239 log_line(SCR *sp, db_recno_t lno, u_int action)
241 DBT data, key;
242 EXF *ep;
243 size_t len;
244 CHAR_T *lp;
245 db_recno_t lcur;
247 ep = sp->ep;
248 if (F_ISSET(ep, F_NOLOG))
249 return (0);
252 * XXX
254 * Kluge for vi. Clear the EXF undo flag so that the
255 * next 'u' command does a roll-back, regardless.
257 F_CLR(ep, F_UNDO);
259 /* Put out one initial cursor record per set of changes. */
260 if (ep->l_cursor.lno != OOBLNO) {
261 if (log_cursor1(sp, LOG_CURSOR_INIT))
262 return (1);
263 ep->l_cursor.lno = OOBLNO;
264 ep->l_win = sp->wp;
265 } /*else if (ep->l_win != sp->wp) {
266 printf("log_line own: %p, this: %p\n", ep->l_win, sp->wp);
267 return 1;
270 switch (action) {
271 /* newly added for DB4 logging */
272 case LOG_LINE_APPEND_B:
273 case LOG_LINE_DELETE_F:
274 return 0;
278 * Put out the changes. If it's a LOG_LINE_RESET_B call, it's a
279 * special case, avoid the caches. Also, if it fails and it's
280 * line 1, it just means that the user started with an empty file,
281 * so fake an empty length line.
283 if (action == LOG_LINE_RESET_B) {
284 if (db_get(sp, lno, DBG_NOCACHE, &lp, &len)) {
285 static CHAR_T nul = 0;
286 if (lno != 1) {
287 db_err(sp, lno);
288 return (1);
290 len = 0;
291 lp = &nul;
293 } else
294 if (db_get(sp, lno, DBG_FATAL, &lp, &len))
295 return (1);
296 BINC_RETC(sp,
297 sp->wp->l_lp, sp->wp->l_len,
298 len * sizeof(CHAR_T) + CHAR_T_OFFSET);
299 sp->wp->l_lp[0] = action;
300 memmove(sp->wp->l_lp + sizeof(u_char), &lno, sizeof(db_recno_t));
301 MEMMOVEW(sp->wp->l_lp + CHAR_T_OFFSET, lp, len);
303 lcur = ep->l_cur;
304 memset(&key, 0, sizeof(key));
305 key.data = &lcur;
306 key.size = sizeof(db_recno_t);
307 memset(&data, 0, sizeof(data));
308 data.data = sp->wp->l_lp;
309 data.size = len * sizeof(CHAR_T) + CHAR_T_OFFSET;
310 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
311 LOG_ERR;
313 #if defined(DEBUG) && 0
314 switch (action) {
315 case LOG_LINE_APPEND_F:
316 vtrace(sp, "%u: log_line: append_f: %lu {%u}\n",
317 ep->l_cur, lno, len);
318 break;
319 case LOG_LINE_APPEND_B:
320 vtrace(sp, "%u: log_line: append_b: %lu {%u}\n",
321 ep->l_cur, lno, len);
322 break;
323 case LOG_LINE_DELETE_F:
324 vtrace(sp, "%lu: log_line: delete_f: %lu {%u}\n",
325 ep->l_cur, lno, len);
326 break;
327 case LOG_LINE_DELETE_B:
328 vtrace(sp, "%lu: log_line: delete_b: %lu {%u}\n",
329 ep->l_cur, lno, len);
330 break;
331 case LOG_LINE_RESET_F:
332 vtrace(sp, "%lu: log_line: reset_f: %lu {%u}\n",
333 ep->l_cur, lno, len);
334 break;
335 case LOG_LINE_RESET_B:
336 vtrace(sp, "%lu: log_line: reset_b: %lu {%u}\n",
337 ep->l_cur, lno, len);
338 break;
340 #endif
341 /* Reset high water mark. */
342 ep->l_high = ++ep->l_cur;
344 return (0);
348 * log_mark --
349 * Log a mark position. For the log to work, we assume that there
350 * aren't any operations that just put out a log record -- this
351 * would mean that undo operations would only reset marks, and not
352 * cause any other change.
354 * PUBLIC: int log_mark __P((SCR *, LMARK *));
357 log_mark(SCR *sp, LMARK *lmp)
359 DBT data, key;
360 EXF *ep;
362 ep = sp->ep;
363 if (F_ISSET(ep, F_NOLOG))
364 return (0);
366 /* Put out one initial cursor record per set of changes. */
367 if (ep->l_cursor.lno != OOBLNO) {
368 if (log_cursor1(sp, LOG_CURSOR_INIT))
369 return (1);
370 ep->l_cursor.lno = OOBLNO;
371 ep->l_win = sp->wp;
374 BINC_RETC(sp, sp->wp->l_lp,
375 sp->wp->l_len, sizeof(u_char) + sizeof(LMARK));
376 sp->wp->l_lp[0] = LOG_MARK;
377 memmove(sp->wp->l_lp + sizeof(u_char), lmp, sizeof(LMARK));
379 memset(&key, 0, sizeof(key));
380 key.data = &ep->l_cur;
381 key.size = sizeof(db_recno_t);
382 memset(&data, 0, sizeof(data));
383 data.data = sp->wp->l_lp;
384 data.size = sizeof(u_char) + sizeof(LMARK);
385 if (ep->log->put(ep->log, NULL, &key, &data, 0) == -1)
386 LOG_ERR;
388 #if defined(DEBUG) && 0
389 vtrace(sp, "%lu: mark %c: %lu/%u\n",
390 ep->l_cur, lmp->name, lmp->lno, lmp->cno);
391 #endif
392 /* Reset high water mark. */
393 ep->l_high = ++ep->l_cur;
394 return (0);
398 * vi_log_get --
399 * Get a line from the log in log buffer.
401 static int
402 vi_log_get(SCR *sp, db_recno_t *lnop, size_t *size)
404 DBT key, data;
405 size_t nlen;
406 EXF *ep;
408 ep = sp->ep;
410 nlen = 1024;
411 retry:
412 BINC_RETC(sp, sp->wp->l_lp, sp->wp->l_len, nlen);
414 memset(&key, 0, sizeof(key));
415 key.data = lnop; /* Initialize db request. */
416 key.size = sizeof(db_recno_t);
417 memset(&data, 0, sizeof(data));
418 data.data = sp->wp->l_lp;
419 data.ulen = sp->wp->l_len;
420 data.flags = DB_DBT_USERMEM;
421 switch (ep->log->get(ep->log, NULL, &key, &data, 0)) {
422 case ENOMEM:
423 nlen = data.size;
424 goto retry;
425 case 0:
426 *size = data.size;
427 return 0;
428 default:
429 return 1;
434 * Log_backward --
435 * Roll the log backward one operation.
437 * PUBLIC: int log_backward __P((SCR *, MARK *));
440 log_backward(SCR *sp, MARK *rp)
442 EXF *ep;
443 LMARK lm;
444 MARK m;
445 db_recno_t lno;
446 int didop;
447 u_char *p;
448 size_t size;
450 ep = sp->ep;
451 if (F_ISSET(ep, F_NOLOG)) {
452 msgq(sp, M_ERR,
453 "010|Logging not being performed, undo not possible");
454 return (1);
457 if (ep->l_cur == 1) {
458 msgq(sp, M_BERR, "011|No changes to undo");
459 return (1);
462 if (ep->l_win && ep->l_win != sp->wp) {
463 ex_emsg(sp, NULL, EXM_LOCKED);
464 return 1;
466 ep->l_win = sp->wp;
469 F_SET(ep, F_NOLOG); /* Turn off logging. */
471 for (didop = 0;;) {
472 --ep->l_cur;
473 if (vi_log_get(sp, &ep->l_cur, &size))
474 LOG_ERR;
475 #if defined(DEBUG) && 0
476 log_trace(sp, "log_backward", ep->l_cur, data.data);
477 #endif
478 switch (*(p = (u_char *)sp->wp->l_lp)) {
479 case LOG_CURSOR_INIT:
480 if (didop) {
481 memmove(rp, p + sizeof(u_char), sizeof(MARK));
482 F_CLR(ep, F_NOLOG);
483 ep->l_win = NULL;
484 return (0);
486 break;
487 case LOG_CURSOR_END:
488 break;
489 case LOG_LINE_APPEND_F:
490 didop = 1;
491 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
492 if (db_delete(sp, lno))
493 goto err;
494 ++sp->rptlines[L_DELETED];
495 break;
496 case LOG_LINE_DELETE_B:
497 didop = 1;
498 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
499 if (db_insert(sp, lno,
500 (CHAR_T *)(p + CHAR_T_OFFSET),
501 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
502 goto err;
503 ++sp->rptlines[L_ADDED];
504 break;
505 case LOG_LINE_RESET_F:
506 break;
507 case LOG_LINE_RESET_B:
508 didop = 1;
509 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
510 if (db_set(sp, lno,
511 (CHAR_T *)(p + CHAR_T_OFFSET),
512 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
513 goto err;
514 if (sp->rptlchange != lno) {
515 sp->rptlchange = lno;
516 ++sp->rptlines[L_CHANGED];
518 break;
519 case LOG_MARK:
520 didop = 1;
521 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
522 m.lno = lm.lno;
523 m.cno = lm.cno;
524 if (mark_set(sp, lm.name, &m, 0))
525 goto err;
526 break;
527 default:
528 abort();
532 err: F_CLR(ep, F_NOLOG);
533 ep->l_win = NULL;
534 return (1);
538 * Log_setline --
539 * Reset the line to its original appearance.
541 * XXX
542 * There's a bug in this code due to our not logging cursor movements
543 * unless a change was made. If you do a change, move off the line,
544 * then move back on and do a 'U', the line will be restored to the way
545 * it was before the original change.
547 * PUBLIC: int log_setline __P((SCR *));
550 log_setline(SCR *sp)
552 EXF *ep;
553 LMARK lm;
554 MARK m;
555 db_recno_t lno;
556 u_char *p;
557 size_t size;
559 ep = sp->ep;
560 if (F_ISSET(ep, F_NOLOG)) {
561 msgq(sp, M_ERR,
562 "012|Logging not being performed, undo not possible");
563 return (1);
566 if (ep->l_cur == 1)
567 return (1);
569 if (ep->l_win && ep->l_win != sp->wp) {
570 ex_emsg(sp, NULL, EXM_LOCKED);
571 return 1;
573 ep->l_win = sp->wp;
575 F_SET(ep, F_NOLOG); /* Turn off logging. */
577 for (;;) {
578 --ep->l_cur;
579 if (vi_log_get(sp, &ep->l_cur, &size))
580 LOG_ERR;
581 #if defined(DEBUG) && 0
582 log_trace(sp, "log_setline", ep->l_cur, data.data);
583 #endif
584 switch (*(p = (u_char *)sp->wp->l_lp)) {
585 case LOG_CURSOR_INIT:
586 memmove(&m, p + sizeof(u_char), sizeof(MARK));
587 if (m.lno != sp->lno || ep->l_cur == 1) {
588 F_CLR(ep, F_NOLOG);
589 ep->l_win = NULL;
590 return (0);
592 break;
593 case LOG_CURSOR_END:
594 memmove(&m, p + sizeof(u_char), sizeof(MARK));
595 if (m.lno != sp->lno) {
596 ++ep->l_cur;
597 F_CLR(ep, F_NOLOG);
598 ep->l_win = NULL;
599 return (0);
601 break;
602 case LOG_LINE_APPEND_F:
603 case LOG_LINE_DELETE_B:
604 case LOG_LINE_RESET_F:
605 break;
606 case LOG_LINE_RESET_B:
607 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
608 if (lno == sp->lno &&
609 db_set(sp, lno, (CHAR_T *)(p + CHAR_T_OFFSET),
610 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
611 goto err;
612 if (sp->rptlchange != lno) {
613 sp->rptlchange = lno;
614 ++sp->rptlines[L_CHANGED];
616 case LOG_MARK:
617 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
618 m.lno = lm.lno;
619 m.cno = lm.cno;
620 if (mark_set(sp, lm.name, &m, 0))
621 goto err;
622 break;
623 default:
624 abort();
628 err: F_CLR(ep, F_NOLOG);
629 ep->l_win = NULL;
630 return (1);
634 * Log_forward --
635 * Roll the log forward one operation.
637 * PUBLIC: int log_forward __P((SCR *, MARK *));
640 log_forward(SCR *sp, MARK *rp)
642 EXF *ep;
643 LMARK lm;
644 MARK m;
645 db_recno_t lno;
646 int didop;
647 u_char *p;
648 size_t size;
650 ep = sp->ep;
651 if (F_ISSET(ep, F_NOLOG)) {
652 msgq(sp, M_ERR,
653 "013|Logging not being performed, roll-forward not possible");
654 return (1);
657 if (ep->l_cur == ep->l_high) {
658 msgq(sp, M_BERR, "014|No changes to re-do");
659 return (1);
662 if (ep->l_win && ep->l_win != sp->wp) {
663 ex_emsg(sp, NULL, EXM_LOCKED);
664 return 1;
666 ep->l_win = sp->wp;
668 F_SET(ep, F_NOLOG); /* Turn off logging. */
670 for (didop = 0;;) {
671 ++ep->l_cur;
672 if (vi_log_get(sp, &ep->l_cur, &size))
673 LOG_ERR;
674 #if defined(DEBUG) && 0
675 log_trace(sp, "log_forward", ep->l_cur, data.data);
676 #endif
677 switch (*(p = (u_char *)sp->wp->l_lp)) {
678 case LOG_CURSOR_END:
679 if (didop) {
680 ++ep->l_cur;
681 memmove(rp, p + sizeof(u_char), sizeof(MARK));
682 F_CLR(ep, F_NOLOG);
683 ep->l_win = NULL;
684 return (0);
686 break;
687 case LOG_CURSOR_INIT:
688 break;
689 case LOG_LINE_APPEND_F:
690 didop = 1;
691 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
692 if (db_insert(sp, lno,
693 (CHAR_T *)(p + CHAR_T_OFFSET),
694 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
695 goto err;
696 ++sp->rptlines[L_ADDED];
697 break;
698 case LOG_LINE_DELETE_B:
699 didop = 1;
700 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
701 if (db_delete(sp, lno))
702 goto err;
703 ++sp->rptlines[L_DELETED];
704 break;
705 case LOG_LINE_RESET_B:
706 break;
707 case LOG_LINE_RESET_F:
708 didop = 1;
709 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
710 if (db_set(sp, lno,
711 (CHAR_T *)(p + CHAR_T_OFFSET),
712 (size - CHAR_T_OFFSET) / sizeof(CHAR_T)))
713 goto err;
714 if (sp->rptlchange != lno) {
715 sp->rptlchange = lno;
716 ++sp->rptlines[L_CHANGED];
718 break;
719 case LOG_MARK:
720 didop = 1;
721 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
722 m.lno = lm.lno;
723 m.cno = lm.cno;
724 if (mark_set(sp, lm.name, &m, 0))
725 goto err;
726 break;
727 default:
728 abort();
732 err: F_CLR(ep, F_NOLOG);
733 ep->l_win = NULL;
734 return (1);
738 * log_err --
739 * Try and restart the log on failure, i.e. if we run out of memory.
741 static void
742 log_err(SCR *sp, char *file, int line)
744 EXF *ep;
746 msgq(sp, M_SYSERR, "015|%s/%d: log put error", tail(file), line);
747 ep = sp->ep;
748 (void)ep->log->close(ep->log, DB_NOSYNC);
749 if (!log_init(sp, ep))
750 msgq(sp, M_ERR, "267|Log restarted");
753 #if defined(DEBUG) && 0
754 static void
755 log_trace(sp, msg, rno, p)
756 SCR *sp;
757 char *msg;
758 db_recno_t rno;
759 u_char *p;
761 LMARK lm;
762 MARK m;
763 db_recno_t lno;
765 switch (*p) {
766 case LOG_CURSOR_INIT:
767 memmove(&m, p + sizeof(u_char), sizeof(MARK));
768 vtrace(sp, "%lu: %s: C_INIT: %u/%u\n", rno, msg, m.lno, m.cno);
769 break;
770 case LOG_CURSOR_END:
771 memmove(&m, p + sizeof(u_char), sizeof(MARK));
772 vtrace(sp, "%lu: %s: C_END: %u/%u\n", rno, msg, m.lno, m.cno);
773 break;
774 case LOG_LINE_APPEND_F:
775 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
776 vtrace(sp, "%lu: %s: APPEND_F: %lu\n", rno, msg, lno);
777 break;
778 case LOG_LINE_APPEND_B:
779 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
780 vtrace(sp, "%lu: %s: APPEND_B: %lu\n", rno, msg, lno);
781 break;
782 case LOG_LINE_DELETE_F:
783 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
784 vtrace(sp, "%lu: %s: DELETE_F: %lu\n", rno, msg, lno);
785 break;
786 case LOG_LINE_DELETE_B:
787 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
788 vtrace(sp, "%lu: %s: DELETE_B: %lu\n", rno, msg, lno);
789 break;
790 case LOG_LINE_RESET_F:
791 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
792 vtrace(sp, "%lu: %s: RESET_F: %lu\n", rno, msg, lno);
793 break;
794 case LOG_LINE_RESET_B:
795 memmove(&lno, p + sizeof(u_char), sizeof(db_recno_t));
796 vtrace(sp, "%lu: %s: RESET_B: %lu\n", rno, msg, lno);
797 break;
798 case LOG_MARK:
799 memmove(&lm, p + sizeof(u_char), sizeof(LMARK));
800 vtrace(sp,
801 "%lu: %s: MARK: %u/%u\n", rno, msg, lm.lno, lm.cno);
802 break;
803 default:
804 abort();
807 #endif