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
= (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
;
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
= (struct cached_names
*)
121 malloc(sizeof(struct cached_names
));
123 ZERO_STRUCTP(new_names
);
124 DLIST_ADD(cached_names
, new_names
);
128 /* Dispose of out of date name list */
130 free_name_list(names
->name_list
);
131 names
->name_list
= NULL
;
136 result
= cli_NetServerEnum(cli
, workgroup
, stype
,
138 &new_names
->name_list
);
140 new_names
->cache_timeout
= now
;
141 new_names
->result
= result
;
142 new_names
->key
= strdup(key
);
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 *),
161 struct cached_names
*names
;
162 struct name_list
*tmp
;
163 time_t now
= time(NULL
);
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 */
176 new_names
= (struct cached_names
*)
177 malloc(sizeof(struct cached_names
));
179 ZERO_STRUCTP(new_names
);
180 DLIST_ADD(cached_names
, new_names
);
184 /* Dispose of out of date name list */
186 free_name_list(names
->name_list
);
187 names
->name_list
= NULL
;
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
);
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
;