yamiYori 8 роки тому
батько
коміт
097d15035e
25 змінених файлів з 2251 додано та 0 видалено
  1. 28 0
      Makefile
  2. 12 0
      XCUI/XCUI.config
  3. 6 0
      XCUI/XCUI.cpp
  4. 71 0
      XCUI/XCUI.h
  5. 14 0
      XCUI/XCUI_Base.h
  6. 36 0
      XCUI/XCUI_Base_linux.cpp
  7. 13 0
      chaos.cpp
  8. 26 0
      chaos.h
  9. 50 0
      definations.h
  10. 220 0
      fileManager.cpp
  11. 55 0
      fileManager.h
  12. 35 0
      fixedmath.cpp
  13. 8 0
      fixedmath.h
  14. 171 0
      include/ipmsg.h
  15. 646 0
      main.cpp
  16. 37 0
      msgManager.cpp
  17. 33 0
      msgManager.h
  18. 62 0
      packMaker.cpp
  19. 8 0
      packMaker.h
  20. 215 0
      tcpReceiver.cpp
  21. 6 0
      tcpReceiver.h
  22. 257 0
      udpReceiver.cpp
  23. 8 0
      udpReceiver.h
  24. 168 0
      usermanager.cpp
  25. 66 0
      usermanager.h

+ 28 - 0
Makefile

@@ -0,0 +1,28 @@
+obj = main.o chaos.o udpReceiver.o tcpReceiver.o fixedmath.o packMaker.o usermanager.o fileManager.o msgManager.o
+target = main
+INC = -I./include
+DFN =             
+CXXFLAGS = -std=gnu++11 -lpthread $(DFN)
+
+$(target):$(obj)
+	$(CXX) -o $@ $^ $(CXXFLAGS) $(INC)
+main.o:main.cpp udpReceiver.o chaos.o packMaker.o usermanager.o
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+udpReceiver.o:udpReceiver.cpp chaos.o fixedmath.o packMaker.o usermanager.o fixedmath.o fileManager.o msgManager.o
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+tcpReceiver.o:tcpReceiver.cpp chaos.o fixedmath.o packMaker.o usermanager.o fixedmath.o fileManager.o msgManager.o
+chaos.o:chaos.cpp chaos.h
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+fixedmath.o:fixedmath.cpp fixedmath.h
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+packMaker.o:packMaker.cpp packMaker.h usermanager.o chaos.o
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+usermanager.o:usermanager.cpp usermanager.h
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+fileManager.o:fileManager.cpp fileManager.h
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+msgManager.o:msgManager.cpp msgManager.h
+	$(CXX) -c $< $(CXXFLAGS) $(INC)
+
+clean:
+	rm $(obj) $(target)

+ 12 - 0
XCUI/XCUI.config

@@ -0,0 +1,12 @@
+#ifndef _XCUI_CONFIG
+#define _XCUI_CONFIG
+
+///////////*platform*///////////
+//linux:        XCUI_OS_LINUX
+//windows:      XCUI_OS_WINDOWS
+////////////////////////////////
+#define XCUI_OS_LINUX
+
+
+
+#endif

+ 6 - 0
XCUI/XCUI.cpp

@@ -0,0 +1,6 @@
+#include "XCUI.h"
+#include "XCUI_Base.h"
+
+
+
+

+ 71 - 0
XCUI/XCUI.h

@@ -0,0 +1,71 @@
+#ifndef _XCUI_H_
+#define _XCUI_H_
+#include<string>
+#include<vector>
+using namespace std;
+
+#pragma region CommonData
+struct rect{
+    int x;
+    int y;
+};
+typedef rect point;
+struct xcui_commondata_t{
+    bool flg_onshow;
+    rect window;
+}xcui_commondata;
+#pragma endregion
+
+#pragma region XcuiBase
+class WidgetBase{
+public:
+	string uniqueID;            //Must be unique in one layer
+    bool active;
+	bool enable;
+	bool visble;
+
+	point pos;
+
+	int _event OnLoad()={};
+	int _event OnShow()={};
+	int _event On
+
+    virtual int  DrawBuf()={};
+    virtual void* Widgetctl(WidgetBase& src,string& info)={};   //for widget interactive
+
+};
+
+
+class LayerBase{
+public:
+	string titleText;
+	vector<WidgetBase> options;		//option text
+	string uniqueID;			//Must be unique.
+	int numOfStatus;
+
+	int highLightedIndex;   //0 < this < numOfStatus
+
+	virtual void DrawMenu();					//菜单绘制,允许重载
+	virtual void StatusMove(int status) = 0;	//状态机跳转,必须提供重载
+	virtual void beginOutPut(){};				//绘制菜单选项前输出信息,允许重载
+	virtual void endOutPut(){};					//绘制菜单选项后输出信息,允许重载
+
+	LayerBase(string _titletext, vector<string>& _options, vector<string>& _infos){
+		titleText = titleText;
+		options = _options;
+		infos = _infos;
+		numOfStatus = options.size();
+		highLightedIndex = 0;
+	}
+	LayerBase(){;}
+
+};
+
+#pragma endregion
+
+
+void Refresh();
+void DrawLayer(LayerBase& layer);
+
+
+#endif

+ 14 - 0
XCUI/XCUI_Base.h

@@ -0,0 +1,14 @@
+#ifndef _XCUI_BASE_H_
+#define _XCUI_BASE_H_
+
+#include "XCUI.config"
+#define _plat               //as platform code
+#define _event virtual      //as object callback event
+
+int _plat GetWindowSize(int &wide,int &height);
+int _plat SetResizeHook();
+
+
+#endif
+
+//GenerateConsoleCtrlEvent

+ 36 - 0
XCUI/XCUI_Base_linux.cpp

@@ -0,0 +1,36 @@
+#include"XCUI_Base.h"
+#ifdef XCUI_OS_LINUX
+
+#include<sys/types.h>  
+#include<sys/ioctl.h>  
+#include<unistd.h>  
+#include<termios.h> 
+#include<stdlib.h>
+#include<signal.h>
+#include"XCUI.h"
+
+ int _plat GetWindowSize(int&wide,int&height){
+    struct winsize size;
+    ioctl(STDIN_FILENO,TIOCGWINSZ,&size);
+    wide=size.ws_col;
+    height=size.ws_row;
+    return 0;
+ }
+void _plat WindowSizeChangeHandler();
+int _plat SetResizeHook(){
+    signal(SIGWINCH,WindowSizeChangeHandler);
+}
+
+void _plat WindowSizeChangeHandler(){
+    if(xcui_commondata.flg_onshow){
+        int a,b;
+        GetWindowSize(a,b);
+        xcui_commondata.window.x=a;
+        xcui_commondata.window.y=b;
+        Refresh();
+    }
+}
+
+
+
+#endif

+ 13 - 0
chaos.cpp

@@ -0,0 +1,13 @@
+#include"chaos.h"
+
+Chaos* Chaos::instance = new Chaos();
+Chaos* Chaos::getInstance(){
+	static bool firflag=true;
+	if(firflag){
+		instance->packNum=1000000001;
+		firflag=false;
+	}
+	return instance;
+}
+
+

+ 26 - 0
chaos.h

@@ -0,0 +1,26 @@
+#ifndef __CHAOS_H_
+#define __CHAOS_H_
+#include<atomic>
+using std::atomic;
+class Chaos{
+	//singleton
+	public:
+		static Chaos* getInstance();
+	private:
+		Chaos()=default;
+		static Chaos* instance;
+
+	//members
+	public:
+		bool udpListen=false;
+		bool tcpListen=false;
+		bool programOK=true;
+		atomic<unsigned>packNum;
+
+		int udpsocket;
+
+};
+
+
+
+#endif

+ 50 - 0
definations.h

@@ -0,0 +1,50 @@
+#ifndef _DEFINATIONS_H_
+#define _DEFINATIONS_H_
+
+#ifdef DEBUG
+#define dpf(fmt,args...) printf(fmt,##args)
+#else
+#define dpf(fmt,args...)
+#endif
+
+#define dpl(x) printf("line:%d\n",x)
+#define _DBG  
+
+#define likely(x) __builtin_expect(!!(x),1)
+#define unlikely(x) __builtin_expect(!!(x),0)
+
+#define FUNCSUCCEED 0
+#define FUNCFAILED -1
+
+#define u8 unsigned char
+#define u16 unsigned short
+#define u32 unsigned int
+#define u64 unsigned long long
+#define s8 char
+#define s16 short
+#define s32 int
+#define s64 long long
+#define BIT bool
+#define BYTE u8
+#define WORD u16
+#define WORD_LO(x) (BYTE)((x)&0xff)
+#define WORD_HI(x) (BYTE)((x)>>8)
+#define DWORD u32
+#define QWORD u64
+
+#define PORT 2425
+#define BUFFLEN 1024*64
+
+#define IPMSG_EX_CHATREADY 		0x0000008EUL
+#define IPMSG_EX_CHATCHECKMAC	0x000000E7UL
+#define IPMSG_EX_REQSHAREFILE	0x00000090UL
+#define IPMSG_EX_REFUSEFILE     0x000000E6UL
+#define IPMSG_EX_CANCELFILE     0x000000E8UL
+#define IPMSG_EX_PREGETFILE     0x0000008BUL
+
+const char vermagic[]="5.1.180210";
+const char fontmagic[]="[rich]0A0000000000860008AE5F6F8FC596D19E12000000000000000000000000000000000000[/rich]";
+
+#define MSGLENGTH 250
+#define PACKRINGLEN 3
+#endif

+ 220 - 0
fileManager.cpp

