mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Merge pull request #330 from CarterLi/dev
Networking: support nowait connection
This commit is contained in:
+2
-1
@@ -220,7 +220,6 @@ set(LIBFASTFETCH_SRC
|
||||
src/common/parsing.c
|
||||
src/common/settings.c
|
||||
src/common/library.c
|
||||
src/common/networking.c
|
||||
src/common/bar.c
|
||||
src/logo/logo.c
|
||||
src/logo/builtin.c
|
||||
@@ -293,6 +292,7 @@ set(LIBFASTFETCH_SRC
|
||||
if(LINUX OR APPLE OR ANDROID OR BSD)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/processing_linux.c
|
||||
src/common/networking_linux.c
|
||||
src/detection/users/users_linux.c
|
||||
src/detection/terminalshell/terminalshell_linux.c
|
||||
src/detection/localip/localip_linux.c
|
||||
@@ -360,6 +360,7 @@ endif()
|
||||
if(WIN32)
|
||||
list(APPEND LIBFASTFETCH_SRC
|
||||
src/common/processing_windows.c
|
||||
src/common/networking_windows.c
|
||||
src/detection/host/host_windows.cpp
|
||||
src/detection/bios/bios_windows.cpp
|
||||
src/detection/board/board_windows.cpp
|
||||
|
||||
+5
-5
@@ -305,13 +305,13 @@ FF_THREAD_ENTRY_DECL_WRAPPER(ffDetectGTK4, FFinstance*)
|
||||
void startDetectionThreads(FFinstance* instance)
|
||||
{
|
||||
#ifdef FF_HAVE_THREADS
|
||||
ffThreadCreateAndDetach(ffConnectDisplayServerThreadMain, instance);
|
||||
ffThreadDetach(ffThreadCreate(ffConnectDisplayServerThreadMain, instance));
|
||||
|
||||
#ifdef FF_DETECT_QT_GTK
|
||||
ffThreadCreateAndDetach(ffDetectQtThreadMain, instance);
|
||||
ffThreadCreateAndDetach(ffDetectGTK2ThreadMain, instance);
|
||||
ffThreadCreateAndDetach(ffDetectGTK3ThreadMain, instance);
|
||||
ffThreadCreateAndDetach(ffDetectGTK4ThreadMain, instance);
|
||||
ffThreadDetach(ffThreadCreate(ffDetectQtThreadMain, instance));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK2ThreadMain, instance));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK3ThreadMain, instance));
|
||||
ffThreadDetach(ffThreadCreate(ffDetectGTK4ThreadMain, instance));
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <synchapi.h>
|
||||
|
||||
static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context)
|
||||
{
|
||||
(void)once;
|
||||
(void)param;
|
||||
static WSADATA wsaData;
|
||||
*context = &wsaData;
|
||||
return WSAStartup(MAKEWORD(2, 2), &wsaData) == 0;
|
||||
}
|
||||
|
||||
//Types of winsock2 are full of mess. Disable warnings for them and keep clean for posix
|
||||
#pragma GCC diagnostic ignored "-Wincompatible-pointer-types"
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#define closesocket close
|
||||
#endif
|
||||
|
||||
//Must be included after <winsock2.h>
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
|
||||
WSADATA* pData;
|
||||
if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData))
|
||||
return INVALID_SOCKET;
|
||||
#endif
|
||||
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return INVALID_SOCKET;
|
||||
|
||||
FFSockType sockfd = (FFSockType)socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(sockfd == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
timev.tv_sec = 0;
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
|
||||
setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
if(connect(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
closesocket(sockfd);
|
||||
freeaddrinfo(addr);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
FFstrbuf command;
|
||||
ffStrbufInitA(&command, 64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
if(send(sockfd, command.chars, command.length, 0) == -1)
|
||||
{
|
||||
ffStrbufDestroy(&command);
|
||||
closesocket(sockfd);
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
ffStrbufDestroy(&command);
|
||||
return sockfd;
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer)
|
||||
{
|
||||
ssize_t received = recv(sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
closesocket(sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
FFSockType sockfd = ffNetworkingSendHttpRequest(host, path, headers, timeout);
|
||||
if(sockfd != INVALID_SOCKET)
|
||||
return ffNetworkingRecvHttpResponse(sockfd, buffer);
|
||||
return false;
|
||||
}
|
||||
+27
-10
@@ -3,20 +3,37 @@
|
||||
#ifndef FF_INCLUDED_common_networking
|
||||
#define FF_INCLUDED_common_networking
|
||||
|
||||
#include "common/thread.h"
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
typedef uintptr_t FFSockType; //SOCKET, unsigned
|
||||
#ifndef INVALID_SOCKET //Don't conflict with <winsock2.h>
|
||||
#define INVALID_SOCKET ((uintptr_t)~0)
|
||||
#include <minwindef.h>
|
||||
#endif
|
||||
|
||||
typedef struct FFNetworkingState {
|
||||
#ifdef _WIN32
|
||||
uintptr_t sockfd;
|
||||
OVERLAPPED overlapped;
|
||||
#else
|
||||
int sockfd;
|
||||
FFstrbuf host;
|
||||
FFstrbuf command;
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
FFThreadType thread;
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
typedef int FFSockType; // signed
|
||||
#define INVALID_SOCKET (-1)
|
||||
#endif
|
||||
} FFNetworkingState;
|
||||
|
||||
FFSockType ffNetworkingSendHttpRequest(const char* host, const char* path, const char* headers, uint32_t timeout);
|
||||
bool ffNetworkingRecvHttpResponse(FFSockType sockfd, FFstrbuf* buffer);
|
||||
bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer);
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers);
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout);
|
||||
|
||||
static inline bool ffNetworkingGetHttp(const char* host, const char* path, uint32_t timeout, const char* headers, FFstrbuf* buffer)
|
||||
{
|
||||
FFNetworkingState state;
|
||||
if(ffNetworkingSendHttpRequest(&state, host, path, headers))
|
||||
return ffNetworkingRecvHttpResponse(&state, buffer, timeout);
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
|
||||
static void connectAndSend(FFNetworkingState* state)
|
||||
{
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(state->host.chars, "80", &hints, &addr) != 0)
|
||||
goto error;
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == -1)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if(connect(state->sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
|
||||
{
|
||||
close(state->sockfd);
|
||||
freeaddrinfo(addr);
|
||||
goto error;
|
||||
}
|
||||
|
||||
freeaddrinfo(addr);
|
||||
|
||||
if(send(state->sockfd, state->command.chars, state->command.length, 0) < 0)
|
||||
{
|
||||
close(state->sockfd);
|
||||
goto error;
|
||||
}
|
||||
|
||||
goto exit;
|
||||
|
||||
error:
|
||||
state->sockfd = -1;
|
||||
|
||||
exit:
|
||||
ffStrbufDestroy(&state->host);
|
||||
ffStrbufDestroy(&state->command);
|
||||
}
|
||||
|
||||
FF_THREAD_ENTRY_DECL_WRAPPER(connectAndSend, FFNetworkingState*);
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
ffStrbufInitS(&state->host, host);
|
||||
|
||||
ffStrbufInitA(&state->command, 64);
|
||||
ffStrbufAppendS(&state->command, "GET ");
|
||||
ffStrbufAppendS(&state->command, path);
|
||||
ffStrbufAppendS(&state->command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&state->command, host);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
ffStrbufAppendS(&state->command, headers);
|
||||
ffStrbufAppendS(&state->command, "\r\n");
|
||||
|
||||
#ifdef FF_HAVE_THREADS
|
||||
state->thread = ffThreadCreate(connectAndSendThreadMain, state);
|
||||
return state->thread != NULL;
|
||||
#else
|
||||
connectAndSend(state);
|
||||
return state->sockfd != -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
#ifdef FF_HAVE_THREADS
|
||||
ffThreadJoin(state->thread);
|
||||
#endif
|
||||
if(state->sockfd == -1)
|
||||
return false;
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
struct timeval timev;
|
||||
timev.tv_sec = 0;
|
||||
timev.tv_usec = (__typeof__(timev.tv_usec)) (timeout * 1000); //milliseconds to microseconds
|
||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, &timev, sizeof(timev));
|
||||
}
|
||||
|
||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
close(state->sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
//Must be included after <mswsock.h>
|
||||
#include "fastfetch.h"
|
||||
#include "common/networking.h"
|
||||
|
||||
static LPFN_CONNECTEX ConnectEx;
|
||||
|
||||
static BOOL WINAPI initWsaData(PINIT_ONCE once, PVOID param, PVOID* context)
|
||||
{
|
||||
(void)once;
|
||||
(void)param;
|
||||
static WSADATA wsaData;
|
||||
*context = &wsaData;
|
||||
if(WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
return FALSE;
|
||||
|
||||
if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
|
||||
return FALSE;
|
||||
|
||||
//Dummy socket needed for WSAIoctl
|
||||
SOCKET sockfd = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if(sockfd == INVALID_SOCKET)
|
||||
return FALSE;
|
||||
|
||||
DWORD dwBytes;
|
||||
GUID guid = WSAID_CONNECTEX;
|
||||
if(WSAIoctl(sockfd, SIO_GET_EXTENSION_FUNCTION_POINTER,
|
||||
&guid, sizeof(guid),
|
||||
&ConnectEx, sizeof(ConnectEx),
|
||||
&dwBytes, NULL, NULL) != 0)
|
||||
return FALSE;
|
||||
|
||||
return closesocket(sockfd) == 0;
|
||||
}
|
||||
|
||||
bool ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* host, const char* path, const char* headers)
|
||||
{
|
||||
static INIT_ONCE once = INIT_ONCE_STATIC_INIT;
|
||||
WSADATA* pData;
|
||||
if(!InitOnceExecuteOnce(&once, initWsaData, NULL, (LPVOID*) &pData))
|
||||
return false;
|
||||
|
||||
memset(state, 0, sizeof(*state));
|
||||
|
||||
struct addrinfo hints = {
|
||||
.ai_family = AF_INET,
|
||||
.ai_socktype = SOCK_STREAM,
|
||||
};
|
||||
|
||||
struct addrinfo* addr;
|
||||
|
||||
if(getaddrinfo(host, "80", &hints, &addr) != 0)
|
||||
return false;
|
||||
|
||||
state->sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
|
||||
if(state->sockfd == INVALID_SOCKET)
|
||||
{
|
||||
freeaddrinfo(addr);
|
||||
return false;
|
||||
}
|
||||
|
||||
{
|
||||
//ConnectEx requires the socket to be initially bound
|
||||
struct sockaddr_in addr = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_addr.s_addr = INADDR_ANY,
|
||||
.sin_port = 0,
|
||||
};
|
||||
if(bind(state->sockfd, (SOCKADDR *)&addr, sizeof(addr)) != 0)
|
||||
{
|
||||
printf("bind %d\n", WSAGetLastError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
FFstrbuf command;
|
||||
ffStrbufInitA(&command, 64);
|
||||
ffStrbufAppendS(&command, "GET ");
|
||||
ffStrbufAppendS(&command, path);
|
||||
ffStrbufAppendS(&command, " HTTP/1.1\nHost: ");
|
||||
ffStrbufAppendS(&command, host);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
ffStrbufAppendS(&command, headers);
|
||||
ffStrbufAppendS(&command, "\r\n");
|
||||
|
||||
BOOL result = ConnectEx(state->sockfd, addr->ai_addr, (int)addr->ai_addrlen, command.chars, command.length, NULL, &state->overlapped);
|
||||
freeaddrinfo(addr);
|
||||
ffStrbufDestroy(&command);
|
||||
|
||||
if(!result && WSAGetLastError() != WSA_IO_PENDING)
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
ffStrbufDestroy(&command);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buffer, uint32_t timeout)
|
||||
{
|
||||
DWORD transfer, flags;
|
||||
if (!WSAGetOverlappedResult(state->sockfd, &state->overlapped, &transfer, TRUE, &flags))
|
||||
{
|
||||
closesocket(state->sockfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(timeout > 0)
|
||||
{
|
||||
//https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-setsockopt
|
||||
setsockopt(state->sockfd, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
|
||||
}
|
||||
|
||||
ssize_t received = recv(state->sockfd, buffer->chars + buffer->length, (int)ffStrbufGetFree(buffer), 0);
|
||||
|
||||
if(received > 0)
|
||||
{
|
||||
buffer->length += (uint32_t) received;
|
||||
buffer->chars[buffer->length] = '\0';
|
||||
}
|
||||
|
||||
closesocket(state->sockfd);
|
||||
return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n");
|
||||
}
|
||||
+14
-9
@@ -9,35 +9,40 @@
|
||||
#if defined(_WIN32)
|
||||
#include <handleapi.h>
|
||||
#include <synchapi.h>
|
||||
#include <process.h> // Win32 <process.h> isn't available on MSYS2
|
||||
#include <process.h>
|
||||
#define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT
|
||||
typedef SRWLOCK FFThreadMutex;
|
||||
typedef HANDLE FFThreadType;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { AcquireSRWLockExclusive(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { ReleaseSRWLockExclusive(mutex); }
|
||||
static inline void ffThreadCreateAndDetach(unsigned (__stdcall* func)(void*), void* data) {
|
||||
uintptr_t newThread = _beginthreadex(NULL, 0, func, data, 0, NULL);
|
||||
if(newThread)
|
||||
CloseHandle((HANDLE)newThread);
|
||||
static inline FFThreadType ffThreadCreate(unsigned (__stdcall* func)(void*), void* data) {
|
||||
return (FFThreadType)_beginthreadex(NULL, 0, func, data, 0, NULL);
|
||||
}
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static __stdcall unsigned fn ## ThreadMain (void* data) { fn((paramType)data); return 0; }
|
||||
static inline void ffThreadDetach(FFThreadType thread) { CloseHandle(thread); }
|
||||
static inline void ffThreadJoin(FFThreadType thread) { WaitForSingleObject(thread, INFINITE); }
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
typedef pthread_mutex_t FFThreadMutex;
|
||||
typedef pthread_t FFThreadType;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { pthread_mutex_lock(mutex); }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { pthread_mutex_unlock(mutex); }
|
||||
static inline void ffThreadCreateAndDetach(void* (* func)(void*), void* data) {
|
||||
pthread_t newThread;
|
||||
if(pthread_create(&newThread, NULL, func, data) == 0)
|
||||
pthread_detach(newThread);
|
||||
static inline FFThreadType ffThreadCreate(void* (* func)(void*), void* data) {
|
||||
FFThreadType newThread = NULL;
|
||||
pthread_create(&newThread, NULL, func, data);
|
||||
return newThread;
|
||||
}
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) static void* fn ## ThreadMain (void* data) { fn((paramType)data); return NULL; }
|
||||
static inline void ffThreadDetach(FFThreadType thread) { pthread_detach(thread); }
|
||||
static inline void ffThreadJoin(FFThreadType thread) { pthread_join(thread, NULL); }
|
||||
#endif
|
||||
#else //FF_HAVE_THREADS
|
||||
#define FF_THREAD_MUTEX_INITIALIZER 0
|
||||
typedef char FFThreadMutex;
|
||||
static inline void ffThreadMutexLock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
|
||||
static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { FF_UNUSED(mutex) }
|
||||
#define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType)
|
||||
#endif //FF_HAVE_THREADS
|
||||
|
||||
#endif
|
||||
|
||||
@@ -5,12 +5,13 @@
|
||||
#define FF_PUBLICIP_MODULE_NAME "Public IP"
|
||||
#define FF_PUBLICIP_NUM_FORMAT_ARGS 1
|
||||
|
||||
static FFSockType sockfd;
|
||||
static FFNetworkingState state;
|
||||
static int status = -1;
|
||||
|
||||
void ffPreparePublicIp(FFinstance* instance)
|
||||
{
|
||||
if(instance->config.publicIpUrl.length == 0)
|
||||
sockfd = ffNetworkingSendHttpRequest("ipinfo.io", "/ip", NULL, instance->config.publicIpTimeout);
|
||||
status = ffNetworkingSendHttpRequest(&state, "ipinfo.io", "/ip", NULL);
|
||||
else
|
||||
{
|
||||
FFstrbuf host;
|
||||
@@ -27,7 +28,7 @@ void ffPreparePublicIp(FFinstance* instance)
|
||||
host.chars[pathStartIndex] = '\0';
|
||||
}
|
||||
|
||||
sockfd = ffNetworkingSendHttpRequest(host.chars, path.length == 0 ? "/" : path.chars, NULL, instance->config.publicIpTimeout);
|
||||
status = ffNetworkingSendHttpRequest(&state, host.chars, path.length == 0 ? "/" : path.chars, NULL);
|
||||
|
||||
ffStrbufDestroy(&path);
|
||||
ffStrbufDestroy(&host);
|
||||
@@ -36,10 +37,10 @@ void ffPreparePublicIp(FFinstance* instance)
|
||||
|
||||
void ffPrintPublicIp(FFinstance* instance)
|
||||
{
|
||||
if(sockfd == 0)
|
||||
if(status == -1)
|
||||
ffPreparePublicIp(instance);
|
||||
|
||||
if(sockfd == INVALID_SOCKET)
|
||||
if(status == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_PUBLICIP_MODULE_NAME, 0, &instance->config.publicIP, "Failed to connect to an IP detection server");
|
||||
return;
|
||||
@@ -47,7 +48,7 @@ void ffPrintPublicIp(FFinstance* instance)
|
||||
|
||||
FFstrbuf result;
|
||||
ffStrbufInitA(&result, 4096);
|
||||
bool success = ffNetworkingRecvHttpResponse(sockfd, &result);
|
||||
bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.publicIpTimeout);
|
||||
if(success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n");
|
||||
|
||||
if(!success || result.length == 0)
|
||||
|
||||
@@ -5,23 +5,24 @@
|
||||
#define FF_WEATHER_MODULE_NAME "Weather"
|
||||
#define FF_WEATHER_NUM_FORMAT_ARGS 1
|
||||
|
||||
static FFSockType sockfd;
|
||||
static FFNetworkingState state;
|
||||
static int status = -1;
|
||||
|
||||
void ffPrepareWeather(FFinstance* instance)
|
||||
{
|
||||
FFstrbuf path;
|
||||
ffStrbufInitS(&path, "/?format=");
|
||||
ffStrbufAppend(&path, &instance->config.weatherOutputFormat);
|
||||
sockfd = ffNetworkingSendHttpRequest("wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n", instance->config.weatherTimeout);
|
||||
status = ffNetworkingSendHttpRequest(&state, "wttr.in", path.chars, "User-Agent: curl/0.0.0\r\n");
|
||||
ffStrbufDestroy(&path);
|
||||
}
|
||||
|
||||
void ffPrintWeather(FFinstance* instance)
|
||||
{
|
||||
if(sockfd == 0)
|
||||
if(status == -1)
|
||||
ffPrepareWeather(instance);
|
||||
|
||||
if(sockfd == INVALID_SOCKET)
|
||||
if(status == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_WEATHER_MODULE_NAME, 0, &instance->config.weather, "Failed to connect to 'wttr.in'");
|
||||
return;
|
||||
@@ -29,7 +30,7 @@ void ffPrintWeather(FFinstance* instance)
|
||||
|
||||
FFstrbuf result;
|
||||
ffStrbufInitA(&result, 4096);
|
||||
bool success = ffNetworkingRecvHttpResponse(sockfd, &result);
|
||||
bool success = ffNetworkingRecvHttpResponse(&state, &result, instance->config.weatherTimeout);
|
||||
if (success) ffStrbufSubstrAfterFirstS(&result, "\r\n\r\n");
|
||||
|
||||
if(!success || result.length == 0)
|
||||
|
||||
Reference in New Issue
Block a user