2002-09-11 18:07:21 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
Copyright ( C ) Rafal Szczesniak 2002
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA . */
# include "includes.h"
# include "net.h"
/**
* @ file net_cache . c
* @ brief This is part of the net tool which is basically command
* line wrapper for gencache . c functions ( mainly for testing )
*
* */
/*
* These routines are used via gencache_iterate ( ) to display the cache ' s contents
* ( print_cache_entry ) and to flush it ( delete_cache_entry ) .
* Both of them are defined by first arg of gencache_iterate ( ) routine .
*/
2003-01-04 11:48:15 +03:00
static void print_cache_entry ( const char * keystr , const char * datastr ,
const time_t timeout , void * dptr )
2002-09-11 18:07:21 +04:00
{
2006-06-15 01:36:49 +04:00
char * timeout_str ;
2006-06-16 01:03:40 +04:00
char * alloc_str = NULL ;
2003-01-04 11:48:15 +03:00
time_t now_t = time ( NULL ) ;
struct tm timeout_tm , * now_tm ;
/* localtime returns statically allocated pointer, so timeout_tm
has to be copied somewhere else */
2006-06-15 01:36:49 +04:00
now_tm = localtime ( & timeout ) ;
if ( ! now_tm ) {
return ;
}
memcpy ( & timeout_tm , now_tm , sizeof ( struct tm ) ) ;
2003-01-04 11:48:15 +03:00
now_tm = localtime ( & now_t ) ;
2006-06-15 01:36:49 +04:00
if ( ! now_tm ) {
return ;
}
2003-01-04 11:48:15 +03:00
/* form up timeout string depending whether it's today's date or not */
if ( timeout_tm . tm_year ! = now_tm - > tm_year | |
2006-06-15 01:36:49 +04:00
timeout_tm . tm_mon ! = now_tm - > tm_mon | |
timeout_tm . tm_mday ! = now_tm - > tm_mday ) {
2003-01-04 11:48:15 +03:00
2006-06-15 01:36:49 +04:00
timeout_str = asctime ( & timeout_tm ) ;
if ( ! timeout_str ) {
return ;
}
timeout_str [ strlen ( timeout_str ) - 1 ] = ' \0 ' ; /* remove tailing CR */
} else {
2006-06-16 01:03:40 +04:00
asprintf ( & alloc_str , " %.2d:%.2d:%.2d " , timeout_tm . tm_hour ,
2003-01-04 11:48:15 +03:00
timeout_tm . tm_min , timeout_tm . tm_sec ) ;
2006-06-16 01:03:40 +04:00
if ( ! alloc_str ) {
return ;
}
timeout_str = alloc_str ;
2006-06-15 01:36:49 +04:00
}
2003-01-04 11:48:15 +03:00
d_printf ( " Key: %s \t Timeout: %s \t Value: %s %s \n " , keystr ,
timeout_str , datastr , timeout > now_t ? " " : " (expired) " ) ;
2006-06-16 01:03:40 +04:00
SAFE_FREE ( alloc_str ) ;
2002-09-11 18:07:21 +04:00
}
2003-01-04 11:48:15 +03:00
static void delete_cache_entry ( const char * keystr , const char * datastr ,
const time_t timeout , void * dptr )
2002-09-11 18:07:21 +04:00
{
if ( ! gencache_del ( keystr ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't delete entry! key = %s \n " , keystr ) ;
2002-09-11 18:07:21 +04:00
}
/**
* Parse text representation of timeout value
*
* @ param timeout_str string containing text representation of the timeout
* @ return numeric timeout of time_t type
* */
static time_t parse_timeout ( const char * timeout_str )
{
char sign = ' \0 ' , * number = NULL , unit = ' \0 ' ;
int len , number_begin , number_end ;
time_t timeout ;
/* sign detection */
if ( timeout_str [ 0 ] = = ' ! ' | | timeout_str [ 0 ] = = ' + ' ) {
sign = timeout_str [ 0 ] ;
number_begin = 1 ;
} else {
number_begin = 0 ;
}
/* unit detection */
len = strlen ( timeout_str ) ;
switch ( timeout_str [ len - 1 ] ) {
case ' s ' :
case ' m ' :
case ' h ' :
case ' d ' :
case ' w ' : unit = timeout_str [ len - 1 ] ;
}
/* number detection */
len = ( sign ) ? strlen ( & timeout_str [ number_begin ] ) : len ;
number_end = ( unit ) ? len - 1 : len ;
2004-12-07 21:25:53 +03:00
number = SMB_STRNDUP ( & timeout_str [ number_begin ] , number_end ) ;
2002-09-11 18:07:21 +04:00
/* calculate actual timeout value */
timeout = ( time_t ) atoi ( number ) ;
switch ( unit ) {
case ' m ' : timeout * = 60 ; break ;
case ' h ' : timeout * = 60 * 60 ; break ;
case ' d ' : timeout * = 60 * 60 * 24 ; break ;
case ' w ' : timeout * = 60 * 60 * 24 * 7 ; break ; /* that's fair enough, I think :) */
}
switch ( sign ) {
case ' ! ' : timeout = time ( NULL ) - timeout ; break ;
case ' + ' :
default : timeout + = time ( NULL ) ; break ;
}
if ( number ) SAFE_FREE ( number ) ;
return timeout ;
}
/**
2003-01-04 11:48:15 +03:00
* Add an entry to the cache . If it does exist , then set it .
2002-09-11 18:07:21 +04:00
*
* @ param argv key , value and timeout are passed in command line
* @ return 0 on success , otherwise failure
* */
static int net_cache_add ( int argc , const char * * argv )
{
const char * keystr , * datastr , * timeout_str ;
time_t timeout ;
if ( argc < 3 ) {
d_printf ( " \n Usage: net cache add <key string> <data string> <timeout> \n " ) ;
return - 1 ;
}
keystr = argv [ 0 ] ;
datastr = argv [ 1 ] ;
timeout_str = argv [ 2 ] ;
/* parse timeout given in command line */
timeout = parse_timeout ( timeout_str ) ;
if ( ! timeout ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Invalid timeout argument. \n " ) ;
2002-09-11 18:07:21 +04:00
return - 1 ;
}
2003-01-04 11:48:15 +03:00
if ( gencache_set ( keystr , datastr , timeout ) ) {
2002-09-11 18:07:21 +04:00
d_printf ( " New cache entry stored successfully. \n " ) ;
gencache_shutdown ( ) ;
return 0 ;
2003-01-04 11:48:15 +03:00
}
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Entry couldn't be added. Perhaps there's already such a key. \n " ) ;
2002-09-11 18:07:21 +04:00
gencache_shutdown ( ) ;
return - 1 ;
}
/**
* Delete an entry in the cache
*
* @ param argv key to delete an entry of
* @ return 0 on success , otherwise failure
* */
static int net_cache_del ( int argc , const char * * argv )
{
const char * keystr = argv [ 0 ] ;
if ( argc < 1 ) {
2003-07-29 06:34:18 +04:00
d_printf ( " \n Usage: net cache del <key string> \n " ) ;
2002-09-11 18:07:21 +04:00
return - 1 ;
}
if ( gencache_del ( keystr ) ) {
d_printf ( " Entry deleted. \n " ) ;
return 0 ;
2003-01-04 11:48:15 +03:00
}
2002-09-11 18:07:21 +04:00
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Couldn't delete specified entry \n " ) ;
2002-09-11 18:07:21 +04:00
return - 1 ;
}
/**
* Get and display an entry from the cache
*
* @ param argv key to search an entry of
* @ return 0 on success , otherwise failure
* */
static int net_cache_get ( int argc , const char * * argv )
{
const char * keystr = argv [ 0 ] ;
char * valuestr ;
time_t timeout ;
if ( argc < 1 ) {
d_printf ( " \n Usage: net cache get <key> \n " ) ;
return - 1 ;
}
if ( gencache_get ( keystr , & valuestr , & timeout ) ) {
2003-01-04 11:48:15 +03:00
print_cache_entry ( keystr , valuestr , timeout , NULL ) ;
2002-09-11 18:07:21 +04:00
return 0 ;
2003-01-04 11:48:15 +03:00
}
2002-09-11 18:07:21 +04:00
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " Failed to find entry \n " ) ;
2002-09-11 18:07:21 +04:00
return - 1 ;
}
/**
* Search an entry / entries in the cache
*
* @ param argv key pattern to match the entries to
* @ return 0 on success , otherwise failure
* */
static int net_cache_search ( int argc , const char * * argv )
{
const char * pattern ;
if ( argc < 1 ) {
d_printf ( " Usage: net cache search <pattern> \n " ) ;
return - 1 ;
}
pattern = argv [ 0 ] ;
2003-01-04 11:48:15 +03:00
gencache_iterate ( print_cache_entry , NULL , pattern ) ;
2002-09-11 18:07:21 +04:00
return 0 ;
}
/**
* List the contents of the cache
*
* @ param argv ignored in this functionailty
* @ return always returns 0
* */
static int net_cache_list ( int argc , const char * * argv )
{
const char * pattern = " * " ;
2003-01-04 11:48:15 +03:00
gencache_iterate ( print_cache_entry , NULL , pattern ) ;
2002-09-11 18:07:21 +04:00
gencache_shutdown ( ) ;
return 0 ;
}
/**
* Flush the whole cache
*
* @ param argv ignored in this functionality
* @ return always returns 0
* */
static int net_cache_flush ( int argc , const char * * argv )
{
const char * pattern = " * " ;
2003-01-04 11:48:15 +03:00
gencache_iterate ( delete_cache_entry , NULL , pattern ) ;
2002-09-11 18:07:21 +04:00
gencache_shutdown ( ) ;
return 0 ;
}
/**
* Short help
*
* @ param argv ignored in this functionality
* @ return always returns - 1
* */
static int net_cache_usage ( int argc , const char * * argv )
{
d_printf ( " net cache add \t add add new cache entry \n " ) ;
d_printf ( " net cache del \t delete existing cache entry by key \n " ) ;
d_printf ( " net cache flush \t delete all entries existing in the cache \n " ) ;
d_printf ( " net cache get \t get cache entry by key \n " ) ;
d_printf ( " net cache search \t search for entries in the cache, by given pattern \n " ) ;
d_printf ( " net cache list \t list all cache entries (just like search for \" * \" ) \n " ) ;
return - 1 ;
}
/**
* Entry point to ' net cache ' subfunctionality
*
* @ param argv arguments passed to further called functions
* @ return whatever further functions return
* */
int net_cache ( int argc , const char * * argv )
{
struct functable func [ ] = {
{ " add " , net_cache_add } ,
{ " del " , net_cache_del } ,
{ " get " , net_cache_get } ,
{ " search " , net_cache_search } ,
{ " list " , net_cache_list } ,
{ " flush " , net_cache_flush } ,
{ NULL , NULL }
} ;
return net_run_function ( argc , argv , func , net_cache_usage ) ;
}