@@ -0,0 +1,220 @@
+#include"fileManager.h"
+#include<pthread.h>
+#include <atomic>
+using namespace std;
+
+static pthread_mutex_t recvDelLock;
+static atomic<bool> recvDelPrelock(false);
+static atomic<int> recvUseCount(0);
+
+static pthread_mutex_t sendDelLock;
+static atomic<bool>sendDelPrelock(false);
+static atomic<int>sendUseCount(0);
+
+const char *(filetype_str[])={
+						 "<Unknown>","<CommonFile>","<Directory>",
+						 "<RtnParent>","<SoftLink>","<CharDev>",
+						 "<BlockDev>","<FIFO>","<Unknown>",
+						 "<Unknown>","<ResFork>"};
+
+FileManager* FileManager::instance=new FileManager();
+FileManager* FileManager::getInstance(){
+    static bool flgfirst=true;
+    if(flgfirst){
+        pthread_mutex_init(&recvDelLock,NULL);
+        pthread_mutex_init(&sendDelLock,NULL);
+    }
+    return instance;
+}
+
+
+int FileManager::Addrecv(recvfile_t& tar){
+    bool correctTime=false;
+    while(correctTime==false){
+        while(recvDelPrelock==true);
+        recvUseCount++;
+        if(recvDelPrelock==true){
+            recvUseCount--;
+        }else{
+            correctTime=true;
+        }
+    }
+    auto i=recvls.begin();
+    auto z=recvls.end();
+    bool nofound=true;
+    for(;i!=z;i++){
+        if((i->fileno==tar.fileno)&&(i->tarIp==tar.tarIp)){
+            nofound=false;
+            break;
+        }
+    }
+    if(nofound){
+        recvUseCount--;
+        recvls.push_back(tar);
+        return FUNCSUCCEED;
+    }else{
+        *i=tar;
+        recvUseCount--;
+        return FUNCFAILED;
+    }
+}
+int FileManager::Delrecv(unsigned tarno,unsigned tarIp){
+    pthread_mutex_lock(&recvDelLock);
+    recvDelPrelock=true;
+    while(recvUseCount!=0);
+    auto i=recvls.begin();
+    auto z=recvls.end();
+    bool nofound=true;
+    for(;i!=z;i++){
+        if((i->fileno==tarno)&&(i->tarIp==tarIp)){
+            nofound=false;
+            break;
+        }
+    }
+    if(nofound==false){
+        i=recvls.erase(i);
+    }
+
+    recvDelPrelock=false;
+    pthread_mutex_unlock(&recvDelLock);
+    return nofound==false?FUNCSUCCEED:FUNCFAILED;
+}
+int FileManager::Findrecv(unsigned tarno,unsigned tarIp,recvfile_t& tar){
+    bool correctTime=false;
+    while(correctTime==false){
+        while(recvDelPrelock==true);
+        recvUseCount++;
+        if(recvDelPrelock==true){
+            recvUseCount--;
+        }else{
+            correctTime=true;
+        }
+    }
+    auto i=recvls.begin();
+    auto z=recvls.end();
+    bool nofound=true;
+    for(;i!=z;i++){
+        if((i->fileno==tarno)&&(i->tarIp==tarIp)){
+            nofound=false;
+            break;
+        }
+    }
+    if(nofound){
+        recvUseCount--;
+        return FUNCFAILED;
+    }else{
+        tar=*i;
+        recvUseCount--;
+        return FUNCSUCCEED;
+    }
+}
+int FileManager::GetrecvCopy(list<recvfile_t>& src){
+    bool correctTime=false;
+    while(correctTime==false){
+        while(recvDelPrelock==true);
+        recvUseCount++;
+        if(recvDelPrelock==true){
+            recvUseCount--;
+        }else{
+            correctTime=true;
+        }
+    }
+    std::copy(recvls.begin(),recvls.end(),std::back_inserter(src));
+    recvUseCount--;
+}
+
+int FileManager::Addsend(sendfile_t& tar){
+    bool correctTime=false;
+    while(correctTime==false){
+        while(sendDelPrelock==true);
+        sendUseCount++;
+        if(sendDelPrelock==true){
+            sendUseCount--;
+        }else{
+            correctTime=true;
+        }
+    }
+    auto i=sendls.begin();
+    auto z=sendls.end();
+    bool nofound=true;
+    for(;i!=z;i++){
+        if((i->fileno==tar.fileno)&&(i->tarIp==tar.tarIp)){
+            nofound=false;
+            break;
+        }
+    }
+    if(nofound){
+        sendUseCount--;
+        sendls.push_back(tar);
+        return FUNCSUCCEED;
+    }else{
+        sendUseCount--;
+        return FUNCFAILED;
+    }
+}
+int FileManager::Delsend(unsigned tarno,unsigned tarIp){
+    pthread_mutex_lock(&sendDelLock);
+    sendDelPrelock=true;
+    while(sendUseCount!=0);
+
+    auto i=sendls.begin();
+    auto z=sendls.end();
+    bool nofound=true;
+    for(;i!=z;i++){
+        if((i->fileno==tarno)&&(i->tarIp==tarIp)){
+            nofound=false;
+            break;
+        }
+    }
+    if(nofound==false){
+        i=sendls.erase(i);
+    }
+
+    sendDelPrelock=false;
+    pthread_mutex_unlock(&sendDelLock);
+    return nofound==false?FUNCSUCCEED:FUNCFAILED;
+}
+int FileManager::Findsend(unsigned tarno,unsigned tarIp,sendfile_t& tar){
+    bool correctTime=false;
+    while(correctTime==false){
+        while(sendDelPrelock==true);
+        sendUseCount++;
+        if(sendDelPrelock==true){
+            sendUseCount--;
+        }else{
+            correctTime=true;
+        }
+    }
+    auto i=sendls.begin();
+    auto z=sendls.end();
+    bool nofound=true;
+    for(;i!=z;i++){
+        if((i->fileno==tarno)&&(i->tarIp==tarIp)){
+            nofound=false;
+            break;
+        }
+    }
+    if(nofound){
+        sendUseCount--;
+        return FUNCFAILED;
+    }else{
+        tar=*i;
+        sendUseCount--;
+        return FUNCSUCCEED;
+    }
+}
+int FileManager::GetsendCopy(list<sendfile_t>& src){
+    bool correctTime=false;
+    while(correctTime==false){
+        while(sendDelPrelock==true);
+        sendUseCount++;
+        if(sendDelPrelock==true){
+            sendUseCount--;
+        }else{
+            correctTime=true;
+        }
+    }
+    std::copy(sendls.begin(),sendls.end(),std::back_inserter(src));
+    sendUseCount--;
+
+}

+ 55 - 0
fileManager.h

@@ -0,0 +1,55 @@
+#ifndef _FILEMANAGER_H_
+#define _FILEMANAGER_H_
+
+#include<sys/types.h>
+#include<list>
+#include<string>
+#include"definations.h"
+#include<cstdio>
+#include<cstring>
+
+using std::list;
+using std::string;
+extern const char *(filetype_str[]);
+
+class recvfile_t{
+public:
+    unsigned tarIp;
+    unsigned fileno;
+    string filename;
+    unsigned filesize;
+    unsigned filetype;
+    unsigned time;
+    unsigned attr;
+};
+class sendfile_t{
+public:
+    unsigned tarIp;
+    unsigned fileno;
+    string filename;
+    unsigned filesize;
+    string filelocate;
+    unsigned filetype;
+};
+class FileManager{
+private:
+    FileManager()=default;
+    static FileManager* instance;
+    list<recvfile_t> recvls;
+    list<sendfile_t> sendls;
+public:
+    static FileManager* getInstance();
+
+    int Addrecv(recvfile_t& tar);
+    int Delrecv(unsigned tarno,unsigned tarIp);
+    int Findrecv(unsigned tarno,unsigned tarIp,recvfile_t& tar);
+    int GetrecvCopy(list<recvfile_t>& src);
+
+    int Addsend(sendfile_t& tar);
+    int Delsend(unsigned tarno,unsigned tarIp);
+    int Findsend(unsigned tarno,unsigned tarIp,sendfile_t& tar);
+    int GetsendCopy(list<sendfile_t>& src);
+
+};
+#endif
+

+ 35 - 0
fixedmath.cpp

@@ -0,0 +1,35 @@
+#include "fixedmath.h"
+
+unsigned u32atoi(const char*src){
+	unsigned ans=0;
+	int i=0;
+	while((src[i]>='0')&&(src[i]<='9')){
+		ans*=10;
+		ans+=(src[i]-'0');
+		i++;
+	}
+	return ans;
+}
+unsigned u32atox(const char* src){
+	unsigned ans=0;
+	int i=0;
+	while(1){
+		if((src[i]>='0')&&(src[i]<='9')){
+			ans*=16;
+			ans+=(src[i]-'0');
+			i++;
+		}else if((src[i]>='a')&&(src[i]<='f')){
+			ans*=16;
+			ans+=(10+src[i]-'a');
+			i++;
+		}else if((src[i]>='A')&&(src[i]<='F')){
+			ans*=16;
+			ans+=(10+src[i]-'A');
+			i++;
+		}else{
+			return ans;
+		}
+	}
+}
+
+

+ 8 - 0
fixedmath.h

@@ -0,0 +1,8 @@
+#ifndef __FIXEDMATH_H_
+#define __FIXEDMATH_H_
+
+unsigned u32atoi(const char*);
+unsigned u32atox(const char*);
+
+
+#endif

+ 171 - 0
include/ipmsg.h

