File: cnid_last.c

package info (click to toggle)
netatalk 3.1.12~ds-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 14,756 kB
  • sloc: ansic: 104,976; sh: 8,247; xml: 7,394; perl: 1,936; makefile: 1,430; python: 1,342; yacc: 309; lex: 49
file content (173 lines) | stat: -rw-r--r-- 4,854 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173

/*
 *
 * Copyright (c) 1999. Adrian Sun (asun@zoology.washington.edu)
 * All Rights Reserved. See COPYRIGHT.
 *
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif /* HAVE_CONFIG_H */

#ifdef CNID_BACKEND_LAST
#include <stdlib.h>
#include "cnid_last.h"
#include <atalk/util.h>
#include <atalk/logger.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <arpa/inet.h>

/* ------------------------ */
cnid_t cnid_last_add(struct _cnid_db *cdb, const struct stat *st,
                     cnid_t did _U_, const char *name _U_, size_t len _U_, cnid_t hint _U_)
{

    /* FIXME: it relies on fact, that this is never called twice for the same file/dir. */
    /* Propably we should look through DID tree. */

    /*
     * First thing:  DID and FNUMs are
     * in the same space for purposes of enumerate (and several
     * other wierd places).  While we consider this Apple's bug,
     * this is the work-around:  In order to maintain constant and
     * unique DIDs and FNUMs, we monotonically generate the DIDs
     * during the session, and derive the FNUMs from the filesystem.
     * Since the DIDs are small, we insure that the FNUMs are fairly
     * large by setting thier high bits to the device number.
     *
     * AFS already does something very similar to this for the
     * inode number, so we don't repeat the procedure.
     *
     * new algorithm:
     * due to complaints over did's being non-persistent,
     * here's the current hack to provide semi-persistent
     * did's:
     *      1) we reserve the first bit for file ids.
     *      2) the next 7 bits are for the device.
     *      3) the remaining 24 bits are for the inode.
     *
     * both the inode and device information are actually hashes
     * that are then truncated to the requisite bit length.
     *
     * it should be okay to use lstat to deal with symlinks.
     */

    struct _cnid_last_private *priv;

    if (!cdb || !(cdb->cnid_db_private))
        return CNID_INVALID;

    priv = (struct _cnid_last_private *) (cdb->cnid_db_private);

    if (S_ISDIR(st->st_mode))
        return htonl(priv->last_did++);
    else
        return htonl((st->st_dev << 16) | (st->st_ino & 0x0000ffff));
}



void cnid_last_close(struct _cnid_db *cdb)
{
    free(cdb->cnid_db_private);
    free(cdb);
}



int cnid_last_delete(struct _cnid_db *cdb _U_, const cnid_t id _U_)
{
    return CNID_INVALID;
}


/* Return CNID for a given did/name. */
cnid_t cnid_last_get(struct _cnid_db *cdb _U_, cnid_t did _U_, const char *name _U_, size_t len _U_)
{
    /* FIXME: it relies on fact, that this is never called twice for the same file/dir. */
    /* Propably we should look through DID tree. */
    return CNID_INVALID;
}


/* */
cnid_t cnid_last_lookup(struct _cnid_db *cdb _U_, const struct stat *st _U_, cnid_t did _U_, 
                        const char *name _U_, size_t len _U_)
{
    /* FIXME: this function doesn't work in [last] scheme ! */
    /* Should be never called or CNID should be somewhat refactored again. */
    return CNID_INVALID;
}


static struct _cnid_db *cnid_last_new(struct vol *vol)
{
    struct _cnid_db *cdb;
    struct _cnid_last_private *priv;

    if ((cdb = (struct _cnid_db *) calloc(1, sizeof(struct _cnid_db))) == NULL)
        return NULL;

    if ((cdb->cnid_db_private = calloc(1, sizeof(struct _cnid_last_private))) == NULL) {
        free(cdb);
        return NULL;
    }

    /* Set up private state */
    priv = (struct _cnid_last_private *) (cdb->cnid_db_private);
    priv->last_did = 17;

    /* Set up standard fields */
    cdb->cnid_db_flags = 0;
    cdb->cnid_add = cnid_last_add;
    cdb->cnid_delete = cnid_last_delete;
    cdb->cnid_get = cnid_last_get;
    cdb->cnid_lookup = cnid_last_lookup;
    cdb->cnid_nextid = NULL;    /* cnid_last_nextid; */
    cdb->cnid_resolve = cnid_last_resolve;
    cdb->cnid_update = cnid_last_update;
    cdb->cnid_close = cnid_last_close;
    cdb->cnid_wipe = NULL;

    return cdb;
}

struct _cnid_db *cnid_last_open(struct cnid_open_args *args)
{
    struct _cnid_db *cdb;

    if ((cdb = cnid_last_new(args->cnid_args_vol)) == NULL) {
        LOG(log_error, logtype_default, "cnid_open: Unable to allocate memory for database");
        return NULL;
    }

    return cdb;
}

struct _cnid_module cnid_last_module = {
    "last",
    {NULL, NULL},
    cnid_last_open,
    0
};

/* Return the did/name pair corresponding to a CNID. */
char *cnid_last_resolve(struct _cnid_db *cdb _U_, cnid_t * id _U_, void *buffer _U_, size_t len _U_)
{
    /* FIXME: frankly, it does not work. As get, add and other functions. */
    return NULL;
}


int cnid_last_update(struct _cnid_db *cdb _U_, cnid_t id _U_, const struct stat *st _U_,
                     cnid_t did  _U_, const char *name  _U_, size_t len _U_)
{
    return 0;
}


#endif /* CNID_BACKEND_LAST */