<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sqlparse.hxx,v $
 *
 *  $Revision: 1.18 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 05:02:35 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_SQLPARSE_HXX
#define _CONNECTIVITY_SQLPARSE_HXX

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _OSL_MUTEX_HXX_ //autogen wg. Mutex
#include <osl/mutex.hxx>
#endif
#ifndef _CONNECTIVITY_SQLNODE_HXX
#include <connectivity/sqlnode.hxx>
#endif
#ifndef YYBISON
#ifndef FLEX_SCANNER
#ifndef BISON_INCLUDED
#define BISON_INCLUDED
#include <sqlbison.hxx>
#endif
#endif
#endif
#ifndef _COM_SUN_STAR_I18N_XCHARACTERCLASSIFICATION_HPP_
#include <com/sun/star/i18n/XCharacterClassification.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_I18N_XLOCALEDATA_HPP_
#include <com/sun/star/i18n/XLocaleData.hpp>
#endif
#ifndef CONNECTIVITY_IPARSECONTEXT_HXX
#include "connectivity/IParseContext.hxx"
#endif

// forward declarations
namespace com
{
    namespace sun
    {
        namespace star
        {
            namespace beans
            {
                class XPropertySet;
            }
            namespace util
            {
                class XNumberFormatter;
            }
            namespace lang
            {
                struct Locale;
            }
        }
    }
}
namespace connectivity
{
    class OSQLScanner;

    //==========================================================================
    //= OParseContext
    //==========================================================================
    class OParseContext : public IParseContext
    {
    public:
        OParseContext();

        virtual ~OParseContext();
        // retrieves language specific error messages
        virtual ::rtl::OUString getErrorMessage(ErrorCode _eCodes) const;

        // retrieves language specific keyword strings (only ASCII allowed)
        virtual ::rtl::OString getIntlKeywordAscii(InternationalKeyCode _eKey) const;

        // finds out, if we have an international keyword (only ASCII allowed)
        virtual InternationalKeyCode getIntlKeyCode(const ::rtl::OString& rToken) const;

        // determines the default international setting
        static const ::com::sun::star::lang::Locale& getDefaultLocale();

        /** set's the default locale which should be used when analyzing strings

If no locale is set, and any method which needs a locale is called, a default
            (en-US) is used.

If, while parsing, the locale can be obtained from other sources (such as the number format
            set for a table column), the preferred locale is ignored.

        */
        static void setDefaultLocale( const ::com::sun::star::lang::Locale& _rLocale );

        /** get's a locale instance which should be used when parsing in the context specified by this instance

if this is not overridden by derived classes, it returns the static default locale.

        */
        virtual ::com::sun::star::lang::Locale getPreferredLocale( ) const;
    };

    //==========================================================================
    //= OSQLParser
    //==========================================================================
    /** Parser for SQL92
    */
    class OSQLParser
    {
        friend class OSQLParseNode;
        friend class OSQLInternalNode;
        friend struct OSQLParseNode::SQLParseNodeParameter;

    private:
    //  static parts for parsers
        static sal_uInt32           s_nRuleIDs[OSQLParseNode::rule_count + 1];
        static OParseContext        s_aDefaultContext;

    //  parts controled by mutex
        //  static ::osl::Mutex         s_aMutex;
        static OSQLScanner*         s_pScanner;
        static OSQLParseNodes*      s_pGarbageCollector;
        static sal_Int32            s_nRefCount;

    // informations on the current parse action
        const IParseContext*        m_pContext;
        OSQLParseNode*              m_pParseTree;   // result from parsing
        ::com::sun::star::lang::Locale* m_pLocale;      // current locale settings for parsing
        ::rtl::OUString                     m_sFieldName;   // current field name for a predicate
        ::rtl::OUString                     m_sErrorMessage;// current error msg

        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                                    m_xField;       // current field
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >
                                    m_xFormatter;   // current number formatter
        sal_Int32                   m_nFormatKey;   // numberformat, which should be used
        sal_Int32                   m_nDateFormatKey;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xServiceFactory;
        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCharacterClassification> m_xCharClass;
        static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData>       s_xLocaleData;
        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData>      xDummy; // can be deleted after 627

        // convert a string into double trim it to scale of _nscale and than transform it back to string
        ::rtl::OUString stringToDouble(const ::rtl::OUString& _rValue,sal_Int16 _nScale);
        sal_Int16 buildDate(sal_Int32 _nType,OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);

        static ::osl::Mutex& getMutex();

    public:
        // if NULL, a default context will be used
        // the context must live as long as the parser
        OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory,const IParseContext* _pContext = NULL);
        ~OSQLParser();

        // Parsing an SQLStatement
        OSQLParseNode* parseTree(::rtl::OUString& rErrorMessage,
                       const ::rtl::OUString& rStatement,
                       sal_Bool bInternational = sal_False);

        // Check a Predicate
        OSQLParseNode* predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement,
                       const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
                       const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xField);

        // Access to the context
        const IParseContext& getContext() const {return *m_pContext;}

        // TokenIDToStr: Token-Name zu einer Token-Nr.
        static ::rtl::OString TokenIDToStr(sal_uInt32 nTokenID, const IParseContext* pContext = NULL);

        // StrToTokenID: Token-Nr. zu einem Token-Namen.
        // static sal_uInt32 StrToTokenID(const ::rtl::OString & rName);

        // RuleIDToStr gibt den zu einer RuleID gehoerenden ::rtl::OUString zurueck
        // (Leerstring, falls nicht gefunden)
        static ::rtl::OUString RuleIDToStr(sal_uInt32 nRuleID);

        // StrToRuleID berechnet zu einem ::rtl::OUString die RuleID (d.h. ::com::sun::star::sdbcx::Index in yytname)
        // (0, falls nicht gefunden). Die Suche nach der ID aufgrund eines Strings ist
        // extrem ineffizient (sequentielle Suche nach ::rtl::OUString)!
        static sal_uInt32 StrToRuleID(const ::rtl::OString & rValue);

        // RuleId mit enum, wesentlich effizienter
        static sal_uInt32 RuleID(OSQLParseNode::Rule eRule);
        // compares the _sFunctionName with all known function names and return the DataType of the return value
        static sal_Int32 getFunctionReturnType(const ::rtl::OUString& _sFunctionName, const IParseContext* pContext = NULL);

        void error(sal_Char *fmt);
        int SQLlex();
#ifdef YYBISON
        void setParseTree(OSQLParseNode * pNewParseTree);

        // Is the parse in a special mode?
        // Predicate chack is used to check a condition for a field
        sal_Bool inPredicateCheck() const {return m_xField.is();}
        const ::rtl::OUString& getFieldName() const {return m_sFieldName;}

        void reduceLiteral(OSQLParseNode*& pLiteral, sal_Bool bAppendBlank);
         // does not change the pLiteral argument
        sal_Int16 buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);
        // makes a string out of a number, pLiteral will be deleted
        sal_Int16 buildNode_STR_NUM(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,OSQLParseNode*& pCompare);
        sal_Int16 buildNode_Date(const double& fValue, sal_Int32 nType, OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);

        sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral);
        // pCompre will be deleted if it is not used
        sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);

        sal_Int16 buildLikeRule(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,const OSQLParseNode* pEscape);
        sal_Int16 buildStringNodes(OSQLParseNode*& pLiteral);
#else
#endif
    };
}

#endif //_CONNECTIVITY_SQLPARSE_HXX
<commit_msg>INTEGRATION: CWS qiq (1.18.104); FILE MERGED 2006/05/10 10:19:40 fs 1.18.104.1: added conversion from Scanner's rule ID to Rule enum value (which allows to implement SQLNode::getKnownRuleID)<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sqlparse.hxx,v $
 *
 *  $Revision: 1.19 $
 *
 *  last change: $Author: obo $ $Date: 2006-07-10 14:16:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _CONNECTIVITY_SQLPARSE_HXX
#define _CONNECTIVITY_SQLPARSE_HXX

#ifndef _COM_SUN_STAR_UNO_REFERENCE_H_
#include <com/sun/star/uno/Reference.h>
#endif
#ifndef _OSL_MUTEX_HXX_ //autogen wg. Mutex
#include <osl/mutex.hxx>
#endif
#ifndef _CONNECTIVITY_SQLNODE_HXX
#include <connectivity/sqlnode.hxx>
#endif
#ifndef YYBISON
#ifndef FLEX_SCANNER
#ifndef BISON_INCLUDED
#define BISON_INCLUDED
#include <sqlbison.hxx>
#endif
#endif
#endif
#ifndef _COM_SUN_STAR_I18N_XCHARACTERCLASSIFICATION_HPP_
#include <com/sun/star/i18n/XCharacterClassification.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XMULTISERVICEFACTORY_HPP_
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#endif
#ifndef _COM_SUN_STAR_I18N_XLOCALEDATA_HPP_
#include <com/sun/star/i18n/XLocaleData.hpp>
#endif
#ifndef CONNECTIVITY_IPARSECONTEXT_HXX
#include "connectivity/IParseContext.hxx"
#endif

#include <map>

// forward declarations
namespace com
{
    namespace sun
    {
        namespace star
        {
            namespace beans
            {
                class XPropertySet;
            }
            namespace util
            {
                class XNumberFormatter;
            }
            namespace lang
            {
                struct Locale;
            }
        }
    }
}
namespace connectivity
{
    class OSQLScanner;

    //==========================================================================
    //= OParseContext
    //==========================================================================
    class OParseContext : public IParseContext
    {
    public:
        OParseContext();

        virtual ~OParseContext();
        // retrieves language specific error messages
        virtual ::rtl::OUString getErrorMessage(ErrorCode _eCodes) const;

        // retrieves language specific keyword strings (only ASCII allowed)
        virtual ::rtl::OString getIntlKeywordAscii(InternationalKeyCode _eKey) const;

        // finds out, if we have an international keyword (only ASCII allowed)
        virtual InternationalKeyCode getIntlKeyCode(const ::rtl::OString& rToken) const;

        // determines the default international setting
        static const ::com::sun::star::lang::Locale& getDefaultLocale();

