X-Git-Url: https://git.creatis.insa-lyon.fr/pubgit/?a=blobdiff_plain;f=src%2FgdcmUtil.cxx;h=0f121c26635a1f948b7e92ff4a8b3b7c4abc7cee;hb=7e9537ac534af5c5b9c5231c1b7fdd7193c2255d;hp=7f21531e74cacf93953b45957d80eb79804bb26d;hpb=185fd6a2080d72d6984f88693c1618cb09ffcfc7;p=gdcm.git diff --git a/src/gdcmUtil.cxx b/src/gdcmUtil.cxx index 7f21531e..0f121c26 100644 --- a/src/gdcmUtil.cxx +++ b/src/gdcmUtil.cxx @@ -3,8 +3,8 @@ Program: gdcm Module: $RCSfile: gdcmUtil.cxx,v $ Language: C++ - Date: $Date: 2005/01/15 20:24:02 $ - Version: $Revision: 1.92 $ + Date: $Date: 2005/01/17 17:26:55 $ + Version: $Revision: 1.106 $ Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de l'Image). All rights reserved. See Doc/License.txt or @@ -40,43 +40,42 @@ // For GetMACAddress #ifdef _WIN32 -#include -#include + #include + #include #else -#include -#include -#include -#include -//#include -#include -#include -#include -#include + #include + #include + #include + #include +#endif + +// How do I do that in CMake ? +#ifdef __APPLE__ + #define HAVE_SA_LEN +#endif //APPLE + #ifdef CMAKE_HAVE_SYS_IOCTL_H -#include // For SIOCGIFCONF on Linux + #include // For SIOCGIFCONF on Linux #endif #ifdef CMAKE_HAVE_SYS_SOCKET_H -#include + #include #endif #ifdef CMAKE_HAVE_SYS_SOCKIO_H -#include // For SIOCGIFCONF on SunOS + #include // For SIOCGIFCONF on SunOS #endif #ifdef CMAKE_HAVE_NET_IF_H -#include + #include #endif #ifdef CMAKE_HAVE_NETINET_IN_H -#include //For IPPROTO_IP + #include //For IPPROTO_IP #endif #ifdef CMAKE_HAVE_NET_IF_DL_H -#include + #include +#endif +#if defined(CMAKE_HAVE_NET_IF_ARP_H) && defined(__sun) + // This is absolutely necesseray on SunOS + #include #endif - -// How do I do that in CMake ? -#ifdef __APPLE__ -#define HAVE_SA_LEN -#endif //APPLE - -#endif //_WIN32 namespace gdcm { @@ -375,7 +374,7 @@ typedef BOOL(WINAPI * pSnmpExtensionInitEx) ( #endif //_WIN32 -long GetMacAddrSys ( unsigned char *addr) +int GetMacAddrSys ( unsigned char *addr ) { #ifdef _WIN32 WSADATA WinsockData; @@ -435,7 +434,8 @@ long GetMacAddrSys ( unsigned char *addr) ret = m_Query(ASN_RFC1157_GETNEXTREQUEST, &varBindList, &errorStatus, &errorIndex); // printf("# of adapters in this system : %i\n", -// varBind[0].value.asnValue.number); varBindList.len = 2; +// varBind[0].value.asnValue.number); + varBindList.len = 2; // Copy in the OID of ifType, the type of interface SNMP_oidcpy(&varBind[0].name, &MIB_ifEntryType); @@ -464,7 +464,7 @@ long GetMacAddrSys ( unsigned char *addr) { j++; dtmp = varBind[0].value.asnValue.number; - printf("Interface #%i type : %i\n", j, dtmp); + std::cerr << "Interface #" << j << " type : " << dtmp << std::endl; // Type 6 describes ethernet interfaces if (dtmp == 6) @@ -481,7 +481,7 @@ long GetMacAddrSys ( unsigned char *addr) && (varBind[1].value.asnValue.address.stream[4] == 0x00) ) { // Ignore all dial-up networking adapters - printf("Interface #%i is a DUN adapter\n", j); + std::cerr << "Interface #" << j << " is a DUN adapter\n"; continue; } if ( (varBind[1].value.asnValue.address.stream[0] == 0x00) @@ -493,7 +493,7 @@ long GetMacAddrSys ( unsigned char *addr) { // Ignore NULL addresses returned by other network // interfaces - printf("Interface #%i is a NULL address\n", j); + std::cerr << "Interface #" << j << " is a NULL address\n"; continue; } memcpy( addr, varBind[1].value.asnValue.address.stream, 6); @@ -506,8 +506,54 @@ long GetMacAddrSys ( unsigned char *addr) SNMP_FreeVarBind(&varBind[0]); SNMP_FreeVarBind(&varBind[1]); return 0; -#else +#endif //Win32 version + + // implementation for POSIX system +#ifdef __sun + //The POSIX version is broken anyway on Solaris, plus would require full + //root power + int i; + struct arpreq parpreq; + struct sockaddr_in sa, *psa; + struct in_addr inaddr; + struct hostent *phost; + char hostname[MAXHOSTNAMELEN]; + unsigned char *ptr; + char **paddrs; + int sock, status=0; + + if(gethostname(hostname, MAXHOSTNAMELEN) != 0) + { + perror("gethostname"); + return -1; + } + phost = gethostbyname(hostname); + paddrs = phost->h_addr_list; + + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(sock == -1) + { + perror("sock"); + return -1; + } + memset(&parpreq, 0, sizeof(struct arpreq)); + psa = (struct sockaddr_in *) &parpreq.arp_pa; + + memset(psa, 0, sizeof(struct sockaddr_in)); + psa->sin_family = AF_INET; + memcpy(&psa->sin_addr, *paddrs, sizeof(struct in_addr)); + + status = ioctl(sock, SIOCGARP, &parpreq); + if(status == -1) + { + perror("SIOCGARP"); + return -1; + } + memcpy(addr, parpreq.arp_ha.sa_data, 6); + + return 0; +#else #ifdef CMAKE_HAVE_NET_IF_H int sd; struct ifreq ifr, *ifrp; @@ -559,6 +605,11 @@ long GetMacAddrSys ( unsigned char *addr) a = (unsigned char *) &ifr.ifr_hwaddr.sa_data; #else #ifdef SIOCGENADDR + // In theory this call should also work on Sun Solaris, but apparently + // SIOCGENADDR is not implemented properly thus the call + // ioctl(sd, SIOCGENADDR, &ifr) always returns errno=2 + // (No such file or directory) + // Furthermore the DLAPI seems to require full root access if (ioctl(sd, SIOCGENADDR, &ifr) < 0) continue; a = (unsigned char *) ifr.ifr_enaddr; @@ -569,10 +620,7 @@ long GetMacAddrSys ( unsigned char *addr) continue; a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen]; #else - /* - * XXX we don't have a way of getting the hardware - * address - */ + perror("No way to access hardware"); close(sd); return -1; #endif // AF_LINK @@ -589,35 +637,37 @@ long GetMacAddrSys ( unsigned char *addr) } close(sd); #endif + /* Not implemented platforms */ + perror("There was a configuration problem on your plateform"); + memset(addr,0,6); return -1; -#endif //_WIN32 - +#endif //__sun } std::string Util::GetMACAddress() { - // This is a rip from: http://cplus.kompf.de/macaddr.html for Linux/CYGWIN, HPUX and AIX - // and http://tangentsoft.net/wskfaq/examples/src/snmpmac.cpp for windows version - // and http://groups-beta.google.com/group/sol.lists.freebsd.hackers/msg/0d0f862e05fce6c0 for the FreeBSD version - // and http://developer.apple.com/samplecode/GetPrimaryMACAddress/GetPrimaryMACAddress.html for MacOSX version - u_char addr[6]; + // This code is the result of a long internet search to find something + // as compact as possible (not OS independant). We only have to separate + // 3 OS: Win32, SunOS and 'real' POSIX + // http://groups-beta.google.com/group/comp.unix.solaris/msg/ad36929d783d63be + // http://bdn.borland.com/article/0,1410,26040,00.html + unsigned char addr[6]; std::string macaddr; - long stat = GetMacAddrSys(addr); + int stat = GetMacAddrSys(addr); if (0 == stat) { - //printf( "MAC address = "); for (int i=0; i<6; ++i) { - //printf("%2.2x", addr[i]); macaddr += Format("%2.2x", addr[i]); + //if(i) macaddr += "."; + //macaddr += Format("%i", (int)addr[i]); } - //printf( "\n"); return macaddr; } else { - //printf( "No MAC address !\n" ); + gdcmVerboseMacro("Problem in finding the MAC Address"); return ""; } } @@ -628,60 +678,60 @@ std::string Util::GetMACAddress() */ std::string Util::GetIPAddress() { - // This is a rip from - // http://www.codeguru.com/Cpp/I-N/internet/network/article.php/c3445/ + // This is a rip from + // http://www.codeguru.com/Cpp/I-N/internet/network/article.php/c3445/ #ifndef HOST_NAME_MAX - // SUSv2 guarantees that `Host names are limited to 255 bytes'. - // POSIX 1003.1-2001 guarantees that `Host names (not including the - // terminating NUL) are limited to HOST_NAME_MAX bytes'. + // SUSv2 guarantees that `Host names are limited to 255 bytes'. + // POSIX 1003.1-2001 guarantees that `Host names (not including the + // terminating NUL) are limited to HOST_NAME_MAX bytes'. # define HOST_NAME_MAX 255 - // In this case we should maybe check the string was not truncated. - // But I don't known how to check that... + // In this case we should maybe check the string was not truncated. + // But I don't known how to check that... #if defined(_MSC_VER) || defined(__BORLANDC__) - // with WinSock DLL we need to initialise the WinSock before using gethostname - WORD wVersionRequested = MAKEWORD(1,0); - WSADATA WSAData; - int err = WSAStartup(wVersionRequested,&WSAData); - if (err != 0) - { + // with WinSock DLL we need to initialise the WinSock before using gethostname + WORD wVersionRequested = MAKEWORD(1,0); + WSADATA WSAData; + int err = WSAStartup(wVersionRequested,&WSAData); + if (err != 0) + { // Tell the user that we could not find a usable // WinSock DLL. WSACleanup(); return "127.0.0.1"; - } + } #endif #endif //HOST_NAME_MAX - std::string str; - char szHostName[HOST_NAME_MAX+1]; - int r = gethostname(szHostName, HOST_NAME_MAX); - - if( r == 0 ) - { - // Get host adresses - struct hostent *pHost = gethostbyname(szHostName); - - for( int i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ ) - { - for( int j = 0; jh_length; j++ ) + std::string str; + char szHostName[HOST_NAME_MAX+1]; + int r = gethostname(szHostName, HOST_NAME_MAX); + + if( r == 0 ) + { + // Get host adresses + struct hostent *pHost = gethostbyname(szHostName); + + for( int i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ ) { - if( j > 0 ) str += "."; - - str += Util::Format("%u", - (unsigned int)((unsigned char*)pHost->h_addr_list[i])[j]); - } - // str now contains one local IP address - + for( int j = 0; jh_length; j++ ) + { + if( j > 0 ) str += "."; + + str += Util::Format("%u", + (unsigned int)((unsigned char*)pHost->h_addr_list[i])[j]); + } + // str now contains one local IP address + #if defined(_MSC_VER) || defined(__BORLANDC__) - WSACleanup(); + WSACleanup(); #endif - - } - } - // If an error occur r == -1 - // Most of the time it will return 127.0.0.1... - return str; + + } + } + // If an error occur r == -1 + // Most of the time it will return 127.0.0.1... + return str; } /** @@ -692,66 +742,62 @@ std::string Util::GetIPAddress() */ std::string Util::CreateUniqueUID(const std::string &root) { - // The code works as follow: - // echo "gdcm" | od -b - // 0000000 147 144 143 155 012 - // Therefore we return - // radical + 147.144.143.155 + IP + time() - std::string radical = root; - if( !root.size() ) //anything better ? - { - radical = "0.0."; // Is this really usefull ? - } - // else - // A root was specified use it to forge our new UID: - radical += "147.144.143.155"; // gdcm - radical += "."; - radical += Util::GetIPAddress(); - radical += "."; - radical += Util::GetCurrentDate(); - radical += "."; - radical += Util::GetCurrentTime(); - - return radical; + std::string radical = root; + if( !root.size() ) + { + // No root was specified use "GDCM" then + // echo "gdcm" | od -b + // 0000000 147 144 143 155 012 + radical = "147.144.143.155"; // special easter egg + } + // else + // A root was specified use it to forge our new UID: + radical += Util::GetMACAddress(); + radical += "."; + radical += Util::GetCurrentDate(); + radical += "."; + radical += Util::GetCurrentTime(); + + return radical; } template std::ostream &binary_write(std::ostream &os, const T &val) { - return os.write(reinterpret_cast(&val), sizeof val); + return os.write(reinterpret_cast(&val), sizeof val); } std::ostream &binary_write(std::ostream &os, const uint16_t &val) { #ifdef GDCM_WORDS_BIGENDIAN - uint16_t swap; - swap = ((( val << 8 ) & 0x0ff00 ) | (( val >> 8 ) & 0x00ff ) ); - return os.write(reinterpret_cast(&swap), 2); + uint16_t swap; + swap = ((( val << 8 ) & 0x0ff00 ) | (( val >> 8 ) & 0x00ff ) ); + return os.write(reinterpret_cast(&swap), 2); #else - return os.write(reinterpret_cast(&val), 2); + return os.write(reinterpret_cast(&val), 2); #endif //GDCM_WORDS_BIGENDIAN } std::ostream &binary_write(std::ostream &os, const uint32_t &val) { #ifdef GDCM_WORDS_BIGENDIAN - uint32_t swap; - swap = ( ((val<<24) & 0xff000000) | ((val<<8) & 0x00ff0000) | - ((val>>8) & 0x0000ff00) | ((val>>24) & 0x000000ff) ); - return os.write(reinterpret_cast(&swap), 4); + uint32_t swap; + swap = ( ((val<<24) & 0xff000000) | ((val<<8) & 0x00ff0000) | + ((val>>8) & 0x0000ff00) | ((val>>24) & 0x000000ff) ); + return os.write(reinterpret_cast(&swap), 4); #else - return os.write(reinterpret_cast(&val), 4); + return os.write(reinterpret_cast(&val), 4); #endif //GDCM_WORDS_BIGENDIAN } std::ostream &binary_write(std::ostream &os, const char *val) { - return os.write(val, strlen(val)); + return os.write(val, strlen(val)); } std::ostream &binary_write(std::ostream &os, std::string const &val) { - return os.write(val.c_str(), val.size()); + return os.write(val.c_str(), val.size()); } } // end namespace gdcm