// Networking.cpp //#include #if defined(_WIN32) || defined(_WIN64) // C4290 - the compiler ignores exception specifications #pragma warning(disable: 4290) #define WIN32_LEAN_AND_MEAN #include #include #include "SystemError.hpp" #elif defined(__unix) || defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) #include #include #include #endif #include #include #include #include #include #include "ErrorHandling.hpp" #include "cipres-jni.h" #define MAX_HOSTNAME_LENGTH 255 namespace Cipres { namespace JNI { // GetFullName static char *GetFullName() throw(std::bad_alloc, std::runtime_error) { boost::scoped_array host_name(new char[MAX_HOSTNAME_LENGTH + 1]); ::gethostname(host_name.get(), MAX_HOSTNAME_LENGTH); // gethostname only consults local files, but gethostbyname will use // the network for name resolution hostent *host_info = ::gethostbyname(host_name.get()); if(host_info == NULL) { #if defined(_WIN32) || defined(_WIN64) throw SystemError("GetFullName", "gethostbyname", ::WSAGetLastError()); #elif defined(__unix) || defined(__unix__) || (defined(__APPLE__) && defined(__MACH__)) std::string message("GetFullName: gethostbyname: "); message.append(::hstrerror(h_errno)); throw std::runtime_error(message); #endif } assert(host_info->h_name); size_t name_length = std::strlen(host_info->h_name) + 1; char *full_name = new char[name_length]; std::memcpy(full_name, host_info->h_name, name_length); return full_name; } } // namespace JNI } // namespace Cipres using namespace Cipres::JNI; // public interface // Java_org_cipres_jni_Networking_getLocalHostName JNIEXPORT jstring JNICALL Java_org_cipres_jni_Networking_getLocalHostName(JNIEnv *env, jclass obj) { try { boost::scoped_array host_name(new char[MAX_HOSTNAME_LENGTH + 1]); ::gethostname(host_name.get(), MAX_HOSTNAME_LENGTH); return env->NewStringUTF(host_name.get()); } catch(const std::bad_alloc &) { ThrowOutOfMemError(env); return NULL; } } // Java_org_cipres_jni_Networking_getShortHostName JNIEXPORT jstring JNICALL Java_org_cipres_jni_Networking_getShortHostName(JNIEnv *env, jclass obj) { try { boost::scoped_array full_name(GetFullName()); // the first segment of the host name is used as the short name char *dot_char = std::strchr(full_name.get(), '.'); if(dot_char != NULL) *dot_char = '\0'; return env->NewStringUTF(full_name.get()); } catch(const std::runtime_error &run_err) { ThrowError(env, JAVA_CLASS_RUNTIME_EXCEPT, run_err.what()); return NULL; } catch(const std::bad_alloc &) { ThrowOutOfMemError(env); return NULL; } } // Java_org_cipres_jni_Networking_getFullHostName JNIEXPORT jstring JNICALL Java_org_cipres_jni_Networking_getFullHostName(JNIEnv *env, jclass obj) { try { boost::scoped_array full_name(GetFullName()); return env->NewStringUTF(full_name.get()); } catch(const std::runtime_error &run_err) { ThrowError(env, JAVA_CLASS_RUNTIME_EXCEPT, run_err.what()); return NULL; } catch(const std::bad_alloc &) { ThrowOutOfMemError(env); return NULL; } }