Jason Tang jtang@tresys.com
This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Definition in file db.cc.
#include <config.h>
#include "sefs_internal.hh"
#include <sefs/db.hh>
#include <sefs/filesystem.hh>
#include <sefs/entry.hh>
#include <apol/util.h>
#include <sqlite3.h>
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
Go to the source code of this file.
Classes | |
| struct | db_callback_arg |
| struct | db_query_arg |
| struct | strindex |
| class | db_convert |
Defines | |
| #define | DB_MAX_VERSION "2" |
| #define | DB_SCHEMA_NONMLS |
| #define | DB_SCHEMA_MLS |
Functions | |
| sefs_context_node * | db_get_context (sefs_db *db, const char *user, const char *role, const char *type, const char *range) throw (std::bad_alloc) |
| sefs_entry * | db_get_entry (sefs_db *db, const struct sefs_context_node *node, uint32_t objClass, const char *path, ino64_t inode, const char *dev) throw (std::bad_alloc) |
| int | db_copy_schema (void *arg, int argc __attribute__((unused)), char *argv[], char *column_names[] __attribute__((unused))) |
| Callback invoked when selecting names of tables from a database. | |
| int | db_copy_table (void *arg, int argc __attribute__((unused)), char *argv[], char *column_names[] __attribute__((unused))) |
| Callback invoked when selecting each row from a table. | |
| void | db_user_compare (sqlite3_context *context, int argc __attribute__((unused)), sqlite3_value **argv) |
| Callback invoked when selecting a user (for a sefs_query). | |
| void | db_role_compare (sqlite3_context *context, int argc __attribute__((unused)), sqlite3_value **argv) |
| Callback invoked when selecting a role (for a sefs_query). | |
| void | db_type_compare (sqlite3_context *context, int argc __attribute__((unused)), sqlite3_value **argv) |
| Callback invoked when selecting a type (for a sefs_query). | |
| void | db_range_compare (sqlite3_context *context, int argc __attribute__((unused)), sqlite3_value **argv) |
| Callback invoked when selecting a range (for a sefs_query). | |
| void | db_path_compare (sqlite3_context *context, int argc __attribute__((unused)), sqlite3_value **argv) |
| Callback invoked when selecting a path (for a sefs_query). | |
| void | db_dev_compare (sqlite3_context *context, int argc __attribute__((unused)), sqlite3_value **argv) |
| Callback invoked when selecting a device name (for a sefs_query). | |
| int | db_query_callback (void *arg, int argc, char *argv[], char *column_names[] __attribute__((unused))) |
| Callback invoked when selecting rows during a query. | |
| int | db_row_exist_callback (void *arg, int argc __attribute__((unused)), char **argv __attribute__((unused)), char **col_names __attribute__((unused))) |
| Callback invoked when checking if there exists any row with the given select parameters. | |
| int | db_ctime_callback (void *arg, int argc __attribute__((unused)), char **argv, char **col_names __attribute__((unused))) |
| Callback invoked when obtaining the ctime value from the database. | |
| int | db_count_callback (void *arg, int argc __attribute__((unused)), char **argv, char **column_names __attribute__((unused))) |
| Callback invoked to determine how many rows match a particular select statement. | |
| int | db_strindex_comp (const void *a, const void *b, void *arg __attribute__((unused))) |
| int | db_create_from_filesystem (sefs_fclist *fclist __attribute__((unused)), const sefs_entry *entry, void *arg) |
| int | db_upgrade_reinsert (void *arg, int argc, char *argv[], char *column_names[]) |
| Callback invoked while upgrading a libsefs database version 1 to version 2. | |
| sefs_fclist_t * | sefs_db_create_from_filesystem (sefs_filesystem_t *fs, sefs_callback_fn_t msg_callback, void *varg) |
| Allocate and return a new sefs database from the filesystem fs. | |
| sefs_fclist_t * | sefs_db_create_from_file (const char *filename, sefs_callback_fn_t msg_callback, void *varg) |
| Allocate and return a new sefs database, loading the entries from the saved database path. | |
| int | sefs_db_save (sefs_db_t *db, const char *filename) |
| Write a database to disk, overwriting any existing file. | |
| time_t | sefs_db_get_ctime (sefs_db_t *db) |
| Get the creation time of a sefs database. | |
| bool | sefs_db_is_db (const char *filename) |
| Determine if the given file is a valid sefs_db. | |
|
|
Definition at line 46 of file db.cc. Referenced by sefs_db::upgradeToDB2(). |
|
|
Value: "CREATE TABLE users (user_id INTEGER PRIMARY KEY, user_name varchar (24));" \ "CREATE TABLE roles (role_id INTEGER PRIMARY KEY, role_name varchar (24));" \ "CREATE TABLE types (type_id INTEGER PRIMARY KEY, type_name varchar (48));" \ "CREATE TABLE devs (dev_id INTEGER PRIMARY KEY, dev_name varchar (32));" \ "CREATE TABLE paths (path varchar (128) PRIMARY KEY, ino int(64), dev int, user int, role int, type int, range int, obj_class int, symlink_target varchar (128));" \ "CREATE TABLE info (key varchar, value varchar);" Definition at line 48 of file db.cc. Referenced by sefs_db::sefs_db(). |
|
|
Value: DB_SCHEMA_NONMLS \ "CREATE TABLE mls (mls_id INTEGER PRIMARY KEY, mls_range varchar (64));" Definition at line 56 of file db.cc. Referenced by sefs_db::sefs_db(). |
|
||||||||||||||||||||||||
|
Definition at line 61 of file db.cc. Referenced by db_query_callback(). 00063 {
00064 return db->getContext(user, role, type, range);
00065 }
|
|
||||||||||||||||||||||||||||
|
Definition at line 67 of file db.cc. Referenced by db_query_callback(). 00069 {
00070 return db->getEntry(node, objClass, path, inode, dev);
00071 }
|
|
||||||||||||||||||||
|
Callback invoked when selecting names of tables from a database.
Definition at line 101 of file db.cc. References db_callback_arg::db, and db_callback_arg::errmsg. Referenced by sefs_db::save(). 00102 {
00103 // argv[0] contains a SQL statement that, if executed against a
00104 // db, will create a table
00105 struct db_callback_arg *db = static_cast < struct db_callback_arg *>(arg);
00106 if (sqlite3_exec(db->db, argv[0], NULL, NULL, &(db->errmsg)) != SQLITE_OK)
00107 {
00108 return -1;
00109 }
00110 return 0;
00111 }
|
|
||||||||||||||||||||
|
Callback invoked when selecting each row from a table.
Definition at line 116 of file db.cc. References db_callback_arg::db, db_callback_arg::errmsg, db_callback_arg::source_db, and db_callback_arg::target_db. Referenced by sefs_db::save(). 00117 {
00118 // argv[0] contains the name of a table
00119 struct db_callback_arg *db = static_cast < struct db_callback_arg *>(arg);
00120 char *insert = NULL;
00121 if (asprintf(&insert, "INSERT INTO %s%s SELECT * FROM %s%s", db->target_db, argv[0], db->source_db, argv[0]) < 0)
00122 {
00123 db->errmsg = strdup(strerror(errno));
00124 return -1;
00125 }
00126 int rc = sqlite3_exec(db->db, insert, NULL, NULL, &(db->errmsg));
00127 free(insert);
00128 if (rc != SQLITE_OK)
00129 {
00130 return -1;
00131 }
00132 return 0;
00133 }
|
|
||||||||||||||||
|
Callback invoked when selecting a user (for a sefs_query).
Definition at line 138 of file db.cc. References query_str_compare(), db_query_arg::regex, db_query_arg::reuser, and db_query_arg::user. Referenced by sefs_db::runQueryMap(). 00139 {
00140 void *arg = sqlite3_user_data(context);
00141 struct db_query_arg *q = static_cast < struct db_query_arg *>(arg);
00142 assert(sqlite3_value_type(argv[0]) == SQLITE_TEXT);
00143 const char *text = reinterpret_cast < const char *>(sqlite3_value_text(argv[0]));
00144 bool retval = query_str_compare(text, q->user, q->reuser, q->regex);
00145 sqlite3_result_int(context, (retval ? 1 : 0));
00146 }
|
|
||||||||||||||||
|
Callback invoked when selecting a role (for a sefs_query).
Definition at line 151 of file db.cc. References query_str_compare(), db_query_arg::regex, db_query_arg::rerole, and db_query_arg::role. Referenced by sefs_db::runQueryMap(). 00152 {
00153 void *arg = sqlite3_user_data(context);
00154 struct db_query_arg *q = static_cast < struct db_query_arg *>(arg);
00155 assert(sqlite3_value_type(argv[0]) == SQLITE_TEXT);
00156 const char *text = reinterpret_cast < const char *>(sqlite3_value_text(argv[0]));
00157 bool retval = query_str_compare(text, q->role, q->rerole, q->regex);
00158 sqlite3_result_int(context, (retval ? 1 : 0));
00159 }
|
|
||||||||||||||||
|
Callback invoked when selecting a type (for a sefs_query).
Definition at line 164 of file db.cc. References apol_str_strcmp(), apol_vector_get_index(), db_query_arg::policy, query_str_compare(), db_query_arg::regex, db_query_arg::retype, db_query_arg::type, and db_query_arg::type_list. Referenced by sefs_db::runQueryMap(). 00165 {
00166 void *arg = sqlite3_user_data(context);
00167 struct db_query_arg *q = static_cast < struct db_query_arg *>(arg);
00168 assert(sqlite3_value_type(argv[0]) == SQLITE_TEXT);
00169 const char *text = reinterpret_cast < const char *>(sqlite3_value_text(argv[0]));
00170 bool retval;
00171 if (q->type_list != NULL)
00172 {
00173 assert(q->policy != NULL);
00174 size_t index;
00175 retval = (apol_vector_get_index(q->type_list, text, apol_str_strcmp, NULL, &index) >= 0);
00176 if (retval)
00177 {
00178 sqlite3_result_int(context, 1);
00179 return;
00180 }
00181 }
00182 retval = query_str_compare(text, q->type, q->retype, q->regex);
00183 sqlite3_result_int(context, (retval ? 1 : 0));
00184 }
|
|
||||||||||||||||
|
Callback invoked when selecting a range (for a sefs_query).
Definition at line 189 of file db.cc. References apol_mls_range_compare(), apol_mls_range_create_from_string(), apol_mls_range_destroy(), apol_mls_range_t, db_query_arg::apol_range, db_query_arg::policy, query_str_compare(), db_query_arg::range, db_query_arg::rangeMatch, db_query_arg::regex, and db_query_arg::rerange. Referenced by sefs_db::runQueryMap(). 00190 {
00191 void *arg = sqlite3_user_data(context);
00192 struct db_query_arg *q = static_cast < struct db_query_arg *>(arg);
00193 assert(sqlite3_value_type(argv[0]) == SQLITE_TEXT);
00194 const char *text = reinterpret_cast < const char *>(sqlite3_value_text(argv[0]));
00195 bool retval;
00196 if (q->apol_range == NULL)
00197 {
00198 retval = query_str_compare(text, q->range, q->rerange, q->regex);
00199 }
00200 else
00201 {
00202 assert(q->policy != NULL);
00203 apol_mls_range_t *db_range = apol_mls_range_create_from_string(q->policy, text);
00204 int ret;
00205 ret = apol_mls_range_compare(q->policy, q->apol_range, db_range, q->rangeMatch);
00206 apol_mls_range_destroy(&db_range);
00207 retval = (ret > 0);
00208 }
00209 sqlite3_result_int(context, (retval ? 1 : 0));
00210 }
|
|
||||||||||||||||
|
Callback invoked when selecting a path (for a sefs_query).
Definition at line 215 of file db.cc. References db_query_arg::path, query_str_compare(), db_query_arg::regex, and db_query_arg::repath. Referenced by sefs_db::runQueryMap(). 00216 {
00217 void *arg = sqlite3_user_data(context);
00218 struct db_query_arg *q = static_cast < struct db_query_arg *>(arg);
00219 assert(sqlite3_value_type(argv[0]) == SQLITE_TEXT);
00220 const char *text = reinterpret_cast < const char *>(sqlite3_value_text(argv[0]));
00221 bool retval = query_str_compare(text, q->path, q->repath, q->regex);
00222 sqlite3_result_int(context, (retval ? 1 : 0));
00223 }
|
|
||||||||||||||||
|
Callback invoked when selecting a device name (for a sefs_query).
Definition at line 228 of file db.cc. References db_query_arg::dev, query_str_compare(), db_query_arg::redev, and db_query_arg::regex. Referenced by sefs_db::runQueryMap(). 00229 {
00230 void *arg = sqlite3_user_data(context);
00231 struct db_query_arg *q = static_cast < struct db_query_arg *>(arg);
00232 assert(sqlite3_value_type(argv[0]) == SQLITE_TEXT);
00233 const char *text = reinterpret_cast < const char *>(sqlite3_value_text(argv[0]));
00234 bool retval = query_str_compare(text, q->dev, q->redev, q->regex);
00235 sqlite3_result_int(context, (retval ? 1 : 0));
00236 }
|
|
||||||||||||||||||||
|
Callback invoked when selecting rows during a query.
Definition at line 241 of file db.cc. References db_query_arg::aborted, db_query_arg::data, db_query_arg::db, db_get_context(), db_get_entry(), db_query_arg::db_is_mls, db_query_arg::fn, and db_query_arg::retval. Referenced by sefs_db::runQueryMap(). 00242 {
00243 struct db_query_arg *q = static_cast < struct db_query_arg *>(arg);
00244 assert(argc == (q->db_is_mls ? 9 : 8));
00245 char *path = argv[0];
00246 ino64_t ino = static_cast < ino64_t > (strtoul(argv[1], NULL, 10));
00247 char *dev = argv[2];
00248 char *user = argv[3];
00249 char *role = argv[4];
00250 char *type = argv[5];
00251 char *range, *objclass_str, *link_target;
00252
00253 if (q->db_is_mls)
00254 {
00255 range = argv[6];
00256 objclass_str = argv[7];
00257 link_target = argv[8];
00258 }
00259 else
00260 {
00261 range = NULL;
00262 objclass_str = argv[6];
00263 link_target = argv[7];
00264 }
00265 struct sefs_context_node *node = NULL;
00266 try
00267 {
00268 node = db_get_context(q->db, user, role, type, range);
00269 }
00270 catch(...)
00271 {
00272 return -1;
00273 }
00274
00275 uint32_t objClass = static_cast < uint32_t > (atoi(objclass_str));
00276 sefs_entry *entry = NULL;
00277 try
00278 {
00279 entry = db_get_entry(q->db, node, objClass, path, ino, dev);
00280 }
00281 catch(...)
00282 {
00283 return -1;
00284 }
00285
00286 // invoke real callback (not just the sqlite3 exec callback)
00287 q->retval = q->fn(q->db, entry, q->data);
00288 delete entry;
00289 if (q->retval < 0)
00290 {
00291 q->aborted = true;
00292 return -1;
00293 }
00294 return 0;
00295 }
|
|
||||||||||||||||||||
|
Callback invoked when checking if there exists any row with the given select parameters.
Definition at line 301 of file db.cc. Referenced by sefs_db::isMLS(), and sefs_db::sefs_db(). 00304 {
00305 bool *answer = static_cast < bool * >(arg);
00306 *answer = true;
00307 return 0;
00308 }
|
|
||||||||||||||||||||
|
Callback invoked when obtaining the ctime value from the database.
Definition at line 313 of file db.cc. Referenced by sefs_db::sefs_db(). 00314 {
00315 time_t *ctime = static_cast < time_t * >(arg);
00316 // argv has the result of a call to ctime_r(); convert the string
00317 // back to a time_t value
00318 struct tm t;
00319 memset(&t, 0, sizeof(t));
00320 if (strptime(argv[0], "%a %b %d %T %Y", &t) == NULL)
00321 {
00322 return -1;
00323 }
00324 *ctime = mktime(&t);
00325 return 0;
00326 }
|
|
||||||||||||||||||||
|
Callback invoked to determine how many rows match a particular select statement.
Definition at line 332 of file db.cc. Referenced by sefs_db::isDB(). 00334 {
00335 int *count = static_cast < int *>(arg);
00336 *count = atoi(argv[0]);
00337 return 0;
00338 }
|
|
||||||||||||||||
|
Definition at line 348 of file db.cc. References strindex::str. Referenced by db_convert::db_convert(). 00349 {
00350 const struct strindex *n1 = static_cast < const struct strindex *>(a);
00351 const struct strindex *n2 = static_cast < const struct strindex *>(b);
00352 return strcmp(n1->str, n2->str);
00353 }
|
|
||||||||||||||||
|
Definition at line 455 of file db.cc. References db_convert::_db, db_convert::_dev, db_convert::_dev_id, db_convert::_errmsg, db_convert::_isMLS, db_convert::_range, db_convert::_range_id, db_convert::_role, db_convert::_role_id, db_convert::_target_db, db_convert::_type, db_convert::_type_id, db_convert::_user, db_convert::_user_id, sefs_entry::dev(), sefs_db::getContextNode(), db_convert::getID(), sefs_entry::inode(), sefs_entry::objectClass(), sefs_entry::path(), sefs_context_node::range, sefs_context_node::role, SEFS_ERR, sefs_context_node::type, and sefs_context_node::user. Referenced by sefs_db::sefs_db(). 00456 {
00457 db_convert *dbc = static_cast < db_convert * >(arg);
00458
00459 const struct sefs_context_node *context = dbc->_db->getContextNode(entry);
00460 try
00461 {
00462
00463 // add the user, role, type, range, and dev into the
00464 // target_db if needed
00465 int user_id = dbc->getID(context->user, dbc->_user, dbc->_user_id, "users");
00466 int role_id = dbc->getID(context->role, dbc->_role, dbc->_role_id, "roles");
00467 int type_id = dbc->getID(context->type, dbc->_type, dbc->_type_id, "types");
00468 int range_id = 0;
00469 if (dbc->_isMLS)
00470 {
00471 range_id = dbc->getID(context->range, dbc->_range, dbc->_range_id, "mls");
00472 }
00473 int dev_id = dbc->getID(entry->dev(), dbc->_dev, dbc->_dev_id, "devs");
00474 const char *path = entry->path();
00475 const ino64_t inode = entry->inode();
00476 const uint32_t objclass = entry->objectClass();
00477 char link_target[128] = "";
00478 // determine the link target as necessary
00479 struct stat64 sb;
00480 if (stat64(path, &sb) == -1)
00481 {
00482 SEFS_ERR(dbc->_db, "%s", strerror(errno));
00483 throw std::bad_alloc();
00484 }
00485 if (S_ISLNK(sb.st_mode))
00486 {
00487 if (readlink(path, link_target, 128) == 0)
00488 {
00489 SEFS_ERR(dbc->_db, "%s", strerror(errno));
00490 throw std::bad_alloc();
00491 }
00492 link_target[127] = '\0';
00493 }
00494
00495 char *insert_stmt = NULL;
00496 if (asprintf
00497 (&insert_stmt, "INSERT INTO paths VALUES ('%s', %lu, %d, %d, %d, %d, %d, %u, '%s')", path,
00498 static_cast < long unsigned int >(inode), dev_id, user_id, role_id, type_id, range_id, objclass,
00499 link_target) < 0)
00500 {
00501 SEFS_ERR(dbc->_db, "%s", strerror(errno));
00502 throw std::bad_alloc();
00503 }
00504 if (sqlite3_exec(dbc->_target_db, insert_stmt, NULL, NULL, &dbc->_errmsg) != SQLITE_OK)
00505 {
00506 SEFS_ERR(dbc->_db, "%s", dbc->_errmsg);
00507 free(insert_stmt);
00508 throw std::runtime_error(dbc->_errmsg);
00509 }
00510 free(insert_stmt);
00511 }
00512 catch(...)
00513 {
00514 return -1;
00515 }
00516 return 0;
00517 }
|
|
||||||||||||||||||||
|
Callback invoked while upgrading a libsefs database version 1 to version 2. Merge the inodes and paths table into one, remap the object class value, and explicitly set the role and dev fields to zero. Definition at line 1091 of file db.cc. Referenced by sefs_db::upgradeToDB2(). 01092 {
01093 struct sqlite3 *db = static_cast < struct sqlite3 *>(arg);
01094 bool mls = (argc == 7);
01095 assert(argc >= 6 && argc <= 7);
01096 uint32_t obj_class = static_cast < uint32_t > (atoi(argv[(mls ? 5 : 4)]));
01097
01098 switch (obj_class)
01099 {
01100 case 16:
01101 obj_class = QPOL_CLASS_BLK_FILE;
01102 break;
01103 case 8:
01104 obj_class = QPOL_CLASS_CHR_FILE;
01105 break;
01106 case 2:
01107 obj_class = QPOL_CLASS_DIR;
01108 break;
01109 case 64:
01110 obj_class = QPOL_CLASS_FIFO_FILE;
01111 break;
01112 case 1:
01113 obj_class = QPOL_CLASS_FILE;
01114 break;
01115 case 4:
01116 obj_class = QPOL_CLASS_LNK_FILE;
01117 break;
01118 case 32:
01119 obj_class = QPOL_CLASS_SOCK_FILE;
01120 break;
01121 }
01122
01123 char *insert_stmt = NULL;
01124 if (mls)
01125 {
01126 if (asprintf(&insert_stmt,
01127 "INSERT INTO new_paths (path, ino, dev, user, role, type, range, obj_class, symlink_target) VALUES ('%s', %s, 0, %s, 0, %s, %s, %u, '%s')",
01128 argv[0], argv[1], argv[2], argv[3], argv[4], obj_class, argv[6]) < 0)
01129 {
01130 return -1;
01131 }
01132 }
01133 else
01134 {
01135 if (asprintf(&insert_stmt,
01136 "INSERT INTO new_paths (path, ino, dev, user, role, type, range, obj_class, symlink_target) VALUES ('%s', %s, 0, %s, 0, %s, 0, %u, '%s')",
01137 argv[0], argv[1], argv[2], argv[3], obj_class, argv[5]) < 0)
01138 {
01139 return -1;
01140 }
01141 }
01142 if (sqlite3_exec(db, insert_stmt, NULL, NULL, NULL) != SQLITE_OK)
01143 {
01144 free(insert_stmt);
01145 return -1;
01146 }
01147 free(insert_stmt);
01148 return 0;
01149 }
|
|
||||||||||||||||
|
Allocate and return a new sefs database from the filesystem fs.
Definition at line 1243 of file db.cc. References sefs_fclist_t, and sefs_filesystem_t. 01244 {
01245 sefs_fclist_t *fc = NULL;
01246 try
01247 {
01248 fc = new sefs_db(fs, msg_callback, varg);
01249 }
01250 catch(...)
01251 {
01252 return NULL;
01253 }
01254 return fc;
01255 }
|
|
||||||||||||||||
|
Allocate and return a new sefs database, loading the entries from the saved database path.
Definition at line 1257 of file db.cc. References sefs_fclist_t. 01258 {
01259 sefs_fclist_t *fc = NULL;
01260 try
01261 {
01262 fc = new sefs_db(filename, msg_callback, varg);
01263 }
01264 catch(...)
01265 {
01266 return NULL;
01267 }
01268 return fc;
01269 }
|
|
||||||||||||
|
Write a database to disk, overwriting any existing file.
Definition at line 1271 of file db.cc. References sefs_db::save(), sefs_db_t, and SEFS_ERR. 01272 {
01273 if (db == NULL)
01274 {
01275 SEFS_ERR(NULL, "%s", strerror(EINVAL));
01276 errno = EINVAL;
01277 return -1;
01278 }
01279 try
01280 {
01281 db->save(filename);
01282 }
01283 catch(...)
01284 {
01285 return -1;
01286 }
01287 return 0;
01288 }
|
|
|
Get the creation time of a sefs database.
Definition at line 1290 of file db.cc. References sefs_db::getCTime(), sefs_db_t, and SEFS_ERR. 01291 {
01292 if (db == NULL)
01293 {
01294 SEFS_ERR(NULL, "%s", strerror(EINVAL));
01295 errno = EINVAL;
01296 return static_cast < time_t > (-1);
01297 }
01298 return db->getCTime();
01299 }
|
|
|
Determine if the given file is a valid sefs_db.
Definition at line 1301 of file db.cc. References sefs_db::isDB(). 01302 {
01303 return sefs_db::isDB(filename);
01304 }
|