static size_t pantheios_getHostName_body_(pan_char_t* buffer, size_t cchBuffer) { #if defined(PLATFORMSTL_OS_IS_UNIX) if(0 == cchBuffer) { errno = ENAMETOOLONG; return 0; } else { int res; PANTHEIOS_CONTRACT_ENFORCE_ASSUMPTION(NULL != buffer); /* First, we mark the last available character in the buffer with * the nul terminator, to test later */ buffer[cchBuffer - 1] = '\0'; errno = 0; res = gethostname(&buffer[0], cchBuffer); /* Test for ENAMETOOLONG, to avoid any implementation-dependent * behaviour wrt whether this it is set on a 0 or a -1 return */ if(ENAMETOOLONG == errno) { /* To homogenise platform behaviour, we ensure that no fragment is filled out */ buffer[0] = '\0'; return cchBuffer; } else { if(0 != res) { /* Was a failure, so return 0 */ return 0; } else if('\0' != buffer[cchBuffer - 1]) { /* Was insufficient buffer, so we return the given size (which is the * failure indicator for that condition * * Also, to homogenise platform behaviour, we ensure that no fragment * of the buffer is returned as filled out. */ buffer[0] = '\0'; return cchBuffer; } else { /* Buffer was sufficient, and the value has been written. The only * way to return the length is to do strlen on it */ return pan_strlen_(buffer); } } } #elif defined(PLATFORMSTL_OS_IS_WINDOWS) DWORD cchSize = stlsoft_static_cast(DWORD, cchBuffer); if(!pan_GetComputerName_(&buffer[0], &cchSize)) { DWORD err = GetLastError(); if(ERROR_BUFFER_OVERFLOW == err) { return cchBuffer; } else { return 0; } } else { return cchSize; } #else /* ? PLATFORMSTL_OS_IS_???? */ # error Platform not discriminated #endif /* PLATFORMSTL_OS_IS_???? */ }
static int pantheios_be_WindowsSyslog_init_a_( char const* processIdentity , int id , pan_be_WindowsSyslog_init_t const* init , void* reserved , void** ptoken ) { WindowsSysLog_Context* ctxt = static_cast<WindowsSysLog_Context*>(::calloc(1, sizeof(WindowsSysLog_Context))); PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(NULL != processIdentity, "process identity may not be the null string"); PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API('\0' != 0[processIdentity], "process identity may not be the empty string"); STLSOFT_SUPPRESS_UNUSED(reserved); PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(NULL != ptoken, "token pointer may not be null"); *ptoken = NULL; if(NULL == ctxt) { return PANTHEIOS_INIT_RC_OUT_OF_MEMORY; } else if(NULL != ::strpbrk(processIdentity, " \t\r\n\b\v")) { return PANTHEIOS_BE_INIT_RC_INVALID_PROCESSID; } else { WSADATA wsadata; pan_be_WindowsSyslog_init_t init_; struct sockaddr_in addr_in; const unsigned long ADDR_BROADCAST = INADDR_BROADCAST; BOOL bBroadcast = TRUE; if(0 != ::WSAStartup(0x0202, &wsadata)) { goto error_startup; } /* (i) apply Null Object (Variable) pattern */ if(NULL == init) { pantheios_be_WindowsSyslog_getDefaultAppInit(&init_); #ifdef PANTHEIOS_BE_USE_CALLBACK pantheios_be_WindowsSyslog_getAppInit(id, &init_); #endif /* PANTHEIOS_BE_USE_CALLBACK */ init = &init_; } ctxt->id = id; ctxt->flags = init->flags; memset(&addr_in, 0, sizeof(addr_in)); if( 0 == init->addrSize && NULL != init->hostName) { unsigned long addr = ::inet_addr(init->hostName); struct hostent* he; if( INADDR_BROADCAST == addr && 0 != ::strcmp(init->hostName, "255.255.255.255") && NULL != (he = ::gethostbyname(init->hostName))) { memcpy(&addr_in.sin_addr, he->h_addr, he->h_length); } else { memcpy(&addr_in.sin_addr, &addr, sizeof(addr)); } } else { switch(init->addrSize) { case 16: default: OutputDebugStringA("Invalid/unsupported address size: currently only 4 (IPv4) is supported\n"); memcpy(&addr_in.sin_addr, &ADDR_BROADCAST, sizeof(ADDR_BROADCAST)); break; case 4: addr_in.sin_addr.S_un.S_un_b.s_b1 = init->bytes[0]; addr_in.sin_addr.S_un.S_un_b.s_b2 = init->bytes[1]; addr_in.sin_addr.S_un.S_un_b.s_b3 = init->bytes[2]; addr_in.sin_addr.S_un.S_un_b.s_b4 = init->bytes[3]; if(addr_in.sin_addr.s_addr != 0xffffffff) { bBroadcast = FALSE; } break; } } addr_in.sin_family = AF_INET; addr_in.sin_port = ::htons(init->port); ctxt->sk = ::socket(AF_INET, SOCK_DGRAM, 0); if(stlsoft_static_cast(SOCKET, SOCKET_ERROR) == ctxt->sk) { goto error_sock; } ctxt->processIdentity = pantheios_util_strdup_nothrow_m(processIdentity); if(NULL == ctxt->processIdentity) { goto error_procId; } ctxt->cchProcessIdentity = ::strlen(ctxt->processIdentity); ctxt->hostIdentity = pan_make_hostIdentity_(); if(NULL == ctxt->hostIdentity) { goto error_hostId; } ctxt->cchHostIdentity = ::strlen(ctxt->hostIdentity); if(bBroadcast) { ::setsockopt(ctxt->sk, SOL_SOCKET, SO_BROADCAST, (char const*)&bBroadcast, sizeof(bBroadcast)); } if(SOCKET_ERROR == ::connect(ctxt->sk, (struct sockaddr const*)&addr_in, sizeof(addr_in))) { goto error_connect; } ctxt->facility = static_cast<unsigned char>(init->facility % 124); // Any more than 124 will overflow priority of <999> *ptoken = ctxt; return PANTHEIOS_INIT_RC_SUCCESS; // NOTE: This goto lark is a vestige of the original C implementation. error_connect: pantheios_util_strfree_m(ctxt->hostIdentity); error_hostId: pantheios_util_strfree_m(ctxt->processIdentity); error_procId: ::closesocket(ctxt->sk); error_sock: ::WSACleanup(); error_startup: ::free(ctxt); return PANTHEIOS_INIT_RC_UNSPECIFIED_FAILURE; } }