ReactOS  0.4.12-dev-57-g7050ac4
tftpd.cpp File Reference
#include <stdio.h>
#include <winsock2.h>
#include <process.h>
#include <time.h>
#include <tchar.h>
#include <ws2tcpip.h>
#include <limits.h>
#include <iphlpapi.h>
#include <math.h>
#include "tftpd.h"
Include dependency graph for tftpd.cpp:

Go to the source code of this file.

Functions

void WINAPI ServiceControlHandler (DWORD controlCode)
 
void WINAPI ServiceMain (DWORD, TCHAR *[])
 
void runService ()
 
bool stopService (SC_HANDLE service)
 
void installService ()
 
void uninstallService ()
 
void printWindowsError ()
 
int main (int argc, TCHAR *argv[])
 
void runProg ()
 
void closeConn ()
 
void processRequest (void *lpParam)
 
bool cleanReq (request *req)
 
bool getSection (const char *sectionName, char *buffer, MYBYTE serial, char *fileName)
 
FILEopenSection (const char *sectionName, MYBYTE serial, char *fileName)
 
charreadSection (char *buff, FILE *f)
 
charmyGetToken (char *buff, MYBYTE index)
 
MYWORD myTokenize (char *target, char *source, char *sep, bool whiteSep)
 
charmyTrim (char *target, char *source)
 
void mySplit (char *name, char *value, char *source, char splitChar)
 
charIP2String (char *target, MYDWORD ip)
 
bool isIP (char *string)
 
charmyUpper (char *string)
 
charmyLower (char *string)
 
void init (void *lpParam)
 
bool detectChange ()
 
void getInterfaces (data1 *network)
 
bool addServer (MYDWORD *array, MYDWORD ip)
 
MYDWORDfindServer (MYDWORD *array, MYDWORD ip)
 
void logMess (char *logBuff, MYBYTE logLevel)
 
void logMess (request *req, MYBYTE logLevel)
 

Variables

char serviceName [] = "TFTPServer"
 
char displayName [] = "Open TFTP Server, MultiThreaded"
 
char sVersion [] = "Open TFTP Server MultiThreaded Version 1.64 Windows Built 2001"
 
char iniFile [_MAX_PATH]
 
char logFile [_MAX_PATH]
 
char lnkFile [_MAX_PATH]
 
char tempbuff [256]
 
char extbuff [_MAX_PATH]
 
char logBuff [512]
 
char fileSep = '\\'
 
char notFileSep = '/'
 
MYWORD blksize = 65464
 
char verbatim = 0
 
MYWORD timeout = 3
 
MYWORD loggingDay
 
data1 network
 
data1 newNetwork
 
data2 cfig
 
HANDLE tEvent
 
HANDLE cEvent
 
HANDLE sEvent
 
HANDLE lEvent
 
MYBYTE currentServer = UCHAR_MAX
 
MYWORD totalThreads =0
 
MYWORD minThreads =1
 
MYWORD activeThreads =0
 
SERVICE_STATUS serviceStatus
 
SERVICE_STATUS_HANDLE serviceStatusHandle = 0
 
HANDLE stopServiceEvent = 0
 

Function Documentation

◆ addServer()

bool addServer ( MYDWORD array,
MYDWORD  ip 
)

Definition at line 2557 of file tftpd.cpp.

Referenced by getInterfaces().

2558 {
2559  for (MYBYTE i = 0; i < MAX_SERVERS; i++)
2560  {
2561  if (!ip || array[i] == ip)
2562  return 0;
2563  else if (!array[i])
2564  {
2565  array[i] = ip;
2566  return 1;
2567  }
2568  }
2569  return 0;
2570 }
GLenum GLclampf GLint i
Definition: glfuncs.h:14
int ip[4]
Definition: rtl.c:1176
#define MYBYTE
Definition: tftpd.h:21
Definition: dhcpd.h:61
#define MAX_SERVERS
Definition: tftpd.h:34

◆ cleanReq()

bool cleanReq ( request req)

Definition at line 1505 of file tftpd.cpp.

Referenced by processRequest().

1506 {
1507  //printf("cleaning\n");
1508 
1509  if (req->file)
1510  fclose(req->file);
1511 
1512  if (!(req->sock == INVALID_SOCKET))
1513  {
1514  //printf("Here\n");
1515  closesocket(req->sock);
1516  }
1517 
1518  if (req->pkt[0])
1519  free(req->pkt[0]);
1520 
1521  if (req->pkt[1])
1522  free(req->pkt[1]);
1523 
1525  activeThreads--;
1526  SetEvent(cEvent);
1527 
1528  //printf("cleaned\n");
1529 
1530  return (totalThreads <= minThreads);
1531 }
#define free
Definition: debug_ros.c:5
HANDLE cEvent
Definition: tftpd.cpp:54
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define closesocket
Definition: main.c:39
SOCKET sock
Definition: tftpd.h:90
#define INVALID_SOCKET
Definition: winsock.h:332
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
packet * pkt[2]
Definition: tftpd.h:104
MYWORD totalThreads
Definition: tftpd.cpp:58
MYWORD minThreads
Definition: tftpd.cpp:59
MYWORD activeThreads
Definition: tftpd.cpp:60
FILE * file
Definition: tftpd.h:95
#define INFINITE
Definition: serial.h:102

◆ closeConn()

void closeConn ( )

Definition at line 481 of file tftpd.cpp.

Referenced by init(), runProg(), and ServiceMain().

482 {
483  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].loaded; i++)
484  if (network.tftpConn[i].ready)
486 }
bool loaded
Definition: tftpd.h:49
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define closesocket
Definition: main.c:39
data1 network
Definition: tftpd.cpp:49
bool ready
Definition: tftpd.h:50
SOCKET sock
Definition: tftpd.h:45
#define MAX_SERVERS
Definition: tftpd.h:34
tftpConnType tftpConn[MAX_SERVERS]
Definition: tftpd.h:127

◆ detectChange()

bool detectChange ( )

Definition at line 2428 of file tftpd.cpp.

Referenced by init().

2429 {
2430  if (!cfig.failureCount)
2431  {
2432  if (cfig.ifspecified)
2433  return false;
2434  }
2435 
2436  MYDWORD eventWait = UINT_MAX;
2437 
2438  if (cfig.failureCount)
2439 #ifdef __REACTOS__
2440  eventWait = 10000 * (1 << cfig.failureCount);
2441 #else
2442  eventWait = 10000 * pow(2, cfig.failureCount);
2443 #endif
2444 
2445  OVERLAPPED overlap;
2446  MYDWORD ret;
2447  HANDLE hand = NULL;
2448  overlap.hEvent = WSACreateEvent();
2449 
2450  ret = NotifyAddrChange(&hand, &overlap);
2451 
2452  if (ret != NO_ERROR)
2453  {
2455  {
2456  printf("NotifyAddrChange error...%d\n", WSAGetLastError());
2457  return true;
2458  }
2459  }
2460 
2461  if ( WaitForSingleObject(overlap.hEvent, eventWait) == WAIT_OBJECT_0 )
2462  WSACloseEvent(overlap.hEvent);
2463 
2464  network.ready = false;
2465 
2466  while (network.busy)
2467  Sleep(1000);
2468 
2469  if (cfig.failureCount)
2470  {
2471  sprintf(logBuff, "Retrying failed Listening Interfaces..");
2472  logMess(logBuff, 1);
2473  }
2474  else
2475  {
2476  sprintf(logBuff, "Network changed, re-detecting Interfaces..");
2477  logMess(logBuff, 1);
2478  }
2479 
2480  return true;
2481 }
data2 cfig
Definition: tftpd.cpp:51
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
bool ifspecified
Definition: tftpd.h:154
char logBuff[512]
Definition: tftpd.cpp:42
bool busy
Definition: tftpd.h:134
#define NO_ERROR
Definition: dderror.h:5
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
float pow(float __x, int __y)
Definition: _cmath.h:458
HANDLE hEvent
Definition: winbase.h:792
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
smooth NULL
Definition: ftsmooth.c:416
#define WSA_IO_PENDING
Definition: winsock2.h:589
bool ready
Definition: tftpd.h:133
data1 network
Definition: tftpd.cpp:49
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
#define WAIT_OBJECT_0
Definition: winbase.h:387
int ret
MYDWORD failureCount
Definition: tftpd.h:152
DWORD WINAPI NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped)
#define UINT_MAX
Definition: limits.h:41
WSAEVENT WSAAPI WSACreateEvent(VOID)
Definition: event.c:42
#define MYDWORD
Definition: tftpd.h:23
void logMess(char *logBuff, MYBYTE logLevel)
Definition: tftpd.cpp:2585
#define printf
Definition: config.h:203

◆ findServer()

MYDWORD* findServer ( MYDWORD array,
MYDWORD  ip 
)

Definition at line 2572 of file tftpd.cpp.

Referenced by init().

2573 {
2574  if (ip)
2575  {
2576  for (MYBYTE i = 0; i < MAX_SERVERS && array[i]; i++)
2577  {
2578  if (array[i] == ip)
2579  return &(array[i]);
2580  }
2581  }
2582  return 0;
2583 }
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define MYBYTE
Definition: tftpd.h:21
Definition: dhcpd.h:61
#define MAX_SERVERS
Definition: tftpd.h:34

◆ getInterfaces()

void getInterfaces ( data1 network)

Definition at line 2519 of file tftpd.cpp.

Referenced by init().

