root/source3/utils/net_cache.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. print_cache_entry
  2. delete_cache_entry
  3. parse_timeout
  4. net_cache_add
  5. net_cache_del
  6. net_cache_get
  7. net_cache_search
  8. net_cache_list
  9. net_cache_flush
  10. net_cache

   1 /*
   2    Samba Unix/Linux SMB client library
   3    Distributed SMB/CIFS Server Management Utility
   4    Copyright (C) Rafal Szczesniak    2002
   5 
   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 3 of the License, or
   9    (at your option) any later version.
  10 
  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.
  15 
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 #include "includes.h"
  21 #include "net.h"
  22 
  23 /**
  24  * @file net_cache.c
  25  * @brief This is part of the net tool which is basically command
  26  *        line wrapper for gencache.c functions (mainly for testing)
  27  *
  28  **/
  29 
  30 
  31 /*
  32  * These routines are used via gencache_iterate() to display the cache's contents
  33  * (print_cache_entry) and to flush it (delete_cache_entry).
  34  * Both of them are defined by first arg of gencache_iterate() routine.
  35  */
  36 static void print_cache_entry(const char* keystr, const char* datastr,
     /* [<][>][^][v][top][bottom][index][help] */
  37                               const time_t timeout, void* dptr)
  38 {
  39         char *timeout_str;
  40         char *alloc_str = NULL;
  41         time_t now_t = time(NULL);
  42         struct tm timeout_tm, *now_tm;
  43         /* localtime returns statically allocated pointer, so timeout_tm
  44            has to be copied somewhere else */
  45 
  46         now_tm = localtime(&timeout);
  47         if (!now_tm) {
  48                 return;
  49         }
  50         memcpy(&timeout_tm, now_tm, sizeof(struct tm));
  51         now_tm = localtime(&now_t);
  52         if (!now_tm) {
  53                 return;
  54         }
  55 
  56         /* form up timeout string depending whether it's today's date or not */
  57         if (timeout_tm.tm_year != now_tm->tm_year ||
  58                         timeout_tm.tm_mon != now_tm->tm_mon ||
  59                         timeout_tm.tm_mday != now_tm->tm_mday) {
  60 
  61                 timeout_str = asctime(&timeout_tm);
  62                 if (!timeout_str) {
  63                         return;
  64                 }
  65                 timeout_str[strlen(timeout_str) - 1] = '\0';    /* remove tailing CR */
  66         } else {
  67                 if (asprintf(&alloc_str, "%.2d:%.2d:%.2d", timeout_tm.tm_hour,
  68                          timeout_tm.tm_min, timeout_tm.tm_sec) == -1) {
  69                         return;
  70                 }
  71                 timeout_str = alloc_str;
  72         }
  73 
  74         d_printf("Key: %s\t Timeout: %s\t Value: %s  %s\n", keystr,
  75                  timeout_str, datastr, timeout > now_t ? "": "(expired)");
  76 
  77         SAFE_FREE(alloc_str);
  78 }
  79 
  80 static void delete_cache_entry(const char* keystr, const char* datastr,
     /* [<][>][^][v][top][bottom][index][help] */
  81                                const time_t timeout, void* dptr)
  82 {
  83         if (!gencache_del(keystr))
  84                 d_fprintf(stderr, "Couldn't delete entry! key = %s\n", keystr);
  85 }
  86 
  87 
  88 /**
  89  * Parse text representation of timeout value
  90  *
  91  * @param timeout_str string containing text representation of the timeout
  92  * @return numeric timeout of time_t type
  93  **/
  94 static time_t parse_timeout(const char* timeout_str)
     /* [<][>][^][v][top][bottom][index][help] */
  95 {
  96         char sign = '\0', *number = NULL, unit = '\0';
  97         int len, number_begin, number_end;
  98         time_t timeout;
  99 
 100         /* sign detection */
 101         if (timeout_str[0] == '!' || timeout_str[0] == '+') {
 102                 sign = timeout_str[0];
 103                 number_begin = 1;
 104         } else {
 105                 number_begin = 0;
 106         }
 107 
 108         /* unit detection */
 109         len = strlen(timeout_str);
 110         switch (timeout_str[len - 1]) {
 111         case 's':
 112         case 'm':
 113         case 'h':
 114         case 'd':
 115         case 'w': unit = timeout_str[len - 1];
 116         }
 117 
 118         /* number detection */
 119         len = (sign) ? strlen(&timeout_str[number_begin]) : len;
 120         number_end = (unit) ? len - 1 : len;
 121         number = SMB_STRNDUP(&timeout_str[number_begin], number_end);
 122 
 123         /* calculate actual timeout value */
 124         timeout = (time_t)atoi(number);
 125 
 126         switch (unit) {
 127         case 'm': timeout *= 60; break;
 128         case 'h': timeout *= 60*60; break;
 129         case 'd': timeout *= 60*60*24; break;
 130         case 'w': timeout *= 60*60*24*7; break;  /* that's fair enough, I think :) */
 131         }
 132 
 133         switch (sign) {
 134         case '!': timeout = time(NULL) - timeout; break;
 135         case '+':
 136         default:  timeout += time(NULL); break;
 137         }
 138 
 139         if (number) SAFE_FREE(number);
 140         return timeout;
 141 }
 142 
 143 
 144 /**
 145  * Add an entry to the cache. If it does exist, then set it.
 146  *
 147  * @param c     A net_context structure
 148  * @param argv key, value and timeout are passed in command line
 149  * @return 0 on success, otherwise failure
 150  **/
 151 static int net_cache_add(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 152 {
 153         const char *keystr, *datastr, *timeout_str;
 154         time_t timeout;
 155 
 156         if (argc < 3 || c->display_usage) {
 157                 d_printf("\nUsage: net cache add <key string> <data string> <timeout>\n");
 158                 return -1;
 159         }
 160 
 161         keystr = argv[0];
 162         datastr = argv[1];
 163         timeout_str = argv[2];
 164 
 165         /* parse timeout given in command line */
 166         timeout = parse_timeout(timeout_str);
 167         if (!timeout) {
 168                 d_fprintf(stderr, "Invalid timeout argument.\n");
 169                 return -1;
 170         }
 171 
 172         if (gencache_set(keystr, datastr, timeout)) {
 173                 d_printf("New cache entry stored successfully.\n");
 174                 gencache_shutdown();
 175                 return 0;
 176         }
 177 
 178         d_fprintf(stderr, "Entry couldn't be added. Perhaps there's already such a key.\n");
 179         gencache_shutdown();
 180         return -1;
 181 }
 182 
 183 /**
 184  * Delete an entry in the cache
 185  *
 186  * @param c     A net_context structure
 187  * @param argv key to delete an entry of
 188  * @return 0 on success, otherwise failure
 189  **/
 190 static int net_cache_del(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 191 {
 192         const char *keystr = argv[0];
 193 
 194         if (argc < 1 || c->display_usage) {
 195                 d_printf("\nUsage: net cache del <key string>\n");
 196                 return -1;
 197         }
 198 
 199         if(gencache_del(keystr)) {
 200                 d_printf("Entry deleted.\n");
 201                 return 0;
 202         }
 203 
 204         d_fprintf(stderr, "Couldn't delete specified entry\n");
 205         return -1;
 206 }
 207 
 208 
 209 /**
 210  * Get and display an entry from the cache
 211  *
 212  * @param c     A net_context structure
 213  * @param argv key to search an entry of
 214  * @return 0 on success, otherwise failure
 215  **/
 216 static int net_cache_get(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 217 {
 218         const char* keystr = argv[0];
 219         char* valuestr = NULL;
 220         time_t timeout;
 221 
 222         if (argc < 1 || c->display_usage) {
 223                 d_printf("\nUsage: net cache get <key>\n");
 224                 return -1;
 225         }
 226 
 227         if (gencache_get(keystr, &valuestr, &timeout)) {
 228                 print_cache_entry(keystr, valuestr, timeout, NULL);
 229                 SAFE_FREE(valuestr);
 230                 return 0;
 231         }
 232 
 233         d_fprintf(stderr, "Failed to find entry\n");
 234         return -1;
 235 }
 236 
 237 
 238 /**
 239  * Search an entry/entries in the cache
 240  *
 241  * @param c     A net_context structure
 242  * @param argv key pattern to match the entries to
 243  * @return 0 on success, otherwise failure
 244  **/
 245 static int net_cache_search(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 246 {
 247         const char* pattern;
 248 
 249         if (argc < 1 || c->display_usage) {
 250                 d_printf("Usage: net cache search <pattern>\n");
 251                 return -1;
 252         }
 253 
 254         pattern = argv[0];
 255         gencache_iterate(print_cache_entry, NULL, pattern);
 256         return 0;
 257 }
 258 
 259 
 260 /**
 261  * List the contents of the cache
 262  *
 263  * @param c     A net_context structure
 264  * @param argv ignored in this functionailty
 265  * @return always returns 0
 266  **/
 267 static int net_cache_list(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 268 {
 269         const char* pattern = "*";
 270 
 271         if (c->display_usage) {
 272                 d_printf("Usage:\n"
 273                          "net cache list\n"
 274                          "    List all cache entries.\n");
 275                 return 0;
 276         }
 277         gencache_iterate(print_cache_entry, NULL, pattern);
 278         gencache_shutdown();
 279         return 0;
 280 }
 281 
 282 
 283 /**
 284  * Flush the whole cache
 285  *
 286  * @param c     A net_context structure
 287  * @param argv ignored in this functionality
 288  * @return always returns 0
 289  **/
 290 static int net_cache_flush(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 291 {
 292         const char* pattern = "*";
 293         if (c->display_usage) {
 294                 d_printf("Usage:\n"
 295                          "net cache flush\n"
 296                          "    Delete all cache entries.\n");
 297                 return 0;
 298         }
 299         gencache_iterate(delete_cache_entry, NULL, pattern);
 300         gencache_shutdown();
 301         return 0;
 302 }
 303 
 304 /**
 305  * Entry point to 'net cache' subfunctionality
 306  *
 307  * @param c     A net_context structure
 308  * @param argv arguments passed to further called functions
 309  * @return whatever further functions return
 310  **/
 311 int net_cache(struct net_context *c, int argc, const char **argv)
     /* [<][>][^][v][top][bottom][index][help] */
 312 {
 313         struct functable func[] = {
 314                 {
 315                         "add",
 316                         net_cache_add,
 317                         NET_TRANSPORT_LOCAL,
 318                         "Add new cache entry",
 319                         "net cache add <key string> <data string> <timeout>\n"
 320                         "  Add new cache entry.\n"
 321                         "    key string\tKey string to add cache data under.\n"
 322                         "    data string\tData to store under given key.\n"
 323                         "    timeout\tTimeout for cache data."
 324                 },
 325                 {
 326                         "del",
 327                         net_cache_del,
 328                         NET_TRANSPORT_LOCAL,
 329                         "Delete existing cache entry by key",
 330                         "net cache del <key string>\n"
 331                         "  Delete existing cache entry by key.\n"
 332                         "    key string\tKey string to delete."
 333                 },
 334                 {
 335                         "get",
 336                         net_cache_get,
 337                         NET_TRANSPORT_LOCAL,
 338                         "Get cache entry by key",
 339                         "net cache get <key string>\n"
 340                         "  Get cache entry by key.\n"
 341                         "    key string\tKey string to look up cache entry for."
 342 
 343                 },
 344                 {
 345                         "search",
 346                         net_cache_search,
 347                         NET_TRANSPORT_LOCAL,
 348                         "Search entry by pattern",
 349                         "net cache search <pattern>\n"
 350                         "  Search entry by pattern.\n"
 351                         "    pattern\tPattern to search for in cache."
 352                 },
 353                 {
 354                         "list",
 355                         net_cache_list,
 356                         NET_TRANSPORT_LOCAL,
 357                         "List all cache entries",
 358                         "net cache list\n"
 359                         "  List all cache entries"
 360                 },
 361                 {
 362                         "flush",
 363                         net_cache_flush,
 364                         NET_TRANSPORT_LOCAL,
 365                         "Delete all cache entries",
 366                         "net cache flush\n"
 367                         "  Delete all cache entries"
 368                 },
 369                 {NULL, NULL, 0, NULL, NULL}
 370         };
 371 
 372         return net_run_function(c, argc, argv, "net cache", func);
 373 }

/* [<][>][^][v][top][bottom][index][help] */