2 Unix SMB/CIFS implementation.
3 SMB client library implementation (server cache)
4 Copyright (C) Andrew Tridgell 1998
5 Copyright (C) Richard Sharpe 2000
6 Copyright (C) John Terpstra 2000
7 Copyright (C) Tom Jansen (Ninja ISD) 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "libsmb/libsmb.h"
25 #include "libsmbclient.h"
26 #include "libsmb_internal.h"
29 * Structure we use if internal caching mechanism is used
32 struct smbc_server_cache
{
39 struct smbc_server_cache
*next
, *prev
;
45 * Add a new connection to the server cache.
46 * This function is only used if the external cache is not enabled
49 SMBC_add_cached_server(SMBCCTX
* context
,
53 const char * workgroup
,
54 const char * username
)
56 struct smbc_server_cache
* srvcache
= NULL
;
58 srvcache
= SMB_CALLOC_ARRAY(struct smbc_server_cache
, 1);
59 if (srvcache
== NULL
) {
60 DEBUG(3, ("Not enough space for server cache allocation\n"));
65 srvcache
->server
= newsrv
;
67 srvcache
->server_name
= SMB_STRDUP(server
);
68 if (!srvcache
->server_name
) {
72 srvcache
->share_name
= SMB_STRDUP(share
);
73 if (!srvcache
->share_name
) {
77 srvcache
->workgroup
= SMB_STRDUP(workgroup
);
78 if (!srvcache
->workgroup
) {
82 srvcache
->username
= SMB_STRDUP(username
);
83 if (!srvcache
->username
) {
87 DLIST_ADD(context
->internal
->server_cache
, srvcache
);
91 SAFE_FREE(srvcache
->server_name
);
92 SAFE_FREE(srvcache
->share_name
);
93 SAFE_FREE(srvcache
->workgroup
);
94 SAFE_FREE(srvcache
->username
);
104 * Search the server cache for a server
105 * returns server handle on success, NULL on error (not found)
106 * This function is only used if the external cache is not enabled
109 SMBC_get_cached_server(SMBCCTX
* context
,
112 const char * workgroup
,
115 struct smbc_server_cache
* srv
= NULL
;
117 /* Search the cache lines */
118 for (srv
= context
->internal
->server_cache
; srv
; srv
= srv
->next
) {
120 if (strcmp(server
,srv
->server_name
) == 0 &&
121 strcmp(workgroup
,srv
->workgroup
) == 0 &&
122 strcmp(user
, srv
->username
) == 0) {
124 /* If the share name matches, we're cool */
125 if (strcmp(share
, srv
->share_name
) == 0) {
130 * We only return an empty share name or the attribute
131 * server on an exact match (which would have been
134 if (*share
== '\0' || strcmp(share
, "*IPC$") == 0)
138 * Never return an empty share name or the attribute
139 * server if it wasn't what was requested.
141 if (*srv
->share_name
== '\0' ||
142 strcmp(srv
->share_name
, "*IPC$") == 0)
146 * If we're only allowing one share per server, then
147 * a connection to the server (other than the
148 * attribute server connection) is cool.
150 if (smbc_getOptionOneSharePerServer(context
)) {
153 * The currently connected share name
154 * doesn't match the requested share, so
155 * disconnect from the current share.
157 status
= cli_tdis(srv
->server
->cli
);
158 if (!NT_STATUS_IS_OK(status
)) {
159 /* Sigh. Couldn't disconnect. */
160 cli_shutdown(srv
->server
->cli
);
161 srv
->server
->cli
= NULL
;
162 smbc_getFunctionRemoveCachedServer(context
)(context
, srv
->server
);
167 * Save the new share name. We've
168 * disconnected from the old share, and are
169 * about to connect to the new one.
171 SAFE_FREE(srv
->share_name
);
172 srv
->share_name
= SMB_STRDUP(share
);
173 if (!srv
->share_name
) {
175 cli_shutdown(srv
->server
->cli
);
176 srv
->server
->cli
= NULL
;
177 smbc_getFunctionRemoveCachedServer(context
)(context
, srv
->server
);
191 * Search the server cache for a server and remove it
192 * returns 0 on success
193 * This function is only used if the external cache is not enabled
196 SMBC_remove_cached_server(SMBCCTX
* context
,
199 struct smbc_server_cache
* srv
= NULL
;
201 for (srv
= context
->internal
->server_cache
; srv
; srv
= srv
->next
) {
202 if (server
== srv
->server
) {
204 /* remove this sucker */
205 DLIST_REMOVE(context
->internal
->server_cache
, srv
);
206 SAFE_FREE(srv
->server_name
);
207 SAFE_FREE(srv
->share_name
);
208 SAFE_FREE(srv
->workgroup
);
209 SAFE_FREE(srv
->username
);
214 /* server not found */
220 * Try to remove all the servers in cache
221 * returns 1 on failure and 0 if all servers could be removed.
224 SMBC_purge_cached_servers(SMBCCTX
* context
)
226 struct smbc_server_cache
* srv
;
227 struct smbc_server_cache
* next
;
228 int could_not_purge_all
= 0;
230 for (srv
= context
->internal
->server_cache
,
231 next
= (srv
? srv
->next
:NULL
);
234 next
= (srv
? srv
->next
: NULL
)) {
236 if (SMBC_remove_unused_server(context
, srv
->server
)) {
237 /* could not be removed */
238 could_not_purge_all
= 1;
241 return could_not_purge_all
;