        /** set's the default locale which should be used when analyzing strings

If no locale is set, and any method which needs a locale is called, a default
            (en-US) is used.

If, while parsing, the locale can be obtained from other sources (such as the number format
            set for a table column), the preferred locale is ignored.

        */
        static void setDefaultLocale( const ::com::sun::star::lang::Locale& _rLocale );

        /** get's a locale instance which should be used when parsing in the context specified by this instance

if this is not overridden by derived classes, it returns the static default locale.

        */
        virtual ::com::sun::star::lang::Locale getPreferredLocale( ) const;
    };

    //==========================================================================
    //= OSQLParser
    //==========================================================================
    /** Parser for SQL92
    */
    class OSQLParser
    {
        friend class OSQLParseNode;
        friend class OSQLInternalNode;
        friend struct SQLParseNodeParameter;

    private:
        typedef ::std::map< sal_uInt32, OSQLParseNode::Rule >   RuleIDMap;
    //  static parts for parsers
        static sal_uInt32           s_nRuleIDs[OSQLParseNode::rule_count + 1];
        static RuleIDMap            s_aReverseRuleIDLookup;
        static OParseContext        s_aDefaultContext;

    //  parts controled by mutex
        //  static ::osl::Mutex         s_aMutex;
        static OSQLScanner*         s_pScanner;
        static OSQLParseNodes*      s_pGarbageCollector;
        static sal_Int32            s_nRefCount;

    // informations on the current parse action
        const IParseContext*        m_pContext;
        OSQLParseNode*              m_pParseTree;   // result from parsing
        ::com::sun::star::lang::Locale* m_pLocale;      // current locale settings for parsing
        ::rtl::OUString                     m_sFieldName;   // current field name for a predicate
        ::rtl::OUString                     m_sErrorMessage;// current error msg

        ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >
                                    m_xField;       // current field
        ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >
                                    m_xFormatter;   // current number formatter
        sal_Int32                   m_nFormatKey;   // numberformat, which should be used
        sal_Int32                   m_nDateFormatKey;
        ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >    m_xServiceFactory;
        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XCharacterClassification> m_xCharClass;
        static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData>       s_xLocaleData;
        ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XLocaleData>      xDummy; // can be deleted after 627

        // convert a string into double trim it to scale of _nscale and than transform it back to string
        ::rtl::OUString stringToDouble(const ::rtl::OUString& _rValue,sal_Int16 _nScale);
        sal_Int16 buildDate(sal_Int32 _nType,OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);

        static ::osl::Mutex& getMutex();

    public:
        // if NULL, a default context will be used
        // the context must live as long as the parser
        OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory,const IParseContext* _pContext = NULL);
        ~OSQLParser();

        // Parsing an SQLStatement
        OSQLParseNode* parseTree(::rtl::OUString& rErrorMessage,
                       const ::rtl::OUString& rStatement,
                       sal_Bool bInternational = sal_False);

        // Check a Predicate
        OSQLParseNode* predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement,
                       const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
                       const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & xField);

        // Access to the context
        const IParseContext& getContext() const {return *m_pContext;}

        // TokenIDToStr: Token-Name zu einer Token-Nr.
        static ::rtl::OString TokenIDToStr(sal_uInt32 nTokenID, const IParseContext* pContext = NULL);

        // StrToTokenID: Token-Nr. zu einem Token-Namen.
        // static sal_uInt32 StrToTokenID(const ::rtl::OString & rName);

        // RuleIDToStr gibt den zu einer RuleID gehoerenden ::rtl::OUString zurueck
        // (Leerstring, falls nicht gefunden)
        static ::rtl::OUString RuleIDToStr(sal_uInt32 nRuleID);

        // StrToRuleID berechnet zu einem ::rtl::OUString die RuleID (d.h. ::com::sun::star::sdbcx::Index in yytname)
        // (0, falls nicht gefunden). Die Suche nach der ID aufgrund eines Strings ist
        // extrem ineffizient (sequentielle Suche nach ::rtl::OUString)!
        static sal_uInt32 StrToRuleID(const ::rtl::OString & rValue);

        static OSQLParseNode::Rule RuleIDToRule( sal_uInt32 _nRule );

        // RuleId mit enum, wesentlich effizienter
        static sal_uInt32 RuleID(OSQLParseNode::Rule eRule);
        // compares the _sFunctionName with all known function names and return the DataType of the return value
        static sal_Int32 getFunctionReturnType(const ::rtl::OUString& _sFunctionName, const IParseContext* pContext = NULL);

        void error(sal_Char *fmt);
        int SQLlex();
#ifdef YYBISON
        void setParseTree(OSQLParseNode * pNewParseTree);

        // Is the parse in a special mode?
        // Predicate chack is used to check a condition for a field
        sal_Bool inPredicateCheck() const {return m_xField.is();}
        const ::rtl::OUString& getFieldName() const {return m_sFieldName;}

        void reduceLiteral(OSQLParseNode*& pLiteral, sal_Bool bAppendBlank);
         // does not change the pLiteral argument
        sal_Int16 buildNode(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);
        // makes a string out of a number, pLiteral will be deleted
        sal_Int16 buildNode_STR_NUM(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,OSQLParseNode*& pCompare);
        sal_Int16 buildNode_Date(const double& fValue, sal_Int32 nType, OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);

        sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral);
        // pCompre will be deleted if it is not used
        sal_Int16 buildComparsionRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare);

        sal_Int16 buildLikeRule(OSQLParseNode*& pAppend,OSQLParseNode*& pLiteral,const OSQLParseNode* pEscape);
        sal_Int16 buildStringNodes(OSQLParseNode*& pLiteral);
#else
#endif
    };
}

#endif //_CONNECTIVITY_SQLPARSE_HXX
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: BDriver.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: obo $ $Date: 2008-02-26 15:26:28 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_ADABAS_BDRIVER_HXX_
#define _CONNECTIVITY_ADABAS_BDRIVER_HXX_

#include <com/sun/star/sdbc/XDriver.hpp>
#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbcx/XCreateCatalog.hpp>
#include <com/sun/star/sdbcx/XDropCatalog.hpp>

#include <com/sun/star/lang/XEventListener.hpp>

//#include <unotools/tempfile.hxx>
#ifndef _CPPUHELPER_IMPLBASE4_HXX_
#include <cppuhelper/implbase4.hxx>
#endif
#ifndef _CONNECTIVITY_OFUNCTIONDEFS_HXX_
#include "odbc/OFunctiondefs.hxx"
#endif
#ifndef _CONNECTIVITY_ODBC_ODRIVER_HXX_
#include "odbc/ODriver.hxx"
#endif

