]> arthur.barton.de Git - netatalk.git/commitdiff
ad find
authorFrank Lahm <franklahm@googlemail.com>
Fri, 19 Nov 2010 08:51:46 +0000 (09:51 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Fri, 19 Nov 2010 08:51:46 +0000 (09:51 +0100)
bin/ad/Makefile.am
bin/ad/ad.c
bin/ad/ad_find.c [new file with mode: 0644]
include/atalk/cnid.h
include/atalk/cnid_dbd_private.h
libatalk/cnid/cnid.c
libatalk/cnid/dbd/cnid_dbd.c
libatalk/cnid/dbd/cnid_dbd.h

index db363aea55e2b9749683e80ab7cc2dba45c8a630..7e6fe922b911db850841a15d3e7e72eb6d3cf491 100644 (file)
@@ -7,6 +7,7 @@ bin_PROGRAMS = ad
 
 ad_SOURCES = \
        ad.c \
+       ad_find.c \
        ad_util.c \
        ad_ls.c \
        ad_cp.c \
index add592a289ca0c0903da1507a6bfaec0f429f1ef..71a0f7449d36927e43deb7a63bcfc4d4813c3445 100644 (file)
@@ -35,7 +35,7 @@
 
 static void usage_main(void)
 {
-    printf("Usage: ad ls|cp|rm|mv [file|dir, ...]\n");
+    printf("Usage: ad ls|cp|rm|mv|find [file|dir, ...]\n");
 }
 
 int main(int argc, char **argv)
@@ -55,6 +55,8 @@ int main(int argc, char **argv)
         return ad_rm(argc - 1, argv + 1);
     else if (STRCMP(argv[1], ==, "mv"))
         return ad_mv(argc, argv);
+    else if (STRCMP(argv[1], ==, "find"))
+        return ad_find(argc, argv);
     else {
         usage_main();
         return 1;
diff --git a/bin/ad/ad_find.c b/bin/ad/ad_find.c
new file mode 100644 (file)
index 0000000..16dbce7
--- /dev/null
@@ -0,0 +1,106 @@
+/* 
+   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   This program 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 General Public License for more details.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <limits.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <pwd.h>
+#include <grp.h>
+#include <time.h>
+
+#include <atalk/adouble.h>
+#include <atalk/cnid.h>
+#include <atalk/volinfo.h>
+#include "ad.h"
+
+static volatile sig_atomic_t alarmed;
+
+/*
+  SIGNAL handling:
+  catch SIGINT and SIGTERM which cause clean exit. Ignore anything else.
+*/
+
+static void sig_handler(int signo)
+{
+    alarmed = 1;
+    return;
+}
+
+static void set_signal(void)
+{
+    struct sigaction sv;
+
+    sv.sa_handler = sig_handler;
+    sv.sa_flags = SA_RESTART;
+    sigemptyset(&sv.sa_mask);
+    if (sigaction(SIGTERM, &sv, NULL) < 0)
+        ERROR("error in sigaction(SIGTERM): %s", strerror(errno));
+
+    if (sigaction(SIGINT, &sv, NULL) < 0)
+        ERROR("error in sigaction(SIGINT): %s", strerror(errno));
+
+    memset(&sv, 0, sizeof(struct sigaction));
+    sv.sa_handler = SIG_IGN;
+    sigemptyset(&sv.sa_mask);
+
+    if (sigaction(SIGABRT, &sv, NULL) < 0)
+        ERROR("error in sigaction(SIGABRT): %s", strerror(errno));
+
+    if (sigaction(SIGHUP, &sv, NULL) < 0)
+        ERROR("error in sigaction(SIGHUP): %s", strerror(errno));
+
+    if (sigaction(SIGQUIT, &sv, NULL) < 0)
+        ERROR("error in sigaction(SIGQUIT): %s", strerror(errno));
+}
+
+static void usage_find(void)
+{
+    printf(
+        "Usage: ad find VOLUME_PATH NAME\n"
+        );
+}
+
+int ad_find(int argc, char **argv)
+{
+    int c;
+    afpvol_t vol;
+
+    printf("argc: %d, argv0: %s\n", argc, argv[0]);
+
+    if (argc != 4) {
+        usage_find();
+        exit(1);
+    }
+
+    set_signal();
+    cnid_init();
+
+    openvol(argv[2], &vol);
+    cnid_find(vol.volume.v_cdb, argv[3], strlen(argv[3]) + 1);
+    closevol(&vol);
+
+    return 0;
+}
index 5cd5ff7039103901fca2025e4e4787e3f8e26886..7a0d0199aa0807125204debd4436666cf1407eb8 100644 (file)
@@ -1,9 +1,9 @@
-/* 
+/*
  * $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 <rlewczuk@pronet.pl>
- * 
+ *
  * This program is free software; you can redistribute and/or modify
  * it under the terms of the GNU General Public License as published
  * by the Free Software Foundation version 2 of the License or later
  *
  */
 
-/* 
- * This file contains all generic CNID related stuff 
+/*
+ * This file contains all generic CNID related stuff
  * declarations. Included:
- * - CNID factory, which retrieves (eventually instantiates) 
+ * - CNID factory, which retrieves (eventually instantiates)
  *   CNID objects on demand
  * - selection of CNID backends (default, detected by volume)
  * - full set of CNID operations needed by server core.
@@ -33,8 +33,8 @@
 #define CNID_FLAG_BLOCK        0x08      /* block signals in update. */
 #define CNID_FLAG_NODEV        0x10      /* don't use device number only inode */
 #define CNID_FLAG_LAZY_INIT    0x20      /* */
-#define CNID_FLAG_MEMORY       0x40     /* this is a memory only db */
-#define CNID_FLAG_INODE        0x80     /* in cnid_add the inode is authoritative */
+#define CNID_FLAG_MEMORY       0x40  /* this is a memory only db */
+#define CNID_FLAG_INODE        0x80  /* in cnid_add the inode is authoritative */
 
 #define CNID_INVALID   0
 /* first valid ID */
  * This is instance of CNID database object.
  */
 struct _cnid_db {
-       
-       u_int32_t flags;             /* Flags describing some CNID backend aspects. */
-       char *volpath;               /* Volume path this particular CNID db refers to. */
-       void *_private;              /* back-end speficic data */
-
-       cnid_t (*cnid_add)(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, 
-                       char *name, const size_t, cnid_t hint);
-       int (*cnid_delete)(struct _cnid_db *cdb, cnid_t id);
-       cnid_t (*cnid_get)(struct _cnid_db *cdb, const cnid_t did, char *name, const  size_t);
-       cnid_t (*cnid_lookup)(struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
-                       char *name, const size_t);
-       cnid_t (*cnid_nextid)(struct _cnid_db *cdb);
-       char *(*cnid_resolve)(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len);
-       int (*cnid_update)(struct _cnid_db *cdb, const cnid_t id, const struct stat *st, 
-                       const cnid_t did, char *name, const size_t len);        
-       void (*cnid_close)(struct _cnid_db *cdb);
-       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);
+    u_int32_t flags;             /* Flags describing some CNID backend aspects. */
+    char *volpath;               /* Volume path this particular CNID db refers to. */
+    void *_private;              /* back-end speficic data */
+
+    cnid_t (*cnid_add)         (struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
+                                char *name, const size_t, cnid_t hint);
+    int    (*cnid_delete)      (struct _cnid_db *cdb, cnid_t id);
+    cnid_t (*cnid_get)         (struct _cnid_db *cdb, const cnid_t did, char *name, const  size_t);
+    cnid_t (*cnid_lookup)      (struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
+                                char *name, const size_t);
+    cnid_t (*cnid_nextid)      (struct _cnid_db *cdb);
+    char * (*cnid_resolve)     (struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len);
+    int    (*cnid_update)      (struct _cnid_db *cdb, const cnid_t id, const struct stat *st,
+                                const cnid_t did, char *name, const size_t len);
+    void   (*cnid_close)       (struct _cnid_db *cdb);
+    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);
 };
 typedef struct _cnid_db cnid_db;
 
