libsmb/libsmb_cache.c

説明を見る。
00001 
00002 /* 
00003    Unix SMB/CIFS implementation.
00004    SMB client library implementation (server cache)
00005    Copyright (C) Andrew Tridgell 1998
00006    Copyright (C) Richard Sharpe 2000
00007    Copyright (C) John Terpstra 2000
00008    Copyright (C) Tom Jansen (Ninja ISD) 2002 
00009    
00010    This program is free software; you can redistribute it and/or modify
00011    it under the terms of the GNU General Public License as published by
00012    the Free Software Foundation; either version 2 of the License, or
00013    (at your option) any later version.
00014    
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019    
00020    You should have received a copy of the GNU General Public License
00021    along with this program; if not, write to the Free Software
00022    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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  * Structure we use if internal caching mechanism is used 
00034  * nothing fancy here.
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  * Add a new connection to the server cache.
00050  * This function is only used if the external cache is not enabled 
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  * Search the server cache for a server 
00109  * returns server handle on success, NULL on error (not found)
00110  * This function is only used if the external cache is not enabled 
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         /* Search the cache lines */
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                         /* If the share name matches, we're cool */
00125                         if (strcmp(share, srv->share_name) == 0) {
00126                                 return srv->server;
00127                         }
00128 
00129                         /*
00130                          * We only return an empty share name or the attribute
00131                          * server on an exact match (which would have been
00132                          * caught above).
00133                          */
00134                         if (*share == '\0' || strcmp(share, "*IPC$") == 0)
00135                                 continue;
00136 
00137                         /*
00138                          * Never return an empty share name or the attribute
00139                          * server if it wasn't what was requested.
00140                          */
00141                         if (*srv->share_name == '\0' ||
00142                             strcmp(srv->share_name, "*IPC$") == 0)
00143                                 continue;
00144 
00145                         /*
00146                          * If we're only allowing one share per server, then
00147                          * a connection to the server (other than the
00148                          * attribute server connection) is cool.
00149                          */
00150                         if (context->options.one_share_per_server) {
00151                                 /*
00152                                  * The currently connected share name
00153                                  * doesn't match the requested share, so
00154                                  * disconnect from the current share.
00155                                  */
00156                                 if (! cli_tdis(srv->server->cli)) {
00157                                         /* Sigh. Couldn't disconnect. */
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                                  * Save the new share name.  We've
00166                                  * disconnected from the old share, and are
00167                                  * about to connect to the new one.
00168                                  */
00169                                 SAFE_FREE(srv->share_name);
00170                                 srv->share_name = SMB_STRDUP(share);
00171                                 if (!srv->share_name) {
00172                                         /* Out of memory. */
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  * Search the server cache for a server and remove it
00191  * returns 0 on success
00192  * This function is only used if the external cache is not enabled 
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                         /* remove this sucker */
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         /* server not found */
00212         return 1;
00213 }
00214 
00215 
00216 /*
00217  * Try to remove all the servers in cache
00218  * returns 1 on failure and 0 if all servers could be removed.
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                         /* could not be removed */
00233                         could_not_purge_all = 1;
00234                 }
00235         }
00236         return could_not_purge_all;
00237 }
00238 
00239 
00240 
00241 /*
00242  * This functions initializes all server-cache related functions 
00243  * to the default (internal) system.
00244  *
00245  * We use this to make the rest of the cache system static.
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 }

Sambaに対してSat Aug 29 21:23:05 2009に生成されました。  doxygen 1.4.7