A fix to allow configure to find iconv on a number of systems including those
[Samba/gebeck_regimport.git] / source3 / smbwrapper / smbw_cache.c
blobfcb0eda80505d9ed78c2ce7af97b64cd8b3f6722
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 = (struct name_list *)malloc(sizeof(struct name_list));
69 if (!new_name) return;
71 ZERO_STRUCTP(new_name);
73 new_name->name = strdup(name);
74 new_name->stype = stype;
75 new_name->comment = 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 = (struct cached_names *)
121 malloc(sizeof(struct cached_names));
123 ZERO_STRUCTP(new_names);
124 DLIST_ADD(cached_names, new_names);
126 } else {
128 /* Dispose of out of date name list */
130 free_name_list(names->name_list);
131 names->name_list = NULL;
133 new_names = names;
136 result = cli_NetServerEnum(cli, workgroup, stype,
137 add_cached_names,
138 &new_names->name_list);
140 new_names->cache_timeout = now;
141 new_names->result = result;
142 new_names->key = strdup(key);
144 names = new_names;
147 /* Return names by running callback function. */
149 for (tmp = names->name_list; tmp; tmp = tmp->next)
150 fn(tmp->name, stype, tmp->comment, state);
152 return names->result;
155 /* Wrapper for RNetShareEnum function */
157 int smbw_RNetShareEnum(struct cli_state *cli,
158 void (*fn)(const char *, uint32, const char *, void *),
159 void *state)
161 struct cached_names *names;
162 struct name_list *tmp;
163 time_t now = time(NULL);
164 char key[PATH_MAX];
166 slprintf(key, PATH_MAX - 1, "SHARE/%s", cli->desthost);
168 names = find_cached_names(key);
170 if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
171 struct cached_names *new_names = NULL;
173 /* No names cached for this server */
175 if (names == NULL) {
176 new_names = (struct cached_names *)
177 malloc(sizeof(struct cached_names));
179 ZERO_STRUCTP(new_names);
180 DLIST_ADD(cached_names, new_names);
182 } else {
184 /* Dispose of out of date name list */
186 free_name_list(names->name_list);
187 names->name_list = NULL;
189 new_names = names;
192 new_names->result = cli_RNetShareEnum(cli, add_cached_names,
193 &new_names->name_list);
195 new_names->cache_timeout = now;
196 new_names->key = strdup(key);
198 names = new_names;
201 /* Return names by running callback function. */
203 for (tmp = names->name_list; tmp; tmp = tmp->next)
204 fn(tmp->name, tmp->stype, tmp->comment, state);
206 return names->result;