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