You can use this quick&dirty piece of software listed below to
redirect std i/o of a program to a tcp connection.
Assuming the executable file is named tcpcmd.exe. Following command line
tcpcmd 12345 "sqlite3 -batch"
will run "sqlite3 -batch" and listen on tcp port 12345 (for security
reasons it listens only on loopback interface (127.0.0.1)).
(You may need to link with ws2_32.lib)
-------------------------------------------------------------------------
#include <WinSock2.h>
#include <stdio.h>
#define BUFFER_SIZE 1024
#define OV_ENTRIES 2
enum TransferState
{
TS_NULL,
TS_READING,
TS_READY,
TS_WRITING
};
WSADATA g_WsaData;
PROCESS_INFORMATION g_Process;
SOCKET g_sockLst, g_sockClient;
HANDLE g_hInWr, g_hInRd, g_hOutWr, g_hOutRd;
HANDLE g_hIOCP;
wchar_t* g_zCommand;
int g_nPort;
int g_bConnected = 0;
enum TransferState g_eInState = TS_NULL, g_eOutState = TS_NULL;
OVERLAPPED g_ovIn, g_ovOut;
WSABUF g_wbIn, g_wbOut;
DWORD g_flgWsaIn;
DWORD g_nIn, g_nOut;
char g_bufIn[BUFFER_SIZE], g_bufOut[BUFFER_SIZE];
void printError(const wchar_t* zFunc, DWORD nErr);
int parseArgs(int argc, wchar_t* argv[]);
int openPort();
int acceptClient();
void closeClient();
int runCommandProcess();
int main_loop();
int wmain(int argc, wchar_t* argv[])
{
int rc = parseArgs(argc, argv);
if (rc)
return rc;
rc = WSAStartup(MAKEWORD(2, 2), &g_WsaData);
if (rc)
{
printError(L"WSAStartup", rc);
return rc;
}
rc = openPort();
if (!rc)
{
rc = runCommandProcess();
if (!rc)
{
while (main_loop() == 0);
TerminateProcess(g_Process.hProcess, 0);
}
closeClient();
closesocket(g_sockLst);
}
WSACleanup();
return rc;
}
int main_loop()
{
int rc;
DWORD dwProcExit;
ULONG i;
ULONG nOvEntries = 0;
OVERLAPPED_ENTRY ovEntries[OV_ENTRIES];
rc = GetExitCodeProcess(g_Process.hProcess, &dwProcExit);
if (!rc)
{
printError(L"GetExitCodeProcess", GetLastError());
return 1;
}
if (dwProcExit != STILL_ACTIVE)
return 1;
switch (g_eInState)
{
case TS_NULL:
rc = acceptClient();
if (rc)
break;
memset(&g_ovIn, 0, sizeof(g_ovIn));
g_wbIn.buf = g_bufIn;
g_wbIn.len = BUFFER_SIZE;
g_nIn = 0;
g_flgWsaIn = 0;
rc = WSARecv(g_sockClient, &g_wbIn, 1, NULL, &g_flgWsaIn,
&g_ovIn, NULL);
if (rc)
{
DWORD err = WSAGetLastError();
if (err != ERROR_IO_PENDING)
{
printError(L"WSARecv", err);
closeClient();
return 0;
}
}
g_eInState = TS_READING;
break;
case TS_READY:
memset(&g_ovIn, 0, sizeof(g_ovIn));
rc = WriteFile(g_hInWr, g_bufIn, g_nIn, NULL, &g_ovIn);
if (!rc)
{
DWORD err = GetLastError();
if (err != ERROR_IO_PENDING)
{
printError(L"WriteFile", err);
return 1;
}
}
g_eInState = TS_WRITING;
break;
default:
break;
}
switch (g_eOutState)
{
case TS_NULL:
memset(&g_ovOut, 0, sizeof(g_ovOut));
rc = ReadFile(g_hOutRd, g_bufOut, BUFFER_SIZE, NULL, &g_ovOut);
if (!rc)
{
DWORD err = GetLastError();
if (err != ERROR_IO_PENDING)
{
printError(L"ReadFile", err);
return 1;
}
}
g_eOutState = TS_READING;
break;
case TS_READY:
rc = acceptClient();
if (rc)
break;
memset(&g_ovOut, 0, sizeof(g_ovOut));
g_wbOut.buf = g_bufOut;
g_wbOut.len = g_nOut;
rc = WSASend(g_sockClient, &g_wbOut, 1, NULL, 0, &g_ovOut,
NULL);
if (rc)
{
DWORD err = WSAGetLastError();
if (err != ERROR_IO_PENDING)
{
printError(L"WSASend", err);
closeClient();
return 0;
}
}
g_eOutState = TS_WRITING;
break;
default:
break;
}
memset(&ovEntries, 0, sizeof(ovEntries));
rc = GetQueuedCompletionStatusEx(g_hIOCP, ovEntries, 2, &nOvEntries,
10000, TRUE);
if (!rc)
return 0;
for (i = 0; i < nOvEntries; ++i)
{
LPOVERLAPPED_ENTRY pOvEn = &ovEntries[i];
if (pOvEn->lpOverlapped == &g_ovIn)
{
switch (g_eInState)
{
case TS_READING:
g_nIn = pOvEn->dwNumberOfBytesTransferred;
if (g_nIn)
g_eInState = TS_READY;
else
{
g_eInState = TS_NULL;
closeClient();
}
break;
case TS_WRITING:
if (g_nIn <= pOvEn->dwNumberOfBytesTransferred)
g_eInState = TS_NULL;
else
{
g_nIn -=
pOvEn->dwNumberOfBytesTransferred;
memmove(g_bufIn, (g_bufIn +
pOvEn->dwNumberOfBytesTransferred), g_nIn);
g_eInState = TS_READY;
}
break;
default:
break;
}
}
else if (pOvEn->lpOverlapped == &g_ovOut)
{
switch (g_eOutState)
{
case TS_READING:
g_nOut = pOvEn->dwNumberOfBytesTransferred;
if (g_nOut)
g_eOutState = TS_READY;
else
g_eOutState = TS_NULL;
break;
case TS_WRITING:
if (g_nOut <= pOvEn->dwNumberOfBytesTransferred)
g_eOutState = TS_NULL;
else
{
g_nOut -=
pOvEn->dwNumberOfBytesTransferred;
memmove(g_bufOut, (g_bufOut +
pOvEn->dwNumberOfBytesTransferred), g_nOut);
g_eOutState = TS_READY;
}
break;
default:
break;
}
}
}
return 0;
}
int openPort()
{
int rc;
struct sockaddr_in saddrLst;
g_sockLst = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (g_sockLst == INVALID_SOCKET)
{
printError(L"socket", WSAGetLastError());
return 1;
}
memset(&saddrLst, 0, sizeof(saddrLst));
saddrLst.sin_family = AF_INET;
saddrLst.sin_port = htons(g_nPort);
saddrLst.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
rc = bind(g_sockLst, (struct sockaddr*)&saddrLst, sizeof(saddrLst));
if (rc)
{
printError(L"bind", WSAGetLastError());
closesocket(g_sockLst);
return rc;
}
rc = listen(g_sockLst, 1);
if (rc)
{
printError(L"listen", WSAGetLastError());
closesocket(g_sockLst);
return rc;
}
return rc;
}
int acceptClient()
{
HANDLE hIOCP;
if (g_bConnected)
return 0;
g_sockClient = accept(g_sockLst, NULL, NULL);
if (g_sockClient == INVALID_SOCKET)
{
printError(L"accept", WSAGetLastError());
return 1;
}
hIOCP = CreateIoCompletionPort((HANDLE)g_sockClient, g_hIOCP, 0, 0);
if (!hIOCP)
{
printError(L"CreateIoCompletionPort", GetLastError());
closesocket(g_sockClient);
return 1;
}
g_bConnected = 1;
return 0;
}
void closeClient()
{
if (g_bConnected)
closesocket(g_sockClient);
g_bConnected = 0;
}
int createPipe(PHANDLE phServer, PHANDLE phClient, int dir)
{
DWORD dwOpenMode = (dir ? PIPE_ACCESS_INBOUND : PIPE_ACCESS_OUTBOUND)
| FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED;
DWORD dwFileAccess = (dir ? GENERIC_WRITE : GENERIC_READ);
DWORD dwFileShare = (dir ? FILE_SHARE_READ : FILE_SHARE_WRITE)
| FILE_SHARE_DELETE;
SECURITY_ATTRIBUTES sec_attr;
wchar_t name[256];
swprintf(name, 255, L"\\\\.\\pipe\\ChildStdPipe%d_P%u_T%u", dir,
GetCurrentProcessId(), GetCurrentThreadId());
*phServer = CreateNamedPipeW(name, dwOpenMode,
PIPE_REJECT_REMOTE_CLIENTS, 1, 0, 0, 0, NULL);
if (*phServer == INVALID_HANDLE_VALUE)
{
printError(L"CreateNamedPipeW", GetLastError());
return 1;
}
memset(&sec_attr, 0, sizeof(sec_attr));
sec_attr.bInheritHandle = TRUE;
*phClient = CreateFileW(name, dwFileAccess, dwFileShare, &sec_attr,
OPEN_EXISTING, 0, NULL);
if (*phClient == INVALID_HANDLE_VALUE)
{
printError(L"CreateFileW", GetLastError());
CloseHandle(*phServer);
return 1;
}
return 0;
}
int runCommandProcess()
{
int rc;
STARTUPINFOW startup_info;
memset(&startup_info, 0, sizeof(startup_info));
rc = createPipe(&g_hInWr, &g_hInRd, 0);
if (rc)
return rc;
rc = createPipe(&g_hOutRd, &g_hOutWr, 1);
if (rc)
return rc;
g_hIOCP = CreateIoCompletionPort(g_hInWr, NULL, 0, 0);
if (!g_hIOCP)
{
printError(L"CreateIoCompletionPort", GetLastError());
return 1;
}
g_hIOCP = CreateIoCompletionPort(g_hOutRd, g_hIOCP, 0, 0);
if (!g_hIOCP)
{
printError(L"CreateIoCompletionPort", GetLastError());
return 1;
}
startup_info.cb = sizeof(startup_info);
startup_info.dwFlags = STARTF_USESTDHANDLES;
startup_info.hStdInput = g_hInRd;
startup_info.hStdOutput = g_hOutWr;
startup_info.hStdError = g_hOutWr;
rc = CreateProcessW(NULL, g_zCommand, NULL, NULL, TRUE,
CREATE_UNICODE_ENVIRONMENT, NULL, NULL, &startup_info,
&g_Process);
if (!rc)
{
printError(L"CreateProcess", GetLastError());
return 1;
}
return 0;
}
void printError(const wchar_t* zFunc, DWORD nErr)
{
static const DWORD fmtFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER
| FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;
LPWSTR zErr = NULL;
FormatMessageW(fmtFlags, NULL, nErr, 0, (LPWSTR)&zErr, 0, NULL);
fwprintf(stderr, L"%ls error (%u): %ls\n", zFunc, nErr, zErr);
LocalFree((HLOCAL)zErr);
}
int parseArgs(int argc, wchar_t* argv[])
{
static const wchar_t* const zUsage = L"Usage %ls <port> <command>";
if (argc != 3)
{
fwprintf(stderr, zUsage, argv[0]);
return 1;
}
g_nPort = wcstol(argv[1], NULL, 0);
if (g_nPort < 1 || g_nPort > 65535)
{
fwprintf(stderr, L"Invalid port number %d\n", g_nPort);
fwprintf(stderr, zUsage, argv[0]);
return 1;
}
g_zCommand = argv[2];
return 0;
}
-------------------------------------------------------------------------
2018-06-08 19:26 GMT+02:00, [email protected]
<[email protected]>:
>
> Hello -
>
> I've been following for a while, a lot of very intelligent
> people here, and not a lot of fuss!!! Very nice, my compliments to
> all!!
>
> I'm just learning SQLite and using it to collect alarm values from a
> monitoring system. The monitoring system can't access the SQLite file
> directly, so I've been using sqlite3.exe as the intermediate.
>
> Since I'm
> making many access to the database the monitoring program is constantly
> launching sqlite3.exe with new commands or files of commands, very wasteful
> of resources. (Windows 7)
>
> Is there a platform/program that can be run as a
> SQLite "front end" that could be launched once and take commands from
> another program and pass back results, or is there a way to do that with
> sqlite3.exe? I've looked around the web and not found anything, so
> far.
>
> Any guidance is greatly appreciated, thanks for your time!!
>
> Leland
>
> _______________________________________________
> sqlite-users mailing list
> [email protected]
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
>
_______________________________________________
sqlite-users mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users