/** * 绑定iptux程序的服务监听端口. */ void bind_iptux_port() { struct sockaddr_in addr; int tcpsock, udpsock; tcpsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); socket_enable_reuse(tcpsock); udpsock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); socket_enable_reuse(udpsock); socket_enable_broadcast(udpsock); if ((tcpsock == -1) || (udpsock == -1)) { pop_error(_("Fatal Error!!\nFailed to create new socket!\n%s"), strerror(errno)); exit(1); } bzero(&addr, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(IPTUX_DEFAULT_PORT); addr.sin_addr.s_addr = htonl(INADDR_ANY); if (bind(tcpsock, (struct sockaddr *)&addr, sizeof(addr)) == -1 || bind(udpsock, (struct sockaddr *)&addr, sizeof(addr)) == -1) { close(tcpsock); close(udpsock); pop_error(_("Fatal Error!!\nFailed to bind the TCP/UDP port(2425)!\n%s"), strerror(errno)); exit(1); } cthrd.TcpSockQuote() = tcpsock; cthrd.UdpSockQuote() = udpsock; }
/** * 好友请求本计算机的共享文件. */ void UdpData::SomeoneAskShared() { Command cmd; pthread_t pid; PalInfo *pal; const char *limit; char *passwd; if (!(pal = cthrd.GetPalFromList(ipv4))) return; limit = cthrd.GetAccessPublicLimit(); if (!limit || *limit == '\0') { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedFile), pal); pthread_detach(pid); } else if (!(iptux_get_dec_number(buf, ':', 4) & IPTUX_PASSWDOPT)) { cmd.SendFileInfo(cthrd.UdpSockQuote(), pal, IPTUX_SHAREDOPT | IPTUX_PASSWDOPT, ""); } else if ( (passwd = ipmsg_get_attach(buf, ':', 5))) { if (strcmp(passwd, limit) == 0) { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedFile), pal); pthread_detach(pid); } g_free(passwd); } }
/** * 好友上线. */ void UdpData::SomeoneEntry() { Command cmd; pthread_t pid; PalInfo *pal; /* 转换缓冲区数据编码 */ ConvertEncode(progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); /* 通知好友本大爷在线 */ cmd.SendAnsentry(cthrd.UdpSockQuote(), pal); if (FLAG_ISSET(pal->flags, 0)) { pthread_create(&pid, NULL, ThreadFunc(CoreThread::SendFeatureData), pal); pthread_detach(pid); } }
/** * 请求获取此好友的共享文件. * @param grpinf 好友群组信息 */ void DialogPeer::AskSharedFiles(GroupInfo *grpinf) { Command cmd; PalInfo *pal; if (!(grpinf->member)) pal = cthrd.GetPalFromList(grpinf->grpid); else pal = (PalInfo *)grpinf->member->data; cmd.SendAskShared(cthrd.UdpSockQuote(), pal, 0, NULL); }
/** * 请求获取好友共享文件的密码. * @param pal class PalInfo */ void UdpData::ThreadAskSharedPasswd(PalInfo *pal) { Command cmd; gchar *passwd, *epasswd; gdk_threads_enter(); passwd = pop_obtain_shared_passwd(pal); gdk_threads_leave(); if (passwd && *passwd != '\0') { epasswd = g_base64_encode((guchar *)passwd, strlen(passwd)); cmd.SendAskShared(cthrd.UdpSockQuote(), pal, IPTUX_PASSWDOPT, epasswd); g_free(epasswd); } g_free(passwd); }
/** * 广播文件信息. * @param plist 好友链表 * @param opttype 命令字选项 * @param filist 文件信息链表 */ void SendFile::BcstFileInfo(GSList *plist, uint32_t opttype, GSList *filist) { AnalogFS afs; Command cmd; char buf[MAX_UDPLEN]; size_t len; char *ptr, *name; GSList *tlist,*pallist,*filelist; FileInfo *file; /* 初始化 */ len = 0; ptr = buf; buf[0] = '\0'; pallist = plist; /* 将文件信息写入缓冲区 */ while (pallist) { filelist = filist; while (filelist) { file = (FileInfo *)filelist->data; if(file->fileown == (PalInfo *)pallist->data) { if (access(file->filepath, F_OK) == -1) { filelist = g_slist_next(filelist); continue; } file->waitFlag = 1; name = ipmsg_get_filename_pal(file->filepath); //获取面向好友的文件名 file->filesize = afs.ftwsize(file->filepath); //不得不计算文件长度了 file->packetn = cmd.Packetn(); snprintf(ptr, MAX_UDPLEN - len, "%" PRIu32 ":%s:%" PRIx64 ":%" PRIx32 ":%" PRIx32 ":\a:", file->fileid, name, file->filesize, file->filectime, file->fileattr); g_free(name); len += strlen(ptr); ptr = buf + len; } filelist = g_slist_next(filelist); } cmd.SendFileInfo(cthrd.UdpSockQuote(), (PalInfo *)pallist->data, opttype, buf); pallist = g_slist_next(pallist); } g_slist_free(filelist); }
/** * 发送文件信息. * @param pal class PalInfo * @param opttype 命令字选项 * @param filist 文件信息链表 */ void SendFile::SendFileInfo(PalInfo *pal, uint32_t opttype, GSList *filist) { AnalogFS afs; Command cmd; char buf[MAX_UDPLEN]; size_t len; char *ptr, *name; GSList *tlist; FileInfo *file; /* 初始化 */ len = 0; ptr = buf; buf[0] = '\0'; /* 将文件信息写入缓冲区 */ tlist = filist; while (tlist) { file = (FileInfo *)tlist->data; if (access(file->filepath, F_OK) == -1) { tlist = g_slist_next(tlist); continue; } name = ipmsg_get_filename_pal(file->filepath); //获取面向好友的文件名 file->packetn = cmd.Packetn(); snprintf(ptr, MAX_UDPLEN - len, "%" PRIu32 ":%s:%" PRIx64 ":%" PRIx32 ":%" PRIx32 ":\a", file->fileid, name, file->filesize, file->filectime, file->fileattr); g_free(name); len += strlen(ptr); ptr = buf + len; tlist = g_slist_next(tlist); } /* 发送文件信息 */ cmd.SendFileInfo(cthrd.UdpSockQuote(), pal, opttype, buf); }
/** * 好友在线. */ void UdpData::SomeoneAnsentry() { Command cmd; pthread_t pid; PalInfo *pal; const char *ptr; /* 若好友不兼容iptux协议,则需转码 */ ptr = iptux_skip_string(buf, size, 3); if (!ptr || *ptr == '\0') ConvertEncode(progdt.encode); /* 加入或更新好友列表 */ gdk_threads_enter(); pthread_mutex_lock(cthrd.GetMutex()); if ( (pal = cthrd.GetPalFromList(ipv4))) { UpdatePalInfo(pal); cthrd.UpdatePalToList(ipv4); } else { pal = CreatePalInfo(); cthrd.AttachPalToList(pal); } pthread_mutex_unlock(cthrd.GetMutex()); if (mwin.PaltreeContainItem(ipv4)) mwin.UpdateItemToPaltree(ipv4); else mwin.AttachItemToPaltree(ipv4); gdk_threads_leave(); /* 更新本大爷的数据信息 */ if (FLAG_ISSET(pal->flags, 0)) { pthread_create(&pid, NULL, ThreadFunc(CoreThread::SendFeatureData), pal); pthread_detach(pid); } else if (strcasecmp(progdt.encode, pal->encode) != 0) cmd.SendAnsentry(cthrd.UdpSockQuote(), pal); }
/** * 发送文本消息. * @param para 消息参数 */ void DialogPeer::ThreadSendTextMsg(MsgPara *para) { Command cmd; GSList *tlist; char *ptr; int sock; tlist = para->dtlist; while (tlist) { ptr = ((ChipData *)tlist->data)->data; switch (((ChipData *)tlist->data)->type) { case MESSAGE_CONTENT_TYPE_STRING: /* 文本类型 */ cmd.SendMessage(cthrd.UdpSockQuote(), para->pal, ptr); break; case MESSAGE_CONTENT_TYPE_PICTURE: /* 图片类型 */ if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) { pop_error(_("Fatal Error!!\nFailed to create new socket!" "\n%s"), strerror(errno)); exit(1); } cmd.SendSublayer(sock, para->pal, IPTUX_MSGPICOPT, ptr); close(sock); //关闭网络套接口 /*/* 删除此图片 */ unlink(ptr); //此文件已无用处 break; default: break; } tlist = g_slist_next(tlist); } /* 释放资源 */ delete para; }
/** * 好友发送消息. * */ void UdpData::SomeoneSendmsg() { GroupInfo *grpinf; PalInfo *pal; Command cmd; uint32_t commandno, packetno; char *text; pthread_t pid; DialogPeer *dlgpr; GtkWidget *window; /* 如果对方兼容iptux协议,则无须再转换编码 */ pal = cthrd.GetPalFromList(ipv4); if (!pal || !FLAG_ISSET(pal->flags, 0)) ConvertEncode(pal ? pal->encode : progdt.encode); /* 确保好友在线,并对编码作出适当调整 */ pal = AssertPalOnline(); if (strcasecmp(pal->encode, encode ? encode : "utf-8") != 0) { g_free(pal->encode); pal->encode = g_strdup(encode ? encode : "utf-8"); } /* 回复好友并检查此消息是否过时 */ commandno = iptux_get_dec_number(buf, ':', 4); packetno = iptux_get_dec_number(buf, ':', 1); if (commandno & IPMSG_SENDCHECKOPT) cmd.SendReply(cthrd.UdpSockQuote(), pal, packetno); if (packetno <= pal->packetn) return; pal->packetn = packetno; /* 插入消息&在消息队列中注册 */ text = ipmsg_get_attach(buf, ':', 5); if (text && *text != '\0') { /*/* 插入消息 */ // if ((commandno & IPMSG_BROADCASTOPT) || (commandno & IPMSG_MULTICASTOPT)) // InsertMessage(pal, GROUP_BELONG_TYPE_BROADCAST, text); // else InsertMessage(pal, GROUP_BELONG_TYPE_REGULAR, text); } g_free(text); /*/* 注册消息 */ pthread_mutex_lock(cthrd.GetMutex()); // if ((commandno & IPMSG_BROADCASTOPT) || (commandno & IPMSG_MULTICASTOPT)) // grpinf = cthrd.GetPalBroadcastItem(pal); // else grpinf = cthrd.GetPalRegularItem(pal); if (!grpinf->dialog && !cthrd.MsglineContainItem(grpinf)) cthrd.PushItemToMsgline(grpinf); pthread_mutex_unlock(cthrd.GetMutex()); /* 标记位处理 先处理底层数据,后面显示窗口*/ if (commandno & IPMSG_FILEATTACHOPT) { if ((commandno & IPTUX_SHAREDOPT) && (commandno & IPTUX_PASSWDOPT)) { pthread_create(&pid, NULL, ThreadFunc(ThreadAskSharedPasswd), pal); pthread_detach(pid); } else RecvPalFile(); } window = GTK_WIDGET(grpinf->dialog); //这里不知道为什么运行时一直会提示window不是object dlgpr = (DialogPeer *)(g_object_get_data(G_OBJECT(window),"dialog")); if(grpinf->dialog) dlgpr->ShowDialogPeer(dlgpr); /* 是否直接弹出聊天窗口 */ if (FLAG_ISSET(progdt.flags, 7)) { gdk_threads_enter(); if (!(grpinf->dialog)) { // switch (grpinf->type) { // case GROUP_BELONG_TYPE_REGULAR: DialogPeer::PeerDialogEntry(grpinf); // break; // case GROUP_BELONG_TYPE_SEGMENT: // case GROUP_BELONG_TYPE_GROUP: // case GROUP_BELONG_TYPE_BROADCAST: // DialogGroup::GroupDialogEntry(grpinf); // default: // break; // } } else { gtk_window_present(GTK_WINDOW(grpinf->dialog)); } gdk_threads_leave(); } /* 播放提示音 */ if (FLAG_ISSET(progdt.sndfgs, 1)) sndsys.Playing(progdt.msgtip); }