ReactOS 0.4.16-dev-329-g9223134
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.

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}
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: dhcpd.h:62
#define MYBYTE
Definition: tftpd.h:21
#define MAX_SERVERS
Definition: tftpd.h:34

Referenced by getInterfaces().

◆ cleanReq()

bool cleanReq ( request req)

Definition at line 1505 of file tftpd.cpp.

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--;
1527
1528 //printf("cleaned\n");
1529
1530 return (totalThreads <= minThreads);
1531}
#define free
Definition: debug_ros.c:5
#define INFINITE
Definition: serial.h:102
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
#define closesocket
Definition: ncftp.h:477
FILE * file
Definition: tftpd.h:95
packet * pkt[2]
Definition: tftpd.h:104
SOCKET sock
Definition: tftpd.h:90
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
MYWORD minThreads
Definition: tftpd.cpp:59
MYWORD activeThreads
Definition: tftpd.cpp:60
HANDLE cEvent
Definition: tftpd.cpp:54
MYWORD totalThreads
Definition: tftpd.cpp:58
#define INVALID_SOCKET
Definition: winsock.h:332

Referenced by processRequest().

◆ closeConn()

void closeConn ( )

Definition at line 481 of file tftpd.cpp.

482{
483 for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].loaded; i++)
484 if (network.tftpConn[i].ready)
486}
tftpConnType tftpConn[MAX_SERVERS]
Definition: tftpd.h:127
bool loaded
Definition: tftpd.h:49
SOCKET sock
Definition: tftpd.h:45
bool ready
Definition: tftpd.h:50
data1 network
Definition: tftpd.cpp:49

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

◆ detectChange()

bool detectChange ( )

Definition at line 2428 of file tftpd.cpp.

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}
#define NO_ERROR
Definition: dderror.h:5
#define NULL
Definition: types.h:112
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
double pow(double x, double y)
Definition: freeldr.c:110
#define printf
Definition: freeldr.h:97
#define UINT_MAX
Definition: intsafe.h:152
DWORD WINAPI NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped)
#define sprintf(buf, format,...)
Definition: sprintf.c:55
HANDLE hEvent
Definition: winbase.h:845
bool busy
Definition: tftpd.h:134
bool ready
Definition: tftpd.h:133
bool ifspecified
Definition: tftpd.h:154
MYDWORD failureCount
Definition: tftpd.h:152
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
char logBuff[512]
Definition: tftpd.cpp:42
void logMess(char *logBuff, MYBYTE logLevel)
Definition: tftpd.cpp:2585
data2 cfig
Definition: tftpd.cpp:51
#define MYDWORD
Definition: tftpd.h:23
int ret
#define WAIT_OBJECT_0
Definition: winbase.h:432
WINSOCK_API_LINKAGE WSAEVENT WSAAPI WSACreateEvent(void)
Definition: event.c:42
#define WSA_IO_PENDING
Definition: winsock2.h:616
int PASCAL FAR WSAGetLastError(void)
Definition: dllmain.c:112

Referenced by init().

◆ findServer()

MYDWORD * findServer ( MYDWORD array,
MYDWORD  ip 
)

Definition at line 2572 of file tftpd.cpp.

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}

Referenced by init().

◆ getInterfaces()

void getInterfaces ( data1 network)

Definition at line 2519 of file tftpd.cpp.

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
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}
return
Definition: dirsup.c:529
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
unsigned long u_long
Definition: linux.h:269
static const WCHAR sd[]
Definition: suminfo.c:286
#define memset(x, y, z)
Definition: compat.h:39
Definition: tftpd.h:126
MYDWORD staticServers[MAX_SERVERS]
Definition: tftpd.h:129
MYDWORD allServers[MAX_SERVERS]
Definition: tftpd.h:128
struct in_addr sin_addr
Definition: winsock.h:512
bool addServer(MYDWORD *array, MYDWORD ip)
Definition: tftpd.cpp:2557
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:181
#define WSASocket
Definition: winsock2.h:2407
#define PF_INET
Definition: winsock.h:373
#define SOCK_DGRAM
Definition: winsock.h:336
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define SIO_GET_INTERFACE_LIST
Definition: ws2ipdef.h:62
#define IFF_POINTTOPOINT
Definition: ws2ipdef.h:24
struct _INTERFACE_INFO INTERFACE_INFO
#define IFF_UP
Definition: ws2ipdef.h:21

Referenced by init().