2520 {
2521  memset(network, 0, sizeof(data1));
2522 
2523  SOCKET sd = WSASocket(PF_INET, SOCK_DGRAM, 0, 0, 0, 0);
2524 
2525  if (sd == INVALID_SOCKET)
2526  return;
2527 
2529  unsigned long nBytesReturned;
2530 
2531  if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
2532  sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR)
2533  return ;
2534 
2535  int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
2536 
2537  for (int i = 0; i < nNumInterfaces; ++i)
2538  {
2539  sockaddr_in *pAddress = (sockaddr_in*)&(InterfaceList[i].iiAddress);
2540  u_long nFlags = InterfaceList[i].iiFlags;
2541 
2542  if (pAddress->sin_addr.s_addr)
2543  {
2544  addServer(network->allServers, pAddress->sin_addr.s_addr);
2545 
2546  if (!(nFlags & IFF_POINTTOPOINT) && (nFlags & IFF_UP))
2547  {
2548  addServer(network->staticServers, pAddress->sin_addr.s_addr);
2549  }
2550  }
2551  }
2552 
2553  closesocket(sd);
2554 }
#define SOCKET_ERROR
Definition: winsock.h:333
return
Definition: dirsup.c:529
struct _INTERFACE_INFO INTERFACE_INFO
unsigned long u_long
Definition: linux.h:269
#define IFF_UP
Definition: ws2ipdef.h:21
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:168
MYDWORD staticServers[MAX_SERVERS]
Definition: tftpd.h:129
Definition: tftpd.h:125
INT WSAAPI WSAIoctl(IN SOCKET s, IN DWORD dwIoControlCode, IN LPVOID lpvInBuffer, IN DWORD cbInBuffer, OUT LPVOID lpvOutBuffer, IN DWORD cbOutBuffer, OUT LPDWORD lpcbBytesReturned, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
Definition: ioctl.c:46
bool addServer(MYDWORD *array, MYDWORD ip)
Definition: tftpd.cpp:2557
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define closesocket
Definition: main.c:39
#define PF_INET
Definition: winsock.h:373
#define INVALID_SOCKET
Definition: winsock.h:332
#define WSASocket
Definition: winsock2.h:2407
#define IFF_POINTTOPOINT
Definition: ws2ipdef.h:24
static const WCHAR sd[]
Definition: suminfo.c:287
MYDWORD allServers[MAX_SERVERS]
Definition: tftpd.h:128
struct in_addr sin_addr
Definition: winsock.h:512
#define MAX_SERVERS
Definition: tftpd.h:34
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCK_DGRAM
Definition: winsock.h:336
#define SIO_GET_INTERFACE_LIST
Definition: ws2ipdef.h:62
#define memset(x, y, z)
Definition: compat.h:39

◆ getSection()

bool getSection ( const char sectionName,
char buffer,
MYBYTE  serial,
char fileName 
)

Definition at line 1533 of file tftpd.cpp.

1534 {
1535  //printf("%s=%s\n",fileName,sectionName);
1536  char section[128];
1537  sprintf(section, "[%s]", sectionName);
1538  myUpper(section);
1539  FILE *f = fopen(fileName, "rt");
1540  char buff[512];
1541  MYBYTE found = 0;
1542 
1543  if (f)
1544  {
1545  while (fgets(buff, 511, f))
1546  {
1547  myUpper(buff);
1548  myTrim(buff, buff);
1549 
1550  if (strstr(buff, section) == buff)
1551  {
1552  found++;
1553  if (found == serial)
1554  {
1555  //printf("%s=%s\n",fileName,sectionName);
1556  while (fgets(buff, 511, f))
1557  {
1558  myTrim(buff, buff);
1559 
1560  if (strstr(buff, "[") == buff)
1561  break;
1562 
1563  if (((*buff) >= '0' && (*buff) <= '9') || ((*buff) >= 'A' && (*buff) <= 'Z') || ((*buff) >= 'a' && (*buff) <= 'z') || ((*buff) && strchr("/\\?*", (*buff))))
1564  {
1565  buffer += sprintf(buffer, "%s", buff);
1566  buffer++;
1567  }
1568  }
1569  break;
1570  }
1571  }
1572  }
1573  fclose(f);
1574  }
1575 
1576  *buffer = 0;
1577  *(buffer + 1) = 0;
1578  return (found == serial);
1579 }
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
GLuint buffer
Definition: glext.h:5915
Definition: parser.c:55
char * myUpper(char *string)
Definition: tftpd.cpp:1785
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLfloat f
Definition: glext.h:7540
#define MYBYTE
Definition: tftpd.h:21
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
uint32_t serial
Definition: fsck.fat.h:64
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * myTrim(char *target, char *source)
Definition: tftpd.cpp:1689
static unsigned char buff[32768]
Definition: fatten.c:17

◆ init()

void init ( void lpParam)

Definition at line 1805 of file tftpd.cpp.

Referenced by runProg(), and ServiceMain().

1806 {
1807  memset(&cfig, 0, sizeof(cfig));
1808 
1810  char *fileExt = strrchr(extbuff, '.');
1811  *fileExt = 0;
1812  sprintf(iniFile, "%s.ini", extbuff);
1813  sprintf(lnkFile, "%s.url", extbuff);
1814  fileExt = strrchr(extbuff, '\\');
1815  *fileExt = 0;
1816  fileExt++;
1817  sprintf(logFile, "%s\\log\\%s%%Y%%m%%d.log", extbuff, fileExt);
1818 
1819  FILE *f = NULL;
1820  char raw[512];
1821  char name[512];
1822  char value[512];
1823 
1824  if (verbatim)
1825  {
1826  cfig.logLevel = 2;
1827  printf("%s\n\n", sVersion);
1828  }
1829  else if ((f = openSection("LOGGING", 1, iniFile)))
1830  {
1831  cfig.logLevel = 1;
1832  tempbuff[0] = 0;
1833 
1834  while (readSection(raw, f))
1835  {
1836  if (!strcasecmp(raw, "None"))
1837  cfig.logLevel = 0;
1838  else if (!strcasecmp(raw, "Errors"))
1839  cfig.logLevel = 1;
1840  else if (!strcasecmp(raw, "All"))
1841  cfig.logLevel = 2;
1842  else
1843  sprintf(tempbuff, "Section [LOGGING], Invalid LogLevel: %s", raw);
1844  }
1845  }
1846 
1847  if (!verbatim && cfig.logLevel && logFile[0])
1848  {
1849  time_t t = time(NULL);
1850  tm *ttm = localtime(&t);
1851  loggingDay = ttm->tm_yday;
1852  strftime(extbuff, sizeof(extbuff), logFile, ttm);
1853 
1854  cfig.logfile = fopen(extbuff, "at");
1855 
1856  if (cfig.logfile)
1857  {
1858  WritePrivateProfileString("InternetShortcut","URL", extbuff, lnkFile);
1859  WritePrivateProfileString("InternetShortcut","IconIndex", "0", lnkFile);
1860  WritePrivateProfileString("InternetShortcut","IconFile", extbuff, lnkFile);
1861  sprintf(logBuff, "%s Starting..", sVersion);
1862  logMess(logBuff, 1);
1863 
1864  if (tempbuff[0])
1865  logMess(tempbuff, 0);
1866  }
1867  }
1868 
1869  MYWORD wVersionRequested = MAKEWORD(1, 1);
1870  WSAStartup(wVersionRequested, &cfig.wsaData);
1871 
1872  if (cfig.wsaData.wVersion != wVersionRequested)
1873  {
1874  sprintf(logBuff, "WSAStartup Error");
1875  logMess(logBuff, 1);
1876  }
1877 
1878  if ((f = openSection("HOME", 1, iniFile)))
1879  {
1880  while (readSection(raw, f))
1881  {
1882  mySplit(name, value, raw, '=');
1883 
1884  if (strlen(value))
1885  {
1886  if (!cfig.homes[0].alias[0] && cfig.homes[0].target[0])
1887  {
1888  sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", raw);
1889  logMess(logBuff, 1);
1890  }
1891  else if (strchr(name, notFileSep) || strchr(name, fileSep) || strchr(name, '>') || strchr(name, '<') || strchr(name, '.'))
1892  {
1893  sprintf(logBuff, "Section [HOME], invalid chars in alias %s, entry ignored", name);
1894  logMess(logBuff, 1);
1895  }
1896  else if (name[0] && strlen(name) < 64 && value[0])
1897  {
1898 #ifdef __REACTOS__
1899  for (int i = 0; i < MAX_SERVERS; i++)
1900 #else
1901  for (int i = 0; i < 8; i++)
1902 #endif
1903  {
1904  if (cfig.homes[i].alias[0] && !strcasecmp(name, cfig.homes[i].alias))
1905  {
1906  sprintf(logBuff, "Section [HOME], Duplicate Entry: %s ignored", raw);
1907  logMess(logBuff, 1);
1908  break;
1909  }
1910  else if (!cfig.homes[i].alias[0])
1911  {
1912  strcpy(cfig.homes[i].alias, name);
1913  strcpy(cfig.homes[i].target, value);
1914 
1915  if (cfig.homes[i].target[strlen(cfig.homes[i].target) - 1] != fileSep)
1916  {
1917  tempbuff[0] = fileSep;
1918  tempbuff[1] = 0;
1920  }
1921 
1922  break;
1923  }
1924  }
1925  }
1926  else
1927  {
1928  sprintf(logBuff, "Section [HOME], alias %s too large", name);
1929  logMess(logBuff, 1);
1930  }
1931  }
1932  else if (!cfig.homes[0].alias[0] && !cfig.homes[0].target[0])
1933  {
1934  strcpy(cfig.homes[0].target, name);
1935 
1936  if (cfig.homes[0].target[strlen(cfig.homes[0].target) - 1] != fileSep)
1937  {
1938  tempbuff[0] = fileSep;
1939  tempbuff[1] = 0;
1941  }
1942  }
1943  else if (cfig.homes[0].alias[0])
1944  {
1945  sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", raw);
1946  logMess(logBuff, 1);
1947  }
1948  else if (cfig.homes[0].target[0])
1949  {
1950  sprintf(logBuff, "Section [HOME], Duplicate Path: %s ignored", raw);
1951  logMess(logBuff, 1);
1952  }
1953  else
1954  {
1955  sprintf(logBuff, "Section [HOME], missing = sign, Invalid Entry: %s ignored", raw);
1956  logMess(logBuff, 1);
1957  }
1958  }
1959  }
1960 
1961  if (!cfig.homes[0].target[0])
1962  {
1964  char *iniFileExt = strrchr(cfig.homes[0].target, fileSep);
1965  *(++iniFileExt) = 0;
1966  }
1967 
1968  cfig.fileRead = true;
1969 
1970  if ((f = openSection("TFTP-OPTIONS", 1, iniFile)))
1971  {
1972  while (readSection(raw, f))
1973  {
1974  mySplit(name, value, raw, '=');
1975 
1976  if (strlen(value))
1977  {
1978  if (!strcasecmp(name, "blksize"))
1979  {
1980  MYDWORD tblksize = atol(value);
1981 
1982  if (tblksize < 512)
1983  blksize = 512;
1984  else if (tblksize > USHRT_MAX - 32)
1985  blksize = USHRT_MAX - 32;
1986  else
1987  blksize = tblksize;
1988  }
1989  else if (!strcasecmp(name, "threadpoolsize"))
1990  {
1991  minThreads = atol(value);
1992  if (minThreads < 1)
1993  minThreads = 0;
1994  else if (minThreads > 100)
1995  minThreads = 100;
1996  }
1997  else if (!strcasecmp(name, "timeout"))
1998  {
1999  timeout = atol(value);
2000  if (timeout < 1)
2001  timeout = 1;
2002  else if (timeout > UCHAR_MAX)
2003  timeout = UCHAR_MAX;
2004  }
2005  else if (!strcasecmp(name, "Read"))
2006  {
2007  if (strchr("Yy", *value))
2008  cfig.fileRead = true;
2009  else
2010  cfig.fileRead = false;
2011  }
2012  else if (!strcasecmp(name, "Write"))
2013  {
2014  if (strchr("Yy", *value))
2015  cfig.fileWrite = true;
2016  else
2017  cfig.fileWrite = false;
2018  }
2019  else if (!strcasecmp(name, "Overwrite"))
2020  {
2021  if (strchr("Yy", *value))
2022  cfig.fileOverwrite = true;
2023  else
2024  cfig.fileOverwrite = false;
2025  }
2026  else if (!strcasecmp(name, "port-range"))
2027  {
2028  char *ptr = strchr(value, '-');
2029  if (ptr)
2030  {
2031  *ptr = 0;
2032  cfig.minport = atol(value);
2033  cfig.maxport = atol(++ptr);
2034 
2035  if (cfig.minport < 1024 || cfig.minport >= USHRT_MAX || cfig.maxport < 1024 || cfig.maxport >= USHRT_MAX || cfig.minport > cfig.maxport)
2036  {
2037  cfig.minport = 0;
2038  cfig.maxport = 0;
2039 
2040  sprintf(logBuff, "Invalid port range %s", value);
2041  logMess(logBuff, 1);
2042  }
2043  }
2044  else
2045  {
2046  sprintf(logBuff, "Invalid port range %s", value);
2047  logMess(logBuff, 1);
2048  }
2049  }
2050  else
2051  {
2052  sprintf(logBuff, "Warning: unknown option %s, ignored", name);
2053  logMess(logBuff, 1);
2054  }
2055  }
2056  }
2057  }
2058 
2059  if ((f = openSection("ALLOWED-CLIENTS", 1, iniFile)))
2060  {
2061 #ifdef __REACTOS__
2062  MYWORD i = 0;
2063 #else
2064  int i = 0;
2065 #endif
2066 
2067  while (readSection(raw, f))
2068  {
2069 #ifdef __REACTOS__
2070  if (i < _countof(cfig.hostRanges))
2071 #else
2072  if (i < 32)
2073 #endif
2074  {
2075  MYDWORD rs = 0;
2076  MYDWORD re = 0;
2077  mySplit(name, value, raw, '-');
2078  rs = htonl(my_inet_addr(name));
2079 
2080  if (strlen(value))
2081  re = htonl(my_inet_addr(value));
2082  else
2083  re = rs;
2084 
2085  if (rs && rs != INADDR_NONE && re && re != INADDR_NONE && rs <= re)
2086  {
2087  cfig.hostRanges[i].rangeStart = rs;
2088  cfig.hostRanges[i].rangeEnd = re;
2089  i++;
2090  }
2091  else
2092  {
2093  sprintf(logBuff, "Section [ALLOWED-CLIENTS] Invalid entry %s in ini file, ignored", raw);
2094  logMess(logBuff, 1);
2095  }
2096  }
2097  }
2098  }
2099 
2100  if (verbatim)
2101  {
2102  printf("starting TFTP...\n");
2103  }
2104  else
2105  {
2106  sprintf(logBuff, "starting TFTP service");
2107  logMess(logBuff, 1);
2108  }
2109 
2110  for (int i = 0; i < MAX_SERVERS; i++)
2111  if (cfig.homes[i].target[0])
2112  {
2113  sprintf(logBuff, "alias /%s is mapped to %s", cfig.homes[i].alias, cfig.homes[i].target);
2114  logMess(logBuff, 1);
2115  }
2116 
2117  if (cfig.hostRanges[0].rangeStart)
2118  {
2119  char temp[128];
2120 
2121 #ifdef __REACTOS__
2122  for (MYWORD i = 0; i < _countof(cfig.hostRanges) && cfig.hostRanges[i].rangeStart; i++)
2123 #else
2124  for (MYWORD i = 0; i <= sizeof(cfig.hostRanges) && cfig.hostRanges[i].rangeStart; i++)
2125 #endif
2126  {
2127  sprintf(logBuff, "%s", "permitted clients: ");
2129  strcat(logBuff, temp);
2130  sprintf(temp, "%s", IP2String(tempbuff, htonl(cfig.hostRanges[i].rangeEnd)));
2131  strcat(logBuff, temp);
2132  logMess(logBuff, 1);
2133  }
2134  }
2135  else
2136  {
2137  sprintf(logBuff, "%s", "permitted clients: all");
2138  logMess(logBuff, 1);
2139  }
2140 
2141  if (cfig.minport)
2142  {
2143  sprintf(logBuff, "server port range: %u-%u", cfig.minport, cfig.maxport);
2144  logMess(logBuff, 1);
2145  }
2146  else
2147  {
2148  sprintf(logBuff, "server port range: all");
2149  logMess(logBuff, 1);
2150  }
2151 
2152  sprintf(logBuff, "max blksize: %u", blksize);
2153  logMess(logBuff, 1);
2154  sprintf(logBuff, "default blksize: %u", 512);
2155  logMess(logBuff, 1);
2156  sprintf(logBuff, "default timeout: %u", timeout);
2157  logMess(logBuff, 1);
2158  sprintf(logBuff, "file read allowed: %s", cfig.fileRead ? "Yes" : "No");
2159  logMess(logBuff, 1);
2160  sprintf(logBuff, "file create allowed: %s", cfig.fileWrite ? "Yes" : "No");
2161  logMess(logBuff, 1);
2162  sprintf(logBuff, "file overwrite allowed: %s", cfig.fileOverwrite ? "Yes" : "No");
2163  logMess(logBuff, 1);
2164 
2165  if (!verbatim)
2166  {
2167  sprintf(logBuff, "logging: %s", cfig.logLevel > 1 ? "all" : "errors");
2168  logMess(logBuff, 1);
2169  }
2170 
2171  lEvent = CreateEvent(
2172  NULL, // default security descriptor
2173  FALSE, // ManualReset
2174  TRUE, // Signalled
2175  TEXT("AchalTFTServerLogEvent")); // object name
2176 
2177  if (lEvent == NULL)
2178  {
2179  printf("CreateEvent error: %lu\n", GetLastError());
2180  exit(-1);
2181  }
2182  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2183  {
2184  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2185  logMess(logBuff, 0);
2186  exit(-1);
2187  }
2188 
2189  tEvent = CreateEvent(
2190  NULL, // default security descriptor
2191  FALSE, // ManualReset
2192  FALSE, // Signalled
2193  TEXT("AchalTFTServerThreadEvent")); // object name
2194 
2195  if (tEvent == NULL)
2196  {
2197  printf("CreateEvent error: %lu\n", GetLastError());
2198  exit(-1);
2199  }
2200  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2201  {
2202  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2203  logMess(logBuff, 0);
2204  exit(-1);
2205  }
2206 
2207  sEvent = CreateEvent(
2208  NULL, // default security descriptor
2209  FALSE, // ManualReset
2210  TRUE, // Signalled
2211  TEXT("AchalTFTServerSocketEvent")); // object name
2212 
2213  if (sEvent == NULL)
2214  {
2215  printf("CreateEvent error: %lu\n", GetLastError());
2216  exit(-1);
2217  }
2218  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2219  {
2220  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2221  logMess(logBuff, 0);
2222  exit(-1);
2223  }
2224 
2225  cEvent = CreateEvent(
2226  NULL, // default security descriptor
2227  FALSE, // ManualReset
2228  TRUE, // Signalled
2229  TEXT("AchalTFTServerCountEvent")); // object name
2230 
2231  if (cEvent == NULL)
2232  {
2233  printf("CreateEvent error: %lu\n", GetLastError());
2234  exit(-1);
2235  }
2236  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2237  {
2238  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2239  logMess(logBuff, 0);
2240  exit(-1);
2241  }
2242 
2243  if (minThreads)
2244  {
2245  for (int i = 0; i < minThreads; i++)
2246  {
2247  _beginthread(
2248  processRequest, // thread function
2249  0, // default security attributes
2250  NULL); // argument to thread function
2251  }
2252 
2253  sprintf(logBuff, "thread pool size: %u", minThreads);
2254  logMess(logBuff, 1);
2255  }
2256 
2257  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].port; i++)
2258  {
2259  sprintf(logBuff, "listening on: %s:%i", IP2String(tempbuff, network.tftpConn[i].server), network.tftpConn[i].port);
2260  logMess(logBuff, 1);
2261  }
2262 
2263  do
2264  {
2265  memset(&newNetwork, 0, sizeof(data1));
2266 
2267  bool bindfailed = false;
2268 
2269  if ((f = openSection("LISTEN-ON", 1, iniFile)))
2270  {
2271  MYBYTE i = 0;
2272 
2273  while (readSection(raw, f))
2274  {
2275  MYWORD port = 69;
2276 
2277  cfig.ifspecified = true;
2278  mySplit(name, value, raw, ':');
2279 
2280  if (value[0])
2281  port = atoi(value);
2282 
2283  if(i < MAX_SERVERS)
2284  {
2285  if (isIP(name))
2286  {
2287  MYDWORD addr = my_inet_addr(name);
2288 
2289  if (!addr)
2290  {
2291  newNetwork.listenServers[0] = 0;
2293  fclose(f);
2294  break;
2295  }
2296  else if (!findServer(newNetwork.listenServers, addr))
2297  {
2300  i++;
2301  }
2302  }
2303  else
2304  {
2305  sprintf(logBuff, "Warning: Section [LISTEN-ON], Invalid Interface Address %s, ignored", raw);
2306  logMess(logBuff, 1);
2307  }
2308  }
2309  }
2310  }
2311 
2312  if (!cfig.ifspecified)
2313  {
2314  sprintf(logBuff, "detecting Interfaces..");
2315  logMess(logBuff, 1);
2317 
2318  for (MYBYTE n = 0; n < MAX_SERVERS && newNetwork.staticServers[n]; n++)
2319  {
2321  newNetwork.listenPorts[n] = 69;
2322  }
2323  }
2324 
2325  MYBYTE i = 0;
2326 
2327  for (int j = 0; j < MAX_SERVERS && newNetwork.listenPorts[j]; j++)
2328  {
2329  int k = 0;
2330 
2331  for (; k < MAX_SERVERS && network.tftpConn[k].loaded; k++)
2332  {
2334  break;
2335  }
2336 
2338  {
2339  memcpy(&(newNetwork.tftpConn[i]), &(network.tftpConn[k]), sizeof(tftpConnType));
2340 
2343 
2344  network.tftpConn[k].ready = false;
2345  //printf("%d, %s found\n", i, IP2String(tempbuff, newNetwork.tftpConn[i].server));
2346  i++;
2347  continue;
2348  }
2349  else
2350  {
2352 
2354  {
2355  bindfailed = true;
2356  sprintf(logBuff, "Failed to Create Socket");
2357  logMess(logBuff, 1);
2358  continue;
2359  }
2360 
2361  //printf("Socket %u\n", newNetwork.tftpConn[i].sock);
2362 
2363  errno = 0;
2367  int nRet = bind(newNetwork.tftpConn[i].sock, (sockaddr*)&newNetwork.tftpConn[i].addr, sizeof(struct sockaddr_in));
2368 
2369  if (nRet == SOCKET_ERROR || errno)
2370  {
2371  bindfailed = true;
2374  logMess(logBuff, 1);
2375  continue;
2376  }
2377 
2378  newNetwork.tftpConn[i].loaded = true;
2379  newNetwork.tftpConn[i].ready = true;
2382 
2383  //printf("%d, %s created\n", i, IP2String(tempbuff, newNetwork.tftpConn[i].server));
2384 
2387 
2388  if (!newNetwork.listenServers[j])
2389  break;
2390 
2391  i++;
2392  }
2393  }
2394 
2395  if (bindfailed)
2396  cfig.failureCount++;
2397  else
2398  cfig.failureCount = 0;
2399 
2400  closeConn();
2401  memcpy(&network, &newNetwork, sizeof(data1));
2402 
2403  //printf("%i %i %i\n", network.tftpConn[0].ready, network.dnsUdpConn[0].ready, network.dnsTcpConn[0].ready);
2404 
2405  if (!network.tftpConn[0].ready)
2406  {
2407  sprintf(logBuff, "No Static Interface ready, Waiting...");
2408  logMess(logBuff, 1);
2409  continue;
2410  }
2411 
2412  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].loaded; i++)
2413  {
2414  sprintf(logBuff, "Listening On: %s:%d", IP2String(tempbuff, network.tftpConn[i].server), network.tftpConn[i].port);
2415  logMess(logBuff, 1);
2416  }
2417 
2418  network.ready = true;
2419 
2420  } while (detectChange());
2421 
2422  //printf("Exiting Init\n");
2423 
2424  _endthread();
2425  return;
2426 }
#define CreateEvent
Definition: winbase.h:3562
int maxport
Definition: tftpd.h:151
#define SOCKET_ERROR
Definition: winsock.h:333
data2 cfig
Definition: tftpd.cpp:51
MYWORD listenPorts[MAX_SERVERS]
Definition: tftpd.h:131
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
Definition: get.c:139
#define TRUE
Definition: types.h:120
bool ifspecified
Definition: tftpd.h:154
_CRTIMP void __cdecl _endthread(void)
Definition: thread.c:95
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
char * readSection(char *buff, FILE *f)
Definition: tftpd.cpp:1611
char notFileSep
Definition: tftpd.cpp:44
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define strcasecmp
Definition: fake.h:9
FILE * logfile
Definition: tftpd.h:145
#define htonl(x)
Definition: module.h:212
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MAKEWORD(a, b)
Definition: typedefs.h:247
char sVersion[]
Definition: tftpd.cpp:36
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
char fileSep
Definition: tftpd.cpp:43
bool loaded
Definition: tftpd.h:49
WORD wVersion
Definition: winsock.h:517
#define _countof(array)
Definition: fontsub.cpp:30
#define INADDR_NONE
Definition: tcp.c:42
HANDLE cEvent
Definition: tftpd.cpp:54
MYDWORD staticServers[MAX_SERVERS]
Definition: tftpd.h:129
char logBuff[512]
Definition: tftpd.cpp:42
#define MYWORD
Definition: tftpd.h:22
GLdouble GLdouble t
Definition: gl.h:2047
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
Definition: tftpd.h:125
Definition: dhcpd.h:245
int errno
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
__u16 time
Definition: mkdosfs.c:366
char tempbuff[256]
Definition: tftpd.cpp:40
char alias[64]
Definition: tftpd.h:39
#define USHRT_MAX
Definition: limits.h:38
#define sprintf(buf, format,...)
Definition: sprintf.c:55
GLuint n
Definition: s_context.h:57
bool detectChange()
Definition: tftpd.cpp:2428
GLenum GLclampf GLint i
Definition: glfuncs.h:14
SOCKET maxFD
Definition: tftpd.h:132
#define closesocket
Definition: main.c:39
#define _MAX_PATH
Definition: utility.h:77
static PVOID ptr
Definition: dispmode.c:27
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
MYDWORD rangeStart
Definition: tftpd.h:81
bool ready
Definition: tftpd.h:133
char logFile[_MAX_PATH]
Definition: tftpd.cpp:38
#define PF_INET
Definition: winsock.h:373
data1 network
Definition: tftpd.cpp:49
bool ready
Definition: tftpd.h:50
MYDWORD rangeEnd
Definition: tftpd.h:82
char target[256]
Definition: tftpd.h:40
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
void processRequest(void *lpParam)
Definition: tftpd.cpp:488
GLfloat f
Definition: glext.h:7540
#define MYBYTE
Definition: tftpd.h:21
#define INVALID_SOCKET
Definition: winsock.h:332
char iniFile[_MAX_PATH]
Definition: tftpd.cpp:37
char lnkFile[_MAX_PATH]
Definition: tftpd.cpp:39
data12 hostRanges[32]
Definition: tftpd.h:146
home homes[8]
Definition: tftpd.h:143
void getInterfaces(data1 *network)
Definition: tftpd.cpp:2519
WSADATA wsaData
Definition: tftpd.h:139
char fileWrite
Definition: tftpd.h:148
#define GetModuleFileName
Definition: winbase.h:3645
MYDWORD server
Definition: tftpd.h:47
MYDWORD listenServers[MAX_SERVERS]
Definition: tftpd.h:130
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
SOCKET sock
Definition: tftpd.h:45
GLenum const GLvoid * addr
Definition: glext.h:9621
MYWORD loggingDay
Definition: tftpd.cpp:48
HANDLE lEvent
Definition: tftpd.cpp:56
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
MYDWORD failureCount
Definition: tftpd.h:152
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
static stack_node_t temp
Definition: rpn.c:18
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
Definition: time.h:76
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:426
HANDLE tEvent
Definition: tftpd.cpp:53
MYDWORD * findServer(MYDWORD *array, MYDWORD ip)
Definition: tftpd.cpp:2572
#define my_inet_addr
Definition: tftpd.h:33
struct in_addr sin_addr
Definition: winsock.h:512
char fileOverwrite
Definition: tftpd.h:149
char verbatim
Definition: tftpd.cpp:46
int tm_yday
Definition: time.h:84
MYBYTE logLevel
Definition: tftpd.h:153
void mySplit(char *name, char *value, char *source, char splitChar)
Definition: tftpd.cpp:1730
MYWORD blksize
Definition: tftpd.cpp:45
sockaddr_in addr
Definition: tftpd.h:46
#define TEXT(s)
Definition: k32.h:26
FILE * openSection(const char *sectionName, MYBYTE serial, char *fileName)
Definition: tftpd.cpp:1581
__kernel_time_t time_t
Definition: linux.h:252
#define MAX_SERVERS
Definition: tftpd.h:34
#define UCHAR_MAX
Definition: limits.h:25
MYWORD port
Definition: tftpd.h:48
HANDLE sEvent
Definition: tftpd.cpp:55
MYWORD minThreads
Definition: tftpd.cpp:59
char * strchr(const char *String, int ch)
Definition: utclib.c:501
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
char extbuff[_MAX_PATH]
Definition: tftpd.cpp:41
Definition: name.c:36
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define AF_INET
Definition: tcpip.h:117
char fileRead
Definition: tftpd.h:147
data1 newNetwork
Definition: tftpd.cpp:50
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
void exit(int exitcode)
Definition: _exit.c:33
char * IP2String(char *target, MYDWORD ip)
Definition: tftpd.cpp:1759
#define htons(x)
Definition: module.h:213
#define SOCK_DGRAM
Definition: winsock.h:336
tftpConnType tftpConn[MAX_SERVERS]
Definition: tftpd.h:127
USHORT port
Definition: uri.c:227
#define memset(x, y, z)
Definition: compat.h:39
#define MYDWORD
Definition: tftpd.h:23
int minport
Definition: tftpd.h:150
int k
Definition: mpi.c:3369
bool isIP(char *string)
Definition: tftpd.cpp:1767
short sin_family
Definition: winsock.h:510
void logMess(char *logBuff, MYBYTE logLevel)
Definition: tftpd.cpp:2585
#define printf
Definition: config.h:203
void closeConn()
Definition: tftpd.cpp:481
#define WritePrivateProfileString
Definition: winbase.h:3737