-/* 
+/*
  * Consolidation of args passedn from main cnid_open to modules cnid_XXX_open, so
  * that it's easier to add aditional args as required.
  */
@@ -88,10 +88,10 @@ struct cnid_open_args {
  * CNID module - represents particular CNID implementation
  */
 struct _cnid_module {
-       char *name;
-       struct list_head db_list;   /* CNID modules are also stored on a bidirectional list. */
-       struct _cnid_db *(*cnid_open)(struct cnid_open_args *args);
-       u_int32_t flags;            /* Flags describing some CNID backend aspects. */
+    char *name;
+    struct list_head db_list;   /* CNID modules are also stored on a bidirectional list. */
+    struct _cnid_db *(*cnid_open)(struct cnid_open_args *args);
+    u_int32_t flags;            /* Flags describing some CNID backend aspects. */
 
 };
 typedef struct _cnid_module cnid_module;
@@ -107,98 +107,21 @@ struct _cnid_db *cnid_open(const char *volpath,
                            mode_t mask,
                            char *type,
                            int flags,
-                           const char *cnidsrv, /* Only for dbd */
-                           const char *cnidport); /* Only for dbd */
-
-cnid_t cnid_add(struct _cnid_db *cdb, const struct stat *st, const cnid_t did, 
-                       const char *name, const size_t len, cnid_t hint);
-
-int    cnid_delete(struct _cnid_db *cdb, cnid_t id);
-
-cnid_t cnid_get   (struct _cnid_db *cdb, const cnid_t did, char *name,const size_t len);
-
-int    cnid_getstamp(struct _cnid_db *cdb, void *buffer, const size_t len);
-
-cnid_t cnid_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
-                       char *name, const size_t len);
-
-char *cnid_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len);
-
-int cnid_update   (struct _cnid_db *cdb, const cnid_t id, const struct stat *st, 
-                       const cnid_t did, char *name, const size_t len);
-
+                           const char *cnidsrv,
+                           const char *cnidport);
+cnid_t cnid_add        (struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
+                        const char *name, const size_t len, cnid_t hint);
+int    cnid_delete     (struct _cnid_db *cdb, cnid_t id);
+cnid_t cnid_get        (struct _cnid_db *cdb, const cnid_t did, char *name,const size_t len);
+int    cnid_getstamp   (struct _cnid_db *cdb, void *buffer, const size_t len);
+cnid_t cnid_lookup     (struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
+                        char *name, const size_t len);
+char  *cnid_resolve    (struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len);
+int    cnid_update     (struct _cnid_db *cdb, const cnid_t id, const struct stat *st,
+                        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);
-
-
-/* This function closes a CNID database and frees all resources assigned to it. */ 
-void cnid_close(struct _cnid_db *db);
+int    cnid_find       (struct _cnid_db *cdb, const char *name, size_t len);
+void   cnid_close      (struct _cnid_db *db);
 
 #endif
