static void TlenPsPostThread(void *ptr) { TLENPSREQUESTTHREADDATA *data = (TLENPSREQUESTTHREADDATA *)ptr; TlenProtocol *proto = data->proto; TLEN_LIST_ITEM *item = data->item; HANDLE socket = TlenWsConnect(proto, "ps.tlen.pl", 443); BOOL bSent = FALSE; if (socket != NULL) { char header[512]; DWORD ret; item->ft->s = socket; item->ft->hFileEvent = CreateEvent(NULL, FALSE, FALSE, NULL); mir_snprintf(header, sizeof(header), "<pic auth='%s' t='p' to='%s' size='%d' idt='%s'/>", proto->threadData->username, item->ft->jid, item->ft->fileTotalSize, item->jid); TlenWsSend(proto, socket, header, (int)strlen(header)); ret = WaitForSingleObject(item->ft->hFileEvent, 1000 * 60 * 5); if (ret == WAIT_OBJECT_0) { FILE *fp = fopen( item->ft->files[0], "rb" ); if (fp) { int i; char header[512]; char fileBuffer[2048]; mir_snprintf(header, sizeof(header), "<pic st='%s' idt='%s'/>", item->ft->iqId, item->jid); TlenWsSend(proto, socket, header, (int)strlen(header)); proto->debugLogA("Sending picture data..."); for (i = item->ft->filesSize[0]; i > 0; ) { int toread = min(2048, i); int readcount = (int)fread(fileBuffer, (size_t)1, (size_t)toread, fp); i -= readcount; if (readcount > 0) { TlenWsSend(proto, socket, fileBuffer, readcount); } if (toread != readcount) { break; } } fclose(fp); SleepEx(3000, TRUE); bSent = TRUE; } else { /* picture not found */ } } else { /* 5 minutes passed */ } Netlib_CloseHandle(socket); if (bSent) { TlenSend(proto, "<message to='%s' idt='%s' rt='%s' pid='1001' type='pic' />", item->ft->jid, item->jid, item->ft->id2); LogPictureMessage(proto, item->ft->jid, item->ft->files[0], TRUE); } TlenP2PFreeFileTransfer(item->ft); TlenListRemove(proto, LIST_PICTURE, item->jid); } else { /* cannot connect to ps server */ } mir_free(data); }
static void TlenPsGetThread(void *ptr) { TLENPSREQUESTTHREADDATA *data = (TLENPSREQUESTTHREADDATA *)ptr; TlenProtocol *proto = data->proto; TLEN_LIST_ITEM *item = data->item; FILE *fp; fp = fopen( item->ft->files[0], "wb" ); if (fp) { HANDLE socket = TlenWsConnect(proto, "ps.tlen.pl", 443); if (socket != NULL) { XmlState xmlState; char header[512]; char fileBuffer[2048]; TlenXmlInitState(&xmlState); mir_snprintf(header, sizeof(header), "<pic auth='%s' t='g' to='%s' pid='1001' idt='%s' rt='%s'/>", proto->threadData->username, item->ft->jid, item->jid, item->ft->id2); TlenWsSend(proto, socket, header, (int)strlen(header)); proto->debugLogA("Reveiving picture data..."); { int totalcount = 0; int size = item->ft->filesSize[0]; BOOL bHeader = TRUE; while (TRUE) { int readcount = TlenWsRecv(proto, socket, fileBuffer, 2048 - totalcount); if (readcount == 0) { break; } totalcount += readcount; if (bHeader) { char * tagend = (char*)memchr(fileBuffer, '/', totalcount); tagend = (char*)memchr(tagend + 1, '>', totalcount - (tagend - fileBuffer) - 1); if (tagend != NULL) { int parsed = TlenXmlParse(&xmlState, fileBuffer, tagend - fileBuffer + 1); if (parsed == 0) { continue; } bHeader = FALSE; totalcount -= parsed; memmove(fileBuffer, fileBuffer+parsed, totalcount); } } if (!bHeader) { if (totalcount > 0) { fwrite(fileBuffer, 1, totalcount, fp); size -= totalcount; totalcount = 0; } if (size == 0) { break; } } } } Netlib_CloseHandle(socket); proto->debugLogA("Picture received..."); LogPictureMessage(proto, item->ft->jid, item->ft->files[0], FALSE); } else { /* cannot connect to ps server */ } fclose(fp); } else { /* cannot create file */ } TlenP2PFreeFileTransfer(item->ft); TlenListRemove(proto, LIST_PICTURE, item->jid); mir_free(data); }
void TlenProcessPic(XmlNode *node, TlenProtocol *proto) { TLEN_LIST_ITEM *item = NULL; char *crc, *crc_c, *idt, *size, *from, *fromRaw, *rt; from = TlenXmlGetAttrValue(node, "from"); fromRaw = TlenLoginFromJID(from); idt = TlenXmlGetAttrValue(node, "idt"); size = TlenXmlGetAttrValue(node, "size"); crc_c = TlenXmlGetAttrValue(node, "crc_c"); crc = TlenXmlGetAttrValue(node, "crc"); rt = TlenXmlGetAttrValue(node, "rt"); if (idt != NULL) { item = TlenListGetItemPtr(proto, LIST_PICTURE, idt); } if (item != NULL) { if (!strcmp(from, "ps")) { char *st = TlenXmlGetAttrValue(node, "st"); if (st != NULL) { item->ft->iqId = mir_strdup(st); item->ft->id2 = mir_strdup(rt); if (item->ft->hFileEvent != NULL) { SetEvent(item->ft->hFileEvent); item->ft->hFileEvent = NULL; } } } else if (!strcmp(item->ft->jid, fromRaw)) { if (crc_c != NULL) { if (!strcmp(crc_c, "n")) { /* crc_c = n, picture transfer accepted */ TlenPsPost(proto, item); } else if (!strcmp(crc_c, "f")) { /* crc_c = f, picture cached, no need to transfer again */ LogPictureMessage(proto, item->ft->jid, item->ft->files[0], TRUE); TlenP2PFreeFileTransfer(item->ft); TlenListRemove(proto, LIST_PICTURE, idt); } } else if (rt != NULL) { item->ft->id2 = mir_strdup(rt); TlenPsGet(proto, item); } } } else if (crc != NULL) { BOOL bAccept = proto->tlenOptions.imagePolicy == TLEN_IMAGES_ACCEPT_ALL || (proto->tlenOptions.imagePolicy == TLEN_IMAGES_IGNORE_NIR && IsAuthorized(proto, from)); if (bAccept) { FILE* fp; char fileName[MAX_PATH]; char *ext = TlenXmlGetAttrValue(node, "ext"); char *tmpPath = Utils_ReplaceVars( "%miranda_userdata%" ); int tPathLen = mir_snprintf(fileName, MAX_PATH, "%s\\Images\\Tlen", tmpPath); long oldSize = 0, lSize = atol(size); DWORD dwAttributes = GetFileAttributesA( fileName ); if ( dwAttributes == 0xffffffff || ( dwAttributes & FILE_ATTRIBUTE_DIRECTORY ) == 0 ) CreateDirectoryTree(fileName); mir_free(tmpPath); fileName[ tPathLen++ ] = '\\'; mir_snprintf( fileName + tPathLen, MAX_PATH - tPathLen, "%s.%s", crc, ext ); fp = fopen( fileName, "rb" ); if (fp) { fseek(fp, 0, SEEK_END); oldSize = ftell(fp); fclose(fp); } if (oldSize != lSize) { item = TlenListAdd(proto, LIST_PICTURE, idt); item->ft = TlenFileCreateFT(proto, from); item->ft->files = (char **) mir_alloc(sizeof(char *)); item->ft->filesSize = (long *) mir_alloc(sizeof(long)); item->ft->files[0] = mir_strdup(fileName); item->ft->filesSize[0] = lSize; item->ft->fileTotalSize = item->ft->filesSize[0]; TlenSend(proto, "<message type='pic' to='%s' crc_c='n' idt='%s'/>", from, idt); } else { TlenSend(proto, "<message type='pic' to='%s' crc_c='f' idt='%s'/>", from, idt); LogPictureMessage(proto, from, fileName, FALSE); } } } mir_free(fromRaw); }
void __cdecl TlenNewFileReceiveThread(TLEN_FILE_TRANSFER *ft) { ft->proto->debugLogA("P2P receive thread started"); ProtoBroadcastAck(ft->proto->m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_CONNECTING, ft, 0); // ft->mode = FT_RECV; // ft->currentFile = 0; // ft->state = FT_CONNECTING; { FILE * fout = fopen("tlen_recv.dxx", "wt"); SOCKADDR_IN toad; toad.sin_family = AF_INET; toad.sin_addr.s_addr = inet_addr(ft->hostName); toad.sin_port = htons(ft->wPort); if (fout != NULL) { fprintf(fout, "START:\n"); } if (fout != NULL) { fclose(fout); } while (ft->udps != INVALID_SOCKET) { SOCKADDR_IN cad; int alen; int j, n; unsigned char buff[1024]; alen = sizeof(struct sockaddr); n=recvfrom(ft->udps, (char*)buff,sizeof(buff),0, (struct sockaddr *) &cad, &alen); if (n<0) { break; } logInfo("tlen_recv.dxx", "UDP"); fout = fopen("tlen_recv.dxx", "at"); if (fout != NULL) { fprintf(fout, "\n|RECV %d bytes from %s:%d|",n, inet_ntoa(cad.sin_addr), cad.sin_port); for (j = 0; j < n; j++) { fprintf(fout, "%02X-", buff[j]); } } if (n == 1) { alen = sizeof(struct sockaddr); n = sendto(ft->udps, (char*)buff, n, 0,(struct sockaddr *) &toad, alen); if (fout != NULL) { fprintf(fout, "\n|SEND |"); for (j = 0; j < n; j++) { fprintf(fout, "%02X-", buff[j]); } } } if (fout != NULL) { fprintf(fout, "\n"); fclose(fout); } } } if (ft->udps != INVALID_SOCKET) { closesocket(ft->udps); } TlenListRemove(ft->proto, LIST_FILE, ft->iqId); if (ft->state == FT_DONE) ProtoBroadcastAck(ft->proto->m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_SUCCESS, ft, 0); else { ProtoBroadcastAck(ft->proto->m_szModuleName, ft->hContact, ACKTYPE_FILE, ACKRESULT_FAILED, ft, 0); } ft->proto->debugLogA("P2P receive thread ended"); TlenP2PFreeFileTransfer(ft); }