◆ installService()

void installService ( )

Definition at line 256 of file tftpd.cpp.

Referenced by main().

257 {
258  SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
259 
260  if (serviceControlManager)
261  {
262  SC_HANDLE service = OpenService(serviceControlManager,
264  if (service)
265  {
266  printf("Service Already Exists..\n");
267  StartService(service,0,NULL);
268  CloseServiceHandle(service);
269  }
270  else
271  {
272  TCHAR path[ _MAX_PATH + 1 ];
273  if (GetModuleFileName(0, path, sizeof(path) / sizeof(path[0])) > 0)
274  {
275  SC_HANDLE service = CreateService(serviceControlManager,
279  0, 0, 0, 0, 0);
280  if (service)
281  {
282  printf("Successfully installed.. !\n");
283  StartService(service,0,NULL);
284  CloseServiceHandle(service);
285  }
286  else
287  printf("Installation Failed..\n");
288  }
289  }
290  CloseServiceHandle(serviceControlManager);
291  }
292  else
294 }
#define StartService
Definition: winsvc.h:585
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:979
#define SERVICE_ALL_ACCESS
Definition: winsvc.h:62
char displayName[]
Definition: tftpd.cpp:35
#define CreateService
Definition: winsvc.h:569
#define OpenService
Definition: winsvc.h:576
void printWindowsError()
Definition: tftpd.cpp:323
#define _MAX_PATH
Definition: utility.h:77
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:576
smooth NULL
Definition: ftsmooth.c:416
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:960
char serviceName[]
Definition: tftpd.cpp:34
char TCHAR
Definition: xmlstorage.h:189
#define OpenSCManager
Definition: winsvc.h:575
#define GetModuleFileName
Definition: winbase.h:3645
Definition: services.c:325
#define SERVICE_AUTO_START
Definition: cmtypes.h:975
#define printf
Definition: config.h:203

◆ IP2String()

char* IP2String ( char target,
MYDWORD  ip 
)

Definition at line 1759 of file tftpd.cpp.

Referenced by init(), and logMess().

1760 {
1761  data15 inaddr;
1762  inaddr.ip = ip;
1763  sprintf(target, "%u.%u.%u.%u", inaddr.octate[0], inaddr.octate[1], inaddr.octate[2], inaddr.octate[3]);
1764  return target;
1765 }
#define sprintf(buf, format,...)
Definition: sprintf.c:55
int ip[4]
Definition: rtl.c:1176
unsigned ip
Definition: tftpd.h:162
GLenum target
Definition: glext.h:7315
Definition: tftpd.h:157
MYBYTE octate[4]
Definition: tftpd.h:163

◆ isIP()

bool isIP ( char string)

Definition at line 1767 of file tftpd.cpp.

Referenced by init().

1768 {
1769  int j = 0;
1770 
1771  for (; *string; string++)
1772  {
1773  if (*string == '.' && *(string + 1) != '.')
1774  j++;
1775  else if (*string < '0' || *string > '9')
1776  return 0;
1777  }
1778 
1779  if (j == 3)
1780  return 1;
1781  else
1782  return 0;
1783 }
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
char string[160]
Definition: util.h:11

◆ logMess() [1/2]

void logMess ( char logBuff,
MYBYTE  logLevel 
)

Definition at line 2585 of file tftpd.cpp.

Referenced by detectChange(), init(), processRequest(), runProg(), and ServiceMain().

2586 {
2588 
2589  if (verbatim)
2590  printf("%s\n", logBuff);
2591  else if (cfig.logfile && logLevel <= cfig.logLevel)
2592  {
2593  time_t t = time(NULL);
2594  tm *ttm = localtime(&t);
2595 
2596  if (ttm->tm_yday != loggingDay)
2597  {
2598  loggingDay = ttm->tm_yday;
2599  strftime(extbuff, sizeof(extbuff), logFile, ttm);
2600  fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
2601  fclose(cfig.logfile);
2602  cfig.logfile = fopen(extbuff, "at");
2603 
2604  if (cfig.logfile)
2605  {
2606  fprintf(cfig.logfile, "%s\n\n", sVersion);
2607  WritePrivateProfileString("InternetShortcut","URL", extbuff, lnkFile);
2608  WritePrivateProfileString("InternetShortcut","IconIndex", "0", lnkFile);
2609  WritePrivateProfileString("InternetShortcut","IconFile", extbuff, lnkFile);
2610  }
2611  else
2612  return;
2613  }
2614 
2615  strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
2616  fprintf(cfig.logfile, "[%s] %s\n", extbuff, logBuff);
2617  fflush(cfig.logfile);
2618  }
2619  SetEvent(lEvent);
2620 }
data2 cfig
Definition: tftpd.cpp:51
FILE * logfile
Definition: tftpd.h:145
char sVersion[]
Definition: tftpd.cpp:36
char logBuff[512]
Definition: tftpd.cpp:42
GLdouble GLdouble t
Definition: gl.h:2047
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
__u16 time
Definition: mkdosfs.c:366
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
smooth NULL
Definition: ftsmooth.c:416
char logFile[_MAX_PATH]
Definition: tftpd.cpp:38
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
char lnkFile[_MAX_PATH]
Definition: tftpd.cpp:39
MYWORD loggingDay
Definition: tftpd.cpp:48
HANDLE lEvent
Definition: tftpd.cpp:56
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
Definition: time.h:76
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:426
char verbatim
Definition: tftpd.cpp:46
int tm_yday
Definition: time.h:84
MYBYTE logLevel
Definition: tftpd.h:153
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
__kernel_time_t time_t
Definition: linux.h:252
char extbuff[_MAX_PATH]
Definition: tftpd.cpp:41
#define INFINITE
Definition: serial.h:102
#define printf
Definition: config.h:203
#define WritePrivateProfileString
Definition: winbase.h:3737

◆ logMess() [2/2]

void logMess ( request req,
MYBYTE  logLevel 
)

Definition at line 2622 of file tftpd.cpp.

2623 {
2625 
2626  char tempbuff[256];
2627 
2628  if (verbatim)
2629  {
2630  if (!req->serverError.errormessage[0])
2632 
2633  if (req->path[0])
2634  printf("Client %s:%u %s, %s\n", IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage);
2635  else
2636  printf("Client %s:%u, %s\n", IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->serverError.errormessage);
2637  }
2638  else if (cfig.logfile && logLevel <= cfig.logLevel)
2639  {
2640  time_t t = time(NULL);
2641  tm *ttm = localtime(&t);
2642 
2643  if (ttm->tm_yday != loggingDay)
2644  {
2645  loggingDay = ttm->tm_yday;
2646  strftime(extbuff, sizeof(extbuff), logFile, ttm);
2647  fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
2648  fclose(cfig.logfile);
2649  cfig.logfile = fopen(extbuff, "at");
2650 
2651  if (cfig.logfile)
2652  {
2653  fprintf(cfig.logfile, "%s\n\n", sVersion);
2654  WritePrivateProfileString("InternetShortcut","URL", extbuff, lnkFile);
2655  WritePrivateProfileString("InternetShortcut","IconIndex", "0", lnkFile);
2656  WritePrivateProfileString("InternetShortcut","IconFile", extbuff, lnkFile);
2657  }
2658  else
2659  return;
2660  }
2661 
2662  strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
2663 
2664  if (req->path[0])
2665  fprintf(cfig.logfile, "[%s] Client %s:%u %s, %s\n", extbuff, IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage);
2666  else
2667  fprintf(cfig.logfile, "[%s] Client %s:%u, %s\n", extbuff, IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->serverError.errormessage);
2668 
2669  fflush(cfig.logfile);
2670  }
2671  SetEvent(lEvent);
2672 }
data2 cfig
Definition: tftpd.cpp:51
u_short sin_port
Definition: winsock.h:511
FILE * logfile
Definition: tftpd.h:145
char sVersion[]
Definition: tftpd.cpp:36
GLdouble GLdouble t
Definition: gl.h:2047
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
int errno
__u16 time
Definition: mkdosfs.c:366
char tempbuff[256]
Definition: tftpd.cpp:40
const char * strerror(int err)
Definition: compat_str.c:23
#define ntohs(x)
Definition: module.h:208
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
char path[256]
Definition: tftpd.h:94
smooth NULL
Definition: ftsmooth.c:416
char logFile[_MAX_PATH]
Definition: tftpd.cpp:38
char errormessage[512]
Definition: tftpd.h:69
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
char lnkFile[_MAX_PATH]
Definition: tftpd.cpp:39
sockaddr_in client
Definition: tftpd.h:105
MYWORD loggingDay
Definition: tftpd.cpp:48
HANDLE lEvent
Definition: tftpd.cpp:56
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
Definition: time.h:76
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:426
struct in_addr sin_addr
Definition: winsock.h:512
char verbatim
Definition: tftpd.cpp:46
int tm_yday
Definition: time.h:84
MYBYTE logLevel
Definition: tftpd.h:153
tftperror serverError
Definition: tftpd.h:109
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
__kernel_time_t time_t
Definition: linux.h:252
char extbuff[_MAX_PATH]
Definition: tftpd.cpp:41
char * IP2String(char *target, MYDWORD ip)
Definition: tftpd.cpp:1759
#define INFINITE
Definition: serial.h:102
#define printf
Definition: config.h:203
#define WritePrivateProfileString
Definition: winbase.h:3737

◆ main()

int main ( int argc  ,
TCHAR argv[] 
)

Definition at line 346 of file tftpd.cpp.

347 {
349  osvi.dwOSVersionInfoSize = sizeof(osvi);
350  bool result = GetVersionEx(&osvi);
351 
352  if (result && osvi.dwPlatformId >= VER_PLATFORM_WIN32_NT)
353  {
354  if (argc > 1 && lstrcmpi(argv[1], TEXT("-i")) == 0)
355  installService();
356  else if (argc > 1 && lstrcmpi(argv[1], TEXT("-u")) == 0)
358  else if (argc > 1 && lstrcmpi(argv[1], TEXT("-v")) == 0)
359  {
360  SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
361  bool serviceStopped = true;
362 
363  if (serviceControlManager)
364  {
365  SC_HANDLE service = OpenService(serviceControlManager,
367  if (service)
368  {
369  serviceStopped = stopService(service);
370  CloseServiceHandle(service);
371  }
372  CloseServiceHandle(serviceControlManager);
373  }
374  else
376 
377  if (serviceStopped)
378  runProg();
379  else
380  printf("Failed to Stop Service\n");
381  }
382  else
383  runService();
384  }
385  else if (argc == 1 || lstrcmpi(argv[1], TEXT("-v")) == 0)
386  runProg();
387  else
388  printf("This option is not available on Windows95/98/ME\n");
389 
390  return 0;
391 }
static int argc
Definition: ServiceArgs.c:12
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:236
#define lstrcmpi
Definition: winbase.h:3687
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
OSVERSIONINFO osvi
Definition: ver.c:28
void runProg()
Definition: tftpd.cpp:393
#define OpenService
Definition: winsvc.h:576
static char ** argv
Definition: ServiceArgs.c:11
void printWindowsError()
Definition: tftpd.cpp:323
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:576
void uninstallService()
Definition: tftpd.cpp:296
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:233
char serviceName[]
Definition: tftpd.cpp:34
#define OpenSCManager
Definition: winsvc.h:575
void installService()
Definition: tftpd.cpp:256
#define TEXT(s)
Definition: k32.h:26
#define SERVICE_STOP
Definition: winsvc.h:58
ULONG dwPlatformId
Definition: rtltypes.h:237
#define GetVersionEx
Definition: winbase.h:3666
GLuint64EXT * result
Definition: glext.h:11304
bool stopService(SC_HANDLE service)
Definition: tftpd.cpp:225
void runService()
Definition: tftpd.cpp:214
#define printf
Definition: config.h:203

◆ myGetToken()

char* myGetToken ( char buff,
MYBYTE  index 
)

Definition at line 1628 of file tftpd.cpp.

1629 {
1630  while (*buff)
1631  {
1632  if (index)
1633  index--;
1634  else
1635  break;
1636 
1637  buff += strlen(buff) + 1;
1638  }
1639 
1640  return buff;
1641 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
GLuint index
Definition: glext.h:6031
static unsigned char buff[32768]
Definition: fatten.c:17

◆ myLower()

char* myLower ( char string)

Definition at line 1795 of file tftpd.cpp.

1796 {
1797  char diff = 'a' - 'A';
1798  MYWORD len = strlen(string);
1799  for (int i = 0; i < len; i++)
1800  if (string[i] >= 'A' && string[i] <= 'Z')
1801  string[i] += diff;
1802  return string;
1803 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MYWORD
Definition: tftpd.h:22
GLenum GLclampf GLint i
Definition: glfuncs.h:14
GLenum GLsizei len
Definition: glext.h:6722
char string[160]
Definition: util.h:11

◆ mySplit()

void mySplit ( char name,
char value,
char source,
char  splitChar 
)

Definition at line 1730 of file tftpd.cpp.

Referenced by init().

1731 {
1732  int i = 0;
1733  int j = 0;
1734  int k = 0;
1735 
1736  for (; source[i] && j <= 510 && source[i] != splitChar; i++, j++)
1737  {
1738  name[j] = source[i];
1739  }
1740 
1741  if (source[i])
1742  {
1743  i++;
1744  for (; k <= 510 && source[i]; i++, k++)
1745  {
1746  value[k] = source[i];
1747  }
1748  }
1749 
1750  name[j] = 0;
1751  value[k] = 0;
1752 
1753  myTrim(name, name);
1754  myTrim(value, value);
1755  //printf("%s %s\n", name, value);
1756 }
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
Definition: get.c:139
GLenum GLclampf GLint i
Definition: glfuncs.h:14
Definition: name.c:36
char * myTrim(char *target, char *source)
Definition: tftpd.cpp:1689
int k
Definition: mpi.c:3369

◆ myTokenize()

MYWORD myTokenize ( char target,
char source,
char sep,
bool  whiteSep 
)

Definition at line 1643 of file tftpd.cpp.

1644 {
1645  bool found = true;
1646  char *dp = target;
1647  MYWORD kount = 0;
1648 
1649  while (*source)
1650  {
1651  if (sep && sep[0] && strchr(sep, (*source)))
1652  {
1653  found = true;
1654  source++;
1655  continue;
1656  }
1657  else if (whiteSep && (*source) <= 32)
1658  {
1659  found = true;
1660  source++;
1661  continue;
1662  }
1663 
1664  if (found)
1665  {
1666  if (target != dp)
1667  {
1668  *dp = 0;
1669  dp++;
1670  }
1671  kount++;
1672  }
1673 
1674  found = false;
1675  *dp = *source;
1676  dp++;
1677  source++;
1678  }
1679 
1680  *dp = 0;
1681  dp++;
1682  *dp = 0;
1683 
1684  //printf("%s\n", target);
1685 
1686  return kount;
1687 }
#define MYWORD
Definition: tftpd.h:22
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
char * strchr(const char *String, int ch)
Definition: utclib.c:501
GLenum target
Definition: glext.h:7315

◆ myTrim()

char* myTrim ( char target,
char source 
)

Definition at line 1689 of file tftpd.cpp.

Referenced by getSection(), mySplit(), openSection(), and readSection().

1690 {
1691  while ((*source) && (*source) <= 32)
1692  source++;
1693 
1694  int i = 0;
1695 
1696  for (; i < 511 && source[i]; i++)
1697  target[i] = source[i];
1698 
1699  target[i] = source[i];
1700  i--;
1701 
1702  for (; i >= 0 && target[i] <= 32; i--)
1703  target[i] = 0;
1704 
1705  return target;
1706 }
GLenum GLclampf GLint i
Definition: glfuncs.h:14
GLenum target
Definition: glext.h:7315

◆ myUpper()

char* myUpper ( char string)

Definition at line 1785 of file tftpd.cpp.

Referenced by getSection(), and openSection().

1786 {
1787  char diff = 'a' - 'A';
1788  MYWORD len = strlen(string);
1789  for (int i = 0; i < len; i++)
1790  if (string[i] >= 'a' && string[i] <= 'z')
1791  string[i] -= diff;
1792  return string;
1793 }
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MYWORD
Definition: tftpd.h:22
GLenum GLclampf GLint i
Definition: glfuncs.h:14
GLenum GLsizei len
Definition: glext.h:6722
char string[160]
Definition: util.h:11

◆ openSection()

FILE* openSection ( const char sectionName,
MYBYTE  serial,
char fileName 
)

Definition at line 1581 of file tftpd.cpp.

Referenced by init().

1582 {
1583  //printf("%s=%s\n",fileName,sectionName);
1584  char section[128];
1585  sprintf(section, "[%s]", sectionName);
1586  myUpper(section);
1587  FILE *f = fopen(fileName, "rt");
1588  char buff[512];
1589  MYBYTE found = 0;
1590 
1591  if (f)
1592  {
1593  while (fgets(buff, 511, f))
1594  {
1595  myUpper(buff);
1596  myTrim(buff, buff);
1597 
1598  if (strstr(buff, section) == buff)
1599  {
1600  found++;
1601 
1602  if (found == serial)
1603  return f;
1604  }
1605  }
1606  fclose(f);
1607  }
1608  return NULL;
1609 }
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
Definition: parser.c:55
char * myUpper(char *string)
Definition: tftpd.cpp:1785
#define sprintf(buf, format,...)
Definition: sprintf.c:55
smooth NULL
Definition: ftsmooth.c:416
GLfloat f
Definition: glext.h:7540
#define MYBYTE
Definition: tftpd.h:21
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
uint32_t serial
Definition: fsck.fat.h:64
#define f
Definition: ke_i.h:83
char * myTrim(char *target, char *source)
Definition: tftpd.cpp:1689
static unsigned char buff[32768]
Definition: fatten.c:17

◆ printWindowsError()

void printWindowsError ( )

Definition at line 323 of file tftpd.cpp.

Referenced by installService(), main(), and uninstallService().

324 {
325  MYDWORD dw = GetLastError();
326 
327  if (dw)
328  {
329  LPVOID lpMsgBuf;
330 
335  NULL,
336  dw,
338  (LPTSTR) &lpMsgBuf,
339  0, NULL );
340 
341  printf("Error: %s\nPress Enter..\n", (LPTSTR)lpMsgBuf);
342  getchar();
343  }
344 }
#define LANG_NEUTRAL
Definition: nls.h:22
#define SUBLANG_DEFAULT
Definition: nls.h:168
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:400
smooth NULL
Definition: ftsmooth.c:416
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:404
REFIID LPVOID DWORD dw
Definition: atlbase.h:40
#define FormatMessage
Definition: winbase.h:3609
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:401
_Check_return_ _CRTIMP int __cdecl getchar(void)
Definition: file.c:3627
#define MAKELANGID(p, s)
Definition: nls.h:15
#define MYDWORD
Definition: tftpd.h:23
#define printf
Definition: config.h:203

◆ processRequest()

void processRequest ( void lpParam)

Definition at line 488 of file tftpd.cpp.

Referenced by init(), runProg(), and ServiceMain().

489 {
490  //printf("New Thread %u\n",GetCurrentThreadId());
491 
492  request req;
493 
495  totalThreads++;
496  SetEvent(cEvent);
497 
498  do
499  {
501  //printf("In Thread %u\n",GetCurrentThreadId());
502 
504  activeThreads++;
505  SetEvent(cEvent);
506 
508  {
509  SetEvent(sEvent);
510  req.attempt = UCHAR_MAX;
511  continue;
512  }
513 
514  memset(&req, 0, sizeof(request));
515  req.sock = INVALID_SOCKET;
516 
517  req.clientsize = sizeof(req.client);
518  req.sockInd = currentServer;
520  req.knock = network.tftpConn[req.sockInd].sock;
521 
522  if (req.knock == INVALID_SOCKET)
523  {
524  SetEvent(sEvent);
525  req.attempt = UCHAR_MAX;
526  continue;
527  }
528 
529  errno = 0;
530  req.bytesRecd = recvfrom(req.knock, (char*)&req.mesin, sizeof(message), 0, (sockaddr*)&req.client, &req.clientsize);
532 
533  //printf("socket Signalled=%u\n",SetEvent(sEvent));
534  SetEvent(sEvent);
535 
536  if (!errno && req.bytesRecd > 0)
537  {
538  if (cfig.hostRanges[0].rangeStart)
539  {
540  MYDWORD iip = ntohl(req.client.sin_addr.s_addr);
541  bool allowed = false;
542 
543 #ifdef __REACTOS__
544  for (MYWORD j = 0; j < _countof(cfig.hostRanges) && cfig.hostRanges[j].rangeStart; j++)
545 #else
546  for (int j = 0; j <= 32 && cfig.hostRanges[j].rangeStart; j++)
547 #endif
548  {
549  if (iip >= cfig.hostRanges[j].rangeStart && iip <= cfig.hostRanges[j].rangeEnd)
550  {
551  allowed = true;
552  break;
553  }
554  }
555 
556  if (!allowed)
557  {
558  req.serverError.opcode = htons(5);
559  req.serverError.errorcode = htons(2);
560  strcpy(req.serverError.errormessage, "Access Denied");
561  logMess(&req, 1);
562  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
563  req.attempt = UCHAR_MAX;
564  continue;
565  }
566  }
567 
568  if ((htons(req.mesin.opcode) == 5))
569  {
570  sprintf(req.serverError.errormessage, "Error Code %i at Client, %s", ntohs(req.clientError.errorcode), req.clientError.errormessage);
571  logMess(&req, 2);
572  req.attempt = UCHAR_MAX;
573  continue;
574  }
575  else if (htons(req.mesin.opcode) != 1 && htons(req.mesin.opcode) != 2)
576  {
577  req.serverError.opcode = htons(5);
578  req.serverError.errorcode = htons(5);
579  sprintf(req.serverError.errormessage, "Unknown Transfer Id");
580  logMess(&req, 2);
581  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
582  req.attempt = UCHAR_MAX;
583  continue;
584  }
585  }
586  else
587  {
588  sprintf(req.serverError.errormessage, "Communication Error");
589  logMess(&req, 1);
590  req.attempt = UCHAR_MAX;
591  continue;
592  }
593 
594  req.blksize = 512;
595  req.timeout = timeout;
596  req.expiry = time(NULL) + req.timeout;
597  bool fetchAck = false;
598 
600 
601  if (req.sock == INVALID_SOCKET)
602  {
603  req.serverError.opcode = htons(5);
604  req.serverError.errorcode = htons(0);
605  strcpy(req.serverError.errormessage, "Thread Socket Creation Error");
606  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
607  logMess(&req, 1);
608  req.attempt = UCHAR_MAX;
609  continue;
610  }
611 
612  sockaddr_in service;
613  service.sin_family = AF_INET;
614  service.sin_addr.s_addr = network.tftpConn[req.sockInd].server;
615 
616  if (cfig.minport)
617  {
618  for (MYWORD comport = cfig.minport; ; comport++)
619  {
620  service.sin_port = htons(comport);
621 
622  if (comport > cfig.maxport)
623  {
624  req.serverError.opcode = htons(5);
625  req.serverError.errorcode = htons(0);
626  strcpy(req.serverError.errormessage, "No port is free");
627  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
628  logMess(&req, 1);
629  req.attempt = UCHAR_MAX;
630  break;
631  }
632  else if (bind(req.sock, (sockaddr*) &service, sizeof(service)) == -1)
633  continue;
634  else
635  break;
636  }
637  }
638  else
639  {
640  service.sin_port = 0;
641 
642  if (bind(req.sock, (sockaddr*) &service, sizeof(service)) == -1)
643  {
644  strcpy(req.serverError.errormessage, "Thread failed to bind");
645  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
646  logMess(&req, 1);
647  req.attempt = UCHAR_MAX;
648  }
649  }
650 
651  if (req.attempt >= 3)
652  continue;
653 
654  if (connect(req.sock, (sockaddr*)&req.client, req.clientsize) == -1)
655  {
656  req.serverError.opcode = htons(5);
657  req.serverError.errorcode = htons(0);
658  strcpy(req.serverError.errormessage, "Connect Failed");
659  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
660  logMess(&req, 1);
661  req.attempt = UCHAR_MAX;
662  continue;
663  }
664 
665  //sprintf(req.serverError.errormessage, "In Temp, Socket");
666  //logMess(&req, 1);
667 
668  char *inPtr = req.mesin.buffer;
669  *(inPtr + (req.bytesRecd - 3)) = 0;
670  req.filename = inPtr;
671 
672  if (!strlen(req.filename) || strlen(req.filename) > UCHAR_MAX)
673  {
674  req.serverError.opcode = htons(5);
675  req.serverError.errorcode = htons(4);
676  strcpy(req.serverError.errormessage, "Malformed Request, Invalid/Missing Filename");
677  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
678  req.attempt = UCHAR_MAX;
679  logMess(&req, 1);
680  continue;
681  }
682 
683  inPtr += strlen(inPtr) + 1;
684  req.mode = inPtr;
685 
686  if (!strlen(req.mode) || strlen(req.mode) > 25)
687  {
688  req.serverError.opcode = htons(5);
689  req.serverError.errorcode = htons(4);
690  strcpy(req.serverError.errormessage, "Malformed Request, Invalid/Missing Mode");
691  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
692  req.attempt = UCHAR_MAX;
693  logMess(&req, 1);
694  continue;
695  }
696 
697  inPtr += strlen(inPtr) + 1;
698 
699  for (MYDWORD i = 0; i < strlen(req.filename); i++)
700  if (req.filename[i] == notFileSep)
701  req.filename[i] = fileSep;
702 
703  tempbuff[0] = '.';
704  tempbuff[1] = '.';
705  tempbuff[2] = fileSep;
706  tempbuff[3] = 0;
707 
708  if (strstr(req.filename, tempbuff))
709  {
710  req.serverError.opcode = htons(5);
711  req.serverError.errorcode = htons(2);
712  strcpy(req.serverError.errormessage, "Access violation");
713  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
714  logMess(&req, 1);
715  req.attempt = UCHAR_MAX;
716  continue;
717  }
718 
719  if (req.filename[0] == fileSep)
720  req.filename++;
721 
722  if (!cfig.homes[0].alias[0])
723  {
724  if (strlen(cfig.homes[0].target) + strlen(req.filename) >= sizeof(req.path))
725  {
726  req.serverError.opcode = htons(5);
727  req.serverError.errorcode = htons(4);
728  sprintf(req.serverError.errormessage, "Filename too large");
729  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
730  logMess(&req, 1);
731  req.attempt = UCHAR_MAX;
732  continue;
733  }
734 
735  strcpy(req.path, cfig.homes[0].target);
736  strcat(req.path, req.filename);
737  }
738  else
739  {
740  char *bname = strchr(req.filename, fileSep);
741 
742  if (bname)
743  {
744  *bname = 0;
745  bname++;
746  }
747  else
748  {
749  req.serverError.opcode = htons(5);
750  req.serverError.errorcode = htons(2);
751  sprintf(req.serverError.errormessage, "Missing directory/alias");
752  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
753  logMess(&req, 1);
754  req.attempt = UCHAR_MAX;
755  continue;
756  }
757 
758 #ifdef __REACTOS__
759  for (int i = 0; i < MAX_SERVERS; i++)
760 #else
761  for (int i = 0; i < 8; i++)
762 #endif
763  {
764  //printf("%s=%i\n", req.filename, cfig.homes[i].alias[0]);
765  if (cfig.homes[i].alias[0] && !strcasecmp(req.filename, cfig.homes[i].alias))
766  {
767  if (strlen(cfig.homes[i].target) + strlen(bname) >= sizeof(req.path))
768  {
769  req.serverError.opcode = htons(5);
770  req.serverError.errorcode = htons(4);
771  sprintf(req.serverError.errormessage, "Filename too large");
772  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
773  logMess(&req, 1);
774  req.attempt = UCHAR_MAX;
775  break;
776  }
777 
778  strcpy(req.path, cfig.homes[i].target);
779  strcat(req.path, bname);
780  break;
781  }
782  else if (i == 7 || !cfig.homes[i].alias[0])
783  {
784  req.serverError.opcode = htons(5);
785  req.serverError.errorcode = htons(2);
786  sprintf(req.serverError.errormessage, "No such directory/alias %s", req.filename);
787  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
788  logMess(&req, 1);
789  req.attempt = UCHAR_MAX;
790  break;
791  }
792  }
793  }
794 
795  if (req.attempt >= 3)
796  continue;
797 
798  if (ntohs(req.mesin.opcode) == 1)
799  {
800  if (!cfig.fileRead)
801  {
802  req.serverError.opcode = htons(5);
803  req.serverError.errorcode = htons(2);
804  strcpy(req.serverError.errormessage, "GET Access Denied");
805  logMess(&req, 1);
806  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
807  req.attempt = UCHAR_MAX;
808  continue;
809  }
810 
811  if (*inPtr)
812  {
813  char *tmp = inPtr;
814 
815  while (*tmp)
816  {
817  if (!strcasecmp(tmp, "blksize"))
818  {
819  tmp += strlen(tmp) + 1;
820  MYDWORD val = atol(tmp);
821 
822  if (val < 512)
823  val = 512;
824  else if (val > blksize)
825  val = blksize;
826 
827  req.blksize = val;
828  break;
829  }
830 
831  tmp += strlen(tmp) + 1;
832  }
833  }
834 
835  errno = 0;
836 
837  if (!strcasecmp(req.mode, "netascii") || !strcasecmp(req.mode, "ascii"))
838  req.file = fopen(req.path, "rt");
839  else
840  req.file = fopen(req.path, "rb");
841 
842  if (errno || !req.file)
843  {
844  req.serverError.opcode = htons(5);
845  req.serverError.errorcode = htons(1);
846  strcpy(req.serverError.errormessage, "File not found or No Access");
847  logMess(&req, 1);
848  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
849  req.attempt = UCHAR_MAX;
850  continue;
851  }
852  }
853  else
854  {
855  if (!cfig.fileWrite && !cfig.fileOverwrite)
856  {
857  req.serverError.opcode = htons(5);
858  req.serverError.errorcode = htons(2);
859  strcpy(req.serverError.errormessage, "PUT Access Denied");
860  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
861  logMess(&req, 1);
862  req.attempt = UCHAR_MAX;
863  continue;
864  }
865 
866  req.file = fopen(req.path, "rb");
867 
868  if (req.file)
869  {
870  fclose(req.file);
871  req.file = NULL;
872 
873  if (!cfig.fileOverwrite)
874  {
875  req.serverError.opcode = htons(5);
876  req.serverError.errorcode = htons(6);
877  strcpy(req.serverError.errormessage, "File already exists");
878  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
879  logMess(&req, 1);
880  req.attempt = UCHAR_MAX;
881  continue;
882  }
883  }
884  else if (!cfig.fileWrite)
885  {
886  req.serverError.opcode = htons(5);
887  req.serverError.errorcode = htons(2);
888  strcpy(req.serverError.errormessage, "Create File Access Denied");
889  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
890  logMess(&req, 1);
891  req.attempt = UCHAR_MAX;
892  continue;
893  }
894 
895  errno = 0;
896 
897  if (!strcasecmp(req.mode, "netascii") || !strcasecmp(req.mode, "ascii"))
898  req.file = fopen(req.path, "wt");
899  else
900  req.file = fopen(req.path, "wb");
901 
902  if (errno || !req.file)
903  {
904  req.serverError.opcode = htons(5);
905  req.serverError.errorcode = htons(2);
906  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
907  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
908  logMess(&req, 1);
909  req.attempt = UCHAR_MAX;
910  continue;
911  }
912  }
913 
914  setvbuf(req.file, NULL, _IOFBF, 5 * req.blksize);
915 
916  if (*inPtr)
917  {
918  fetchAck = true;
919  char *outPtr = req.mesout.buffer;
920  req.mesout.opcode = htons(6);
921  MYDWORD val;
922  while (*inPtr)
923  {
924  //printf("%s\n", inPtr);
925  if (!strcasecmp(inPtr, "blksize"))
926  {
927  strcpy(outPtr, inPtr);
928  outPtr += strlen(outPtr) + 1;
929  inPtr += strlen(inPtr) + 1;
930  val = atol(inPtr);
931 
932  if (val < 512)
933  val = 512;
934  else if (val > blksize)
935  val = blksize;
936 
937  req.blksize = val;
938  sprintf(outPtr, "%u", val);
939  outPtr += strlen(outPtr) + 1;
940  }
941  else if (!strcasecmp(inPtr, "tsize"))
942  {
943  strcpy(outPtr, inPtr);
944  outPtr += strlen(outPtr) + 1;
945  inPtr += strlen(inPtr) + 1;
946 
947  if (ntohs(req.mesin.opcode) == 1)
948  {
949  if (!fseek(req.file, 0, SEEK_END))
950  {
951  if (ftell(req.file) >= 0)
952  {
953  req.tsize = ftell(req.file);
954  sprintf(outPtr, "%u", req.tsize);
955  outPtr += strlen(outPtr) + 1;
956  }
957  else
958  {
959  req.serverError.opcode = htons(5);
960  req.serverError.errorcode = htons(2);
961  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
962  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
963  logMess(&req, 1);
964  req.attempt = UCHAR_MAX;
965  break;
966  }
967  }
968  else
969  {
970  req.serverError.opcode = htons(5);
971  req.serverError.errorcode = htons(2);
972  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
973  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
974  logMess(&req, 1);
975  req.attempt = UCHAR_MAX;
976  break;
977  }
978  }
979  else
980  {
981  req.tsize = 0;
982  sprintf(outPtr, "%u", req.tsize);
983  outPtr += strlen(outPtr) + 1;
984  }
985  }
986  else if (!strcasecmp(inPtr, "timeout"))
987  {
988  strcpy(outPtr, inPtr);
989  outPtr += strlen(outPtr) + 1;
990  inPtr += strlen(inPtr) + 1;
991  val = atoi(inPtr);
992 
993  if (val < 1)
994  val = 1;
995  else if (val > UCHAR_MAX)
996  val = UCHAR_MAX;
997 
998  req.timeout = val;
999  req.expiry = time(NULL) + req.timeout;
1000  sprintf(outPtr, "%u", val);
1001  outPtr += strlen(outPtr) + 1;
1002  }
1003 
1004  inPtr += strlen(inPtr) + 1;
1005  //printf("=%u\n", val);
1006  }
1007 
1008  if (req.attempt >= 3)
1009  continue;
1010 
1011  errno = 0;
1012  req.bytesReady = (const char*)outPtr - (const char*)&req.mesout;
1013  //printf("Bytes Ready=%u\n", req.bytesReady);
1014  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1015  errno = WSAGetLastError();
1016  }
1017  else if (htons(req.mesin.opcode) == 2)
1018  {
1019  req.acout.opcode = htons(4);
1020  req.acout.block = htons(0);
1021  errno = 0;
1022  req.bytesReady = 4;
1023  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1024  errno = WSAGetLastError();
1025  }
1026 
1027  if (errno)
1028  {
1029  sprintf(req.serverError.errormessage, "Communication Error");
1030  logMess(&req, 1);
1031  req.attempt = UCHAR_MAX;
1032  continue;
1033  }
1034  else if (ntohs(req.mesin.opcode) == 1)
1035  {
1036  errno = 0;
1037  req.pkt[0] = (packet*)calloc(1, req.blksize + 4);
1038  req.pkt[1] = (packet*)calloc(1, req.blksize + 4);
1039 
1040  if (errno || !req.pkt[0] || !req.pkt[1])
1041  {
1042  sprintf(req.serverError.errormessage, "Memory Error");
1043  logMess(&req, 1);
1044  req.attempt = UCHAR_MAX;
1045  continue;
1046  }
1047 
1048  long ftellLoc = ftell(req.file);
1049 
1050  if (ftellLoc > 0)
1051  {
1052  if (fseek(req.file, 0, SEEK_SET))
1053  {
1054  req.serverError.opcode = htons(5);
1055  req.serverError.errorcode = htons(2);
1056  strcpy(req.serverError.errormessage, "File Access Error");
1057  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1058  logMess(&req, 1);
1059  req.attempt = UCHAR_MAX;
1060  continue;
1061  }
1062  }
1063  else if (ftellLoc < 0)
1064  {
1065  req.serverError.opcode = htons(5);
1066  req.serverError.errorcode = htons(2);
1067  strcpy(req.serverError.errormessage, "File Access Error");
1068  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1069  logMess(&req, 1);
1070  req.attempt = UCHAR_MAX;
1071  continue;
1072  }
1073 
1074  errno = 0;
1075  req.pkt[0]->opcode = htons(3);
1076  req.pkt[0]->block = htons(1);
1077  req.bytesRead[0] = fread(&req.pkt[0]->buffer, 1, req.blksize, req.file);
1078 
1079  if (errno)
1080  {
1081  req.serverError.opcode = htons(5);
1082  req.serverError.errorcode = htons(2);
1083  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
1084  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1085  logMess(&req, 1);
1086  req.attempt = UCHAR_MAX;
1087  continue;
1088  }
1089 
1090  if (req.bytesRead[0] == req.blksize)
1091  {
1092  req.pkt[1]->opcode = htons(3);
1093  req.pkt[1]->block = htons(2);
1094  req.bytesRead[1] = fread(&req.pkt[1]->buffer, 1, req.blksize, req.file);
1095  if (req.bytesRead[1] < req.blksize)
1096  {
1097  fclose(req.file);
1098  req.file = 0;
1099  }
1100  }
1101  else
1102  {
1103  fclose(req.file);
1104  req.file = 0;
1105  }
1106 
1107  if (errno)
1108  {
1109  req.serverError.opcode = htons(5);
1110  req.serverError.errorcode = htons(2);
1111  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
1112  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1113  logMess(&req, 1);
1114  req.attempt = UCHAR_MAX;
1115  continue;
1116  }
1117 
1118  while (req.attempt <= 3)
1119  {
1120  if (fetchAck)
1121  {
1122  FD_ZERO(&req.readfds);
1123  req.tv.tv_sec = 1;
1124  req.tv.tv_usec = 0;
1125  FD_SET(req.sock, &req.readfds);
1126  select(req.sock + 1, &req.readfds, NULL, NULL, &req.tv);
1127 
1128  if (FD_ISSET(req.sock, &req.readfds))
1129  {
1130  errno = 0;
1131  req.bytesRecd = recv(req.sock, (char*)&req.mesin, sizeof(message), 0);
1132  errno = WSAGetLastError();
1133  if (req.bytesRecd <= 0 || errno)
1134  {
1135  sprintf(req.serverError.errormessage, "Communication Error");
1136  logMess(&req, 1);
1137  req.attempt = UCHAR_MAX;
1138  break;
1139  }
1140  else if(req.bytesRecd >= 4 && ntohs(req.mesin.opcode) == 4)
1141  {
1142  if (ntohs(req.acin.block) == req.block)
1143  {
1144  req.block++;
1145  req.fblock++;
1146  req.attempt = 0;
1147  }
1148  else if (req.expiry > time(NULL))
1149  continue;
1150  else
1151  req.attempt++;
1152  }
1153  else if (ntohs(req.mesin.opcode) == 5)
1154  {
1155  sprintf(req.serverError.errormessage, "Client %s:%u, Error Code %i at Client, %s", inet_ntoa(req.client.sin_addr), ntohs(req.client.sin_port), ntohs(req.clientError.errorcode), req.clientError.errormessage);
1156  logMess(&req, 1);
1157  req.attempt = UCHAR_MAX;
1158  break;
1159  }
1160  else
1161  {
1162  req.serverError.opcode = htons(5);
1163  req.serverError.errorcode = htons(4);
1164  sprintf(req.serverError.errormessage, "Unexpected Option Code %i", ntohs(req.mesin.opcode));
1165  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1166  logMess(&req, 1);
1167  req.attempt = UCHAR_MAX;
1168  break;
1169  }
1170  }
1171  else if (req.expiry > time(NULL))
1172  continue;
1173  else
1174  req.attempt++;
1175  }
1176  else
1177  {
1178  fetchAck = true;
1179  req.acin.block = 1;
1180  req.block = 1;
1181  req.fblock = 1;
1182  }
1183 
1184  if (req.attempt >= 3)
1185  {
1186  req.serverError.opcode = htons(5);
1187  req.serverError.errorcode = htons(0);
1188 
1189  if (req.fblock && !req.block)
1190  strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
1191  else
1192  strcpy(req.serverError.errormessage, "Timeout");
1193 
1194  logMess(&req, 1);
1195  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1196  req.attempt = UCHAR_MAX;
1197  break;
1198  }
1199  else if (!req.fblock)
1200  {
1201  errno = 0;
1202  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1203  errno = WSAGetLastError();
1204  if (errno)
1205  {
1206  sprintf(req.serverError.errormessage, "Communication Error");
1207  logMess(&req, 1);
1208  req.attempt = UCHAR_MAX;
1209  break;
1210  }
1211  req.expiry = time(NULL) + req.timeout;
1212  }
1213  else if (ntohs(req.pkt[0]->block) == req.block)
1214  {
1215  errno = 0;
1216  send(req.sock, (const char*)req.pkt[0], req.bytesRead[0] + 4, 0);
1217  errno = WSAGetLastError();
1218  if (errno)
1219  {
1220  sprintf(req.serverError.errormessage, "Communication Error");
1221  logMess(&req, 1);
1222  req.attempt = UCHAR_MAX;
1223  break;
1224  }
1225  req.expiry = time(NULL) + req.timeout;
1226 
1227  if (req.file)
1228  {
1229  req.tblock = ntohs(req.pkt[1]->block) + 1;
1230  if (req.tblock == req.block)
1231  {
1232  req.pkt[1]->block = htons(++req.tblock);
1233  req.bytesRead[1] = fread(&req.pkt[1]->buffer, 1, req.blksize, req.file);
1234 
1235  if (errno)
1236  {
1237  req.serverError.opcode = htons(5);
1238  req.serverError.errorcode = htons(4);
1240  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1241  logMess(&req, 1);
1242  req.attempt = UCHAR_MAX;
1243  break;
1244  }
1245  else if (req.bytesRead[1] < req.blksize)
1246  {
1247  fclose(req.file);
1248  req.file = 0;
1249  }
1250  }
1251  }
1252  }
1253  else if (ntohs(req.pkt[1]->block) == req.block)
1254  {
1255  errno = 0;
1256  send(req.sock, (const char*)req.pkt[1], req.bytesRead[1] + 4, 0);
1257  errno = WSAGetLastError();
1258  if (errno)
1259  {
1260  sprintf(req.serverError.errormessage, "Communication Error");
1261  logMess(&req, 1);
1262  req.attempt = UCHAR_MAX;
1263  break;
1264  }
1265 
1266  req.expiry = time(NULL) + req.timeout;
1267 
1268  if (req.file)
1269  {
1270  req.tblock = ntohs(req.pkt[0]->block) + 1;
1271  if (req.tblock == req.block)
1272  {
1273  req.pkt[0]->block = htons(++req.tblock);
1274  req.bytesRead[0] = fread(&req.pkt[0]->buffer, 1, req.blksize, req.file);
1275  if (errno)
1276  {
1277  req.serverError.opcode = htons(5);
1278  req.serverError.errorcode = htons(4);
1280  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1281  logMess(&req, 1);
1282  req.attempt = UCHAR_MAX;
1283  break;
1284  }
1285  else if (req.bytesRead[0] < req.blksize)
1286  {
1287  fclose(req.file);
1288  req.file = 0;
1289  }
1290  }
1291  }
1292  }
1293  else
1294  {
1295  sprintf(req.serverError.errormessage, "%u Blocks Served", req.fblock - 1);
1296  logMess(&req, 2);
1297  req.attempt = UCHAR_MAX;
1298  break;
1299  }
1300  }
1301  }
1302  else if (ntohs(req.mesin.opcode) == 2)
1303  {
1304  errno = 0;
1305  req.pkt[0] = (packet*)calloc(1, req.blksize + 4);
1306 
1307  if (errno || !req.pkt[0])
1308  {
1309  sprintf(req.serverError.errormessage, "Memory Error");
1310  logMess(&req, 1);
1311  req.attempt = UCHAR_MAX;
1312  continue;
1313  }
1314 
1315  while (req.attempt <= 3)
1316  {
1317  FD_ZERO(&req.readfds);
1318  req.tv.tv_sec = 1;
1319  req.tv.tv_usec = 0;
1320  FD_SET(req.sock, &req.readfds);
1321  select(req.sock + 1, &req.readfds, NULL, NULL, &req.tv);
1322 
1323  if (FD_ISSET(req.sock, &req.readfds))
1324  {
1325  errno = 0;
1326  req.bytesRecd = recv(req.sock, (char*)req.pkt[0], req.blksize + 4, 0);
1327  errno = WSAGetLastError();
1328 
1329  if (errno)
1330  {
1331  sprintf(req.serverError.errormessage, "Communication Error");
1332  logMess(&req, 1);
1333  req.attempt = UCHAR_MAX;
1334  break;
1335  }
1336  }
1337  else
1338  req.bytesRecd = 0;
1339 
1340  if (req.bytesRecd >= 4)
1341  {
1342  if (ntohs(req.pkt[0]->opcode) == 3)
1343  {
1344  req.tblock = req.block + 1;
1345 
1346  if (ntohs(req.pkt[0]->block) == req.tblock)
1347  {
1348  req.acout.opcode = htons(4);
1349  req.acout.block = req.pkt[0]->block;
1350  req.block++;
1351  req.fblock++;
1352  req.bytesReady = 4;
1353  req.expiry = time(NULL) + req.timeout;
1354 
1355  errno = 0;
1356  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1357  errno = WSAGetLastError();
1358 
1359  if (errno)
1360  {
1361  sprintf(req.serverError.errormessage, "Communication Error");
1362  logMess(&req, 1);
1363  req.attempt = UCHAR_MAX;
1364  break;
1365  }
1366 
1367  if (req.bytesRecd > 4)
1368  {
1369  errno = 0;
1370  if (fwrite(&req.pkt[0]->buffer, req.bytesRecd - 4, 1, req.file) != 1 || errno)
1371  {
1372  req.serverError.opcode = htons(5);
1373  req.serverError.errorcode = htons(3);
1374  strcpy(req.serverError.errormessage, "Disk full or allocation exceeded");
1375  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1376  logMess(&req, 1);
1377  req.attempt = UCHAR_MAX;
1378  break;
1379  }
1380  else
1381  req.attempt = 0;
1382  }
1383  else
1384  req.attempt = 0;
1385 
1386  if ((MYWORD)req.bytesRecd < req.blksize + 4)
1387  {
1388  fclose(req.file);
1389  req.file = 0;
1390  sprintf(req.serverError.errormessage, "%u Blocks Received", req.fblock);
1391  logMess(&req, 2);
1392  req.attempt = UCHAR_MAX;
1393  break;
1394  }
1395  }
1396  else if (req.expiry > time(NULL))
1397  continue;
1398  else if (req.attempt >= 3)
1399  {
1400  req.serverError.opcode = htons(5);
1401  req.serverError.errorcode = htons(0);
1402 
1403  if (req.fblock && !req.block)
1404  strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
1405  else
1406  strcpy(req.serverError.errormessage, "Timeout");
1407 
1408  logMess(&req, 1);
1409  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1410  req.attempt = UCHAR_MAX;
1411  break;
1412  }
1413  else
1414  {
1415  req.expiry = time(NULL) + req.timeout;
1416  errno = 0;
1417  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1418  errno = WSAGetLastError();
1419  req.attempt++;
1420 
1421  if (errno)
1422  {
1423  sprintf(req.serverError.errormessage, "Communication Error");
1424  logMess(&req, 1);
1425  req.attempt = UCHAR_MAX;
1426  break;
1427  }
1428  }
1429  }
1430  else if (req.bytesRecd > (int)sizeof(message))
1431  {
1432  req.serverError.opcode = htons(5);
1433  req.serverError.errorcode = htons(4);
1434  sprintf(req.serverError.errormessage, "Error: Incoming Packet too large");
1435  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1436  logMess(&req, 1);
1437  req.attempt = UCHAR_MAX;
1438  break;
1439  }
1440  else if (ntohs(req.pkt[0]->opcode) == 5)
1441  {
1442  sprintf(req.serverError.errormessage, "Error Code %i at Client, %s", ntohs(req.pkt[0]->block), &req.pkt[0]->buffer);
1443  logMess(&req, 1);
1444  req.attempt = UCHAR_MAX;
1445  break;
1446  }
1447  else
1448  {
1449  req.serverError.opcode = htons(5);
1450  req.serverError.errorcode = htons(4);
1451  sprintf(req.serverError.errormessage, "Unexpected Option Code %i", ntohs(req.pkt[0]->opcode));
1452  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1453  logMess(&req, 1);
1454  req.attempt = UCHAR_MAX;
1455  break;
1456  }
1457  }
1458  else if (req.expiry > time(NULL))
1459  continue;
1460  else if (req.attempt >= 3)
1461  {
1462  req.serverError.opcode = htons(5);
1463  req.serverError.errorcode = htons(0);
1464 
1465  if (req.fblock && !req.block)
1466  strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
1467  else
1468  strcpy(req.serverError.errormessage, "Timeout");
1469 
1470  logMess(&req, 1);
1471  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1472  req.attempt = UCHAR_MAX;
1473  break;
1474  }
1475  else
1476  {
1477  req.expiry = time(NULL) + req.timeout;
1478  errno = 0;
1479  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1480  errno = WSAGetLastError();
1481  req.attempt++;
1482 
1483  if (errno)
1484  {
1485  sprintf(req.serverError.errormessage, "Communication Error");
1486  logMess(&req, 1);
1487  req.attempt = UCHAR_MAX;
1488  break;
1489  }
1490  }
1491  }
1492  }
1493  }
1494  while (cleanReq(&req));
1495 
1497  totalThreads--;
1498  SetEvent(cEvent);
1499 
1500  //printf("Thread %u Killed\n",GetCurrentThreadId());
1501  _endthread();
1502  return;
1503 }
char * filename
Definition: tftpd.h:96
int maxport
Definition: tftpd.h:151
INT WSAAPI recvfrom(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags, OUT LPSOCKADDR from, IN OUT INT FAR *fromlen)
Definition: recv.c:87
data2 cfig
Definition: tftpd.cpp:51
MYBYTE attempt
Definition: tftpd.h:93
Definition: tftpd.h:59
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
MYWORD tblock
Definition: tftpd.h:122
time_t expiry
Definition: tftpd.h:89
_CRTIMP void __cdecl _endthread(void)
Definition: thread.c:95
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
char buffer[514]
Definition: tftpd.h:62
MYWORD timeout
Definition: tftpd.h:120
char notFileSep
Definition: tftpd.cpp:44
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define strcasecmp
Definition: fake.h:9
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
char fileSep
Definition: tftpd.cpp:43
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define _countof(array)
Definition: fontsub.cpp:30
unsigned long tv_sec
Definition: linux.h:1738
HANDLE cEvent
Definition: tftpd.cpp:54
MYWORD block
Definition: tftpd.h:121
#define MYWORD
Definition: tftpd.h:22
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
MYWORD opcode
Definition: tftpd.h:74
int errno
__u16 time
Definition: mkdosfs.c:366
#define FD_ZERO(set)
Definition: winsock.h:96
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
int bytesRecd
Definition: tftpd.h:102
#define FD_SET(fd, set)
Definition: winsock.h:89
char tempbuff[256]
Definition: tftpd.cpp:40
MYBYTE sockInd
Definition: tftpd.h:92
MYWORD timeout
Definition: tftpd.cpp:47
const char * strerror(int err)
Definition: compat_str.c:23
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
#define ntohs(x)
Definition: module.h:208
MYWORD errorcode
Definition: tftpd.h:68
char alias[64]
Definition: tftpd.h:39
MYDWORD tsize
Definition: tftpd.h:99
#define _IOFBF
Definition: stdio.h:128
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
socklen_t clientsize
Definition: tftpd.h:106
GLenum GLclampf GLint i
Definition: glfuncs.h:14
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
#define FD_ISSET(fd, set)
Definition: winsock.h:100
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
MYWORD block
Definition: tftpd.h:75
message mesout
Definition: tftpd.h:110
SOCKET sock
Definition: tftpd.h:90
char path[256]
Definition: tftpd.h:94
MYWORD blksize
Definition: tftpd.h:119
smooth NULL
Definition: ftsmooth.c:416
unsigned long tv_usec
Definition: linux.h:1739
acknowledgement acout
Definition: tftpd.h:111
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
MYDWORD rangeStart
Definition: tftpd.h:81
MYWORD opcode
Definition: tftpd.h:55
fd_set readfds
Definition: tftpd.h:88
tftperror clientError
Definition: tftpd.h:115
#define PF_INET
Definition: winsock.h:373
data1 network
Definition: tftpd.cpp:49
MYDWORD rangeEnd
Definition: tftpd.h:82
timeval tv
Definition: tftpd.h:87
#define inet_ntoa(addr)
Definition: inet.h:100
GLuint GLfloat * val
Definition: glext.h:7180
char target[256]
Definition: tftpd.h:40
char * mode
Definition: tftpd.h:97
char errormessage[512]
Definition: tftpd.h:69
Definition: dhcpd.h:135
#define SEEK_SET
Definition: jmemansi.c:26
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
#define INVALID_SOCKET
Definition: winsock.h:332
data12 hostRanges[32]
Definition: tftpd.h:146
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
bool cleanReq(request *req)
Definition: tftpd.cpp:1505
home homes[8]
Definition: tftpd.h:143
SOCKET knock
Definition: tftpd.h:91
char fileWrite
Definition: tftpd.h:148
sockaddr_in client
Definition: tftpd.h:105
MYDWORD server
Definition: tftpd.h:47
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
SOCKET sock
Definition: tftpd.h:45
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
HANDLE tEvent
Definition: tftpd.cpp:53
struct in_addr sin_addr
Definition: winsock.h:512
char fileOverwrite
Definition: tftpd.h:149
int bytesRead[2]
Definition: tftpd.h:103
MYWORD blksize
Definition: tftpd.cpp:45
MYWORD block
Definition: tftpd.h:56
MYWORD opcode
Definition: tftpd.h:61
tftperror serverError
Definition: tftpd.h:109
MYBYTE currentServer
Definition: tftpd.cpp:57
#define MAX_SERVERS
Definition: tftpd.h:34
#define UCHAR_MAX
Definition: limits.h:25
MYWORD port
Definition: tftpd.h:48
HANDLE sEvent
Definition: tftpd.cpp:55
packet * pkt[2]
Definition: tftpd.h:104
MYWORD totalThreads
Definition: tftpd.cpp:58
INT WSAAPI sendto(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags, IN CONST struct sockaddr *to, IN INT tolen)
Definition: send.c:82
MYWORD opcode
Definition: tftpd.h:67
Definition: tftpd.h:85
char * strchr(const char *String, int ch)
Definition: utclib.c:501
MYWORD activeThreads
Definition: tftpd.cpp:60
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
#define calloc
Definition: rosglue.h:14
acknowledgement acin
Definition: tftpd.h:117
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
FILE * file
Definition: tftpd.h:95
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
#define AF_INET
Definition: tcpip.h:117
#define SEEK_END
Definition: cabinet.c:27
_Check_return_opt_ _CRTIMP int __cdecl setvbuf(_Inout_ FILE *_File, _Inout_updates_opt_z_(_Size) char *_Buf, _In_ int _Mode, _In_ size_t _Size)
char fileRead
Definition: tftpd.h:147
MYDWORD fblock
Definition: tftpd.h:100
char buffer
Definition: tftpd.h:76
#define htons(x)
Definition: module.h:213
#define INFINITE
Definition: serial.h:102
#define SOCK_DGRAM
Definition: winsock.h:336
tftpConnType tftpConn[MAX_SERVERS]
Definition: tftpd.h:127
#define memset(x, y, z)
Definition: compat.h:39
#define MYDWORD
Definition: tftpd.h:23
int minport
Definition: tftpd.h:150
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
short sin_family
Definition: winsock.h:510
void logMess(char *logBuff, MYBYTE logLevel)
Definition: tftpd.cpp:2585
message mesin
Definition: tftpd.h:116
int bytesReady
Definition: tftpd.h:101
#define ntohl(x)
Definition: module.h:203

◆ readSection()

char* readSection ( char buff,
FILE f 
)

Definition at line 1611 of file tftpd.cpp.

Referenced by init().

1612 {
1613  while (fgets(buff, 511, f))
1614  {
1615  myTrim(buff, buff);
1616 
1617  if (*buff == '[')
1618  break;
1619 
1620  if (((*buff) >= '0' && (*buff) <= '9') || ((*buff) >= 'A' && (*buff) <= 'Z') || ((*buff) >= 'a' && (*buff) <= 'z') || ((*buff) && strchr("/\\?*", (*buff))))
1621  return buff;
1622  }
1623 
1624  fclose(f);
1625  return NULL;
1626 }
smooth NULL
Definition: ftsmooth.c:416
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
char * strchr(const char *String, int ch)
Definition: utclib.c:501
char * myTrim(char *target, char *source)
Definition: tftpd.cpp:1689
static unsigned char buff[32768]
Definition: fatten.c:17

◆ runProg()

void runProg ( )

Definition at line 393 of file tftpd.cpp.

Referenced by main().

394 {
395  verbatim = true;
396 
397  if (_beginthread(init, 0, 0) == 0)
398  {
399  if (cfig.logLevel)
400  {
401  sprintf(logBuff, "Thread Creation Failed");
402  logMess(logBuff, 1);
403  }
404  exit(-1);
405  }
406 
407  fd_set readfds;
408  timeval tv;
409  int fdsReady = 0;
410  tv.tv_sec = 20;
411  tv.tv_usec = 0;
412 
413  printf("\naccepting requests..\n");
414 
415  do
416  {
417  network.busy = false;
418 
419  //printf("Active=%u Total=%u\n",activeThreads, totalThreads);
420 
421  if (!network.tftpConn[0].ready || !network.ready)
422  {
423  Sleep(1000);
424  continue;
425  }
426 
427  FD_ZERO(&readfds);
428 
429  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].ready; i++)
430  FD_SET(network.tftpConn[i].sock, &readfds);
431 
432  fdsReady = select(network.maxFD, &readfds, NULL, NULL, &tv);
433 
434  if (!network.ready)
435  continue;
436 
437  //errno = WSAGetLastError();
438 
439  //if (errno)
440  // printf("%d\n", errno);
441 
442  for (int i = 0; fdsReady > 0 && i < MAX_SERVERS && network.tftpConn[i].ready; i++)
443  {
444  if (network.ready)
445  {
446  network.busy = true;
447 
448  if (FD_ISSET(network.tftpConn[i].sock, &readfds))
449  {
450  //printf("%d Requests Waiting\n", fdsReady);
451 
453 
454  currentServer = i;
455 
457  {
458  _beginthread(
459  processRequest, // thread function
460  0, // default security attributes
461  NULL); // argument to thread function
462  }
463  SetEvent(tEvent);
464 
465  //printf("thread signalled=%u\n",SetEvent(tEvent));
466 
468  fdsReady--;
469  SetEvent(sEvent);
470  }
471  }
472  }
473  }
474  while (true);
475 
476  closeConn();
477 
478  WSACleanup();
479 }
Definition: winsock.h:66
data2 cfig
Definition: tftpd.cpp:51
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
unsigned long tv_sec
Definition: linux.h:1738
char logBuff[512]
Definition: tftpd.cpp:42
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
bool busy
Definition: tftpd.h:134
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
GLenum GLclampf GLint i
Definition: glfuncs.h:14
SOCKET maxFD
Definition: tftpd.h:132
#define FD_ISSET(fd, set)
Definition: winsock.h:100
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
smooth NULL
Definition: ftsmooth.c:416
unsigned long tv_usec
Definition: linux.h:1739
bool ready
Definition: tftpd.h:133
data1 network
Definition: tftpd.cpp:49
bool ready
Definition: tftpd.h:50
void processRequest(void *lpParam)
Definition: tftpd.cpp:488
void init(void *lpParam)
Definition: tftpd.cpp:1805
SOCKET sock
Definition: tftpd.h:45
HANDLE tEvent
Definition: tftpd.cpp:53
char verbatim
Definition: tftpd.cpp:46
MYBYTE logLevel
Definition: tftpd.h:153
MYBYTE currentServer
Definition: tftpd.cpp:57
#define MAX_SERVERS
Definition: tftpd.h:34
HANDLE sEvent
Definition: tftpd.cpp:55
MYWORD totalThreads
Definition: tftpd.cpp:58
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
MYWORD activeThreads
Definition: tftpd.cpp:60
void exit(int exitcode)
Definition: _exit.c:33
#define INFINITE
Definition: serial.h:102
tftpConnType tftpConn[MAX_SERVERS]
Definition: tftpd.h:127
void logMess(char *logBuff, MYBYTE logLevel)
Definition: tftpd.cpp:2585
#define printf
Definition: config.h:203
void closeConn()
Definition: tftpd.cpp:481

◆ runService()

void runService ( )

Definition at line 214 of file tftpd.cpp.

Referenced by main().

215 {
216  SERVICE_TABLE_ENTRY serviceTable[] =
217  {
219  {0, 0}
220  };
221 
222  StartServiceCtrlDispatcher(serviceTable);
223 }
void WINAPI ServiceMain(DWORD, TCHAR *[])
Definition: tftpd.cpp:98
#define StartServiceCtrlDispatcher
Definition: winsvc.h:586
char serviceName[]
Definition: tftpd.cpp:34

◆ ServiceControlHandler()

void WINAPI ServiceControlHandler ( DWORD  controlCode)

Definition at line 67 of file tftpd.cpp.

Referenced by ServiceMain().

68 {
69  switch (controlCode)
70  {
72  break;
73 
78 
80  return ;
81 
83  break;
84 
86  break;
87 
88  default:
89  if (controlCode >= 128 && controlCode <= 255)
90  break;
91  else
92  break;
93  }
94 
96 }
return
Definition: dirsup.c:529
DWORD dwCurrentState
Definition: winsvc.h:100
SERVICE_STATUS_HANDLE serviceStatusHandle
Definition: tftpd.cpp:64
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:957
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39
HANDLE stopServiceEvent
Definition: tftpd.cpp:65
SERVICE_STATUS serviceStatus
Definition: tftpd.cpp:63
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40

◆ ServiceMain()

void WINAPI ServiceMain ( DWORD  ,
TCHAR [] 
)

Definition at line 98 of file tftpd.cpp.

Referenced by runService().

99 {
107 
109 
111  {
114 
115  //init
116  verbatim = false;
117 
118  if (_beginthread(init, 0, 0) == 0)
119  {
120  if (cfig.logLevel)
121  {
122  sprintf(logBuff, "Thread Creation Failed");
123  logMess(logBuff, 1);
124  }
125  exit(-1);
126  }
127 
128  fd_set readfds;
129  timeval tv;
130  tv.tv_sec = 20;
131  tv.tv_usec = 0;
132 
134 
138 
139  do
140  {
141  network.busy = false;
142 
143  if (!network.tftpConn[0].ready || !network.ready)
144  {
145  Sleep(1000);
146  continue;
147  }
148 
149  FD_ZERO(&readfds);
150 
151  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].ready; i++)
152  FD_SET(network.tftpConn[i].sock, &readfds);
153 
154  int fdsReady = select(network.maxFD, &readfds, NULL, NULL, &tv);
155 
156  for (int i = 0; fdsReady > 0 && i < MAX_SERVERS && network.tftpConn[i].ready; i++)
157  {
158  if (network.ready)
159  {
160  network.busy = true;
161 
162  if (FD_ISSET(network.tftpConn[i].sock, &readfds))
163  {
165 
166  currentServer = i;
167 
169  {
170  _beginthread(
171  processRequest, // thread function
172  0, // default security attributes
173  NULL); // argument to thread function
174 
175  }
176 
177  SetEvent(tEvent);
179  fdsReady--;
180  SetEvent(sEvent);
181  }
182  }
183  }
184  }
186 
189 
190  sprintf(logBuff, "Closing Network Connections...");
191  logMess(logBuff, 1);
192 
193  closeConn();
194 
195  WSACleanup();
196 
197  sprintf(logBuff, "TFTP Server Stopped !\n");
198  logMess(logBuff, 1);
199 
200  if (cfig.logfile)
201  {
203  cfig.logfile = NULL;
204  }
205 
210  stopServiceEvent = 0;
211  }
212 }
#define CreateEvent
Definition: winbase.h:3562
Definition: winsock.h:66
data2 cfig
Definition: tftpd.cpp:51
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
DWORD dwCurrentState
Definition: winsvc.h:100
FILE * logfile
Definition: tftpd.h:145
SERVICE_STATUS_HANDLE serviceStatusHandle
Definition: tftpd.cpp:64
unsigned long tv_sec
Definition: linux.h:1738
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
char logBuff[512]
Definition: tftpd.cpp:42
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
bool busy
Definition: tftpd.h:134
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
#define SERVICE_START_PENDING
Definition: winsvc.h:22
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89
#define NO_ERROR
Definition: dderror.h:5
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:957
#define sprintf(buf, format,...)
Definition: sprintf.c:55
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
GLenum GLclampf GLint i
Definition: glfuncs.h:14
SOCKET maxFD
Definition: tftpd.h:132
DWORD dwCheckPoint
Definition: winsvc.h:104
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define RegisterServiceCtrlHandler
Definition: winsvc.h:583
#define FD_ISSET(fd, set)
Definition: winsock.h:100
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define SERVICE_RUNNING
Definition: winsvc.h:24
smooth NULL
Definition: ftsmooth.c:416
unsigned long tv_usec
Definition: linux.h:1739
void WINAPI ServiceControlHandler(DWORD controlCode)
Definition: tftpd.cpp:67
bool ready
Definition: tftpd.h:133
data1 network
Definition: tftpd.cpp:49
bool ready
Definition: tftpd.h:50
void processRequest(void *lpParam)
Definition: tftpd.cpp:488
char serviceName[]
Definition: tftpd.cpp:34
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
void init(void *lpParam)
Definition: tftpd.cpp:1805
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwWin32ExitCode
Definition: winsvc.h:102
HANDLE stopServiceEvent
Definition: tftpd.cpp:65
DWORD dwServiceType
Definition: winsvc.h:99
SERVICE_STATUS serviceStatus
Definition: tftpd.cpp:63
#define WAIT_TIMEOUT
Definition: dderror.h:14
SOCKET sock
Definition: tftpd.h:45
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
HANDLE tEvent
Definition: tftpd.cpp:53
char verbatim
Definition: tftpd.cpp:46
DWORD dwControlsAccepted
Definition: winsvc.h:101
MYBYTE logLevel
Definition: tftpd.h:153
MYBYTE currentServer
Definition: tftpd.cpp:57
#define MAX_SERVERS
Definition: tftpd.h:34
#define SERVICE_WIN32
Definition: cmtypes.h:962
HANDLE sEvent
Definition: tftpd.cpp:55
MYWORD totalThreads
Definition: tftpd.cpp:58
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
MYWORD activeThreads
Definition: tftpd.cpp:60
void exit(int exitcode)
Definition: _exit.c:33
#define INFINITE
Definition: serial.h:102
tftpConnType tftpConn[MAX_SERVERS]
Definition: tftpd.h:127
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
void logMess(char *logBuff, MYBYTE logLevel)
Definition: tftpd.cpp:2585
void closeConn()
Definition: tftpd.cpp:481