-
-/*
- * $Log: cnid.h,v $
- * Revision 1.15  2010-03-31 09:47:32  franklahm
- * clustering support: new per volume option cnidserver
- *
- * Revision 1.14  2009/11/28 13:09:25  didg
- * guard against confused DB returning junk values
- *
- * Revision 1.13  2009/11/24 12:18:19  didg
- * add a flag parameter to cnid open functions
- *
- * Revision 1.12  2005/09/07 15:23:21  didg
- *
- * lazy init dbd database, help with pre tiger OS and a lot of volumes.
- *
- * Revision 1.11  2005/05/03 14:55:12  didg
- *
- * remove gcc warning
- *
- * Revision 1.10  2005/04/28 20:49:51  bfernhomberg
- *
- * - merge branch-netatalk-afp-3x-dev, HEAD was tagged before
- *
- * Revision 1.9.6.8  2005/04/25 22:33:24  lenneis
- * Add a new interface to the cdb and dbd backends: cnid_rebuild_add. It
- * takes dev, ino, did, name and cnid and writes these values unconditionally
- * into the cnid database. To be used in a recovery tool that writes cnids
- * cached in AppleDouble files back into the database. Not used yet by
- * any daemons or command line utilities.
- *
- * Revision 1.9.6.7  2005/02/08 11:46:59  didg
- *
- * warnings fixes from 2.0 branch
- *
- * Revision 1.9.6.6  2004/02/22 18:36:37  didg
- *
- * small clean up
- *
- * Revision 1.9.6.5  2004/01/14 23:15:19  lenneis
- * Check if we can get a DB stamp sucessfully in afs_openvol and fail
- * the open if not.
- *
- * Revision 1.9.6.4  2004/01/10 07:19:31  bfernhomberg
- * add cnid_init prototype
- *
- * Revision 1.9.6.3  2004/01/03 22:42:55  didg
- *
- * better errors handling in afpd for dbd cnid.
- *
- * Revision 1.9.6.2  2004/01/03 22:21:09  didg
- *
- * add nodev volume option (always use 0 for device number).
- *
- * Revision 1.9.6.1  2003/09/09 16:42:20  didg
- *
- * big merge for db frontend and unicode.
- *
- * Revision 1.9.4.2  2003/06/11 15:29:11  rlewczuk
- * Removed obsolete parameter from cnid_add. Spotted by Didier.
- *
- * Revision 1.9.4.1  2003/05/29 07:53:19  rlewczuk
- * Selectable CNIDs. Some refactoring. Propably needs more of refactoring, mainly
- * a well designed API (current API is just an old cnid_* API enclosed in VMT).
- *
- */
-
index 0607aec228c5889a4ac93e02e83feaa269f76cc3..36dee3d8264890402fa6cc7b0f7d233c08efa706 100644 (file)
@@ -43,7 +43,7 @@ struct cnid_dbd_rqst {
     ino_t   ino;
     uint32_t type;
     cnid_t  did;
-    char   *name;
+    char    *name;
     size_t  namelen;
 };
 
@@ -51,7 +51,7 @@ struct cnid_dbd_rply {
     int     result;    
     cnid_t  cnid;
     cnid_t  did;
-    char   *name;
+    char    *name;
     size_t  namelen;
 };
 
