ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

tftpd.cpp
Go to the documentation of this file.
00001 /**************************************************************************
00002 *   Copyright (C) 2005 by Achal Dhir                                      *
00003 *   achaldhir@gmail.com                                                   *
00004 *                                                                         *
00005 *   This program is free software; you can redistribute it and/or modify  *
00006 *   it under the terms of the GNU General Public License as published by  *
00007 *   the Free Software Foundation; either version 2 of the License, or     *
00008 *   (at your option) any later version.                                   *
00009 *                                                                         *
00010 *   This program is distributed in the hope that it will be useful,       *
00011 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013 *   GNU General Public License for more details.                          *
00014 *                                                                         *
00015 *   You should have received a copy of the GNU General Public License     *
00016 *   along with this program; if not, write to the                         *
00017 *   Free Software Foundation, Inc.,                                       *
00018 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019 ***************************************************************************/
00020 // TFTPServer.cpp
00021 
00022 #include <stdio.h>
00023 #include <winsock2.h>
00024 #include <process.h>
00025 #include <time.h>
00026 #include <tchar.h>
00027 #include <ws2tcpip.h>
00028 #include <limits.h>
00029 #include <iphlpapi.h>
00030 #include "tftpd.h"
00031 
00032 //Global Variables
00033 char serviceName[] = "TFTPServer";
00034 char displayName[] = "TFTP Server Multithreaded";
00035 char sVersion[] = "TFTP Server MultiThreaded Version 1.61 Windows Built 1611";
00036 char iniFile[_MAX_PATH];
00037 char logFile[_MAX_PATH];
00038 char tempbuff[256];
00039 char logBuff[512];
00040 char fileSep = '\\';
00041 char notFileSep = '/';
00042 WORD blksize = 65464;
00043 char verbatim = 0;
00044 WORD timeout = 3;
00045 data2 cfig;
00046 //ThreadPool Variables
00047 HANDLE tEvent;
00048 HANDLE cEvent;
00049 HANDLE sEvent;
00050 HANDLE lEvent;
00051 BYTE currentServer = UCHAR_MAX;
00052 WORD totalThreads=0;
00053 WORD minThreads=1;
00054 WORD activeThreads=0;
00055 
00056 //Service Variables
00057 SERVICE_STATUS serviceStatus;
00058 SERVICE_STATUS_HANDLE serviceStatusHandle = 0;
00059 HANDLE stopServiceEvent = 0;
00060 
00061 void WINAPI ServiceControlHandler(DWORD controlCode)
00062 {
00063     switch (controlCode)
00064     {
00065         case SERVICE_CONTROL_INTERROGATE:
00066             break;
00067 
00068         case SERVICE_CONTROL_SHUTDOWN:
00069         case SERVICE_CONTROL_STOP:
00070             serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
00071             SetServiceStatus(serviceStatusHandle, &serviceStatus);
00072 
00073             SetEvent(stopServiceEvent);
00074             return ;
00075 
00076         case SERVICE_CONTROL_PAUSE:
00077             break;
00078 
00079         case SERVICE_CONTROL_CONTINUE:
00080             break;
00081 
00082         default:
00083             if (controlCode >= 128 && controlCode <= 255)
00084                 break;
00085             else
00086                 break;
00087     }
00088 
00089     SetServiceStatus(serviceStatusHandle, &serviceStatus);
00090 }
00091 
00092 void WINAPI ServiceMain(DWORD /*argc*/, TCHAR* /*argv*/[])
00093 {
00094     serviceStatus.dwServiceType = SERVICE_WIN32;
00095     serviceStatus.dwCurrentState = SERVICE_STOPPED;
00096     serviceStatus.dwControlsAccepted = 0;
00097     serviceStatus.dwWin32ExitCode = NO_ERROR;
00098     serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
00099     serviceStatus.dwCheckPoint = 0;
00100     serviceStatus.dwWaitHint = 0;
00101 
00102     serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler);
00103 
00104     if (serviceStatusHandle)
00105     {
00106         serviceStatus.dwCurrentState = SERVICE_START_PENDING;
00107         SetServiceStatus(serviceStatusHandle, &serviceStatus);
00108 
00109         //init
00110         verbatim = false;
00111         init();
00112         fd_set readfds;
00113         timeval tv;
00114         tv.tv_sec = 20;
00115         tv.tv_usec = 0;
00116 
00117         stopServiceEvent = CreateEvent(0, FALSE, FALSE, 0);
00118 
00119         serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
00120         serviceStatus.dwCurrentState = SERVICE_RUNNING;
00121         SetServiceStatus(serviceStatusHandle, &serviceStatus);
00122 
00123         do
00124         {
00125             FD_ZERO(&readfds);
00126 
00127             for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].port; i++)
00128                 FD_SET(cfig.tftpConn[i].sock, &readfds);
00129 
00130             int fdsReady = select(cfig.maxFD, &readfds, NULL, NULL, &tv);
00131 
00132             for (int i = 0; fdsReady > 0 && i < MAX_SERVERS && cfig.tftpConn[i].port; i++)
00133             {
00134                 if (FD_ISSET(cfig.tftpConn[i].sock, &readfds))
00135                 {
00136                     WaitForSingleObject(sEvent, INFINITE);
00137 
00138                     currentServer = i;
00139 
00140                     if (!totalThreads || activeThreads >= totalThreads)
00141                     {
00142                         _beginthread(
00143                               processRequest,                 // thread function
00144                               0,                            // default security attributes
00145                               NULL);                          // argument to thread function
00146 
00147                     }
00148 
00149                     SetEvent(tEvent);
00150                     WaitForSingleObject(sEvent, INFINITE);
00151                     fdsReady--;
00152                     SetEvent(sEvent);
00153                 }
00154             }
00155         }
00156         while (WaitForSingleObject(stopServiceEvent, 0) == WAIT_TIMEOUT);
00157 
00158         if (cfig.logfile)
00159             fclose(cfig.logfile);
00160 
00161         serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
00162         SetServiceStatus(serviceStatusHandle, &serviceStatus);
00163 
00164         sprintf(logBuff, "Closing Network Connections...");
00165         logMess(logBuff, 1);
00166 
00167         for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].port; i++)
00168             closesocket(cfig.tftpConn[i].sock);
00169 
00170         WSACleanup();
00171 
00172         sprintf(logBuff, "TFTP Server Stopped !");
00173         logMess(logBuff, 1);
00174 
00175         serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);
00176         serviceStatus.dwCurrentState = SERVICE_STOPPED;
00177         SetServiceStatus(serviceStatusHandle, &serviceStatus);
00178         CloseHandle(stopServiceEvent);
00179         stopServiceEvent = 0;
00180     }
00181 }
00182 
00183 void runService()
00184 {
00185     SERVICE_TABLE_ENTRY serviceTable[] =
00186         {
00187             {serviceName, ServiceMain},
00188             {0, 0}
00189         };
00190 
00191     StartServiceCtrlDispatcher(serviceTable);
00192 }
00193 
00194 bool stopService(SC_HANDLE service)
00195 {
00196     if (service)
00197     {
00198         SERVICE_STATUS serviceStatus;
00199         QueryServiceStatus(service, &serviceStatus);
00200         if (serviceStatus.dwCurrentState != SERVICE_STOPPED)
00201         {
00202             ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus);
00203             printf("Stopping Service.");
00204             for (int i = 0; i < 100; i++)
00205             {
00206                 QueryServiceStatus(service, &serviceStatus);
00207                 if (serviceStatus.dwCurrentState == SERVICE_STOPPED)
00208                 {
00209                     printf("Stopped\n");
00210                     return true;
00211                 }
00212                 else
00213                 {
00214                     Sleep(500);
00215                     printf(".");
00216                 }
00217             }
00218             printf("Failed\n");
00219             return false;
00220         }
00221     }
00222     return true;
00223 }
00224 
00225 void installService()
00226 {
00227     SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE);
00228 
00229     if (serviceControlManager)
00230     {
00231         SC_HANDLE service = OpenService(serviceControlManager,
00232                                         serviceName, SERVICE_QUERY_STATUS);
00233         if (service)
00234         {
00235             printf("Service Already Exists..\n");
00236             StartService(service,0,NULL);
00237             CloseServiceHandle(service);
00238         }
00239         else
00240         {
00241             TCHAR path[ _MAX_PATH + 1 ];
00242             if (GetModuleFileName(0, path, sizeof(path) / sizeof(path[0])) > 0)
00243             {
00244                 SC_HANDLE service = CreateService(serviceControlManager,
00245                                                   serviceName, displayName,
00246                                                   SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
00247                                                   SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path,
00248                                                   0, 0, 0, 0, 0);
00249                 if (service)
00250                 {
00251                     printf("Successfully installed.. !\n");
00252                     StartService(service,0,NULL);
00253                     CloseServiceHandle(service);
00254                 }
00255                 else
00256                     printf("Installation Failed..\n");
00257             }
00258         }
00259         CloseServiceHandle(serviceControlManager);
00260     }
00261     else
00262         printWindowsError();
00263 }
00264 
00265 void uninstallService()
00266 {
00267     SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
00268 
00269     if (serviceControlManager)
00270     {
00271         SC_HANDLE service = OpenService(serviceControlManager,
00272                                         serviceName, SERVICE_QUERY_STATUS | SERVICE_STOP | DELETE);
00273         if (service)
00274         {
00275             if (stopService(service))
00276             {
00277                 DeleteService(service);
00278                 printf("Successfully Removed !\n");
00279             }
00280             else
00281                 printf("Failed to Stop Service..\n");
00282 
00283             CloseServiceHandle(service);
00284         }
00285 
00286         CloseServiceHandle(serviceControlManager);
00287     }
00288     else
00289         printWindowsError();
00290 }
00291 
00292 void printWindowsError()
00293 {
00294     DWORD dw = GetLastError();
00295 
00296     if (dw)
00297     {
00298         LPVOID lpMsgBuf;
00299 
00300         FormatMessage(
00301             FORMAT_MESSAGE_ALLOCATE_BUFFER |
00302             FORMAT_MESSAGE_FROM_SYSTEM |
00303             FORMAT_MESSAGE_IGNORE_INSERTS,
00304             NULL,
00305             dw,
00306             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00307             (LPTSTR) &lpMsgBuf,
00308             0, NULL );
00309 
00310         _tprintf(_T("Error: %s\nPress Enter..\n"), (LPTSTR)lpMsgBuf);
00311         getchar();
00312 
00313         if(lpMsgBuf)
00314             LocalFree(lpMsgBuf);
00315     }
00316 }
00317 
00318 int main(int argc, TCHAR* argv[])
00319 {
00320     OSVERSIONINFO osvi;
00321     osvi.dwOSVersionInfoSize = sizeof(osvi);
00322     bool result = GetVersionEx(&osvi);
00323 
00324     if (result && osvi.dwPlatformId >= VER_PLATFORM_WIN32_NT)
00325     {
00326         if (argc > 1 && lstrcmpi(argv[1], TEXT("-i")) == 0)
00327             installService();
00328         else if (argc > 1 && lstrcmpi(argv[1], TEXT("-u")) == 0)
00329             uninstallService();
00330         else if (argc > 1 && lstrcmpi(argv[1], TEXT("-v")) == 0)
00331         {
00332             SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
00333             bool serviceStopped = true;
00334 
00335             if (serviceControlManager)
00336             {
00337                 SC_HANDLE service = OpenService(serviceControlManager,
00338                                                 serviceName, SERVICE_QUERY_STATUS | SERVICE_STOP);
00339                 if (service)
00340                 {
00341                     serviceStopped = stopService(service);
00342                     CloseServiceHandle(service);
00343                 }
00344                 CloseServiceHandle(serviceControlManager);
00345             }
00346             else
00347                 printWindowsError();
00348 
00349             if (serviceStopped)
00350                 runProg();
00351             else
00352                 printf("Failed to Stop Service\n");
00353         }
00354         else
00355             runService();
00356     }
00357     else if (argc == 1 || lstrcmpi(argv[1], TEXT("-v")) == 0)
00358         runProg();
00359     else
00360         printf("This option is not available on Windows95/98/ME\n");
00361 
00362     return 0;
00363 }
00364 
00365 void runProg()
00366 {
00367     verbatim = true;
00368     init();
00369     fd_set readfds;
00370     timeval tv;
00371     int fdsReady = 0;
00372     tv.tv_sec = 20;
00373     tv.tv_usec = 0;
00374 
00375     printf("\naccepting requests..\n");
00376 
00377     do
00378     {
00379         //printf("Active=%u Total=%u\n",activeThreads, totalThreads);
00380 
00381         FD_ZERO(&readfds);
00382 
00383         for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].port; i++)
00384             FD_SET(cfig.tftpConn[i].sock, &readfds);
00385 
00386         fdsReady = select(cfig.maxFD, &readfds, NULL, NULL, &tv);
00387 
00388         //if (errno)
00389         //    printf("%s\n", strerror(errno));
00390 
00391         for (int i = 0; fdsReady > 0 && i < MAX_SERVERS && cfig.tftpConn[i].port; i++)
00392         {
00393             if (FD_ISSET(cfig.tftpConn[i].sock, &readfds))
00394             {
00395                 //printf("Request Waiting\n");
00396 
00397                 WaitForSingleObject(sEvent, INFINITE);
00398 
00399                 currentServer = i;
00400 
00401                 if (!totalThreads || activeThreads >= totalThreads)
00402                 {
00403                     _beginthread(
00404                           processRequest,                 // thread function
00405                           0,                            // default security attributes
00406                           NULL);                          // argument to thread function
00407                 }
00408                 SetEvent(tEvent);
00409 
00410                 //printf("thread signalled=%u\n",SetEvent(tEvent));
00411 
00412                 WaitForSingleObject(sEvent, INFINITE);
00413                 fdsReady--;
00414                 SetEvent(sEvent);
00415             }
00416         }
00417     }
00418     while (true);
00419 
00420     for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].port; i++)
00421         closesocket(cfig.tftpConn[i].sock);
00422 
00423     WSACleanup();
00424 }
00425 
00426 void processRequest(void *lpParam)
00427 {
00428     //printf("New Thread %u\n",GetCurrentThreadId());
00429 
00430     request req;
00431 
00432     WaitForSingleObject(cEvent, INFINITE);
00433     totalThreads++;
00434     SetEvent(cEvent);
00435 
00436     do
00437     {
00438         WaitForSingleObject(tEvent, INFINITE);
00439         //printf("In Thread %u\n",GetCurrentThreadId());
00440 
00441         WaitForSingleObject(cEvent, INFINITE);
00442         activeThreads++;
00443         SetEvent(cEvent);
00444 
00445         if (currentServer >= MAX_SERVERS || !cfig.tftpConn[currentServer].port)
00446         {
00447             SetEvent(sEvent);
00448             req.attempt = UCHAR_MAX;
00449             continue;
00450         }
00451 
00452         memset(&req, 0, sizeof(request));
00453         req.sock = INVALID_SOCKET;
00454 
00455         req.clientsize = sizeof(req.client);
00456         req.sockInd = currentServer;
00457         currentServer = UCHAR_MAX;
00458         req.knock = cfig.tftpConn[req.sockInd].sock;
00459 
00460         if (req.knock == INVALID_SOCKET)
00461         {
00462             SetEvent(sEvent);
00463             req.attempt = UCHAR_MAX;
00464             continue;
00465         }
00466 
00467         errno = 0;
00468         req.bytesRecd = recvfrom(req.knock, (char*)&req.mesin, sizeof(message), 0, (sockaddr*)&req.client, &req.clientsize);
00469         errno = WSAGetLastError();
00470 
00471         //printf("socket Signalled=%u\n",SetEvent(sEvent));
00472         SetEvent(sEvent);
00473 
00474         if (!errno && req.bytesRecd > 0)
00475         {
00476             if (cfig.hostRanges[0].rangeStart)
00477             {
00478                 DWORD iip = ntohl(req.client.sin_addr.s_addr);
00479                 bool allowed = false;
00480 
00481                 for (int j = 0; j <= 32 && cfig.hostRanges[j].rangeStart; j++)
00482                 {
00483                     if (iip >= cfig.hostRanges[j].rangeStart && iip <= cfig.hostRanges[j].rangeEnd)
00484                     {
00485                         allowed = true;
00486                         break;
00487                     }
00488                 }
00489 
00490                 if (!allowed)
00491                 {
00492                     req.serverError.opcode = htons(5);
00493                     req.serverError.errorcode = htons(2);
00494                     strcpy(req.serverError.errormessage, "Access Denied");
00495                     logMess(&req, 1);
00496                     sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
00497                     req.attempt = UCHAR_MAX;
00498                     continue;
00499                 }
00500             }
00501 
00502             if ((htons(req.mesin.opcode) == 5))
00503             {
00504                 sprintf(req.serverError.errormessage, "Error Code %i at Client, %s", ntohs(req.clientError.errorcode), req.clientError.errormessage);
00505                 logMess(&req, 2);
00506                 req.attempt = UCHAR_MAX;
00507                 continue;
00508             }
00509             else if (htons(req.mesin.opcode) != 1 && htons(req.mesin.opcode) != 2)
00510             {
00511                 req.serverError.opcode = htons(5);
00512                 req.serverError.errorcode = htons(5);
00513                 sprintf(req.serverError.errormessage, "Unknown Transfer Id");
00514                 logMess(&req, 2);
00515                 sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
00516                 req.attempt = UCHAR_MAX;
00517                 continue;
00518             }
00519         }
00520         else
00521         {
00522             sprintf(req.serverError.errormessage, "Communication Error");
00523             logMess(&req, 1);
00524             req.attempt = UCHAR_MAX;
00525             continue;
00526         }
00527 
00528         req.blksize = 512;
00529         req.timeout = timeout;
00530         req.expiry = time(NULL) + req.timeout;
00531         bool fetchAck = false;
00532 
00533         req.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
00534 
00535         if (req.sock == INVALID_SOCKET)
00536         {
00537             req.serverError.opcode = htons(5);
00538             req.serverError.errorcode = htons(0);
00539             strcpy(req.serverError.errormessage, "Thread Socket Creation Error");
00540             sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
00541             logMess(&req, 1);
00542             req.attempt = UCHAR_MAX;
00543             continue;
00544         }
00545 
00546         sockaddr_in service;
00547         service.sin_family = AF_INET;
00548         service.sin_addr.s_addr = cfig.tftpConn[req.sockInd].server;
00549 
00550         if (cfig.minport)
00551         {
00552             for (WORD comport = cfig.minport; ; comport++)
00553             {
00554                 service.sin_port = htons(comport);
00555 
00556                 if (comport > cfig.maxport)
00557                 {
00558                     req.serverError.opcode = htons(5);
00559                     req.serverError.errorcode = htons(0);
00560                     strcpy(req.serverError.errormessage, "No port is free");
00561                     sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
00562                     logMess(&req, 1);
00563                     req.attempt = UCHAR_MAX;
00564                     break;
00565                 }
00566                 else if (bind(req.sock, (sockaddr*) &service, sizeof(service)) == -1)
00567                     continue;
00568                 else
00569                     break;
00570             }
00571         }
00572         else
00573         {
00574             service.sin_port = 0;
00575 
00576             if (bind(req.sock, (sockaddr*) &service, sizeof(service)) == -1)
00577             {
00578                 strcpy(req.serverError.errormessage, "Thread failed to bind");
00579                 sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
00580                 logMess(&req, 1);
00581                 req.attempt = UCHAR_MAX;
00582             }
00583         }
00584 
00585         if (req.attempt >= 3)
00586             continue;
00587 
00588         if (connect(req.sock, (sockaddr*)&req.client, req.clientsize) == -1)
00589         {
00590             req.serverError.opcode = htons(5);
00591             req.serverError.errorcode = htons(0);
00592             strcpy(req.serverError.errormessage, "Connect Failed");
00593             sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
00594             logMess(&req, 1);
00595             req.attempt = UCHAR_MAX;
00596             continue;
00597         }
00598 
00599         //sprintf(req.serverError.errormessage, "In Temp, Socket");
00600         //logMess(&req, 1);
00601 
00602         char *inPtr = req.mesin.buffer;
00603         *(inPtr + (req.bytesRecd - 3)) = 0;
00604         req.filename = inPtr;
00605 
00606         if (!strlen(req.filename) || strlen(req.filename) > UCHAR_MAX)
00607         {
00608             req.serverError.opcode = htons(5);
00609             req.serverError.errorcode = htons(4);
00610             strcpy(req.serverError.errormessage, "Malformed Request, Invalid/Missing Filename");
00611             send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00612             req.attempt = UCHAR_MAX;
00613             logMess(&req, 1);
00614             continue;
00615         }
00616 
00617         inPtr += strlen(inPtr) + 1;
00618         req.mode = inPtr;
00619 
00620         if (!strlen(req.mode) || strlen(req.mode) > 25)
00621         {
00622             req.serverError.opcode = htons(5);
00623             req.serverError.errorcode = htons(4);
00624             strcpy(req.serverError.errormessage, "Malformed Request, Invalid/Missing Mode");
00625             send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00626             req.attempt = UCHAR_MAX;
00627             logMess(&req, 1);
00628             continue;
00629         }
00630 
00631         inPtr += strlen(inPtr) + 1;
00632 
00633         for (DWORD i = 0; i < strlen(req.filename); i++)
00634             if (req.filename[i] == notFileSep)
00635                 req.filename[i] = fileSep;
00636 
00637         tempbuff[0] = '.';
00638         tempbuff[1] = '.';
00639         tempbuff[2] = fileSep;
00640         tempbuff[3] = 0;
00641 
00642         if (strstr(req.filename, tempbuff))
00643         {
00644             req.serverError.opcode = htons(5);
00645             req.serverError.errorcode = htons(2);
00646             strcpy(req.serverError.errormessage, "Access violation");
00647             send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00648             logMess(&req, 1);
00649             req.attempt = UCHAR_MAX;
00650             continue;
00651         }
00652 
00653         if (req.filename[0] == fileSep)
00654             req.filename++;
00655 
00656         if (!cfig.homes[0].alias[0])
00657         {
00658             if (strlen(cfig.homes[0].target) + strlen(req.filename) >= sizeof(req.path))
00659             {
00660                 req.serverError.opcode = htons(5);
00661                 req.serverError.errorcode = htons(4);
00662                 sprintf(req.serverError.errormessage, "Filename too large");
00663                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00664                 logMess(&req, 1);
00665                 req.attempt = UCHAR_MAX;
00666                 continue;
00667             }
00668 
00669             strcpy(req.path, cfig.homes[0].target);
00670             strcat(req.path, req.filename);
00671         }
00672         else
00673         {
00674             char *bname = strchr(req.filename, fileSep);
00675 
00676             if (bname)
00677             {
00678                 *bname = 0;
00679                 bname++;
00680             }
00681             else
00682             {
00683                 req.serverError.opcode = htons(5);
00684                 req.serverError.errorcode = htons(2);
00685                 sprintf(req.serverError.errormessage, "Missing directory/alias");
00686                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00687                 logMess(&req, 1);
00688                 req.attempt = UCHAR_MAX;
00689                 continue;
00690             }
00691 
00692             for (int i = 0; i < 8; i++)
00693             {
00694                 //printf("%s=%i\n", req.filename, cfig.homes[i].alias[0]);
00695                 if (cfig.homes[i].alias[0] && !strcasecmp(req.filename, cfig.homes[i].alias))
00696                 {
00697                     if (strlen(cfig.homes[i].target) + strlen(bname) >= sizeof(req.path))
00698                     {
00699                         req.serverError.opcode = htons(5);
00700                         req.serverError.errorcode = htons(4);
00701                         sprintf(req.serverError.errormessage, "Filename too large");
00702                         send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00703                         logMess(&req, 1);
00704                         req.attempt = UCHAR_MAX;
00705                         break;
00706                     }
00707 
00708                     strcpy(req.path, cfig.homes[i].target);
00709                     strcat(req.path, bname);
00710                     break;
00711                 }
00712                 else if (i == 7 || !cfig.homes[i].alias[0])
00713                 {
00714                     req.serverError.opcode = htons(5);
00715                     req.serverError.errorcode = htons(2);
00716                     sprintf(req.serverError.errormessage, "No such directory/alias %s", req.filename);
00717                     send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00718                     logMess(&req, 1);
00719                     req.attempt = UCHAR_MAX;
00720                     break;
00721                 }
00722             }
00723         }
00724 
00725         if (req.attempt >= 3)
00726             continue;
00727 
00728         if (ntohs(req.mesin.opcode) == 1)
00729         {
00730             if (!cfig.fileRead)
00731             {
00732                 req.serverError.opcode = htons(5);
00733                 req.serverError.errorcode = htons(2);
00734                 strcpy(req.serverError.errormessage, "GET Access Denied");
00735                 logMess(&req, 1);
00736                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00737                 req.attempt = UCHAR_MAX;
00738                 continue;
00739             }
00740 
00741             if (*inPtr)
00742             {
00743                 char *tmp = inPtr;
00744 
00745                 while (*tmp)
00746                 {
00747                     if (!strcasecmp(tmp, "blksize"))
00748                     {
00749                         tmp += strlen(tmp) + 1;
00750                         DWORD val = atol(tmp);
00751 
00752                         if (val < 512)
00753                             val = 512;
00754                         else if (val > blksize)
00755                             val = blksize;
00756 
00757                         req.blksize = val;
00758                         break;
00759                     }
00760 
00761                     tmp += strlen(tmp) + 1;
00762                 }
00763             }
00764 
00765             errno = 0;
00766 
00767             if (!strcasecmp(req.mode, "netascii") || !strcasecmp(req.mode, "ascii"))
00768                 req.file = fopen(req.path, "rt");
00769             else
00770                 req.file = fopen(req.path, "rb");
00771 
00772             if (errno || !req.file)
00773             {
00774                 req.serverError.opcode = htons(5);
00775                 req.serverError.errorcode = htons(1);
00776                 strcpy(req.serverError.errormessage, "File not found or No Access");
00777                 logMess(&req, 1);
00778                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00779                 req.attempt = UCHAR_MAX;
00780                 continue;
00781             }
00782 
00783             setvbuf(req.file, NULL, _IOFBF, req.blksize);
00784         }
00785         else
00786         {
00787             if (!cfig.fileWrite && !cfig.fileOverwrite)
00788             {
00789                 req.serverError.opcode = htons(5);
00790                 req.serverError.errorcode = htons(2);
00791                 strcpy(req.serverError.errormessage, "PUT Access Denied");
00792                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00793                 logMess(&req, 1);
00794                 req.attempt = UCHAR_MAX;
00795                 continue;
00796             }
00797 
00798             req.file = fopen(req.path, "rb");
00799 
00800             if (req.file)
00801             {
00802                 fclose(req.file);
00803                 req.file = NULL;
00804 
00805                 if (!cfig.fileOverwrite)
00806                 {
00807                     req.serverError.opcode = htons(5);
00808                     req.serverError.errorcode = htons(6);
00809                     strcpy(req.serverError.errormessage, "File already exists");
00810                     send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00811                     logMess(&req, 1);
00812                     req.attempt = UCHAR_MAX;
00813                     continue;
00814                 }
00815             }
00816             else if (!cfig.fileWrite)
00817             {
00818                 req.serverError.opcode = htons(5);
00819                 req.serverError.errorcode = htons(2);
00820                 strcpy(req.serverError.errormessage, "Create File Access Denied");
00821                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00822                 logMess(&req, 1);
00823                 req.attempt = UCHAR_MAX;
00824                 continue;
00825             }
00826 
00827             errno = 0;
00828 
00829             if (!strcasecmp(req.mode, "netascii") || !strcasecmp(req.mode, "ascii"))
00830                 req.file = fopen(req.path, "wt");
00831             else
00832                 req.file = fopen(req.path, "wb");
00833 
00834             if (errno || !req.file)
00835             {
00836                 req.serverError.opcode = htons(5);
00837                 req.serverError.errorcode = htons(2);
00838                 strcpy(req.serverError.errormessage, "Invalid Path or No Access");
00839                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00840                 logMess(&req, 1);
00841                 req.attempt = UCHAR_MAX;
00842                 continue;
00843             }
00844         }
00845 
00846         if (*inPtr)
00847         {
00848             fetchAck = true;
00849             char *outPtr = req.mesout.buffer;
00850             req.mesout.opcode = htons(6);
00851             DWORD val;
00852             while (*inPtr)
00853             {
00854                 //printf("%s\n", inPtr);
00855                 if (!strcasecmp(inPtr, "blksize"))
00856                 {
00857                     strcpy(outPtr, inPtr);
00858                     outPtr += strlen(outPtr) + 1;
00859                     inPtr += strlen(inPtr) + 1;
00860                     val = atol(inPtr);
00861 
00862                     if (val < 512)
00863                         val = 512;
00864                     else if (val > blksize)
00865                         val = blksize;
00866 
00867                     req.blksize = val;
00868                     sprintf(outPtr, "%lu", val);
00869                     outPtr += strlen(outPtr) + 1;
00870                 }
00871                 else if (!strcasecmp(inPtr, "tsize"))
00872                 {
00873                     strcpy(outPtr, inPtr);
00874                     outPtr += strlen(outPtr) + 1;
00875                     inPtr += strlen(inPtr) + 1;
00876 
00877                     if (ntohs(req.mesin.opcode) == 1)
00878                     {
00879                         if (!fseek(req.file, 0, SEEK_END))
00880                         {
00881                             if (ftell(req.file) >= 0)
00882                             {
00883                                 req.tsize = ftell(req.file);
00884                                 sprintf(outPtr, "%lu", req.tsize);
00885                                 outPtr += strlen(outPtr) + 1;
00886                             }
00887                             else
00888                             {
00889                                 req.serverError.opcode = htons(5);
00890                                 req.serverError.errorcode = htons(2);
00891                                 strcpy(req.serverError.errormessage, "Invalid Path or No Access");
00892                                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00893                                 logMess(&req, 1);
00894                                 req.attempt = UCHAR_MAX;
00895                                 break;
00896                             }
00897                         }
00898                         else
00899                         {
00900                             req.serverError.opcode = htons(5);
00901                             req.serverError.errorcode = htons(2);
00902                             strcpy(req.serverError.errormessage, "Invalid Path or No Access");
00903                             send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00904                             logMess(&req, 1);
00905                             req.attempt = UCHAR_MAX;
00906                             break;
00907                         }
00908                     }
00909                     else
00910                     {
00911                         req.tsize = 0;
00912                         sprintf(outPtr, "%lu", req.tsize);
00913                         outPtr += strlen(outPtr) + 1;
00914                     }
00915                 }
00916                 else if (!strcasecmp(inPtr, "timeout"))
00917                 {
00918                     strcpy(outPtr, inPtr);
00919                     outPtr += strlen(outPtr) + 1;
00920                     inPtr += strlen(inPtr) + 1;
00921                     val = atoi(inPtr);
00922 
00923                     if (val < 1)
00924                         val = 1;
00925                     else if (val > UCHAR_MAX)
00926                         val = UCHAR_MAX;
00927 
00928                     req.timeout = val;
00929                     req.expiry = time(NULL) + req.timeout;
00930                     sprintf(outPtr, "%lu", val);
00931                     outPtr += strlen(outPtr) + 1;
00932                 }
00933 
00934                 inPtr += strlen(inPtr) + 1;
00935                 //printf("=%u\n", val);
00936             }
00937 
00938             if (req.attempt >= 3)
00939                 continue;
00940 
00941             errno = 0;
00942             req.bytesReady = (DWORD_PTR)outPtr - (DWORD_PTR)&req.mesout;
00943             //printf("Bytes Ready=%u\n", req.bytesReady);
00944             send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
00945             errno = WSAGetLastError();
00946         }
00947         else if (htons(req.mesin.opcode) == 2)
00948         {
00949             req.acout.opcode = htons(4);
00950             req.acout.block = htons(0);
00951             errno = 0;
00952             req.bytesReady = 4;
00953             send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
00954             errno = WSAGetLastError();
00955         }
00956 
00957         if (errno)
00958         {
00959             sprintf(req.serverError.errormessage, "Communication Error");
00960             logMess(&req, 1);
00961             req.attempt = UCHAR_MAX;
00962             continue;
00963         }
00964         else if (ntohs(req.mesin.opcode) == 1)
00965         {
00966             errno = 0;
00967             req.pkt[0] = (packet*)calloc(1, req.blksize + 4);
00968             req.pkt[1] = (packet*)calloc(1, req.blksize + 4);
00969 
00970             if (errno || !req.pkt[0] || !req.pkt[1])
00971             {
00972                 sprintf(req.serverError.errormessage, "Memory Error");
00973                 logMess(&req, 1);
00974                 req.attempt = UCHAR_MAX;
00975                 continue;
00976             }
00977 
00978             long ftellLoc = ftell(req.file);
00979 
00980             if (ftellLoc > 0)
00981             {
00982                 if (fseek(req.file, 0, SEEK_SET))
00983                 {
00984                     req.serverError.opcode = htons(5);
00985                     req.serverError.errorcode = htons(2);
00986                     strcpy(req.serverError.errormessage, "File Access Error");
00987                     send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00988                     logMess(&req, 1);
00989                     req.attempt = UCHAR_MAX;
00990                     continue;
00991                 }
00992             }
00993             else if (ftellLoc < 0)
00994             {
00995                 req.serverError.opcode = htons(5);
00996                 req.serverError.errorcode = htons(2);
00997                 strcpy(req.serverError.errormessage, "File Access Error");
00998                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
00999                 logMess(&req, 1);
01000                 req.attempt = UCHAR_MAX;
01001                 continue;
01002             }
01003 
01004             errno = 0;
01005             req.pkt[0]->opcode = htons(3);
01006             req.pkt[0]->block = htons(1);
01007             req.bytesRead[0] = fread(&req.pkt[0]->buffer, 1, req.blksize, req.file);
01008 
01009             if (errno)
01010             {
01011                 req.serverError.opcode = htons(5);
01012                 req.serverError.errorcode = htons(2);
01013                 strcpy(req.serverError.errormessage, "Invalid Path or No Access");
01014                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01015                 logMess(&req, 1);
01016                 req.attempt = UCHAR_MAX;
01017                 continue;
01018             }
01019 
01020             if (req.bytesRead[0] == req.blksize)
01021             {
01022                 req.pkt[1]->opcode = htons(3);
01023                 req.pkt[1]->block = htons(2);
01024                 req.bytesRead[1] = fread(&req.pkt[1]->buffer, 1, req.blksize, req.file);
01025                 if (req.bytesRead[1] < req.blksize)
01026                 {
01027                     fclose(req.file);
01028                     req.file = 0;
01029                 }
01030             }
01031             else
01032             {
01033                 fclose(req.file);
01034                 req.file = 0;
01035             }
01036 
01037             if (errno)
01038             {
01039                 req.serverError.opcode = htons(5);
01040                 req.serverError.errorcode = htons(2);
01041                 strcpy(req.serverError.errormessage, "Invalid Path or No Access");
01042                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01043                 logMess(&req, 1);
01044                 req.attempt = UCHAR_MAX;
01045                 continue;
01046             }
01047 
01048             while (req.attempt <= 3)
01049             {
01050                 if (fetchAck)
01051                 {
01052                     FD_ZERO(&req.readfds);
01053                     req.tv.tv_sec = 1;
01054                     req.tv.tv_usec = 0;
01055                     FD_SET(req.sock, &req.readfds);
01056                     select(req.sock + 1, &req.readfds, NULL, NULL, &req.tv);
01057 
01058                     if (FD_ISSET(req.sock, &req.readfds))
01059                     {
01060                         errno = 0;
01061                         req.bytesRecd = recv(req.sock, (char*)&req.mesin, sizeof(message), 0);
01062                         errno = WSAGetLastError();
01063                         if (req.bytesRecd <= 0 || errno)
01064                         {
01065                             sprintf(req.serverError.errormessage, "Communication Error");
01066                             logMess(&req, 1);
01067                             req.attempt = UCHAR_MAX;
01068                             break;
01069                         }
01070                         else if(req.bytesRecd >= 4 && ntohs(req.mesin.opcode) == 4)
01071                         {
01072                             if (ntohs(req.acin.block) == req.block)
01073                             {
01074                                 req.block++;
01075                                 req.fblock++;
01076                                 req.attempt = 0;
01077                             }
01078                             else if (req.expiry > time(NULL))
01079                                 continue;
01080                             else
01081                                 req.attempt++;
01082                         }
01083                         else if (ntohs(req.mesin.opcode) == 5)
01084                         {
01085                             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);
01086                             logMess(&req, 1);
01087                             req.attempt = UCHAR_MAX;
01088                             break;
01089                         }
01090                         else
01091                         {
01092                             req.serverError.opcode = htons(5);
01093                             req.serverError.errorcode = htons(4);
01094                             sprintf(req.serverError.errormessage, "Unexpected Option Code %i", ntohs(req.mesin.opcode));
01095                             send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01096                             logMess(&req, 1);
01097                             req.attempt = UCHAR_MAX;
01098                             break;
01099                         }
01100                     }
01101                     else if (req.expiry > time(NULL))
01102                         continue;
01103                     else
01104                         req.attempt++;
01105                 }
01106                 else
01107                 {
01108                     fetchAck = true;
01109                     req.acin.block = 1;
01110                     req.block = 1;
01111                     req.fblock = 1;
01112                 }
01113 
01114                 if (req.attempt >= 3)
01115                 {
01116                     req.serverError.opcode = htons(5);
01117                     req.serverError.errorcode = htons(0);
01118 
01119                     if (req.fblock && !req.block)
01120                         strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
01121                     else
01122                         strcpy(req.serverError.errormessage, "Timeout");
01123 
01124                     logMess(&req, 1);
01125                     send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01126                     req.attempt = UCHAR_MAX;
01127                     break;
01128                 }
01129                 else if (!req.fblock)
01130                 {
01131                     errno = 0;
01132                     send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
01133                     errno = WSAGetLastError();
01134                     if (errno)
01135                     {
01136                         sprintf(req.serverError.errormessage, "Communication Error");
01137                         logMess(&req, 1);
01138                         req.attempt = UCHAR_MAX;
01139                         break;
01140                     }
01141                     req.expiry = time(NULL) + req.timeout;
01142                 }
01143                 else if (ntohs(req.pkt[0]->block) == req.block)
01144                 {
01145                     errno = 0;
01146                     send(req.sock, (const char*)req.pkt[0], req.bytesRead[0] + 4, 0);
01147                     errno = WSAGetLastError();
01148                     if (errno)
01149                     {
01150                         sprintf(req.serverError.errormessage, "Communication Error");
01151                         logMess(&req, 1);
01152                         req.attempt = UCHAR_MAX;
01153                         break;
01154                     }
01155                     req.expiry = time(NULL) + req.timeout;
01156 
01157                     if (req.file)
01158                     {
01159                         req.tblock = ntohs(req.pkt[1]->block) + 1;
01160                         if (req.tblock == req.block)
01161                         {
01162                             req.pkt[1]->block = htons(++req.tblock);
01163                             req.bytesRead[1] = fread(&req.pkt[1]->buffer, 1, req.blksize, req.file);
01164 
01165                             if (errno)
01166                             {
01167                                 req.serverError.opcode = htons(5);
01168                                 req.serverError.errorcode = htons(4);
01169                                 sprintf(req.serverError.errormessage, strerror(errno));
01170                                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01171                                 logMess(&req, 1);
01172                                 req.attempt = UCHAR_MAX;
01173                                 break;
01174                             }
01175                             else if (req.bytesRead[1] < req.blksize)
01176                             {
01177                                 fclose(req.file);
01178                                 req.file = 0;
01179                             }
01180                         }
01181                     }
01182                 }
01183                 else if (ntohs(req.pkt[1]->block) == req.block)
01184                 {
01185                     errno = 0;
01186                     send(req.sock, (const char*)req.pkt[1], req.bytesRead[1] + 4, 0);
01187                     errno = WSAGetLastError();
01188                     if (errno)
01189                     {
01190                         sprintf(req.serverError.errormessage, "Communication Error");
01191                         logMess(&req, 1);
01192                         req.attempt = UCHAR_MAX;
01193                         break;
01194                     }
01195 
01196                     req.expiry = time(NULL) + req.timeout;
01197 
01198                     if (req.file)
01199                     {
01200                         req.tblock = ntohs(req.pkt[0]->block) + 1;
01201                         if (req.tblock == req.block)
01202                         {
01203                             req.pkt[0]->block = htons(++req.tblock);
01204                             req.bytesRead[0] = fread(&req.pkt[0]->buffer, 1, req.blksize, req.file);
01205                             if (errno)
01206                             {
01207                                 req.serverError.opcode = htons(5);
01208                                 req.serverError.errorcode = htons(4);
01209                                 sprintf(req.serverError.errormessage, strerror(errno));
01210                                 send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01211                                 logMess(&req, 1);
01212                                 req.attempt = UCHAR_MAX;
01213                                 break;
01214                             }
01215                             else if (req.bytesRead[0] < req.blksize)
01216                             {
01217                                 fclose(req.file);
01218                                 req.file = 0;
01219                             }
01220                         }
01221                     }
01222                 }
01223                 else
01224                 {
01225                     sprintf(req.serverError.errormessage, "%lu Blocks Served", req.fblock - 1);
01226                     logMess(&req, 2);
01227                     req.attempt = UCHAR_MAX;
01228                     break;
01229                 }
01230             }
01231         }
01232         else if (ntohs(req.mesin.opcode) == 2)
01233         {
01234             errno = 0;
01235             req.pkt[0] = (packet*)calloc(1, req.blksize + 4);
01236 
01237             if (errno || !req.pkt[0])
01238             {
01239                 sprintf(req.serverError.errormessage, "Memory Error");
01240                 logMess(&req, 1);
01241                 req.attempt = UCHAR_MAX;
01242                 continue;
01243             }
01244 
01245             while (req.attempt <= 3)
01246             {
01247                 FD_ZERO(&req.readfds);
01248                 req.tv.tv_sec = 1;
01249                 req.tv.tv_usec = 0;
01250                 FD_SET(req.sock, &req.readfds);
01251                 select(req.sock + 1, &req.readfds, NULL, NULL, &req.tv);
01252 
01253                 if (FD_ISSET(req.sock, &req.readfds))
01254                 {
01255                     errno = 0;
01256                     req.bytesRecd = recv(req.sock, (char*)req.pkt[0], req.blksize + 4, 0);
01257                     errno = WSAGetLastError();
01258 
01259                     if (errno)
01260                     {
01261                         sprintf(req.serverError.errormessage, "Communication Error");
01262                         logMess(&req, 1);
01263                         req.attempt = UCHAR_MAX;
01264                         break;
01265                     }
01266                 }
01267                 else
01268                     req.bytesRecd = 0;
01269 
01270                 if (req.bytesRecd >= 4)
01271                 {
01272                     if (ntohs(req.pkt[0]->opcode) == 3)
01273                     {
01274                         req.tblock = req.block + 1;
01275 
01276                         if (ntohs(req.pkt[0]->block) == req.tblock)
01277                         {
01278                             req.acout.opcode = htons(4);
01279                             req.acout.block = req.pkt[0]->block;
01280                             req.block++;
01281                             req.fblock++;
01282                             req.bytesReady = 4;
01283                             req.expiry = time(NULL) + req.timeout;
01284 
01285                             errno = 0;
01286                             send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
01287                             errno = WSAGetLastError();
01288 
01289                             if (errno)
01290                             {
01291                                 sprintf(req.serverError.errormessage, "Communication Error");
01292                                 logMess(&req, 1);
01293                                 req.attempt = UCHAR_MAX;
01294                                 break;
01295                             }
01296 
01297                             if (req.bytesRecd > 4)
01298                             {
01299                                 errno = 0;
01300                                 if (fwrite(&req.pkt[0]->buffer, req.bytesRecd - 4, 1, req.file) != 1 || errno)
01301                                 {
01302                                     req.serverError.opcode = htons(5);
01303                                     req.serverError.errorcode = htons(3);
01304                                     strcpy(req.serverError.errormessage, "Disk full or allocation exceeded");
01305                                     send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01306                                     logMess(&req, 1);
01307                                     req.attempt = UCHAR_MAX;
01308                                     break;
01309                                 }
01310                                 else
01311                                     req.attempt = 0;
01312                             }
01313                             else
01314                                 req.attempt = 0;
01315 
01316                             if ((WORD)req.bytesRecd < req.blksize + 4)
01317                             {
01318                                 fclose(req.file);
01319                                 req.file = 0;
01320                                 sprintf(req.serverError.errormessage, "%lu Blocks Received", req.fblock);
01321                                 logMess(&req, 2);
01322                                 req.attempt = UCHAR_MAX;
01323                                 break;
01324                             }
01325                         }
01326                         else if (req.expiry > time(NULL))
01327                             continue;
01328                         else if (req.attempt >= 3)
01329                         {
01330                             req.serverError.opcode = htons(5);
01331                             req.serverError.errorcode = htons(0);
01332 
01333                             if (req.fblock && !req.block)
01334                                 strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
01335                             else
01336                                 strcpy(req.serverError.errormessage, "Timeout");
01337 
01338                             logMess(&req, 1);
01339                             send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01340                             req.attempt = UCHAR_MAX;
01341                             break;
01342                         }
01343                         else
01344                         {
01345                             req.expiry = time(NULL) + req.timeout;
01346                             errno = 0;
01347                             send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
01348                             errno = WSAGetLastError();
01349                             req.attempt++;
01350 
01351                             if (errno)
01352                             {
01353                                 sprintf(req.serverError.errormessage, "Communication Error");
01354                                 logMess(&req, 1);
01355                                 req.attempt = UCHAR_MAX;
01356                                 break;
01357                             }
01358                         }
01359                     }
01360                     else if (req.bytesRecd > (int)sizeof(message))
01361                     {
01362                         req.serverError.opcode = htons(5);
01363                         req.serverError.errorcode = htons(4);
01364                         sprintf(req.serverError.errormessage, "Error: Incoming Packet too large");
01365                         send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01366                         logMess(&req, 1);
01367                         req.attempt = UCHAR_MAX;
01368                         break;
01369                     }
01370                     else if (ntohs(req.pkt[0]->opcode) == 5)
01371                     {
01372                         sprintf(req.serverError.errormessage, "Error Code %i at Client, %s", ntohs(req.pkt[0]->block), &req.pkt[0]->buffer);
01373                         logMess(&req, 1);
01374                         req.attempt = UCHAR_MAX;
01375                         break;
01376                     }
01377                     else
01378                     {
01379                         req.serverError.opcode = htons(5);
01380                         req.serverError.errorcode = htons(4);
01381                         sprintf(req.serverError.errormessage, "Unexpected Option Code %i", ntohs(req.pkt[0]->opcode));
01382                         send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01383                         logMess(&req, 1);
01384                         req.attempt = UCHAR_MAX;
01385                         break;
01386                     }
01387                 }
01388                 else if (req.expiry > time(NULL))
01389                     continue;
01390                 else if (req.attempt >= 3)
01391                 {
01392                     req.serverError.opcode = htons(5);
01393                     req.serverError.errorcode = htons(0);
01394 
01395                     if (req.fblock && !req.block)
01396                         strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
01397                     else
01398                         strcpy(req.serverError.errormessage, "Timeout");
01399 
01400                     logMess(&req, 1);
01401                     send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
01402                     req.attempt = UCHAR_MAX;
01403                     break;
01404                 }
01405                 else
01406                 {
01407                     req.expiry = time(NULL) + req.timeout;
01408                     errno = 0;
01409                     send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
01410                     errno = WSAGetLastError();
01411                     req.attempt++;
01412 
01413                     if (errno)
01414                     {
01415                         sprintf(req.serverError.errormessage, "Communication Error");
01416                         logMess(&req, 1);
01417                         req.attempt = UCHAR_MAX;
01418                         break;
01419                     }
01420                 }
01421             }
01422         }
01423     }
01424     while (cleanReq(&req));
01425 
01426     WaitForSingleObject(cEvent, INFINITE);
01427     totalThreads--;
01428     SetEvent(cEvent);
01429 
01430     //printf("Thread %u Killed\n",GetCurrentThreadId());
01431     _endthread();
01432     return;
01433 }
01434 
01435 bool cleanReq(request* req)
01436 {
01437     //printf("cleaning\n");
01438 
01439     if (req->file)
01440         fclose(req->file);
01441 
01442     if (!(req->sock == INVALID_SOCKET))
01443     {
01444         //printf("Here\n");
01445         closesocket(req->sock);
01446     }
01447 
01448     if (req->pkt[0])
01449         free(req->pkt[0]);
01450 
01451     if (req->pkt[1])
01452         free(req->pkt[1]);
01453 
01454     WaitForSingleObject(cEvent, INFINITE);
01455     activeThreads--;
01456     SetEvent(cEvent);
01457 
01458     //printf("cleaned\n");
01459 
01460     return (totalThreads <= minThreads);
01461 }
01462 
01463 char* myGetToken(char* buff, BYTE index)
01464 {
01465     while (*buff)
01466     {
01467         if (index)
01468             index--;
01469         else
01470             break;
01471 
01472         buff += strlen(buff) + 1;
01473     }
01474 
01475     return buff;
01476 }
01477 
01478 WORD myTokenize(char *target, char *source, char *sep, bool whiteSep)
01479 {
01480     bool found = true;
01481     char *dp = target;
01482     WORD kount = 0;
01483 
01484     while (*source)
01485     {
01486         if (sep && sep[0] && strchr(sep, (*source)))
01487         {
01488             found = true;
01489             source++;
01490             continue;
01491         }
01492         else if (whiteSep && *source <= 32)
01493         {
01494             found = true;
01495             source++;
01496             continue;
01497         }
01498 
01499         if (found)
01500         {
01501             if (target != dp)
01502             {
01503                 *dp = 0;
01504                 dp++;
01505             }
01506             kount++;
01507         }
01508 
01509         found = false;
01510         *dp = *source;
01511         dp++;
01512         source++;
01513     }
01514 
01515     *dp = 0;
01516     dp++;
01517     *dp = 0;
01518 
01519     //printf("%s\n", target);
01520 
01521     return kount;
01522 }
01523 
01524 char* myTrim(char *target, char *source)
01525 {
01526     while ((*source) && (*source) <= 32)
01527         source++;
01528 
01529     int i = 0;
01530 
01531     for (; i < 511 && source[i]; i++)
01532         target[i] = source[i];
01533 
01534     target[i] = source[i];
01535     i--;
01536 
01537     for (; i >= 0 && target[i] <= 32; i--)
01538         target[i] = 0;
01539 
01540     return target;
01541 }
01542 
01543 void mySplit(char *name, char *value, char *source, char splitChar)
01544 {
01545     int i = 0;
01546     int j = 0;
01547     int k = 0;
01548 
01549     for (; source[i] && j <= 510 && source[i] != splitChar; i++, j++)
01550     {
01551         name[j] = source[i];
01552     }
01553 
01554     if (source[i])
01555     {
01556         i++;
01557         for (; k <= 510 && source[i]; i++, k++)
01558         {
01559             value[k] = source[i];
01560         }
01561     }
01562 
01563     name[j] = 0;
01564     value[k] = 0;
01565 
01566     myTrim(name, name);
01567     myTrim(value, value);
01568     //printf("%s %s\n", name, value);
01569 }
01570 
01571 bool getSection(const char *sectionName, char *buffer, BYTE serial, char *fileName)
01572 {
01573     //printf("%s=%s\n",fileName,sectionName);
01574     char section[128];
01575     sprintf(section, "[%s]", sectionName);
01576     myUpper(section);
01577     FILE *f = fopen(fileName, "rt");
01578     char buff[512];
01579     BYTE found = 0;
01580 
01581     if (f)
01582     {
01583         while (fgets(buff, 511, f))
01584         {
01585             myUpper(buff);
01586             myTrim(buff, buff);
01587 
01588             if (strstr(buff, section) == buff)
01589             {
01590                 found++;
01591                 if (found == serial)
01592                 {
01593                     //printf("%s=%s\n",fileName,sectionName);
01594                     while (fgets(buff, 511, f))
01595                     {
01596                         myTrim(buff, buff);
01597 
01598                         if (strstr(buff, "[") == buff)
01599                             break;
01600 
01601                         if (((*buff) >= '0' && (*buff) <= '9') || ((*buff) >= 'A' && (*buff) <= 'Z') || ((*buff) >= 'a' && (*buff) <= 'z') || (((*buff) && strchr("/\\?*", (*buff)))))
01602                         {
01603                             buffer += sprintf(buffer, "%s", buff);
01604                             buffer++;
01605                         }
01606                     }
01607                     break;
01608                 }
01609             }
01610         }
01611         fclose(f);
01612     }
01613 
01614     *buffer = 0;
01615     *(buffer + 1) = 0;
01616     return (found == serial);
01617 }
01618 
01619 char *IP2String(char *target, DWORD ip)
01620 {
01621     data15 inaddr;
01622     inaddr.ip = ip;
01623     sprintf(target, "%u.%u.%u.%u", inaddr.octate[0], inaddr.octate[1], inaddr.octate[2], inaddr.octate[3]);
01624     return target;
01625 }
01626 
01627 bool isIP(char *string)
01628 {
01629     int j = 0;
01630 
01631     for (; *string; string++)
01632     {
01633         if (*string == '.' && *(string + 1) != '.')
01634             j++;
01635         else if (*string < '0' || *string > '9')
01636             return 0;
01637     }
01638 
01639     if (j == 3)
01640         return 1;
01641     else
01642         return 0;
01643 }
01644 
01645 char *myUpper(char *string)
01646 {
01647     char diff = 'a' - 'A';
01648     WORD len = strlen(string);
01649     for (int i = 0; i < len; i++)
01650         if (string[i] >= 'a' && string[i] <= 'z')
01651             string[i] -= diff;
01652     return string;
01653 }
01654 
01655 char *myLower(char *string)
01656 {
01657     char diff = 'a' - 'A';
01658     WORD len = strlen(string);
01659     for (int i = 0; i < len; i++)
01660         if (string[i] >= 'A' && string[i] <= 'Z')
01661             string[i] += diff;
01662     return string;
01663 }
01664 
01665 void init()
01666 {
01667     memset(&cfig, 0, sizeof(cfig));
01668 
01669     GetModuleFileName(NULL, iniFile, MAX_PATH);
01670     char *iniFileExt = strrchr(iniFile, '.');
01671     strcpy(iniFileExt, ".ini");
01672     GetModuleFileName(NULL, logFile, MAX_PATH);
01673     iniFileExt = strrchr(logFile, '.');
01674     strcpy(iniFileExt, ".log");
01675 
01676     char iniStr[4096];
01677     char name[256];
01678     char value[256];
01679 
01680     if (verbatim)
01681     {
01682         cfig.logLevel = 2;
01683         printf("%s\n\n", sVersion);
01684     }
01685     else if (getSection("LOGGING", iniStr, 1, iniFile))
01686     {
01687         char *iniStrPtr = myGetToken(iniStr, 0);
01688 
01689         if (!iniStrPtr[0] || !strcasecmp(iniStrPtr, "None"))
01690             cfig.logLevel = 0;
01691         else if (!strcasecmp(iniStrPtr, "Errors"))
01692             cfig.logLevel = 1;
01693         else if (!strcasecmp(iniStrPtr, "All"))
01694             cfig.logLevel = 2;
01695         else if (!strcasecmp(iniStrPtr, "Debug"))
01696             cfig.logLevel = 3;
01697         else
01698             cfig.logLevel = UCHAR_MAX;
01699     }
01700 
01701     if (!verbatim && cfig.logLevel)
01702     {
01703         cfig.logfile = fopen(logFile, "wt");
01704 
01705         if (cfig.logfile)
01706         {
01707             fclose(cfig.logfile);
01708             cfig.logfile = fopen(logFile, "at");
01709             fprintf(cfig.logfile, "%s\n", sVersion);
01710         }
01711     }
01712 
01713     if (cfig.logLevel == UCHAR_MAX)
01714     {
01715         cfig.logLevel = 1;
01716         sprintf(logBuff, "Section [LOGGING], Invalid Logging Level: %s, ignored", myGetToken(iniStr, 0));
01717         logMess(logBuff, 1);
01718     }
01719 
01720     WORD wVersionRequested = MAKEWORD(1, 1);
01721     WSAStartup(wVersionRequested, &cfig.wsaData);
01722 
01723     if (cfig.wsaData.wVersion != wVersionRequested)
01724     {
01725         sprintf(logBuff, "WSAStartup Error");
01726         logMess(logBuff, 1);
01727     }
01728 
01729     if (getSection("LISTEN-ON", iniStr, 1, iniFile))
01730     {
01731         char *iniStrPtr = myGetToken(iniStr, 0);
01732 
01733         for (int i = 0; i < MAX_SERVERS && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
01734         {
01735             strncpy(name, iniStrPtr, UCHAR_MAX);
01736             WORD port = 69;
01737             char *dp = strchr(name, ':');
01738             if (dp)
01739             {
01740                 *dp = 0;
01741                 dp++;
01742                 port = atoi(dp);
01743             }
01744 
01745             DWORD ip = my_inet_addr(name);
01746 
01747             if (isIP(name) && ip)
01748             {
01749                 for (BYTE j = 0; j < MAX_SERVERS; j++)
01750                 {
01751                     if (cfig.servers[j] == ip)
01752                         break;
01753                     else if (!cfig.servers[j])
01754                     {
01755                         cfig.servers[j] = ip;
01756                         cfig.ports[j] = port;
01757                         i++;
01758                         break;
01759                     }
01760                 }
01761             }
01762             else
01763             {
01764                 sprintf(logBuff, "Warning: Section [LISTEN-ON], Invalid IP Address %s, ignored", iniStrPtr);
01765                 logMess(logBuff, 1);
01766             }
01767         }
01768     }
01769 
01770     if (getSection("HOME", iniStr, 1, iniFile))
01771     {
01772         char *iniStrPtr = myGetToken(iniStr, 0);
01773         for (; iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
01774         {
01775             mySplit(name, value, iniStrPtr, '=');
01776             if (strlen(value))
01777             {
01778                 if (!cfig.homes[0].alias[0] && cfig.homes[0].target[0])
01779                 {
01780                     sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", iniStrPtr);
01781                     logMess(logBuff, 1);
01782                 }
01783                 else if (strchr(name, notFileSep) || strchr(name, fileSep) || strchr(name, '>') || strchr(name, '<') || strchr(name, '.'))
01784                 {
01785                     sprintf(logBuff, "Section [HOME], invalid chars in alias %s, entry ignored", name);
01786                     logMess(logBuff, 1);
01787                 }
01788                 else if (name[0] && strlen(name) < 64 && value[0])
01789                 {
01790                     for (int i = 0; i < 8; i++)
01791                     {
01792                         if (cfig.homes[i].alias[0] && !strcasecmp(name, cfig.homes[i].alias))
01793                         {
01794                             sprintf(logBuff, "Section [HOME], Duplicate Entry: %s ignored", iniStrPtr);
01795                             logMess(logBuff, 1);
01796                             break;
01797                         }
01798                         else if (!cfig.homes[i].alias[0])
01799                         {
01800                             strcpy(cfig.homes[i].alias, name);
01801                             strcpy(cfig.homes[i].target, value);
01802 
01803                             if (cfig.homes[i].target[strlen(cfig.homes[i].target) - 1] != fileSep)
01804                             {
01805                                 tempbuff[0] = fileSep;
01806                                 tempbuff[1] = 0;
01807                                 strcat(cfig.homes[i].target, tempbuff);
01808                             }
01809 
01810                             break;
01811                         }
01812                     }
01813                 }
01814                 else
01815                 {
01816                     sprintf(logBuff, "Section [HOME], alias %s too large", name);
01817                     logMess(logBuff, 1);
01818                 }
01819             }
01820             else if (!cfig.homes[0].alias[0] && !cfig.homes[0].target[0])
01821             {
01822                 strcpy(cfig.homes[0].target, name);
01823 
01824                 if (cfig.homes[0].target[strlen(cfig.homes[0].target) - 1] != fileSep)
01825                 {
01826                     tempbuff[0] = fileSep;
01827                     tempbuff[1] = 0;
01828                     strcat(cfig.homes[0].target, tempbuff);
01829                 }
01830             }
01831             else if (cfig.homes[0].alias[0])
01832             {
01833                 sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", iniStrPtr);
01834                 logMess(logBuff, 1);
01835             }
01836             else if (cfig.homes[0].target[0])
01837             {
01838                 sprintf(logBuff, "Section [HOME], Duplicate Path: %s ignored", iniStrPtr);
01839                 logMess(logBuff, 1);
01840             }
01841             else
01842             {
01843                 sprintf(logBuff, "Section [HOME], missing = sign, Invalid Entry: %s ignored", iniStrPtr);
01844                 logMess(logBuff, 1);
01845             }
01846         }
01847     }
01848 
01849     if (!cfig.homes[0].target[0])
01850     {
01851         GetModuleFileName(NULL, cfig.homes[0].target, UCHAR_MAX);
01852         char *iniFileExt = strrchr(cfig.homes[0].target, fileSep);
01853         *(++iniFileExt) = 0;
01854     }
01855 
01856     cfig.fileRead = true;
01857 
01858     if (getSection("TFTP-OPTIONS", iniStr, 1, iniFile))
01859     {
01860         char *iniStrPtr = myGetToken(iniStr, 0);
01861         for (;strlen(iniStrPtr);iniStrPtr = myGetToken(iniStrPtr, 1))
01862         {
01863             mySplit(name, value, iniStrPtr, '=');
01864             if (strlen(value))
01865             {
01866                 if (!strcasecmp(name, "blksize"))
01867                 {
01868                     DWORD tblksize = atol(value);
01869 
01870                     if (tblksize < 512)
01871                         blksize = 512;
01872                     else if (tblksize > USHRT_MAX - 32)
01873                         blksize = USHRT_MAX - 32;
01874                     else
01875                         blksize = tblksize;
01876                 }
01877                 else if (!strcasecmp(name, "threadpoolsize"))
01878                 {
01879                     minThreads = atol(value);
01880                     if (minThreads < 1)
01881                         minThreads = 0;
01882                     else if (minThreads > 100)
01883                         minThreads = 100;
01884                 }
01885                 else if (!strcasecmp(name, "timeout"))
01886                 {
01887                     timeout = atol(value);
01888                     if (timeout < 1)
01889                         timeout = 1;
01890                     else if (timeout > UCHAR_MAX)
01891                         timeout = UCHAR_MAX;
01892                 }
01893                 else if (!strcasecmp(name, "Read"))
01894                 {
01895                     if (strchr("Yy", *value))
01896                         cfig.fileRead = true;
01897                     else
01898                         cfig.fileRead = false;
01899                 }
01900                 else if (!strcasecmp(name, "Write"))
01901                 {
01902                     if (strchr("Yy", *value))
01903                         cfig.fileWrite = true;
01904                     else
01905                         cfig.fileWrite = false;
01906                 }
01907                 else if (!strcasecmp(name, "Overwrite"))
01908                 {
01909                     if (strchr("Yy", *value))
01910                         cfig.fileOverwrite = true;
01911                     else
01912                         cfig.fileOverwrite = false;
01913                 }
01914                 else if (!strcasecmp(name, "port-range"))
01915                 {
01916                     char *ptr = strchr(value, '-');
01917                     if (ptr)
01918                     {
01919                         *ptr = 0;
01920                         cfig.minport = atol(value);
01921                         cfig.maxport = atol(++ptr);
01922 
01923                         if (cfig.minport < 1024 || cfig.minport >= USHRT_MAX || cfig.maxport < 1024 || cfig.maxport >= USHRT_MAX || cfig.minport > cfig.maxport)
01924                         {
01925                             cfig.minport = 0;
01926                             cfig.maxport = 0;
01927 
01928                             sprintf(logBuff, "Invalid port range %s", value);
01929                             logMess(logBuff, 1);
01930                         }
01931                     }
01932                     else
01933                     {
01934                         sprintf(logBuff, "Invalid port range %s", value);
01935                         logMess(logBuff, 1);
01936                     }
01937                 }
01938                 else
01939                 {
01940                     sprintf(logBuff, "Warning: unknown option %s, ignored", name);
01941                     logMess(logBuff, 1);
01942                 }
01943             }
01944         }
01945     }
01946 
01947     if (getSection("ALLOWED-CLIENTS", iniStr, 1, iniFile))
01948     {
01949         char *iniStrPtr = myGetToken(iniStr, 0);
01950         for (int i = 0; i < 32 && iniStrPtr[0]; iniStrPtr = myGetToken(iniStrPtr, 1))
01951         {
01952             DWORD rs = 0;
01953             DWORD re = 0;
01954             mySplit(name, value, iniStrPtr, '-');
01955             rs = htonl(my_inet_addr(name));
01956 
01957             if (strlen(value))
01958                 re = htonl(my_inet_addr(value));
01959             else
01960                 re = rs;
01961 
01962             if (rs && rs != INADDR_NONE && re && re != INADDR_NONE && rs <= re)
01963             {
01964                 cfig.hostRanges[i].rangeStart = rs;
01965                 cfig.hostRanges[i].rangeEnd = re;
01966                 i++;
01967             }
01968             else
01969             {
01970                 sprintf(logBuff, "Section [ALLOWED-CLIENTS] Invalid entry %s in ini file, ignored", iniStrPtr);
01971                 logMess(logBuff, 1);
01972             }
01973         }
01974     }
01975 
01976 //    if (!cfig.servers[0])
01977 //        getServ();
01978 
01979     int i = 0;
01980 
01981     for (int j = 0; j < MAX_SERVERS; j++)
01982     {
01983          if (j && !cfig.servers[j])
01984              break;
01985 
01986          cfig.tftpConn[i].sock = socket(PF_INET,
01987                                        SOCK_DGRAM,
01988                                        IPPROTO_UDP);
01989 
01990         if (cfig.tftpConn[i].sock == INVALID_SOCKET)
01991         {
01992             sprintf(logBuff, "Failed to Create Socket");
01993             logMess(logBuff, 1);
01994             continue;
01995         }
01996 
01997         cfig.tftpConn[i].addr.sin_family = AF_INET;
01998 
01999         if (!cfig.ports[j])
02000             cfig.ports[j] = 69;
02001 
02002         cfig.tftpConn[i].addr.sin_addr.s_addr = cfig.servers[j];
02003         cfig.tftpConn[i].addr.sin_port = htons(cfig.ports[j]);
02004 
02005         socklen_t nRet = bind(cfig.tftpConn[i].sock,
02006                               (sockaddr*)&cfig.tftpConn[i].addr,
02007                               sizeof(struct sockaddr_in)
02008                              );
02009 
02010         if (nRet == SOCKET_ERROR)
02011         {
02012             closesocket(cfig.tftpConn[i].sock);
02013             sprintf(logBuff, "%s Port %u, bind failed", IP2String(tempbuff, cfig.servers[j]), cfig.ports[j]);
02014             logMess(logBuff, 1);
02015             continue;
02016         }
02017 
02018         if (cfig.maxFD < cfig.tftpConn[i].sock)
02019             cfig.maxFD = cfig.tftpConn[i].sock;
02020 
02021         cfig.tftpConn[i].server = cfig.tftpConn[i].addr.sin_addr.s_addr;
02022         cfig.tftpConn[i].port = htons(cfig.tftpConn[i].addr.sin_port);
02023         i++;
02024     }
02025 
02026     cfig.maxFD++;
02027 
02028     if (!cfig.tftpConn[0].port)
02029     {
02030         sprintf(logBuff, "no listening interfaces available, stopping..\nPress Enter to exit\n");
02031         logMess(logBuff, 1);
02032         getchar();
02033         exit(-1);
02034     }
02035     else if (verbatim)
02036     {
02037         printf("starting TFTP...\n");
02038     }
02039     else
02040     {
02041         sprintf(logBuff, "starting TFTP service");
02042         logMess(logBuff, 1);
02043     }
02044 
02045     for (int i = 0; i < MAX_SERVERS; i++)
02046         if (cfig.homes[i].target[0])
02047         {
02048             sprintf(logBuff, "alias /%s is mapped to %s", cfig.homes[i].alias, cfig.homes[i].target);
02049             logMess(logBuff, 1);
02050         }
02051 
02052     if (cfig.hostRanges[0].rangeStart)
02053     {
02054         char temp[128];
02055 
02056         for (WORD i = 0; i <= sizeof(cfig.hostRanges) && cfig.hostRanges[i].rangeStart; i++)
02057         {
02058             sprintf(logBuff, "%s", "permitted clients: ");
02059             sprintf(temp, "%s-", IP2String(tempbuff, htonl(cfig.hostRanges[i].rangeStart)));
02060             strcat(logBuff, temp);
02061             sprintf(temp, "%s", IP2String(tempbuff, htonl(cfig.hostRanges[i].rangeEnd)));
02062             strcat(logBuff, temp);
02063             logMess(logBuff, 1);
02064         }
02065     }
02066     else
02067     {
02068         sprintf(logBuff, "%s", "permitted clients: all");
02069         logMess(logBuff, 1);
02070     }
02071 
02072     if (cfig.minport)
02073     {
02074         sprintf(logBuff, "server port range: %u-%u", cfig.minport, cfig.maxport);
02075         logMess(logBuff, 1);
02076     }
02077     else
02078     {
02079         sprintf(logBuff, "server port range: all");
02080         logMess(logBuff, 1);
02081     }
02082 
02083     sprintf(logBuff, "max blksize: %u", blksize);
02084     logMess(logBuff, 1);
02085     sprintf(logBuff, "default blksize: %u", 512);
02086     logMess(logBuff, 1);
02087     sprintf(logBuff, "default timeout: %u", timeout);
02088     logMess(logBuff, 1);
02089     sprintf(logBuff, "file read allowed: %s", cfig.fileRead ? "Yes" : "No");
02090     logMess(logBuff, 1);
02091     sprintf(logBuff, "file create allowed: %s", cfig.fileWrite ? "Yes" : "No");
02092     logMess(logBuff, 1);
02093     sprintf(logBuff, "file overwrite allowed: %s", cfig.fileOverwrite ? "Yes" : "No");
02094     logMess(logBuff, 1);
02095 
02096     if (!verbatim)
02097     {
02098         sprintf(logBuff, "logging: %s", cfig.logLevel > 1 ? "all" : "errors");
02099         logMess(logBuff, 1);
02100     }
02101 
02102     lEvent = CreateEvent(
02103         NULL,                  // default security descriptor
02104         FALSE,                 // ManualReset
02105         TRUE,                  // Signalled
02106         TEXT("AchalTFTServerLogEvent"));  // object name
02107 
02108     if (lEvent == NULL)
02109     {
02110         printf("CreateEvent error: %lu\n", GetLastError());
02111         exit(-1);
02112     }
02113     else if ( GetLastError() == ERROR_ALREADY_EXISTS )
02114     {
02115         sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
02116         logMess(logBuff, 0);
02117         exit(-1);
02118     }
02119 
02120     tEvent = CreateEvent(
02121         NULL,                  // default security descriptor
02122         FALSE,                 // ManualReset
02123         FALSE,                 // Signalled
02124         TEXT("AchalTFTServerThreadEvent"));  // object name
02125 
02126     if (tEvent == NULL)
02127     {
02128         printf("CreateEvent error: %lu\n", GetLastError());
02129         exit(-1);
02130     }
02131     else if ( GetLastError() == ERROR_ALREADY_EXISTS )
02132     {
02133         sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
02134         logMess(logBuff, 0);
02135         exit(-1);
02136     }
02137 
02138     sEvent = CreateEvent(
02139         NULL,                  // default security descriptor
02140         FALSE,                 // ManualReset
02141         TRUE,                  // Signalled
02142         TEXT("AchalTFTServerSocketEvent"));  // object name
02143 
02144     if (sEvent == NULL)
02145     {
02146         printf("CreateEvent error: %lu\n", GetLastError());
02147         exit(-1);
02148     }
02149     else if ( GetLastError() == ERROR_ALREADY_EXISTS )
02150     {
02151         sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
02152         logMess(logBuff, 0);
02153         exit(-1);
02154     }
02155 
02156     cEvent = CreateEvent(
02157         NULL,                  // default security descriptor
02158         FALSE,                 // ManualReset
02159         TRUE,                  // Signalled
02160         TEXT("AchalTFTServerCountEvent"));  // object name
02161 
02162     if (cEvent == NULL)
02163     {
02164         printf("CreateEvent error: %lu\n", GetLastError());
02165         exit(-1);
02166     }
02167     else if ( GetLastError() == ERROR_ALREADY_EXISTS )
02168     {
02169         sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
02170         logMess(logBuff, 0);
02171         exit(-1);
02172     }
02173 
02174     if (minThreads)
02175     {
02176         for (int i = 0; i < minThreads; i++)
02177         {
02178             _beginthread(
02179                   processRequest,                 // thread function
02180                   0,                            // default security attributes
02181                   NULL);                          // argument to thread function
02182         }
02183 
02184         sprintf(logBuff, "thread pool size: %u", minThreads);
02185         logMess(logBuff, 1);
02186     }
02187 
02188     for (int i = 0; i < MAX_SERVERS && cfig.tftpConn[i].port; i++)
02189     {
02190         sprintf(logBuff, "listening on: %s:%i", IP2String(tempbuff, cfig.tftpConn[i].server), cfig.tftpConn[i].port);
02191         logMess(logBuff, 1);
02192     }
02193 }
02194 
02195 void logMess(char *logBuff, BYTE logLevel)
02196 {
02197     WaitForSingleObject(lEvent, INFINITE);
02198 
02199     if (verbatim)
02200         printf("%s\n", logBuff);
02201     else if (cfig.logfile && logLevel <= cfig.logLevel)
02202     {
02203         char currentTime[32];
02204         time_t t = time(NULL);
02205         tm *ttm = localtime(&t);
02206         strftime(currentTime, sizeof(currentTime), "%d-%b-%y %X", ttm);
02207         fprintf(cfig.logfile, "[%s] %s\n", currentTime, logBuff);
02208         fflush(cfig.logfile);
02209     }
02210     SetEvent(lEvent);
02211 }
02212 
02213 void logMess(request *req, BYTE logLevel)
02214 {
02215     WaitForSingleObject(lEvent, INFINITE);
02216 
02217     char tempbuff[256];
02218 
02219     if (verbatim)
02220     {
02221         if (!req->serverError.errormessage[0])
02222             sprintf(req->serverError.errormessage, strerror(errno));
02223 
02224         if (req->path[0])
02225             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);
02226         else
02227             printf("Client %s:%u, %s\n", IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->serverError.errormessage);
02228     }
02229     else if (cfig.logfile && logLevel <= cfig.logLevel)
02230     {
02231         char currentTime[32];
02232         time_t t = time(NULL);
02233         tm *ttm = localtime(&t);
02234         strftime(currentTime, sizeof(currentTime), "%d-%b-%y %X", ttm);
02235 
02236         if (req->path[0])
02237             fprintf(cfig.logfile, "[%s] Client %s:%u %s, %s\n", currentTime, IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage);
02238         else
02239             fprintf(cfig.logfile, "[%s] Client %s:%u, %s\n", currentTime, IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->serverError.errormessage);
02240 
02241         fflush(cfig.logfile);
02242     }
02243     SetEvent(lEvent);
02244 }

Generated on Thu May 24 2012 04:17:58 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.