◆ 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);
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
char * strchr(const char *String, int ch)
Definition: utclib.c:501
static unsigned char buff[32768]
Definition: fatten.c:17
uint32_t serial
Definition: fsck.fat.h:29
GLuint buffer
Definition: glext.h:5915
GLfloat f
Definition: glext.h:7540
_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)
Definition: parser.c:56
char * myTrim(char *target, char *source)
Definition: tftpd.cpp:1689
char * myUpper(char *string)
Definition: tftpd.cpp:1785

◆ init()

void init ( void lpParam)

Definition at line 1805 of file tftpd.cpp.

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 {
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 {
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 {
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)
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;
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 {
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__
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: ");
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
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
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
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
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 {
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 {
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 {
2288
2289 if (!addr)
2290 {
2293 fclose(f);
2294 break;
2295 }
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 {
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
2389 break;
2390
2391 i++;
2392 }
2393 }
2394
2395 if (bindfailed)
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 {
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}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define INADDR_NONE
Definition: tcp.c:42
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
USHORT port
Definition: uri.c:228
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define IPPROTO_UDP
Definition: ip.h:197
__kernel_time_t time_t
Definition: linux.h:252
#define AF_INET
Definition: tcpip.h:117
#define strcasecmp
Definition: fake.h:9
GLdouble GLdouble t
Definition: gl.h:2047
GLdouble n
Definition: glext.h:7729
GLenum const GLvoid * addr
Definition: glext.h:9621
GLsizei GLenum const GLvoid GLsizei GLenum 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 const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
#define UCHAR_MAX
Definition: limits.h:25
#define USHRT_MAX
Definition: limits.h:38
#define TEXT(s)
Definition: k32.h:26
__u16 time
Definition: mkdosfs.c:8
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define htons(x)
Definition: module.h:215
#define htonl(x)
Definition: module.h:214
#define _MAX_PATH
Definition: utility.h:77
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
static PVOID ptr
Definition: dispmode.c:27
int k
Definition: mpi.c:3369
static calc_node_t temp
Definition: rpn_ieee.c:38
#define errno
Definition: errno.h:18
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
_CRTIMP void __cdecl _endthread(void)
Definition: thread.c:95
_CRT_RESTORE_GCC_WARNINGS _CRT_DISABLE_GCC_WARNINGS _Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:416
#define exit(n)
Definition: config.h:202
#define _countof(array)
Definition: sndvol32.h:70
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:294
WORD wVersion
Definition: winsock.h:517
MYDWORD rangeEnd
Definition: tftpd.h:82
MYDWORD rangeStart
Definition: tftpd.h:81
SOCKET maxFD
Definition: tftpd.h:132
MYDWORD listenServers[MAX_SERVERS]
Definition: tftpd.h:130
MYWORD listenPorts[MAX_SERVERS]
Definition: tftpd.h:131
data12 hostRanges[32]
Definition: tftpd.h:146
char fileWrite
Definition: tftpd.h:148
MYBYTE logLevel
Definition: tftpd.h:153
char fileOverwrite
Definition: tftpd.h:149
int maxport
Definition: tftpd.h:151
char fileRead
Definition: tftpd.h:147
int minport
Definition: tftpd.h:150
WSADATA wsaData
Definition: tftpd.h:139
home homes[8]
Definition: tftpd.h:143
FILE * logfile
Definition: tftpd.h:145
char alias[64]
Definition: tftpd.h:39
char target[256]
Definition: tftpd.h:40
Definition: name.c:39
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
MYWORD port
Definition: tftpd.h:48
MYDWORD server
Definition: tftpd.h:47
sockaddr_in addr
Definition: tftpd.h:46
Definition: dhcpd.h:245
Definition: time.h:68
int tm_yday
Definition: time.h:76
MYWORD blksize
Definition: tftpd.cpp:45
MYWORD loggingDay
Definition: tftpd.cpp:48
char iniFile[_MAX_PATH]
Definition: tftpd.cpp:37
bool detectChange()
Definition: tftpd.cpp:2428
bool isIP(char *string)
Definition: tftpd.cpp:1767
char extbuff[_MAX_PATH]
Definition: tftpd.cpp:41
char logFile[_MAX_PATH]
Definition: tftpd.cpp:38
char sVersion[]
Definition: tftpd.cpp:36
FILE * openSection(const char *sectionName, MYBYTE serial, char *fileName)
Definition: tftpd.cpp:1581
char verbatim
Definition: tftpd.cpp:46
char notFileSep
Definition: tftpd.cpp:44
HANDLE sEvent
Definition: tftpd.cpp:55
char lnkFile[_MAX_PATH]
Definition: tftpd.cpp:39
void closeConn()
Definition: tftpd.cpp:481
void getInterfaces(data1 *network)
Definition: tftpd.cpp:2519
HANDLE lEvent
Definition: tftpd.cpp:56
char tempbuff[256]
Definition: tftpd.cpp:40
char * IP2String(char *target, MYDWORD ip)
Definition: tftpd.cpp:1759
void processRequest(void *lpParam)
Definition: tftpd.cpp:488
char fileSep
Definition: tftpd.cpp:43
MYDWORD * findServer(MYDWORD *array, MYDWORD ip)
Definition: tftpd.cpp:2572
char * readSection(char *buff, FILE *f)
Definition: tftpd.cpp:1611
void mySplit(char *name, char *value, char *source, char splitChar)
Definition: tftpd.cpp:1730
HANDLE tEvent
Definition: tftpd.cpp:53
data1 newNetwork
Definition: tftpd.cpp:50
#define my_inet_addr
Definition: tftpd.h:33
#define MYWORD
Definition: tftpd.h:22
#define MAKEWORD(a, b)
Definition: typedefs.h:248
Definition: pdh_main.c:94
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CreateEvent
Definition: winbase.h:3773
#define WritePrivateProfileString
Definition: winbase.h:3948
#define GetModuleFileName
Definition: winbase.h:3856

◆ installService()

void installService ( )

Definition at line 256 of file tftpd.cpp.

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}
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:580
char serviceName[]
Definition: tftpd.cpp:34
char displayName[]
Definition: tftpd.cpp:35
void printWindowsError()
Definition: tftpd.cpp:323
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
#define OpenSCManager
Definition: winsvc.h:575
#define SERVICE_ALL_ACCESS
Definition: winsvc.h:62
#define CreateService
Definition: winsvc.h:569
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define StartService
Definition: winsvc.h:585
#define OpenService
Definition: winsvc.h:576
#define SERVICE_AUTO_START
Definition: cmtypes.h:977
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:981
char TCHAR
Definition: xmlstorage.h:189

Referenced by main().

◆ IP2String()

char * IP2String ( char target,
MYDWORD  ip 
)

Definition at line 1759 of file tftpd.cpp.

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}
GLenum target
Definition: glext.h:7315
Definition: tftpd.h:158
unsigned ip
Definition: tftpd.h:162
MYBYTE octate[4]
Definition: tftpd.h:163

Referenced by init(), and logMess().

◆ isIP()

bool isIP ( char string)

Definition at line 1767 of file tftpd.cpp.

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}
char string[160]
Definition: util.h:11

Referenced by init().

◆ logMess() [1/2]

void logMess ( char logBuff,
MYBYTE  logLevel 
)

Definition at line 2585 of file tftpd.cpp.

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);
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);
2618 }
2620}
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)

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

