xapian-core  2.0.0
databasehelpers.cc
Go to the documentation of this file.
1 
4 /* Copyright 2002-2020 Olly Betts
5  * Copyright 2008 Lemur Consulting Ltd
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of the
10  * License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, see
19  * <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <config.h>
23 
24 #include "databasehelpers.h"
25 
26 #include "backends.h"
27 
28 #include "glass/glass_defs.h"
29 #include "honey/honey_defs.h"
30 
31 #include "io_utils.h"
32 #include "omassert.h"
33 #include "posixy_wrapper.h"
34 
35 #include <algorithm>
36 #include <cstring>
37 #include <string>
38 #include <sys/types.h>
39 #include "safesysstat.h"
40 #include "safeunistd.h"
41 
42 using namespace std;
43 
44 static int
46 {
47 #if defined XAPIAN_HAS_GLASS_BACKEND || \
48  defined XAPIAN_HAS_HONEY_BACKEND
49  char magic_buf[14];
50  // FIXME: Don't duplicate magic check here...
51  if (io_read(fd, magic_buf, 14) == 14 &&
52  lseek(fd, pos, SEEK_SET) == pos &&
53  memcmp(magic_buf, "\x0f\x0dXapian ", 9) == 0) {
54  switch (magic_buf[9]) {
55 #ifdef XAPIAN_HAS_GLASS_BACKEND
56  case 'G':
57  if (memcmp(magic_buf + 10, "lass", 4) == 0) {
58  return BACKEND_GLASS;
59  }
60  break;
61 #endif
62 #ifdef XAPIAN_HAS_HONEY_BACKEND
63  case 'H':
64  if (memcmp(magic_buf + 10, "oney", 4) == 0) {
65  return BACKEND_HONEY;
66  }
67  break;
68 #endif
69  }
70  return BACKEND_UNKNOWN;
71  }
72 #else
73  (void)fd;
74 #endif
75  return BACKEND_UNKNOWN;
76 }
77 
78 int
80 {
81  off_t pos = lseek(fd, 0, SEEK_CUR);
82  if (pos < 0) {
83  return BACKEND_UNKNOWN;
84  }
85  return test_if_single_file_db_(fd, pos);
86 }
87 
88 int
89 test_if_single_file_db(const struct stat& sb,
90  const string& path,
91  int* fd_ptr)
92 {
93  Assert(fd_ptr);
94 #if defined XAPIAN_HAS_GLASS_BACKEND || \
95  defined XAPIAN_HAS_HONEY_BACKEND
96  if (!S_ISREG(sb.st_mode)) return BACKEND_UNKNOWN;
97  // Look at the size as a clue - if it's less than both GLASS_MIN_BLOCKSIZE
98  // and HONEY_MIN_DB_SIZE then it's not a single-file glass or honey
99  // database. For a larger file, we peek at the start of the file to
100  // determine what it is.
101  if (sb.st_size < min(GLASS_MIN_BLOCKSIZE, HONEY_MIN_DB_SIZE))
102  return BACKEND_UNKNOWN;
103  int fd = posixy_open(path.c_str(), O_RDONLY|O_BINARY);
104  if (fd != -1) {
105  int result = test_if_single_file_db_(fd, off_t{0});
106  if (result != BACKEND_UNKNOWN) {
107  *fd_ptr = fd;
108  } else {
109  ::close(fd);
110  }
111  return result;
112  }
113 #else
114  (void)sb;
115  (void)path;
116  (void)fd_ptr;
117 #endif
118  return BACKEND_UNKNOWN;
119 }
BACKEND_* constants.
@ BACKEND_GLASS
Definition: backends.h:29
@ BACKEND_UNKNOWN
Definition: backends.h:26
@ BACKEND_HONEY
Definition: backends.h:30
int test_if_single_file_db(int fd)
Probe if a file descriptor is a single-file database.
static int test_if_single_file_db_(int fd, off_t pos)
Helper functions for database handling.
Xapian::termpos pos
int close(FD &fd)
Definition: fd.h:63
Definitions, types, etc for use inside glass.
#define GLASS_MIN_BLOCKSIZE
Minimum B-tree block size.
Definition: glass_defs.h:33
Definitions, types, etc for use inside honey.
#define HONEY_MIN_DB_SIZE
Minimum size to pad a honey table to.
Definition: honey_defs.h:36
size_t io_read(int fd, char *p, size_t n, size_t min)
Read n bytes (or until EOF) into block pointed to by p from file descriptor fd.
Definition: io_utils.cc:241
Wrappers for low-level POSIX I/O routines.
Various assertion macros.
#define Assert(COND)
Definition: omassert.h:122
Provides wrappers with POSIXy semantics.
#define posixy_open
#define O_BINARY
Definition: safefcntl.h:80
include <sys/stat.h> with portability enhancements
#define S_ISREG(ST_MODE)
Definition: safesysstat.h:59
<unistd.h>, but with compat.