if ((vol->volinfo.v_flags & AFPVOL_NODEV))
flags |= CNID_FLAG_NODEV;
- if ((vol->volume.v_cdb = cnid_open(vol->volinfo.v_dbpath,
+ if ((vol->volume.v_cdb = cnid_open(vol->volinfo.v_path,
0000,
"dbd",
flags,
/*
- $Id: cmd_dbd.c,v 1.26 2010-04-20 16:46:20 hat001 Exp $
-
Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
This program is free software; you can redistribute it and/or modify
int nocniddb = 0; /* Dont open CNID database, only scan filesystem */
volatile sig_atomic_t alarmed;
+struct volinfo volinfo;
static DBD *dbd;
static int verbose; /* Logging flag */
-1,
-1
};
-static char dbpath[PATH_MAX]; /* Path to the dbd database */
+static char dbpath[MAXPATHLEN+1]; /* Path to the dbd database */
/*
Provide some logging
int dump=0, scan=0, rebuild=0, prep_upgrade=0, rebuildindexes=0, dumpindexes=0, force=0;
dbd_flags_t flags = 0;
char *volpath;
- struct volinfo volinfo;
int cdir;
if (geteuid() != 0) {
}
/* Put "/.AppleDB" at end of volpath, get path from volinfo file */
- if ( (strlen(volinfo.v_dbpath) + strlen("/.AppleDB")) > (PATH_MAX - 1) ) {
+ if ( (strlen(volinfo.v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
dbd_log( LOGSTD, "Volume pathname too long");
exit(EXIT_FAILURE);
}
- strncpy(dbpath, volinfo.v_dbpath, PATH_MAX - 9 - 1);
+ strncpy(dbpath, volinfo.v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
strcat(dbpath, "/.AppleDB");
/* Check or create dbpath */
/* Check if -f is requested and wipe db if yes */
if ((flags & DBD_FLAGS_FORCE) && rebuild && (volinfo.v_flags & AFPVOL_CACHE)) {
char cmd[8 + MAXPATHLEN];
- snprintf(cmd, 8 + MAXPATHLEN, "rm -f %s/*", dbpath);
+ snprintf(cmd, 8 + MAXPATHLEN, "rm -rf \"%s\"", dbpath);
dbd_log( LOGDEBUG, "Removing old database of volume: '%s'", volpath);
system(cmd);
+ if ((mkdir(dbpath, 0755)) != 0) {
+ dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", dbpath, strerror(errno));
+ exit(EXIT_FAILURE);
+ }
dbd_log( LOGDEBUG, "Removed old database.");
}
dbif_close(dbd);
goto exit_failure;
}
-
- if (dbd_stamp(dbd) < 0) {
- dbif_close(dbd);
- goto exit_failure;
- }
}
/* Now execute given command scan|rebuild|dump */
extern int nocniddb; /* Dont open CNID database, only scan filesystem */
extern volatile sig_atomic_t alarmed;
-extern struct volinfo *volinfo;
+// extern struct volinfo *volinfo;
extern char cwdbuf[MAXPATHLEN+1];
extern void dbd_log(enum logtype lt, char *fmt, ...);
extern int add_cnid(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply);
extern int get_cnid(DBD *dbd, struct cnid_dbd_rply *rply);
-extern int dbd_stamp(DBD *dbd);
extern int dbd_add(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *, int nolookup);
extern int dbd_lookup(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *, int roflag);
extern int dbd_get(DBD *dbd, struct cnid_dbd_rqst *, struct cnid_dbd_rply *);
return 0;
}
-/* ---------------
-*/
-int dbd_stamp(DBD *dbd)
-{
- DBT rootinfo_key, rootinfo_data;
- cnid_t hint;
- char buf[ROOTINFO_DATALEN];
- char stamp[CNID_DEV_LEN];
-
- memset(&rootinfo_key, 0, sizeof(rootinfo_key));
- memset(&rootinfo_data, 0, sizeof(rootinfo_data));
- rootinfo_key.data = ROOTINFO_KEY;
- rootinfo_key.size = ROOTINFO_KEYLEN;
-
- switch (dbif_get(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0)) {
- case 0:
- hint = htonl(CNID_START);
- memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
- rootinfo_data.data = buf;
- rootinfo_data.size = ROOTINFO_DATALEN;
- if (dbif_stamp(dbd, stamp, CNID_DEV_LEN) < 0) {
- return -1;
- }
- memcpy((char *)rootinfo_data.data + CNID_TYPE_OFS, &hint, sizeof(hint));
- memcpy((char *)rootinfo_data.data + CNID_DEV_OFS, stamp, sizeof(stamp));
- if (dbif_put(dbd, DBIF_CNID, &rootinfo_key, &rootinfo_data, 0) < 0) {
- return -1;
- }
- return 0;
-
- case 1: /* we already have one */
- return 0;
- default:
- return -1;
- }
- return -1;
-}
-
/* ------------------------ */
/* We need a nolookup version for `dbd` */
int dbd_add(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply, int nolookup)
+
/*
* $Id: dbd_getstamp.c,v 1.4 2009-05-06 11:54:24 franklahm Exp $
*
return ret;
}
+#include <atalk/util.h>
+
/* --------------- */
int dbif_stamp(DBD *dbd, void *buffer, int size)
{
LOG(log_error, logtype_cnid, "error stating database %s: %s", dbd->db_table[DBIF_CNID].name, db_strerror(errno));
return -1;
}
+
+ LOG(log_maxdebug, logtype_cnid,"stamp: %s", asctime(localtime(&st.st_ctime)));
+
memset(buffer, 0, size);
memcpy(buffer, &st.st_ctime, sizeof(st.st_ctime));
if (reindex)
LOG(log_info, logtype_cnid, "Reindexing name index...");
- int version = dbif_getversion(dbd);
- if (version == -1)
- return -1;
+
+ int version = CNID_VERSION;
+ if (dbd->db_envhome) {
+ if ((version = dbif_getversion(dbd)) == -1)
+ return -1;
+ }
+
if ((ret = dbd->db_table[0].db->associate(dbd->db_table[0].db,
dbd->db_txn,
dbd->db_table[DBIF_IDX_NAME].db,
if (reindex)
LOG(log_info, logtype_cnid, "... done.");
- if ((ret = dbif_upgrade(dbd)) != 0) {
+ if ((dbd->db_envhome) && ((ret = dbif_upgrade(dbd)) != 0)) {
LOG(log_error, logtype_cnid, "Error upgrading CNID database to version %d", CNID_VERSION);
return -1;
}
return 1;
}
+/*!
+ * Inititialize rootinfo key (which has CNID 0 as key)
+ *
+ * This also "stamps" the database, which means storing st.st_ctime of the
+ * "cnid2.db" file in the rootinfo data at the DEV offset
+ *
+ * @param dbd (rw) database handle
+ * @param version (r) database version number
+ *
+ * @returns -1 on error, 0 on success
+ */
+static int dbif_init_rootinfo(DBD *dbd, int version)
+{
+ DBT key, data;
+ uint32_t v;
+ char buf[ROOTINFO_DATALEN];
+
+ LOG(log_debug, logtype_cnid, "Setting CNID database version to %u", version);
+
+ v = version;
+ v = htonl(v);
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ key.data = ROOTINFO_KEY;
+ key.size = ROOTINFO_KEYLEN;
+ data.data = buf;
+ data.size = ROOTINFO_DATALEN;
+
+ memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
+ memcpy(buf + CNID_DID_OFS, &v, sizeof(v));
+ if (dbif_stamp(dbd, buf + CNID_DEV_OFS, CNID_DEV_LEN) < 0)
+ return -1;
+
+ if (dbif_put(dbd, DBIF_CNID, &key, &data, 0) < 0)
+ return -1;
+
+ return 0;
+}
+
/*!
* Initialize or return CNID database version number
+ *
+ * Calls dbif_init_rootinfo if the rootinfo key does not exist yet
+ *
* @returns -1 on error, version number otherwise
*/
int dbif_getversion(DBD *dbd)
ret = version;
break;
case 0: /* not found */
- if (dbif_setversion(dbd, CNID_VERSION) != 0)
+ if (dbif_init_rootinfo(dbd, CNID_VERSION) != 0)
return -1;
ret = CNID_VERSION;
break;
}
/*!
- * Return CNID database version number
+ * Set CNID database version number
+ *
+ * Initializes rootinfo key as neccessary, as does dbif_getversion
* @returns -1 on error, version number otherwise
*/
int dbif_setversion(DBD *dbd, int version)
int ret;
DBT key, data;
uint32_t v;
- char buf[ROOTINFO_DATALEN];
LOG(log_debug, logtype_cnid, "Setting CNID database version to %u", version);
if ((ret = dbif_get(dbd, DBIF_CNID, &key, &data, 0)) == -1)
return -1;
if (ret == 0) {
- memcpy(buf, ROOTINFO_DATA, ROOTINFO_DATALEN);
- data.data = buf;
+ /* No rootinfo key yet, init it */
+ if (dbif_init_rootinfo(dbd, CNID_VERSION) != 0)
+ return -1;
+ /* Now try again */
+ if (dbif_get(dbd, DBIF_CNID, &key, &data, 0) == -1)
+ return -1;
}
memcpy((char *)data.data + CNID_DID_OFS, &v, sizeof(v));
data.size = ROOTINFO_DATALEN;
int dbif_dump(DBD *dbd, int dumpindexes)
{
int rc;
- uint32_t max = 0, count = 0, cnid, type, did, lastid;
+ uint32_t max = 0, count = 0, cnid, type, did, lastid, version;
uint64_t dev, ino;
time_t stamp;
DBC *cur;
/* Rootinfo node ? */
if (cnid == 0) {
- memcpy(&stamp, (char *)data.data + 4, sizeof(time_t));
- memcpy(&lastid, (char *)data.data + 20, sizeof(cnid_t));
+ memcpy(&stamp, (char *)data.data + CNID_DEV_OFS, sizeof(time_t));
+ memcpy(&lastid, (char *)data.data + CNID_TYPE_OFS, CNID_TYPE_LEN);
lastid = ntohl(lastid);
+ memcpy(&version, (char *)data.data + CNID_DID_OFS, CNID_DID_LEN);
+ version = ntohl(version);
+
strftime(timebuf, sizeof(timebuf), "%b %d %Y %H:%M:%S", localtime(&stamp));
- printf("dbd stamp: 0x%08x (%s), next free CNID: %u\n", (unsigned int)stamp, timebuf, lastid + 1);
+ printf("CNID db version: %u, dbd stamp: 0x%08x (%s), next free CNID: %u\n",
+ version, (unsigned int)stamp, timebuf, lastid + 1);
} else {
/* dev */
memcpy(&dev, (char *)data.data + CNID_DEV_OFS, 8);
struct db_param *dbp;
int err = 0;
int lockfd, ctrlfd, clntfd;
- char *dir, *logconfig;
+ char *logconfig;
set_processname("cnid_dbd");
exit(1);
}
- dir = argv[1];
ctrlfd = atoi(argv[2]);
clntfd = atoi(argv[3]);
logconfig = strdup(argv[4]);
setuplog(logconfig);
/* Load .volinfo file */
- if (loadvolinfo(dir, &volinfo) == -1) {
- LOG(log_error, logtype_cnid, "Cant load volinfo for \"%s\"", dir);
+ if (loadvolinfo(argv[1], &volinfo) == -1) {
+ LOG(log_error, logtype_cnid, "Cant load volinfo for \"%s\"", argv[1]);
exit(EXIT_FAILURE);
}
- dir = volinfo.v_dbpath;
+ /* Put "/.AppleDB" at end of volpath, get path from volinfo file */
+ char dbpath[MAXPATHLEN+1];
+ if ((strlen(volinfo.v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
+ LOG(log_error, logtype_cnid, "CNID db pathname too long: \"%s\"", volinfo.v_dbpath);
+ exit(EXIT_FAILURE);
+ }
+ strncpy(dbpath, volinfo.v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
+ strcat(dbpath, "/.AppleDB");
+
if (vol_load_charsets(&volinfo) == -1) {
LOG(log_error, logtype_cnid, "Error loading charsets!");
exit(EXIT_FAILURE);
}
- LOG(log_note, logtype_cnid, "db dir: \"%s\"", dir);
+ LOG(log_note, logtype_cnid, "db dir: \"%s\"", dbpath);
- switch_to_user(dir);
+ switch_to_user(dbpath);
/* Before we do anything else, check if there is an instance of cnid_dbd
running already and silently exit if yes. */
/* SIGINT and SIGTERM are always off, unless we are in pselect */
block_sigs_onoff(1);
- if ((dbp = db_param_read(dir, CNID_DBD)) == NULL)
+ if ((dbp = db_param_read(dbpath, CNID_DBD)) == NULL)
exit(1);
LOG(log_maxdebug, logtype_cnid, "Finished parsing db_param config file");
}
LOG(log_debug, logtype_cnid, "Finished opening BerkeleyDB databases");
- if (dbd_stamp(dbd) < 0) {
- dbif_close(dbd);
- exit(5);
- }
- LOG(log_maxdebug, logtype_cnid, "Finished checking database stamp");
-
if (comm_init(dbp, ctrlfd, clntfd) < 0) {
dbif_close(dbd);
exit(3);
if (dbif_close(dbd) < 0)
err++;
- if (dbif_env_remove(dir) < 0)
+ if (dbif_env_remove(dbpath) < 0)
err++;
free_lock(lockfd);
#include <atalk/cnid_dbd_private.h>
#include "pack.h"
-/* in main.c */
+/* in main.c for `cnid_dbd` or cmd_dbd.c for `dbd` */
extern struct volinfo volinfo;
/* --------------- */
#define CNID_INO_LEN 8
#define CNID_DEVINO_OFS CNID_LEN
-#define CNID_DEVINO_LEN (CNID_DEV_LEN +CNID_INO_LEN)
+#define CNID_DEVINO_LEN (CNID_DEV_LEN + CNID_INO_LEN)
-#define CNID_TYPE_OFS (CNID_DEVINO_OFS +CNID_DEVINO_LEN)
+#define CNID_TYPE_OFS (CNID_DEVINO_OFS + CNID_DEVINO_LEN)
#define CNID_TYPE_LEN 4
-#define CNID_DID_OFS (CNID_TYPE_OFS +CNID_TYPE_LEN)
+#define CNID_DID_OFS (CNID_TYPE_OFS + CNID_TYPE_LEN)
#define CNID_DID_LEN CNID_LEN
#define CNID_NAME_OFS (CNID_DID_OFS + CNID_DID_LEN)