/* ---------------------- */ cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, cnid_t did, const char *name, size_t len) { CNID_private *db; struct cnid_dbd_rqst rqst; struct cnid_dbd_rply rply; cnid_t id; if (!cdb || !(db = cdb->_private) || !st || !name) { LOG(log_error, logtype_cnid, "cnid_lookup: Parameter error"); errno = CNID_ERR_PARAM; return CNID_INVALID; } if (len > MAXPATHLEN) { LOG(log_error, logtype_cnid, "cnid_lookup: Path name is too long"); errno = CNID_ERR_PATH; return CNID_INVALID; } RQST_RESET(&rqst); rqst.op = CNID_DBD_OP_LOOKUP; if (!(cdb->flags & CNID_FLAG_NODEV)) { rqst.dev = st->st_dev; } rqst.ino = st->st_ino; rqst.type = S_ISDIR(st->st_mode)?1:0; rqst.did = did; rqst.name = name; rqst.namelen = len; LOG(log_debug, logtype_cnid, "cnid_dbd_lookup: CNID: %u, name: '%s', inode: 0x%llx, type: %d (0=file, 1=dir)", ntohl(did), name, (long long)st->st_ino, rqst.type); rply.namelen = 0; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; return CNID_INVALID; } switch (rply.result) { case CNID_DBD_RES_OK: id = rply.cnid; LOG(log_debug, logtype_cnid, "cnid_dbd_lookup: got CNID: %u", ntohl(id)); break; case CNID_DBD_RES_NOTFOUND: id = CNID_INVALID; break; case CNID_DBD_RES_ERR_DB: errno = CNID_ERR_DB; id = CNID_INVALID; break; default: abort(); } return id; }
int cnid_dbd_wipe(struct _cnid_db *cdb) { CNID_bdb_private *db; struct cnid_dbd_rqst rqst; struct cnid_dbd_rply rply; if (!cdb || !(db = cdb->cnid_db_private)) { LOG(log_error, logtype_cnid, "cnid_wipe: Parameter error"); errno = CNID_ERR_PARAM; return -1; } LOG(log_debug, logtype_cnid, "cnid_dbd_wipe"); RQST_RESET(&rqst); rqst.op = CNID_DBD_OP_WIPE; rqst.cnid = 0; rply.namelen = 0; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; return -1; } if (rply.result != CNID_DBD_RES_OK) { errno = CNID_ERR_DB; return -1; } LOG(log_debug, logtype_cnid, "cnid_dbd_wipe: ok"); return cnid_dbd_stamp(db); }
/* ---------------------- */ char *cnid_dbd_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len) { CNID_private *db; struct cnid_dbd_rqst rqst; struct cnid_dbd_rply rply; char *name; if (!cdb || !(db = cdb->_private) || !id || !(*id)) { LOG(log_error, logtype_cnid, "cnid_resolve: Parameter error"); errno = CNID_ERR_PARAM; return NULL; } LOG(log_debug, logtype_cnid, "cnid_dbd_resolve: resolving CNID: %u", ntohl(*id)); /* TODO: We should maybe also check len. At the moment we rely on the caller to provide a buffer that is large enough for MAXPATHLEN plus CNID_HEADER_LEN plus 1 byte, which is large enough for the maximum that can come from the database. */ RQST_RESET(&rqst); rqst.op = CNID_DBD_OP_RESOLVE; rqst.cnid = *id; /* Pass buffer to transmit so it can stuff the reply data there */ rply.name = (char *)buffer; rply.namelen = len; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; *id = CNID_INVALID; return NULL; } switch (rply.result) { case CNID_DBD_RES_OK: *id = rply.did; name = rply.name + CNID_NAME_OFS; LOG(log_debug, logtype_cnid, "cnid_dbd_resolve: resolved did: %u, name: '%s'", ntohl(*id), name); break; case CNID_DBD_RES_NOTFOUND: *id = CNID_INVALID; name = NULL; break; case CNID_DBD_RES_ERR_DB: errno = CNID_ERR_DB; *id = CNID_INVALID; name = NULL; break; default: abort(); } return name; }
/* ---------------------- */ int cnid_dbd_find(struct _cnid_db *cdb, const char *name, size_t namelen, void *buffer, size_t buflen) { CNID_private *db; struct cnid_dbd_rqst rqst; struct cnid_dbd_rply rply; int count; if (!cdb || !(db = cdb->_private) || !name) { LOG(log_error, logtype_cnid, "cnid_find: Parameter error"); errno = CNID_ERR_PARAM; return CNID_INVALID; } if (namelen > MAXPATHLEN) { LOG(log_error, logtype_cnid, "cnid_find: Path name is too long"); errno = CNID_ERR_PATH; return CNID_INVALID; } LOG(log_debug, logtype_cnid, "cnid_find(\"%s\")", name); RQST_RESET(&rqst); rqst.op = CNID_DBD_OP_SEARCH; rqst.name = name; rqst.namelen = namelen; rply.name = buffer; rply.namelen = buflen; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; return CNID_INVALID; } switch (rply.result) { case CNID_DBD_RES_OK: count = rply.namelen / sizeof(cnid_t); LOG(log_debug, logtype_cnid, "cnid_find: got %d matches", count); break; case CNID_DBD_RES_NOTFOUND: count = 0; break; case CNID_DBD_RES_ERR_DB: errno = CNID_ERR_DB; count = -1; break; default: abort(); } return count; }
/* ---------------------- */ int cnid_dbd_update(struct _cnid_db *cdb, cnid_t id, const struct stat *st, cnid_t did, const char *name, size_t len) { CNID_bdb_private *db; struct cnid_dbd_rqst rqst; struct cnid_dbd_rply rply; if (!cdb || !(db = cdb->cnid_db_private) || !id || !st || !name) { LOG(log_error, logtype_cnid, "cnid_update: Parameter error"); errno = CNID_ERR_PARAM; return -1; } if (len > MAXPATHLEN) { LOG(log_error, logtype_cnid, "cnid_update: Path name is too long"); errno = CNID_ERR_PATH; return -1; } RQST_RESET(&rqst); rqst.op = CNID_DBD_OP_UPDATE; rqst.cnid = id; if (!(cdb->cnid_db_flags & CNID_FLAG_NODEV)) { rqst.dev = st->st_dev; } rqst.ino = st->st_ino; rqst.type = S_ISDIR(st->st_mode)?1:0; rqst.did = did; rqst.name = name; rqst.namelen = len; LOG(log_debug, logtype_cnid, "cnid_dbd_update: CNID: %u, name: '%s', inode: 0x%llx, type: %d (0=file, 1=dir)", ntohl(id), name, (long long)st->st_ino, rqst.type); rply.namelen = 0; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; return -1; } switch (rply.result) { case CNID_DBD_RES_OK: LOG(log_debug, logtype_cnid, "cnid_dbd_update: updated"); case CNID_DBD_RES_NOTFOUND: return 0; case CNID_DBD_RES_ERR_DB: errno = CNID_ERR_DB; return -1; default: abort(); } }
/* ---------------------- */ cnid_t cnid_dbd_get(struct _cnid_db *cdb, cnid_t did, const char *name, size_t len) { CNID_private *db; struct cnid_dbd_rqst rqst; struct cnid_dbd_rply rply; cnid_t id; if (!cdb || !(db = cdb->_private) || !name) { LOG(log_error, logtype_cnid, "cnid_dbd_get: Parameter error"); errno = CNID_ERR_PARAM; return CNID_INVALID; } if (len > MAXPATHLEN) { LOG(log_error, logtype_cnid, "cnid_dbd_get: Path name is too long"); errno = CNID_ERR_PATH; return CNID_INVALID; } LOG(log_debug, logtype_cnid, "cnid_dbd_get: DID: %u, name: '%s'", ntohl(did), name); RQST_RESET(&rqst); rqst.op = CNID_DBD_OP_GET; rqst.did = did; rqst.name = name; rqst.namelen = len; rply.namelen = 0; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; return CNID_INVALID; } switch(rply.result) { case CNID_DBD_RES_OK: id = rply.cnid; LOG(log_debug, logtype_cnid, "cnid_dbd_get: got CNID: %u", ntohl(id)); break; case CNID_DBD_RES_NOTFOUND: id = CNID_INVALID; break; case CNID_DBD_RES_ERR_DB: id = CNID_INVALID; errno = CNID_ERR_DB; break; default: abort(); } return id; }
/* ---------------------- */ int cnid_dbd_delete(struct _cnid_db *cdb, const cnid_t id) { CNID_private *db; struct cnid_dbd_rqst rqst; struct cnid_dbd_rply rply; if (!cdb || !(db = cdb->_private) || !id) { LOG(log_error, logtype_cnid, "cnid_delete: Parameter error"); errno = CNID_ERR_PARAM; return -1; } LOG(log_debug, logtype_cnid, "cnid_dbd_delete: delete CNID: %u", ntohl(id)); RQST_RESET(&rqst); rqst.op = CNID_DBD_OP_DELETE; rqst.cnid = id; rply.namelen = 0; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; return -1; } switch (rply.result) { case CNID_DBD_RES_OK: LOG(log_debug, logtype_cnid, "cnid_dbd_delete: deleted CNID: %u", ntohl(id)); case CNID_DBD_RES_NOTFOUND: return 0; case CNID_DBD_RES_ERR_DB: errno = CNID_ERR_DB; return -1; default: abort(); } }
/* ------------------- */ static void dbd_initstamp(struct cnid_dbd_rqst *rqst) { RQST_RESET(rqst); rqst->op = CNID_DBD_OP_GETSTAMP; }