◆ 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);
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
2670 }
2672}
#define ntohs(x)
Definition: module.h:210
const char * strerror(int err)
Definition: compat_str.c:23
char path[256]
Definition: tftpd.h:94
tftperror serverError
Definition: tftpd.h:109
sockaddr_in client
Definition: tftpd.h:105
char errormessage[512]
Definition: tftpd.h:69

◆ 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
353 {
354 if (argc > 1 && lstrcmpi(argv[1], TEXT("-i")) == 0)
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
GLuint64EXT * result
Definition: glext.h:11304
#define argv
Definition: mplay32.c:18
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:238
ULONG dwPlatformId
Definition: rtltypes.h:241
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:237
void uninstallService()
Definition: tftpd.cpp:296
void runProg()
Definition: tftpd.cpp:393
void installService()
Definition: tftpd.cpp:256
bool stopService(SC_HANDLE service)
Definition: tftpd.cpp:225
void runService()
Definition: tftpd.cpp:214
OSVERSIONINFO osvi
Definition: ver.c:28
#define lstrcmpi
Definition: winbase.h:3898
#define GetVersionEx
Definition: winbase.h:3877
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
#define SERVICE_STOP
Definition: winsvc.h:58

◆ 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}
GLuint index
Definition: glext.h:6031

◆ 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}
GLenum GLsizei len
Definition: glext.h:6722

◆ mySplit()

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

Definition at line 1730 of file tftpd.cpp.

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}

Referenced by init().

◆ 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}

◆ myTrim()

char * myTrim ( char target,
char source 
)

Definition at line 1689 of file tftpd.cpp.

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}

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

◆ myUpper()

