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.
23 /* We cache lists of workgroups, lists of servers in workgroups, and lists
24 of shares exported by servers. */
26 #define CACHE_TIMEOUT 30
29 struct name_list
*prev
, *next
;
36 struct cached_names
*prev
, *next
;
38 struct name_list
*name_list
;
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
)) {
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
;
85 struct name_list
*next
;
90 SAFE_FREE(tmp
->comment
);
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 *),
103 struct cached_names
*names
;
104 struct name_list
*tmp
;
105 time_t now
= time(NULL
);
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 */
120 new_names
= SMB_MALLOC_P(struct cached_names
);
122 ZERO_STRUCTP(new_names
);
123 DLIST_ADD(cached_names
, new_names
);
127 /* Dispose of out of date name list */
129 free_name_list(names
->name_list
);
130 names
->name_list
= NULL
;
135 result
= cli_NetServerEnum(cli
, workgroup
, stype
,
137 &new_names
->name_list
);
139 new_names
->cache_timeout
= now
;
140 new_names
->result
= result
;
141 new_names
->key
= SMB_STRDUP(key
);
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 *),
160 struct cached_names
*names
;
161 struct name_list
*tmp
;
162 time_t now
= time(NULL
);
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 */
175 new_names
= SMB_MALLOC_P(struct cached_names
);
177 ZERO_STRUCTP(new_names
);
178 DLIST_ADD(cached_names
, new_names
);
182 /* Dispose of out of date name list */
184 free_name_list(names
->name_list
);
185 names
->name_list
= NULL
;
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
);
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
;