2 Unix SMB/Netbios implementation.
4 SMB wrapper directory functions
5 Copyright (C) Tim Potter 2000
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 /* We cache lists of workgroups, lists of servers in workgroups, and lists
25 of shares exported by servers. */
27 #define CACHE_TIMEOUT 30
30 struct name_list *prev, *next;
37 struct cached_names *prev, *next;
39 struct name_list *name_list;
44 static struct cached_names *cached_names = NULL;
46 /* Find a list of cached name for a workgroup, server or share list */
48 static struct cached_names *find_cached_names(char *key)
50 struct cached_names *tmp;
52 for (tmp = cached_names; tmp; tmp = tmp->next) {
53 if (strequal(tmp->key, key)) {
61 /* Add a name to a list stored in the state variable */
63 static void add_cached_names(const char *name, uint32 stype,
64 const char *comment, void *state)
66 struct name_list **name_list = (struct name_list **)state;
67 struct name_list *new_name;
69 new_name = (struct name_list *)malloc(sizeof(struct name_list));
70 if (!new_name) return;
72 ZERO_STRUCTP(new_name);
74 new_name->name = strdup(name);
75 new_name->stype = stype;
76 new_name->comment = strdup(comment);
78 DLIST_ADD(*name_list, new_name);
81 static void free_name_list(struct name_list *name_list)
83 struct name_list *tmp = name_list;
86 struct name_list *next;
91 SAFE_FREE(tmp->comment);
98 /* Wrapper for NetServerEnum function */
100 BOOL smbw_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
101 void (*fn)(const char *, uint32, const char *, void *),
104 struct cached_names *names;
105 struct name_list *tmp;
106 time_t now = time(NULL);
110 slprintf(key, PATH_MAX - 1, "%s/%s#%s", cli->desthost,
111 workgroup, (stype == SV_TYPE_DOMAIN_ENUM ? "DOM" : "SRV"));
113 names = find_cached_names(key);
115 if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
116 struct cached_names *new_names = NULL;
118 /* No names cached for this workgroup */
121 new_names = (struct cached_names *)
122 malloc(sizeof(struct cached_names));
124 ZERO_STRUCTP(new_names);
125 DLIST_ADD(cached_names, new_names);
129 /* Dispose of out of date name list */
131 free_name_list(names->name_list);
132 names->name_list = NULL;
137 result = cli_NetServerEnum(cli, workgroup, stype,
139 &new_names->name_list);
141 new_names->cache_timeout = now;
142 new_names->result = result;
143 new_names->key = strdup(key);
148 /* Return names by running callback function. */
150 for (tmp = names->name_list; tmp; tmp = tmp->next)
151 fn(tmp->name, stype, tmp->comment, state);
153 return names->result;
156 /* Wrapper for RNetShareEnum function */
158 int smbw_RNetShareEnum(struct cli_state *cli,
159 void (*fn)(const char *, uint32, const char *, void *),
162 struct cached_names *names;
163 struct name_list *tmp;
164 time_t now = time(NULL);
167 slprintf(key, PATH_MAX - 1, "SHARE/%s", cli->desthost);
169 names = find_cached_names(key);
171 if (names == NULL || (now - names->cache_timeout) > CACHE_TIMEOUT) {
172 struct cached_names *new_names = NULL;
174 /* No names cached for this server */
177 new_names = (struct cached_names *)
178 malloc(sizeof(struct cached_names));
180 ZERO_STRUCTP(new_names);
181 DLIST_ADD(cached_names, new_names);
185 /* Dispose of out of date name list */
187 free_name_list(names->name_list);
188 names->name_list = NULL;
193 new_names->result = cli_RNetShareEnum(cli, add_cached_names,
194 &new_names->name_list);
196 new_names->cache_timeout = now;
197 new_names->key = strdup(key);
202 /* Return names by running callback function. */
204 for (tmp = names->name_list; tmp; tmp = tmp->next)
205 fn(tmp->name, tmp->stype, tmp->comment, state);
207 return names->result;