📄 tftpserver.cpp
字号:
errno = 0; if (!strcasecmp(req->mode, "netascii") || !strcasecmp(req->mode, "ascii")) req->file = fopen(req->path, "wt"); else req->file = fopen(req->path, "wb"); if (errno || !req->file) { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(2); strcpy(req->serverError.errormessage, "Invalid Path or No Access"); //strcpy(req->serverError.errormessage, strerror(errno)); logMess(req, 1); req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0); clean(req); pthread_exit(NULL); } } if (*temp) { fetchAck = true; char *pointer = req->acout.buffer; req->acout.opcode = htons(6); DWORD val; while (*temp) { //printf("%s", temp); if (!strcasecmp(temp, "blksize")) { strcpy(pointer, temp); pointer += strlen(pointer) + 1; temp += strlen(temp) + 1; val = atol(temp); if (val < 512) val = 512; else if (val > blksize) val = blksize; req->blksize = val; sprintf(pointer, "%u", req->blksize); pointer += strlen(pointer) + 1; temp += strlen(temp) + 1; } else if (!strcasecmp(temp, "tsize")) { strcpy(pointer, temp); pointer += strlen(pointer) + 1; temp += strlen(temp) + 1; fseek(req->file, 0, SEEK_END); req->tsize = ftell(req->file); sprintf(pointer, "%u", req->tsize); pointer += strlen(pointer) + 1; temp += strlen(temp) + 1; } else if (!strcasecmp(temp, "interval")) { strcpy(pointer, temp); pointer += strlen(pointer) + 1; temp += strlen(temp) + 1; val = atoi(temp); if (val < 1) val = 1; else if (val > 120) val = 120; req->interval = val - (val/2); sprintf(pointer, "%u", val); pointer += strlen(pointer) + 1; temp += strlen(temp) + 1; } else temp += strlen(temp) + 1; //printf("=%u\n",val); } errno = 0; req->bytesSent = send(req->m_socket, (const char*) & req->acout, (DWORD)pointer - (DWORD) & req->acout, 0); } else if (htons(req->datain.opcode) == 2) { req->acout.opcode = htons(4); req->acout.block = htons(0); errno = 0; req->bytesSent = send(req->m_socket, (const char*) & req->acout, 4, 0); } if (errno ) { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(0); sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } else if (ntohs(req->datain.opcode) == 1) { req->pkt[0] = (packet*)malloc(req->blksize + 4); memset(req->pkt[0], 0, req->blksize + 4); req->pkt[1] = (packet*)malloc(req->blksize + 4); memset(req->pkt[1], 0, req->blksize + 4); if (ftell(req->file)) fseek(req->file, 0, SEEK_SET); errno = 0; req->pkt[0]->opcode = htons(3); req->pkt[0]->block = htons(1); req->bytesRead[0] = fread(&req->pkt[0]->buffer, 1, req->blksize, req->file); if (errno) { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(0); //sprintf(req->serverError.errormessage, "%s", strerror(errno)); logMess(req, 1); req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0); clean(req); pthread_exit(NULL); } if (req->bytesRead[0] == req->blksize) { req->pkt[1]->opcode = htons(3); req->pkt[1]->block = htons(2); req->bytesRead[1] = fread(&req->pkt[1]->buffer, 1, req->blksize, req->file); if (req->bytesRead[1] < req->blksize) { fclose(req->file); req->file = 0; } } else { fclose(req->file); req->file = 0; } while (true) { if (fetchAck) { FD_ZERO(&req->readfds); req->tv.tv_sec = req->interval; req->tv.tv_usec = 0; FD_SET(req->m_socket, &req->readfds); select(req->m_socket + 1, &req->readfds, NULL, NULL, &req->tv); if (FD_ISSET(req->m_socket, &req->readfds)) { errno = 0; memset(&req->serverError, 0, sizeof(tftperror)); req->bytesRecd = recv(req->m_socket, (char*) &req->datain, sizeof(ack), 0); if (errno) { sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } } else { req->bytesRecd = 0; } } else req->datain.block = htons(0); fetchAck = true; if (req->bytesRecd >= 4) { if (ntohs(req->datain.opcode) == 1 || ntohs(req->datain.opcode) == 4) { if (ntohs(req->datain.block) == req->block) { req->block++; req->fblock++; req->attempt = 0; } else continue; } else if (ntohs(req->datain.opcode) == 5) { 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); logMess(req, 1); clean(req); pthread_exit(NULL); } else { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(0); strcpy(req->serverError.errormessage, "Unexpected Option Code"); break; } } else if (req->attempt >= 3) { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(0); if (req->fblock && !req->block) strcpy(req->serverError.errormessage, "File too large for client"); else strcpy(req->serverError.errormessage, "Timeout"); break; } else req->attempt++; if (req->block) { if (ntohs(req->pkt[0]->block) == req->block) { errno = 0; req->bytesSent = send(req->m_socket, (const char*)req->pkt[0], req->bytesRead[0] + 4, 0); if (errno) { sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } if (req->file) { req->tblock = ntohs(req->pkt[1]->block) + 1; if (req->tblock == req->block) { req->pkt[1]->block = htons(++req->tblock); req->bytesRead[1] = fread(&req->pkt[1]->buffer, 1, req->blksize, req->file); if (req->bytesRead[1] < req->blksize) { fclose(req->file); req->file = 0; } } } } else if (ntohs(req->pkt[1]->block) == req->block) { errno = 0; req->bytesSent = send(req->m_socket, (const char*)req->pkt[1], req->bytesRead[1] + 4, 0); if (errno) { sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } if (req->file) { req->tblock = ntohs(req->pkt[0]->block) + 1; if (req->tblock == req->block) { req->pkt[0]->block = htons(++req->tblock); req->bytesRead[0] = fread(&req->pkt[0]->buffer, 1, req->blksize, req->file); if (req->bytesRead[0] < req->blksize) { fclose(req->file); req->file = 0; } } } } else { sprintf(logBuff, "Client %s:%u %s, %u Blocks Served", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->fblock - 1); logMess(2); req->attempt = 255; break; } } else { errno = 0; send(req->m_socket, (const char*)&req->acout, req->bytesSent, 0); if (errno) { sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } } } } else if (ntohs(req->datain.opcode) == 2) { req->pkt[0] = (packet*)malloc(req->blksize + 4); memset(req->pkt[0], 0, req->blksize + 4); while (true) { FD_ZERO(&req->readfds); req->tv.tv_sec = req->interval; req->tv.tv_usec = 0; FD_SET(req->m_socket, &req->readfds); select(req->m_socket + 1, &req->readfds, NULL, NULL, &req->tv); if (FD_ISSET(req->m_socket, &req->readfds)) { memset(&req->serverError, 0, sizeof(tftperror)); errno = 0; req->bytesRecd = recv(req->m_socket, (char*)req->pkt[0], req->blksize + 4, 0); if (errno) { sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } } else req->bytesRecd = 0; if (req->bytesRecd >= 4) { if (ntohs(req->pkt[0]->opcode) == 3) { req->tblock = req->block + 1; if (ntohs(req->pkt[0]->block) == req->tblock) { req->acout.opcode = htons(4); req->acout.block = req->pkt[0]->block; req->block++; req->fblock++; errno = 0; req->bytesSent = send(req->m_socket, (const char*)&req->acout, 4, 0); if (errno ) { sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } if (req->file && req->bytesRecd > 4) { errno = 0; fwrite(&req->pkt[0]->buffer, req->bytesRecd - 4, 1, req->file); if (errno) { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(3); strcpy(req->serverError.errormessage, "Disk full or allocation exceeded"); break; } else req->attempt = 0; } if (req->bytesRecd - 4 < req->blksize) { fclose(req->file); req->file = 0; sprintf(logBuff, "Client %s:%u %s, %u Blocks Received", inet_ntoa(req->client.sin_addr), ntohs(req->client.sin_port), req->path, req->fblock); logMess(2); break; } } else continue; } else if (ntohs(req->pkt[0]->opcode) == 5) { sprintf(logBuff, "Error Code %i at Client, %s", ntohs(req->clientError.errorcode), req->clientError.errormessage); logMess(1); clean(req); pthread_exit(NULL); } else { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(0); strcpy(req->serverError.errormessage, "Unexpected Option Code"); break; } } else if (req->attempt >= 3) { req->serverError.opcode = htons(5); req->serverError.errorcode = htons(0); if (req->fblock && !req->block) strcpy(req->serverError.errormessage, "File too large for client"); else strcpy(req->serverError.errormessage, "Timeout"); break; } else { errno = 0; send(req->m_socket, (const char*)&req->acout, req->bytesSent, 0); req->attempt++; if (errno ) { sprintf(req->serverError.errormessage, "Communication Error"); logMess(req, 1); clean(req); pthread_exit(NULL); } } } } if (errno || req->serverError.errormessage[0]) { logMess(req, 1); req->bytesSent = send(req->m_socket, (const char*) & req->serverError, strlen(req->serverError.errormessage) + 5, 0); } clean(req); return 0;}void init(){ memset(&cfig, 0, sizeof(cfig)); char iniStr[4096]; if (verbatim) cfig.logLevel = 2; else if (getSection("LOGGING", iniStr, sizeof(iniStr), iniFile)) { char *iniStrPtr = cleanstr(iniStr, false); if (!iniStrPtr[0] || !strcasecmp(iniStrPtr, "None")) cfig.logLevel = 0; else if (!strcasecmp(iniStrPtr, "Errors")) cfig.logLevel = 1; else if (!strcasecmp(iniStrPtr, "All")) cfig.logLevel = 2; else { sprintf(logBuff, "Section [LOGGING], Invalid Logging Level: %s ignored", iniStrPtr); logMess(0); } } if (getSection("LISTEN-ON", iniStr, sizeof(iniStr), iniFile)) { char *iniStrPtr = cleanstr(iniStr, false); for (int i = 0; i < MAX_SERVERS && iniStrPtr[0]; iniStrPtr = cleanstr(iniStrPtr, true)) { char name[256]; strncpy(name, iniStrPtr, 255); WORD port = 69; char *dp = strchr(name,':'); if (dp) { *dp = 0; dp++; port = atoi(dp); } DWORD ip = my_inet_addr(name); if (isIP(name) && ip) { for (BYTE j = 0; j < MAX_SERVERS; j++) { if (cfig.servers[j] == ip) break; else if (!cfig.servers[j]) { cfig.servers[j] = ip; cfig.ports[j] = port; i++; break; } } } else { sprintf(logBuff, "Warning: Section [LISTEN-ON], Invalid IP Address %s, ignored", iniStrPtr); logMess(1); } } } if (getSection("HOME", iniStr, sizeof(iniStr), iniFile)) { char *iniStrPtr = cleanstr(iniStr, false); for (; iniStrPtr[0]; iniStrPtr = cleanstr(iniStrPtr, true)) { char name[256];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -