From 2491b79180cd99e246d034999b3a6e84966587fa Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Fri, 19 Nov 2010 11:25:53 +0100 Subject: [PATCH] It works --- bin/ad/ad_find.c | 24 +++++++++- bin/ad/ad_util.c | 88 ++++++++++++++++++------------------ etc/cnid_dbd/dbd_search.c | 5 +- etc/cnid_dbd/dbif.c | 13 ++++-- include/atalk/cnid.h | 9 ++-- libatalk/cnid/cnid.c | 4 +- libatalk/cnid/dbd/cnid_dbd.c | 12 +++-- libatalk/cnid/dbd/cnid_dbd.h | 3 +- 8 files changed, 95 insertions(+), 63 deletions(-) diff --git a/bin/ad/ad_find.c b/bin/ad/ad_find.c index 16dbce7f..121a3e44 100644 --- a/bin/ad/ad_find.c +++ b/bin/ad/ad_find.c @@ -33,6 +33,7 @@ #include #include +#include #include #include "ad.h" @@ -98,8 +99,27 @@ int ad_find(int argc, char **argv) set_signal(); cnid_init(); - openvol(argv[2], &vol); - cnid_find(vol.volume.v_cdb, argv[3], strlen(argv[3]) + 1); + SLOG("opening volume: %s", argv[2]); + if (openvol(argv[2], &vol) != 0) + ERROR("Cant open volume \"%s\"", argv[2]); + + SLOG("searching: %s", argv[3]); + + int count; + char resbuf[DBD_MAX_SRCH_RSLTS * sizeof(cnid_t)]; + if ((count = cnid_find(vol.volume.v_cdb, argv[3], strlen(argv[3]), resbuf, sizeof(resbuf))) < 1) { + SLOG("No results"); + } else { + SLOG("%d matches", count); + cnid_t cnid; + char *bufp = resbuf; + while (count--) { + memcpy(&cnid, bufp, sizeof(cnid_t)); + bufp += sizeof(cnid_t); + SLOG("Got CNID: %u", ntohl(cnid)); + } + } + closevol(&vol); return 0; diff --git a/bin/ad/ad_util.c b/bin/ad/ad_util.c index 58e333e7..3032b93b 100644 --- a/bin/ad/ad_util.c +++ b/bin/ad/ad_util.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2009 Frank Lahm * Copyright (c) 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -25,7 +25,7 @@ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * SUCH DAMAGE. */ #ifdef HAVE_CONFIG_H @@ -89,10 +89,10 @@ void _log(enum logtype lt, char *fmt, ...) /*! * Load volinfo and initialize struct vol * - * Only opens "dbd" volumes ! + * Only opens "dbd" volumes ! * * @param path (r) path to evaluate - * @param vol (rw) structure to initialize + * @param vol (rw) structure to initialize * * @returns 0 on success, exits on error */ @@ -103,42 +103,42 @@ int openvol(const char *path, afpvol_t *vol) memset(vol, 0, sizeof(afpvol_t)); /* try to find a .AppleDesktop/.volinfo */ - if (loadvolinfo((char *)path, &vol->volinfo) == 0) { - - if (STRCMP(vol->volinfo.v_cnidscheme, != , "dbd")) - ERROR("\"%s\" isn't a \"dbd\" CNID volume!", vol->volinfo.v_path); + if (loadvolinfo((char *)path, &vol->volinfo) != 0) + return -1; - if (vol_load_charsets(&vol->volinfo) == -1) - ERROR("Error loading charsets!"); + if (STRCMP(vol->volinfo.v_cnidscheme, != , "dbd")) + ERROR("\"%s\" isn't a \"dbd\" CNID volume!", vol->volinfo.v_path); - /* Sanity checks to ensure we can touch this volume */ - if (vol->volinfo.v_adouble != AD_VERSION2) - ERROR("Unsupported adouble versions: %u", vol->volinfo.v_adouble); + if (vol_load_charsets(&vol->volinfo) == -1) + ERROR("Error loading charsets!"); - if (vol->volinfo.v_vfs_ea != AFPVOL_EA_SYS) - ERROR("Unsupported Extended Attributes option: %u", vol->volinfo.v_vfs_ea); + /* Sanity checks to ensure we can touch this volume */ + if (vol->volinfo.v_adouble != AD_VERSION2) + ERROR("Unsupported adouble versions: %u", vol->volinfo.v_adouble); - /* initialize sufficient struct vol for VFS initialisation */ - vol->volume.v_adouble = AD_VERSION2; - vol->volume.v_vfs_ea = AFPVOL_EA_SYS; - initvol_vfs(&vol->volume); + if (vol->volinfo.v_vfs_ea != AFPVOL_EA_SYS) + ERROR("Unsupported Extended Attributes option: %u", vol->volinfo.v_vfs_ea); - if ((vol->volinfo.v_flags & AFPVOL_NODEV)) - flags |= CNID_FLAG_NODEV; + /* initialize sufficient struct vol for VFS initialisation */ + vol->volume.v_adouble = AD_VERSION2; + vol->volume.v_vfs_ea = AFPVOL_EA_SYS; + initvol_vfs(&vol->volume); - if ((vol->volume.v_cdb = cnid_open(vol->volinfo.v_dbpath, - 0000, - "dbd", - flags, - vol->volinfo.v_dbd_host, - vol->volinfo.v_dbd_port)) == NULL) - ERROR("Cant initialize CNID database connection for %s", vol->volinfo.v_path); + if ((vol->volinfo.v_flags & AFPVOL_NODEV)) + flags |= CNID_FLAG_NODEV; - cnid_getstamp(vol->volume.v_cdb, - vol->db_stamp, - sizeof(vol->db_stamp)); - } + if ((vol->volume.v_cdb = cnid_open(vol->volinfo.v_dbpath, + 0000, + "dbd", + flags, + vol->volinfo.v_dbd_host, + vol->volinfo.v_dbd_port)) == NULL) + ERROR("Cant initialize CNID database connection for %s", vol->volinfo.v_path); + cnid_getstamp(vol->volume.v_cdb, + vol->db_stamp, + sizeof(vol->db_stamp)); + return 0; } @@ -183,7 +183,7 @@ char *utompath(const struct volinfo *volinfo, const char *upath) volinfo->v_maccharset, u, outlen, mpath, MAXPATHLEN, &flags)) ) { SLOG("Conversion from %s to %s for %s failed.", - volinfo->v_volcodepage, volinfo->v_maccodepage, u); + volinfo->v_volcodepage, volinfo->v_maccodepage, u); return NULL; } @@ -200,7 +200,7 @@ char *utompath(const struct volinfo *volinfo, const char *upath) * "/afp_volume/dir/subdir" * * @param path (r) path relative to cwd() or absolute - * @param volpath (r) volume path that path is a subdir of (has been computed in volinfo funcs) + * @param volpath (r) volume path that path is a subdir of (has been computed in volinfo funcs) * * @returns relative path in new bstring, caller must bdestroy it */ @@ -363,14 +363,14 @@ cnid_t cnid_for_path(const afpvol_t *vol, cfrombstr(statpath), strerror(errno)); if ((cnid = cnid_add(vol->volume.v_cdb, - &st, - *did, - cfrombstr(l->entry[i]), - blength(l->entry[i]), + &st, + *did, + cfrombstr(l->entry[i]), + blength(l->entry[i]), 0)) == CNID_INVALID) { EC_FAIL; } - EC_ZERO(bcatcstr(statpath, "/")); + EC_ZERO(bcatcstr(statpath, "/")); } EC_CLEANUP: @@ -432,14 +432,14 @@ cnid_t cnid_for_paths_parent(const afpvol_t *vol, cfrombstr(statpath), strerror(errno)); if ((cnid = cnid_add(vol->volume.v_cdb, - &st, - *did, - cfrombstr(l->entry[i]), - blength(l->entry[i]), + &st, + *did, + cfrombstr(l->entry[i]), + blength(l->entry[i]), 0)) == CNID_INVALID) { EC_FAIL; } - EC_ZERO(bcatcstr(statpath, "/")); + EC_ZERO(bcatcstr(statpath, "/")); } EC_CLEANUP: diff --git a/etc/cnid_dbd/dbd_search.c b/etc/cnid_dbd/dbd_search.c index 09624c83..a2efc33c 100644 --- a/etc/cnid_dbd/dbd_search.c +++ b/etc/cnid_dbd/dbd_search.c @@ -22,6 +22,9 @@ int dbd_search(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) DBT key; int results; static char resbuf[DBD_MAX_SRCH_RSLTS * sizeof(cnid_t)]; + + LOG(log_debug, logtype_cnid, "dbd_search(\"%s\"):", rqst->name); + memset(&key, 0, sizeof(key)); rply->name = resbuf; rply->namelen = 0; @@ -29,7 +32,7 @@ int dbd_search(DBD *dbd, struct cnid_dbd_rqst *rqst, struct cnid_dbd_rply *rply) key.data = rqst->name; key.size = rqst->namelen; - if ((results = dbif_search(dbd, &key, 0)) < 0) { + if ((results = dbif_search(dbd, &key, resbuf)) < 0) { LOG(log_error, logtype_cnid, "dbd_search(\"%s\"): db error", rqst->name); rply->result = CNID_DBD_RES_ERR_DB; return -1; diff --git a/etc/cnid_dbd/dbif.c b/etc/cnid_dbd/dbif.c index 0abfc2e9..8ddebc1f 100644 --- a/etc/cnid_dbd/dbif.c +++ b/etc/cnid_dbd/dbif.c @@ -760,6 +760,8 @@ int dbif_search(DBD *dbd, DBT *key, char *resbuf) DBT pkey, data; char *cnids = resbuf; cnid_t cnid; + char *namebkp = key->data; + int namelenbkp = key->size; memset(&pkey, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); @@ -777,10 +779,13 @@ int dbif_search(DBD *dbd, DBT *key, char *resbuf) ret = cursorp->pget(cursorp, key, &pkey, &data, DB_SET_RANGE); while (count < DBD_MAX_SRCH_RSLTS && ret != DB_NOTFOUND) { - count++; - memcpy(cnids, pkey.data, sizeof(cnid_t)); - cnids += sizeof(cnid_t); - LOG(log_error, logtype_cnid, "match: CNID %" PRIu32, memcpy(&cnid, pkey.data, sizeof(cnid_t)), ntohl(cnid)); + if (namelenbkp <= key->size && strncmp(namebkp, key->data, namelenbkp) == 0) { + count++; + memcpy(cnids, pkey.data, sizeof(cnid_t)); + memcpy(&cnid, pkey.data, sizeof(cnid_t)); + cnids += sizeof(cnid_t); + LOG(log_error, logtype_cnid, "match: CNID %" PRIu32, ntohl(cnid)); + } ret = cursorp->pget(cursorp, key, &pkey, &data, DB_NEXT_DUP); } diff --git a/include/atalk/cnid.h b/include/atalk/cnid.h index 7a0d0199..385f646d 100644 --- a/include/atalk/cnid.h +++ b/include/atalk/cnid.h @@ -1,8 +1,7 @@ /* - * $Id: cnid.h,v 1.15 2010-03-31 09:47:32 franklahm Exp $ - * * Copyright (c) 2003 the Netatalk Team * Copyright (c) 2003 Rafal Lewczuk + * Copyright (c) 2010 Frank Lahm * * This program is free software; you can redistribute and/or modify * it under the terms of the GNU General Public License as published @@ -68,7 +67,8 @@ struct _cnid_db { int (*cnid_getstamp) (struct _cnid_db *cdb, void *buffer, const size_t len); cnid_t (*cnid_rebuild_add) (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t, cnid_t); - int (*cnid_find) (struct _cnid_db *cdb, const char *name, size_t len); + int (*cnid_find) (struct _cnid_db *cdb, const char *name, size_t namelen, + void *buffer, size_t buflen); }; typedef struct _cnid_db cnid_db; @@ -121,7 +121,8 @@ int cnid_update (struct _cnid_db *cdb, const cnid_t id, const struct stat const cnid_t did, char *name, const size_t len); cnid_t cnid_rebuild_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, char *name, const size_t len, cnid_t hint); -int cnid_find (struct _cnid_db *cdb, const char *name, size_t len); +int cnid_find (struct _cnid_db *cdb, const char *name, size_t namelen, + void *buffer, size_t buflen); void cnid_close (struct _cnid_db *db); #endif diff --git a/libatalk/cnid/cnid.c b/libatalk/cnid/cnid.c index d4b85e35..68136f9f 100644 --- a/libatalk/cnid/cnid.c +++ b/libatalk/cnid/cnid.c @@ -281,7 +281,7 @@ cnid_t cnid_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did } /* --------------- */ -int cnid_find(struct _cnid_db *cdb, const char *name, size_t len) +int cnid_find(struct _cnid_db *cdb, const char *name, size_t namelen, void *buffer, size_t buflen) { int ret; @@ -291,7 +291,7 @@ int cnid_find(struct _cnid_db *cdb, const char *name, size_t len) } block_signal(cdb->flags); - ret = cdb->cnid_find(cdb, name, len); + ret = cdb->cnid_find(cdb, name, namelen, buffer, buflen); unblock_signal(cdb->flags); return ret; } diff --git a/libatalk/cnid/dbd/cnid_dbd.c b/libatalk/cnid/dbd/cnid_dbd.c index c33b601c..22ac6d3b 100644 --- a/libatalk/cnid/dbd/cnid_dbd.c +++ b/libatalk/cnid/dbd/cnid_dbd.c @@ -793,7 +793,7 @@ cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t } /* ---------------------- */ -int cnid_dbd_find(struct _cnid_db *cdb, const char *name, size_t len) +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; @@ -806,21 +806,23 @@ int cnid_dbd_find(struct _cnid_db *cdb, const char *name, size_t len) return CNID_INVALID; } - if (len > MAXPATHLEN) { + 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 = len; + rqst.namelen = namelen; - LOG(log_debug, logtype_cnid, "cnid_find(\"%s\")", name); + rply.name = buffer; + rply.namelen = buflen; - rply.namelen = 0; if (transmit(db, &rqst, &rply) < 0) { errno = CNID_ERR_DB; return CNID_INVALID; diff --git a/libatalk/cnid/dbd/cnid_dbd.h b/libatalk/cnid/dbd/cnid_dbd.h index 22db5a5c..f25e3618 100644 --- a/libatalk/cnid/dbd/cnid_dbd.h +++ b/libatalk/cnid/dbd/cnid_dbd.h @@ -26,7 +26,8 @@ extern char *cnid_dbd_resolve (struct _cnid_db *, cnid_t *, void *, size_t ) extern int cnid_dbd_getstamp (struct _cnid_db *, void *, const size_t ); extern cnid_t cnid_dbd_lookup (struct _cnid_db *, const struct stat *, const cnid_t, char *, const size_t); -extern int cnid_dbd_find (struct _cnid_db *cdb, const char *name, size_t len); +extern int cnid_dbd_find (struct _cnid_db *cdb, const char *name, size_t namelen, + void *buffer, size_t buflen); extern int cnid_dbd_update (struct _cnid_db *, const cnid_t, const struct stat *, const cnid_t, char *, size_t); extern int cnid_dbd_delete (struct _cnid_db *, const cnid_t); -- 2.39.2