char * myUpper ( char string)

Definition at line 1785 of file tftpd.cpp.

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}

Referenced by getSection(), and openSection().

◆ openSection()

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

Definition at line 1581 of file tftpd.cpp.

1582{
1583 //printf("%s=%s\n",fileName,sectionName);
1584 char section[128];
1585 sprintf(section, "[%s]", sectionName);
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}
#define f
Definition: ke_i.h:83

Referenced by init().

◆ printWindowsError()

void printWindowsError ( )

Definition at line 323 of file tftpd.cpp.

324{
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}
_Check_return_ _CRTIMP int __cdecl getchar(void)
Definition: file.c:3629
REFIID LPVOID DWORD_PTR dw
Definition: atlbase.h:40
#define LANG_NEUTRAL
Definition: nls.h:22
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SUBLANG_DEFAULT
Definition: nls.h:168
#define FormatMessage
Definition: winbase.h:3820
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:446
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:449
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:445
CHAR * LPTSTR
Definition: xmlstorage.h:192

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

◆ processRequest()

void processRequest ( void lpParam)

Definition at line 488 of file tftpd.cpp.

489{
490 //printf("New Thread %u\n",GetCurrentThreadId());
491
492 request req;
493
495 totalThreads++;
497
498 do
499 {
501 //printf("In Thread %u\n",GetCurrentThreadId());
502
506
508 {
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);
520 req.knock = network.tftpConn[req.sockInd].sock;
521
522 if (req.knock == INVALID_SOCKET)
523 {
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));
535
536 if (!errno && req.bytesRecd > 0)
537 {
539 {
540 MYDWORD iip = ntohl(req.client.sin_addr.s_addr);
541 bool allowed = false;
542
543#ifdef __REACTOS__
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 {
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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--;
1499
1500 //printf("Thread %u Killed\n",GetCurrentThreadId());
1501 _endthread();
1502 return;
1503}
CHAR FAR *WSAAPI inet_ntoa(IN IN_ADDR in)
Definition: addrconv.c:160
#define SEEK_END
Definition: cabinet.c:29
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
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
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
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
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
GLuint GLfloat * val
Definition: glext.h:7180
_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)
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
_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)
#define _IOFBF
Definition: stdio.h:127
_Check_return_opt_ _CRTIMP int __cdecl setvbuf(_Inout_ FILE *_File, _Inout_updates_opt_z_(_Size) char *_Buf, _In_ int _Mode, _In_ size_t _Size)
#define SEEK_SET
Definition: jmemansi.c:26
#define ntohl(x)
Definition: module.h:205
#define calloc
Definition: rosglue.h:14
MYWORD opcode
Definition: tftpd.h:55
MYWORD block
Definition: tftpd.h:56
Definition: tftpd.h:60
MYWORD opcode
Definition: tftpd.h:61
char buffer[514]
Definition: tftpd.h:62
Definition: dhcpd.h:135
char buffer
Definition: tftpd.h:76
MYWORD opcode
Definition: tftpd.h:74
MYWORD block
Definition: tftpd.h:75
Definition: tftpd.h:86
MYBYTE sockInd
Definition: tftpd.h:92
MYDWORD tsize
Definition: tftpd.h:99
char * filename
Definition: tftpd.h:96
acknowledgement acin
Definition: tftpd.h:117
int bytesReady
Definition: tftpd.h:101
time_t expiry
Definition: tftpd.h:89
MYWORD blksize
Definition: tftpd.h:119
int bytesRecd
Definition: tftpd.h:102
MYBYTE attempt
Definition: tftpd.h:93
SOCKET knock
Definition: tftpd.h:91
char * mode
Definition: tftpd.h:97
int bytesRead[2]
Definition: tftpd.h:103
MYDWORD fblock
Definition: tftpd.h:100
acknowledgement acout
Definition: tftpd.h:111
MYWORD tblock
Definition: tftpd.h:122
MYWORD timeout
Definition: tftpd.h:120
fd_set readfds
Definition: tftpd.h:88
tftperror clientError
Definition: tftpd.h:115
message mesin
Definition: tftpd.h:116
socklen_t clientsize
Definition: tftpd.h:106
timeval tv
Definition: tftpd.h:87
message mesout
Definition: tftpd.h:110
MYWORD block
Definition: tftpd.h:121
MYWORD opcode
Definition: tftpd.h:67
MYWORD errorcode
Definition: tftpd.h:68
unsigned long tv_sec
Definition: linux.h:1738
unsigned long tv_usec
Definition: linux.h:1739
MYBYTE currentServer
Definition: tftpd.cpp:57
MYWORD timeout
Definition: tftpd.cpp:47
bool cleanReq(request *req)
Definition: tftpd.cpp:1505
#define FD_ISSET(fd, set)
Definition: winsock.h:100
#define FD_ZERO(set)
Definition: winsock.h:96
#define FD_SET(fd, set)
Definition: winsock.h:89

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

◆ readSection()

char * readSection ( char buff,
FILE f 
)

Definition at line 1611 of file tftpd.cpp.

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}