namespace connectivity
{
    namespace adabas
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ODriver_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception );

        typedef ::cppu::ImplHelper4<    ::com::sun::star::sdbcx::XCreateCatalog,
                                        ::com::sun::star::sdbcx::XDataDefinitionSupplier,
                                        ::com::sun::star::lang::XEventListener,
                                        ::com::sun::star::sdbcx::XDropCatalog> ODriver_BASE2;

        typedef odbc::ODBCDriver ODriver_BASE;

        class ODriver : public ODriver_BASE,
                        public ODriver_BASE2
        {
            typedef struct DatabaseStruct
            {
                ::rtl::OUString sControlUser;
                ::rtl::OUString sControlPassword;
                ::rtl::OUString sSysUser;
                ::rtl::OUString sSysPassword;
                ::rtl::OUString sDomainPassword;
                ::rtl::OUString sCacheSize;
                ::rtl::OUString sBackupFile;
                ::rtl::OUString sDataDevName;
                ::rtl::OUString sSysDevSpace;
                ::rtl::OUString sTransLogName;
                ::rtl::OUString sDBName;
                sal_Int32       nDataIncrement;     // which size the database should grow
                sal_Int32       nDataSize;
                sal_Int32       nLogSize;
                sal_Bool        bShutDown;
                sal_Bool        bRestoreDatabase;

                DatabaseStruct() : nDataIncrement(0),nDataSize(0),nLogSize(0),bShutDown(sal_False),bRestoreDatabase(sal_False){ }
            } TDatabaseStruct;

            DECLARE_STL_USTRINGACCESS_MAP(TDatabaseStruct,TDatabaseMap);
            TDatabaseMap    m_aDatabaseMap; // contains all adabas databases with their flag to shut down or not

            // environment vars
            ::rtl::OUString m_sDbWork;
            ::rtl::OUString m_sDbConfig;
            ::rtl::OUString m_sDbRoot;
            ::rtl::OUString m_sDbWorkURL;
            ::rtl::OUString m_sDbConfigURL;
            ::rtl::OUString m_sDbRootURL;
            ::rtl::OUString m_sDbRunDir;
            ::rtl::OUString m_sDelimit;

            void checkAndInsertNewDevSpace(const ::rtl::OUString& _rDBName,const TDatabaseStruct& _rDBInfo);
            void checkAndRestart(const ::rtl::OUString& _rDBName,const TDatabaseStruct& _rDbInfo);
            void X_CONS(const ::rtl::OUString& _DBNAME,const ::rtl::OString& _ACTION,const ::rtl::OUString& _FILENAME);
            sal_Bool getDBName(const ::rtl::OUString& _rName,::rtl::OUString& _rDBName) const;
            ::rtl::OUString getDatabaseInitFile(  const TDatabaseStruct& _aInfo);
            ::rtl::OUString generateInitFile()  const;
            void fillEnvironmentVariables();
            void fillInfo(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info, TDatabaseStruct& _rDBInfo /*out*/);
            void LoadBatch(const ::rtl::OUString& _rDBNAME,
                        const ::rtl::OUString& _rUSR,
                        const ::rtl::OUString& _rPWD,
                        const ::rtl::OUString& _rBatch);
            void XUTIL(const ::rtl::OUString& _rParam,
                    const ::rtl::OUString& _DBNAME,
                    const ::rtl::OUString& _USRNAME,
                    const ::rtl::OUString& _USRPWD);
            int X_STOP(const ::rtl::OUString& _DBNAME);
            int X_START(const ::rtl::OUString& _DBNAME);
            void createDb(const TDatabaseStruct& _aInfo);
            void clearDatabase(const ::rtl::OUString& _rDBName);
            int X_PARAM(const ::rtl::OUString& _DBNAME,
                        const ::rtl::OUString& _USR,
                        const ::rtl::OUString& _PWD,
                        const ::rtl::OUString& _CMD);
            sal_Int32 CreateFiles(const TDatabaseStruct& _aInfo);
            sal_Bool CreateFile(const ::rtl::OUString &_FileName,
                                sal_Int32 _nSize);
            void PutParam(const ::rtl::OUString& rDBNAME,
                        const ::rtl::OUString& rWhat,
                        const ::rtl::OUString& rHow);
            void createNeededDirs(      const ::rtl::OUString& _rDBName);
            sal_Bool isKernelVersion(const char* _pVersion);
            sal_Bool isVersion(     const ::rtl::OUString& _rDBName,
                                    const char* _pVersion);

            void convertOldVersion(     const ::rtl::OUString& _rDBName,
                                        const TDatabaseStruct& _rDbInfo);

            void installSystemTables(   const TDatabaseStruct& _aInfo);

        protected:
            virtual SQLHANDLE EnvironmentHandle(::rtl::OUString &_rPath);
            virtual ~ODriver();
        public:
            explicit ODriver(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory);

            // XInterface
            static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
            static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw (::com::sun::star::uno::RuntimeException);
        private:
            DECLARE_SERVICE_INFO();

            virtual oslGenericFunction getOdbcFunction(sal_Int32 _nIndex)  const;
            // OComponentHelper
            virtual void SAL_CALL disposing(void);
            virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL acquire() throw();
            virtual void SAL_CALL release() throw();

            // XDriver
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMajorVersion(  ) throw(::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMinorVersion(  ) throw(::com::sun::star::uno::RuntimeException);

            // XDataDefinitionSupplier
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& connection ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByURL( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);

            // XCreateCatalog
            virtual void SAL_CALL createCatalog( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
            // XDropCatalog
            virtual void SAL_CALL dropCatalog( const ::rtl::OUString& catalogName, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
            // XEventListener
            virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
        };
    }

}
#endif //_CONNECTIVITY_ADABAS_BDRIVER_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.12.12); FILE MERGED 2008/04/01 15:09:08 thb 1.12.12.3: #i85898# Stripping all external header guards 2008/04/01 10:53:18 thb 1.12.12.2: #i85898# Stripping all external header guards 2008/03/28 15:24:07 rt 1.12.12.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: BDriver.hxx,v $
 * $Revision: 1.13 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_ADABAS_BDRIVER_HXX_
#define _CONNECTIVITY_ADABAS_BDRIVER_HXX_

#include <com/sun/star/sdbc/XDriver.hpp>
#include <com/sun/star/sdbcx/XDataDefinitionSupplier.hpp>
#include <com/sun/star/sdbcx/XTablesSupplier.hpp>
#include <com/sun/star/sdbcx/XCreateCatalog.hpp>
#include <com/sun/star/sdbcx/XDropCatalog.hpp>

#include <com/sun/star/lang/XEventListener.hpp>

//#include <unotools/tempfile.hxx>
#include <cppuhelper/implbase4.hxx>
#include "odbc/OFunctiondefs.hxx"
#include "odbc/ODriver.hxx"

namespace connectivity
{
    namespace adabas
    {
        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ODriver_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception );

        typedef ::cppu::ImplHelper4<    ::com::sun::star::sdbcx::XCreateCatalog,
                                        ::com::sun::star::sdbcx::XDataDefinitionSupplier,
                                        ::com::sun::star::lang::XEventListener,
                                        ::com::sun::star::sdbcx::XDropCatalog> ODriver_BASE2;

        typedef odbc::ODBCDriver ODriver_BASE;

        class ODriver : public ODriver_BASE,
                        public ODriver_BASE2
        {
            typedef struct DatabaseStruct
            {
                ::rtl::OUString sControlUser;
                ::rtl::OUString sControlPassword;
                ::rtl::OUString sSysUser;
                ::rtl::OUString sSysPassword;
                ::rtl::OUString sDomainPassword;
                ::rtl::OUString sCacheSize;
                ::rtl::OUString sBackupFile;
                ::rtl::OUString sDataDevName;
                ::rtl::OUString sSysDevSpace;
                ::rtl::OUString sTransLogName;
                ::rtl::OUString sDBName;
                sal_Int32       nDataIncrement;     // which size the database should grow
                sal_Int32       nDataSize;
                sal_Int32       nLogSize;
                sal_Bool        bShutDown;
                sal_Bool        bRestoreDatabase;

                DatabaseStruct() : nDataIncrement(0),nDataSize(0),nLogSize(0),bShutDown(sal_False),bRestoreDatabase(sal_False){ }
            } TDatabaseStruct;

            DECLARE_STL_USTRINGACCESS_MAP(TDatabaseStruct,TDatabaseMap);
            TDatabaseMap    m_aDatabaseMap; // contains all adabas databases with their flag to shut down or not

            // environment vars
            ::rtl::OUString m_sDbWork;
            ::rtl::OUString m_sDbConfig;
            ::rtl::OUString m_sDbRoot;
            ::rtl::OUString m_sDbWorkURL;
            ::rtl::OUString m_sDbConfigURL;
            ::rtl::OUString m_sDbRootURL;
            ::rtl::OUString m_sDbRunDir;
            ::rtl::OUString m_sDelimit;

            void checkAndInsertNewDevSpace(const ::rtl::OUString& _rDBName,const TDatabaseStruct& _rDBInfo);
            void checkAndRestart(const ::rtl::OUString& _rDBName,const TDatabaseStruct& _rDbInfo);
            void X_CONS(const ::rtl::OUString& _DBNAME,const ::rtl::OString& _ACTION,const ::rtl::OUString& _FILENAME);
            sal_Bool getDBName(const ::rtl::OUString& _rName,::rtl::OUString& _rDBName) const;
            ::rtl::OUString getDatabaseInitFile(  const TDatabaseStruct& _aInfo);
            ::rtl::OUString generateInitFile()  const;
            void fillEnvironmentVariables();
            void fillInfo(const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info, TDatabaseStruct& _rDBInfo /*out*/);
            void LoadBatch(const ::rtl::OUString& _rDBNAME,
                        const ::rtl::OUString& _rUSR,
                        const ::rtl::OUString& _rPWD,
                        const ::rtl::OUString& _rBatch);
            void XUTIL(const ::rtl::OUString& _rParam,
                    const ::rtl::OUString& _DBNAME,
                    const ::rtl::OUString& _USRNAME,
                    const ::rtl::OUString& _USRPWD);
            int X_STOP(const ::rtl::OUString& _DBNAME);
            int X_START(const ::rtl::OUString& _DBNAME);
            void createDb(const TDatabaseStruct& _aInfo);
            void clearDatabase(const ::rtl::OUString& _rDBName);
            int X_PARAM(const ::rtl::OUString& _DBNAME,
                        const ::rtl::OUString& _USR,
                        const ::rtl::OUString& _PWD,
                        const ::rtl::OUString& _CMD);
            sal_Int32 CreateFiles(const TDatabaseStruct& _aInfo);
            sal_Bool CreateFile(const ::rtl::OUString &_FileName,
                                sal_Int32 _nSize);
            void PutParam(const ::rtl::OUString& rDBNAME,
                        const ::rtl::OUString& rWhat,
                        const ::rtl::OUString& rHow);
            void createNeededDirs(      const ::rtl::OUString& _rDBName);
            sal_Bool isKernelVersion(const char* _pVersion);
            sal_Bool isVersion(     const ::rtl::OUString& _rDBName,
                                    const char* _pVersion);

            void convertOldVersion(     const ::rtl::OUString& _rDBName,
                                        const TDatabaseStruct& _rDbInfo);

            void installSystemTables(   const TDatabaseStruct& _aInfo);

        protected:
            virtual SQLHANDLE EnvironmentHandle(::rtl::OUString &_rPath);
            virtual ~ODriver();
        public:
            explicit ODriver(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory);

            // XInterface
            static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
            static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw (::com::sun::star::uno::RuntimeException);
        private:
            DECLARE_SERVICE_INFO();

            virtual oslGenericFunction getOdbcFunction(sal_Int32 _nIndex)  const;
            // OComponentHelper
            virtual void SAL_CALL disposing(void);
            virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException);
            virtual void SAL_CALL acquire() throw();
            virtual void SAL_CALL release() throw();

            // XDriver
            ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMajorVersion(  ) throw(::com::sun::star::uno::RuntimeException);
            virtual sal_Int32 SAL_CALL getMinorVersion(  ) throw(::com::sun::star::uno::RuntimeException);

            // XDataDefinitionSupplier
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByConnection( const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& connection ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbcx::XTablesSupplier > SAL_CALL getDataDefinitionByURL( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);

            // XCreateCatalog
            virtual void SAL_CALL createCatalog( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException);
            // XDropCatalog
            virtual void SAL_CALL dropCatalog( const ::rtl::OUString& catalogName, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::container::NoSuchElementException, ::com::sun::star::uno::RuntimeException);
            // XEventListener
            virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) throw(::com::sun::star::uno::RuntimeException);
        };
    }

}
#endif //_CONNECTIVITY_ADABAS_BDRIVER_HXX_

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "sysinv.h"

PNODE GetVolumeNode(__in PNODE parent, __in LPTSTR volumeName);
HANDLE GetVolumeHandle(LPWSTR volumePath);
LPTSTR GetNextStringInMulti(LPTSTR multiString);

PNODE GetVolumesNode()
{
	HANDLE fvh;
	TCHAR lpszVolumeName[MAX_PATH + 1];
	BOOL moreVolumes;
	PNODE node = node_alloc(L"Volumes", NODE_FLAG_TABLE);

	moreVolumes = (INVALID_HANDLE_VALUE != (fvh = FindFirstVolume((LPWSTR)lpszVolumeName, MAX_PATH)));
	if(moreVolumes) {
		while(0 != moreVolumes) {
			GetVolumeNode(node, lpszVolumeName);
			moreVolumes = FindNextVolume(fvh, (LPWSTR)lpszVolumeName, MAX_PATH);
		}

		FindVolumeClose(fvh);
	}

	return node;
}

