#include "fastfetch.h" #include "users.h" #if FF_HAVE_UTMPX #include #else //for Android compatibility #include #define utmpx utmp #define setutxent setutent #define getutxent getutent #endif #ifdef __linux__ #include #include #endif const char* ffDetectUsers(FFUsersOptions* options, FFlist* users) { struct utmpx* n = NULL; setutxent(); next: while ((n = getutxent())) { if (n->ut_type != USER_PROCESS) continue; if (options->myselfOnly && !ffStrbufEqualS(&instance.state.platform.userName, n->ut_user)) continue; FF_LIST_FOR_EACH(FFUserResult, user, *users) { if(ffStrbufEqualS(&user->name, n->ut_user)) goto next; } FFUserResult* user = (FFUserResult*) ffListAdd(users); ffStrbufInitS(&user->name, n->ut_user); ffStrbufInitS(&user->hostName, n->ut_host); ffStrbufInitS(&user->sessionName, n->ut_line); ffStrbufInit(&user->clientIp); #ifdef __linux__ bool isIpv6 = false; for (int i = 1; i < 4; ++i) { if (n->ut_addr_v6[i] != 0) { isIpv6 = true; break; } } if (isIpv6) { char ipv6_str[INET6_ADDRSTRLEN]; if (inet_ntop(AF_INET6, n->ut_addr_v6, ipv6_str, INET6_ADDRSTRLEN) != NULL) { ffStrbufSetS(&user->clientIp, ipv6_str); } } else if (n->ut_addr_v6[0] != 0) { char ipv4_str[INET_ADDRSTRLEN]; if (inet_ntop(AF_INET, n->ut_addr_v6, ipv4_str, INET_ADDRSTRLEN) != NULL) { ffStrbufSetS(&user->clientIp, ipv4_str); } } #endif user->loginTime = (uint64_t) n->ut_tv.tv_sec * 1000 + (uint64_t) n->ut_tv.tv_usec / 1000; } return NULL; }