Referenced by init().

◆ runProg()

void runProg ( )

Definition at line 393 of file tftpd.cpp.

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
455
457 {
459 processRequest, // thread function
460 0, // default security attributes
461 NULL); // argument to thread function
462 }
464
465 //printf("thread signalled=%u\n",SetEvent(tEvent));
466
468 fdsReady--;
470 }
471 }
472 }
473 }
474 while (true);
475
476 closeConn();
477
478 WSACleanup();
479}
Definition: winsock.h:66
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
static int init
Definition: wintirpc.c:33

Referenced by main().

◆ runService()

void runService ( )

Definition at line 214 of file tftpd.cpp.

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

Referenced by main().

◆ ServiceControlHandler()

void WINAPI ServiceControlHandler ( DWORD  controlCode)

Definition at line 67 of file tftpd.cpp.

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}
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:997
DWORD dwCurrentState
Definition: winsvc.h:100
SERVICE_STATUS_HANDLE serviceStatusHandle
Definition: tftpd.cpp:64
SERVICE_STATUS serviceStatus
Definition: tftpd.cpp:63
HANDLE stopServiceEvent
Definition: tftpd.cpp:65
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39

Referenced by ServiceMain().

◆ ServiceMain()

void WINAPI ServiceMain ( DWORD  ,
TCHAR [] 
)

Definition at line 98 of file tftpd.cpp.

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
167
169 {
171 processRequest, // thread function
172 0, // default security attributes
173 NULL); // argument to thread function
174
175 }
176
179 fdsReady--;
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
211 }
212}
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define CloseHandle
Definition: compat.h:739
DWORD dwServiceType
Definition: winsvc.h:99
DWORD dwWin32ExitCode
Definition: winsvc.h:102
DWORD dwControlsAccepted
Definition: winsvc.h:101
DWORD dwWaitHint
Definition: winsvc.h:105
DWORD dwCheckPoint
Definition: winsvc.h:104
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
void WINAPI ServiceControlHandler(DWORD controlCode)
Definition: tftpd.cpp:67
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
#define SERVICE_START_PENDING
Definition: winsvc.h:22
#define SERVICE_RUNNING
Definition: winsvc.h:24
#define RegisterServiceCtrlHandler
Definition: winsvc.h:583
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
#define SERVICE_WIN32
Definition: cmtypes.h:964

Referenced by runService().

◆ stopService()

bool stopService ( SC_HANDLE  service)

Definition at line 225 of file tftpd.cpp.

226{
227 if (service)
228 {
232 {
234 printf("Stopping Service.");
235 for (int i = 0; i < 100; i++)
236 {
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}
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2845
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:622

Referenced by main(), and uninstallService().

◆ uninstallService()

void uninstallService ( )

Definition at line 296 of file tftpd.cpp.

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 DELETE
Definition: nt_native.h:57
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:921

Referenced by main().

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.

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

◆ cfig

data2 cfig

Definition at line 51 of file tftpd.cpp.

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

◆ currentServer

MYBYTE currentServer = UCHAR_MAX

Definition at line 57 of file tftpd.cpp.

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

◆ displayName

◆ 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(), and test_profile_int().

◆ lEvent

◆ 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(), logMess(), 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

◆ newNetwork

data1 newNetwork

Definition at line 50 of file tftpd.cpp.

Referenced by init(), and NetBTEnum().

◆ notFileSep

char notFileSep = '/'

Definition at line 44 of file tftpd.cpp.

Referenced by init(), and processRequest().

◆ serviceName

◆ serviceStatus

SERVICE_STATUS serviceStatus

Definition at line 63 of file tftpd.cpp.

Referenced by ServiceControlHandler(), ServiceMain(), 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.

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

◆ stopServiceEvent

HANDLE stopServiceEvent = 0

Definition at line 65 of file tftpd.cpp.

Referenced by ServiceControlHandler(), and ServiceMain().

◆ 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.

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

◆ 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().