PNODE GetVolumeNode(__in PNODE parent, __in LPTSTR volumeName)
{
	PNODE volumeNode, extentsNode, extentNode;
	WCHAR buffer[8][MAX_PATH + 1];
	DWORD dwords[4];
	LPTSTR dbuffer = NULL;
	LPTSTR dbuffer2 = NULL;
	const DWORD maxBufferSize = MAX_PATH + 1;
	DWORD bufferSize = 0;
	HANDLE hVolume = INVALID_HANDLE_VALUE;
	DWORD ret;
	PVOLUME_DISK_EXTENTS extents;
	DISK_EXTENT extent;
	DWORD i;

	// Allocate new node
	volumeNode = node_alloc(L"Volume", NODE_FLAG_TABLE_ENTRY);
	node_att_set(volumeNode, L"Name", volumeName, NODE_ATT_FLAG_KEY);

	// Get volume path without trailing '\'
	wcscpy((TCHAR *) &buffer, volumeName);
	buffer[0][wcslen(buffer[0]) - 1] = '\0';

	// Get a handle to volume (not the volume's root)
	hVolume = GetVolumeHandle(buffer[0]);

	// Get DOS Device path (eg. "\Device\HarddiskVolume1")
	bufferSize = sizeof(TCHAR) * maxBufferSize;
	dbuffer = (LPTSTR) LocalAlloc(LPTR, bufferSize);
	while(!(ret = QueryDosDevice(&buffer[0][4], dbuffer, bufferSize))) {
		if(ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
			LocalFree(dbuffer);
			dbuffer = NULL;
			break;
		} else {
			LocalFree(dbuffer);
			bufferSize *= 2;
			dbuffer = (LPTSTR) LocalAlloc(LPTR, bufferSize);
		}
	}
	// Expand DosPath string array
	if(NULL != dbuffer) {
		node_att_set_multi(volumeNode, L"DosPaths", dbuffer, 0);
		LocalFree(dbuffer);
	}

	// Get mount point paths (Eg. "C:\")
	bufferSize = sizeof(TCHAR) * maxBufferSize;
	dbuffer = (LPTSTR) LocalAlloc(LPTR, bufferSize);
	while(!GetVolumePathNamesForVolumeName(volumeName, dbuffer, bufferSize, &bufferSize)) {
		if(ERROR_MORE_DATA == GetLastError()) {
			LocalFree(dbuffer);
			bufferSize *= 2;
			dbuffer = (LPTSTR) LocalAlloc(LPTR, sizeof(TCHAR) * bufferSize);
		}

		else {
			LocalFree(dbuffer);
			dbuffer = NULL;
			break;
		}
	}

	if(NULL != dbuffer) {
		node_att_set_multi(volumeNode, L"MountPoints", dbuffer, 0);
		LocalFree(dbuffer);
	}

	// Get volume information from API
	if(GetVolumeInformation(
		volumeName,
		(LPWSTR) &buffer[1],
		maxBufferSize,
		&dwords[0],
		&dwords[1],
		&dwords[2],
		(LPWSTR) &buffer[2],
		maxBufferSize
	)) {
		node_att_set(volumeNode, L"Label", buffer[1], 0);
		node_att_set(volumeNode, L"Format", buffer[2], 0);
	}

	// Get disk extents
	if(INVALID_HANDLE_VALUE != hVolume) {
		ret = 0;
		bufferSize = sizeof(VOLUME_DISK_EXTENTS);
		extents = (VOLUME_DISK_EXTENTS *) LocalAlloc(LPTR, bufferSize);
		while(!DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, (LPVOID) extents, bufferSize, &ret, NULL)) {
			if(ERROR_MORE_DATA == GetLastError()) {
				bufferSize *= 2;
				LocalFree(extents);
				extents = (VOLUME_DISK_EXTENTS *) LocalAlloc(LPTR, bufferSize);
			}

			else {
				break;
			}
		}

		if(0 < extents->NumberOfDiskExtents) {
			extentsNode = node_alloc(L"DiskExtents", NODE_FLAG_TABLE);
			node_append_child(volumeNode, extentsNode);
			for(i = 0; i < extents->NumberOfDiskExtents; i++) {
				extent = extents->Extents[i];
				swprintf(buffer[0], L"%u", i);
				swprintf(buffer[1], L"%u", extent.DiskNumber);
				swprintf(buffer[2], L"0x%016lX", extent.StartingOffset.QuadPart);
				swprintf(buffer[3], L"0x%016lX", extent.ExtentLength.QuadPart);

				extentNode = node_append_new(extentsNode, L"Extent", NODE_FLAG_TABLE_ENTRY);
				node_att_set(extentNode, L"Index", buffer[0], NODE_ATT_FLAG_KEY);
				node_att_set(extentNode, L"DiskIndex", buffer[1], 0);
				node_att_set(extentNode, L"StartingOffset", buffer[2], 0);
				node_att_set(extentNode, L"Length", buffer[3], 0);
			}
		}

		LocalFree(extents);
	}

	// Clean up
	if(INVALID_HANDLE_VALUE != hVolume)
		CloseHandle(hVolume);

	node_append_child(parent, volumeNode);
	return volumeNode;
}

HANDLE GetVolumeHandle(LPWSTR volumePath)
{
	HANDLE hVolume = INVALID_HANDLE_VALUE;

	hVolume = CreateFile(volumePath, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

	return hVolume;
}

LPTSTR GetNextStringInMulti(LPTSTR multiString) {
	WCHAR *p = multiString;

	if((* p) == '\0')
		return NULL;

	while((* p++) != '\0')
	{};

	return p;
}<commit_msg>Added volume type discovery<commit_after>#include "stdafx.h"
#include "sysinv.h"

PNODE GetVolumeNode(__in PNODE parent, __in LPTSTR volumeName);
HANDLE GetVolumeHandle(LPWSTR volumePath);
LPTSTR GetNextStringInMulti(LPTSTR multiString);

PNODE GetVolumesNode()
{
	HANDLE fvh;
	TCHAR lpszVolumeName[MAX_PATH + 1];
	BOOL moreVolumes;
	PNODE node = node_alloc(L"Volumes", NODE_FLAG_TABLE);

	moreVolumes = (INVALID_HANDLE_VALUE != (fvh = FindFirstVolume((LPWSTR)lpszVolumeName, MAX_PATH)));
	if(moreVolumes) {
		while(0 != moreVolumes) {
			GetVolumeNode(node, lpszVolumeName);
			moreVolumes = FindNextVolume(fvh, (LPWSTR)lpszVolumeName, MAX_PATH);
		}

		FindVolumeClose(fvh);
	}

	return node;
}

PNODE GetVolumeNode(__in PNODE parent, __in LPTSTR volumeName)
{
	PNODE volumeNode, extentsNode, extentNode;
	WCHAR buffer[8][MAX_PATH + 1];
	DWORD dwords[4];
	LPTSTR dbuffer = NULL;
	LPTSTR dbuffer2 = NULL;
	const DWORD maxBufferSize = MAX_PATH + 1;
	DWORD bufferSize = 0;
	HANDLE hVolume = INVALID_HANDLE_VALUE;
	DWORD ret;
	PVOLUME_DISK_EXTENTS extents;
	DISK_EXTENT extent;
	DWORD i;
	UINT driveType;

	// Allocate new node
	volumeNode = node_alloc(L"Volume", NODE_FLAG_TABLE_ENTRY);
	node_att_set(volumeNode, L"Name", volumeName, NODE_ATT_FLAG_KEY);

	// Get volume type
	driveType = GetDriveType(volumeName);
	switch (driveType) {
	case DRIVE_REMOVABLE:
		node_att_set(volumeNode, _T("Type"), _T("Removable"), 0);
		break;

	case DRIVE_FIXED:
		node_att_set(volumeNode, _T("Type"), _T("Fixed"), 0);
		break;

	case DRIVE_REMOTE:
		node_att_set(volumeNode, _T("Type"), _T("Network"), 0);
		break;

	case DRIVE_CDROM:
		node_att_set(volumeNode, _T("Type"), _T("Optical"), 0);
		break;

	case DRIVE_RAMDISK:
		node_att_set(volumeNode, _T("Type"), _T("RAM Disk"), 0);
		break;

	default:
		node_att_set(volumeNode, _T("Type"), _T("Unknown"), 0);
		break;
	}

	// Get volume path without trailing '\'
	wcscpy((TCHAR *) &buffer, volumeName);
	buffer[0][wcslen(buffer[0]) - 1] = '\0';

	// Get a handle to volume (not the volume's root)
	hVolume = GetVolumeHandle(buffer[0]);

	// Get DOS Device path (eg. "\Device\HarddiskVolume1")
	bufferSize = sizeof(TCHAR) * maxBufferSize;
	dbuffer = (LPTSTR) LocalAlloc(LPTR, bufferSize);
	while(!(ret = QueryDosDevice(&buffer[0][4], dbuffer, bufferSize))) {
		if(ERROR_INSUFFICIENT_BUFFER != GetLastError()) {
			LocalFree(dbuffer);
			dbuffer = NULL;
			break;
		} else {
			LocalFree(dbuffer);
			bufferSize *= 2;
			dbuffer = (LPTSTR) LocalAlloc(LPTR, bufferSize);
		}
	}
	// Expand DosPath string array
	if(NULL != dbuffer) {
		node_att_set_multi(volumeNode, L"DosPaths", dbuffer, 0);
		LocalFree(dbuffer);
	}

	// Get mount point paths (Eg. "C:\")
	bufferSize = sizeof(TCHAR) * maxBufferSize;
	dbuffer = (LPTSTR) LocalAlloc(LPTR, bufferSize);
	while(!GetVolumePathNamesForVolumeName(volumeName, dbuffer, bufferSize, &bufferSize)) {
		if(ERROR_MORE_DATA == GetLastError()) {
			LocalFree(dbuffer);
			bufferSize *= 2;
			dbuffer = (LPTSTR) LocalAlloc(LPTR, sizeof(TCHAR) * bufferSize);
		}

		else {
			LocalFree(dbuffer);
			dbuffer = NULL;
			break;
		}
	}

	if(NULL != dbuffer) {
		node_att_set_multi(volumeNode, L"MountPoints", dbuffer, 0);
		LocalFree(dbuffer);
	}

	// Get volume information from API
	if(GetVolumeInformation(
		volumeName,
		(LPWSTR) &buffer[1],
		maxBufferSize,
		&dwords[0],
		&dwords[1],
		&dwords[2],
		(LPWSTR) &buffer[2],
		maxBufferSize
	)) {
		node_att_set(volumeNode, L"Label", buffer[1], 0);
		node_att_set(volumeNode, L"Format", buffer[2], 0);
	}

	// Get disk extents
	if(INVALID_HANDLE_VALUE != hVolume) {
		ret = 0;
		bufferSize = sizeof(VOLUME_DISK_EXTENTS);
		extents = (VOLUME_DISK_EXTENTS *) LocalAlloc(LPTR, bufferSize);
		while(!DeviceIoControl(hVolume, IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS, NULL, 0, (LPVOID) extents, bufferSize, &ret, NULL)) {
			if(ERROR_MORE_DATA == GetLastError()) {
				bufferSize *= 2;
				LocalFree(extents);
				extents = (VOLUME_DISK_EXTENTS *) LocalAlloc(LPTR, bufferSize);
			}

			else {
				break;
			}
		}

		if(0 < extents->NumberOfDiskExtents) {
			extentsNode = node_alloc(L"DiskExtents", NODE_FLAG_TABLE);
			node_append_child(volumeNode, extentsNode);
			for(i = 0; i < extents->NumberOfDiskExtents; i++) {
				extent = extents->Extents[i];
				swprintf(buffer[0], L"%u", i);
				swprintf(buffer[1], L"%u", extent.DiskNumber);
				swprintf(buffer[2], L"0x%016lX", extent.StartingOffset.QuadPart);
				swprintf(buffer[3], L"0x%016lX", extent.ExtentLength.QuadPart);

				extentNode = node_append_new(extentsNode, L"Extent", NODE_FLAG_TABLE_ENTRY);
				node_att_set(extentNode, L"Index", buffer[0], NODE_ATT_FLAG_KEY);
				node_att_set(extentNode, L"DiskIndex", buffer[1], 0);
				node_att_set(extentNode, L"StartingOffset", buffer[2], 0);
				node_att_set(extentNode, L"Length", buffer[3], 0);
			}
		}

		LocalFree(extents);
	}

	// Clean up
	if(INVALID_HANDLE_VALUE != hVolume)
		CloseHandle(hVolume);

	node_append_child(parent, volumeNode);
	return volumeNode;
}

HANDLE GetVolumeHandle(LPWSTR volumePath)
{
	HANDLE hVolume = INVALID_HANDLE_VALUE;

	hVolume = CreateFile(volumePath, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

	return hVolume;
}

LPTSTR GetNextStringInMulti(LPTSTR multiString) {
	WCHAR *p = multiString;

	if((* p) == '\0')
		return NULL;

	while((* p++) != '\0')
	{};

	return p;
}<|endoftext|>


<commit_before>#include "peercred.h"

// PUT
#include <specialized/osdetect.h>
#include <cxxutils/posix_helpers.h>
#include <cxxutils/socket_helpers.h>

#if defined(__solaris__) // Solaris
#pragma message("Information: using Solaris code")

#include <ucred.h>

int recv_cred(int socket, proccred_t& cred) noexcept
{
  uproccred_t* data = nullptr;

  int rval = ::getpeerucred(socket, &data);

  if(rval == posix::success_response)
  {
    cred.pid = ucred_getpid (data);
    cred.uid = ucred_geteuid(data);
    cred.gid = ucred_getegid(data);
    ucred_free(data);
    if (cred.pid == pid_t(-1) ||
        cred.uid == uid_t(-1) ||
        cred.gid == gid_t(-1))
      rval = posix::error_response;
  }
  return rval;
}

int send_cred(int) noexcept
{ return posix::success_response; }

#elif defined (SO_PEERCRED) || defined (LOCAL_PEEREID) || defined(LOCAL_PEERCRED) /* Linux/OpenBSD/legacy NetBSD/Darwin/legacy FreeBSD */

# if defined (SO_PEERCRED) && \
    (defined(__linux__)    /* Linux    */ || \
     defined(__kfreebsd__) /* kFreeBSD */ )
constexpr int socket_cred_option = SO_PEERCRED;
typedef ucred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.uid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.gid; }

# elif defined(SO_PEERCRED) && defined(__OpenBSD__)
constexpr int socket_cred_option = SO_PEERCRED;
typedef sockpeercred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.uid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.gid; }