@@ -0,0 +1,171 @@
+/*	@(#)Copyright (C) H.Shirouzu 1996-2004   ipmsg.h	Ver2.05 */
+/* ========================================================================
+	Project  Name			: IP Messenger for Win32
+	Module Name				: Main Header
+	Create					: 1996-06-01(Sat)
+	Update					: 2004-01-01(Thu)
+	Copyright				: H.Shirouzu
+	Reference				: 
+	======================================================================== */
+
+#ifndef IPMSG_H
+#define IPMSG_H
+
+#include <time.h>
+
+/*  IP Messenger Communication Protocol version 1.2 define  */
+/*  macro  */
+#define GET_MODE(command)	(command & 0x000000ffUL)
+#define GET_OPT(command)	(command & 0xffffff00UL)
+
+/*  header  */
+#define IPMSG_VERSION			0x0001
+#define IPMSG_DEFAULT_PORT		0x0979
+
+/*  command  */
+#define IPMSG_NOOPERATION		0x00000000UL
+
+#define IPMSG_BR_ENTRY			0x00000001UL
+#define IPMSG_BR_EXIT			0x00000002UL
+#define IPMSG_ANSENTRY			0x00000003UL
+#define IPMSG_BR_ABSENCE		0x00000004UL
+
+#define IPMSG_BR_ISGETLIST		0x00000010UL
+#define IPMSG_OKGETLIST			0x00000011UL
+#define IPMSG_GETLIST			0x00000012UL
+#define IPMSG_ANSLIST			0x00000013UL
+#define IPMSG_BR_ISGETLIST2		0x00000018UL
+
+#define IPMSG_SENDMSG			0x00000020UL
+#define IPMSG_RECVMSG			0x00000021UL
+#define IPMSG_READMSG			0x00000030UL
+#define IPMSG_DELMSG			0x00000031UL
+#define IPMSG_ANSREADMSG		0x00000032UL
+
+#define IPMSG_GETINFO			0x00000040UL
+#define IPMSG_SENDINFO			0x00000041UL
+
+#define IPMSG_GETABSENCEINFO	0x00000050UL
+#define IPMSG_SENDABSENCEINFO	0x00000051UL
+
+#define IPMSG_GETFILEDATA		0x00000060UL
+#define IPMSG_RELEASEFILES		0x00000061UL
+#define IPMSG_GETDIRFILES		0x00000062UL
+
+#define IPMSG_GETPUBKEY			0x00000072UL
+#define IPMSG_ANSPUBKEY			0x00000073UL
+
+/*  option for all command  */
+#define IPMSG_ABSENCEOPT		0x00000100UL
+#define IPMSG_SERVEROPT			0x00000200UL
+#define IPMSG_DIALUPOPT			0x00010000UL
+#define IPMSG_FILEATTACHOPT		0x00200000UL
+#define IPMSG_ENCRYPTOPT		0x00400000UL
+
+/*  option for send command  */
+#define IPMSG_SENDCHECKOPT		0x00000100UL
+#define IPMSG_SECRETOPT			0x00000200UL
+#define IPMSG_BROADCASTOPT		0x00000400UL
+#define IPMSG_MULTICASTOPT		0x00000800UL
+#define IPMSG_NOPOPUPOPT		0x00001000UL
+#define IPMSG_AUTORETOPT		0x00002000UL
+#define IPMSG_RETRYOPT			0x00004000UL
+#define IPMSG_PASSWORDOPT		0x00008000UL
+#define IPMSG_NOLOGOPT			0x00020000UL
+#define IPMSG_NEWMUTIOPT		0x00040000UL
+#define IPMSG_NOADDLISTOPT		0x00080000UL
+#define IPMSG_READCHECKOPT		0x00100000UL
+#define IPMSG_SECRETEXOPT		(IPMSG_READCHECKOPT|IPMSG_SECRETOPT)
+
+/* encryption flags for encrypt command */
+#define IPMSG_RSA_512			0x00000001UL
+#define IPMSG_RSA_1024			0x00000002UL
+#define IPMSG_RSA_2048			0x00000004UL
+#define IPMSG_RC2_40			0x00001000UL
+#define IPMSG_RC2_128			0x00004000UL
+#define IPMSG_RC2_256			0x00008000UL
+#define IPMSG_BLOWFISH_128		0x00020000UL
+#define IPMSG_BLOWFISH_256		0x00040000UL
+#define IPMSG_SIGN_MD5			0x10000000UL
+
+/* compatibilty for Win beta version */
+#define IPMSG_RC2_40OLD			0x00000010UL	// for beta1-4 only
+#define IPMSG_RC2_128OLD		0x00000040UL	// for beta1-4 only
+#define IPMSG_BLOWFISH_128OLD	0x00000400UL	// for beta1-4 only
+#define IPMSG_RC2_40ALL			(IPMSG_RC2_40|IPMSG_RC2_40OLD)
+#define IPMSG_RC2_128ALL		(IPMSG_RC2_128|IPMSG_RC2_128OLD)
+#define IPMSG_BLOWFISH_128ALL	(IPMSG_BLOWFISH_128|IPMSG_BLOWFISH_128OLD)
+
+/* file types for fileattach command */
+#define IPMSG_FILE_REGULAR		0x00000001UL
+#define IPMSG_FILE_DIR			0x00000002UL
+#define IPMSG_FILE_RETPARENT	0x00000003UL	// return parent directory
+#define IPMSG_FILE_SYMLINK		0x00000004UL
+#define IPMSG_FILE_CDEV			0x00000005UL	// for UNIX
+#define IPMSG_FILE_BDEV			0x00000006UL	// for UNIX
+#define IPMSG_FILE_FIFO			0x00000007UL	// for UNIX
+#define IPMSG_FILE_RESFORK		0x00000010UL	// for Mac
+
+/* file attribute options for fileattach command */
+#define IPMSG_FILE_RONLYOPT		0x00000100UL
+#define IPMSG_FILE_HIDDENOPT	0x00001000UL
+#define IPMSG_FILE_EXHIDDENOPT	0x00002000UL	// for MacOS X
+#define IPMSG_FILE_ARCHIVEOPT	0x00004000UL
+#define IPMSG_FILE_SYSTEMOPT	0x00008000UL
+
+/* extend attribute types for fileattach command */
+#define IPMSG_FILE_UID			0x00000001UL
+#define IPMSG_FILE_USERNAME		0x00000002UL	// uid by string
+#define IPMSG_FILE_GID			0x00000003UL
+#define IPMSG_FILE_GROUPNAME	0x00000004UL	// gid by string
+#define IPMSG_FILE_PERM			0x00000010UL	// for UNIX
+#define IPMSG_FILE_MAJORNO		0x00000011UL	// for UNIX devfile
+#define IPMSG_FILE_MINORNO		0x00000012UL	// for UNIX devfile
+#define IPMSG_FILE_CTIME		0x00000013UL	// for UNIX
+#define IPMSG_FILE_MTIME		0x00000014UL
+#define IPMSG_FILE_ATIME		0x00000015UL
+#define IPMSG_FILE_CREATETIME	0x00000016UL
+#define IPMSG_FILE_CREATOR		0x00000020UL	// for Mac
+#define IPMSG_FILE_FILETYPE		0x00000021UL	// for Mac
+#define IPMSG_FILE_FINDERINFO	0x00000022UL	// for Mac
+#define IPMSG_FILE_ACL			0x00000030UL
+#define IPMSG_FILE_ALIASFNAME	0x00000040UL	// alias fname
+#define IPMSG_FILE_UNICODEFNAME	0x00000041UL	// UNICODE fname
+
+#define FILELIST_SEPARATOR	'\a'
+#define HOSTLIST_SEPARATOR	'\a'
+#define HOSTLIST_DUMMY		"\b"
+
+/*  end of IP Messenger Communication Protocol version 1.2 define  */
+
+
+/*  IP Messenger for Windows  internal define  */
+#define IPMSG_REVERSEICON			0x0100
+#define IPMSG_TIMERINTERVAL			500
+#define IPMSG_ENTRYMINSEC			5
+#define IPMSG_GETLIST_FINISH		0
+
+#define IPMSG_BROADCAST_TIMER		0x0101
+#define IPMSG_SEND_TIMER			0x0102
+#define IPMSG_LISTGET_TIMER			0x0104
+#define IPMSG_LISTGETRETRY_TIMER	0x0105
+#define IPMSG_ENTRY_TIMER			0x0106
+#define IPMSG_DUMMY_TIMER			0x0107
+#define IPMSG_RECV_TIMER			0x0108
+#define IPMSG_ANS_TIMER				0x0109
+
+#define IPMSG_NICKNAME			1
+#define IPMSG_FULLNAME			2
+
+#define IPMSG_NAMESORT			0x00000000
+#define IPMSG_IPADDRSORT		0x00000001
+#define IPMSG_HOSTSORT			0x00000002
+#define IPMSG_NOGROUPSORTOPT	0x00000100
+#define IPMSG_ICMPSORTOPT		0x00000200
+#define IPMSG_NOKANJISORTOPT	0x00000400
+#define IPMSG_ALLREVSORTOPT		0x00000800
+#define IPMSG_GROUPREVSORTOPT	0x00001000
+#define IPMSG_SUBREVSORTOPT		0x00002000
+
+#endif
+

+ 646 - 0
main.cpp