index ca2190e5485ad274c3b8aa45ee76b73b9135baaa..d4b85e35bc1e9da75d2c199c9fbb837045873f34 100644 (file)
@@ -270,9 +270,9 @@ time_t t;
 
 /* --------------- */
 cnid_t cnid_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t did,
-                       char *name, const size_t len)
+                   char *name, const size_t len)
 {
-cnid_t ret;
+    cnid_t ret;
 
     block_signal(cdb->flags);
     ret = valide(cdb->cnid_lookup(cdb, st, did, name, len));
@@ -280,6 +280,22 @@ cnid_t ret;
     return ret;
 }
 
+/* --------------- */
+int cnid_find(struct _cnid_db *cdb, const char *name, size_t len)
+{
+    int ret;
+    
+    if (cdb->cnid_find == NULL) {
+        LOG(log_error, logtype_cnid, "cnid_find not supported by CNID backend");        
+        return -1;
+    }
+
+    block_signal(cdb->flags);
+    ret = cdb->cnid_find(cdb, name, len);
+    unblock_signal(cdb->flags);
+    return ret;
+}
+
 /* --------------- */
 char *cnid_resolve(struct _cnid_db *cdb, cnid_t *id, void *buffer, size_t len)
 {
index 60f16f9185efcaf4a1a7d4452b63691c9ac6885c..c33b601c5c78674451885397fddfb435a9a37773 100644 (file)
@@ -454,6 +454,7 @@ static struct _cnid_db *cnid_dbd_new(const char *volpath)
     cdb->cnid_delete = cnid_dbd_delete;
     cdb->cnid_get = cnid_dbd_get;
     cdb->cnid_lookup = cnid_dbd_lookup;
+    cdb->cnid_find = cnid_dbd_find;
     cdb->cnid_nextid = NULL;
     cdb->cnid_resolve = cnid_dbd_resolve;
     cdb->cnid_getstamp = cnid_dbd_getstamp;
@@ -791,6 +792,59 @@ cnid_t cnid_dbd_lookup(struct _cnid_db *cdb, const struct stat *st, const cnid_t
     return id;
 }
 
+/* ---------------------- */
+int cnid_dbd_find(struct _cnid_db *cdb, const char *name, size_t len)
+{
+    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 (len > MAXPATHLEN) {
+        LOG(log_error, logtype_cnid, "cnid_find: Path name is too long");
+        errno = CNID_ERR_PATH;
+        return CNID_INVALID;
+    }
+
+    RQST_RESET(&rqst);
+    rqst.op = CNID_DBD_OP_SEARCH;
+
+    rqst.name = name;
+    rqst.namelen = len;
+
+    LOG(log_debug, logtype_cnid, "cnid_find(\"%s\")", name);
+
+    rply.namelen = 0;
+    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, const cnid_t id, const struct stat *st,
                     const cnid_t did, char *name, const size_t len)
index 6d43f9a0a27ccd1bfc5bd7dad71a3572fc72e719..22db5a5cc0c1d77f4ff44269921244982cf4df10 100644 (file)
@@ -1,7 +1,6 @@
 /*
- * $Id: cnid_dbd.h,v 1.6 2010-03-31 09:47:32 franklahm Exp $
- *
  * Copyright (C) Joerg Lenneis 2003
+ * Copyright (C) Frank Lahm 2010
  * All Rights Reserved.  See COPYING.
  */
 
 
 extern struct _cnid_module cnid_dbd_module;
 extern struct _cnid_db *cnid_dbd_open (struct cnid_open_args *args);
-extern void cnid_dbd_close (struct _cnid_db *);
-extern cnid_t cnid_dbd_add (struct _cnid_db *, const struct stat *, const cnid_t,
-                           char *, const size_t, cnid_t);
-extern cnid_t cnid_dbd_get (struct _cnid_db *, const cnid_t, char *, const size_t); 
-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_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);
-extern cnid_t cnid_dbd_rebuild_add (struct _cnid_db *, const struct stat *,
-                const cnid_t, char *, const size_t, cnid_t);
+extern void   cnid_dbd_close      (struct _cnid_db *);
+extern cnid_t cnid_dbd_add        (struct _cnid_db *, const struct stat *, const cnid_t,
+                                   char *, const size_t, cnid_t);
+extern cnid_t cnid_dbd_get        (struct _cnid_db *, const cnid_t, char *, const size_t); 
+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_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);
+extern cnid_t cnid_dbd_rebuild_add(struct _cnid_db *, const struct stat *,
+                                   const cnid_t, char *, const size_t, cnid_t);
 
 /* FIXME: These functions could be static in cnid_dbd.c */