/build/buildd/libnl-1.0~pre6/lib/cache_mngt.c

00001 /*
00002  * lib/cache_mngt.c     Cache Management
00003  *
00004  *      This library is free software; you can redistribute it and/or
00005  *      modify it under the terms of the GNU Lesser General Public
00006  *      License as published by the Free Software Foundation version 2.1
00007  *      of the License.
00008  *
00009  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
00010  */
00011 
00012 /**
00013  * @ingroup utils
00014  * @defgroup cache_mngt Cache Management
00015  * @{
00016  */
00017 
00018 #include <netlink-local.h>
00019 #include <netlink/netlink.h>
00020 #include <netlink/cache.h>
00021 #include <netlink/utils.h>
00022 
00023 /**
00024  * @name Access Functions
00025  * @{
00026  */
00027 
00028 /**
00029  * Return the cache type of the cache operations
00030  * @arg ops             cache operations
00031  */
00032 char *nl_cache_ops_get_name(struct nl_cache_ops *ops)
00033 {
00034         return ops->co_name;
00035 }
00036 
00037 /** @} */
00038 
00039 /**
00040  * @name Message Type Association
00041  * @{
00042  */
00043 
00044 static struct nl_cache_ops *cache_ops;
00045 
00046 /**
00047  * Associate a message type to a set of cache operations
00048  * @arg protocol                netlink protocol
00049  * @arg message_type            netlink message type
00050  *
00051  * Associates the specified netlink message type with
00052  * a registered set of cache operations.
00053  *
00054  * @return The cache operations or NULL if no association
00055  *         could be made.
00056  */
00057 struct nl_cache_ops *nl_cache_mngt_associate(int protocol, int message_type)
00058 {
00059         int i;
00060         struct nl_cache_ops *ops;
00061 
00062         for (ops = cache_ops; ops; ops = ops->co_next)
00063                 for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++)
00064                         if (ops->co_msgtypes[i].mt_id == message_type &&
00065                             ops->co_protocol == protocol)
00066                                 return ops;
00067 
00068         return NULL;
00069 }
00070 
00071 /**
00072  * Convert message type to character string.
00073  * @arg ops             Cache operations.
00074  * @arg msgtype         Message type.
00075  * @arg buf             Destination buffer.
00076  * @arg len             Size of destination buffer.
00077  *
00078  * Converts a message type to a character string and stores it in the
00079  * provided buffer.
00080  *
00081  * @return The destination buffer or the message type encoded in
00082  *         hexidecimal form if no match was found.
00083  */
00084 char *nl_cache_mngt_type2name(struct nl_cache_ops *ops, int msgtype,
00085                               char *buf, size_t len)
00086 {
00087         int i;
00088 
00089         for (i = 0; ops->co_msgtypes[i].mt_id >= 0; i++) {
00090                 if (ops->co_msgtypes[i].mt_id == msgtype) {
00091                         snprintf(buf, len, "%s::%s",
00092                                  ops->co_name,
00093                                  ops->co_msgtypes[i].mt_name);
00094                         return buf;
00095                 }
00096         }
00097 
00098         snprintf(buf, len, "%s->0x%x()", ops->co_name, msgtype);
00099         return buf;
00100 }
00101 
00102 /** @} */
00103 
00104 /**
00105  * @name Cache Type Management
00106  * @{
00107  */
00108 
00109 /**
00110  * Lookup the set cache operations of a certain cache type
00111  * @arg name            name of the cache type
00112  *
00113  * @return The cache operations or NULL if no operations
00114  *         have been registered under the specified name.
00115  */
00116 struct nl_cache_ops *nl_cache_mngt_lookup(const char *name)
00117 {
00118         struct nl_cache_ops *ops;
00119 
00120         for (ops = cache_ops; ops; ops = ops->co_next)
00121                 if (!strcmp(ops->co_name, name))
00122                         return ops;
00123 
00124         return NULL;
00125 }
00126 
00127 /**
00128  * Register a set of cache operations
00129  * @arg ops             cache operations
00130  *
00131  * Called by users of caches to announce the avaibility of
00132  * a certain cache type.
00133  *
00134  * @return 0 on success or a negative error code.
00135  */
00136 int nl_cache_mngt_register(struct nl_cache_ops *ops)
00137 {
00138         if (!ops->co_name)
00139                 return nl_error(EINVAL, "No cache name specified");
00140 
00141         if (nl_cache_mngt_lookup(ops->co_name))
00142                 return nl_error(EEXIST, "Cache operations already exist");
00143             
00144         ops->co_next = cache_ops;
00145         cache_ops = ops;
00146 
00147         NL_DBG(1, "Registered cache operations %s\n", ops->co_name);
00148 
00149         return 0;
00150 }
00151 
00152 /**
00153  * Unregister a set of cache operations
00154  * @arg ops             cache operations
00155  *
00156  * Called by users of caches to announce a set of
00157  * cache operations is no longer available. The
00158  * specified cache operations must have been registered
00159  * previously using nl_cache_mngt_register()
00160  *
00161  * @return 0 on success or a negative error code
00162  */
00163 int nl_cache_mngt_unregister(struct nl_cache_ops *ops)
00164 {
00165         struct nl_cache_ops *t, **tp;
00166 
00167         for (tp = &cache_ops; (t=*tp) != NULL; tp = &t->co_next)
00168                 if (t == ops)
00169                         break;
00170 
00171         if (!t)
00172                 return nl_error(ENOENT, "No such cache operations");
00173 
00174         NL_DBG(1, "Unregistered cache operations %s\n", ops->co_name);
00175 
00176         *tp = t->co_next;
00177         return 0;
00178 }
00179 
00180 /** @} */
00181 
00182 /**
00183  * @name Global Cache Provisioning/Requiring
00184  * @{
00185  */
00186 
00187 /**
00188  * Provide a cache for global use
00189  * @arg cache           cache to provide
00190  *
00191  * Offers the specified cache to be used by other modules.
00192  * Only one cache per type may be shared at a time,
00193  * a previsouly provided caches will be overwritten.
00194  */
00195 void nl_cache_mngt_provide(struct nl_cache *cache)
00196 {
00197         struct nl_cache_ops *ops;
00198 
00199         ops = nl_cache_mngt_lookup(cache->c_ops->co_name);
00200         if (!ops)
00201                 BUG();
00202         else
00203                 ops->co_major_cache = cache;
00204 }
00205 
00206 /**
00207  * Unprovide a cache for global use
00208  * @arg cache           cache to unprovide
00209  *
00210  * Cancels the offer to use a cache globally. The
00211  * cache will no longer be returned via lookups but
00212  * may still be in use.
00213  */
00214 void nl_cache_mngt_unprovide(struct nl_cache *cache)
00215 {
00216         struct nl_cache_ops *ops;
00217 
00218         ops = nl_cache_mngt_lookup(cache->c_ops->co_name);
00219         if (!ops)
00220                 BUG();
00221         else if (ops->co_major_cache == cache)
00222                 ops->co_major_cache = NULL;
00223 }
00224 
00225 /**
00226  * Demand the use of a global cache
00227  * @arg name            name of the required cache type
00228  *
00229  * Trys to find a cache of the specified type for global
00230  * use.
00231  *
00232  * @return A cache provided by another subsystem of the
00233  *         specified type marked to be available.
00234  */
00235 struct nl_cache *nl_cache_mngt_require(const char *name)
00236 {
00237         struct nl_cache_ops *ops;
00238 
00239         ops = nl_cache_mngt_lookup(name);
00240         if (!ops || !ops->co_major_cache) {
00241                 fprintf(stderr, "Application BUG: Your application must "
00242                         "call nl_cache_mngt_provide() and\nprovide a valid "
00243                         "%s cache to be used for internal lookups.\nSee the "
00244                         " API documentation for more details.\n", name);
00245 
00246                 return NULL;
00247         }
00248         
00249         return ops->co_major_cache;
00250 }
00251 
00252 /** @} */
00253 
00254 /** @} */

Generated on Fri Apr 27 14:14:07 2007 for libnl by  doxygen 1.5.1