/** * @see See header file for interface comments. */ uint16_t *utilinet_getportfromstorage(const struct sockaddr_storage * const addr) { uint16_t *ret = NULL; if (addr == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: parameter validation failed\n", __FUNCTION__); } else { switch (addr->ss_family) { case AF_INET: ret = &(((struct sockaddr_in*)addr)->sin_port); break; case AF_INET6: ret = &(((struct sockaddr_in6*)addr)->sin6_port); break; default: logger_printf(LOGGER_LEVEL_ERROR, "%s: invalid family (%d)\n", __FUNCTION__, addr->ss_family); break; } } return ret; }
/** * @see See header file for interface comments. */ bool utilioctl_gettermsize(uint16_t * const rows, uint16_t * const cols) { int32_t retval = 0; struct winsize win; if ((rows == NULL) || (cols == NULL)) { logger_printf(LOGGER_LEVEL_ERROR, "%s: parameter validation failed\n", __FUNCTION__); } else if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &win) == -1) { logger_printf(LOGGER_LEVEL_ERROR, "%s: ioctl request failed (%d)\n", __FUNCTION__, errno); *rows = 0; *cols = 0; } else { *rows = win.ws_row; *cols = win.ws_col; retval = true; } return retval; }
/** * @see See header file for interface comments. */ int32_t utilioctl_getifmtubyname(char * const name) { int32_t retval = -1, fd = -1; struct ifreq ifr; if (name == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: parameter validation failed\n", __FUNCTION__); } else if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to create socket (%d)\n", __FUNCTION__, errno); } else { memset(&ifr, 0, sizeof(struct ifreq)); ifr.ifr_addr.sa_family = AF_INET; strncpy(ifr.ifr_name, name, IFNAMSIZ-1); if (ioctl(fd, SIOCGIFMTU, &ifr) == 0) { retval = ifr.ifr_mtu; } close(fd); } return retval; }
/** * @see See header file for interface comments. */ int32_t utilioctl_getifmtubyaddr(const struct sockaddr_in * const addr) { int32_t retval = -1; struct ifaddrs *addrs = NULL, *ifa = NULL; struct sockaddr_in *sa = NULL; char buf1[INET6_ADDRSTRLEN], buf2[INET6_ADDRSTRLEN]; if (addr == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: parameter validation failed\n", __FUNCTION__); } else if (getifaddrs(&addrs) == -1) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to get network interface list (%d)\n", __FUNCTION__, errno); } else { for (ifa = addrs; ifa != NULL; ifa = ifa->ifa_next) { if (ifa->ifa_addr->sa_family == addr->sin_family) { sa = (struct sockaddr_in *)ifa->ifa_addr; inet_ntop(ifa->ifa_addr->sa_family, (void *)&(sa->sin_addr), buf1, sizeof(buf1)); inet_ntop(addr->sin_family, (void *)&addr->sin_addr, buf2, sizeof(buf2)); if (strcmp(buf1, buf2) == 0) { retval = utilioctl_getifmtubyname(ifa->ifa_name); break; } } } freeifaddrs(addrs); } return retval; }
bool sockobj_setopts(struct sockobj * const obj, struct vector * const opts) { bool ret = false; int32_t err = 0; struct sockobj_opt *opt = NULL; uint32_t i; if (UTILDEBUG_VERIFY((obj != NULL) && (opts != NULL) && (vector_getsize(opts) > 0))) { ret = true; for (i = 0; i < vector_getsize(opts); i++) { opt = (struct sockobj_opt *)vector_getval(opts, i); if (opt == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u option index %u is empty\n", __FUNCTION__, obj->sid, i); ret = false; } else { err = setsockopt(obj->fd, opt->level, opt->name, &opt->val, sizeof(opt->val)); if (err != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u '%s' option failed (%d)\n", __FUNCTION__, obj->sid, sockobj_getoptname(opt->name), errno); ret = false; } } } } return ret; }
bool sockobj_close(struct sockobj * const obj) { int32_t ret = false; if (UTILDEBUG_VERIFY(obj != NULL)) { if (close(obj->fd) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u could not be closed (%d)\n", __FUNCTION__, obj->sid, errno); } else { obj->info.stopusec = utildate_gettstime(DATE_CLOCK_MONOTONIC, UNIT_TIME_USEC); ret = true; } obj->state = SOCKOBJ_STATE_CLOSE; } return ret; }
bool sockobj_bind(struct sockobj * const obj) { bool ret = false; if (!UTILDEBUG_VERIFY(obj != NULL)) { // Do nothing. } else if (bind(obj->fd, (struct sockaddr*)&obj->addrself.sockaddr, obj->addrself.addrlen) == 0) { sockobj_getaddrself(obj); obj->state |= SOCKOBJ_STATE_BIND; ret = true; } else { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u bind failed (%d)\n", __FUNCTION__, obj->sid, errno); } return ret; }
bool sockobj_getaddrself(struct sockobj * const obj) { bool ret = false; socklen_t socklen = 0; if (!UTILDEBUG_VERIFY((obj != NULL) && ((socklen = sizeof(obj->addrself.sockaddr)) > 0))) { // Do nothing. } else if (getsockname(obj->fd, (struct sockaddr *)&(obj->addrself.sockaddr), &socklen) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u getsockname failed (%d)\n", __FUNCTION__, obj->sid, errno); } else { ret = sockobj_getaddrsock(&obj->addrself); } return ret; }
static void log_sql_errors(MYSQL_THD thd __attribute__((unused)), unsigned int event_class __attribute__((unused)), const void *ev) { const struct mysql_event_general *event = (const struct mysql_event_general*)ev; if (rate && event->event_subclass == MYSQL_AUDIT_GENERAL_ERROR) { if (++count >= rate) { struct tm t; time_t event_time = event->general_time; count = 0; (void) localtime_r(&event_time, &t); logger_printf(logfile, "%04d-%02d-%02d %2d:%02d:%02d " "%s ERROR %d: %s : %s\n", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec, event->general_user, event->general_error_code, event->general_command, event->general_query); } } }
bool fionpoll_create(struct fionobj * const obj) { bool ret = false; if (UTILDEBUG_VERIFY((obj != NULL) && (vector_getsize(&obj->fds) == 0))) { obj->ops.fion_create = fionpoll_create; obj->ops.fion_destroy = fionpoll_destroy; obj->ops.fion_insertfd = fionpoll_insertfd; obj->ops.fion_deletefd = fionpoll_deletefd; obj->ops.fion_setflags = fionpoll_setflags; obj->ops.fion_poll = fionpoll_poll; obj->ops.fion_getevents = fionpoll_getevents; obj->timeoutms = 0; obj->pevents = 0; obj->revents = 0; if (!vector_create(&obj->fds, 0, sizeof(struct pollfd))) { logger_printf(LOGGER_LEVEL_ERROR, "%s: vector allocation failed (%d)\n", __FUNCTION__, errno); } else { ret = true; } } return ret; }
/** * @see See header file for interface comments. */ int32_t utilioctl_getifminmtu(void) { int32_t retval = -1, mtu = -1; struct ifaddrs *ifaddr = NULL, *ifa = NULL; if (getifaddrs(&ifaddr) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to get network interface list (%d)\n", __FUNCTION__, errno); } else { for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) { if ((ifa->ifa_addr != NULL) && ((ifa->ifa_addr->sa_family == AF_INET) || (ifa->ifa_addr->sa_family == AF_INET6))) { if ((mtu = utilioctl_getifmtubyname(ifa->ifa_name)) > -1) { if ((retval == -1) || (mtu < retval)) { retval = mtu; } } } } freeifaddrs(ifaddr); } return retval; }
/** * @see See header file for interface comments. */ bool utilinet_getaddrfromhost(const char * const host, const int32_t family, char * const addr, const uint32_t len) { bool ret = false; struct addrinfo hints, *res, *rp; struct sockaddr_in *ipv4; struct sockaddr_in6 *ipv6; if ((host == NULL) || (addr == NULL) || (len == 0)) { logger_printf(LOGGER_LEVEL_ERROR, "%s: parameter validation failed\n", __FUNCTION__); } else { memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; hints.ai_protocol = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; if (getaddrinfo(host, NULL, &hints, &res) == 0) { for (rp = res; rp != NULL; rp = rp->ai_next) { if (rp->ai_family == AF_INET) { ipv4 = (struct sockaddr_in*)rp->ai_addr; inet_ntop(AF_INET, &ipv4->sin_addr, addr, len); ret = true; break; } else if (rp->ai_family == AF_INET6) { ipv6 = (struct sockaddr_in6*)rp->ai_addr; inet_ntop(AF_INET6, &ipv6->sin6_addr, addr, len); ret = true; break; } } freeaddrinfo(res); } } return ret; }
static void deployer_event_cb(DeployerEventContext *event_cb_ctx, void *ctx) { const char *result = out[event_cb_ctx->result]; switch (event_cb_ctx->event) { case DEPLOYER_EVENT_TARGET_START: printf("==================================================\n"); logger_printf("==================================================\n"); printf("target: %s\n", event_cb_ctx->target); logger_printf("target: %s\n", event_cb_ctx->target); break; case DEPLOYER_EVENT_FTP_CONNECT: printf("--> FTP connect %s\n", result); break; case DEPLOYER_EVENT_FTP_LOGIN: printf("--> FTP login %s\n", result); break; case DEPLOYER_EVENT_FTP_SET_TYPE: printf("--> FTP set type %s\n", result); break; case DEPLOYER_EVENT_FTP_PUT_FILE: printf("--> FTP put file %s %s\n", event_cb_ctx->file, result); break; case DEPLOYER_EVENT_FTP_CLOSE: printf("--> FTP close %s\n", result); break; case DEPLOYER_EVENT_TELNET_CONNECT: printf("--> Telnet connect %s\n", result); break; case DEPLOYER_EVENT_TELNET_LOGIN: printf("--> Telnet login %s\n", result); break; case DEPLOYER_EVENT_TELNET_COMMAND: printf("--> Telnet command %s\n", result); break; case DEPLOYER_EVENT_TELNET_CLOSE: printf("--> Telnet close %s\n", result); break; case DEPLOYER_EVENT_TARGET_END: printf("RESULT: %s\n", out[event_cb_ctx->result]); break; default: break; } }
bool sockobj_getaddrsock(struct sockobj_addr * const addr) { bool ret = false; uint16_t *port = NULL; if (!UTILDEBUG_VERIFY(addr != NULL)) { // Do nothing. } else if (inet_ntop(addr->sockaddr.ss_family, utilinet_getaddrfromstorage(&addr->sockaddr), addr->ipaddr, sizeof(addr->ipaddr)) == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to convert address format (%d)\n", __FUNCTION__, errno); } else if ((port = utilinet_getportfromstorage(&addr->sockaddr)) == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to convert port format\n", __FUNCTION__); } else { addr->ipport = ntohs(*port); snprintf(addr->sockaddrstr, sizeof(addr->sockaddrstr), "%s:%u", addr->ipaddr, addr->ipport); ret = true; } return ret; }
/** * @see See header file for interface comments. */ int32_t utilioctl_getrecvqsize(const int32_t fd) { int32_t retval = 0; if (ioctl(fd, FIONREAD, &retval) == -1) { logger_printf(LOGGER_LEVEL_ERROR, "%s: ioctl request failed (%d)\n", __FUNCTION__, errno); retval = -1; } return retval; }
static DWORD WINAPI SvcCtrlHandler(DWORD dwControl, DWORD dwEventType, void *lpEventData, void *lpContext) { switch (dwControl) { case SERVICE_CONTROL_STOP: report_status(SERVICE_STOP_PENDING, NO_ERROR, 0); SetEvent(stopEvent); return NO_ERROR; case SERVICE_CONTROL_INTERROGATE: return NO_ERROR; case SERVICE_CONTROL_POWEREVENT: logger_printf(TEXT("power event %d"), dwEventType); break; case SERVICE_CONTROL_SESSIONCHANGE: logger_printf(TEXT("session change %d"), dwEventType); break; } return ERROR_CALL_NOT_IMPLEMENTED; }
/** * @see See header file for interface comments. */ int32_t utilioctl_getsendqsize(const int32_t fd) { int32_t retval = -1; #if !defined (__CYGWIN__) if (ioctl(fd, TIOCOUTQ, &retval) == -1) #endif { logger_printf(LOGGER_LEVEL_ERROR, "%s: fd %d ioctl request failed (%d)\n", __FUNCTION__, fd, errno); } return retval; }
bool fionpoll_poll(struct fionobj * const obj) { bool ret = false; int32_t err; uint32_t i; if (UTILDEBUG_VERIFY((obj != NULL) && (vector_getsize(&obj->fds) > 0))) { obj->revents = 0; err = poll((struct pollfd *)vector_getval(&obj->fds, 0), vector_getsize(&obj->fds), obj->timeoutms); if (err == 0) { // No event on any file descriptor. obj->revents = FIONOBJ_REVENT_TIMEOUT; ret = true; } else if (err > 0) { for (i = 0; i < vector_getsize(&obj->fds); i++) { obj->revents |= fionpoll_getevents(obj, i); } ret = true; } else { logger_printf(LOGGER_LEVEL_ERROR, "%s: poll failed (%d)\n", __FUNCTION__, errno); } } return ret; }
bool sockobj_create(struct sockobj * const obj) { bool ret = false; if (UTILDEBUG_VERIFY(obj != NULL)) { memset(obj, 0, sizeof(struct sockobj)); if (!fionpoll_create(&obj->event)) { logger_printf(LOGGER_LEVEL_ERROR, "%s: event allocation failed\n", __FUNCTION__); } else { obj->event.pevents = FIONOBJ_PEVENT_IN; //obj->event.ops.fion_setflags(&obj->event); ret = true; } } return ret; }
/** * @see See header file for interface comments. */ bool utilinet_isipv6(const char * const addr) { bool ret = false; int32_t err; struct sockaddr_in6 ipv6; if (addr == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: parameter validation failed\n", __FUNCTION__); } else { err = inet_pton(AF_INET6, addr, &ipv6); if (err == 1) { ret = true; } } return ret; }
bool mutexobj_lock(struct mutexobj * const mtx) { bool ret = false; int32_t err = 0; if (UTILDEBUG_VERIFY(mtx != NULL)) { err = pthread_mutex_lock(&mtx->obj); if (err != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to lock mutex (%d) %p\n", __FUNCTION__, err, mtx); } else { ret = true; } } return ret; }
static TCHAR * get_string_parameter(HKEY hkey, const TCHAR *param_name) { TCHAR tmp[MAX_PATH]; DWORD dwSize = sizeof(tmp); LONG rv; rv = RegQueryValueEx(hkey, param_name, NULL, NULL, (BYTE *) tmp, &dwSize); if (rv == ERROR_SUCCESS) { size_t nchars = dwSize / sizeof(TCHAR); if (nchars >= MAX_PATH) { nchars = MAX_PATH - 1; } tmp[nchars] = '\0'; return _tcsdup(tmp); } else { logger_printf(TEXT("RegQueryValueEx for '%s' returned %d"), param_name, rv); return NULL; } }
bool threadpool_create(struct threadpool * pool, const uint32_t size) { bool ret = false; uint32_t i = 0; struct threadpool_thread *thread = NULL; if (UTILDEBUG_VERIFY((pool != NULL) && (pool->priv == NULL) && (size > 0))) { pool->priv = UTILMEM_CALLOC(struct threadpool_priv, sizeof(struct threadpool_priv), 1); if (pool->priv == NULL) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to allocate private memory (%d)\n", __FUNCTION__, errno); } else if (!vector_create(&pool->priv->threads, size, sizeof(struct threadpool_thread))) { threadpool_destroy(pool); } else if (!vector_create(&pool->priv->tasks, 0, sizeof(struct threadpool_task))) { threadpool_destroy(pool); } else if (!cvobj_create(&pool->priv->cv_task)) { threadpool_destroy(pool); } else if (!cvobj_create(&pool->priv->cv_wait)) { threadpool_destroy(pool); } else if (!mutexobj_create(&pool->priv->mtx)) { threadpool_destroy(pool); } else { for (i = 0; i < vector_getsize(&pool->priv->threads); i++) { thread = vector_getval(&pool->priv->threads, i); memset(thread, 0, sizeof(*thread)); if (!threadobj_create(&thread->handle)) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to create thread #%u\n", __FUNCTION__, i); } else if (!threadobj_init(&thread->handle, threadpool_taskthread, pool)) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to initialize thread #%u\n", __FUNCTION__, i); } } if (i != vector_getsize(&pool->priv->threads)) { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to create thread pool\n", __FUNCTION__); threadpool_destroy(pool); } else { pool->priv->shutdown = true; ret = true; } } }
bool fionpoll_insertfd(struct fionobj * const obj, const int32_t fd) { bool ret = false, found = false; struct pollfd *pfd = NULL; struct pollfd val = {.fd = fd, .events = 0, .revents = 0}; uint32_t i; if (UTILDEBUG_VERIFY(obj != NULL)) { for (i = 0; i < vector_getsize(&obj->fds); i++) { pfd = (struct pollfd *)vector_getval(&obj->fds, i); if (pfd->fd == fd) { logger_printf(LOGGER_LEVEL_ERROR, "%s: fd %d is already in the list\n", __FUNCTION__, fd); found = true; break; } } if (!found) { if ((vector_inserttail(&obj->fds, &val)) && (obj->ops.fion_setflags(obj))) { ret = true; } } } return ret; } bool fionpoll_deletefd(struct fionobj * const obj, const int32_t fd) { bool ret = false, found = false; struct pollfd *pfd = NULL; uint32_t i; if (UTILDEBUG_VERIFY(obj != NULL)) { for (i = 0; i < vector_getsize(&obj->fds); i++) { pfd = (struct pollfd *)vector_getval(&obj->fds, i); if (pfd->fd == fd) { found = true; break; } } if (!found) { logger_printf(LOGGER_LEVEL_ERROR, "%s: fd %d is not in the list\n", __FUNCTION__, fd); } else { ret = vector_delete(&obj->fds, i); } } return ret; }
static void SvcInit(DWORD dwArgc, TCHAR *lpszArgv[]) { MyParams params = {0}; /* create an event; this event will be raised when we're told * to shut down */ stopEvent = CreateEvent( NULL, /* default security attributes */ TRUE, /* manual reset event */ FALSE, /* not signaled */ NULL); /* no name */ if (stopEvent == NULL) { report_status(SERVICE_STOPPED, NO_ERROR, 0); return; } /* look in registry for guidance */ get_registry_params(lpszArgv[0], ¶ms); logger_message(TEXT("startup: version 2011.03.21")); report_status(SERVICE_RUNNING, NO_ERROR, 0); while(1) { if (params.delay != 0) { HANDLE hTimer; LARGE_INTEGER li = {0}; const __int64 nTimerUnitsPerSecond = 10000000; int nsecs_delay; if (params.hour != 101) { struct tm *tm; time_t t; int nhours_delay; time(&t); tm = localtime(&t); nhours_delay = (params.hour + 24 - tm->tm_hour) % 24; nsecs_delay = params.delay + 3600 * nhours_delay; } else { nsecs_delay = params.delay; } logger_printf(TEXT("waiting for %d seconds"), nsecs_delay); li.QuadPart = -(nsecs_delay * nTimerUnitsPerSecond); hTimer = CreateWaitableTimer(NULL, FALSE, NULL); SetWaitableTimer(hTimer, &li, 0, NULL, NULL, TRUE); { HANDLE handles[2]; DWORD dwEvent; handles[0] = stopEvent; handles[1] = hTimer; dwEvent = WaitForMultipleObjects(2, handles, FALSE, INFINITE); if (dwEvent == WAIT_OBJECT_0 + 0) { /* stop the service */ logger_message(TEXT("received stop signal")); report_status(SERVICE_STOPPED, NO_ERROR, 0); CloseHandle(hTimer); return; } else if (dwEvent != WAIT_OBJECT_0 + 1) { /* FIXME- error returned by WaitForMultipleObjects */ } } CloseHandle(hTimer); } if (check_for_active_sessions()) { logger_printf(TEXT("station appears to be in use")); continue; } break; } if (params.script != NULL) { logger_printf(TEXT("resetting the idle timer")); SetThreadExecutionState(ES_SYSTEM_REQUIRED | ES_CONTINUOUS); if (params.status_window_cmd != NULL) { logger_printf(TEXT("launching status window process")); launch_status_window(params.status_window_cmd); } logger_printf(TEXT("launching script %s"), params.script); create_process(params.script); } else { logger_message(TEXT("nothing to run")); } { WaitForSingleObject(stopEvent, INFINITE); logger_message(TEXT("received stop signal")); report_status(SERVICE_STOPPED, NO_ERROR, 0); return; } }
bool sockobj_open(struct sockobj * const obj) { bool ret = false; int32_t portsize = 0, flags; struct addrinfo *alist = NULL, *anext = NULL, ahints; socklen_t optlen, optval; char ipport[6]; if (UTILDEBUG_VERIFY(obj != NULL)) { memset(&ahints, 0, sizeof(struct addrinfo)); ahints.ai_family = obj->conf.family; ahints.ai_socktype = obj->conf.type; ahints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG; ahints.ai_protocol = 0; ahints.ai_canonname = NULL; ahints.ai_addr = NULL; ahints.ai_next = NULL; portsize = snprintf(ipport, 6, "%d", obj->conf.ipport); if ((portsize > 0) && (portsize < 6) && (getaddrinfo(obj->conf.ipaddr, ipport, &ahints, &alist) == 0)) { for (anext = alist; anext != NULL; anext = anext->ai_next) { if ((anext->ai_family == obj->conf.family) && ((obj->fd = socket(anext->ai_family, anext->ai_socktype, anext->ai_protocol)) != -1)) { obj->addrself.sockaddr.ss_family = anext->ai_family; inet_pton(obj->addrself.sockaddr.ss_family, obj->conf.ipaddr, utilinet_getaddrfromstorage(&obj->addrself.sockaddr)); *utilinet_getportfromstorage(&obj->addrself.sockaddr) = htons(obj->conf.ipport); obj->addrself.addrlen = anext->ai_addrlen; obj->addrpeer.sockaddr.ss_family = anext->ai_family; inet_pton(obj->addrpeer.sockaddr.ss_family, obj->conf.ipaddr, utilinet_getaddrfromstorage(&obj->addrpeer.sockaddr)); *utilinet_getportfromstorage(&obj->addrpeer.sockaddr) = htons(obj->conf.ipport); obj->addrpeer.addrlen = anext->ai_addrlen; optlen = sizeof(obj->info.recv.winsize); optval = 1; obj->event.ops.fion_insertfd(&obj->event, obj->fd); flags = fcntl(obj->fd, F_GETFL, 0); if (!obj->event.ops.fion_setflags(&obj->event)) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u event creation failed\n", __FUNCTION__, obj->sid, errno); sockobj_close(obj); } else if (fcntl(obj->fd, F_SETFL, flags | O_NONBLOCK) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u O_NONBLOCK option failed (%d)\n", __FUNCTION__, obj->sid, errno); } // @todo - SO_LINGER? etc else if (setsockopt(obj->fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u SO_REUSEADDR option failed (%d)\n", __FUNCTION__, obj->sid, errno); sockobj_close(obj); } #if defined(SO_REUSEPORT) else if (setsockopt(obj->fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u SO_REUSEPORT option failed (%d)\n", __FUNCTION__, obj->sid, errno); sockobj_close(obj); } #endif #if defined(__APPLE__) else if (setsockopt(obj->fd, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u SO_NOSIGPIPE option failed (%d)\n", __FUNCTION__, obj->sid, errno); sockobj_close(obj); } #endif else if (getsockopt(obj->fd, SOL_SOCKET, SO_RCVBUF, &obj->info.recv.winsize, &optlen) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u SO_RCVBUF option failed (%d)\n", __FUNCTION__, obj->sid, errno); sockobj_close(obj); } else if (getsockopt(obj->fd, SOL_SOCKET, SO_SNDBUF, &obj->info.send.winsize, &optlen) != 0) { logger_printf(LOGGER_LEVEL_ERROR, "%s: socket %u SO_SNDBUF option failed (%d)\n", __FUNCTION__, obj->sid, errno); sockobj_close(obj); } else { tokenbucket_init(&obj->tb, obj->conf.ratelimitbps); obj->state = SOCKOBJ_STATE_OPEN; ret = true; } break; } } freeaddrinfo(alist); } else { logger_printf(LOGGER_LEVEL_ERROR, "%s: failed to get address information (%d)\n", __FUNCTION__, errno); } } return ret; }
static BOOL check_for_active_sessions(void) { WTS_SESSION_INFO *session_info; DWORD session_info_count; BOOL rv; BOOL found_active_session = FALSE; rv = WTSEnumerateSessions( WTS_CURRENT_SERVER_HANDLE, 0, /* Reserved */ 1, /* Version */ &session_info, &session_info_count); if (!rv) { logger_printf(TEXT("WTSEnumerateSessions: error")); return FALSE; } if (session_info_count > 0) { size_t i; for (i = 0; i < session_info_count; i++) { logger_printf(TEXT("session %d \"%s\" is %d"), session_info[i].SessionId, session_info[i].pWinStationName, session_info[i].State); { TCHAR *pBuffer = NULL; DWORD bytesReturned; if (WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, session_info[i].SessionId, WTSUserName, &pBuffer, &bytesReturned)) { logger_printf(TEXT(" username: %s"), pBuffer); if (_tcscmp(TEXT("Student-PAC"), pBuffer) == 0) { logger_printf(TEXT(" this username is EXEMPT")); } else if (session_info[i].State == WTSActive && _tcscmp(TEXT("Console"), session_info[i].pWinStationName) == 0 && _tcslen(pBuffer) > 0) { logger_printf(TEXT(" this session is active")); found_active_session = TRUE; } WTSFreeMemory(pBuffer); pBuffer = NULL; } } } } else { logger_printf(TEXT("no sessions found")); } WTSFreeMemory(session_info); { LASTINPUTINFO lii = { sizeof(LASTINPUTINFO) }; if (GetLastInputInfo(&lii)) { size_t elapsed = GetTickCount() - lii.dwTime; logger_printf(TEXT("Note: %d seconds since last input"), elapsed / 1000); // if (elapsed / 1000 < 300 && lii.dwTime / 1000 > 300) // { // return TRUE; // } } } logger_printf(TEXT("found active session == %s"), found_active_session ? TEXT("true") : TEXT("false")); return found_active_session; }