◆ stopService()

bool stopService ( SC_HANDLE  service)

Definition at line 225 of file tftpd.cpp.

Referenced by main(), and uninstallService().

226 {
227  if (service)
228  {
230  QueryServiceStatus(service, &serviceStatus);
231  if (serviceStatus.dwCurrentState != SERVICE_STOPPED)
232  {
233  ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus);
234  printf("Stopping Service.");
235  for (int i = 0; i < 100; i++)
236  {
237  QueryServiceStatus(service, &serviceStatus);
238  if (serviceStatus.dwCurrentState == SERVICE_STOPPED)
239  {
240  printf("Stopped\n");
241  return true;
242  }
243  else
244  {
245  Sleep(500);
246  printf(".");
247  }
248  }
249  printf("Failed\n");
250  return false;
251  }
252  }
253  return true;
254 }
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
DWORD dwCurrentState
Definition: winsvc.h:100
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define SERVICE_STOPPED
Definition: winsvc.h:21
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2787
SERVICE_STATUS serviceStatus
Definition: tftpd.cpp:63
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:618
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define printf
Definition: config.h:203

◆ uninstallService()

void uninstallService ( )

Definition at line 296 of file tftpd.cpp.

Referenced by main().

297 {
298  SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
299 
300  if (serviceControlManager)
301  {
302  SC_HANDLE service = OpenService(serviceControlManager,
304  if (service)
305  {
306  if (stopService(service))
307  {
308  DeleteService(service);
309  printf("Successfully Removed !\n");
310  }
311  else
312  printf("Failed to Stop Service..\n");
313 
314  CloseServiceHandle(service);
315  }
316 
317  CloseServiceHandle(serviceControlManager);
318  }
319  else
321 }
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:915
#define OpenService
Definition: winsvc.h:576
void printWindowsError()
Definition: tftpd.cpp:323
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:576
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
char serviceName[]
Definition: tftpd.cpp:34
#define OpenSCManager
Definition: winsvc.h:575
#define SERVICE_STOP
Definition: winsvc.h:58
bool stopService(SC_HANDLE service)
Definition: tftpd.cpp:225
#define DELETE
Definition: nt_native.h:57
#define printf
Definition: config.h:203

Variable Documentation

◆ activeThreads

MYWORD activeThreads =0

Definition at line 60 of file tftpd.cpp.

Referenced by cleanReq(), processRequest(), runProg(), and ServiceMain().

◆ blksize

MYWORD blksize = 65464

Definition at line 45 of file tftpd.cpp.

Referenced by init(), and processRequest().

◆ cEvent

HANDLE cEvent

Definition at line 54 of file tftpd.cpp.

◆ cfig

data2 cfig

Definition at line 51 of file tftpd.cpp.

◆ currentServer

MYBYTE currentServer = UCHAR_MAX

Definition at line 57 of file tftpd.cpp.

Referenced by processRequest(), runProg(), and ServiceMain().

◆ displayName

char displayName[] = "Open TFTP Server, MultiThreaded"

Definition at line 35 of file tftpd.cpp.

Referenced by installService(), ItemMonikerImpl_ParseDisplayName(), and test_GetName().

◆ extbuff

char extbuff[_MAX_PATH]

Definition at line 41 of file tftpd.cpp.

Referenced by init(), and logMess().

◆ fileSep

char fileSep = '\\'

Definition at line 43 of file tftpd.cpp.

Referenced by init(), and processRequest().

◆ iniFile

char iniFile[_MAX_PATH]

Definition at line 37 of file tftpd.cpp.

Referenced by init().

◆ lEvent

HANDLE lEvent

Definition at line 56 of file tftpd.cpp.

Referenced by WSPAsyncSelect().

◆ lnkFile

char lnkFile[_MAX_PATH]

Definition at line 39 of file tftpd.cpp.

Referenced by init(), and logMess().

◆ logBuff

char logBuff[512]

Definition at line 42 of file tftpd.cpp.

Referenced by detectChange(), init(), runProg(), and ServiceMain().

◆ logFile

char logFile[_MAX_PATH]

Definition at line 38 of file tftpd.cpp.

Referenced by handle_escape_cmd(), init(), and logMess().

◆ loggingDay

MYWORD loggingDay

Definition at line 48 of file tftpd.cpp.

Referenced by init(), and logMess().

◆ minThreads

MYWORD minThreads =1

Definition at line 59 of file tftpd.cpp.

Referenced by cleanReq(), and init().

◆ network

data1 network

Definition at line 49 of file tftpd.cpp.

Referenced by wnet_use_connection().

◆ newNetwork

data1 newNetwork

Definition at line 50 of file tftpd.cpp.

Referenced by NetBTEnum().

◆ notFileSep

char notFileSep = '/'

Definition at line 44 of file tftpd.cpp.

Referenced by init(), and processRequest().

◆ serviceName

char serviceName[] = "TFTPServer"

◆ serviceStatus

SERVICE_STATUS serviceStatus

Definition at line 63 of file tftpd.cpp.

Referenced by StopDriver(), and stopService().

◆ serviceStatusHandle

SERVICE_STATUS_HANDLE serviceStatusHandle = 0

Definition at line 64 of file tftpd.cpp.

Referenced by ServiceControlHandler(), and ServiceMain().

◆ sEvent

HANDLE sEvent

Definition at line 55 of file tftpd.cpp.

◆ stopServiceEvent

HANDLE stopServiceEvent = 0

Definition at line 65 of file tftpd.cpp.

◆ sVersion

char sVersion[] = "Open TFTP Server MultiThreaded Version 1.64 Windows Built 2001"

Definition at line 36 of file tftpd.cpp.

Referenced by init(), and logMess().

◆ tempbuff

char tempbuff[256]

Definition at line 40 of file tftpd.cpp.

Referenced by init(), logMess(), and processRequest().

◆ tEvent

HANDLE tEvent

Definition at line 53 of file tftpd.cpp.

◆ timeout

Definition at line 47 of file tftpd.cpp.

Referenced by processRequest().

◆ totalThreads

MYWORD totalThreads =0

Definition at line 58 of file tftpd.cpp.

Referenced by cleanReq(), processRequest(), runProg(), and ServiceMain().

◆ verbatim

char verbatim = 0

Definition at line 46 of file tftpd.cpp.

Referenced by init(), logMess(), runProg(), and ServiceMain().