@@ -0,0 +1,646 @@
+#include"chaos.h"
+#include"definations.h"
+#include"errno.h"
+#include"fileManager.h"
+#include"include/ipmsg.h"
+#include"msgManager.h"
+#include"packMaker.h"
+#include"tcpReceiver.h"
+#include"udpReceiver.h"
+#include"usermanager.h"
+#include<arpa/inet.h>
+#include<cstdio>
+#include<cstdlib>
+#include<cstring>
+#include<fcntl.h>
+#include<net/if.h>
+#include<netdb.h>
+#include<netinet/in.h>
+#include<pthread.h>
+#include<pthread.h>
+#include<pwd.h>
+#include<sys/ioctl.h>
+#include<sys/socket.h>
+#include<sys/stat.h>
+#include<sys/types.h>
+#include<unistd.h>
+#include<utime.h>
+#include<vector>
+
+using std::vector;
+static Chaos* chaos=0;
+static UserManager* users=0;
+static MsgManager* msgs=0;
+static FileManager* filels=0;
+
+int main(){
+	chaos=Chaos::getInstance();
+	if(unlikely(chaos==NULL)){
+		printf("\e[31mFatel error:\e[0mChaos not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,chaos,errno);
+		exit(1);
+	}
+	users=UserManager::getInstance();
+	if(unlikely(users==NULL)){
+		printf("\e[31mFatel error:\e[0mUserManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,users,errno);
+		exit(1);
+	}
+	msgs=MsgManager::getInstance();
+	if(unlikely(msgs==NULL)){
+		printf("\e[31mFatel error:\e[0mMsgManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,msgs,errno);
+	}
+	filels=FileManager::getInstance();
+	if(unlikely(filels==NULL)){
+		printf("\e[31mFatel error:\e[0mFileManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,filels,errno);
+	}
+
+	pthread_t udpThd;
+	pthread_t tcpThd;
+	pthread_attr_t attr;
+	int funcAns=pthread_attr_init(&attr);
+	if(unlikely(funcAns!=0)){
+		printf("\e[31mFatel error:\e[0mthread create error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,funcAns,errno);
+		exit(1);
+	}
+	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
+
+	funcAns=pthread_create(&udpThd,&attr,thd_udpReceiver,NULL);
+	if(unlikely(funcAns!=0)){
+		printf("\e[31mFatel error:\e[0mthread create error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,funcAns,errno);
+		exit(1);
+	}
+	funcAns=pthread_create(&tcpThd,&attr,thd_tcpReceiver,NULL);
+	if(unlikely(funcAns!=0)){
+		printf("\e[31mFatel error:\e[0mthread create error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,funcAns,errno);
+		exit(1);
+	}
+
+	gethostname(users->myinfo.computername,100);
+	struct passwd *pwd;
+	pwd=getpwuid(getuid());
+	strncpy(users->myinfo.sysusrname,pwd->pw_name,100);
+
+	printf("waiting udp thread ready...\n");
+	while(chaos->udpListen==false);
+	printf("waiting tcp thread ready...\n");
+	while(chaos->tcpListen==false);
+	//broadcast...
+	char buff[BUFFLEN];
+	int opt=1;
+	int pklen=mkHeartPack(buff,IPMSG_BR_ENTRY|IPMSG_BROADCASTOPT);
+	int bcudpsock=chaos->udpsocket;
+
+	struct sockaddr_in bcudpaddr;
+	bzero(&bcudpaddr,sizeof(struct sockaddr_in));
+	bcudpaddr.sin_family=AF_INET;
+	bcudpaddr.sin_addr.s_addr=htonl(INADDR_BROADCAST);
+	bcudpaddr.sin_port=htons(PORT);
+	socklen_t bcudpaddr_len=sizeof(bcudpaddr);
+	sprintf(buff+1,"1.feige.1");
+	buff[10]=':';
+	sendto(bcudpsock,buff+1,pklen-1,0,(struct sockaddr*)&bcudpaddr,bcudpaddr_len);
+	sprintf(buff,"%s",vermagic);
+	buff[10]=':';
+	sendto(bcudpsock,buff,pklen,0,(struct sockaddr*)&bcudpaddr,bcudpaddr_len);
+
+	if(1){		//console...
+		char cmdbuf[BUFFLEN];
+		char sendbuff[BUFFLEN];
+		int sendlen=0;
+		struct sockaddr_in c_addr;
+		int sock=chaos->udpsocket;
+		bzero(&c_addr,sizeof(c_addr));
+		c_addr.sin_family=AF_INET;
+		c_addr.sin_port=htons(PORT);
+		socklen_t addr_len=sizeof(c_addr);
+
+		while(chaos->programOK){
+			msg_t tmpmsg;
+			while(msgs->PopMsg(tmpmsg)==FUNCSUCCEED){
+			char sztmpip[24];
+			struct in_addr ip;
+			ip.s_addr=tmpmsg.ip;
+				strcpy(sztmpip,inet_ntoa(ip));
+				printf("%s said:\n%s\n",sztmpip,tmpmsg.msg.c_str());
+			}
+
+			memset(cmdbuf,0,sizeof(cmdbuf));
+			memset(sendbuff,0,sizeof(sendbuff));
+			printf(">");
+			fflush(stdin);
+			fgets(cmdbuf,sizeof(cmdbuf),stdin);
+			if(cmdbuf[0]==0)continue;
+			if(cmdbuf[0]=='\n')continue;
+			int curpos=0;
+			char tmpbuf[BUFFLEN/16];
+			sscanf(cmdbuf+curpos," %[^\n ]%n",tmpbuf,&curpos);
+
+			if(strncmp(tmpbuf,"ls",3)				==0){
+				list<user_t> tmplist;
+				users->GetUserCopy(tmplist);
+				for(auto person:tmplist){
+					char tmpip[24];
+					strcpy(tmpip,inet_ntoa(person.ip.sin_addr));
+					printf("%-20s %-12s %-12s %-10s\n",tmpip,person.sysusrname,
+								person.computername,person.usrname);
+				}
+			}else if(strncmp(tmpbuf,"la",3)			==0){
+				char ipbuf[20];
+				sscanf(cmdbuf+curpos," %[0-9.]",ipbuf);
+				in_addr_t tarip=inet_addr(ipbuf);
+				if(tarip==-1){
+					printf("Invaild ip address.\n");
+					dpf("%d,%s,%d\n",__LINE__,__FILE__,errno);
+				}else{
+					user_t tar;
+					int findans=users->Finduser(tar,tarip);
+					if(findans==FUNCSUCCEED){
+						printf("%-20s:%s\n","IP  Address",ipbuf);
+						printf("%-20s:%s\n","System  Username",tar.sysusrname);
+						printf("%-20s:%s\n","Computer Username",tar.computername);
+						printf("%-20s:%s\n","Username",tar.usrname);
+						printf("%-20s:%s\n","Groupname",tar.grpname);
+						printf("%-20s:%s\n","Mac Address",tar.macaddr);
+						printf("%-20s:%s\n","Telephone Number",tar.phone);
+						printf("%-20s:%s\n","E-mail Address",tar.mail);
+						printf("%-20s:%s\n","Share Printer Name",tar.printer);
+						printf("%-20s:%s\n","Icon Number",tar.icon);
+						char statusbuf[16]={0};
+						switch(tar.icon[0]){
+						case '0':
+							sprintf(statusbuf,"Online");
+							break;
+						case '1':
+							sprintf(statusbuf,"Busy");
+							break;
+						case '2':
+							sprintf(statusbuf,"Away from keyboard");
+							break;
+						}
+						printf("%-20s:%s\n","User Status",statusbuf);
+						printf("%-20s:%s\n","Sign",tar.sign);
+					}else{
+						printf("User %s not found.\n",ipbuf);
+					}
+					printf("\n");
+				}
+
+			}else if(strncmp(tmpbuf,"setmyinfo",10)	==0){
+				char infobuf[1000];
+				fflush(stdin);
+				infobuf[0]=0;
+				printf("Please input your username.Input nothing to keep current value.\n(current is \e[32m%2s\e[0m)\e[47;32m\n",users->myinfo.usrname);
+				scanf(" %[^\n]",infobuf);
+				if(infobuf[0]!='\n'){
+					strncpy(users->myinfo.usrname,infobuf,100);
+				}
+				printf("\e[0m");
+
+				fflush(stdin);
+				infobuf[0]=0;
+				printf("Please input your groupname.Input nothing to keep current value.\n(current is \e[32m%2s\e[0m)\e[47;32m\n",users->myinfo.grpname);
+				scanf(" %[^\n]",infobuf);
+				if(infobuf[0]!='\n'){
+					strncpy(users->myinfo.grpname,infobuf,100);
+				}
+				printf("\e[0m");
+
+				fflush(stdin);
+				infobuf[0]=0;
+				printf("Please input your phone number.Input nothing to keep current value.\n(current is \e[32m%2s\e[0m)\e[47;32m\n",users->myinfo.phone);
+				scanf(" %[^\n]",infobuf);
+				if(infobuf[0]!='\n'){
+					strncpy(users->myinfo.phone,infobuf,20);
+				}
+				printf("\e[0m");
+
+				fflush(stdin);
+				infobuf[0]=0;
+				printf("Please input your e-mail.Input nothing to keep current value.\n(current is \e[32m%2s\e[0m)\e[47;32m\n",users->myinfo.mail);
+				scanf(" %[^\n]",infobuf);
+				if(infobuf[0]!='\n'){
+					strncpy(users->myinfo.mail,infobuf,100);
+				}
+				printf("\e[0m");
+
+				fflush(stdin);
+				infobuf[0]=0;
+				printf("Please select your icon(0-31).Input nothing to keep current value.\n(current is \e[32m%2s\e[0m)\e[47;32m\n",users->myinfo.icon);
+				scanf(" %[^\n]",infobuf);
+				if(infobuf[0]!='\n'){
+					strncpy(users->myinfo.icon,infobuf,10);
+				}
+				printf("\e[0m");
+
+				fflush(stdin);
+				infobuf[0]=0;
+				printf("Please input your sign.Input nothing to keep current value.\n(current is \e[32m%2s\e[0m)\e[47;32m\n",users->myinfo.sign);
+				scanf(" %[^\n]",infobuf);
+				if(infobuf[0]!='\n'){
+					strncpy(users->myinfo.sign,infobuf,1000);
+				}
+				printf("\e[0m");
+				strncpy(users->myinfo.netstatus,"10000001",10);
+				strncpy(users->myinfo.space02,"5",10);
+				pklen=mkHeartPack(buff,IPMSG_BR_ENTRY);
+				sendto(bcudpsock,buff,pklen,0,(struct sockaddr*)&bcudpaddr,bcudpaddr_len);
+				printf("Set personal info complete!\n");
+			}else if(strncmp(tmpbuf,"send",5)		==0){
+				char ipbuf[20];
+				int optstart;
+				sscanf(cmdbuf+curpos," %[^\n ]%n",ipbuf,&optstart);
+				in_addr_t tarip=inet_addr(ipbuf);
+				if(tarip==-1){
+					printf("Invaild ip address.\n");
+					dpf("%d,%s,%d\n",__LINE__,__FILE__,errno);
+				}else{
+					char msgbuf[BUFFLEN];
+					sscanf(cmdbuf+curpos+optstart," %[^\n]%n",msgbuf,&curpos);
+					c_addr.sin_addr.s_addr=tarip;
+					sendlen=mkHeader(sendbuff,IPMSG_SENDMSG);
+					sendlen+=sprintf(sendbuff+sendlen,msgbuf);
+					sendlen+=sprintf(sendbuff+sendlen,"%s",fontmagic);
+					sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+					printf("\n");
+				}
+			}else if(strncmp(tmpbuf,"refresh",8)	==0){
+				users->UserIllness();
+				pklen=mkHeartPack(buff,IPMSG_BR_ENTRY|IPMSG_BROADCASTOPT);
+				sprintf(buff+1,"1.feige.1");
+				buff[10]=':';
+				sendto(bcudpsock,buff+1,pklen-1,0,(struct sockaddr*)&bcudpaddr,bcudpaddr_len);
+				sprintf(buff,"%s",vermagic);
+				buff[10]=':';
+				sendto(bcudpsock,buff,pklen,0,(struct sockaddr*)&bcudpaddr,bcudpaddr_len);
+
+				printf("BroadCast to %s\n",inet_ntoa(bcudpaddr.sin_addr));
+				printf("Refreshing");
+				fflush(stdout);
+				sleep(1);
+				printf(".");
+				fflush(stdout);
+				sleep(1);
+				printf(".");
+				fflush(stdout);
+				sleep(1);
+				printf(".");
+				fflush(stdout);
+				sleep(1);
+				list<user_t> tmpusr;
+				users->GetUserCopy(tmpusr);
+				auto i=tmpusr.begin();
+				auto z=tmpusr.end();
+				for(;i!=z;i++){
+					if(i->healthy==false){
+						users->Deluser(i->ip);
+					}
+				}
+				printf("\n");
+			}else if(strncmp(tmpbuf,"lsfile",7)		==0){
+				list<recvfile_t> tmprecvls;
+				filels->GetrecvCopy(tmprecvls);
+				for(auto i:tmprecvls){
+					struct sockaddr_in tmpaddr;
+					tmpaddr.sin_addr.s_addr=i.tarIp;
+					char tmpip[24];
+					strcpy(tmpip,inet_ntoa(tmpaddr.sin_addr));
+					int typeindex=((i.filetype>0)&&(i.filetype<11))?i.filetype:0;
+					printf("%20s-%-12u %15s %s\n",tmpip,i.fileno,filetype_str[i.filetype],i.filename.c_str());
+				}
+				printf("Press any key to continue...");
+				getchar();
+
+				list<sendfile_t> tmpsendls;
+				filels->GetsendCopy(tmpsendls);
+				for(auto i:tmpsendls){
+					struct sockaddr_in tmpaddr;
+					tmpaddr.sin_addr.s_addr=i.tarIp;
+					char tmpip[24];
+					strcpy(tmpip,inet_ntoa(tmpaddr.sin_addr));
+					int typeindex=((i.filetype>0)&&(i.filetype<11))?i.filetype:0;
+					printf("%20s-%-12u %15s %s\n",tmpip,i.fileno,filetype_str[i.filetype],i.filename.c_str());
+				}
+				printf("Press any key to continue...");
+				getchar();
+			}else if(strncmp(tmpbuf,"sendfile",9)	==0){
+				char raw_ip[20];
+				char fnamebuf[BUFFLEN];
+				char extra=0;
+				struct in_addr tmpip;
+				int optindex=0;
+				sscanf(cmdbuf+curpos," %[^\n ]%n",raw_ip,&optindex);
+				if(inet_aton(raw_ip,&tmpip)!=-1){
+					sscanf(cmdbuf+curpos+optindex," %[^\n ]%n",fnamebuf,&optindex);
+					if(fnamebuf[0]=='-'){
+						extra=fnamebuf[1];
+						sscanf(cmdbuf+curpos," %[^\n ]%n",fnamebuf,&curpos);
+					}
+					struct stat statbuf;
+					int statans=stat(fnamebuf,&statbuf);
+					puts(fnamebuf);
+					if(statans==0){
+						char nakedfnamebuf[BUFFLEN];
+						char* tmp=strrchr(fnamebuf,'/');
+						if(tmp!=NULL){
+							strcpy(nakedfnamebuf,strrchr(fnamebuf,'/')+1);
+						}else{
+							strcpy(nakedfnamebuf,fnamebuf);
+						}
+						int filetp=0;
+						if(S_ISREG(statbuf.st_mode)){
+							filetp=IPMSG_FILE_REGULAR;
+						}else if(S_ISDIR(statbuf.st_mode)){
+							filetp=IPMSG_FILE_DIR;
+						}
+						if(filetp){
+							unsigned packno;
+							sendlen=mkHeader(sendbuff,IPMSG_SENDMSG|IPMSG_FILEATTACHOPT|IPMSG_SENDCHECKOPT,&packno);
+							sendlen+=sprintf(sendbuff+sendlen,"")+1;
+							sendlen+=sprintf(sendbuff+sendlen,"%u:%s:%x:0:%u:%u:%u:%u:",
+								packno-1,nakedfnamebuf,statbuf.st_size,filetp,
+								statbuf.st_atime,statbuf.st_mtime,statbuf.st_ctime)+1;
+							sendfile_t sendnode;
+							sendnode.tarIp=tmpip.s_addr;
+							sendnode.fileno=packno-1;
+							sendnode.filename=nakedfnamebuf;
+							sendnode.filesize=statbuf.st_size;
+							sendnode.filelocate=fnamebuf;
+							sendnode.filetype=filetp;
+
+							if(filels->Addsend(sendnode)==FUNCSUCCEED){
+								c_addr.sin_addr.s_addr=tmpip.s_addr;
+								sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+							}else{
+								printf("Unknown error,please retry.\n");
+							}
+						}
+					}else{
+						printf("Read file information error.\n");
+						dpf("%d,%s,%d\n",__LINE__,__FILE__,errno);
+					}
+				}else{
+					printf("Invalid ip address!\n");
+				}
+
+			}else if(strncmp(tmpbuf,"recvfile",9)	==0){		//From this function, A rebuild occured, Code style changed
+				char raw_ip[20];
+				unsigned fileno;
+				struct in_addr tmpip;
+				char other[BUFFLEN]={0};
+				char optlocate[BUFFLEN]={0};
+				sscanf(cmdbuf+curpos," %[^\n-]-%u %[%^\n]",raw_ip,&fileno,other);
+
+				if(inet_aton(raw_ip,&tmpip)==-1){
+					printf("Invalid ip address!\n");
+					continue;
+				}
+				if((other[0]=='-')&&((other[1]=='f')||(other[1]=='F'))){
+					sscanf(other+2," %[^\n]",optlocate);
+				}
+				recvfile_t recvnode;
+				if(filels->Findrecv(fileno,tmpip.s_addr,recvnode)==FUNCFAILED){
+					printf("Pending file not found!\n");
+					continue;
+				}
+				if(optlocate[0]==0){
+					sprintf(optlocate,"./%s",recvnode.filename.c_str());
+				}
+
+				int sockfd=socket(AF_INET,SOCK_STREAM,0);					//NC
+				if(sockfd==-1){
+					printf("Connect failed!\n");
+					dpf("%d,%s,%d\n",__LINE__,__FILE__,errno);
+					continue;
+				}
+				struct sockaddr_in addr;
+				addr.sin_family=AF_INET;
+				addr.sin_addr.s_addr=tmpip.s_addr;
+				addr.sin_port=htons(PORT);
+				int len=sizeof(addr);
+
+				int newsockfd=connect(sockfd,(struct sockaddr *)&addr,len);	//NC
+
+				if(newsockfd==-1){
+					printf("Connect failed!\n");
+					dpf("%d,%s,%d\n",__LINE__,__FILE__,errno);
+					close(sockfd);
+					continue;
+				}
+				char sendbuff[BUFFLEN];
+				int sendlen;
+				char recvbuff[BUFFLEN];
+				int recvlen;
+				int filetp;
+				if(recvnode.filetype==IPMSG_FILE_REGULAR){
+					filetp=IPMSG_GETFILEDATA;
+					FILE * fp;
+					if((fp=fopen(optlocate,"wb"))==NULL){				//NC
+						printf("Open %s failed:%d.\n",optlocate,errno);
+						close(sockfd);
+						continue;
+					}
+
+					sendlen=mkHeader(sendbuff,filetp);
+					sendlen+=sprintf(sendbuff+sendlen,"%lx:%lx:0:",recvnode.fileno+1,recvnode.fileno);
+					send(sockfd,sendbuff,sendlen,0);
+					char *filebuff=(char *)malloc(recvnode.filesize);				//NC
+					if(filebuff==NULL){
+						printf("Recving failed.Not enough memory.\n");
+						close(sockfd);
+						fclose(fp);
+					}
+
+					bool transok=false;
+					while(transok==false){
+						recvlen=recv(sockfd,filebuff,sizeof(filebuff),0);
+						if(recvlen<=0){
+							transok=true;
+						}else{
+							fwrite(filebuff,recvlen,1,fp);
+						}
+					}
+					fclose(fp);
+					free(filebuff);
+					filels->Delrecv(fileno,tmpip.s_addr);
+
+				}else if(recvnode.filetype==IPMSG_FILE_DIR){
+					filetp=IPMSG_GETDIRFILES;
+					int mkans=mkdir(optlocate,0755);
+					if(mkans==-1){
+						printf("Create directory failed:%d.",errno);
+						dpf("%d,%s,%d\n",__LINE__,__FILE__,errno);
+						continue;
+					}
+					sendlen=mkHeader(sendbuff,filetp);
+					sendlen+=sprintf(sendbuff+sendlen,"%lx:%lx:0:",recvnode.fileno+1,recvnode.fileno);
+					send(sockfd,sendbuff,sendlen,0);
+
+					bool transok=false;
+					while(transok==false){
+						recvlen=recv(sockfd,recvbuff,BUFFLEN,0);
+						if(recvlen<=0){
+							transok=true;
+						}else{
+							utime(optlocate,NULL);
+							transok=true;//FIXME: I ignored all file under a directory.Someday this sentence need to be removed.
+						}
+					}
+					filels->Delrecv(fileno,tmpip.s_addr);
+				}else{
+					printf("Unsupported file type.\n");
+				}
+				close(sockfd);
+			}else if(strncmp(tmpbuf,"refuse",7)		==0){
+				char raw_ip[20];
+				unsigned fileno;
+				struct in_addr tmpip;
+				char other[BUFFLEN]={0};
+				char optlocate[BUFFLEN]={0};
+				sscanf(cmdbuf+curpos,"  %[^\n-]-%u",raw_ip,&fileno);
+				if(inet_aton(raw_ip,&tmpip)==-1){
+					printf("Invalid ip address!\n");
+					continue;
+				}
+				recvfile_t recvnode;
+				if(filels->Findrecv(fileno,tmpip.s_addr,recvnode)==FUNCFAILED){
+					printf("Pending file not found!\n");
+					continue;
+				}
+				filels->Delrecv(fileno,tmpip.s_addr);
+				sendlen=mkHeader(sendbuff,IPMSG_EX_REFUSEFILE);
+				sendlen+=sprintf(sendbuff+sendlen,"%lx",recvnode.fileno+1)+1;
+				sendlen+=sprintf(sendbuff+sendlen,"");
+				sendlen+=sprintf(sendbuff+sendlen,"%lx",recvnode.fileno);
+				c_addr.sin_addr.s_addr=tmpip.s_addr;
+				sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+				printf("\n");
+
+			}else if(strncmp(tmpbuf,"cancel",7)		==0){
+				char raw_ip[20];
+				unsigned fileno;
+				struct in_addr tmpip;
+				char other[BUFFLEN]={0};
+				char optlocate[BUFFLEN]={0};
+				sscanf(cmdbuf+curpos," %[^\n-]-%u",raw_ip,&fileno);
+				if(inet_aton(raw_ip,&tmpip)==-1){
+					printf("Invalid ip address!\n");
+					continue;
+				}
+				sendfile_t sendnode;
+				if(filels->Findsend(fileno,tmpip.s_addr,sendnode)==FUNCFAILED){
+					printf("Pending file not found!\n");
+					continue;
+				}
+				filels->Delsend(fileno,tmpip.s_addr);
+				sendlen=mkHeader(sendbuff,IPMSG_EX_CANCELFILE);
+				sendlen+=sprintf(sendbuff+sendlen,"%lx",sendnode.fileno+1)+1;
+				sendlen+=sprintf(sendbuff+sendlen,"");
+				sendlen+=sprintf(sendbuff+sendlen,"%lx",sendnode.fileno);
+				c_addr.sin_addr.s_addr=tmpip.s_addr;
+				sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+				printf("\n");
+			}else if(strncmp(tmpbuf,"listen",7)		==0){
+				printf("Unimplemented feature.\n");
+				continue;
+			}else if(strncmp(tmpbuf,"system",7)		==0){
+				char other[BUFFLEN]={0};
+				sscanf(cmdbuf+curpos," %[^\n]",other);
+				system(other);
+				printf("\n");
+			}else if(strncmp(tmpbuf,"setnetwork",11)==0){
+				struct ifconf ifconf;
+				struct ifreq *ifreq;
+				vector<unsigned> arrayip;
+				char buf[512];
+				ifconf.ifc_len=512;
+				ifconf.ifc_buf=buf;
+				ioctl(sock,SIOCGIFCONF,&ifconf);
+				ifreq=(struct ifreq*)ifconf.ifc_buf;
+				struct ifreq*ifreqbackup=ifreq;
+				printf("Founded network device number:%d\n",(ifconf.ifc_len/sizeof (struct ifreq)));
+				for (int i=(ifconf.ifc_len/sizeof (struct ifreq)); i>0; i--){
+					if(ifreq->ifr_flags == AF_INET){ //for ipv4
+						printf("name =[%s]\n" , ifreq->ifr_name);
+						printf("local addr = [%s]\n" ,inet_ntoa(((struct sockaddr_in*)&(ifreq->ifr_addr))->sin_addr));
+						arrayip.push_back(((struct sockaddr_in*)&(ifreq->ifr_addr))->sin_addr.s_addr);
+						ifreq++;
+					}
+				}
+				printf("Select your device[1-%d]:",arrayip.size());
+				int select=0;
+				scanf(" %d",&select);
+				fflush(stdin);
+				if((select>=1)&&(select<=arrayip.size())){
+					printf("Reset network device success!\n");
+					bcudpaddr.sin_addr.s_addr=arrayip[select-1]|0xFF000000UL;
+					struct in_addr tmpip;
+					tmpip.s_addr=arrayip[select-1];
+					strncpy(users->myinfo.ipaddr,inet_ntoa(tmpip),20);
+					int macsel=select;
+					while(macsel>1){
+						macsel--;
+						ifreqbackup++;
+					}
+					sprintf(users->myinfo.macaddr,"%02X-%02X-%02X-%02X-%02X-%02X",
+							(unsigned char)ifreqbackup->ifr_hwaddr.sa_data[0],
+							(unsigned char)ifreqbackup->ifr_hwaddr.sa_data[1],
+							(unsigned char)ifreqbackup->ifr_hwaddr.sa_data[2],
+							(unsigned char)ifreqbackup->ifr_hwaddr.sa_data[3],
+							(unsigned char)ifreqbackup->ifr_hwaddr.sa_data[4],
+							(unsigned char)ifreqbackup->ifr_hwaddr.sa_data[5]);
+				}else{
+					printf("Invalid device number!\n");
+				}
+			}else if(strncmp(tmpbuf,"exit",5)		==0){
+				chaos->programOK=false;
+			}else if(strncmp(tmpbuf,"help",5)		==0){
+				printf("*****************************Help Menu****************************\n");
+				printf(" ls-------------------------------------------list all online usr \n");
+				printf(" la [ip]-----------------------------------list detail infomation \n");
+				printf(" refresh---------------------------------------refresh online usr \n");
+				printf(" **************************************************************** \n");
+				printf(" send [ip] [message]--------------------------------begin to chat \n");
+				printf(" sendfile [ip] [filename] -----------------send file or directory \n");
+				printf(" recvfile [ip]-[fileno] {-fF [newname]}----recv file or directory \n");
+				printf(" lsfile-------------------------------------list all pending file \n");
+				printf(" refuse [ip]-[fileno]-----------------------refuse to accept file \n");
+				printf(" cancel [ip]-[fileno]-------------------------cancel to send file \n");
+				printf(" **************************************************************** \n");
+				printf(" setmyinfo---------------------------------------------set myinfo \n");
+				printf(" setnetwork---------------------------------select network device \n");
+				printf(" help---------------------------------------------------help info \n");
+				printf(" exit-------------------------------------------------quit system \n");
+				printf(" **************************************************************** \n");
+				printf(" system [command]------------------------------call shell command \n");
+				printf("*****************************Help Menu*************************** \n");
+
+			}else{
+				printf("Unknown command!\nUse \"help\" to get more info.\n");
+			}
+
+		}
+		sendlen=mkHeader(sendbuff,IPMSG_BR_EXIT);
+		sendlen+=sprintf(sendbuff+sendlen,"%s",users->myinfo.usrname);
+		sendto(bcudpsock,sendbuff,sendlen,0,(struct sockaddr*)&bcudpaddr,bcudpaddr_len);
+		list<user_t> tmplist;
+		users->GetUserCopy(tmplist);
+		for(auto person:tmplist){
+			c_addr.sin_addr.s_addr=person.ip.sin_addr.s_addr;
+			sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+		}
+		printf("Exiting...\n");
+		pthread_join(udpThd,NULL);
+		pthread_join(tcpThd,NULL);
+
+	}
+	if(0){		//TODO:XCUI...
+	}
+	return 0;
+}
+

+ 37 - 0
msgManager.cpp

@@ -0,0 +1,37 @@
+#include"msgManager.h"
+#include"definations.h"
+#include<list>
+#include<cstdlib>
+#include<cstring>
+#include<string>
+#include<cstdio>
+
+MsgManager* MsgManager::instance=new MsgManager();
+MsgManager* MsgManager::getInstance(){
+    static bool flgfirst=true;
+    if(flgfirst){
+        ;
+    }
+    return instance;
+}
+
+int MsgManager::PopMsg(msg_t& dst){
+    if(!mlist.empty()){
+        dst=*(mlist.begin());
+        mlist.pop_front();
+        return FUNCSUCCEED;
+    }
+    return FUNCFAILED;
+}
+
+int MsgManager::PushMsg(msg_t& src){
+    mlist.push_back(src);
+    if(mlist.size()>maxlength){
+        mlist.pop_front();
+    }
+    return FUNCSUCCEED;
+}
+
+int MsgManager::size(){
+    return mlist.size();
+}

+ 33 - 0
msgManager.h

@@ -0,0 +1,33 @@
+#ifndef _MSGMANAGER_H_
+#define _MSGMANAGER_H_
+
+#include<sys/types.h>
+#include<list>
+#include<cstring>
+#include"definations.h"
+#include"usermanager.h"
+#include<cstdio>
+#include<string>
+
+using std::list;
+using std::string;
+class msg_t{
+public:
+    unsigned int ip;
+    string msg;
+};
+
+class MsgManager{
+private:
+    MsgManager()=default;
+    static MsgManager* instance;
+    list<msg_t> mlist;
+public:
+    static MsgManager* getInstance();
+    int maxlength=MSGLENGTH;
+    int PopMsg(msg_t& dst);
+    int PushMsg(msg_t& src);
+    int size();
+};
+
+#endif

+ 62 - 0
packMaker.cpp

@@ -0,0 +1,62 @@
+#include"packMaker.h"
+#include"usermanager.h"
+#include"chaos.h"
+#include"definations.h"
+#include"cstring"
+
+
+static Chaos* chaos=0;
+static UserManager* users=0;
+
+static bool needupdate=true;
+static int bufusage[PACKRINGLEN]={0};
+static char buff[PACKRINGLEN][BUFFLEN]={0};
+static int buflength[PACKRINGLEN]={0};
+static int next=0;
+
+
+int mkHeartPack(char dst[],int magic){
+	if(chaos==0){
+		chaos=Chaos::getInstance();
+		users=UserManager::getInstance();
+	}
+	int cur=next;
+	int len=0;
+	next++;
+	next=next<PACKRINGLEN?next:0;
+	len=mkHeader(buff[cur],magic);
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.usrname)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.grpname)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.macaddr)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.space01)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.phone)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.mail)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.printer)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.space02)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.ipaddr)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.space03)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.icon)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.netstatus)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.sign)+1;
+	len+=sprintf(buff[cur]+len,"%s",users->myinfo.computername);
+	buflength[cur]=len;
+	bufusage[cur]=magic;
+	memcpy(dst,buff[cur],buflength[cur]);
+	return buflength[cur];
+}
+
+int mkHeader(char dst[],int magic,unsigned* rtnPackNum){
+	if(chaos==0){
+		chaos=Chaos::getInstance();
+		users=UserManager::getInstance();
+	}
+	unsigned packNum=(chaos->packNum)++;
+	int len=sprintf(dst,"%s:%u:%s:%s:%u:",vermagic,
+			packNum,users->myinfo.sysusrname,
+			users->myinfo.computername,magic);
+	if(rtnPackNum!=NULL){
+		*rtnPackNum=packNum;
+	}
+	return len;
+}
+

