]> arthur.barton.de Git - netatalk.git/blob - libatalk/cnid/hash/cnid_hash_add.c
304b599bc30082b724b90c9ee66113247f37be56
[netatalk.git] / libatalk / cnid / hash / cnid_hash_add.c
1 /*
2  * $Id: cnid_hash_add.c,v 1.1.2.1 2003-09-09 16:42:21 didg Exp $
3  *
4  * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
5  * All Rights Reserved. See COPYRIGHT.
6  *
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif /* HAVE_CONFIG_H */
12
13 #ifdef CNID_BACKEND_HASH
14
15 #include "cnid_hash.h"
16 #include <atalk/util.h>
17 #include <sys/param.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <unistd.h>
21 #include <atalk/logger.h>
22
23 /* ------------------------ */
24 cnid_t cnid_hash_add(struct _cnid_db *cdb, const struct stat *st,
25                      const cnid_t did, const char *name, const int len, cnid_t hint)
26 {
27     struct stat lst;
28     const struct stat *lstp;
29     cnid_t aint;
30     struct _cnid_hash_private *priv;
31     static char buffer[sizeof(cnid_t) + MAXPATHLEN + 1];        
32     TDB_DATA key, data;       
33     
34     if (!cdb || !(cdb->_private))
35         return CNID_INVALID;
36
37     priv = (struct _cnid_hash_private *) (cdb->_private);
38     lstp = lstat(name, &lst) < 0 ? st : &lst;
39     aint = lstp->st_ino & 0xffffffff;
40
41     if (!priv->st_set) {
42         priv->st_set = 1;
43         priv->st_dev = lstp->st_dev;
44     }
45     if (!(priv->error & HASH_ERROR_DEV)) {
46         if (lstp->st_dev != priv->st_dev) {
47             priv->error |= HASH_ERROR_DEV;
48             LOG(log_error, logtype_default, "cnid_hash_add: %s not on the same device", name);
49         }
50     }
51     if (!(priv->error & HASH_ERROR_LINK)) {
52         if (!S_ISDIR(lstp->st_mode) && lstp->st_nlink > 1) {
53             priv->error |= HASH_ERROR_DEV;
54             LOG(log_error, logtype_default, "cnid_hash_add: %s more than one hardlink", name);
55         }
56     }
57     if (sizeof(ino_t) > 4 && !(priv->error & HASH_ERROR_INODE)) {
58         if (aint != lstp->st_ino) {
59             priv->error |= HASH_ERROR_INODE;
60             LOG(log_error, logtype_default, "cnid_hash_add: %s high bits set, duplicate", name);
61         }
62     }
63     key.dptr = (char *)&aint;
64     key.dsize = sizeof(cnid_t);
65                 
66     memcpy(buffer, &did, sizeof(cnid_t));
67     memcpy(buffer+sizeof(cnid_t), name, len +1);
68     data.dptr = buffer;
69     data.dsize = len+1 +sizeof(cnid_t);
70     if (tdb_store(priv->tdb, key, data, TDB_REPLACE)) {
71         LOG(log_error, logtype_default, "cnid_hash_add: unable to add %s", name);
72     }
73     return aint;
74 }
75
76 #endif /* CNID_BACKEND_HASH */