ReactOS  0.4.11-dev-946-g431643b
tftpd.cpp
Go to the documentation of this file.
1 /**************************************************************************
2 * Copyright (C) 2005 by Achal Dhir *
3 * achaldhir@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20 // TFTPServer.cpp
21 
22 #include <stdio.h>
23 #include <winsock2.h>
24 #include <process.h>
25 #include <time.h>
26 #include <tchar.h>
27 #include <ws2tcpip.h>
28 #include <limits.h>
29 #include <iphlpapi.h>
30 #include <math.h>
31 #include "tftpd.h"
32 
33 //Global Variables
34 char serviceName[] = "TFTPServer";
35 char displayName[] = "Open TFTP Server, MultiThreaded";
36 char sVersion[] = "Open TFTP Server MultiThreaded Version 1.64 Windows Built 2001";
40 char tempbuff[256];
42 char logBuff[512];
43 char fileSep = '\\';
44 char notFileSep = '/';
45 MYWORD blksize = 65464;
46 char verbatim = 0;
52 //ThreadPool Variables
61 
62 //Service Variables
66 
68 {
69  switch (controlCode)
70  {
72  break;
73 
76  serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
77  SetServiceStatus(serviceStatusHandle, &serviceStatus);
78 
79  SetEvent(stopServiceEvent);
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 
95  SetServiceStatus(serviceStatusHandle, &serviceStatus);
96 }
97 
98 void WINAPI ServiceMain(DWORD /*argc*/, TCHAR* /*argv*/[])
99 {
100  serviceStatus.dwServiceType = SERVICE_WIN32;
101  serviceStatus.dwCurrentState = SERVICE_STOPPED;
102  serviceStatus.dwControlsAccepted = 0;
103  serviceStatus.dwWin32ExitCode = NO_ERROR;
104  serviceStatus.dwServiceSpecificExitCode = NO_ERROR;
105  serviceStatus.dwCheckPoint = 0;
106  serviceStatus.dwWaitHint = 0;
107 
109 
111  {
112  serviceStatus.dwCurrentState = SERVICE_START_PENDING;
113  SetServiceStatus(serviceStatusHandle, &serviceStatus);
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 
133  stopServiceEvent = CreateEvent(0, FALSE, FALSE, 0);
134 
136  serviceStatus.dwCurrentState = SERVICE_RUNNING;
137  SetServiceStatus(serviceStatusHandle, &serviceStatus);
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  {
164  WaitForSingleObject(sEvent, INFINITE);
165 
166  currentServer = i;
167 
169  {
170  _beginthread(
171  processRequest, // thread function
172  0, // default security attributes
173  NULL); // argument to thread function
174 
175  }
176 
177  SetEvent(tEvent);
178  WaitForSingleObject(sEvent, INFINITE);
179  fdsReady--;
180  SetEvent(sEvent);
181  }
182  }
183  }
184  }
185  while (WaitForSingleObject(stopServiceEvent, 0) == WAIT_TIMEOUT);
186 
187  serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
188  SetServiceStatus(serviceStatusHandle, &serviceStatus);
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  {
202  fclose(cfig.logfile);
203  cfig.logfile = NULL;
204  }
205 
207  serviceStatus.dwCurrentState = SERVICE_STOPPED;
208  SetServiceStatus(serviceStatusHandle, &serviceStatus);
209  CloseHandle(stopServiceEvent);
210  stopServiceEvent = 0;
211  }
212 }
213 
215 {
216  SERVICE_TABLE_ENTRY serviceTable[] =
217  {
219  {0, 0}
220  };
221 
222  StartServiceCtrlDispatcher(serviceTable);
223 }
224 
225 bool stopService(SC_HANDLE service)
226 {
227  if (service)
228  {
230  QueryServiceStatus(service, &serviceStatus);
231  if (serviceStatus.dwCurrentState != SERVICE_STOPPED)
232  {
233  ControlService(service, SERVICE_CONTROL_STOP, &serviceStatus);
234  printf("Stopping Service.");
235  for (int i = 0; i < 100; i++)
236  {
237  QueryServiceStatus(service, &serviceStatus);
238  if (serviceStatus.dwCurrentState == SERVICE_STOPPED)
239  {
240  printf("Stopped\n");
241  return true;
242  }
243  else
244  {
245  Sleep(500);
246  printf(".");
247  }
248  }
249  printf("Failed\n");
250  return false;
251  }
252  }
253  return true;
254 }
255 
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 }
295 
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 }
322 
324 {
325  MYDWORD dw = GetLastError();
326 
327  if (dw)
328  {
329  LPVOID lpMsgBuf;
330 
335  NULL,
336  dw,
338  (LPTSTR) &lpMsgBuf,
339  0, NULL );
340 
341  printf("Error: %s\nPress Enter..\n", (LPTSTR)lpMsgBuf);
342  getchar();
343  }
344 }
345 
346 int main(int argc, TCHAR* argv[])
347 {
349  osvi.dwOSVersionInfoSize = sizeof(osvi);
350  bool result = GetVersionEx(&osvi);
351 
352  if (result && osvi.dwPlatformId >= VER_PLATFORM_WIN32_NT)
353  {
354  if (argc > 1 && lstrcmpi(argv[1], TEXT("-i")) == 0)
355  installService();
356  else if (argc > 1 && lstrcmpi(argv[1], TEXT("-u")) == 0)
358  else if (argc > 1 && lstrcmpi(argv[1], TEXT("-v")) == 0)
359  {
360  SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT);
361  bool serviceStopped = true;
362 
363  if (serviceControlManager)
364  {
365  SC_HANDLE service = OpenService(serviceControlManager,
367  if (service)
368  {
369  serviceStopped = stopService(service);
370  CloseServiceHandle(service);
371  }
372  CloseServiceHandle(serviceControlManager);
373  }
374  else
376 
377  if (serviceStopped)
378  runProg();
379  else
380  printf("Failed to Stop Service\n");
381  }
382  else
383  runService();
384  }
385  else if (argc == 1 || lstrcmpi(argv[1], TEXT("-v")) == 0)
386  runProg();
387  else
388  printf("This option is not available on Windows95/98/ME\n");
389 
390  return 0;
391 }
392 
393 void runProg()
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 
452  WaitForSingleObject(sEvent, INFINITE);
453 
454  currentServer = i;
455 
457  {
458  _beginthread(
459  processRequest, // thread function
460  0, // default security attributes
461  NULL); // argument to thread function
462  }
463  SetEvent(tEvent);
464 
465  //printf("thread signalled=%u\n",SetEvent(tEvent));
466 
467  WaitForSingleObject(sEvent, INFINITE);
468  fdsReady--;
469  SetEvent(sEvent);
470  }
471  }
472  }
473  }
474  while (true);
475 
476  closeConn();
477 
478  WSACleanup();
479 }
480 
481 void closeConn()
482 {
483  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].loaded; i++)
484  if (network.tftpConn[i].ready)
485  closesocket(network.tftpConn[i].sock);
486 }
487 
488 void processRequest(void *lpParam)
489 {
490  //printf("New Thread %u\n",GetCurrentThreadId());
491 
492  request req;
493 
494  WaitForSingleObject(cEvent, INFINITE);
495  totalThreads++;
496  SetEvent(cEvent);
497 
498  do
499  {
500  WaitForSingleObject(tEvent, INFINITE);
501  //printf("In Thread %u\n",GetCurrentThreadId());
502 
503  WaitForSingleObject(cEvent, INFINITE);
504  activeThreads++;
505  SetEvent(cEvent);
506 
508  {
509  SetEvent(sEvent);
510  req.attempt = UCHAR_MAX;
511  continue;
512  }
513 
514  memset(&req, 0, sizeof(request));
515  req.sock = INVALID_SOCKET;
516 
517  req.clientsize = sizeof(req.client);
518  req.sockInd = currentServer;
520  req.knock = network.tftpConn[req.sockInd].sock;
521 
522  if (req.knock == INVALID_SOCKET)
523  {
524  SetEvent(sEvent);
525  req.attempt = UCHAR_MAX;
526  continue;
527  }
528 
529  errno = 0;
530  req.bytesRecd = recvfrom(req.knock, (char*)&req.mesin, sizeof(message), 0, (sockaddr*)&req.client, &req.clientsize);
532 
533  //printf("socket Signalled=%u\n",SetEvent(sEvent));
534  SetEvent(sEvent);
535 
536  if (!errno && req.bytesRecd > 0)
537  {
538  if (cfig.hostRanges[0].rangeStart)
539  {
540  MYDWORD iip = ntohl(req.client.sin_addr.s_addr);
541  bool allowed = false;
542 
543 #ifdef __REACTOS__
544  for (MYWORD j = 0; j < _countof(cfig.hostRanges) && cfig.hostRanges[j].rangeStart; j++)
545 #else
546  for (int j = 0; j <= 32 && cfig.hostRanges[j].rangeStart; j++)
547 #endif
548  {
549  if (iip >= cfig.hostRanges[j].rangeStart && iip <= cfig.hostRanges[j].rangeEnd)
550  {
551  allowed = true;
552  break;
553  }
554  }
555 
556  if (!allowed)
557  {
558  req.serverError.opcode = htons(5);
559  req.serverError.errorcode = htons(2);
560  strcpy(req.serverError.errormessage, "Access Denied");
561  logMess(&req, 1);
562  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
563  req.attempt = UCHAR_MAX;
564  continue;
565  }
566  }
567 
568  if ((htons(req.mesin.opcode) == 5))
569  {
570  sprintf(req.serverError.errormessage, "Error Code %i at Client, %s", ntohs(req.clientError.errorcode), req.clientError.errormessage);
571  logMess(&req, 2);
572  req.attempt = UCHAR_MAX;
573  continue;
574  }
575  else if (htons(req.mesin.opcode) != 1 && htons(req.mesin.opcode) != 2)
576  {
577  req.serverError.opcode = htons(5);
578  req.serverError.errorcode = htons(5);
579  sprintf(req.serverError.errormessage, "Unknown Transfer Id");
580  logMess(&req, 2);
581  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
582  req.attempt = UCHAR_MAX;
583  continue;
584  }
585  }
586  else
587  {
588  sprintf(req.serverError.errormessage, "Communication Error");
589  logMess(&req, 1);
590  req.attempt = UCHAR_MAX;
591  continue;
592  }
593 
594  req.blksize = 512;
595  req.timeout = timeout;
596  req.expiry = time(NULL) + req.timeout;
597  bool fetchAck = false;
598 
600 
601  if (req.sock == INVALID_SOCKET)
602  {
603  req.serverError.opcode = htons(5);
604  req.serverError.errorcode = htons(0);
605  strcpy(req.serverError.errormessage, "Thread Socket Creation Error");
606  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
607  logMess(&req, 1);
608  req.attempt = UCHAR_MAX;
609  continue;
610  }
611 
612  sockaddr_in service;
613  service.sin_family = AF_INET;
614  service.sin_addr.s_addr = network.tftpConn[req.sockInd].server;
615 
616  if (cfig.minport)
617  {
618  for (MYWORD comport = cfig.minport; ; comport++)
619  {
620  service.sin_port = htons(comport);
621 
622  if (comport > cfig.maxport)
623  {
624  req.serverError.opcode = htons(5);
625  req.serverError.errorcode = htons(0);
626  strcpy(req.serverError.errormessage, "No port is free");
627  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
628  logMess(&req, 1);
629  req.attempt = UCHAR_MAX;
630  break;
631  }
632  else if (bind(req.sock, (sockaddr*) &service, sizeof(service)) == -1)
633  continue;
634  else
635  break;
636  }
637  }
638  else
639  {
640  service.sin_port = 0;
641 
642  if (bind(req.sock, (sockaddr*) &service, sizeof(service)) == -1)
643  {
644  strcpy(req.serverError.errormessage, "Thread failed to bind");
645  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
646  logMess(&req, 1);
647  req.attempt = UCHAR_MAX;
648  }
649  }
650 
651  if (req.attempt >= 3)
652  continue;
653 
654  if (connect(req.sock, (sockaddr*)&req.client, req.clientsize) == -1)
655  {
656  req.serverError.opcode = htons(5);
657  req.serverError.errorcode = htons(0);
658  strcpy(req.serverError.errormessage, "Connect Failed");
659  sendto(req.knock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0, (sockaddr*)&req.client, req.clientsize);
660  logMess(&req, 1);
661  req.attempt = UCHAR_MAX;
662  continue;
663  }
664 
665  //sprintf(req.serverError.errormessage, "In Temp, Socket");
666  //logMess(&req, 1);
667 
668  char *inPtr = req.mesin.buffer;
669  *(inPtr + (req.bytesRecd - 3)) = 0;
670  req.filename = inPtr;
671 
672  if (!strlen(req.filename) || strlen(req.filename) > UCHAR_MAX)
673  {
674  req.serverError.opcode = htons(5);
675  req.serverError.errorcode = htons(4);
676  strcpy(req.serverError.errormessage, "Malformed Request, Invalid/Missing Filename");
677  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
678  req.attempt = UCHAR_MAX;
679  logMess(&req, 1);
680  continue;
681  }
682 
683  inPtr += strlen(inPtr) + 1;
684  req.mode = inPtr;
685 
686  if (!strlen(req.mode) || strlen(req.mode) > 25)
687  {
688  req.serverError.opcode = htons(5);
689  req.serverError.errorcode = htons(4);
690  strcpy(req.serverError.errormessage, "Malformed Request, Invalid/Missing Mode");
691  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
692  req.attempt = UCHAR_MAX;
693  logMess(&req, 1);
694  continue;
695  }
696 
697  inPtr += strlen(inPtr) + 1;
698 
699  for (MYDWORD i = 0; i < strlen(req.filename); i++)
700  if (req.filename[i] == notFileSep)
701  req.filename[i] = fileSep;
702 
703  tempbuff[0] = '.';
704  tempbuff[1] = '.';
705  tempbuff[2] = fileSep;
706  tempbuff[3] = 0;
707 
708  if (strstr(req.filename, tempbuff))
709  {
710  req.serverError.opcode = htons(5);
711  req.serverError.errorcode = htons(2);
712  strcpy(req.serverError.errormessage, "Access violation");
713  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
714  logMess(&req, 1);
715  req.attempt = UCHAR_MAX;
716  continue;
717  }
718 
719  if (req.filename[0] == fileSep)
720  req.filename++;
721 
722  if (!cfig.homes[0].alias[0])
723  {
724  if (strlen(cfig.homes[0].target) + strlen(req.filename) >= sizeof(req.path))
725  {
726  req.serverError.opcode = htons(5);
727  req.serverError.errorcode = htons(4);
728  sprintf(req.serverError.errormessage, "Filename too large");
729  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
730  logMess(&req, 1);
731  req.attempt = UCHAR_MAX;
732  continue;
733  }
734 
735  strcpy(req.path, cfig.homes[0].target);
736  strcat(req.path, req.filename);
737  }
738  else
739  {
740  char *bname = strchr(req.filename, fileSep);
741 
742  if (bname)
743  {
744  *bname = 0;
745  bname++;
746  }
747  else
748  {
749  req.serverError.opcode = htons(5);
750  req.serverError.errorcode = htons(2);
751  sprintf(req.serverError.errormessage, "Missing directory/alias");
752  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
753  logMess(&req, 1);
754  req.attempt = UCHAR_MAX;
755  continue;
756  }
757 
758 #ifdef __REACTOS__
759  for (int i = 0; i < MAX_SERVERS; i++)
760 #else
761  for (int i = 0; i < 8; i++)
762 #endif
763  {
764  //printf("%s=%i\n", req.filename, cfig.homes[i].alias[0]);
765  if (cfig.homes[i].alias[0] && !strcasecmp(req.filename, cfig.homes[i].alias))
766  {
767  if (strlen(cfig.homes[i].target) + strlen(bname) >= sizeof(req.path))
768  {
769  req.serverError.opcode = htons(5);
770  req.serverError.errorcode = htons(4);
771  sprintf(req.serverError.errormessage, "Filename too large");
772  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
773  logMess(&req, 1);
774  req.attempt = UCHAR_MAX;
775  break;
776  }
777 
778  strcpy(req.path, cfig.homes[i].target);
779  strcat(req.path, bname);
780  break;
781  }
782  else if (i == 7 || !cfig.homes[i].alias[0])
783  {
784  req.serverError.opcode = htons(5);
785  req.serverError.errorcode = htons(2);
786  sprintf(req.serverError.errormessage, "No such directory/alias %s", req.filename);
787  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
788  logMess(&req, 1);
789  req.attempt = UCHAR_MAX;
790  break;
791  }
792  }
793  }
794 
795  if (req.attempt >= 3)
796  continue;
797 
798  if (ntohs(req.mesin.opcode) == 1)
799  {
800  if (!cfig.fileRead)
801  {
802  req.serverError.opcode = htons(5);
803  req.serverError.errorcode = htons(2);
804  strcpy(req.serverError.errormessage, "GET Access Denied");
805  logMess(&req, 1);
806  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
807  req.attempt = UCHAR_MAX;
808  continue;
809  }
810 
811  if (*inPtr)
812  {
813  char *tmp = inPtr;
814 
815  while (*tmp)
816  {
817  if (!strcasecmp(tmp, "blksize"))
818  {
819  tmp += strlen(tmp) + 1;
820  MYDWORD val = atol(tmp);
821 
822  if (val < 512)
823  val = 512;
824  else if (val > blksize)
825  val = blksize;
826 
827  req.blksize = val;
828  break;
829  }
830 
831  tmp += strlen(tmp) + 1;
832  }
833  }
834 
835  errno = 0;
836 
837  if (!strcasecmp(req.mode, "netascii") || !strcasecmp(req.mode, "ascii"))
838  req.file = fopen(req.path, "rt");
839  else
840  req.file = fopen(req.path, "rb");
841 
842  if (errno || !req.file)
843  {
844  req.serverError.opcode = htons(5);
845  req.serverError.errorcode = htons(1);
846  strcpy(req.serverError.errormessage, "File not found or No Access");
847  logMess(&req, 1);
848  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
849  req.attempt = UCHAR_MAX;
850  continue;
851  }
852  }
853  else
854  {
855  if (!cfig.fileWrite && !cfig.fileOverwrite)
856  {
857  req.serverError.opcode = htons(5);
858  req.serverError.errorcode = htons(2);
859  strcpy(req.serverError.errormessage, "PUT Access Denied");
860  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
861  logMess(&req, 1);
862  req.attempt = UCHAR_MAX;
863  continue;
864  }
865 
866  req.file = fopen(req.path, "rb");
867 
868  if (req.file)
869  {
870  fclose(req.file);
871  req.file = NULL;
872 
873  if (!cfig.fileOverwrite)
874  {
875  req.serverError.opcode = htons(5);
876  req.serverError.errorcode = htons(6);
877  strcpy(req.serverError.errormessage, "File already exists");
878  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
879  logMess(&req, 1);
880  req.attempt = UCHAR_MAX;
881  continue;
882  }
883  }
884  else if (!cfig.fileWrite)
885  {
886  req.serverError.opcode = htons(5);
887  req.serverError.errorcode = htons(2);
888  strcpy(req.serverError.errormessage, "Create File Access Denied");
889  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
890  logMess(&req, 1);
891  req.attempt = UCHAR_MAX;
892  continue;
893  }
894 
895  errno = 0;
896 
897  if (!strcasecmp(req.mode, "netascii") || !strcasecmp(req.mode, "ascii"))
898  req.file = fopen(req.path, "wt");
899  else
900  req.file = fopen(req.path, "wb");
901 
902  if (errno || !req.file)
903  {
904  req.serverError.opcode = htons(5);
905  req.serverError.errorcode = htons(2);
906  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
907  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
908  logMess(&req, 1);
909  req.attempt = UCHAR_MAX;
910  continue;
911  }
912  }
913 
914  setvbuf(req.file, NULL, _IOFBF, 5 * req.blksize);
915 
916  if (*inPtr)
917  {
918  fetchAck = true;
919  char *outPtr = req.mesout.buffer;
920  req.mesout.opcode = htons(6);
921  MYDWORD val;
922  while (*inPtr)
923  {
924  //printf("%s\n", inPtr);
925  if (!strcasecmp(inPtr, "blksize"))
926  {
927  strcpy(outPtr, inPtr);
928  outPtr += strlen(outPtr) + 1;
929  inPtr += strlen(inPtr) + 1;
930  val = atol(inPtr);
931 
932  if (val < 512)
933  val = 512;
934  else if (val > blksize)
935  val = blksize;
936 
937  req.blksize = val;
938  sprintf(outPtr, "%u", val);
939  outPtr += strlen(outPtr) + 1;
940  }
941  else if (!strcasecmp(inPtr, "tsize"))
942  {
943  strcpy(outPtr, inPtr);
944  outPtr += strlen(outPtr) + 1;
945  inPtr += strlen(inPtr) + 1;
946 
947  if (ntohs(req.mesin.opcode) == 1)
948  {
949  if (!fseek(req.file, 0, SEEK_END))
950  {
951  if (ftell(req.file) >= 0)
952  {
953  req.tsize = ftell(req.file);
954  sprintf(outPtr, "%u", req.tsize);
955  outPtr += strlen(outPtr) + 1;
956  }
957  else
958  {
959  req.serverError.opcode = htons(5);
960  req.serverError.errorcode = htons(2);
961  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
962  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
963  logMess(&req, 1);
964  req.attempt = UCHAR_MAX;
965  break;
966  }
967  }
968  else
969  {
970  req.serverError.opcode = htons(5);
971  req.serverError.errorcode = htons(2);
972  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
973  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
974  logMess(&req, 1);
975  req.attempt = UCHAR_MAX;
976  break;
977  }
978  }
979  else
980  {
981  req.tsize = 0;
982  sprintf(outPtr, "%u", req.tsize);
983  outPtr += strlen(outPtr) + 1;
984  }
985  }
986  else if (!strcasecmp(inPtr, "timeout"))
987  {
988  strcpy(outPtr, inPtr);
989  outPtr += strlen(outPtr) + 1;
990  inPtr += strlen(inPtr) + 1;
991  val = atoi(inPtr);
992 
993  if (val < 1)
994  val = 1;
995  else if (val > UCHAR_MAX)
996  val = UCHAR_MAX;
997 
998  req.timeout = val;
999  req.expiry = time(NULL) + req.timeout;
1000  sprintf(outPtr, "%u", val);
1001  outPtr += strlen(outPtr) + 1;
1002  }
1003 
1004  inPtr += strlen(inPtr) + 1;
1005  //printf("=%u\n", val);
1006  }
1007 
1008  if (req.attempt >= 3)
1009  continue;
1010 
1011  errno = 0;
1012  req.bytesReady = (const char*)outPtr - (const char*)&req.mesout;
1013  //printf("Bytes Ready=%u\n", req.bytesReady);
1014  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1015  errno = WSAGetLastError();
1016  }
1017  else if (htons(req.mesin.opcode) == 2)
1018  {
1019  req.acout.opcode = htons(4);
1020  req.acout.block = htons(0);
1021  errno = 0;
1022  req.bytesReady = 4;
1023  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1024  errno = WSAGetLastError();
1025  }
1026 
1027  if (errno)
1028  {
1029  sprintf(req.serverError.errormessage, "Communication Error");
1030  logMess(&req, 1);
1031  req.attempt = UCHAR_MAX;
1032  continue;
1033  }
1034  else if (ntohs(req.mesin.opcode) == 1)
1035  {
1036  errno = 0;
1037  req.pkt[0] = (packet*)calloc(1, req.blksize + 4);
1038  req.pkt[1] = (packet*)calloc(1, req.blksize + 4);
1039 
1040  if (errno || !req.pkt[0] || !req.pkt[1])
1041  {
1042  sprintf(req.serverError.errormessage, "Memory Error");
1043  logMess(&req, 1);
1044  req.attempt = UCHAR_MAX;
1045  continue;
1046  }
1047 
1048  long ftellLoc = ftell(req.file);
1049 
1050  if (ftellLoc > 0)
1051  {
1052  if (fseek(req.file, 0, SEEK_SET))
1053  {
1054  req.serverError.opcode = htons(5);
1055  req.serverError.errorcode = htons(2);
1056  strcpy(req.serverError.errormessage, "File Access Error");
1057  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1058  logMess(&req, 1);
1059  req.attempt = UCHAR_MAX;
1060  continue;
1061  }
1062  }
1063  else if (ftellLoc < 0)
1064  {
1065  req.serverError.opcode = htons(5);
1066  req.serverError.errorcode = htons(2);
1067  strcpy(req.serverError.errormessage, "File Access Error");
1068  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1069  logMess(&req, 1);
1070  req.attempt = UCHAR_MAX;
1071  continue;
1072  }
1073 
1074  errno = 0;
1075  req.pkt[0]->opcode = htons(3);
1076  req.pkt[0]->block = htons(1);
1077  req.bytesRead[0] = fread(&req.pkt[0]->buffer, 1, req.blksize, req.file);
1078 
1079  if (errno)
1080  {
1081  req.serverError.opcode = htons(5);
1082  req.serverError.errorcode = htons(2);
1083  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
1084  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1085  logMess(&req, 1);
1086  req.attempt = UCHAR_MAX;
1087  continue;
1088  }
1089 
1090  if (req.bytesRead[0] == req.blksize)
1091  {
1092  req.pkt[1]->opcode = htons(3);
1093  req.pkt[1]->block = htons(2);
1094  req.bytesRead[1] = fread(&req.pkt[1]->buffer, 1, req.blksize, req.file);
1095  if (req.bytesRead[1] < req.blksize)
1096  {
1097  fclose(req.file);
1098  req.file = 0;
1099  }
1100  }
1101  else
1102  {
1103  fclose(req.file);
1104  req.file = 0;
1105  }
1106 
1107  if (errno)
1108  {
1109  req.serverError.opcode = htons(5);
1110  req.serverError.errorcode = htons(2);
1111  strcpy(req.serverError.errormessage, "Invalid Path or No Access");
1112  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1113  logMess(&req, 1);
1114  req.attempt = UCHAR_MAX;
1115  continue;
1116  }
1117 
1118  while (req.attempt <= 3)
1119  {
1120  if (fetchAck)
1121  {
1122  FD_ZERO(&req.readfds);
1123  req.tv.tv_sec = 1;
1124  req.tv.tv_usec = 0;
1125  FD_SET(req.sock, &req.readfds);
1126  select(req.sock + 1, &req.readfds, NULL, NULL, &req.tv);
1127 
1128  if (FD_ISSET(req.sock, &req.readfds))
1129  {
1130  errno = 0;
1131  req.bytesRecd = recv(req.sock, (char*)&req.mesin, sizeof(message), 0);
1132  errno = WSAGetLastError();
1133  if (req.bytesRecd <= 0 || errno)
1134  {
1135  sprintf(req.serverError.errormessage, "Communication Error");
1136  logMess(&req, 1);
1137  req.attempt = UCHAR_MAX;
1138  break;
1139  }
1140  else if(req.bytesRecd >= 4 && ntohs(req.mesin.opcode) == 4)
1141  {
1142  if (ntohs(req.acin.block) == req.block)
1143  {
1144  req.block++;
1145  req.fblock++;
1146  req.attempt = 0;
1147  }
1148  else if (req.expiry > time(NULL))
1149  continue;
1150  else
1151  req.attempt++;
1152  }
1153  else if (ntohs(req.mesin.opcode) == 5)
1154  {
1155  sprintf(req.serverError.errormessage, "Client %s:%u, Error Code %i at Client, %s", inet_ntoa(req.client.sin_addr), ntohs(req.client.sin_port), ntohs(req.clientError.errorcode), req.clientError.errormessage);
1156  logMess(&req, 1);
1157  req.attempt = UCHAR_MAX;
1158  break;
1159  }
1160  else
1161  {
1162  req.serverError.opcode = htons(5);
1163  req.serverError.errorcode = htons(4);
1164  sprintf(req.serverError.errormessage, "Unexpected Option Code %i", ntohs(req.mesin.opcode));
1165  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1166  logMess(&req, 1);
1167  req.attempt = UCHAR_MAX;
1168  break;
1169  }
1170  }
1171  else if (req.expiry > time(NULL))
1172  continue;
1173  else
1174  req.attempt++;
1175  }
1176  else
1177  {
1178  fetchAck = true;
1179  req.acin.block = 1;
1180  req.block = 1;
1181  req.fblock = 1;
1182  }
1183 
1184  if (req.attempt >= 3)
1185  {
1186  req.serverError.opcode = htons(5);
1187  req.serverError.errorcode = htons(0);
1188 
1189  if (req.fblock && !req.block)
1190  strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
1191  else
1192  strcpy(req.serverError.errormessage, "Timeout");
1193 
1194  logMess(&req, 1);
1195  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1196  req.attempt = UCHAR_MAX;
1197  break;
1198  }
1199  else if (!req.fblock)
1200  {
1201  errno = 0;
1202  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1203  errno = WSAGetLastError();
1204  if (errno)
1205  {
1206  sprintf(req.serverError.errormessage, "Communication Error");
1207  logMess(&req, 1);
1208  req.attempt = UCHAR_MAX;
1209  break;
1210  }
1211  req.expiry = time(NULL) + req.timeout;
1212  }
1213  else if (ntohs(req.pkt[0]->block) == req.block)
1214  {
1215  errno = 0;
1216  send(req.sock, (const char*)req.pkt[0], req.bytesRead[0] + 4, 0);
1217  errno = WSAGetLastError();
1218  if (errno)
1219  {
1220  sprintf(req.serverError.errormessage, "Communication Error");
1221  logMess(&req, 1);
1222  req.attempt = UCHAR_MAX;
1223  break;
1224  }
1225  req.expiry = time(NULL) + req.timeout;
1226 
1227  if (req.file)
1228  {
1229  req.tblock = ntohs(req.pkt[1]->block) + 1;
1230  if (req.tblock == req.block)
1231  {
1232  req.pkt[1]->block = htons(++req.tblock);
1233  req.bytesRead[1] = fread(&req.pkt[1]->buffer, 1, req.blksize, req.file);
1234 
1235  if (errno)
1236  {
1237  req.serverError.opcode = htons(5);
1238  req.serverError.errorcode = htons(4);
1240  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1241  logMess(&req, 1);
1242  req.attempt = UCHAR_MAX;
1243  break;
1244  }
1245  else if (req.bytesRead[1] < req.blksize)
1246  {
1247  fclose(req.file);
1248  req.file = 0;
1249  }
1250  }
1251  }
1252  }
1253  else if (ntohs(req.pkt[1]->block) == req.block)
1254  {
1255  errno = 0;
1256  send(req.sock, (const char*)req.pkt[1], req.bytesRead[1] + 4, 0);
1257  errno = WSAGetLastError();
1258  if (errno)
1259  {
1260  sprintf(req.serverError.errormessage, "Communication Error");
1261  logMess(&req, 1);
1262  req.attempt = UCHAR_MAX;
1263  break;
1264  }
1265 
1266  req.expiry = time(NULL) + req.timeout;
1267 
1268  if (req.file)
1269  {
1270  req.tblock = ntohs(req.pkt[0]->block) + 1;
1271  if (req.tblock == req.block)
1272  {
1273  req.pkt[0]->block = htons(++req.tblock);
1274  req.bytesRead[0] = fread(&req.pkt[0]->buffer, 1, req.blksize, req.file);
1275  if (errno)
1276  {
1277  req.serverError.opcode = htons(5);
1278  req.serverError.errorcode = htons(4);
1280  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1281  logMess(&req, 1);
1282  req.attempt = UCHAR_MAX;
1283  break;
1284  }
1285  else if (req.bytesRead[0] < req.blksize)
1286  {
1287  fclose(req.file);
1288  req.file = 0;
1289  }
1290  }
1291  }
1292  }
1293  else
1294  {
1295  sprintf(req.serverError.errormessage, "%u Blocks Served", req.fblock - 1);
1296  logMess(&req, 2);
1297  req.attempt = UCHAR_MAX;
1298  break;
1299  }
1300  }
1301  }
1302  else if (ntohs(req.mesin.opcode) == 2)
1303  {
1304  errno = 0;
1305  req.pkt[0] = (packet*)calloc(1, req.blksize + 4);
1306 
1307  if (errno || !req.pkt[0])
1308  {
1309  sprintf(req.serverError.errormessage, "Memory Error");
1310  logMess(&req, 1);
1311  req.attempt = UCHAR_MAX;
1312  continue;
1313  }
1314 
1315  while (req.attempt <= 3)
1316  {
1317  FD_ZERO(&req.readfds);
1318  req.tv.tv_sec = 1;
1319  req.tv.tv_usec = 0;
1320  FD_SET(req.sock, &req.readfds);
1321  select(req.sock + 1, &req.readfds, NULL, NULL, &req.tv);
1322 
1323  if (FD_ISSET(req.sock, &req.readfds))
1324  {
1325  errno = 0;
1326  req.bytesRecd = recv(req.sock, (char*)req.pkt[0], req.blksize + 4, 0);
1327  errno = WSAGetLastError();
1328 
1329  if (errno)
1330  {
1331  sprintf(req.serverError.errormessage, "Communication Error");
1332  logMess(&req, 1);
1333  req.attempt = UCHAR_MAX;
1334  break;
1335  }
1336  }
1337  else
1338  req.bytesRecd = 0;
1339 
1340  if (req.bytesRecd >= 4)
1341  {
1342  if (ntohs(req.pkt[0]->opcode) == 3)
1343  {
1344  req.tblock = req.block + 1;
1345 
1346  if (ntohs(req.pkt[0]->block) == req.tblock)
1347  {
1348  req.acout.opcode = htons(4);
1349  req.acout.block = req.pkt[0]->block;
1350  req.block++;
1351  req.fblock++;
1352  req.bytesReady = 4;
1353  req.expiry = time(NULL) + req.timeout;
1354 
1355  errno = 0;
1356  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1357  errno = WSAGetLastError();
1358 
1359  if (errno)
1360  {
1361  sprintf(req.serverError.errormessage, "Communication Error");
1362  logMess(&req, 1);
1363  req.attempt = UCHAR_MAX;
1364  break;
1365  }
1366 
1367  if (req.bytesRecd > 4)
1368  {
1369  errno = 0;
1370  if (fwrite(&req.pkt[0]->buffer, req.bytesRecd - 4, 1, req.file) != 1 || errno)
1371  {
1372  req.serverError.opcode = htons(5);
1373  req.serverError.errorcode = htons(3);
1374  strcpy(req.serverError.errormessage, "Disk full or allocation exceeded");
1375  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1376  logMess(&req, 1);
1377  req.attempt = UCHAR_MAX;
1378  break;
1379  }
1380  else
1381  req.attempt = 0;
1382  }
1383  else
1384  req.attempt = 0;
1385 
1386  if ((MYWORD)req.bytesRecd < req.blksize + 4)
1387  {
1388  fclose(req.file);
1389  req.file = 0;
1390  sprintf(req.serverError.errormessage, "%u Blocks Received", req.fblock);
1391  logMess(&req, 2);
1392  req.attempt = UCHAR_MAX;
1393  break;
1394  }
1395  }
1396  else if (req.expiry > time(NULL))
1397  continue;
1398  else if (req.attempt >= 3)
1399  {
1400  req.serverError.opcode = htons(5);
1401  req.serverError.errorcode = htons(0);
1402 
1403  if (req.fblock && !req.block)
1404  strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
1405  else
1406  strcpy(req.serverError.errormessage, "Timeout");
1407 
1408  logMess(&req, 1);
1409  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1410  req.attempt = UCHAR_MAX;
1411  break;
1412  }
1413  else
1414  {
1415  req.expiry = time(NULL) + req.timeout;
1416  errno = 0;
1417  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1418  errno = WSAGetLastError();
1419  req.attempt++;
1420 
1421  if (errno)
1422  {
1423  sprintf(req.serverError.errormessage, "Communication Error");
1424  logMess(&req, 1);
1425  req.attempt = UCHAR_MAX;
1426  break;
1427  }
1428  }
1429  }
1430  else if (req.bytesRecd > (int)sizeof(message))
1431  {
1432  req.serverError.opcode = htons(5);
1433  req.serverError.errorcode = htons(4);
1434  sprintf(req.serverError.errormessage, "Error: Incoming Packet too large");
1435  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1436  logMess(&req, 1);
1437  req.attempt = UCHAR_MAX;
1438  break;
1439  }
1440  else if (ntohs(req.pkt[0]->opcode) == 5)
1441  {
1442  sprintf(req.serverError.errormessage, "Error Code %i at Client, %s", ntohs(req.pkt[0]->block), &req.pkt[0]->buffer);
1443  logMess(&req, 1);
1444  req.attempt = UCHAR_MAX;
1445  break;
1446  }
1447  else
1448  {
1449  req.serverError.opcode = htons(5);
1450  req.serverError.errorcode = htons(4);
1451  sprintf(req.serverError.errormessage, "Unexpected Option Code %i", ntohs(req.pkt[0]->opcode));
1452  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1453  logMess(&req, 1);
1454  req.attempt = UCHAR_MAX;
1455  break;
1456  }
1457  }
1458  else if (req.expiry > time(NULL))
1459  continue;
1460  else if (req.attempt >= 3)
1461  {
1462  req.serverError.opcode = htons(5);
1463  req.serverError.errorcode = htons(0);
1464 
1465  if (req.fblock && !req.block)
1466  strcpy(req.serverError.errormessage, "Large File, Block# Rollover not supported by Client");
1467  else
1468  strcpy(req.serverError.errormessage, "Timeout");
1469 
1470  logMess(&req, 1);
1471  send(req.sock, (const char*)&req.serverError, strlen(req.serverError.errormessage) + 5, 0);
1472  req.attempt = UCHAR_MAX;
1473  break;
1474  }
1475  else
1476  {
1477  req.expiry = time(NULL) + req.timeout;
1478  errno = 0;
1479  send(req.sock, (const char*)&req.mesout, req.bytesReady, 0);
1480  errno = WSAGetLastError();
1481  req.attempt++;
1482 
1483  if (errno)
1484  {
1485  sprintf(req.serverError.errormessage, "Communication Error");
1486  logMess(&req, 1);
1487  req.attempt = UCHAR_MAX;
1488  break;
1489  }
1490  }
1491  }
1492  }
1493  }
1494  while (cleanReq(&req));
1495 
1496  WaitForSingleObject(cEvent, INFINITE);
1497  totalThreads--;
1498  SetEvent(cEvent);
1499 
1500  //printf("Thread %u Killed\n",GetCurrentThreadId());
1501  _endthread();
1502  return;
1503 }
1504 
1505 bool cleanReq(request* req)
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 
1524  WaitForSingleObject(cEvent, INFINITE);
1525  activeThreads--;
1526  SetEvent(cEvent);
1527 
1528  //printf("cleaned\n");
1529 
1530  return (totalThreads <= minThreads);
1531 }
1532 
1533 bool getSection(const char *sectionName, char *buffer, MYBYTE serial, char *fileName)
1534 {
1535  //printf("%s=%s\n",fileName,sectionName);
1536  char section[128];
1537  sprintf(section, "[%s]", sectionName);
1538  myUpper(section);
1539  FILE *f = fopen(fileName, "rt");
1540  char buff[512];
1541  MYBYTE found = 0;
1542 
1543  if (f)
1544  {
1545  while (fgets(buff, 511, f))
1546  {
1547  myUpper(buff);
1548  myTrim(buff, buff);
1549 
1550  if (strstr(buff, section) == buff)
1551  {
1552  found++;
1553  if (found == serial)
1554  {
1555  //printf("%s=%s\n",fileName,sectionName);
1556  while (fgets(buff, 511, f))
1557  {
1558  myTrim(buff, buff);
1559 
1560  if (strstr(buff, "[") == buff)
1561  break;
1562 
1563  if (((*buff) >= '0' && (*buff) <= '9') || ((*buff) >= 'A' && (*buff) <= 'Z') || ((*buff) >= 'a' && (*buff) <= 'z') || ((*buff) && strchr("/\\?*", (*buff))))
1564  {
1565  buffer += sprintf(buffer, "%s", buff);
1566  buffer++;
1567  }
1568  }
1569  break;
1570  }
1571  }
1572  }
1573  fclose(f);
1574  }
1575 
1576  *buffer = 0;
1577  *(buffer + 1) = 0;
1578  return (found == serial);
1579 }
1580 
1581 FILE *openSection(const char *sectionName, MYBYTE serial, char *fileName)
1582 {
1583  //printf("%s=%s\n",fileName,sectionName);
1584  char section[128];
1585  sprintf(section, "[%s]", sectionName);
1586  myUpper(section);
1587  FILE *f = fopen(fileName, "rt");
1588  char buff[512];
1589  MYBYTE found = 0;
1590 
1591  if (f)
1592  {
1593  while (fgets(buff, 511, f))
1594  {
1595  myUpper(buff);
1596  myTrim(buff, buff);
1597 
1598  if (strstr(buff, section) == buff)
1599  {
1600  found++;
1601 
1602  if (found == serial)
1603  return f;
1604  }
1605  }
1606  fclose(f);
1607  }
1608  return NULL;
1609 }
1610 
1611 char *readSection(char* buff, FILE *f)
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 }
1627 
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 }
1642 
1643 MYWORD myTokenize(char *target, char *source, char *sep, bool whiteSep)
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 }
1688 
1689 char* myTrim(char *target, char *source)
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 }
1707 
1708 /*
1709 void mySplit(char *name, char *value, char *source, char splitChar)
1710 {
1711  char *dp = strchr(source, splitChar);
1712 
1713  if (dp)
1714  {
1715  strncpy(name, source, (dp - source));
1716  name[dp - source] = 0;
1717  strcpy(value, dp + 1);
1718  myTrim(name, name);
1719  myTrim(value, value);
1720  }
1721  else
1722  {
1723  strcpy(name, source);
1724  myTrim(name, name);
1725  *value = 0;
1726  }
1727 }
1728 */
1729 
1730 void mySplit(char *name, char *value, char *source, char splitChar)
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 }
1757 
1758 
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 }
1766 
1767 bool isIP(char *string)
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 }
1784 
1785 char *myUpper(char *string)
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 }
1794 
1795 char *myLower(char *string)
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 }
1804 
1805 void init(void *lpParam)
1806 {
1807  memset(&cfig, 0, sizeof(cfig));
1808 
1810  char *fileExt = strrchr(extbuff, '.');
1811  *fileExt = 0;
1812  sprintf(iniFile, "%s.ini", extbuff);
1813  sprintf(lnkFile, "%s.url", extbuff);
1814  fileExt = strrchr(extbuff, '\\');
1815  *fileExt = 0;
1816  fileExt++;
1817  sprintf(logFile, "%s\\log\\%s%%Y%%m%%d.log", extbuff, fileExt);
1818 
1819  FILE *f = NULL;
1820  char raw[512];
1821  char name[512];
1822  char value[512];
1823 
1824  if (verbatim)
1825  {
1826  cfig.logLevel = 2;
1827  printf("%s\n\n", sVersion);
1828  }
1829  else if ((f = openSection("LOGGING", 1, iniFile)))
1830  {
1831  cfig.logLevel = 1;
1832  tempbuff[0] = 0;
1833 
1834  while (readSection(raw, f))
1835  {
1836  if (!strcasecmp(raw, "None"))
1837  cfig.logLevel = 0;
1838  else if (!strcasecmp(raw, "Errors"))
1839  cfig.logLevel = 1;
1840  else if (!strcasecmp(raw, "All"))
1841  cfig.logLevel = 2;
1842  else
1843  sprintf(tempbuff, "Section [LOGGING], Invalid LogLevel: %s", raw);
1844  }
1845  }
1846 
1847  if (!verbatim && cfig.logLevel && logFile[0])
1848  {
1849  time_t t = time(NULL);
1850  tm *ttm = localtime(&t);
1851  loggingDay = ttm->tm_yday;
1852  strftime(extbuff, sizeof(extbuff), logFile, ttm);
1853 
1854  cfig.logfile = fopen(extbuff, "at");
1855 
1856  if (cfig.logfile)
1857  {
1858  WritePrivateProfileString("InternetShortcut","URL", extbuff, lnkFile);
1859  WritePrivateProfileString("InternetShortcut","IconIndex", "0", lnkFile);
1860  WritePrivateProfileString("InternetShortcut","IconFile", extbuff, lnkFile);
1861  sprintf(logBuff, "%s Starting..", sVersion);
1862  logMess(logBuff, 1);
1863 
1864  if (tempbuff[0])
1865  logMess(tempbuff, 0);
1866  }
1867  }
1868 
1869  MYWORD wVersionRequested = MAKEWORD(1, 1);
1870  WSAStartup(wVersionRequested, &cfig.wsaData);
1871 
1872  if (cfig.wsaData.wVersion != wVersionRequested)
1873  {
1874  sprintf(logBuff, "WSAStartup Error");
1875  logMess(logBuff, 1);
1876  }
1877 
1878  if ((f = openSection("HOME", 1, iniFile)))
1879  {
1880  while (readSection(raw, f))
1881  {
1882  mySplit(name, value, raw, '=');
1883 
1884  if (strlen(value))
1885  {
1886  if (!cfig.homes[0].alias[0] && cfig.homes[0].target[0])
1887  {
1888  sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", raw);
1889  logMess(logBuff, 1);
1890  }
1891  else if (strchr(name, notFileSep) || strchr(name, fileSep) || strchr(name, '>') || strchr(name, '<') || strchr(name, '.'))
1892  {
1893  sprintf(logBuff, "Section [HOME], invalid chars in alias %s, entry ignored", name);
1894  logMess(logBuff, 1);
1895  }
1896  else if (name[0] && strlen(name) < 64 && value[0])
1897  {
1898 #ifdef __REACTOS__
1899  for (int i = 0; i < MAX_SERVERS; i++)
1900 #else
1901  for (int i = 0; i < 8; i++)
1902 #endif
1903  {
1904  if (cfig.homes[i].alias[0] && !strcasecmp(name, cfig.homes[i].alias))
1905  {
1906  sprintf(logBuff, "Section [HOME], Duplicate Entry: %s ignored", raw);
1907  logMess(logBuff, 1);
1908  break;
1909  }
1910  else if (!cfig.homes[i].alias[0])
1911  {
1912  strcpy(cfig.homes[i].alias, name);
1913  strcpy(cfig.homes[i].target, value);
1914 
1915  if (cfig.homes[i].target[strlen(cfig.homes[i].target) - 1] != fileSep)
1916  {
1917  tempbuff[0] = fileSep;
1918  tempbuff[1] = 0;
1919  strcat(cfig.homes[i].target, tempbuff);
1920  }
1921 
1922  break;
1923  }
1924  }
1925  }
1926  else
1927  {
1928  sprintf(logBuff, "Section [HOME], alias %s too large", name);
1929  logMess(logBuff, 1);
1930  }
1931  }
1932  else if (!cfig.homes[0].alias[0] && !cfig.homes[0].target[0])
1933  {
1934  strcpy(cfig.homes[0].target, name);
1935 
1936  if (cfig.homes[0].target[strlen(cfig.homes[0].target) - 1] != fileSep)
1937  {
1938  tempbuff[0] = fileSep;
1939  tempbuff[1] = 0;
1940  strcat(cfig.homes[0].target, tempbuff);
1941  }
1942  }
1943  else if (cfig.homes[0].alias[0])
1944  {
1945  sprintf(logBuff, "Section [HOME], alias and bare path mixup, entry %s ignored", raw);
1946  logMess(logBuff, 1);
1947  }
1948  else if (cfig.homes[0].target[0])
1949  {
1950  sprintf(logBuff, "Section [HOME], Duplicate Path: %s ignored", raw);
1951  logMess(logBuff, 1);
1952  }
1953  else
1954  {
1955  sprintf(logBuff, "Section [HOME], missing = sign, Invalid Entry: %s ignored", raw);
1956  logMess(logBuff, 1);
1957  }
1958  }
1959  }
1960 
1961  if (!cfig.homes[0].target[0])
1962  {
1964  char *iniFileExt = strrchr(cfig.homes[0].target, fileSep);
1965  *(++iniFileExt) = 0;
1966  }
1967 
1968  cfig.fileRead = true;
1969 
1970  if ((f = openSection("TFTP-OPTIONS", 1, iniFile)))
1971  {
1972  while (readSection(raw, f))
1973  {
1974  mySplit(name, value, raw, '=');
1975 
1976  if (strlen(value))
1977  {
1978  if (!strcasecmp(name, "blksize"))
1979  {
1980  MYDWORD tblksize = atol(value);
1981 
1982  if (tblksize < 512)
1983  blksize = 512;
1984  else if (tblksize > USHRT_MAX - 32)
1985  blksize = USHRT_MAX - 32;
1986  else
1987  blksize = tblksize;
1988  }
1989  else if (!strcasecmp(name, "threadpoolsize"))
1990  {
1991  minThreads = atol(value);
1992  if (minThreads < 1)
1993  minThreads = 0;
1994  else if (minThreads > 100)
1995  minThreads = 100;
1996  }
1997  else if (!strcasecmp(name, "timeout"))
1998  {
1999  timeout = atol(value);
2000  if (timeout < 1)
2001  timeout = 1;
2002  else if (timeout > UCHAR_MAX)
2003  timeout = UCHAR_MAX;
2004  }
2005  else if (!strcasecmp(name, "Read"))
2006  {
2007  if (strchr("Yy", *value))
2008  cfig.fileRead = true;
2009  else
2010  cfig.fileRead = false;
2011  }
2012  else if (!strcasecmp(name, "Write"))
2013  {
2014  if (strchr("Yy", *value))
2015  cfig.fileWrite = true;
2016  else
2017  cfig.fileWrite = false;
2018  }
2019  else if (!strcasecmp(name, "Overwrite"))
2020  {
2021  if (strchr("Yy", *value))
2022  cfig.fileOverwrite = true;
2023  else
2024  cfig.fileOverwrite = false;
2025  }
2026  else if (!strcasecmp(name, "port-range"))
2027  {
2028  char *ptr = strchr(value, '-');
2029  if (ptr)
2030  {
2031  *ptr = 0;
2032  cfig.minport = atol(value);
2033  cfig.maxport = atol(++ptr);
2034 
2035  if (cfig.minport < 1024 || cfig.minport >= USHRT_MAX || cfig.maxport < 1024 || cfig.maxport >= USHRT_MAX || cfig.minport > cfig.maxport)
2036  {
2037  cfig.minport = 0;
2038  cfig.maxport = 0;
2039 
2040  sprintf(logBuff, "Invalid port range %s", value);
2041  logMess(logBuff, 1);
2042  }
2043  }
2044  else
2045  {
2046  sprintf(logBuff, "Invalid port range %s", value);
2047  logMess(logBuff, 1);
2048  }
2049  }
2050  else
2051  {
2052  sprintf(logBuff, "Warning: unknown option %s, ignored", name);
2053  logMess(logBuff, 1);
2054  }
2055  }
2056  }
2057  }
2058 
2059  if ((f = openSection("ALLOWED-CLIENTS", 1, iniFile)))
2060  {
2061 #ifdef __REACTOS__
2062  MYWORD i = 0;
2063 #else
2064  int i = 0;
2065 #endif
2066 
2067  while (readSection(raw, f))
2068  {
2069 #ifdef __REACTOS__
2070  if (i < _countof(cfig.hostRanges))
2071 #else
2072  if (i < 32)
2073 #endif
2074  {
2075  MYDWORD rs = 0;
2076  MYDWORD re = 0;
2077  mySplit(name, value, raw, '-');
2078  rs = htonl(my_inet_addr(name));
2079 
2080  if (strlen(value))
2081  re = htonl(my_inet_addr(value));
2082  else
2083  re = rs;
2084 
2085  if (rs && rs != INADDR_NONE && re && re != INADDR_NONE && rs <= re)
2086  {
2087  cfig.hostRanges[i].rangeStart = rs;
2088  cfig.hostRanges[i].rangeEnd = re;
2089  i++;
2090  }
2091  else
2092  {
2093  sprintf(logBuff, "Section [ALLOWED-CLIENTS] Invalid entry %s in ini file, ignored", raw);
2094  logMess(logBuff, 1);
2095  }
2096  }
2097  }
2098  }
2099 
2100  if (verbatim)
2101  {
2102  printf("starting TFTP...\n");
2103  }
2104  else
2105  {
2106  sprintf(logBuff, "starting TFTP service");
2107  logMess(logBuff, 1);
2108  }
2109 
2110  for (int i = 0; i < MAX_SERVERS; i++)
2111  if (cfig.homes[i].target[0])
2112  {
2113  sprintf(logBuff, "alias /%s is mapped to %s", cfig.homes[i].alias, cfig.homes[i].target);
2114  logMess(logBuff, 1);
2115  }
2116 
2117  if (cfig.hostRanges[0].rangeStart)
2118  {
2119  char temp[128];
2120 
2121 #ifdef __REACTOS__
2122  for (MYWORD i = 0; i < _countof(cfig.hostRanges) && cfig.hostRanges[i].rangeStart; i++)
2123 #else
2124  for (MYWORD i = 0; i <= sizeof(cfig.hostRanges) && cfig.hostRanges[i].rangeStart; i++)
2125 #endif
2126  {
2127  sprintf(logBuff, "%s", "permitted clients: ");
2128  sprintf(temp, "%s-", IP2String(tempbuff, htonl(cfig.hostRanges[i].rangeStart)));
2129  strcat(logBuff, temp);
2130  sprintf(temp, "%s", IP2String(tempbuff, htonl(cfig.hostRanges[i].rangeEnd)));
2131  strcat(logBuff, temp);
2132  logMess(logBuff, 1);
2133  }
2134  }
2135  else
2136  {
2137  sprintf(logBuff, "%s", "permitted clients: all");
2138  logMess(logBuff, 1);
2139  }
2140 
2141  if (cfig.minport)
2142  {
2143  sprintf(logBuff, "server port range: %u-%u", cfig.minport, cfig.maxport);
2144  logMess(logBuff, 1);
2145  }
2146  else
2147  {
2148  sprintf(logBuff, "server port range: all");
2149  logMess(logBuff, 1);
2150  }
2151 
2152  sprintf(logBuff, "max blksize: %u", blksize);
2153  logMess(logBuff, 1);
2154  sprintf(logBuff, "default blksize: %u", 512);
2155  logMess(logBuff, 1);
2156  sprintf(logBuff, "default timeout: %u", timeout);
2157  logMess(logBuff, 1);
2158  sprintf(logBuff, "file read allowed: %s", cfig.fileRead ? "Yes" : "No");
2159  logMess(logBuff, 1);
2160  sprintf(logBuff, "file create allowed: %s", cfig.fileWrite ? "Yes" : "No");
2161  logMess(logBuff, 1);
2162  sprintf(logBuff, "file overwrite allowed: %s", cfig.fileOverwrite ? "Yes" : "No");
2163  logMess(logBuff, 1);
2164 
2165  if (!verbatim)
2166  {
2167  sprintf(logBuff, "logging: %s", cfig.logLevel > 1 ? "all" : "errors");
2168  logMess(logBuff, 1);
2169  }
2170 
2171  lEvent = CreateEvent(
2172  NULL, // default security descriptor
2173  FALSE, // ManualReset
2174  TRUE, // Signalled
2175  TEXT("AchalTFTServerLogEvent")); // object name
2176 
2177  if (lEvent == NULL)
2178  {
2179  printf("CreateEvent error: %lu\n", GetLastError());
2180  exit(-1);
2181  }
2182  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2183  {
2184  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2185  logMess(logBuff, 0);
2186  exit(-1);
2187  }
2188 
2189  tEvent = CreateEvent(
2190  NULL, // default security descriptor
2191  FALSE, // ManualReset
2192  FALSE, // Signalled
2193  TEXT("AchalTFTServerThreadEvent")); // object name
2194 
2195  if (tEvent == NULL)
2196  {
2197  printf("CreateEvent error: %lu\n", GetLastError());
2198  exit(-1);
2199  }
2200  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2201  {
2202  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2203  logMess(logBuff, 0);
2204  exit(-1);
2205  }
2206 
2207  sEvent = CreateEvent(
2208  NULL, // default security descriptor
2209  FALSE, // ManualReset
2210  TRUE, // Signalled
2211  TEXT("AchalTFTServerSocketEvent")); // object name
2212 
2213  if (sEvent == NULL)
2214  {
2215  printf("CreateEvent error: %lu\n", GetLastError());
2216  exit(-1);
2217  }
2218  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2219  {
2220  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2221  logMess(logBuff, 0);
2222  exit(-1);
2223  }
2224 
2225  cEvent = CreateEvent(
2226  NULL, // default security descriptor
2227  FALSE, // ManualReset
2228  TRUE, // Signalled
2229  TEXT("AchalTFTServerCountEvent")); // object name
2230 
2231  if (cEvent == NULL)
2232  {
2233  printf("CreateEvent error: %lu\n", GetLastError());
2234  exit(-1);
2235  }
2236  else if ( GetLastError() == ERROR_ALREADY_EXISTS )
2237  {
2238  sprintf(logBuff, "CreateEvent opened an existing Event\nServer May already be Running");
2239  logMess(logBuff, 0);
2240  exit(-1);
2241  }
2242 
2243  if (minThreads)
2244  {
2245  for (int i = 0; i < minThreads; i++)
2246  {
2247  _beginthread(
2248  processRequest, // thread function
2249  0, // default security attributes
2250  NULL); // argument to thread function
2251  }
2252 
2253  sprintf(logBuff, "thread pool size: %u", minThreads);
2254  logMess(logBuff, 1);
2255  }
2256 
2257  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].port; i++)
2258  {
2259  sprintf(logBuff, "listening on: %s:%i", IP2String(tempbuff, network.tftpConn[i].server), network.tftpConn[i].port);
2260  logMess(logBuff, 1);
2261  }
2262 
2263  do
2264  {
2265  memset(&newNetwork, 0, sizeof(data1));
2266 
2267  bool bindfailed = false;
2268 
2269  if ((f = openSection("LISTEN-ON", 1, iniFile)))
2270  {
2271  MYBYTE i = 0;
2272 
2273  while (readSection(raw, f))
2274  {
2275  MYWORD port = 69;
2276 
2277  cfig.ifspecified = true;
2278  mySplit(name, value, raw, ':');
2279 
2280  if (value[0])
2281  port = atoi(value);
2282 
2283  if(i < MAX_SERVERS)
2284  {
2285  if (isIP(name))
2286  {
2287  MYDWORD addr = my_inet_addr(name);
2288 
2289  if (!addr)
2290  {
2291  newNetwork.listenServers[0] = 0;
2292  newNetwork.listenPorts[0] = port;
2293  fclose(f);
2294  break;
2295  }
2296  else if (!findServer(newNetwork.listenServers, addr))
2297  {
2298  newNetwork.listenServers[i] = addr;
2299  newNetwork.listenPorts[i] = port;
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);
2316  getInterfaces(&newNetwork);
2317 
2318  for (MYBYTE n = 0; n < MAX_SERVERS && newNetwork.staticServers[n]; n++)
2319  {
2320  newNetwork.listenServers[n] = newNetwork.staticServers[n];
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  {
2333  if (network.tftpConn[k].ready && network.tftpConn[k].server == newNetwork.listenServers[j] && network.tftpConn[k].port == newNetwork.listenPorts[j])
2334  break;
2335  }
2336 
2337  if (network.tftpConn[k].ready && network.tftpConn[k].server == newNetwork.listenServers[j] && network.tftpConn[k].port == newNetwork.listenPorts[j])
2338  {
2339  memcpy(&(newNetwork.tftpConn[i]), &(network.tftpConn[k]), sizeof(tftpConnType));
2340 
2341  if (newNetwork.maxFD < newNetwork.tftpConn[i].sock)
2342  newNetwork.maxFD = newNetwork.tftpConn[i].sock;
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  {
2351  newNetwork.tftpConn[i].sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
2352 
2353  if (newNetwork.tftpConn[i].sock == INVALID_SOCKET)
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;
2364  newNetwork.tftpConn[i].addr.sin_family = AF_INET;
2365  newNetwork.tftpConn[i].addr.sin_addr.s_addr = newNetwork.listenServers[j];
2366  newNetwork.tftpConn[i].addr.sin_port = htons(newNetwork.listenPorts[j]);
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;
2372  closesocket(newNetwork.tftpConn[i].sock);
2373  sprintf(logBuff, "%s Port %i bind failed", IP2String(tempbuff, newNetwork.listenServers[j]), newNetwork.listenPorts[j]);
2374  logMess(logBuff, 1);
2375  continue;
2376  }
2377 
2378  newNetwork.tftpConn[i].loaded = true;
2379  newNetwork.tftpConn[i].ready = true;
2380  newNetwork.tftpConn[i].server = newNetwork.listenServers[j];
2381  newNetwork.tftpConn[i].port = newNetwork.listenPorts[j];
2382 
2383  //printf("%d, %s created\n", i, IP2String(tempbuff, newNetwork.tftpConn[i].server));
2384 
2385  if (newNetwork.maxFD < newNetwork.tftpConn[i].sock)
2386  newNetwork.maxFD = newNetwork.tftpConn[i].sock;
2387 
2388  if (!newNetwork.listenServers[j])
2389  break;
2390 
2391  i++;
2392  }
2393  }
2394 
2395  if (bindfailed)
2396  cfig.failureCount++;
2397  else
2398  cfig.failureCount = 0;
2399 
2400  closeConn();
2401  memcpy(&network, &newNetwork, sizeof(data1));
2402 
2403  //printf("%i %i %i\n", network.tftpConn[0].ready, network.dnsUdpConn[0].ready, network.dnsTcpConn[0].ready);
2404 
2405  if (!network.tftpConn[0].ready)
2406  {
2407  sprintf(logBuff, "No Static Interface ready, Waiting...");
2408  logMess(logBuff, 1);
2409  continue;
2410  }
2411 
2412  for (int i = 0; i < MAX_SERVERS && network.tftpConn[i].loaded; i++)
2413  {
2414  sprintf(logBuff, "Listening On: %s:%d", IP2String(tempbuff, network.tftpConn[i].server), network.tftpConn[i].port);
2415  logMess(logBuff, 1);
2416  }
2417 
2418  network.ready = true;
2419 
2420  } while (detectChange());
2421 
2422  //printf("Exiting Init\n");
2423 
2424  _endthread();
2425  return;
2426 }
2427 
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 }
2482 
2483 /*
2484 void getInterfaces(data1 *network)
2485 {
2486  memset(network, 0, sizeof(data1));
2487 
2488  SOCKET sd = WSASocket(PF_INET, SOCK_DGRAM, 0, 0, 0, 0);
2489 
2490  if (sd == INVALID_SOCKET)
2491  return;
2492 
2493  INTERFACE_INFO InterfaceList[MAX_SERVERS];
2494  unsigned long nBytesReturned;
2495 
2496  if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
2497  sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR)
2498  return ;
2499 
2500  int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
2501 
2502  for (int i = 0; i < nNumInterfaces; ++i)
2503  {
2504  sockaddr_in *pAddress = (sockaddr_in*)&(InterfaceList[i].iiAddress);
2505  u_long nFlags = InterfaceList[i].iiFlags;
2506 
2507  if (!(nFlags & IFF_POINTTOPOINT))
2508  {
2509  //printf("%s\n", IP2String(tempbuff, pAddress->sin_addr.S_un.S_addr));
2510  addServer(network->staticServers, pAddress->sin_addr.s_addr);
2511  }
2512  }
2513 
2514  closesocket(sd);
2515 }
2516 */
2517 
2518 
2519 void getInterfaces(data1 *network)
2520 {
2521  memset(network, 0, sizeof(data1));
2522 
2523  SOCKET sd = WSASocket(PF_INET, SOCK_DGRAM, 0, 0, 0, 0);
2524 
2525  if (sd == INVALID_SOCKET)
2526  return;
2527 
2529  unsigned long nBytesReturned;
2530 
2531  if (WSAIoctl(sd, SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList,
2532  sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR)
2533  return ;
2534 
2535  int nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO);
2536 
2537  for (int i = 0; i < nNumInterfaces; ++i)
2538  {
2539  sockaddr_in *pAddress = (sockaddr_in*)&(InterfaceList[i].iiAddress);
2540  u_long nFlags = InterfaceList[i].iiFlags;
2541 
2542  if (pAddress->sin_addr.s_addr)
2543  {
2544  addServer(network->allServers, pAddress->sin_addr.s_addr);
2545 
2546  if (!(nFlags & IFF_POINTTOPOINT) && (nFlags & IFF_UP))
2547  {
2548  addServer(network->staticServers, pAddress->sin_addr.s_addr);
2549  }
2550  }
2551  }
2552 
2553  closesocket(sd);
2554 }
2555 
2556 
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 }
2571 
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 }
2584 
2585 void logMess(char *logBuff, MYBYTE logLevel)
2586 {
2587  WaitForSingleObject(lEvent, INFINITE);
2588 
2589  if (verbatim)
2590  printf("%s\n", logBuff);
2591  else if (cfig.logfile && logLevel <= cfig.logLevel)
2592  {
2593  time_t t = time(NULL);
2594  tm *ttm = localtime(&t);
2595 
2596  if (ttm->tm_yday != loggingDay)
2597  {
2598  loggingDay = ttm->tm_yday;
2599  strftime(extbuff, sizeof(extbuff), logFile, ttm);
2600  fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
2601  fclose(cfig.logfile);
2602  cfig.logfile = fopen(extbuff, "at");
2603 
2604  if (cfig.logfile)
2605  {
2606  fprintf(cfig.logfile, "%s\n\n", sVersion);
2607  WritePrivateProfileString("InternetShortcut","URL", extbuff, lnkFile);
2608  WritePrivateProfileString("InternetShortcut","IconIndex", "0", lnkFile);
2609  WritePrivateProfileString("InternetShortcut","IconFile", extbuff, lnkFile);
2610  }
2611  else
2612  return;
2613  }
2614 
2615  strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
2616  fprintf(cfig.logfile, "[%s] %s\n", extbuff, logBuff);
2617  fflush(cfig.logfile);
2618  }
2619  SetEvent(lEvent);
2620 }
2621 
2622 void logMess(request *req, MYBYTE logLevel)
2623 {
2624  WaitForSingleObject(lEvent, INFINITE);
2625 
2626  char tempbuff[256];
2627 
2628  if (verbatim)
2629  {
2630  if (!req->serverError.errormessage[0])
2632 
2633  if (req->path[0])
2634  printf("Client %s:%u %s, %s\n", IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage);
2635  else
2636  printf("Client %s:%u, %s\n", IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->serverError.errormessage);
2637  }
2638  else if (cfig.logfile && logLevel <= cfig.logLevel)
2639  {
2640  time_t t = time(NULL);
2641  tm *ttm = localtime(&t);
2642 
2643  if (ttm->tm_yday != loggingDay)
2644  {
2645  loggingDay = ttm->tm_yday;
2646  strftime(extbuff, sizeof(extbuff), logFile, ttm);
2647  fprintf(cfig.logfile, "Logging Continued on file %s\n", extbuff);
2648  fclose(cfig.logfile);
2649  cfig.logfile = fopen(extbuff, "at");
2650 
2651  if (cfig.logfile)
2652  {
2653  fprintf(cfig.logfile, "%s\n\n", sVersion);
2654  WritePrivateProfileString("InternetShortcut","URL", extbuff, lnkFile);
2655  WritePrivateProfileString("InternetShortcut","IconIndex", "0", lnkFile);
2656  WritePrivateProfileString("InternetShortcut","IconFile", extbuff, lnkFile);
2657  }
2658  else
2659  return;
2660  }
2661 
2662  strftime(extbuff, sizeof(extbuff), "%d-%b-%y %X", ttm);
2663 
2664  if (req->path[0])
2665  fprintf(cfig.logfile, "[%s] Client %s:%u %s, %s\n", extbuff, IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->path, req->serverError.errormessage);
2666  else
2667  fprintf(cfig.logfile, "[%s] Client %s:%u, %s\n", extbuff, IP2String(tempbuff, req->client.sin_addr.s_addr), ntohs(req->client.sin_port), req->serverError.errormessage);
2668 
2669  fflush(cfig.logfile);
2670  }
2671  SetEvent(lEvent);
2672 }
#define CreateEvent
Definition: winbase.h:3562
#define StartService
Definition: winsvc.h:585
Definition: winsock.h:66
char * filename
Definition: tftpd.h:96
int maxport
Definition: tftpd.h:151
#define SOCKET_ERROR
Definition: winsock.h:333
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
char * myGetToken(char *buff, MYBYTE index)
Definition: tftpd.cpp:1628
data2 cfig
Definition: tftpd.cpp:51
static int argc
Definition: ServiceArgs.c:12
MYBYTE attempt
Definition: tftpd.h:93
#define SERVICE_ERROR_IGNORE
Definition: cmtypes.h:979
return
Definition: dirsup.c:529
MYWORD listenPorts[MAX_SERVERS]
Definition: tftpd.h:131
#define VER_PLATFORM_WIN32_NT
Definition: rtltypes.h:236
Definition: tftpd.h:59
GLenum GLclampf GLint GLenum GLuint GLenum GLenum GLsizei GLenum const GLvoid GLfloat GLfloat GLfloat GLfloat GLclampd GLint GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean GLboolean GLboolean GLboolean GLint GLenum GLsizei const GLvoid GLenum GLint GLenum GLint GLint GLsizei GLint GLenum GLint GLint GLint GLint GLsizei GLenum GLsizei const GLuint GLboolean GLenum GLenum GLint GLsizei GLenum GLsizei GLenum const GLvoid GLboolean const GLboolean GLenum const GLdouble const GLfloat const GLdouble const GLfloat GLenum GLint GLint GLint GLint GLint GLint j
Definition: glfuncs.h:98
Definition: get.c:139
#define TRUE
Definition: types.h:120
struct _INTERFACE_INFO INTERFACE_INFO
MYWORD tblock
Definition: tftpd.h:122
#define CloseHandle
Definition: compat.h:398
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:736
bool ifspecified
Definition: tftpd.h:154
time_t expiry
Definition: tftpd.h:89
#define lstrcmpi
Definition: winbase.h:3687
_CRTIMP void __cdecl _endthread(void)
Definition: thread.c:95
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
char buffer[514]
Definition: tftpd.h:62
MYWORD timeout
Definition: tftpd.h:120
char * readSection(char *buff, FILE *f)
Definition: tftpd.cpp:1611
unsigned long u_long
Definition: linux.h:269
char notFileSep
Definition: tftpd.cpp:44
DWORD dwCurrentState
Definition: winsvc.h:100
#define SC_MANAGER_CONNECT
Definition: winsvc.h:14
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
#define strcasecmp
Definition: fake.h:9
OSVERSIONINFO osvi
Definition: ver.c:28
FILE * logfile
Definition: tftpd.h:145
SERVICE_STATUS_HANDLE serviceStatusHandle
Definition: tftpd.cpp:64
#define htonl(x)
Definition: module.h:212
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define MAKEWORD(a, b)
Definition: typedefs.h:247
char sVersion[]
Definition: tftpd.cpp:36
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
char fileSep
Definition: tftpd.cpp:43
#define IFF_UP
Definition: ws2ipdef.h:21
bool loaded
Definition: tftpd.h:49
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
WORD wVersion
Definition: winsock.h:517
#define LANG_NEUTRAL
Definition: nls.h:22
#define _countof(array)
Definition: fontsub.cpp:30
#define free
Definition: debug_ros.c:5
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:168
#define INADDR_NONE
Definition: tcp.c:42
unsigned long tv_sec
Definition: linux.h:1738
#define SUBLANG_DEFAULT
Definition: nls.h:168
HANDLE cEvent
Definition: tftpd.cpp:54
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
MYDWORD staticServers[MAX_SERVERS]
Definition: tftpd.h:129
char logBuff[512]
Definition: tftpd.cpp:42
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
MYWORD block
Definition: tftpd.h:121
#define MYWORD
Definition: tftpd.h:22
GLdouble GLdouble t
Definition: gl.h:2047
void WINAPI ServiceMain(DWORD, TCHAR *[])
Definition: tftpd.cpp:98
bool busy
Definition: tftpd.h:134
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
MYWORD opcode
Definition: tftpd.h:74
Definition: tftpd.h:125
GLuint buffer
Definition: glext.h:5915
#define SERVICE_START_PENDING
Definition: winsvc.h:22
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
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
Definition: dhcpd.h:245
int errno
_Check_return_ _CRTIMP _CONST_RETURN char *__cdecl strrchr(_In_z_ const char *_Str, _In_ int _Ch)
__u16 time
Definition: mkdosfs.c:366
#define SERVICE_ALL_ACCESS
Definition: winsvc.h:62
char displayName[]
Definition: tftpd.cpp:35
Definition: parser.c:55
BOOL WINAPI DeleteService(SC_HANDLE hService)
Definition: scm.c:915
#define FD_ZERO(set)
Definition: winsock.h:96
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
int bytesRecd
Definition: tftpd.h:102
#define CreateService
Definition: winsvc.h:569
#define FD_SET(fd, set)
Definition: winsock.h:89
#define NO_ERROR
Definition: dderror.h:5
char tempbuff[256]
Definition: tftpd.cpp:40
MYBYTE sockInd
Definition: tftpd.h:92
void runProg()
Definition: tftpd.cpp:393
MYWORD timeout
Definition: tftpd.cpp:47
const char * strerror(int err)
Definition: compat_str.c:23
INT WSAAPI connect(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: sockctrl.c:23
#define OpenService
Definition: winsvc.h:576
int main(int argc, TCHAR *argv[])
Definition: tftpd.cpp:346
#define ntohs(x)
Definition: module.h:208
MYWORD errorcode
Definition: tftpd.h:68
static char ** argv
Definition: ServiceArgs.c:11
CHAR * LPTSTR
Definition: xmlstorage.h:192
char alias[64]
Definition: tftpd.h:39
MYDWORD tsize
Definition: tftpd.h:99
void printWindowsError()
Definition: tftpd.cpp:323
bool addServer(MYDWORD *array, MYDWORD ip)
Definition: tftpd.cpp:2557
#define USHRT_MAX
Definition: limits.h:38
#define _IOFBF
Definition: stdio.h:128
char * myUpper(char *string)
Definition: tftpd.cpp:1785
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:957
#define sprintf(buf, format,...)
Definition: sprintf.c:55
char * myLower(char *string)
Definition: tftpd.cpp:1795
GLuint n
Definition: s_context.h:57
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
socklen_t clientsize
Definition: tftpd.h:106
bool detectChange()
Definition: tftpd.cpp:2428
GLenum GLclampf GLint i
Definition: glfuncs.h:14
SOCKET maxFD
Definition: tftpd.h:132
DWORD dwCheckPoint
Definition: winsvc.h:104
#define SERVICE_STOPPED
Definition: winsvc.h:21
#define RegisterServiceCtrlHandler
Definition: winsvc.h:583
bool getSection(const char *sectionName, char *buffer, MYBYTE serial, char *fileName)
Definition: tftpd.cpp:1533
_Check_return_opt_ _CRTIMP size_t __cdecl fread(_Out_writes_bytes_(_ElementSize *_Count) void *_DstBuf, _In_ size_t _ElementSize, _In_ size_t _Count, _Inout_ FILE *_File)
#define closesocket
Definition: main.c:39
#define FD_ISSET(fd, set)
Definition: winsock.h:100
float pow(float __x, int __y)
Definition: _cmath.h:458
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
INT WSAAPI select(IN INT s, IN OUT LPFD_SET readfds, IN OUT LPFD_SET writefds, IN OUT LPFD_SET exceptfds, IN CONST struct timeval *timeout)
Definition: select.c:41
#define _MAX_PATH
Definition: utility.h:77
#define StartServiceCtrlDispatcher
Definition: winsvc.h:586
#define SERVICE_RUNNING
Definition: winsvc.h:24
MYWORD block
Definition: tftpd.h:75
message mesout
Definition: tftpd.h:110
static PVOID ptr
Definition: dispmode.c:27
int ip[4]
Definition: rtl.c:1176
#define FORMAT_MESSAGE_ALLOCATE_BUFFER
Definition: winbase.h:400
SOCKET sock
Definition: tftpd.h:90
HANDLE hEvent
Definition: winbase.h:792
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
char path[256]
Definition: tftpd.h:94
BOOL WINAPI CloseServiceHandle(SC_HANDLE hSCObject)
Definition: scm.c:576
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
MYWORD blksize
Definition: tftpd.h:119
smooth NULL
Definition: ftsmooth.c:416
unsigned long tv_usec
Definition: linux.h:1739
acknowledgement acout
Definition: tftpd.h:111
_Check_return_opt_ _CRTIMP int __cdecl fseek(_Inout_ FILE *_File, _In_ long _Offset, _In_ int _Origin)
MYDWORD rangeStart
Definition: tftpd.h:81
void uninstallService()
Definition: tftpd.cpp:296
void WINAPI ServiceControlHandler(DWORD controlCode)
Definition: tftpd.cpp:67
#define WSA_IO_PENDING
Definition: winsock2.h:589
unsigned ip
Definition: tftpd.h:162
MYWORD opcode
Definition: tftpd.h:55
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39
fd_set readfds
Definition: tftpd.h:88
bool ready
Definition: tftpd.h:133
#define SERVICE_QUERY_STATUS
Definition: winsvc.h:55
char logFile[_MAX_PATH]
Definition: tftpd.cpp:38
GLuint index
Definition: glext.h:6031
#define SC_MANAGER_CREATE_SERVICE
Definition: winsvc.h:15
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:960
tftperror clientError
Definition: tftpd.h:115
#define PF_INET
Definition: winsock.h:373
data1 network
Definition: tftpd.cpp:49
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:404
ULONG dwOSVersionInfoSize
Definition: rtltypes.h:233
bool ready
Definition: tftpd.h:50
MYDWORD rangeEnd
Definition: tftpd.h:82
timeval tv
Definition: tftpd.h:87
#define inet_ntoa(addr)
Definition: inet.h:100
GLuint GLfloat * val
Definition: glext.h:7180
char target[256]
Definition: tftpd.h:40
char * mode
Definition: tftpd.h:97
char errormessage[512]
Definition: tftpd.h:69
size_t CDECL strftime(char *str, size_t max, const char *format, const struct tm *mstm)
Definition: strftime.c:293
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
void processRequest(void *lpParam)
Definition: tftpd.cpp:488
Definition: dhcpd.h:135
char serviceName[]
Definition: tftpd.cpp:34
#define SEEK_SET
Definition: jmemansi.c:26
char TCHAR
Definition: xmlstorage.h:189
#define OpenSCManager
Definition: winsvc.h:575
GLfloat f
Definition: glext.h:7540
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
void init(void *lpParam)
Definition: tftpd.cpp:1805
INT WSAAPI WSAGetLastError(VOID)
Definition: dllmain.c:112
#define WAIT_OBJECT_0
Definition: winbase.h:387
#define MYBYTE
Definition: tftpd.h:21
#define INVALID_SOCKET
Definition: winsock.h:332
Definition: dhcpd.h:61
char iniFile[_MAX_PATH]
Definition: tftpd.cpp:37
char lnkFile[_MAX_PATH]
Definition: tftpd.cpp:39
data12 hostRanges[32]
Definition: tftpd.h:146
DWORD dwWaitHint
Definition: winsvc.h:105
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
#define WSASocket
Definition: winsock2.h:2407
bool cleanReq(request *req)
Definition: tftpd.cpp:1505
home homes[8]
Definition: tftpd.h:143
void getInterfaces(data1 *network)
Definition: tftpd.cpp:2519
DWORD dwWin32ExitCode
Definition: winsvc.h:102
SOCKET knock
Definition: tftpd.h:91
HANDLE stopServiceEvent
Definition: tftpd.cpp:65
unsigned long DWORD
Definition: ntddk_ex.h:95
WSADATA wsaData
Definition: tftpd.h:139
char fileWrite
Definition: tftpd.h:148
BOOL WINAPI QueryServiceStatus(SC_HANDLE hService, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:2787
DWORD dwServiceType
Definition: winsvc.h:99
#define GetModuleFileName
Definition: winbase.h:3645
REFIID LPVOID DWORD dw
Definition: atlbase.h:40
sockaddr_in client
Definition: tftpd.h:105
MYDWORD server
Definition: tftpd.h:47
SERVICE_STATUS serviceStatus
Definition: tftpd.cpp:63
MYDWORD listenServers[MAX_SERVERS]
Definition: tftpd.h:130
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
#define IFF_POINTTOPOINT
Definition: ws2ipdef.h:24
#define WAIT_TIMEOUT
Definition: dderror.h:14
void installService()
Definition: tftpd.cpp:256
#define FormatMessage
Definition: winbase.h:3609
static const WCHAR sd[]
Definition: suminfo.c:287
#define SERVICE_CONTROL_PAUSE
Definition: winsvc.h:37
int ret
SOCKET sock
Definition: tftpd.h:45
GLenum const GLvoid * addr
Definition: glext.h:9621
MYDWORD allServers[MAX_SERVERS]
Definition: tftpd.h:128
MYWORD loggingDay
Definition: tftpd.cpp:48
HANDLE lEvent
Definition: tftpd.cpp:56
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
GLenum GLsizei len
Definition: glext.h:6722
MYDWORD failureCount
Definition: tftpd.h:152
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
static stack_node_t temp
Definition: rpn.c:18
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
Definition: time.h:76
_CRTIMP struct tm *__cdecl localtime(const time_t *_Time)
Definition: time.h:426
HANDLE tEvent
Definition: tftpd.cpp:53
#define WINAPI
Definition: msvc.h:20
MYDWORD * findServer(MYDWORD *array, MYDWORD ip)
Definition: tftpd.cpp:2572
#define my_inet_addr
Definition: tftpd.h:33
char string[160]
Definition: util.h:11
DWORD WINAPI NotifyAddrChange(PHANDLE Handle, LPOVERLAPPED overlapped)
struct in_addr sin_addr
Definition: winsock.h:512
char fileOverwrite
Definition: tftpd.h:149
int bytesRead[2]
Definition: tftpd.h:103
char verbatim
Definition: tftpd.cpp:46
int tm_yday
Definition: time.h:84
DWORD dwControlsAccepted
Definition: winsvc.h:101
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:401
MYBYTE logLevel
Definition: tftpd.h:153
void mySplit(char *name, char *value, char *source, char splitChar)
Definition: tftpd.cpp:1730
MYWORD blksize
Definition: tftpd.cpp:45
_Check_return_opt_ _CRTIMP char *__cdecl fgets(_Out_writes_z_(_MaxCount) char *_Buf, _In_ int _MaxCount, _Inout_ FILE *_File)
#define UINT_MAX
Definition: limits.h:41
_Check_return_ _CRTIMP int __cdecl getchar(void)
Definition: file.c:3627
sockaddr_in addr
Definition: tftpd.h:46
#define TEXT(s)
Definition: k32.h:26
MYWORD block
Definition: tftpd.h:56
uint32_t serial
Definition: fsck.fat.h:64
FILE * openSection(const char *sectionName, MYBYTE serial, char *fileName)
Definition: tftpd.cpp:1581
MYWORD opcode
Definition: tftpd.h:61
WSAEVENT WSAAPI WSACreateEvent(VOID)
Definition: event.c:42
tftperror serverError
Definition: tftpd.h:109
MYBYTE currentServer
Definition: tftpd.cpp:57
_Check_return_opt_ _CRTIMP int __cdecl fflush(_Inout_opt_ FILE *_File)
__kernel_time_t time_t
Definition: linux.h:252
#define MAX_SERVERS
Definition: tftpd.h:34
#define SERVICE_STOP
Definition: winsvc.h:58
GLsizei GLsizei GLchar * source
Definition: glext.h:6048
ULONG dwPlatformId
Definition: rtltypes.h:237
#define f
Definition: ke_i.h:83
#define SERVICE_CONTROL_CONTINUE
Definition: winsvc.h:38
#define UCHAR_MAX
Definition: limits.h:25
#define SERVICE_WIN32
Definition: cmtypes.h:962
Definition: services.c:325
MYWORD port
Definition: tftpd.h:48
MYWORD myTokenize(char *target, char *source, char *sep, bool whiteSep)
Definition: tftpd.cpp:1643
#define GetVersionEx
Definition: winbase.h:3666
HANDLE sEvent
Definition: tftpd.cpp:55
BOOL WINAPI ControlService(SC_HANDLE hService, DWORD dwControl, LPSERVICE_STATUS lpServiceStatus)
Definition: scm.c:618
packet * pkt[2]
Definition: tftpd.h:104
MYWORD totalThreads
Definition: tftpd.cpp:58
MYWORD minThreads
Definition: tftpd.cpp:59
INT WSAAPI sendto(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags, IN CONST struct sockaddr *to, IN INT tolen)
Definition: send.c:82
MYWORD opcode
Definition: tftpd.h:67
Definition: tftpd.h:85
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define SERVICE_AUTO_START
Definition: cmtypes.h:975
_CRTIMP uintptr_t __cdecl _beginthread(_In_ void(__cdecl *_StartAddress)(void *), _In_ unsigned _StackSize, _In_opt_ void *_ArgList)
MYWORD activeThreads
Definition: tftpd.cpp:60
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
char extbuff[_MAX_PATH]
Definition: tftpd.cpp:41
Definition: name.c:36
#define calloc
Definition: rosglue.h:14
acknowledgement acin
Definition: tftpd.h:117
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
FILE * file
Definition: tftpd.h:95
_Check_return_ _CRTIMP long __cdecl ftell(_Inout_ FILE *_File)
GLenum target
Definition: glext.h:7315
#define AF_INET
Definition: tcpip.h:117
#define MAKELANGID(p, s)
Definition: nls.h:15
#define SEEK_END
Definition: cabinet.c:27
Definition: tftpd.h:157
_Check_return_opt_ _CRTIMP int __cdecl setvbuf(_Inout_ FILE *_File, _Inout_updates_opt_z_(_Size) char *_Buf, _In_ int _Mode, _In_ size_t _Size)
char fileRead
Definition: tftpd.h:147
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
UINT_PTR SOCKET
Definition: winsock.h:47
data1 newNetwork
Definition: tftpd.cpp:50
MYDWORD fblock
Definition: tftpd.h:100
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
char buffer
Definition: tftpd.h:76
void exit(int exitcode)
Definition: _exit.c:33
char * IP2String(char *target, MYDWORD ip)
Definition: tftpd.cpp:1759
#define htons(x)
Definition: module.h:213
#define INFINITE
Definition: serial.h:102
#define SOCK_DGRAM
Definition: winsock.h:336
#define SIO_GET_INTERFACE_LIST
Definition: ws2ipdef.h:62
MYBYTE octate[4]
Definition: tftpd.h:163
tftpConnType tftpConn[MAX_SERVERS]
Definition: tftpd.h:127
USHORT port
Definition: uri.c:227
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
char * myTrim(char *target, char *source)
Definition: tftpd.cpp:1689
#define MYDWORD
Definition: tftpd.h:23
int minport
Definition: tftpd.h:150
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
int k
Definition: mpi.c:3369
static unsigned char buff[32768]
Definition: fatten.c:17
bool stopService(SC_HANDLE service)
Definition: tftpd.cpp:225
bool isIP(char *string)
Definition: tftpd.cpp:1767
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
short sin_family
Definition: winsock.h:510
#define DELETE
Definition: nt_native.h:57
void logMess(char *logBuff, MYBYTE logLevel)
Definition: tftpd.cpp:2585
void runService()
Definition: tftpd.cpp:214
message mesin
Definition: tftpd.h:116
#define printf
Definition: config.h:203
int bytesReady
Definition: tftpd.h:101
void closeConn()
Definition: tftpd.cpp:481
Definition: tftpd.h:137
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40
#define WritePrivateProfileString
Definition: winbase.h:3737
#define ntohl(x)
Definition: module.h:203