# elif defined(LOCAL_PEEREID) && defined(__NetBSD__) /* legacy NetBSD */
constexpr int socket_cred_option = LOCAL_PEEREID;
typedef unpcbid cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.unp_pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.unp_euid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.unp_egid; }

# elif defined(LOCAL_PEERCRED)  /* Darwin / legacy FreeBSD */
#include <sys/ucred.h>
constexpr int credential_message = LOCAL_PEERCRED;
typedef xucred cred_t;
constexpr pid_t peer_pid(const cred_t&     ) { return -1; }
constexpr uid_t peer_uid(const cred_t& data) { return data.cr_uid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.cr_groups[0]; }

# elif defined(SO_PEERCRED)
#  error SO_PEERCRED macro detected but platform is unrecognized.  Please submit a patch!
# elif defined(LOCAL_PEEREID)
#  error LOCAL_PEEREID macro detected but platform is unrecognized.  Please submit a patch!
# endif

int recv_cred(int socket, proccred_t& cred) noexcept
{
  cred_t data;
  socklen_t len = sizeof(data);

  int rval = ::getsockopt(socket, SOL_SOCKET, socket_cred_option, &data, &len);

  if(len != sizeof(data))
    rval = posix::error(std::errc::invalid_argument);

  if(rval == posix::success_response)
  {
    cred.pid = peer_pid(data);
    cred.uid = peer_uid(data);
    cred.gid = peer_gid(data);
  }
  return rval;
}

int send_cred(int) noexcept
{ return posix::success_response; }

#elif defined(SCM_CREDENTIALS) || defined(SCM_CREDS)

# if defined(SCM_CREDENTIALS) /* Linux / kFreeBSD */
constexpr int credential_message = SCM_CREDENTIALS;
typedef ucred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.uid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.gid; }

# elif defined(SCM_CREDS) && defined(__NetBSD__) /* NetBSD */
constexpr int credential_message = SCM_CREDS;
typedef cred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.sc_pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.sc_euid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.sc_egid; }

# elif defined(SCM_CREDS) && \
      (defined(__FreeBSD__)   /* FreeBSD      */ || \
       defined(__DragonFly__) /* DragonFlyBSD */ || \
       defined(__gnu_hurd__)  /* GNU/HURD     */ )
constexpr int credential_message = SCM_CREDS;
typedef cmsgcred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.cmcred_pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.cmcred_euid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.cmcred_groups[0]; }

# elif defined(SCM_CREDS)
#  error SCM_CREDS macro detected but platform is unrecognized.  Please submit a patch!
# endif

int recv_cred(int socket, proccred_t& cred) noexcept
{
  struct msghdr message;
  union
  {
    char    rawbuffer[CMSG_SPACE(sizeof(cred_t))];
    cmsghdr formatted;
  } cmsg_header;
  std::memset(cmsg_header.rawbuffer, 0, sizeof(cmsg_header.rawbuffer)); // initialize memory

  char data = 0; // dummy data
  struct iovec iov = { &data, sizeof(data) };

  message.msg_iov = &iov;
  message.msg_iovlen = 1;
  message.msg_name = NULL;
  message.msg_namelen = 0;
  message.msg_control = &cmsg_header.formatted;
  message.msg_controllen = sizeof(cmsg_header.rawbuffer);
  message.msg_flags = 0;

  ssize_t nr = posix::recvmsg(socket, &message);
  if(nr == -1)
    return posix::error_response;

  if(CMSG_FIRSTHDR(&message) == &cmsg_header.formatted &&
     cmsg_header.formatted.cmsg_len   <= sizeof(cmsg_header.rawbuffer) &&
     cmsg_header.formatted.cmsg_level == SOL_SOCKET &&
     cmsg_header.formatted.cmsg_type  == credential_message)
  {
    cred_t* data = reinterpret_cast<cred_t*>(CMSG_DATA(&cmsg_header.formatted));
    cred.pid = peer_pid(*data);
    cred.uid = peer_uid(*data);
    cred.gid = peer_gid(*data);
    return posix::success_response;
  }
  return posix::error_response;
}

int send_cred(int socket) noexcept
{
  struct msghdr message;
  union
  {
    char    rawbuffer[CMSG_SPACE(sizeof(cred_t))];
    cmsghdr formatted;
  } cmsg_header;
  std::memset(cmsg_header.rawbuffer, 0, sizeof(cmsg_header.rawbuffer)); // initialize memory

  cmsg_header.formatted.cmsg_len   = CMSG_LEN(sizeof(cred_t));
  cmsg_header.formatted.cmsg_level = SOL_SOCKET;
  cmsg_header.formatted.cmsg_type  = credential_message;

  char data = 0; // dummy data
  struct iovec iov = { &data, sizeof(data) };

  message.msg_iov = &iov;
  message.msg_iovlen = 1;
  message.msg_name = NULL;
  message.msg_namelen = 0;
  message.msg_control = &cmsg_header.formatted;
  message.msg_controllen = sizeof(cmsg_header.rawbuffer);
  message.msg_flags = 0;

  ssize_t nr = posix::sendmsg(socket, &message);
  if(nr == -1)
    return posix::error_response;
  return int(nr);
}

#else

#pragma message("Socket credentials are not supported on this platform.")

int recv_cred(int socket, proccred_t& cred) noexcept
{
  cred.pid = -1;
  cred.uid = -1;
  cred.gid = -1;
  return posix::error(ENOSYS);
}

int send_cred(int) noexcept
{ return posix::error(ENOSYS); }

#endif
<commit_msg>a section just for darwin! :)<commit_after>#include "peercred.h"

// PUT
#include <specialized/osdetect.h>
#include <cxxutils/posix_helpers.h>
#include <cxxutils/socket_helpers.h>

#if defined(__solaris__) // Solaris
# include <ucred.h>

int recv_cred(int socket, proccred_t& cred) noexcept
{
  uproccred_t* data = nullptr;

  int rval = ::getpeerucred(socket, &data);

  if(rval == posix::success_response)
  {
    cred.pid = ucred_getpid (data);
    cred.uid = ucred_geteuid(data);
    cred.gid = ucred_getegid(data);
    ucred_free(data);
    if (cred.pid == pid_t(-1) ||
        cred.uid == uid_t(-1) ||
        cred.gid == gid_t(-1))
      rval = posix::error_response;
  }
  return rval;
}

int send_cred(int) noexcept
{ return posix::success_response; }

#elif defined(__darwin__)  /* Darwin */
# include <sys/ucred.h>

int recv_cred(int socket, proccred_t& cred) noexcept
{
  xucred data;
  socklen_t len = sizeof(data);

  int rval = ::getsockopt(socket, SOL_LOCAL, LOCAL_PEERCRED, &data, &len);

  if(len != sizeof(data))
    rval = posix::error(std::errc::invalid_argument);

  if(rval == posix::success_response)
  {
    cred.uid = data.cr_uid;
    cred.gid = data.cr_groups[0];

    len = sizeof(cred.pid);
    rval = ::getsockopt(socket, SOL_LOCAL, LOCAL_PEERPID, &cred.pid, &len);

    if(len != sizeof(pid))
      rval = posix::error(std::errc::invalid_argument);
  }

  return rval;
}

int send_cred(int) noexcept
{ return posix::success_response; }

#elif defined (SO_PEERCRED) || defined (LOCAL_PEEREID) /* Linux/OpenBSD/legacy NetBSD */

# if defined (SO_PEERCRED) && \
    (defined(__linux__)    /* Linux    */ || \
     defined(__kfreebsd__) /* kFreeBSD */ )
constexpr int socket_cred_option = SO_PEERCRED;
typedef ucred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.uid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.gid; }

# elif defined(SO_PEERCRED) && defined(__OpenBSD__)
constexpr int socket_cred_option = SO_PEERCRED;
typedef sockpeercred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.uid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.gid; }

# elif defined(LOCAL_PEEREID) && defined(__NetBSD__) /* legacy NetBSD */
constexpr int socket_cred_option = LOCAL_PEEREID;
typedef unpcbid cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.unp_pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.unp_euid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.unp_egid; }

# elif defined(SO_PEERCRED)
#  error SO_PEERCRED macro detected but platform is unrecognized.  Please submit a patch!
# elif defined(LOCAL_PEEREID)
#  error LOCAL_PEEREID macro detected but platform is unrecognized.  Please submit a patch!
# endif

int recv_cred(int socket, proccred_t& cred) noexcept
{
  cred_t data;
  socklen_t len = sizeof(data);

  int rval = ::getsockopt(socket, SOL_SOCKET, socket_cred_option, &data, &len);

  if(len != sizeof(data))
    rval = posix::error(std::errc::invalid_argument);

  if(rval == posix::success_response)
  {
    cred.pid = peer_pid(data);
    cred.uid = peer_uid(data);
    cred.gid = peer_gid(data);
  }
  return rval;
}

int send_cred(int) noexcept
{ return posix::success_response; }

#elif defined(SCM_CREDENTIALS) || defined(SCM_CREDS)

# if defined(SCM_CREDENTIALS) /* Linux / kFreeBSD */
constexpr int credential_message = SCM_CREDENTIALS;
typedef ucred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.uid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.gid; }

# elif defined(SCM_CREDS) && defined(__NetBSD__) /* NetBSD */
constexpr int credential_message = SCM_CREDS;
typedef cred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.sc_pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.sc_euid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.sc_egid; }

# elif defined(SCM_CREDS) && \
      (defined(__FreeBSD__)   /* FreeBSD      */ || \
       defined(__DragonFly__) /* DragonFlyBSD */ || \
       defined(__gnu_hurd__)  /* GNU/HURD     */ )
constexpr int credential_message = SCM_CREDS;
typedef cmsgcred cred_t;
constexpr pid_t peer_pid(const cred_t& data) { return data.cmcred_pid; }
constexpr uid_t peer_uid(const cred_t& data) { return data.cmcred_euid; }
constexpr gid_t peer_gid(const cred_t& data) { return data.cmcred_groups[0]; }

# elif defined(SCM_CREDS)
#  error SCM_CREDS macro detected but platform is unrecognized.  Please submit a patch!
# endif

int recv_cred(int socket, proccred_t& cred) noexcept
{
  struct msghdr message;
  union
  {
    char    rawbuffer[CMSG_SPACE(sizeof(cred_t))];
    cmsghdr formatted;
  } cmsg_header;
  std::memset(cmsg_header.rawbuffer, 0, sizeof(cmsg_header.rawbuffer)); // initialize memory

  char data = 0; // dummy data
  struct iovec iov = { &data, sizeof(data) };

  message.msg_iov = &iov;
  message.msg_iovlen = 1;
  message.msg_name = NULL;
  message.msg_namelen = 0;
  message.msg_control = &cmsg_header.formatted;
  message.msg_controllen = sizeof(cmsg_header.rawbuffer);
  message.msg_flags = 0;

  ssize_t nr = posix::recvmsg(socket, &message);
  if(nr == -1)
    return posix::error_response;

  if(CMSG_FIRSTHDR(&message) == &cmsg_header.formatted &&
     cmsg_header.formatted.cmsg_len   <= sizeof(cmsg_header.rawbuffer) &&
     cmsg_header.formatted.cmsg_level == SOL_SOCKET &&
     cmsg_header.formatted.cmsg_type  == credential_message)
  {
    cred_t* data = reinterpret_cast<cred_t*>(CMSG_DATA(&cmsg_header.formatted));
    cred.pid = peer_pid(*data);
    cred.uid = peer_uid(*data);
    cred.gid = peer_gid(*data);
    return posix::success_response;
  }
  return posix::error_response;
}

int send_cred(int socket) noexcept
{
  struct msghdr message;
  union
  {
    char    rawbuffer[CMSG_SPACE(sizeof(cred_t))];
    cmsghdr formatted;
  } cmsg_header;
  std::memset(cmsg_header.rawbuffer, 0, sizeof(cmsg_header.rawbuffer)); // initialize memory

  cmsg_header.formatted.cmsg_len   = CMSG_LEN(sizeof(cred_t));
  cmsg_header.formatted.cmsg_level = SOL_SOCKET;
  cmsg_header.formatted.cmsg_type  = credential_message;

  char data = 0; // dummy data
  struct iovec iov = { &data, sizeof(data) };

  message.msg_iov = &iov;
  message.msg_iovlen = 1;
  message.msg_name = NULL;
  message.msg_namelen = 0;
  message.msg_control = &cmsg_header.formatted;
  message.msg_controllen = sizeof(cmsg_header.rawbuffer);
  message.msg_flags = 0;

  ssize_t nr = posix::sendmsg(socket, &message);
  if(nr == -1)
    return posix::error_response;
  return int(nr);
}

#else

#pragma message("Socket credentials are not supported on this platform.")

int recv_cred(int socket, proccred_t& cred) noexcept
{
  cred.pid = -1;
  cred.uid = -1;
  cred.gid = -1;
  return posix::error(ENOSYS);
}

int send_cred(int) noexcept
{ return posix::error(ENOSYS); }

#endif
<|endoftext|>


<commit_before>#include <ros/ros.h>
#include <ros/console.h>

#include <math.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/image_encodings.h>
#include <sensor_msgs/CameraInfo.h>
#include <std_msgs/Bool.h>
#include <std_msgs/Float32.h>
#include <std_msgs/Int8.h>
#include <std_msgs/UInt16MultiArray.h>
#include <std_msgs/Int32MultiArray.h>

// Customized message
#include <drv_msgs/target_info.h>

#include <stdio.h>

#include "androidlistener.h"
#include "facelistener.h"
#include "targetlistener.h"

using namespace std;
using namespace std_msgs;

/* Global params */
// Feedback
// 0:not working, 1:working, 2:failed, 3:finished with success
string param_vision_feedback = "/comm/param/feedback/vision/overall";
// 0:wandering, 1:searching, 2:tracking
string param_vision_feedback_mode = "/comm/param/feedback/vision/mode";
// 0:no search, 1:found, -1:current not found. -2:around not found
string param_vision_feedback_search = "/comm/param/feedback/vision/search";
// 0:no track, 1:tracking, -1:lost
string param_vision_feedback_track = "/comm/param/feedback/vision/track";
// 0:no grasp, 1:found location, -1:can't find location
string param_vision_feedback_grasp = "/comm/param/feedback/vision/grasp";
// 0:no face recognize, 1:found faces, -1:failed to recognize
string param_vision_feedback_face = "/comm/param/feedback/vision/face";
// vision shared
// true:switch on to execute tasks, false:switch off and run in wander mode
string param_vision_shared_switch = "/comm/param/shared/vision/switch";

bool centralSwitch_ = true; // main switch

// Target properties
bool targetSetTemp_ = false;
string param_target_label = "/vision/target/label";
enum TargetType{t_null, t_onTable, t_onGround, t_onHead, t_onHand};
string targetTypeName[5] = {"in air", "on the table", "on the ground",
                            "on the face", "in the hand"};
int tgtType_ = t_null;
string param_target_type = "/status/target/type";

string param_target_set =   "/comm/param/control/target/is_set";
string param_target_label = "/comm/param/control/target/label";

// Target status control
string targetLabel_ = "";
bool isTargetSet_ = false;

// Target status feedback
bool foundTarget_ = false;

// Publish servo initial position
ros::Publisher servoPub_;
bool servo_initialized_ = false;

// Servo initial angles
int pitchAngle_ = 70;
int yawAngle_ = 90;
// Range of servo angles
int pitch_min_ = 60;
int pitch_max_ = 140;
int yaw_min_ = 0;
int yaw_max_ = 180;
// The rosparam that store pitch and yaw values
string param_servo_pitch = "/status/servo/pitch";
string param_servo_yaw = "/status/servo/yaw";

// Mode control params
enum ModeType{m_wander, m_search, m_track};
int modeType_ = m_wander;
int modeTypeTemp_ = -1;
string modeName[3] = {"wandering", "searching", "tracking"};
string param_running_mode = "/status/running_mode";
ros::Publisher drvPubMode_; // vision system mode publisher

// General infomation publisher
ros::Publisher drvPubInfo_;

void resetStatus()
{
  // Reset global params
  ros::param::set(param_vision_feedback, 0);
  ros::param::set(param_vision_feedback_search, 0);
  ros::param::set(param_vision_feedback_track, 0);
  ros::param::set(param_vision_feedback_grasp, 0);
  ros::param::set(param_vision_feedback_face, 0);

  tgtType_ = t_null;
  targetLabel_ = "";

  isTargetSet_ = false;
  foundTarget_ = false;

  modeType_ = m_wander;

  ros::param::set(param_target_set, false);
  ros::param::set(param_target_label, "");
}

/* This function is used for servo initialization and
 * publishing servo angles received from cellphone
 */
void pubServo(int pitch_angle, int yaw_angle, int power)
{
  std_msgs::UInt16MultiArray array;
  array.data.push_back(pitch_angle);
  array.data.push_back(yaw_angle);
  array.data.push_back(50 * power);
  servoPub_.publish(array);
}

void pubInfo(string info)
{
  ROS_INFO(info.c_str());
  String msg;
  msg.data = info;
  drvPubInfo_.publish(msg);
}

void teleOpCallback(const Int32MultiArrayConstPtr &msg)
{
  int power = 2;
  if (msg->data.empty() || (msg->data[0] == 0 && msg->data[1] == 0))
    return;

  int pitch_temp = pitchAngle_ + msg->data[0];
  if (pitch_temp < pitch_min_ || pitch_temp > pitch_max_)
    return;
  else
    pitchAngle_ = pitch_temp;

  int yaw_temp = yawAngle_ - msg->data[1];
  if (yaw_temp < yaw_min_ || yaw_temp > yaw_max_)
    return;
  else
    yawAngle_ = yaw_temp;

  pubServo(pitchAngle_, yawAngle_, power);
}

void servoCallback(const UInt16MultiArrayConstPtr &msg)
{
  // This callback should always active
  pitchAngle_ = msg->data[0];
  yawAngle_ = msg->data[1];

  ros::param::set(param_servo_pitch, pitchAngle_);
  ros::param::set(param_servo_yaw, yawAngle_);
}

void searchCallback(const Int8ConstPtr &msg)
{
  if (modeType_ == m_search) {
    if (msg->data == -1) {
      pubInfo("Search around didn't get target, continue searching...");
      foundTarget_ = false;
      ros::param::set(param_vision_feedback_search, -2);
      ros::param::set(param_vision_feedback, 2);
    }
    else if (msg->data == 0) {
      pubInfo("Currently didn't find target, continue searching...");
      ros::param::set(param_vision_feedback_search, -1);
      ros::param::set(param_vision_feedback, 1);
      foundTarget_ = false;
    }
    else {
      foundTarget_ = true;
      ros::param::set(param_vision_feedback_search, 1);
      ros::param::set(param_vision_feedback, 1);
    }
  }
}

void trackCallback(const BoolConstPtr &msg)
{
  if (modeType_ == m_track) {
    if (!msg->data) {
      ROS_INFO("Track report: Target lost!");
      foundTarget_ = false;
      ros::param::set(param_vision_feedback_track, -1);
      ros::param::set(param_vision_feedback, 1);
    }
    else {
      ROS_INFO_THROTTLE(7, "Track report: Tracking...");
      foundTarget_ = true;
      ros::param::set(param_vision_feedback_track, 1);
      ros::param::set(param_vision_feedback, 1);
    }
  }
}

void graspCallback(const Int8ConstPtr &msg)
{
  if (modeType_ == m_track) {
    if (!msg->data) {
      ROS_INFO_THROTTLE(3, "Grasp report: Failed.");
      ros::param::set(param_vision_feedback_grasp, -1);
      ros::param::set(param_vision_feedback, 1);
    }
    else if (msg->data == 1) {
      ROS_INFO_THROTTLE(3, "Grasp report: Reaching to the target...");
      ros::param::set(param_vision_feedback_grasp, 1);
      ros::param::set(param_vision_feedback, 1);
    }
    else {
      ROS_INFO("Grasp report: Target in reach.");
      // Reset if grasping has been performed
      resetStatus();
    }
  }
}

void faceRecognizeCallback(const BoolConstPtr &msg)
{
  if (modeType_ == m_wander) {
    if (!msg->data) {
      pubInfo("Face report: Failed.");
      ros::param::set(param_vision_feedback_face, -1);
      ros::param::set(param_vision_feedback, 2);
    }
    else {
      pubInfo("Face report: Successed.");
      ros::param::set(param_vision_feedback_face, 1);
      ros::param::set(param_vision_feedback, 3);
    }
  }
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "drv_brain");

  ros::NodeHandle nh;
  ros::NodeHandle pnh("~");

  pnh.getParam("pitch_min", pitch_min_);
  pnh.getParam("pitch_max", pitch_max_);
  pnh.getParam("yaw_min", yaw_min_);
  pnh.getParam("yaw_max", yaw_max_);

  servoPub_ = nh.advertise<UInt16MultiArray>("servo", 1, true);
  // For publishing mode info
  drvPubMode_ = nh.advertise<String>("/comm/msg/vision/mode", 1);
  drvPubInfo_ = nh.advertise<String>("/comm/msg/vision/info", 1);

  // Don't change the order without reason
  ros::Subscriber sub_servo_ctrl = nh.subscribe<Int32MultiArray>("/joy_teleop/servo", 1, teleOpCallback);
  ros::Subscriber sub_servo = nh.subscribe<UInt16MultiArray>("servo", 1, servoCallback);
  //ros::Subscriber sub_tgt = nh.subscribe<drv_msgs::target_info>("recognize/target", 1, targetCallback);
  ros::Subscriber sub_sh = nh.subscribe<Int8>("status/search/feedback", 1, searchCallback);
  ros::Subscriber sub_tk = nh.subscribe<Bool>("status/track/feedback", 1, trackCallback);
  ros::Subscriber sub_gp = nh.subscribe<Int8>("status/grasp/feedback", 1, graspCallback);
  ros::Subscriber sub_fr = nh.subscribe<Bool>("status/face/feedback", 1, faceRecognizeCallback);

  AndroidListener al;
  FaceListener fl;
  TargetListener tl;

  resetStatus();

  pubInfo("Deep Robot Vision system initialized!");

  while (ros::ok()) {
    // Main on/off control
    if (ros::param::has(param_vision_shared_switch)) {
      bool temp = true;
      ros::param::get(param_vision_shared_switch, temp);
      if (temp)
        ROS_WARN_COND(!centralSwitch_, "Central switch is ON.");
      centralSwitch_ = temp;
    }

    if (!centralSwitch_) {
      ROS_WARN_THROTTLE(9, "Central switch is OFF.");
      resetStatus();
      continue;
    }

    // Initialize servo position
    if (!servo_initialized_) {
      pubServo(90, 90, 1);
      servo_initialized_ = true;
      ROS_INFO("Servo initialized.");
    }

    // Get feedback to determine whether target were found
    ros::spinOnce();

    // Get target label if the params were set
    tl.getTargetStatus(isTargetSet_, targetLabel_);
    ros::param::set(param_target_label, targetLabel_);

    if (isTargetSet_ != targetSetTemp_) {
      if (isTargetSet_)
        pubInfo("Target set to be '" + targetLabel_ + "'.");
      else {
        pubInfo("Target cancelled.");
        resetStatus();
      }
      targetSetTemp_ = isTargetSet_;
    }

    // If user selects target on cellphone, publish the target
    al.publishOnceIfTargetSelected(isTargetSet_, foundTarget_);

    // Mode selection, notice that modeType_ should only be set by central control
    if (isTargetSet_) {
      if (foundTarget_) {
        // No matter whether the target is searched or selected by user,
        // as long as it was found, track it.
        modeType_ = m_track;
      }
      else {
        if (targetLabel_ == "user selected object") {
          // If the target is selected by user but no more been found,
          // which means tracking has lost it, reset.
          resetStatus();
        }
        else
          modeType_ = m_search;
      }
    }
    else {
      modeType_ = m_wander;
      fl.isNeedRecognizeFace(); // Only recognize face in wander mode
    }

    // Set running mode
    ros::param::set(param_running_mode, modeType_);

    if (modeType_ != modeTypeTemp_) {
      String mode_msg;
      mode_msg.data = modeName[modeType_];
      drvPubMode_.publish(mode_msg);
      ROS_INFO("Current mode: %s.", modeName[modeType_].c_str());
      modeTypeTemp_ = modeType_;
    }
  }

  return 0;
}

<commit_msg>Bug fix<commit_after>#include <ros/ros.h>
#include <ros/console.h>

#include <math.h>
#include <sensor_msgs/Image.h>
#include <sensor_msgs/image_encodings.h>
#include <sensor_msgs/CameraInfo.h>
#include <std_msgs/Bool.h>
#include <std_msgs/Float32.h>
#include <std_msgs/Int8.h>
#include <std_msgs/UInt16MultiArray.h>
#include <std_msgs/Int32MultiArray.h>

// Customized message
#include <drv_msgs/target_info.h>

#include <stdio.h>

#include "androidlistener.h"
#include "facelistener.h"
#include "targetlistener.h"

using namespace std;
using namespace std_msgs;

/* Global params */
// Feedback
// 0:not working, 1:working, 2:failed, 3:finished with success
string param_vision_feedback = "/comm/param/feedback/vision/overall";
// 0:wandering, 1:searching, 2:tracking
string param_vision_feedback_mode = "/comm/param/feedback/vision/mode";
// 0:no search, 1:found, -1:current not found. -2:around not found
string param_vision_feedback_search = "/comm/param/feedback/vision/search";
// 0:no track, 1:tracking, -1:lost
string param_vision_feedback_track = "/comm/param/feedback/vision/track";
// 0:no grasp, 1:found location, -1:can't find location
string param_vision_feedback_grasp = "/comm/param/feedback/vision/grasp";
// 0:no face recognize, 1:found faces, -1:failed to recognize
string param_vision_feedback_face = "/comm/param/feedback/vision/face";
// vision shared
// true:switch on to execute tasks, false:switch off and run in wander mode
string param_vision_shared_switch = "/comm/param/shared/vision/switch";

