/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 1996, 1997, 1998
* Sleepycat Software. All rights reserved.
*/
#include "config.h"
#ifndef lint
#endif /* not lint */
#ifndef NO_SYSTEM_INCLUDES
#include <errno.h>
#include <string.h>
#include <unistd.h>
#endif
#include "db_int.h"
#include "shqueue.h"
#include "db_page.h"
#include "log.h"
#include "hash.h"
#include "common_ext.h"
/*
* log_get --
* Get a log record.
*/
int
{
int ret;
/* Validate arguments. */
}
/*
* If we get one of the log's header records, repeat the operation.
* This assumes that applications don't ever request the log header
* records by LSN, but that seems reasonable to me.
*/
switch (flags) {
case DB_FIRST:
break;
case DB_LAST:
break;
}
}
return (ret);
}
/*
* __log_get --
* Get a log record; internal version.
*
* PUBLIC: int __log_get __P((DB_LOG *, DB_LSN *, DBT *, u_int32_t, int));
*/
int
int silent;
{
const char *fail;
void *p, *shortp;
switch (flags) {
case DB_CHECKPOINT:
if (IS_ZERO_LSN(nlsn)) {
"log_get: unable to find checkpoint record: no checkpoint set.");
goto err2;
}
break;
case DB_NEXT: /* Next log record. */
if (!IS_ZERO_LSN(nlsn)) {
/* Increment the cursor by the cursor record size. */
break;
}
/* FALLTHROUGH */
case DB_FIRST: /* Find the first log record. */
/* Find the first log file. */
goto err2;
/*
* We may have only entered records in the buffer, and not
* yet written a log file. If no log files were found and
* there's anything in the buffer, it belongs to file 1.
*/
if (cnt == 0)
cnt = 1;
break;
case DB_CURRENT: /* Current log record. */
break;
case DB_PREV: /* Previous log record. */
if (!IS_ZERO_LSN(nlsn)) {
/* If at start-of-file, move to the previous file. */
return (DB_NOTFOUND);
} else
break;
}
/* FALLTHROUGH */
case DB_LAST: /* Last log record. */
break;
case DB_SET: /* Set log record. */
break;
}
/* Return 1 if the request is past end-of-file. */
return (DB_NOTFOUND);
/* If we've switched files, discard the current fd. */
}
/* If the entire record is in the in-memory buffer, copy it out. */
/* Copy the header. */
/* Copy the record. */
goto err1;
goto cksum;
}
/* Acquire a file descriptor. */
goto err1;
}
}
/* Seek to the header offset and read the header. */
if ((ret =
fail = "seek";
goto err1;
}
fail = "read";
goto err1;
}
else {
/* If read returns EOF, try the next file. */
if (nr == 0) {
goto corrupt;
/* Move to the next file. */
goto retry;
}
/*
* If read returns a short count the rest of the record has
* to be in the in-memory buffer.
*/
goto corrupt;
/* Get the rest of the header from the in-memory buffer. */
}
/*
* Check for buffers of 0's, that's what we usually see during
* recovery, although it's certainly not something on which we
* can depend.
*/
goto corrupt;
/* If we've already moved to the in-memory buffer, fill from there. */
goto corrupt;
goto err1;
goto cksum;
}
/*
* Allocate temporary memory to hold the record.
*
* XXX
* We're calling malloc(3) with a region locked. This isn't
* a good idea.
*/
goto err1;
/*
* Read the record into the buffer. If read returns a short count,
* there was an error or the rest of the record is in the in-memory
* buffer. Note, the information may be garbage if we're in recovery,
* so don't read past the end of the buffer's memory.
*/
fail = "read";
goto err1;
}
goto corrupt;
goto corrupt;
/* Get the rest of the record from the in-memory buffer. */
}
/* Copy the record into the user's DBT. */
goto err1;
if (!silent)
goto corrupt;
}
/* Update the cursor and the return lsn. */
return (0);
corrupt:/*
* This is the catchall -- for some reason we didn't find enough
* information or it wasn't reasonable information, and it wasn't
* because a system call failed.
*/
fail = "read";
else
return (ret);
}