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"; 37 char iniFile[_MAX_PATH]; 38 char logFile[_MAX_PATH]; 39 char lnkFile[_MAX_PATH]; 40 char tempbuff[256]; 41 char extbuff[_MAX_PATH]; 42 char logBuff[512]; 43 char fileSep = '\\'; 44 char notFileSep = '/'; 45 MYWORD blksize = 65464; 46 char verbatim = 0; 47 MYWORD timeout = 3; 48 MYWORD loggingDay; 49 data1 network; 50 data1 newNetwork; 51 data2 cfig; 52 //ThreadPool Variables 53 HANDLE tEvent; 54 HANDLE cEvent; 55 HANDLE sEvent; 56 HANDLE lEvent; 57 MYBYTE currentServer = UCHAR_MAX; 58 MYWORD totalThreads=0; 59 MYWORD minThreads=1; 60 MYWORD activeThreads=0; 61 62 //Service Variables 63 SERVICE_STATUS serviceStatus; 64 SERVICE_STATUS_HANDLE serviceStatusHandle = 0; 65 HANDLE stopServiceEvent = 0; 66 67 void WINAPI ServiceControlHandler(DWORD controlCode) 68 { 69 switch (controlCode) 70 { 71 case SERVICE_CONTROL_INTERROGATE: 72 break; 73 74 case SERVICE_CONTROL_SHUTDOWN: 75 case SERVICE_CONTROL_STOP: 76 serviceStatus.dwCurrentState = SERVICE_STOP_PENDING; 77 SetServiceStatus(serviceStatusHandle, &serviceStatus); 78 79 SetEvent(stopServiceEvent); 80 return ; 81 82 case SERVICE_CONTROL_PAUSE: 83 break; 84 85 case SERVICE_CONTROL_CONTINUE: 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 108 serviceStatusHandle = RegisterServiceCtrlHandler(serviceName, ServiceControlHandler); 109 110 if (serviceStatusHandle) 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 135 serviceStatus.dwControlsAccepted |= (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); 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 168 if (!totalThreads || activeThreads >= totalThreads) 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 206 serviceStatus.dwControlsAccepted &= ~(SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); 207 serviceStatus.dwCurrentState = SERVICE_STOPPED; 208 SetServiceStatus(serviceStatusHandle, &serviceStatus); 209 CloseHandle(stopServiceEvent); 210 stopServiceEvent = 0; 211 } 212 } 213 214 void runService() 215 { 216 SERVICE_TABLE_ENTRY serviceTable[] = 217 { 218 {serviceName, ServiceMain}, 219 {0, 0} 220 }; 221 222 StartServiceCtrlDispatcher(serviceTable); 223 } 224 225 bool stopService(SC_HANDLE service) 226 { 227 if (service) 228 { 229 SERVICE_STATUS serviceStatus; 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 256 void installService() 257 { 258 SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CREATE_SERVICE); 259 260 if (serviceControlManager) 261 { 262 SC_HANDLE service = OpenService(serviceControlManager, 263 serviceName, SERVICE_QUERY_STATUS); 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, 276 serviceName, displayName, 277 SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 278 SERVICE_AUTO_START, SERVICE_ERROR_IGNORE, path, 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 293 printWindowsError(); 294 } 295 296 void uninstallService() 297 { 298 SC_HANDLE serviceControlManager = OpenSCManager(0, 0, SC_MANAGER_CONNECT); 299 300 if (serviceControlManager) 301 { 302 SC_HANDLE service = OpenService(serviceControlManager, 303 serviceName, SERVICE_QUERY_STATUS | SERVICE_STOP | DELETE); 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 320 printWindowsError(); 321 } 322 323 void printWindowsError() 324 { 325 MYDWORD dw = GetLastError(); 326 327 if (dw) 328 { 329 LPVOID lpMsgBuf; 330 331 FormatMessage( 332 FORMAT_MESSAGE_ALLOCATE_BUFFER | 333 FORMAT_MESSAGE_FROM_SYSTEM | 334 FORMAT_MESSAGE_IGNORE_INSERTS, 335 NULL, 336 dw, 337 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 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 { 348 OSVERSIONINFO osvi; 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) 357 uninstallService(); 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, 366 serviceName, SERVICE_QUERY_STATUS | SERVICE_STOP); 367 if (service) 368 { 369 serviceStopped = stopService(service); 370 CloseServiceHandle(service); 371 } 372 CloseServiceHandle(serviceControlManager); 373 } 374 else 375 printWindowsError(); 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 456 if (!totalThreads || activeThreads >= totalThreads) 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 507 if (currentServer >= MAX_SERVERS || !network.tftpConn[currentServer].port) 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; 519 currentServer = UCHAR_MAX; 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); 531 errno = WSAGetLastError(); 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 599 req.sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 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); 1239 sprintf(req.serverError.errormessage, strerror(errno)); 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); 1279 sprintf(req.serverError.errormessage, strerror(errno)); 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 1628 char* myGetToken(char* buff, MYBYTE index) 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 1759 char *IP2String(char *target, MYDWORD ip) 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 1809 GetModuleFileName(NULL, extbuff, _MAX_PATH); 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 { 1963 GetModuleFileName(NULL, cfig.homes[0].target, UCHAR_MAX); 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 2428 bool detectChange() 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 { 2454 if (WSAGetLastError() != WSA_IO_PENDING) 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 2528 INTERFACE_INFO InterfaceList[MAX_SERVERS]; 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 2557 bool addServer(MYDWORD *array, MYDWORD ip) 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 2572 MYDWORD *findServer(MYDWORD *array, MYDWORD ip) 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]) 2631 sprintf(req->serverError.errormessage, strerror(errno)); 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 } 2673