+ 8 - 0
packMaker.h

@@ -0,0 +1,8 @@
+#ifndef __PACKMAKER_H_
+#define __PACKMAKER_H_
+
+int mkHeartPack(char dst[],int magic);
+int mkHeader(char dst[],int magic,unsigned *rtnPackNum=0);
+
+#endif
+

+ 215 - 0
tcpReceiver.cpp

@@ -0,0 +1,215 @@
+#include"tcpReceiver.h"
+#include"usermanager.h"
+#include"fileManager.h"
+#include"definations.h"
+#include"msgManager.h"
+#include"chaos.h"
+#include"include/ipmsg.h"
+#include"fixedmath.h"
+#include"packMaker.h"
+#include<pthread.h>
+#include<netinet/in.h>
+#include<sys/socket.h>
+#include<arpa/inet.h>
+#include<errno.h>
+#include<cstdio>
+#include<fcntl.h>
+#include<unistd.h>
+#include<cstdlib>
+#include<ctime>
+
+using namespace std;
+
+static Chaos* chaos=0;
+static UserManager* users=0;
+static MsgManager* msgs=0;
+static FileManager* filels=0;
+
+static char ver[40]={0};
+static char raw_pkgnum[30];
+static unsigned pkgnum;
+static char sysusrname[100]={0};
+static char computername[100]={0};
+static char raw_command[30];
+static unsigned command;
+static int optstart;
+static bool needreply=false;
+
+struct threadarg_t{
+	int sockfd;
+	unsigned clientIp;
+};
+
+void* thd_tcpReceiver(void*){
+	//init..
+	chaos=Chaos::getInstance();
+	if(unlikely(chaos==NULL)){
+		printf("\e[31mFatel error:\e[0mChaos not exist.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,chaos,errno);
+		exit(1);
+	}
+	users=UserManager::getInstance();
+	if(unlikely(users==NULL)){
+		printf("\e[31mFatel error:\e[0mUserManager not exist.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,users,errno);
+		exit(1);
+	}
+	msgs=MsgManager::getInstance();
+	if(unlikely(msgs==NULL)){
+		printf("\e[31mFatel error:\e[0mMsgManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,msgs,errno);
+	}
+	filels=FileManager::getInstance();
+	if(unlikely(filels==NULL)){
+		printf("\e[31mFatel error:\e[0mFileManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,filels,errno);
+	}
+
+	struct sockaddr_in s_addr;
+	struct sockaddr_in c_addr;
+	int sock;
+	socklen_t addr_len;
+	int len;
+	char buff[BUFFLEN];
+
+	sock = socket(AF_INET, SOCK_STREAM,0);
+
+	int flags = fcntl(sock, F_GETFL, 0);
+    fcntl(sock, F_SETFL, flags | O_NONBLOCK);
+
+	if(unlikely(sock==-1)){
+		printf("\e[31mFatel error:\e[0mTCP init error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,sock,errno);
+		exit(1);
+	}
+	memset(&s_addr,0,sizeof(struct sockaddr_in));
+	s_addr.sin_family = AF_INET;
+	s_addr.sin_port = htons(PORT);
+	s_addr.sin_addr.s_addr=INADDR_ANY;
+
+	int funcAns = bind(sock,(struct sockaddr*)&s_addr,sizeof(s_addr));
+	if(unlikely(funcAns==-1)){
+		printf("\e[31mFatel error:\e[0mTCP init error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,funcAns,errno);
+		exit(1);
+	}
+	int listen_sock=listen(sock,10);
+	if(unlikely(listen_sock==-1)){
+		printf("\e[31mFatel error:\e[0mTCP init error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,listen_sock,errno);
+	}
+	addr_len=sizeof(c_addr);
+
+	chaos->tcpListen=true;
+	pthread_t tcpinstance;
+	int tcpthdfd;
+	while(chaos->programOK){
+		int accept_fd=accept(sock,(struct sockaddr*)&c_addr,&addr_len);
+		if(accept_fd==-1){
+			sleep(1);
+			continue;
+		}
+		threadarg_t *arg=(threadarg_t *)malloc(sizeof(threadarg_t));
+		arg->clientIp=c_addr.sin_addr.s_addr;
+		arg->sockfd=accept_fd;
+		tcpthdfd=pthread_create(&tcpinstance,NULL,tcp_inst,(void *)arg);
+		pthread_detach(tcpinstance);
+	}
+
+	close(sock);
+	return 0;
+}
+
+void *tcp_inst(void* arg){
+	int sockfd=((threadarg_t*)arg)->sockfd;
+	int clientIp=((threadarg_t*)arg)->clientIp;
+	free(arg);
+
+	char ver[40]={0};
+	char raw_pkgnum[30];
+	unsigned pkgnum;
+	char sysusrname[100]={0};
+	char computername[100]={0};
+	char raw_command[30];
+	unsigned command;
+	int optstart;
+
+	char recvbuff[BUFFLEN];
+	int recvlen=recv(sockfd,recvbuff,sizeof(recvbuff),0);
+	if(unlikely(recvlen<0)){
+		dpf("tcp recv error,%d\n",errno);
+		close(sockfd);
+		return 0;
+	}
+
+	recvbuff[recvlen]=0;
+	ver[0]=raw_pkgnum[0]=sysusrname[0]=computername[0]=raw_command[0]=0;
+
+	sscanf(recvbuff,"%[0-9a-zA-Z.]:%[0-9]:%[^:]:%[^:]:%[0-9]:%n",
+			   ver,raw_pkgnum,sysusrname,computername,raw_command,&optstart);
+	if((ver[0]==0)||(raw_pkgnum[0]==0)||(sysusrname[0]==0)||
+			(computername[0]==0)||(raw_command[0]==0)){
+		dpf("\e[33mtcppack error:not a pack\e[0m\n");
+	}
+	command=u32atoi(raw_command);
+	if((command&IPMSG_GETFILEDATA)==IPMSG_GETFILEDATA){
+		unsigned fileno;
+		int optsplit=0;
+		sscanf(recvbuff+optstart+optsplit,"%x%n",&fileno,&optsplit);
+		optsplit++;
+		sscanf(recvbuff+optstart+optsplit,"%x",&fileno);
+
+		if((command==IPMSG_GETFILEDATA)){
+			sendfile_t tmpsendfile;
+			int findans=filels->Findsend(fileno,clientIp,tmpsendfile);
+			if(findans==FUNCSUCCEED){
+				char *filebuff=(char *)malloc(tmpsendfile.filesize);
+
+				//FILE* fp=fopen(tmpsendfile.filelocate.c_str(),"rb");
+				int fd = open(tmpsendfile.filelocate.c_str(), O_RDONLY);
+				//if(fp!=NULL){
+				if (fd != -1){
+					//fread(filebuff,tmpsendfile.filesize,1,fp);
+					int len;
+					while ((len = read(fd, filebuff, tmpsendfile.filesize)) > 0){
+						//send(sockfd,filebuff,sizeof(tmpsendfile.filesize),0);
+						write(sockfd, filebuff, len);
+					}
+					close(fd);
+				}else{
+					dpf("\e[33mSendfile failed,file %s open failed:%d.\e[0m\n",tmpsendfile.filelocate.c_str(),errno);
+				}
+				free(filebuff);
+				filels->Delsend(fileno,clientIp);
+			}else{
+				dpf("\e[33mSendfile failed,file %ld for %lx not exist.\e[0m\n",fileno,clientIp);
+			}
+		}else if((command&IPMSG_FILE_DIR)==IPMSG_FILE_DIR){
+			sendfile_t tmpsendfile;
+			int findans=filels->Findsend(fileno,clientIp,tmpsendfile);
+			if(findans==FUNCSUCCEED){
+				char sendbuff[BUFFLEN];
+				int bufheadlen;
+				char array_bufheadlen[10];
+				sprintf(sendbuff,"0000:%s:%u:%d:14=%lx:16=%lx%n",tmpsendfile.filename,tmpsendfile.filesize,tmpsendfile.filetype,time(NULL),time(NULL),&bufheadlen);
+				sprintf(array_bufheadlen,"%04x",bufheadlen);
+				memcpy(sendbuff,array_bufheadlen,4);
+				send(sockfd,sendbuff,sizeof(sendbuff),0);
+
+				filels->Delsend(fileno,clientIp);
+			}else{
+				dpf("\e[33mSendfile failed,file %ld for %lx not exist.\e[0m\n",fileno,clientIp);
+			}
+
+		}else{
+			dpf("\e[33munknown recv command,%d\e[0m\n",command);
+		}
+	}else{
+		dpf("\e[33munknown tcp command,%d\e[0m\n",command);
+	}
+
+	close(sockfd);
+	return 0;
+
+
+}

+ 6 - 0
tcpReceiver.h

@@ -0,0 +1,6 @@
+#ifndef _TCPRECEIVER_H_
+#define _TCPRECEIVER_H_
+
+void *thd_tcpReceiver(void*);
+void *tcp_inst(void* arg);
+#endif

+ 257 - 0
udpReceiver.cpp

@@ -0,0 +1,257 @@
+#include"udpReceiver.h"
+#include"usermanager.h"
+#include"msgManager.h"
+#include"fileManager.h"
+#include"definations.h"
+#include"chaos.h"
+#include"include/ipmsg.h"
+#include"fixedmath.h"
+#include"packMaker.h"
+#include<sys/types.h>
+#include<netinet/in.h>
+#include<sys/socket.h>
+#include<arpa/inet.h>
+#include<errno.h>
+#include<cstdio>
+#include<unistd.h>
+#include<cstring>
+#include<cstdlib>
+
+static Chaos* chaos=0;
+static UserManager* users=0;
+static MsgManager* msgs=0;
+static FileManager* filels=0;
+
+static char ver[40]={0};
+static char raw_pkgnum[30];
+static unsigned pkgnum;
+static char sysusrname[100]={0};
+static char computername[100]={0};
+static char raw_command[30];
+static unsigned command;
+static int optstart;
+static user_t tmpusr;
+static char *(dest[15])={
+	tmpusr.usrname,
+	tmpusr.grpname,
+	tmpusr.macaddr,
+	tmpusr.space01,
+	tmpusr.phone,
+	tmpusr.mail,
+	tmpusr.printer,
+	tmpusr.space02,
+	tmpusr.ipaddr,
+	tmpusr.space03,
+	tmpusr.icon,
+	tmpusr.netstatus,
+	tmpusr.sign,
+};
+static bool needreply=false;
+
+void* thd_udpReceiver(void*){
+	//init..
+	chaos=Chaos::getInstance();
+	if(unlikely(chaos==NULL)){
+		printf("\e[31mFatel error:\e[0mChaos not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,chaos,errno);
+		exit(1);
+	}
+	users=UserManager::getInstance();
+	if(unlikely(users==NULL)){
+		printf("\e[31mFatel error:\e[0mUserManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,users,errno);
+		exit(1);
+	}
+	msgs=MsgManager::getInstance();
+	if(unlikely(msgs==NULL)){
+		printf("\e[31mFatel error:\e[0mMsgManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,msgs,errno);
+	}
+	filels=FileManager::getInstance();
+	if(unlikely(filels==NULL)){
+		printf("\e[31mFatel error:\e[0mFileManager not exist.\n");
+		dpf("%s,%d,%p,%d\n",__FILE__,__LINE__,filels,errno);
+	}
+
+	struct sockaddr_in s_addr;
+	struct sockaddr_in c_addr;
+	int sock;
+	socklen_t addr_len;
+	int len;
+	char buff[BUFFLEN];
+	sock=socket(AF_INET,SOCK_DGRAM,0);
+	int opt=1;
+	setsockopt(sock,SOL_SOCKET,SO_BROADCAST,(char*)&opt,sizeof(opt));
+
+	if(unlikely(sock==-1)){
+		printf("\e[31mFatel error:\e[0mUDP init error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,sock,errno);
+		exit(1);
+	}
+	memset(&s_addr,0,sizeof(struct sockaddr_in));
+	s_addr.sin_family = AF_INET;
+	s_addr.sin_port = htons(PORT);
+	s_addr.sin_addr.s_addr=INADDR_ANY;
+
+	int funcAns = bind(sock,(struct sockaddr*)&s_addr,sizeof(s_addr));
+	if(unlikely(funcAns==-1)){
+		printf("\e[31mFatel error:\e[0mUDP init error.\n");
+		dpf("%s,%d,%d,%d\n",__FILE__,__LINE__,funcAns,errno);
+		exit(1);
+	}
+	addr_len=sizeof(c_addr);
+	chaos->udpsocket=sock;
+	chaos->udpListen=true;
+
+	while(chaos->programOK){
+		len=recvfrom(sock,buff,sizeof(buff)-1,0,(struct sockaddr*)&c_addr,&addr_len);
+		if(unlikely(len<0)){
+			dpf("recvfrom error,%d\n",errno);
+			sleep(1);
+			continue;
+		}
+		buff[len]=0;
+		dpf("%s\n",buff);
+		ver[0]=raw_pkgnum[0]=sysusrname[0]=computername[0]=raw_command[0]=0;
+		sscanf(buff,"%[0-9a-zA-Z.]:%[0-9]:%[^:]:%[^:]:%[0-9]:%n",
+			   ver,raw_pkgnum,sysusrname,computername,raw_command,&optstart);
+		if((ver[0]==0)||(raw_pkgnum[0]==0)||(sysusrname[0]==0)||
+				(computername[0]==0)||(raw_command[0]==0)){
+			dpf("\e[33munpack error:not a pack\e[0m\n");
+			continue;
+		}
+		command=u32atoi(raw_command);
+		dpf("mode:%lx\n",GET_MODE(command));
+		switch(GET_MODE(command)){
+			case IPMSG_BR_ENTRY:
+				needreply=true;
+			case IPMSG_ANSENTRY:{
+				//USR LIST UPDATE
+				tmpusr.ip.sin_addr.s_addr=c_addr.sin_addr.s_addr;
+				strcpy(tmpusr.sysusrname,sysusrname);
+				strcpy(tmpusr.computername,computername);
+				for(int i=optstart,cnt=0,sz=0;i<=len;i++){
+					if(buff[i])dest[cnt][sz++]=buff[i];
+					else{
+						dest[cnt][sz++]=0;
+						cnt++;
+						if(cnt>12)break;
+						sz=0;
+					}
+				}
+				tmpusr.healthy=true;
+				int ans=users->Adduser(tmpusr);
+				if(ans==FUNCSUCCEED){
+				}
+				if(needreply){
+					char buff[BUFFLEN];
+					int len=0;
+					len=mkHeartPack(buff,IPMSG_ANSENTRY);
+					sendto(sock,buff,len,0,(struct sockaddr*)&c_addr,addr_len);
+				}
+				dpf("ans entry done\n");
+				break;
+			}
+			case IPMSG_BR_EXIT:{
+				//USR LIST DELETE
+				int ans=users->Deluser(c_addr);
+				if(ans==FUNCSUCCEED){
+				}
+				break;
+			}
+			case IPMSG_SENDMSG:{
+				if((GET_OPT(command)&IPMSG_FILEATTACHOPT)==IPMSG_FILEATTACHOPT){
+					recvfile_t tmprecvf;
+					char tmpstr[512];
+					tmprecvf.tarIp=c_addr.sin_addr.s_addr;
+					sscanf(buff+optstart+1,"%u:%[^:]:%x:%u:%u",&(tmprecvf.fileno),tmpstr,
+						&(tmprecvf.filesize),&(tmprecvf.time),&(tmprecvf.filetype));
+					tmprecvf.filename=tmpstr;
+					tmprecvf.fileno;
+					filels->Addrecv(tmprecvf);
+				}else{
+					msg_t tmpmsg;
+					tmpmsg.ip=c_addr.sin_addr.s_addr;
+					strrchr(buff,'[')[0]=0;
+					strrchr(buff,'[')[0]=0;
+					tmpmsg.msg=buff+optstart;
+					msgs->PushMsg(tmpmsg);
+				}
+
+				if(GET_OPT(command)|IPMSG_SENDCHECKOPT){
+					char rtnbuff[BUFFLEN];
+					int rtnlen=0;
+					rtnlen=mkHeader(rtnbuff,IPMSG_RECVMSG);
+					rtnlen+=sprintf(rtnbuff+rtnlen,"%s",raw_pkgnum);
+					sendto(sock,rtnbuff,rtnlen,0,(struct sockaddr*)&c_addr,addr_len);
+				}
+				break;
+			}
+			case IPMSG_EX_CHATREADY:{
+				char sendbuff[BUFFLEN];
+				int sendlen=0;
+				sendlen=mkHeader(sendbuff,IPMSG_RECVMSG);
+				sendlen+=sprintf(sendbuff+sendlen,"%s",raw_pkgnum);
+				sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+				if(buff[optstart]=='6'){
+					sendlen=mkHeader(sendbuff,IPMSG_EX_CHATREADY);
+					sendlen+=sprintf(sendbuff+sendlen,"5")+1;
+					sendlen+=sprintf(sendbuff+sendlen,"1")+1;
+					sendlen+=sprintf(sendbuff+sendlen,"123");
+					sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+				}else if(buff[optstart]=='5'){
+					user_t tmp;
+					int findans=users->Finduser(tmp,c_addr);
+					if(findans==FUNCSUCCEED){
+						sendlen=mkHeader(sendbuff,IPMSG_EX_CHATCHECKMAC);
+						sendlen+=sprintf(sendbuff+sendlen,"%s",tmp.macaddr);
+						sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+					}
+				}
+				break;
+			}
+			case IPMSG_EX_CHATCHECKMAC:{
+				char sendbuff[BUFFLEN];
+				int sendlen=0;
+				sendlen=mkHeader(sendbuff,IPMSG_RECVMSG);
+				sendlen+=sprintf(sendbuff+sendlen,"%s",raw_pkgnum);
+				sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+				break;
+			}
+			case IPMSG_EX_REFUSEFILE:{
+				unsigned tmpfno;
+				int optsplit=0;
+				sscanf(buff+optstart+optsplit,"%x%n",&tmpfno,&optsplit);
+				optsplit++;
+				sscanf(buff+optstart+optsplit,"%x",&tmpfno);
+				printf("%d",tmpfno);
+				filels->Delsend(tmpfno,c_addr.sin_addr.s_addr);
+				break;
+			}
+			case IPMSG_EX_CANCELFILE:{
+				unsigned tmpfno;
+				int optsplit=0;
+				sscanf(buff+optstart+optsplit,"%x%n",&tmpfno,&optsplit);
+				optsplit++;
+				sscanf(buff+optstart+optsplit,"%x",&tmpfno);
+				filels->Delrecv(tmpfno,c_addr.sin_addr.s_addr);
+				break;
+			}
+			case IPMSG_EX_PREGETFILE:{
+				unsigned sendlen;
+				char sendbuff[BUFFLEN];
+				sendlen=mkHeader(sendbuff,IPMSG_SENDMSG);
+				sendlen+=sprintf(sendbuff+sendlen,"Unsupported function!")+1;
+				sendlen+=sprintf(sendbuff+sendlen,"%s",fontmagic);
+				sendto(sock,sendbuff,sendlen,0,(struct sockaddr*)&c_addr,addr_len);
+				break;
+			}
+			default:
+				dpf("\e[36mUnset command:%X\e[0m\n",command);
+			break;
+		}
+		needreply=false;
+
+	}
+
+}

+ 8 - 0
udpReceiver.h

@@ -0,0 +1,8 @@
+#ifndef __UDPRECEIVER_H_
+#define __UDPRECEIVER_H_
+
+void* thd_udpReceiver(void*);
+
+
+
+#endif

+ 168 - 0
usermanager.cpp

@@ -0,0 +1,168 @@
+#include"usermanager.h"
+#include"definations.h"
+#include<netinet/in.h>
+#include<list>
+#include<pthread.h>
+#include<cstdlib>
+#include<cstring>
+
+user_t::user_t(const user_t& src){
+	(*this)=src;
+}
+#define simplyCopy(x) x = src.x
+#define deepCopy(x) memcpy( x , src.x ,sizeof( x ))
+user_t& user_t::operator=(const user_t& src){
+	simplyCopy(ip.sin_family);
+	simplyCopy(ip.sin_port);
+	simplyCopy(ip.sin_addr.s_addr);
+	deepCopy(sysusrname);
+	deepCopy(computername);
+	deepCopy(usrname);
+	deepCopy(grpname);
+	deepCopy(macaddr);
+	deepCopy(space01);
+	deepCopy(phone);
+	deepCopy(mail);
+	deepCopy(printer);
+	deepCopy(space02);
+	deepCopy(ipaddr);
+	deepCopy(space03);
+	deepCopy(icon);
+	deepCopy(netstatus);
+	deepCopy(sign);
+	simplyCopy(healthy);
+	return(*this);
+}
+#undef simplyCopy
+#undef deepCopy
+
+static pthread_mutex_t userAddLock;
+static pthread_mutex_t userScanLock;
+static pthread_mutex_t userCopyLock;
+UserManager* UserManager::instance = new UserManager();
+UserManager* UserManager::getInstance(){
+	static bool flgfirst=true;
+	if(flgfirst){			//2-step init
+		flgfirst=!flgfirst;
+		pthread_mutex_init(&userAddLock,NULL);
+		pthread_mutex_init(&userScanLock,NULL);
+		pthread_mutex_init(&userCopyLock,NULL);
+	}
+	return instance;
+}
+
+#define check_replace(x) do{		\
+	if(strcmp(tar.x , i->x)!=0){	\
+		fixed=true;					\
+		strcpy(i->x , tar.x);		\
+	}}while(0)
+int UserManager::Adduser(user_t& tar){
+	bool nofound=true;
+	pthread_mutex_lock(&userAddLock);
+	auto i=ulist.begin();
+	auto z=ulist.end();
+	for(;i!=z;i++){
+		if(i->ip.sin_addr.s_addr==tar.ip.sin_addr.s_addr){
+			nofound=false;
+			break;
+		}
+	}
+	if(nofound){
+		pthread_mutex_unlock(&userAddLock);
+		ulist.push_back(tar);
+		return FUNCSUCCEED;
+	}else{
+		bool fixed=false;
+		check_replace(sysusrname);
+		check_replace(computername);
+		check_replace(usrname);
+		check_replace(grpname);
+		check_replace(macaddr);
+		check_replace(space01);
+		check_replace(phone);
+		check_replace(mail);
+		check_replace(printer);
+		check_replace(space02);
+		check_replace(ipaddr);
+		check_replace(space03);
+		check_replace(icon);
+		check_replace(netstatus);
+		check_replace(sign);
+		i->healthy=true;
+		pthread_mutex_unlock(&userAddLock);
+		if(fixed){
+			return FUNCSUCCEED;
+		}else{
+			return FUNCFAILED;
+		}
+	}
+}
+#undef check_replace
+
+int UserManager::Deluser(struct sockaddr_in tar){
+	pthread_mutex_lock(&userAddLock);
+	pthread_mutex_lock(&userScanLock);
+	pthread_mutex_lock(&userCopyLock);
+	bool nofound=true;
+	auto i=ulist.begin();
+	auto z=ulist.end();
+	for(;i!=z;i++){
+		if(i->ip.sin_addr.s_addr==tar.sin_addr.s_addr){
+			nofound=false;
+			break;
+		}
+	}
+	if(nofound==false){
+		i=ulist.erase(i);
+	}
+	pthread_mutex_unlock(&userAddLock);
+	pthread_mutex_unlock(&userScanLock);
+	pthread_mutex_unlock(&userCopyLock);
+	if(nofound==false){
+		return FUNCSUCCEED;
+	}else{
+		return FUNCFAILED;
+	}
+}
+
+int UserManager::Finduser(user_t &tar,const struct sockaddr_in src){
+	return Finduser(tar,src.sin_addr.s_addr);
+}
+
+int UserManager::Finduser(user_t&tar ,unsigned int src){
+	pthread_mutex_lock(&userScanLock);
+	bool nofound=true;
+	auto i=ulist.begin();
+	auto z=ulist.end();
+	for(;i!=z;i++){
+		if(i->ip.sin_addr.s_addr==src){
+			nofound=false;
+			tar=*i;
+			break;
+		}
+	}
+	pthread_mutex_unlock(&userScanLock);
+	if(nofound==false){
+		return FUNCSUCCEED;
+	}else{
+		return FUNCFAILED;
+	}
+}
+
+int UserManager::GetUserCopy(list<user_t>&src){
+	pthread_mutex_lock(&userCopyLock);
+	std::copy(ulist.begin(),ulist.end(),std::back_inserter(src));
+	pthread_mutex_unlock(&userCopyLock);
+	return FUNCSUCCEED;
+}
+
+int UserManager::UserIllness(void){
+	pthread_mutex_lock(&userCopyLock);
+	auto i=ulist.begin();
+	auto z=ulist.end();
+	for(;i!=z;i++){
+		i->healthy=false;
+	}
+	pthread_mutex_unlock(&userCopyLock);
+	return FUNCSUCCEED;
+}

+ 66 - 0
usermanager.h

@@ -0,0 +1,66 @@
+#ifndef __USERMANAGER_H_
+#define __USERMANAGER_H_
+#include<sys/types.h>
+#include<sys/socket.h>
+#include<list>
+#include<vector>
+#include<cstring>
+#include"definations.h"
+#include<netinet/in.h>
+#include<cstdio>
+using std::list;
+class user_t{
+public:
+//id
+    struct sockaddr_in ip;
+//information
+	char sysusrname[100];
+	char computername[100];
+	char usrname[100];
+	char grpname[100];
+	char macaddr[20];
+	char space01[10];//
+	char phone[20];
+	char mail[100];
+	char printer[200];
+	char space02[10];//
+	char ipaddr[20];
+	char space03[10];//
+	char icon[10];
+	char netstatus[10];
+	char sign[1000];
+	bool healthy;
+	user_t()=default;
+	user_t(const struct sockaddr_in sai,const char* sname,
+	const char* cname,const char*str){
+		ip=sai;
+		strcpy(sysusrname,sname);
+		strcpy(computername,cname);
+		sscanf(str,"%s%s%s%s%s%s%s%s%s%s%s%s%s",
+				usrname,grpname,macaddr,space01,phone,mail,printer,
+				space02,ipaddr,space03,icon,netstatus,sign);
+	}
+	user_t(const user_t& src);
+	user_t& operator=(const user_t& src);
+};
+
+class UserManager{
+private:
+	UserManager()=default;
+	static UserManager* instance;
+	list<user_t> ulist;
+
+public:
+	user_t myinfo;
+	static UserManager* getInstance();
+
+	int	Adduser(user_t& tar);
+	int Deluser(struct sockaddr_in tar);
+	int Finduser(user_t& tar,const struct sockaddr_in src);
+	int Finduser(user_t& tar,unsigned int src);
+	int GetUserCopy(list<user_t>& src);
+	int UserIllness(void);
+};
+
+#endif
+