00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026
00027 #include "include/libsmbclient.h"
00028 #include "../include/libsmb_internal.h"
00029
00030 int smbc_default_cache_functions(SMBCCTX * context);
00031
00032
00033
00034
00035
00036 struct smbc_server_cache {
00037 char *server_name;
00038 char *share_name;
00039 char *workgroup;
00040 char *username;
00041 SMBCSRV *server;
00042
00043 struct smbc_server_cache *next, *prev;
00044 };
00045
00046
00047
00048
00049
00050
00051
00052 static int smbc_add_cached_server(SMBCCTX * context, SMBCSRV * newsrv,
00053 const char * server, const char * share,
00054 const char * workgroup, const char * username)
00055 {
00056 struct smbc_server_cache * srvcache = NULL;
00057
00058 if (!(srvcache = SMB_MALLOC_P(struct smbc_server_cache))) {
00059 errno = ENOMEM;
00060 DEBUG(3, ("Not enough space for server cache allocation\n"));
00061 return 1;
00062 }
00063
00064 ZERO_STRUCTP(srvcache);
00065
00066 srvcache->server = newsrv;
00067
00068 srvcache->server_name = SMB_STRDUP(server);
00069 if (!srvcache->server_name) {
00070 errno = ENOMEM;
00071 goto failed;
00072 }
00073
00074 srvcache->share_name = SMB_STRDUP(share);
00075 if (!srvcache->share_name) {
00076 errno = ENOMEM;
00077 goto failed;
00078 }
00079
00080 srvcache->workgroup = SMB_STRDUP(workgroup);
00081 if (!srvcache->workgroup) {
00082 errno = ENOMEM;
00083 goto failed;
00084 }
00085
00086 srvcache->username = SMB_STRDUP(username);
00087 if (!srvcache->username) {
00088 errno = ENOMEM;
00089 goto failed;
00090 }
00091
00092 DLIST_ADD((context->server_cache), srvcache);
00093 return 0;
00094
00095 failed:
00096 SAFE_FREE(srvcache->server_name);
00097 SAFE_FREE(srvcache->share_name);
00098 SAFE_FREE(srvcache->workgroup);
00099 SAFE_FREE(srvcache->username);
00100 SAFE_FREE(srvcache);
00101
00102 return 1;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112 static SMBCSRV * smbc_get_cached_server(SMBCCTX * context, const char * server,
00113 const char * share, const char * workgroup, const char * user)
00114 {
00115 struct smbc_server_cache * srv = NULL;
00116
00117
00118 for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) {
00119
00120 if (strcmp(server,srv->server_name) == 0 &&
00121 strcmp(workgroup,srv->workgroup) == 0 &&
00122 strcmp(user, srv->username) == 0) {
00123
00124
00125 if (strcmp(share, srv->share_name) == 0) {
00126 return srv->server;
00127 }
00128
00129
00130
00131
00132
00133
00134 if (*share == '\0' || strcmp(share, "*IPC$") == 0)
00135 continue;
00136
00137
00138
00139
00140
00141 if (*srv->share_name == '\0' ||
00142 strcmp(srv->share_name, "*IPC$") == 0)
00143 continue;
00144
00145
00146
00147
00148
00149
00150 if (context->options.one_share_per_server) {
00151
00152
00153
00154
00155
00156 if (! cli_tdis(srv->server->cli)) {
00157
00158 cli_shutdown(srv->server->cli);
00159 srv->server->cli = NULL;
00160 context->callbacks.remove_cached_srv_fn(context, srv->server);
00161 continue;
00162 }
00163
00164
00165
00166
00167
00168
00169 SAFE_FREE(srv->share_name);
00170 srv->share_name = SMB_STRDUP(share);
00171 if (!srv->share_name) {
00172
00173 cli_shutdown(srv->server->cli);
00174 srv->server->cli = NULL;
00175 context->callbacks.remove_cached_srv_fn(context, srv->server);
00176 continue;
00177 }
00178
00179
00180 return srv->server;
00181 }
00182 }
00183 }
00184
00185 return NULL;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 static int smbc_remove_cached_server(SMBCCTX * context, SMBCSRV * server)
00195 {
00196 struct smbc_server_cache * srv = NULL;
00197
00198 for (srv=((struct smbc_server_cache *)context->server_cache);srv;srv=srv->next) {
00199 if (server == srv->server) {
00200
00201
00202 DLIST_REMOVE(context->server_cache, srv);
00203 SAFE_FREE(srv->server_name);
00204 SAFE_FREE(srv->share_name);
00205 SAFE_FREE(srv->workgroup);
00206 SAFE_FREE(srv->username);
00207 SAFE_FREE(srv);
00208 return 0;
00209 }
00210 }
00211
00212 return 1;
00213 }
00214
00215
00216
00217
00218
00219
00220 static int smbc_purge_cached(SMBCCTX * context)
00221 {
00222 struct smbc_server_cache * srv;
00223 struct smbc_server_cache * next;
00224 int could_not_purge_all = 0;
00225
00226 for (srv = ((struct smbc_server_cache *) context->server_cache),
00227 next = (srv ? srv->next :NULL);
00228 srv;
00229 srv = next, next = (srv ? srv->next : NULL)) {
00230
00231 if (smbc_remove_unused_server(context, srv->server)) {
00232
00233 could_not_purge_all = 1;
00234 }
00235 }
00236 return could_not_purge_all;
00237 }
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248 int smbc_default_cache_functions(SMBCCTX * context)
00249 {
00250 context->callbacks.add_cached_srv_fn = smbc_add_cached_server;
00251 context->callbacks.get_cached_srv_fn = smbc_get_cached_server;
00252 context->callbacks.remove_cached_srv_fn = smbc_remove_cached_server;
00253 context->callbacks.purge_cached_fn = smbc_purge_cached;
00254
00255 return 0;
00256 }