[complement-svn] SF.net SVN: complement: [1293] trunk/explore
Status: Pre-Alpha
Brought to you by:
complement
From: <com...@us...> - 2006-10-05 06:49:48
|
Revision: 1293 http://svn.sourceforge.net/complement/?rev=1293&view=rev Author: complement Date: 2006-10-04 23:49:32 -0700 (Wed, 04 Oct 2006) Log Message: ----------- recover from working copy after disk crash---master CVS was lost or corrupted Added Paths: ----------- trunk/explore/include/misc/dir_utils.h trunk/explore/include/misc/node.h trunk/explore/lib/misc/args.cc trunk/explore/lib/sockios/ChangeLog trunk/explore/lib/sockios/Makefile.inc Added: trunk/explore/include/misc/dir_utils.h =================================================================== --- trunk/explore/include/misc/dir_utils.h (rev 0) +++ trunk/explore/include/misc/dir_utils.h 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,43 @@ +// -*- C++ -*- Time-stamp: <01/03/19 16:32:47 ptr> + +/* + * + * Copyright (c) 1997 + * Petr Ovchenkov + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + */ + +#ifndef __dir_utils_h + +#ifdef __unix +# ifdef __HP_aCC +#pragma VERSIONID "$SunId$" +# else +#pragma ident "$SunId$" +# endif +#endif + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#include <string> + +#ifndef _UNISTD_H +#include <unistd.h> +#endif + +std::string mkunique_dir( const std::string& base, const std::string& prefix ); + +inline void rm_dir( const std::string& d ) { ::rmdir( d.c_str() ); } +void rm_dir_all( const std::string& d ); + +#endif // __dir_utils_h Added: trunk/explore/include/misc/node.h =================================================================== --- trunk/explore/include/misc/node.h (rev 0) +++ trunk/explore/include/misc/node.h 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,621 @@ +// -*- C++ -*- Time-stamp: <03/11/16 21:49:19 ptr> + +/* + * Copyright (c) 1999 + * Petr Ovchenkov + * + * Copyright (c) 1999-2001 + * ParallelGraphics Ltd. + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + */ + +#ifndef __node_h +#define __node_h + +#ifdef __unix +# ifdef __HP_aCC +#pragma VERSIONID "@(#)$Id: node.h,v 1.20 2005/03/31 10:22:26 ptr Exp $" +# else +#pragma ident "@(#)$Id: node.h,v 1.20 2005/03/31 10:22:26 ptr Exp $" +# endif +#endif + +#ifndef __config_feature_h +#include <config/feature.h> +#endif + +#include <list> +#include <string> +#include <map> + +#ifndef __XMT_H +#include <mt/xmt.h> +#endif + +#include <iostream> +#include <stdexcept> + +namespace Helios { + +class __node_base +{ + public: + typedef unsigned key_type; + typedef std::list<unsigned> grp_container_type; + + enum { + u_mask = 00700, + g_mask = 00070, + o_mask = 00007, + c_bit = 01000, // catalog bit + r_mask = 00444, + w_mask = 00222, + x_mask = 00111, + rw_mask = 00666 + }; + + __node_base() : + prot( 0 ), + refcount( 0 ), + uid( static_cast<unsigned>(-1) ), + gid( static_cast<unsigned>(-1) ) + { } + + __node_base( unsigned _uid, unsigned _gid, unsigned _prot ) : + prot( _prot ), + refcount( 0 ), + uid( _uid ), + gid( _gid ) + { } + + unsigned addref() + { return (unsigned)(++refcount); } + unsigned rmref() + { return (unsigned)(--refcount); } + void protection( unsigned _prot ) + { + prot &= ~0777; + prot |= _prot & 0777; + } + unsigned protection() const + { return (unsigned)( prot & 0777 ); } + bool is_catalog() const + { return (prot & c_bit) != 0; } + + bool can_read( unsigned __u, unsigned __g ) const + { return _can( __u, __g, r_mask ); } + bool can_write( unsigned __u, unsigned __g ) const + { return _can( __u, __g, w_mask ); } + bool can_exec( unsigned __u, unsigned __g ) const + { return _can( __u, __g, x_mask ); } + + bool can_read( unsigned __u, unsigned __g, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { return _can( __u, __g, r_mask, __first, __last ); } + bool can_write( unsigned __u, unsigned __g, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { return _can( __u, __g, w_mask, __first, __last ); } + bool can_exec( unsigned __u, unsigned __g, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { return _can( __u, __g, x_mask, __first, __last ); } + + unsigned short prot; + unsigned short refcount; + unsigned uid; + unsigned gid; + + private: + bool _can( unsigned __u, unsigned __g, unsigned mask ) const + { return (prot & ( __u == uid ? u_mask : __g == gid ? g_mask : o_mask) & mask) != 0; } + bool _can( unsigned __u, unsigned __g, unsigned mask, + grp_container_type::const_iterator __first, + grp_container_type::const_iterator __last ) const + { + if ( (prot & ( __u == uid ? u_mask : __g == gid ? g_mask : o_mask) & mask) != 0 ) + return true; + + if ( (prot & g_mask & mask) != 0 ) { // any group permissions + while ( __first != __last ) { + if ( gid == *__first++ ) { // user is group member + return true; + } + } + } + return false; + } +}; + +class __node_base_catalog : + public __node_base +{ + public: + typedef std::pair<key_type,std::string> catalog_entry; +// typedef __STD::list<catalog_entry, __STL_DEFAULT_ALLOCATOR(catalog_entry) > catalog_type; + typedef std::list<catalog_entry > catalog_type; + typedef catalog_type::iterator iterator; + typedef catalog_type::const_iterator const_iterator; + + __node_base_catalog() : + __node_base() + { prot |= c_bit; } + + __node_base_catalog( unsigned _uid, unsigned _gid, unsigned _prot ) : + __node_base( _uid, _gid, _prot ) + { prot |= c_bit; } + + iterator begin() + { return catalog.begin(); } + iterator end() + { return catalog.end(); } + const_iterator begin() const + { return catalog.begin(); } + const_iterator end() const + { return catalog.end(); } + + iterator erase( iterator __x ) + { return catalog.erase( __x ); } + iterator erase( key_type __k ) + { + iterator i = entry( __k ); + if ( i != catalog.end() ) { + return catalog.erase( i ); + } + return i; + } + void push( key_type inode, const std::string& name ) + { catalog.push_back(catalog_entry(inode,name)); } + iterator insert( iterator i, key_type inode, const std::string& name ) + { return catalog.insert( i, catalog_entry(inode,name)); } + key_type inode( const std::string& name ) + { + iterator i = entry( name ); + return i != catalog.end() ? (*i).first : static_cast<key_type>(-1); + } + iterator entry( const std::string& name ) + { + iterator i = catalog.begin(); + while ( i != catalog.end() && (*i).second != name ) { + ++i; + } + return i; + } + iterator entry( key_type k ) + { + iterator i = catalog.begin(); + while ( i != catalog.end() && (*i).first != k ) { + ++i; + } + return i; + } + + catalog_type::size_type size() const + { return catalog.size(); } + + protected: + catalog_type catalog; +}; + +template <class T> +class __node_base_t : + public __node_base +{ + public: + typedef T value_type; + typedef value_type& reference; + + __node_base_t() : + __node_base() + { } + + __node_base_t( unsigned _uid, unsigned _gid, unsigned _prot ) : + __node_base( _uid, _gid, _prot ) + { } + + reference value() + { return data; } + + T data; +}; + +typedef __node_base_t<std::string> node_string; +typedef __node_base_t<void *> node_void_ptr; + +class __nodes_heap_base +{ + public: + typedef __node_base::key_type key_type; + + __nodes_heap_base() : + _low( 0 ), + _high( 0x7fffffff ), + _id( _low ) + { } + + __nodes_heap_base( key_type __low, key_type __high ) : + _low( __low ), + _high( __high ), + _id( _low ) + { } + + bool is_avail( key_type __id ) const + { return heap.find( __id ) != heap.end(); } + + protected: +// typedef __STD::map<key_type,void *,__STD::less<key_type>, +// __STL_DEFAULT_ALLOCATOR(void *) > heap_type; + + typedef std::map<key_type,void *,std::less<key_type> > heap_type; + void *& value( key_type __id ) + { + // _STLP_ASSERT( heap.find( __id ) != heap.end() ); + return heap[__id]; + } + key_type create_unique(); + const __impl::MutexSDS& oplock() const + { return _op_lock; } + + const key_type _low; + const key_type _high; + + key_type _id; + heap_type heap; + __impl::Mutex _lock; + __impl::MutexSDS _op_lock; + static const std::string dot; + static const std::string dotdot; +}; + +template <class Node> class nodes_heap_cursor; + +template <class Node> +class nodes_heap : + public __nodes_heap_base +{ + public: + typedef typename Node::reference reference; + typedef __node_base_catalog Catalog; + typedef nodes_heap_cursor<Node> cursor_type; + + nodes_heap() : + __nodes_heap_base() + { create_root( 0755 ); } + + nodes_heap( unsigned prot ) : + __nodes_heap_base() + { create_root( prot ); } + + nodes_heap( key_type __low, key_type __high, unsigned prot = 0755 ) : + __nodes_heap_base( __low, __high ) + { create_root( prot ); } + + heap_type::size_type size() + { return heap.size(); } + + reference operator[]( key_type __id ) + { + // __node_base *tmp = reinterpret_cast<__node_base *> + // if this is catalog, result undefined + return reinterpret_cast<Node *>(heap[__id])->value(); + } + + cursor_type cursor( unsigned uid, unsigned gid, unsigned prot_mask = 0 ) + { return cursor_type( this, uid, gid, prot_mask ); } + + key_type create_node( unsigned uid, unsigned gid, unsigned prot ); + key_type create_catalog( unsigned uid, unsigned gid, unsigned prot ); + void destroy( key_type __id ); + + private: + key_type create_root( unsigned ); + + friend class nodes_heap_cursor<Node>; +}; + +class entry_error : +// #ifdef __GNUC__ +// public __STD_QUALIFIER runtime_error +// #else + public std::runtime_error +// #endif +{ + public: + entry_error(const std::string& __arg) : runtime_error(__arg) {} +}; + + +template <class Node> +class nodes_heap_cursor +{ + public: + typedef Helios::__node_base::key_type key_type; + typedef __node_base_catalog Catalog; + typedef Catalog::iterator iterator; + typedef Catalog::const_iterator const_iterator; + typedef typename Node::value_type value_type; + typedef typename Node::reference reference; + + nodes_heap_cursor() : + _heap( 0 ), + catalog( 0 ), + _uid( -1 ), + _gid( -1 ), + _defprot( 0 ) + { } + nodes_heap_cursor( const nodes_heap_cursor<Node>& cursor ) : + _heap( cursor._heap ), + _uid( cursor._uid ), + _gid( cursor._gid ), + _defprot( cursor._defprot ), + _grp( cursor._grp ) + { + catalog = cursor.catalog; + catalog->addref(); // that's locking indeed + } + ~nodes_heap_cursor() + { + if ( catalog != 0 ) catalog->rmref(); + } + + void close() + { + _grp.clear(); + if ( catalog != 0 ) { + catalog->rmref(); + catalog = 0; + } + } + + const __impl::MutexSDS& oplocker() + { + if ( _heap == 0 ) { + throw std::domain_error( "nodes_heap_cursor" ); + } + return _heap->oplock(); + } + + bool operator ==( const nodes_heap_cursor<Node>& cursor ) + { return _heap == cursor._heap && catalog == cursor.catalog; } + bool operator !=( const nodes_heap_cursor<Node>& cursor ) + { return _heap != cursor._heap || catalog != cursor.catalog; } + + void cr_uid( unsigned __uid ) + { _uid = __uid; } + void cr_gid( unsigned __gid ) + { _gid = __gid; } + void cr_own( unsigned __uid, unsigned __gid ) + { _uid = __uid; _gid = __gid; } + void add_grp( unsigned __gid ) + { _grp.push_back( __gid ); } + + iterator begin() + { return catalog->begin(); } + iterator end() + { return catalog->end(); } + const_iterator begin() const + { return catalog->begin(); } + const_iterator end() const + { return catalog->end(); } + + bool is_catalog( const_iterator i ) const + { + // __stl_assert( i != catalog->end() ); + //_STLP_ASSERT( (*i).first != -1 ); + //_STLP_ASSERT( _heap->value((*i).first) != 0 ); + return reinterpret_cast<__node_base *>(_heap->value((*i).first))->is_catalog(); + } + unsigned uid() const + { return _uid; } + unsigned gid() const + { return _gid; } + unsigned uid( const_iterator i ) const + { return reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid; } + unsigned gid( const_iterator i ) const + { return reinterpret_cast<__node_base *>(_heap->value((*i).first))->gid; } + unsigned uid( key_type k ) const + { return uid( catalog->entry( k ) ); } + unsigned gid( key_type k ) const + { return gid( catalog->entry( k ) ); } + unsigned uid( const std::string& name ) const + { return uid( catalog->entry( name ) ); } + unsigned gid( const std::string& name ) const + { return gid( catalog->entry( name ) ); } + void uid( iterator i, unsigned __uid ) + { + if ( _uid == 0 || _gid == 0 ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid = __uid; + } + } + void gid( iterator i, unsigned __gid ) + { + if ( _uid == 0 || _gid == 0 ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->gid = __gid; + } else if ( reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid == _uid ) { +#ifndef __GNUC__ +#if !defined(__HP_aCC) || (__HP_aCC > 1) + typename __node_base::grp_container_type::iterator g = _grp.begin(); +#else + __node_base::grp_container_type::iterator g = _grp.begin(); +#endif +#else +// typename Helios::__node_base::grp_container_type::iterator g = _grp.begin(); + typename std::list<unsigned>::iterator g = _grp.begin(); +#endif + while ( g != _grp.end() ) { + if ( __gid == *g++ ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->gid = __gid; + break; + } + } + } + } + void uid( key_type k, unsigned __uid ) + { uid( catalog->entry( k ), __uid ); } + void gid( key_type k, unsigned __gid ) + { gid( catalog->entry( k ), __gid ); } + void uid( const std::string& name, unsigned __uid ) + { uid( catalog->entry( name ), __uid ); } + void gid( const std::string& name, unsigned __gid ) + { gid( catalog->entry( name ), __gid ); } + bool can_read() const + { + return reinterpret_cast<__node_base *>(_heap->value(dot()))->can_read( _uid, _gid, _grp.begin(), _grp.end() ); + } + bool can_write() const + { + return reinterpret_cast<__node_base *>(_heap->value(dot()))->can_write( _uid, _gid, _grp.begin(), _grp.end() ); + } + bool can_exec() const + { + return reinterpret_cast<__node_base *>(_heap->value(dot()))->can_exec( _uid, _gid, _grp.begin(), _grp.end() ); + } + reference operator [] ( iterator i ) + { + if ( is_catalog(i) ) throw entry_error( "catalog" ); + return reinterpret_cast<Node *>(_heap->value((*i).first))->value(); + } + reference operator [] ( const std::string& name ) + { + iterator i = catalog->entry( name ); + if ( i == catalog->end() ) throw entry_error( "no entry" ); + if ( is_catalog(i) ) throw entry_error( "catalog" ); + return reinterpret_cast<Node *>(_heap->value((*i).first))->value(); + } + iterator entry( const std::string& name ) + { return catalog->entry( name ); } + iterator entry( key_type k ) + { return catalog->entry( k ); } + // key_type inode( const std::string& name ) + // { return catalog->inode( name ); } + + iterator create( const std::string& name, unsigned prot ) + { + if ( can_write() ) { + catalog->push( _heap->create_node( _uid, _gid, prot ), name ); + return --catalog->end(); + } + return catalog->end(); + } + iterator create( const std::string& name ) + { return create( name, _defprot ); } + iterator insert( iterator i, const std::string& name, unsigned prot ) + { + if ( can_write() ) { + return catalog->insert( i, _heap->create_node( _uid, _gid, prot ), name ); + } + return catalog->end(); + } + iterator insert( iterator i, const std::string& name ) + { return insert( i, name, _defprot ); } + + // if default protection has read bit, for catalog should be set exec bit + iterator create_catalog( const std::string& name ) + { return create_catalog( name, _defprot | + ((_defprot & __node_base::r_mask) >> 2 ) ); } + iterator create_catalog( const std::string& name, unsigned prot ); + iterator insert_catalog( iterator i, const std::string& name ) + { return insert_catalog( i, name, _defprot | + ((_defprot & __node_base::r_mask) >> 2 ) ); } + iterator insert_catalog( iterator i, const std::string& name, unsigned prot ); + + void erase( const std::string& name ) + { erase( catalog->entry( name ) ); } + void erase( iterator i ); + void erase( key_type k ) + { erase( catalog->entry( k ) ); } + + void cd( key_type k ); + void cd( iterator i ); + void cd( const std::string& name ) + { cd( catalog->entry(name) ); } + void cd_dotdot() + { cd( ++begin() ); } + + iterator mv( iterator i, nodes_heap_cursor<Node>& cursor ); + iterator mv( iterator i, nodes_heap_cursor<Node>& cursor, const std::string& name ); + iterator mv( key_type k, nodes_heap_cursor<Node>& cursor ); + iterator mv( key_type k, nodes_heap_cursor<Node>& cursor, iterator i ); + iterator ln( iterator i ); + iterator ln( key_type k, nodes_heap_cursor<Node>& cursor ); + + unsigned protection( iterator i ) + { return reinterpret_cast<__node_base *>(_heap->value((*i).first))->protection(); } + unsigned protection( key_type k ) + { return protection( catalog->entry( k ) ); } + unsigned protection( const std::string& name ) + { return protection( catalog->entry( name ) ); } + void protection( iterator i, unsigned p ) + { + if ( reinterpret_cast<__node_base *>(_heap->value((*i).first))->uid == _uid || _uid == 0 ) { + reinterpret_cast<__node_base *>(_heap->value((*i).first))->protection( p ); + } + } + void protection( key_type k, unsigned p ) + { protection( catalog->entry( k ), p ); } + void protection( const std::string& name, unsigned p ) + { protection( catalog->entry( name ), p ); } + + key_type dot() const + { return (*catalog->begin()).first; } + key_type dotdot() const + { return (*++catalog->begin()).first; } + + protected: + // prot_mask here is mask for clear protection bits from 0666 + // I never set default exec bit. It's set for catalogs if default + // protection has read bit (see above, create_catalog) + + nodes_heap_cursor( nodes_heap<Node>& __heap, unsigned uid, unsigned gid, unsigned prot_mask ) : + _heap( &__heap ), + _uid( uid ), + _gid( gid ), + _defprot( ~prot_mask & __node_base::rw_mask ) // clear exec bits + { + catalog = reinterpret_cast<Catalog *>(_heap->value(0)); + catalog->addref(); + } + nodes_heap_cursor( nodes_heap<Node> *__heap, unsigned uid, unsigned gid, unsigned prot_mask ) : + _heap( __heap ), + _uid( uid ), + _gid( gid ), + _defprot( ~prot_mask & __node_base::rw_mask ) // clear exec bits + { + catalog = reinterpret_cast<Catalog *>(_heap->value(0)); + catalog->addref(); + } + + bool erase_catalog( __node_base& node ); + + Catalog *catalog; + nodes_heap<Node> *_heap; + unsigned _uid; + unsigned _gid; + unsigned _defprot; +#if defined(__HP_aCC) && (__HP_aCC == 1) + __node_base::grp_container_type _grp; +#else + typename __node_base::grp_container_type _grp; +#endif + + friend class nodes_heap<Node>; +}; + +typedef nodes_heap<node_string> stringtree; + +} // namespace Helios + +#ifndef __STL_LINK_TIME_INSTANTIATION +# include <misc/node.cc> +#endif + +#endif // __node.h Added: trunk/explore/lib/misc/args.cc =================================================================== --- trunk/explore/lib/misc/args.cc (rev 0) +++ trunk/explore/lib/misc/args.cc 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,372 @@ +// -*- C++ -*- Time-stamp: <04/05/21 17:47:51 ptr> + +/* + * + * Copyright (c) 1997-1998, 2001, 2006 + * Petr Ovtchenkov + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. + */ + +#include <config/feature.h> +#include <ostream> +#include <iomanip> +#include <sstream> +#include <string> +#include <functional> +#include "misc/args.h" + +using namespace std; + +ArgsParser::ArgsParser( int argc, char * const *argv ) +{ + int i = 1; + + while ( i < argc ) { + arg.push_back( argv[i] ); + ++i; + } +} + +ArgsParser::ArgsParser( const string& in ) +{ + stringstream s( in ); + string tmp; + + while ( s.good() ) { + s >> tmp; + if ( tmp.length() != 0 && tmp[0] == '"' ) { +// s.unsetf( ios_base::skipws ); + getline( s, tmp, '"' ); + } + arg.push_back( tmp ); + } +} + +ArgsParser::ArgsParser( istream& in ) +{ + string tmp; + + while ( in.good() ) { + in >> tmp; + if ( tmp.length() != 0 && tmp[0] == '"' ) { +// s.unsetf( ios_base::skipws ); + getline( in, tmp, '"' ); + } + arg.push_back( tmp ); + } +} + +ArgsParser::ArgsParser() +{ +} + +void ArgsParser::parse( int argc, char * const *argv ) +{ + _pname = argv[0]; + + int i = 1; + + while ( i < argc ) { + arg.push_back( argv[i] ); + ++i; + } +} + +void ArgsParser::copyright( const char *s ) +{ + _copyright = s; +} + +void ArgsParser::brief( const char *s ) +{ + _announce = s; +} + +void ArgsParser::print_help( ostream& s ) +{ + s << "This is " << _pname << ", " << _announce << "\n" + << _copyright << "\n\n" + << "Usage: \n"; +} + +string ArgsParser::get_next( const string& op ) +{ + container_type::iterator i = find( arg.begin(), arg.end(), op ); + + if ( i != arg.end() ) { + ++i; + if ( i != arg.end() ) { + return *i; + } + } + + return ""; +} + +string ArgsParser::get( int n ) +{ + iterator i; + if ( n >= 0 ) { + i = arg.begin(); + int j = 0; + + while ( i != arg.end() && j < n ) { + ++i; + ++j; + } + } else { + i = --arg.end(); + int j = -1; + + while ( i != arg.end() && j > n ) { + --i; + --j; + } + } + + return i != arg.end() ? (*i) : string(""); +} + +bool ArgsParser::is_option_X( const string& op ) +{ + container_type::iterator i = arg.begin(); + while ( i != arg.end() ) { + if ( (*i).length() > 0 && (*i)[0] == '-' && + (*i).find( op ) != string::npos ) { + return true; + } + ++i; + } + return false; +} + +Option<std::string>::Option( const char *n, const std::string& v, const char *h ) +{ + _nm = n; + _v = v; + if ( h != 0 ) { + _hlp = h; + } +} + +Option<char *>::Option( const char *n, const char *v, const char *h ) +{ + _nm = n; + _v = v; + if ( h != 0 ) { + _hlp = h; + } +} + +void Argv::parse( int argc, char * const *argv ) +{ + _pname = argv[0]; + + int i = 1; + opt_container_type::iterator a; + string argvI; + string argvII; + string::size_type p; + + while ( i < argc ) { + if ( _stop_opt == argv[i] || (strlen( argv[i] ) > 0 && argv[i][0] != '-') ) { + // ++i; + break; + } + + argvI = argv[i]; + + if ( (p = argvI.find( '=' ) ) != string::npos ) { + argvII = argvI.substr( p + 1 ); + argvI.erase( p ); + } else { + argvII.clear(); + } + + // find '=' in argvI + // strip after '=' + // after '=' is a value; search in options the string before '=' + a = std::find_if( opt.begin(), opt.end(), bind2nd( eqs, /* argv[i] */ argvI ) ); + if ( a == opt.end() ) { + string err( "unknown option: " ); + err += argv[i]; + throw std::invalid_argument( err ); + } + if ( (*a)->type() != typeid(bool) ) { +// if ( ++i < argc ) { + (*a)->read( argvII ); + (*a)->is_set = true; +// } else { +// string err( "option " ); +// err += argv[i-1]; +// err += " require value"; +// throw std::invalid_argument( err ); +// } + } else { + (*a)->read( "1" ); + (*a)->is_set = true; + } + ++i; + } + while ( i < argc ) { + arg.push_back( argv[i] ); + ++i; + } +} + +const std::string& Argv::operator[]( int i ) const +{ + if ( i < 0 || i >= arg.size() ) { + throw std::range_error( "out of range" ); + } + return arg[i]; +} + +void Argv::stop_option( const char *s ) +{ + _stop_opt = s; +} + +void Argv::copyright( const char *s ) +{ + _copyright = s; +} + +void Argv::brief( const char *s ) +{ + _announce = s; +} + +void Argv::args( const char *s ) +{ + _args = s; +} + +void Argv::print_help( ostream& s ) +{ + s << "This is " << _pname << ", " << _announce << "\n\n" + << _copyright << "\n\n" + << "Usage:\n" << " " << _pname << "\n\n" + << "Options:\n"; + string tmp; + for ( opt_container_type::iterator i = opt.begin(); i != opt.end(); ++i ) { + tmp = (*i)->_nm; + if ( (*i)->type() == typeid(std::string) ) { + tmp += "=<string>"; + } else if ( (*i)->type() == typeid(int) ) { + tmp += "=<int>"; + } else if ( (*i)->type() == typeid(unsigned) ) { + tmp += "=<uint>"; + } + s << " " << setw(24) << setfill( ' ' ) << setiosflags( ios_base::left ) + << tmp << (*i)->_hlp << "\n"; + } + s << "\n"; +} + +bool Argv::is( const char *nm ) const +{ + return (*find( nm ))->is_set; +} + +Argv::opt_container_type::iterator Argv::find( const char *nm ) +{ + opt_container_type::iterator i = std::find_if( opt.begin(), opt.end(), bind2nd( eq, nm ) ); + if ( i == opt.end() ) { + std::string err( "unknown option " ); + err += nm; + throw std::invalid_argument( err ); + } + return i; +} + +Argv::opt_container_type::const_iterator Argv::find( const char *nm ) const +{ + opt_container_type::const_iterator i = std::find_if( opt.begin(), opt.end(), bind2nd( eq, nm ) ); + if ( i == opt.end() ) { + std::string err( "unknown option " ); + err += nm; + throw std::invalid_argument( err ); + } + return i; +} + +IniParser::IniParser( istream& cfg ) +{ + string tmp; + string::size_type p; + + while ( cfg.good() ) { + tmp.clear(); + getline( cfg, tmp ); + p = tmp.find( '#' ); + if ( p != string::npos ) { + tmp.erase( p ); + } + if ( tmp.length() > 0 ) { + p = tmp.find( ':' ); + if ( p != string::npos ) { + string name = tmp.substr( 0, p ); + ++p; + string value = tmp.substr( p, tmp.size() - p ); + + p = name.find_first_not_of( " \t" ); + if ( p != string::npos ) { + if ( p > 0 ) { + name.erase( 0, p ); + } + p = name.find_last_not_of( " \t" ); + if ( p != string::npos ) { + ++p; + name.erase( p, name.length() - p ); + } + p = value.find_first_not_of( " \t" ); + if ( p != string::npos ) { + if ( p > 0 ) { + value.erase( 0, p ); + } + p = value.find_last_not_of( " \t" ); + if ( p != string::npos ) { + ++p; + value.erase( p, value.length() - p ); + } + pars.push_back( par( name, value ) ); + } + } + } + } + } +} + +string IniParser::value( const string& key, const string& def ) +{ + container_type::iterator i = find( pars.begin(), pars.end(), par( key, "" ) ); + + return i != pars.end()? (*i).value : def; +} + +#if defined(__SUNPRO_CC) && (__SUNPRO_CC == 0x500) + +// #pragma weak __1cDstdMbasic_string4Ccn0ALchar_traits4Cc__n0AJallocator4Cc___Rfind_first_not_of6kMpkcII_I_ +// #pragma weak unsigned std::string::find_first_not_of( const char *, unsigned, unsigned ) + +// void __Bug1() +// { +// const char *_ch = 0; +// std::basic_string<char,std::char_traits<char>,std::allocator<char> > _str; +// _str.find( _ch, 0, 0 ); +// _str.find_first_not_of( (const char *)0, 0U, 0U ); +// } +// unsigned _xxx = _str.find_first_not_of( (const char *)0, 0U, 0U ); + +// #pragma weak __Bug1 + +#endif Added: trunk/explore/lib/sockios/ChangeLog =================================================================== --- trunk/explore/lib/sockios/ChangeLog (rev 0) +++ trunk/explore/lib/sockios/ChangeLog 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,456 @@ +2006-09-25 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: introduce configuration parameters + for connection processing---limit of threads, time interval + to detect 'busy' thread, time interval to observe processing + threads, time interval to detect 'idle' thread + [ready for termination]. Implemented concurrent + connections processing by minimal number of threads with + guarantee that blocking in processing of some connections + don't lead to stop other connections processing [but + within number of limit of processsing threads; the marginal + case may be one thread per connect; adjust number + of processing threads, if needed]. If number of + processing threads unlimited [i.e. too big], too many + threads created under heavy load, and resources + used ineffective. + +2006-09-22 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: use concurrent threads pool; + special thread [observer] control threads creation; + connection processing thread can detect that no more + work and go away. + +2006-09-21 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: revision of sockmgr_stream_MP; + pass ready for read sockets to processing thread via + FIFO queue; don't listen sockets that in the processing; + avoid situation when same connection processed in + the different threads in the same time. + Note, that udp processing is broken now. + + * libsockios: Version 1.9.0 + +2006-09-20 Petr Ovtchenkov <pt...@is...> + + * libsockios: Version 1.8.1 + +2006-09-18 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: use vector as container for pollfd structures, + instead of raw array; move processed socket to the end of pollfd sequence, + to avoid usurp processing by older connections. + +2006-08-21 Petr Ovtchenkov <pt...@is...> + + * sockmgr.cc: the same as 2006-08-18 for poll/select on server side. + +2006-08-18 Petr Ovtchenkov <pt...@is...> + + * sockstream.cc: poll and select can be interrupted by signal not associated + with data on socket [SIGCHLD, for example]; in this case ones return some + negative value and set errno to EINTR; following read return 0 too---just + like end of connection; I check errno for EINTR, clear it and return + to listen on poll/select in this case. + +2006-08-04 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: changes in thread entry function. + +2006-07-11 Petr Ovtchenkov <pt...@is...> + + * socksream, sockstream.cc: add constructor from in_addr + for basic_sockbuf and sockstreams; generate list of + network interfaces in user-defined container. + +2006-06-28 Petr Ovtchenkov <pt...@is...> + + * socksream: use Mutex wrapper from xmt instead + of STLport; consider compilation with libstdc++; + + * _sockstream.cc: ditto + + * _sockmgr.cc: ditto + + * sockstream.cc: use socklen_t insted size_t, as + in POSIX---useful for platforms where size_t and + socklen_t are different types (like amd64). + + * socksream: idem + + * libsockios: Version 1.8.0 + +2006-05-24 Petr Ovtchenkov <pt...@is...> + + * socksream: explicitly add stdexcept header. + +2005-12-22 Petr Ovtchenkov <pt...@is...> + + * sockstream: add forward declaration of reentrant + workarounds for DNS resolver. + +2005-12-21 Petr Ovtchenkov <pt...@is...> + + * sockstream, sockstream.cc: remove previous + dup socket [see record 2005-12-19]---wrong + [dup here leads to problem in implementation of + sockmgr]. + + * sockstream, sockstream.cc: add 'attach' functions + in basic_sockbuf and basic_sockstream---attach + to existent socket with duplication [dup] to do + real close only for last close call; near the same + effect may be established with _doclose flag + [may be useful for platforms without dup call]. + + * libsockios: Version 1.7.4 + +2005-12-20 Petr Ovtchenkov <pt...@is...> + + * sockmgr.h, sockmgr.cc: wait for loop start; + use xmt namespace instead of __impl for xmt library. + +2005-12-19 Petr Ovtchenkov <pt...@is...> + + * sockstream, sockstream.cc: add timeout for + poll/select system calls. + + * sockstream.cc: use dup call to duplicate socket + descriptor, if open with descriptor. + +2005-12-12 Petr Ovtchenkov <pt...@is...> + + * Makefile.inc, freebsd/*: FreeBSD 4.11 has + non-reentrant res_*, getaddrinfor, ns_* functions; + we can use reentrant ones from FreeBSD 5.3 libc + instead. + + * freebsd/_freebsd_dummy.h: redefinition of functions + that will be replaced by reentrant ones + + * _sockstream.cc: use __FIT_GETHOSTBYADDR macro + + * libsockios: Version 1.7.3 + +2005-12-07 Petr Ovtchenkov <pt...@is...> + + * sockstream: add __FIT_GETHOSTBYADDR for platforms that + has no get*by*_r functions + +2005-12-01 Petr Ovtchenkov <pt...@is...> + + * sockstream: add gethostaddr and gethostaddr2 functions + that return list of all addresses for requested host + [via back insert iterator]. gethostaddr return objects of + type in_addr, while gethostaddr2 return objects of type + sockaddr (so it useful for IPv6 too). + + * unit_test.cc: tests for gethostaddr*. + + * libsockios: Version 1.7.2 + +2005-08-05 Petr Ovtchenkov <Pet...@Ka...> + + * sockstream: add function that return name of host, + this useful to take primary interface. + + * sockmgr.h, sockmgr.cc, _sockmgr.cc: add 'open' variants + that allow to bind on specific IP; as IP this interfaces + accept unsigned long [in host byteorder] or + in_addr [in network byteorder]; if no IP specified + INADDANY will be used. + + * libsockios: Version 1.7.1 + +2005-08-05 Petr Ovtchenkov <pt...@is...> + + * libsockios: Update license version, now + Academic Free License Version 2.1 + +2005-03-31 Petr Ovtchenkov <pt...@is...> + + * sockstream: add class scope to setstate call---it has + interference with char *setstate( char * ) in stdlib.h + [pseudorandom number generators] + + * sockstream, sockstream.cc: uClibc don't have stropts.h + +2005-03-25 Petr Ovtchenkov <pt...@is...> + + * Makefile: revision of Makefiles---path to stlport lib and + -lstlport went to common Makefiles. + +2004-11-05 Petr Ovtchenkov <pt...@Is...> + + * library naming changed. + +2003-07-05 Petr Ovtchenkov <pt...@Is...> + + * libsockios: Version 1.7.0 + + * libsockios: Update license version, now + Academic Free License Version 1.2 + + * libsockios: changes in sockmgr---set locks on change + descriptor of listened socket, due to this descriptor used in + separate thread, function loop, and changed outside this + thread in functions like close; add protected unsafe variants + of some functions; recover version with 'select' call in addition + to 'poll' system call; as 'poll' as 'select' variants are + accessible in one program, if this calls available in OS. + +2002-09-25 Petr Ovtchenkov <pt...@Is...> + + * libsockios: prepare for public on sourceforge.net under + the Academic Free License Version 1.0 + +2002-07-15 Petr Ovtchenkov <pt...@Is...> + + * sockmgr.h, sockmgr.cc (Repository): remove sockmgr + class, i.e. class with one Connection object per thread. + This functionality too reach, and if still need one can be + realized in sockmgr_MP clients. + + * sockstream, _sockstream.cc (Repository): provide + portable functions that return service by name and by port. + +2002-07-12 Petr Ovtchenkov <pt...@Is...> + + * libsockios: Version 1.6.0 + +2002-07-11 Petr Ovtchenkov <pt...@Is...> + + * sockmgr.cc, sockmgr.h (Repository): remove signaling to sockets + processing loop; remove signals handlers; call close() method + of ConnectionProcessing on close as server as socket. + + * _sockmgr.cc (Repository): shutdown binded socket before + close---otherwise problems with loop thread termination + on close. + +2002-06-23 Petr Ovtchenkov <pt...@Is...> + + * sockmgr.h, sockmgr.cc, _sockmgr.cc (Repository): remove signal + throw---seems not work properly; provide handler that make sanity + of socket_managerMP<> object by signal TERM---data pass via + thread-specific data with Thread iword/pword functions; + this still need to fix for solaris threads and Windows. + + +2002-06-15 Petr Ovtchenkov <pt...@Is...> + + * _sockstream.cc, sockmgr.cc, sockmgr.h, sockstream, sockstream.cc + (Repository): SELECT and POLL differentiation, depends from OS; + fix 0 bytes read problem on close socket---no ERR, like normal read, but + err will be detected only after attempt to read; + + No search of DNS resolution---optional non-class functions now. + + +2001-07-27 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: Version 1.5.1 + + * Makefile.gcc (Repository): provide workaround for + bug in GNU make 3.79*---it foget old value of variable when + tag-dependent variable use += operator, if includes of makefiles + is too deep---near deepth of 3. This influence to libraries building. + Add explicit link with other C++ shared libraries---this significantly + reduce library size. + +2001-06-05 Petr Ovtchenkov <pt...@Pa...> + + * Makefile.inc (Message): library version 1.5.0 + This reflect real major libsockios release. + +2001-06-04 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: Work with STLport 4.5 beta 8 (from stlport cvs); + remove obsolete in any case dependence from non-STLport iostreams + realization (it should not work). + +2001-06-01 Petr Ovtchenkov <pt...@Pa...> + + * libxmt: + The fork and become_daemon now in xmt library. + + * libxmt: + New exception class fork_in_parent added in xmt. + + * libsockios: + libsockios: version 0.5.0 + +2001-04-09 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + make workaround for bogus Linux define for htons + +2001-03-20 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Satisfy for STLport 4.1 beta 5. + + * libsockios: + Increment patch number. + +2001-03-01 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Removed fields _state and _open in basic_sockbuf; + Socket expected is open if it descriptor (_fd) is not -1; + Function setoptions moved from basic_sockbuf in the sockstream + and bug in passing options fixed (all options except linger)---we need + pass int, bool give an error in result. + + * libsockios: + findhost not set error state in _state (no more this field), + instead of return true/false. + + * libsockios: + Added check for open socket before poll (in underflow) and + check for error flag after. But one require NONBLOCK mode and + removing poll in case of NONBLOCK for Multiple Connections Single Flow + processing policy. + + * libsockios: + Removed shutdown function for socket manager---no sense for it here. + + * libsockios: + Removed fields _state and _open in sockmgr; + + * libsockios: + Incremented patch number (in version presentation) after sockstream + modifications. + +2001-02-15 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Change version + +2001-02-06 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Under hard load I see the same behavior as under HP-UX and Linux. + Fix code: remove difference in code between Solaris and non-Solaris + for MCSF polisy of socket manager. + +2001-01-23 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + The same code as for HP-UX: ERR may not come on poll, and socket + may be closed before + +2001-01-22 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Approach for fix problem with lost info about closed connections + on non-Solaris OSes. Should be checked on other OS, including Solaris + and non-MP variant. + +2000-12-08 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Change STLport version + +2000-11-04 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Fixed bug in Multiplexsor variant of Sock manager: + data from net, that was readed from net and buffered in sockbuf, + not extracted befor next data received (I wait on poll). + Now I check is available data in buffer and return this + sockstream if yes before calling poll. + +2000-09-12 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + ifdef #ident directive (for vary compilers) + Removed wrong 'explicit' declaration: + 'explicit' may be used only for converting constructors. + this-> for inherited functions (HP's aCC A.03.13 don't understand + inheritance and 'using' clause). Created Makefiles for HP's aCC + compiler. Workarounds for HP's aCC names resolution. + This is release that start working on HP-UX 11.00 (with aCC A.03.13). + +2000-06-01 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Artifical delays added when WSAStartup and WSAClean, and Mutex lock + in Init added. Hopes this help... + +2000-05-24 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Attempt to put explicit instantiated code in library. + Seems fail. Size of lib grow, and size of executable also. No sence. + +2000-02-24 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + DLL export/import/none + +2000-02-18 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Fix hidden sockets initialization error. Show MessageBox now. + +2000-01-27 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Remove DllMain + +2000-01-05 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Sockets in diffirent Wins should be initialized by different way (Wins) + +1999-09-16 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Try workaround Win 95 socket problem + +1999-09-14 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Check for WIN version, if winsock not 2.0, allow winsock 1.0 + for Win 95. + +1999-09-03 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Remove __DLLEXPORT definition; This work in DLL now. + +1999-05-25 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + DllMain added; __thr_key moved into _sockstream.cc, where used only + +1999-05-06 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + trying some thread-specific data... + +1999-02-09 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + make dllexport for sockbase (Win); + + * libsockios: + remove constructor/destructor of sockbase for __unix at all. + +1999-02-08 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Include fixes for Win + +1999-02-04 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Socket initialization back here. Counters are per-thread. + +1999-02-03 Petr Ovtchenkov <pt...@Pa...> + + * libsockios: + Initial revision Added: trunk/explore/lib/sockios/Makefile.inc =================================================================== --- trunk/explore/lib/sockios/Makefile.inc (rev 0) +++ trunk/explore/lib/sockios/Makefile.inc 2006-10-05 06:49:32 UTC (rev 1293) @@ -0,0 +1,17 @@ +# -*- Makefile -*- Time-stamp: <06/09/21 22:08:04 ptr> + +LIBNAME = sockios +MAJOR = 1 +MINOR = 9 +PATCH = 0 +SRC_CC = _sockstream.cc _sockmgr.cc +SRC_C = freebsd/getaddrinfo.c \ + freebsd/ns_parse.c \ + freebsd/res_comp.c \ + freebsd/res_data.c \ + freebsd/res_init.c \ + freebsd/res_mkquery.c \ + freebsd/res_query.c \ + freebsd/res_send.c \ + freebsd/res_update.c \ + freebsd/nsdispatch.c This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |