RpcStringBinding.cpp
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:10k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* RpcStringBinding.cpp - A DCE/RPC endpoints symbolic address */
  2. /* Copyright (c) 1999 Wind River Systems, Inc. */
  3. /*
  4. modification history
  5. --------------------
  6. 01l,03jan02,nel  Remove OLE2T.
  7. 01k,17dec01,nel  Add include symbol for diab build.
  8. 01j,13jul01,dbs  fix up includes
  9. 01i,13mar01,nel  SPR#35873 - add extra method to check to see if an address
  10.                  string can be resolved.
  11. 01h,21jul99,aim  fix compiler warnings
  12. 01g,21jul99,aim  all ctors use initialiseFromString
  13. 01f,16jul99,aim  fix initialiseFromString
  14. 01e,15jul99,dbs  fix return-value check of gethostname
  15. 01d,15jul99,dbs  add isLocalhost() method
  16. 01c,08jul99,dbs  add equality operator
  17. 01b,07jul99,aim  added strdup; apparently it doesn't exist on the target??
  18. 01a,06jul99,aim  created
  19. */
  20. #include <stdio.h>
  21. #include "RpcStringBinding.h"
  22. #include "private/comMisc.h"
  23. #include "INETSockAddr.h"
  24. /* Include symbol for diab */
  25. extern "C" int include_vxdcom_RpcStringBinding (void)
  26.     {
  27.     return 0;
  28.     }
  29. RpcStringBinding::RpcStringBinding ()
  30.   : m_ipAddress (0),
  31.     m_portNumber (-1),
  32.     m_protocolSeq (0),
  33.     m_strFormat (0),
  34.     m_strFormatNoPortNumber (0)
  35.     {
  36.     }
  37. RpcStringBinding::RpcStringBinding
  38.     (
  39.     DUALSTRINGARRAY*    pdsa,
  40.     int portNumber
  41.     )
  42.   : m_ipAddress (0),
  43.     m_portNumber (portNumber),
  44.     m_protocolSeq (0),
  45.     m_strFormat (0),
  46.     m_strFormatNoPortNumber (0)
  47.     {
  48.     // Check the DUALSTRINGARRAY entries, to find one which can be
  49.     // 'resolved' into an IP address on this machine. Win2K sometimes
  50.     // provides hostnames as well as the IP numbers that NT usually
  51.     // sends, so we need to scan the array to find an IP number...
  52.     OLECHAR* pStart = pdsa->aStringArray;
  53.     OLECHAR* pCurr = pStart;
  54.     
  55.     while ((pCurr - pStart) < pdsa->wNumEntries)
  56.         {
  57.         // Make a string-binding out of the DSA entry...
  58. char * pStr = new char [comWideStrLen (pCurr + 1) + 1];
  59. comWideToAscii (pStr, pCurr + 1, comWideStrLen (pCurr + 1) + 1);
  60.         initialiseFromString (pStr);
  61. delete []pStr;
  62.         m_protocolSeq  = *pCurr;
  63.         // See if it can be 'resolved' into a viable IP number...
  64.         if (! resolve ())
  65.             {
  66.             S_ERR (LOG_DCOM, "Could not resolve " << ipAddress ());
  67.             // Free up the allocated strings.
  68.             delString (m_ipAddress);
  69.             delString (m_strFormat);
  70.             delString (m_strFormatNoPortNumber);
  71.             // Could not make sense of the address, so move on through
  72.             // the array to the next entry, or the end of the array...
  73.             while (((pCurr - pStart) < pdsa->wNumEntries) && (*pCurr))
  74.                 ++pCurr;
  75.             ++pCurr;
  76.             }
  77.         else
  78.             {
  79.             S_INFO (LOG_DCOM, "Resolved " << ipAddress ());
  80.             // Take the first one that is viable...
  81.             break;
  82.             }
  83.         }
  84.     // at this point the string binding may have worked or not so the calling
  85.     // routine must make a call to resolve to determine if a valid address was
  86.     // bound since the constructor can't /init
  87.     }
  88. RpcStringBinding::RpcStringBinding
  89.     (
  90.     const char* binding,
  91.     PROTSEQ protocolSeq
  92.     )
  93.   : m_ipAddress (0),
  94.     m_portNumber (-1),
  95.     m_protocolSeq (protocolSeq),
  96.     m_strFormat (0),
  97.     m_strFormatNoPortNumber (0)
  98.     {
  99.     initialiseFromString (binding);
  100.     }
  101. RpcStringBinding::RpcStringBinding
  102.     (
  103.     const OLECHAR* binding,
  104.     PROTSEQ protocolSeq
  105.     )
  106.   : m_ipAddress (0),
  107.     m_portNumber (-1),
  108.     m_protocolSeq (protocolSeq),
  109.     m_strFormat (0),
  110.     m_strFormatNoPortNumber (0)
  111.     {
  112.     char * pStr = new char [comWideStrLen (binding) + 1];
  113.     comWideToAscii (pStr, binding, comWideStrLen (binding) + 1);
  114.     initialiseFromString (pStr);
  115.     delete []pStr;
  116.     }
  117. RpcStringBinding::RpcStringBinding
  118.     (
  119.     const char* binding,
  120.     PROTSEQ protocolSeq,
  121.     int portNumber
  122.     )
  123.   : m_ipAddress (0),
  124.     m_portNumber (portNumber),
  125.     m_protocolSeq (protocolSeq),
  126.     m_strFormat (0),
  127.     m_strFormatNoPortNumber (0)
  128.     {
  129.     initialiseFromString (binding);
  130.     }
  131. RpcStringBinding::RpcStringBinding
  132.     (
  133.     const OLECHAR* binding, 
  134.     PROTSEQ protocolSeq,
  135.     int portNumber
  136.     )
  137.   : m_ipAddress (0),
  138.     m_portNumber (portNumber),
  139.     m_protocolSeq (protocolSeq),
  140.     m_strFormat (0),
  141.     m_strFormatNoPortNumber (0)
  142.     {
  143.     if (binding)
  144. {
  145. char * pStr = new char [comWideStrLen (binding) + 1];
  146. comWideToAscii (pStr, binding, comWideStrLen (binding) + 1);
  147. initialiseFromString (pStr);
  148. delete []pStr;
  149. }
  150.     }
  151. RpcStringBinding::RpcStringBinding
  152.     (
  153.     const SockAddr& addr,
  154.     PROTSEQ protocolSeq
  155.     )
  156.   : m_ipAddress (0),
  157.     m_portNumber (-1),
  158.     m_protocolSeq (protocolSeq),
  159.     m_strFormat (0),
  160.     m_strFormatNoPortNumber (0)
  161.     {
  162.     char buf [MAXHOSTNAMELEN +1];
  163.     if (addr.hostAddrGet (buf, MAXHOSTNAMELEN) == 0)
  164. {
  165. m_ipAddress = copyString (buf);
  166. m_portNumber = addr.portGet ();
  167. }
  168.     }
  169. RpcStringBinding::~RpcStringBinding ()
  170.     {
  171.     delString (m_ipAddress);
  172.     delString (m_strFormat);
  173.     delString (m_strFormatNoPortNumber);
  174.     }
  175. RpcStringBinding::RpcStringBinding (const RpcStringBinding& other)
  176.   : m_ipAddress (0),
  177.     m_portNumber (-1),
  178.     m_protocolSeq (0),
  179.     m_strFormat (0),
  180.     m_strFormatNoPortNumber (0)
  181.     {
  182.     *this = other;
  183.     }
  184. RpcStringBinding& RpcStringBinding::operator=(const RpcStringBinding& rhs)
  185.     {
  186.     if (this != &rhs)
  187. {
  188. delString (m_ipAddress);
  189. delString (m_strFormat);
  190. delString (m_strFormatNoPortNumber);
  191. m_ipAddress = copyString (rhs.m_ipAddress);
  192. m_portNumber = rhs.m_portNumber;
  193. m_protocolSeq = rhs.m_protocolSeq;
  194. m_strFormat = copyString (rhs.m_strFormat);
  195. m_strFormatNoPortNumber = copyString (rhs.m_strFormatNoPortNumber);
  196. }
  197.     return *this;
  198.     }
  199. int RpcStringBinding::initialiseFromString (const char* binding)
  200.     {
  201.     if (binding == 0)
  202. return -1;
  203.     int len = ::strlen (binding);
  204.     char* sb = ::strchr (binding, '[');
  205.     if (sb) // found opening square bracket
  206. {
  207. // we copy the whole binding and then set the square bracket
  208. // to "NULL".  Cheap and nasty but we are only going to
  209. // waste at most 7 bytes.
  210. m_ipAddress = copyString (binding);
  211. // copy over the opening "["
  212. m_ipAddress[sb - binding] = '';
  213. // convert the portnumber if there is any data left in binding.
  214. if ((1 + (sb - binding)) < len)
  215.     m_portNumber = ::atoi (++sb);
  216. else
  217.     return -1;
  218. }
  219.     else
  220. {
  221. // no square bracket, just copy the address.
  222. m_ipAddress = copyString (binding);
  223. }
  224.     return 0;
  225.     }
  226. const char* RpcStringBinding::ipAddress () const
  227.     {
  228.     return m_ipAddress;
  229.     }
  230. int RpcStringBinding::portNumber () const
  231.     {
  232.     return m_portNumber;
  233.     }
  234. PROTSEQ RpcStringBinding::protocolSequence () const
  235.     {
  236.     return m_protocolSeq;
  237.     }
  238. const char* RpcStringBinding::formatted (bool includePortNumber) const
  239.     {
  240.     char*& p = includePortNumber ? m_strFormat : m_strFormatNoPortNumber;
  241.     if (p == 0 && m_ipAddress != 0)
  242. {
  243. char binding [MAXHOSTNAMELEN]; // XXX
  244. int n = 0;
  245. n = ::sprintf (binding, "%c%s", protocolSequence (), ipAddress ());
  246. if (n && includePortNumber)
  247.     ::sprintf (&binding[n], "[%d]", portNumber ());
  248. p = copyString (binding);
  249. }
  250.     return p;
  251.     }
  252. int RpcStringBinding::format
  253.     (
  254.     BSTR* bstr,
  255.     bool includePortNumber
  256.     ) const
  257.     {
  258.     USES_CONVERSION;
  259.     const char* f = formatted (includePortNumber);
  260.     if (f != 0)
  261. {
  262. OLECHAR * wStr = new OLECHAR [strlen (f) + 1];
  263. comAsciiToWide (wStr, f, strlen (f) + 1);
  264. *bstr = ::SysAllocString (wStr);
  265. delete []wStr;
  266. }
  267.     else
  268. *bstr = 0;
  269.     return *bstr != 0 ? 0 : -1;
  270.     }
  271. bool RpcStringBinding::isLocalhost () const
  272.     {
  273.     INETSockAddr addr (m_ipAddress);
  274.     char hostname [MAXHOSTNAMELEN +1];
  275.     if (::gethostname (hostname, MAXHOSTNAMELEN) < 0)
  276. return false;
  277.     INETSockAddr local (hostname);
  278.     return (local == addr);
  279.     }
  280. //////////////////////////////////////////////////////////////////////////
  281. //
  282. // RpcStringBinding::resolve - does the IP address of this string
  283. // binding resolve
  284. //
  285. bool RpcStringBinding::resolve () const
  286.     {
  287.     // check to see if a valid address is present.
  288.     if (!m_ipAddress)
  289.         return false;
  290.     // Do a very TCP/IP-specific test to see if the ipAddress can be
  291.     // resolved. This needs to be made more protocol-independent in
  292.     // future... 
  293.     // Firstly, check if its a dotted-IP number...
  294.     if (inet_addr (m_ipAddress) == (unsigned long)ERROR)
  295.         {
  296.         // No, so try to resolve the hostname...
  297. #ifndef VXDCOM_PLATFORM_VXWORKS
  298.     hostent* hp = ::gethostbyname (m_ipAddress);
  299.     if (hp == 0)
  300.         return false;
  301. #else
  302.     if (::hostGetByName (const_cast<char*> (m_ipAddress)) == ERROR)
  303.         return false;
  304. #endif
  305.         }
  306.     // Address did resolve...
  307.     return true;
  308.     }
  309. bool RpcStringBinding::operator== (const RpcStringBinding& sb) const
  310.     {
  311.     const char* s1 = formatted ();
  312.     const char* s2 = sb.formatted ();
  313.     if (s1 && s2 && (strcmp (s1, s2) == 0))
  314.         return true;
  315.     if ((s1 == 0) && (s2 == 0))
  316.         return true;
  317.     return false;    
  318.     }
  319. bool RpcStringBinding::operator< (const RpcStringBinding& sb) const
  320.     {
  321.     const char* s1 = formatted ();
  322.     const char* s2 = sb.formatted ();
  323.     if (s1 && s2)
  324.         return (strcmp (s1, s2) < 0);
  325.     
  326.     if (s1 == 0)
  327.         return false;
  328.     
  329.     return true;    
  330.     }
  331. bool RpcStringBinding::isValid () const
  332.     {
  333.     return m_ipAddress != 0 && m_portNumber != -1;
  334.     }
  335. ostream& operator<< (ostream& os, const RpcStringBinding& obj)
  336.     {
  337.     const char* s = obj.formatted ();
  338.     if (s)
  339. os << s;
  340.     return os;
  341.     }
  342. char* RpcStringBinding::copyString (const char* s1) const
  343.     {
  344.     char* s2 = 0;
  345.     if (s1)
  346. {
  347. s2 = reinterpret_cast<char*> (::malloc (::strlen (s1) + 1));
  348. if (s2)
  349.     ::strcpy (s2, s1);
  350. }
  351.     return s2;
  352.     }
  353. void RpcStringBinding::delString (char*& s1)
  354.     {
  355.     if (s1)
  356. ::free (s1);
  357.     
  358.     s1 = 0;
  359.     }