bool centralSwitch_ = true; // main switch

// Target properties
bool targetSetTemp_ = false;
string param_target_label = "/vision/target/label";
enum TargetType{t_null, t_onTable, t_onGround, t_onHead, t_onHand};
string targetTypeName[5] = {"in air", "on the table", "on the ground",
                            "on the face", "in the hand"};
int tgtType_ = t_null;
string param_target_type = "/status/target/type";

string param_comm_target_set =   "/comm/param/control/target/is_set";
string param_comm_target_label = "/comm/param/control/target/label";

// Target status control
string targetLabel_ = "";
bool isTargetSet_ = false;

// Target status feedback
bool foundTarget_ = false;

// Publish servo initial position
ros::Publisher servoPub_;
bool servo_initialized_ = false;

// Servo initial angles
int pitchAngle_ = 70;
int yawAngle_ = 90;
// Range of servo angles
int pitch_min_ = 60;
int pitch_max_ = 140;
int yaw_min_ = 0;
int yaw_max_ = 180;
// The rosparam that store pitch and yaw values
string param_servo_pitch = "/status/servo/pitch";
string param_servo_yaw = "/status/servo/yaw";

// Mode control params
enum ModeType{m_wander, m_search, m_track};
int modeType_ = m_wander;
int modeTypeTemp_ = -1;
string modeName[3] = {"wandering", "searching", "tracking"};
string param_running_mode = "/status/running_mode";
ros::Publisher drvPubMode_; // vision system mode publisher

// General infomation publisher
ros::Publisher drvPubInfo_;

void resetStatus()
{
  // Reset global params
  ros::param::set(param_vision_feedback, 0);
  ros::param::set(param_vision_feedback_search, 0);
  ros::param::set(param_vision_feedback_track, 0);
  ros::param::set(param_vision_feedback_grasp, 0);
  ros::param::set(param_vision_feedback_face, 0);

  tgtType_ = t_null;
  targetLabel_ = "";

  isTargetSet_ = false;
  foundTarget_ = false;

  modeType_ = m_wander;

  ros::param::set(param_comm_target_set, false);
  ros::param::set(param_comm_target_label, "");
}

/* This function is used for servo initialization and
 * publishing servo angles received from cellphone
 */
void pubServo(int pitch_angle, int yaw_angle, int power)
{
  std_msgs::UInt16MultiArray array;
  array.data.push_back(pitch_angle);
  array.data.push_back(yaw_angle);
  array.data.push_back(50 * power);
  servoPub_.publish(array);
}

void pubInfo(string info)
{
  ROS_INFO(info.c_str());
  String msg;
  msg.data = info;
  drvPubInfo_.publish(msg);
}

void teleOpCallback(const Int32MultiArrayConstPtr &msg)
{
  int power = 2;
  if (msg->data.empty() || (msg->data[0] == 0 && msg->data[1] == 0))
    return;

  int pitch_temp = pitchAngle_ + msg->data[0];
  if (pitch_temp < pitch_min_ || pitch_temp > pitch_max_)
    return;
  else
    pitchAngle_ = pitch_temp;

  int yaw_temp = yawAngle_ - msg->data[1];
  if (yaw_temp < yaw_min_ || yaw_temp > yaw_max_)
    return;
  else
    yawAngle_ = yaw_temp;

  pubServo(pitchAngle_, yawAngle_, power);
}

void servoCallback(const UInt16MultiArrayConstPtr &msg)
{
  // This callback should always active
  pitchAngle_ = msg->data[0];
  yawAngle_ = msg->data[1];

  ros::param::set(param_servo_pitch, pitchAngle_);
  ros::param::set(param_servo_yaw, yawAngle_);
}

void searchCallback(const Int8ConstPtr &msg)
{
  if (modeType_ == m_search) {
    if (msg->data == -1) {
      pubInfo("Search around didn't get target, continue searching...");
      foundTarget_ = false;
      ros::param::set(param_vision_feedback_search, -2);
      ros::param::set(param_vision_feedback, 2);
    }
    else if (msg->data == 0) {
      pubInfo("Currently didn't find target, continue searching...");
      ros::param::set(param_vision_feedback_search, -1);
      ros::param::set(param_vision_feedback, 1);
      foundTarget_ = false;
    }
    else {
      foundTarget_ = true;
      ros::param::set(param_vision_feedback_search, 1);
      ros::param::set(param_vision_feedback, 1);
    }
  }
}

void trackCallback(const BoolConstPtr &msg)
{
  if (modeType_ == m_track) {
    if (!msg->data) {
      ROS_INFO("Track report: Target lost!");
      foundTarget_ = false;
      ros::param::set(param_vision_feedback_track, -1);
      ros::param::set(param_vision_feedback, 1);
    }
    else {
      ROS_INFO_THROTTLE(7, "Track report: Tracking...");
      foundTarget_ = true;
      ros::param::set(param_vision_feedback_track, 1);
      ros::param::set(param_vision_feedback, 1);
    }
  }
}

void graspCallback(const Int8ConstPtr &msg)
{
  if (modeType_ == m_track) {
    if (!msg->data) {
      ROS_INFO_THROTTLE(3, "Grasp report: Failed.");
      ros::param::set(param_vision_feedback_grasp, -1);
      ros::param::set(param_vision_feedback, 1);
    }
    else if (msg->data == 1) {
      ROS_INFO_THROTTLE(3, "Grasp report: Reaching to the target...");
      ros::param::set(param_vision_feedback_grasp, 1);
      ros::param::set(param_vision_feedback, 1);
    }
    else {
      ROS_INFO("Grasp report: Target in reach.");
      // Reset if grasping has been performed
      resetStatus();
    }
  }
}

void faceRecognizeCallback(const BoolConstPtr &msg)
{
  if (modeType_ == m_wander) {
    if (!msg->data) {
      pubInfo("Face report: Failed.");
      ros::param::set(param_vision_feedback_face, -1);
      ros::param::set(param_vision_feedback, 2);
    }
    else {
      pubInfo("Face report: Successed.");
      ros::param::set(param_vision_feedback_face, 1);
      ros::param::set(param_vision_feedback, 3);
    }
  }
}

int main(int argc, char **argv)
{
  ros::init(argc, argv, "drv_brain");

  ros::NodeHandle nh;
  ros::NodeHandle pnh("~");

  pnh.getParam("pitch_min", pitch_min_);
  pnh.getParam("pitch_max", pitch_max_);
  pnh.getParam("yaw_min", yaw_min_);
  pnh.getParam("yaw_max", yaw_max_);

  servoPub_ = nh.advertise<UInt16MultiArray>("servo", 1, true);
  // For publishing mode info
  drvPubMode_ = nh.advertise<String>("/comm/msg/vision/mode", 1);
  drvPubInfo_ = nh.advertise<String>("/comm/msg/vision/info", 1);

  // Don't change the order without reason
  ros::Subscriber sub_servo_ctrl = nh.subscribe<Int32MultiArray>("/joy_teleop/servo", 1, teleOpCallback);
  ros::Subscriber sub_servo = nh.subscribe<UInt16MultiArray>("servo", 1, servoCallback);
  //ros::Subscriber sub_tgt = nh.subscribe<drv_msgs::target_info>("recognize/target", 1, targetCallback);
  ros::Subscriber sub_sh = nh.subscribe<Int8>("status/search/feedback", 1, searchCallback);
  ros::Subscriber sub_tk = nh.subscribe<Bool>("status/track/feedback", 1, trackCallback);
  ros::Subscriber sub_gp = nh.subscribe<Int8>("status/grasp/feedback", 1, graspCallback);
  ros::Subscriber sub_fr = nh.subscribe<Bool>("status/face/feedback", 1, faceRecognizeCallback);

  AndroidListener al;
  FaceListener fl;
  TargetListener tl;

  resetStatus();

  pubInfo("Deep Robot Vision system initialized!");

  while (ros::ok()) {
    // Main on/off control
    if (ros::param::has(param_vision_shared_switch)) {
      bool temp = true;
      ros::param::get(param_vision_shared_switch, temp);
      if (temp)
        ROS_WARN_COND(!centralSwitch_, "Central switch is ON.");
      centralSwitch_ = temp;
    }

    if (!centralSwitch_) {
      ROS_WARN_THROTTLE(9, "Central switch is OFF.");
      resetStatus();
      continue;
    }

    // Initialize servo position
    if (!servo_initialized_) {
      pubServo(90, 90, 1);
      servo_initialized_ = true;
      ROS_INFO("Servo initialized.");
    }

    // Get feedback to determine whether target were found
    ros::spinOnce();

    // Get target label if the params were set
    tl.getTargetStatus(isTargetSet_, targetLabel_);
    ros::param::set(param_target_label, targetLabel_);

    if (isTargetSet_ != targetSetTemp_) {
      if (isTargetSet_)
        pubInfo("Target set to be '" + targetLabel_ + "'.");
      else {
        pubInfo("Target cancelled.");
        resetStatus();
      }
      targetSetTemp_ = isTargetSet_;
    }

    // If user selects target on cellphone, publish the target
    al.publishOnceIfTargetSelected(isTargetSet_, foundTarget_);

    // Mode selection, notice that modeType_ should only be set by central control
    if (isTargetSet_) {
      if (foundTarget_) {
        // No matter whether the target is searched or selected by user,
        // as long as it was found, track it.
        modeType_ = m_track;
      }
      else {
        if (targetLabel_ == "user selected object") {
          // If the target is selected by user but no more been found,
          // which means tracking has lost it, reset.
          resetStatus();
        }
        else
          modeType_ = m_search;
      }
    }
    else {
      modeType_ = m_wander;
      fl.isNeedRecognizeFace(); // Only recognize face in wander mode
    }

    // Set running mode
    ros::param::set(param_running_mode, modeType_);

    if (modeType_ != modeTypeTemp_) {
      String mode_msg;
      mode_msg.data = modeName[modeType_];
      drvPubMode_.publish(mode_msg);
      ROS_INFO("Current mode: %s.", modeName[modeType_].c_str());
      modeTypeTemp_ = modeType_;
    }
  }

  return 0;
}

<|endoftext|>