r21400: fix version to 3.0.24 (Thanks Karolin)
[Samba.git] / source / smbwrapper / smbw_cache.c
blobcfa8ab1f76c35cb659f2db0d970fa7958edbbd2c
1 /*
2 Unix SMB/CIFS implementation.
3 SMB wrapper directory functions
4 Copyright (C) Tim Potter 2000
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "includes.h"
23 /* We cache lists of workgroups, lists of servers in workgroups, and lists
24 of shares exported by servers. */
26 #define CACHE_TIMEOUT 30
28 struct name_list {
29 struct name_list *prev, *next;
30 char *name;
31 uint32 stype;
32 char *comment;
35 struct cached_names {
36 struct cached_names *prev, *next;
37 char *key;
38 struct name_list *name_list;
39 time_t cache_timeout;
40 int result;
43 static struct cached_names *cached_names = NULL;
45 /* Find a list of cached name for a workgroup, server or share list */
47 static struct cached_names *find_cached_names(char *key)
49 struct cached_names *tmp;
51 for (tmp = cached_names; tmp; tmp = tmp->next) {
52 if (strequal(tmp->key, key)) {
53 return tmp;
57 return NULL;
60 /* Add a name to a list stored in the state variable */
62 static void add_cached_names(const char *name, uint32 stype,
63 const char *comment, void *state)
65 struct name_list **name_list = (struct name_list **)state;
66 struct name_list *new_name;
68 new_name = SMB_MALLOC_P(struct name_list);
69 if (!new_name) return;
71 ZERO_STRUCTP(new_name);
73 new_name->name = SMB_STRDUP(name);
74 new_name->stype = stype;
75 new_name->comment = SMB_STRDUP(comment);
77 DLIST_ADD(*name_list, new_name);
80 static void free_name_list(struct name_list *name_list)
82 struct name_list *tmp = name_list;
84 while(tmp) {
85 struct name_list *next;
87 next = tmp->next;
89 SAFE_FREE(tmp->name);
90 SAFE_FREE(tmp->comment);
91 SAFE_FREE(tmp);
93 tmp = next;
97 /* Wrapper for NetServerEnum function */
99 BOOL smbw_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
100 void (*fn)(const char *, uint32, const char *, void *),
101 void *state)
103 struct cached_names *names;
104 struct name_list *tmp;
105 time_t now = time(NULL);
106 char key[PATH_MAX];
107 BOOL result = True;
109 slprintf(key, PATH_MAX - 1, "%s/%s#%s", cli->desthost,
110 workgroup, (stype == SV_TYPE_DOMAIN_ENUM ? "DOM" : "SRV"));
112 names = find_cached_names(key);
114 if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
115 struct cached_names *new_names = NULL;
117 /* No names cached for this workgroup */
119 if (names == NULL) {
120 new_names = SMB_MALLOC_P(struct cached_names);
122 ZERO_STRUCTP(new_names);
123 DLIST_ADD(cached_names, new_names);
125 } else {
127 /* Dispose of out of date name list */
129 free_name_list(names->name_list);
130 names->name_list = NULL;
132 new_names = names;
135 result = cli_NetServerEnum(cli, workgroup, stype,
136 add_cached_names,
137 &new_names->name_list);
139 new_names->cache_timeout = now;
140 new_names->result = result;
141 new_names->key = SMB_STRDUP(key);
143 names = new_names;
146 /* Return names by running callback function. */
148 for (tmp = names->name_list; tmp; tmp = tmp->next)
149 fn(tmp->name, stype, tmp->comment, state);
151 return names->result;
154 /* Wrapper for RNetShareEnum function */
156 int smbw_RNetShareEnum(struct cli_state *cli,
157 void (*fn)(const char *, uint32, const char *, void *),
158 void *state)
160 struct cached_names *names;
161 struct name_list *tmp;
162 time_t now = time(NULL);
163 char key[PATH_MAX];
165 slprintf(key, PATH_MAX - 1, "SHARE/%s", cli->desthost);
167 names = find_cached_names(key);
169 if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
170 struct cached_names *new_names = NULL;
172 /* No names cached for this server */
174 if (names == NULL) {
175 new_names = SMB_MALLOC_P(struct cached_names);
177 ZERO_STRUCTP(new_names);
178 DLIST_ADD(cached_names, new_names);
180 } else {
182 /* Dispose of out of date name list */
184 free_name_list(names->name_list);
185 names->name_list = NULL;
187 new_names = names;
190 new_names->result = cli_RNetShareEnum(cli, add_cached_names,
191 &new_names->name_list);
193 new_names->cache_timeout = now;
194 new_names->key = SMB_STRDUP(key);
196 names = new_names;
199 /* Return names by running callback function. */
201 for (tmp = names->name_list; tmp; tmp = tmp->next)
202 fn(tmp->name, tmp->stype, tmp->comment, state);
204 return names->result;