#ifndef HEAD_H_
#define HEAD_H_
#include <stdio.h>
#include <sqlite3.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <pthread.h>
#include <semaphore.h>
#include <termios.h>
#include <time.h>
#include <sys/stat.h>
#include <fcntl.h>
#define PORT 888
/****************注册******************/
#define reg 1
#define reg_success 2
#define reg_failure 3
/***************注册*******************/
/***************登录*******************/
#define enter 4
#define log_success 5
#define log_failure 6
/****************登录******************/
/***************忘记密码**************/
#define forget 7
/***************忘记密码***************/
/**************普通用户功能**************/
#define private_chat 8
#define group_chat 9
#define online 10
#define face 11
#define expression 12
#define chat_record 13
/***************普通用户功能**************/
/**************管理员功能****************/
#define ban 14
#define lift 15
#define kick 16
/***************管理员功能*************/
/***************功能返回结果*************/
#define send_success 17
#define send_failure 18
#define ban_success 19
#define ban_failure 20
#define lift_success 21
#define lift_failure 22
#define kick_success 23
#define kick_failure 24
/****************功能返回结果************/
/*****************公用功能******************/
#define quit 25
/*****************公用功能******************/
/****************遗漏的**********************/
#define open_success 26
#define open_failure 27
#define delete_success 28
#define delete_failure 29
#define client_private 30
#define client_group 31
#define client_face 32
#define client_expression 33
#define client_ban 34
#define client_lift 35
#define client_kick 36
#define real_quit 37
#define chat 41
/****************遗漏的***********************/
/******************链表****************/
#define SUCCESS 1000001
#define FAILURE 1000002
/*******************链表****************/
struct node1
{
int data;
char name[20];
struct node1 *next;
};
typedef struct node1 Node;
typedef Node* LinkList;
struct send
{
char name[20];
char account[20];
char password[20];
char identity[20];
char question[20];
char answer[20];
int cmd;
char message[200];
char toname[20];
int result;
};
struct recv
{
char name[20];
int result;
char question[20];
char answer[20];
char password[20];
char identity[20];
char message[200];
char fromname[20];
char recvname[20];
int time;
int number;
char onlinename[20];
int cmd;
};
LinkList list;
int flag;
int sockfd;
int ret;
sqlite3 *db;
pthread_t tid;
char sql[100] = {0};
int note;
char shut[10] = {0};
char localname[20];
struct send userinfo;
struct recv userback;
int out;
#endif
#include"HEAD.h"
void save();
void check_log();
void deal_forget();
void deal_private();
void deal_group();
void deal_online();
void deal_face();
void deal_expression();
void deal_chat_record();
void deal_exit();
void deal_ban();
void deal_lift();
void deal_kick();
void deal_chat();
void *MyRecv(void *arg);
int ListInit(LinkList *L);
int GetElem(LinkList L,char a[]);
int ListInsert(LinkList L,char a[],int b);
void ListTraverse(LinkList L);
void ListDelate(LinkList L,char a[]);
int ListInit(LinkList *L)
{
(*L) = (LinkList)malloc(sizeof(Node));
if(NULL == (*L))
{
return FAILURE;
}
(*L)->next = NULL;
return SUCCESS;
}
int ListInsert(LinkList L,char a[],int b)
{
LinkList p = L;
LinkList n = (LinkList)malloc(sizeof(Node));
if(NULL == n)
{
return FAILURE;
}
strcpy(n->name,a);
n->data = b;
n->next = p->next;
p->next = n;
return SUCCESS;
}
int GetElem(LinkList L,char a[])
{
char find[20];
strcpy(find,a);
LinkList p = L->next;
while(p)
{
if(!strcmp(p->name,find))
{
return SUCCESS;
break;
}
p = p->next;
}
return FAILURE;
}
void ListTraverse(LinkList L)
{
LinkList p = L->next;
while(p)
{
printf("%s %d \n",p->name,p->data);
p = p->next;
}
}
void ListDelete(LinkList L,char a[])
{
char find[20];
strcpy(find,a);
LinkList p = L;
LinkList tmp;
while(p)
{
if(!strcmp(p->next->name,find))
{
break;
}
p = p->next;
}
tmp = p->next;
p->next = tmp->next;
free(tmp);
}
void *MyRecv(void *arg)
{
pthread_detach(pthread_self());
int local;
local = (*(int *)arg);
int t = 1;
while(t)
{
ret = recv(local,&userinfo,sizeof(userinfo),0);
if(-1 == ret)
{
perror("recv");
exit(1);
}
switch(userinfo.cmd)
{
case reg:
{
save(db);
send(local,&userback,sizeof(userback),0);
break;
}
case enter:
{
check_log(local);
send(local,&userback,sizeof(userback),0);
break;
}
case forget:
{
deal_forget(local);
send(local,&userback,sizeof(userback),0);
break;
}
case private_chat:
{
deal_private(local);
userback.cmd = private_chat;
send(local,&userback,sizeof(userback),0);
break;
}
case group_chat:
{
deal_group(local);
userback.cmd = group_chat;
send(local,&userback,sizeof(userback),0);
break;
}
case online:
{
deal_online(local);
userback.cmd = online;
send(local,&userback,sizeof(userback),0);
break;
}
case face:
{
deal_face(local);
userback.cmd = face;
send(local,&userback,sizeof(userback),0);
break;
}
case expression:
{
deal_expression(local);
userback.cmd = expression;
send(local,&userback,sizeof(userback),0);
break;
}
case chat_record:
{
deal_chat_record(local);
userback.cmd = chat_record;
send(local,&userback,sizeof(userback),0);
break;
}
case quit:
{
deal_exit(local);
break;
}
case real_quit:
{
close(local);
t = 0;
}
case ban:
{
deal_ban(local);
userback.cmd = ban;
send(local,&userback,sizeof(userback),0);
break;
}
case lift:
{
deal_lift(local);
userback.cmd = lift;
send(local,&userback,sizeof(userback),0);
break;
}
case kick:
{
deal_kick(local);
userback.cmd = kick;
send(local,&userback,sizeof(userback),0);
break;
}
case chat:
{
deal_chat(local);
break;
}
}
}
}
void save()
{
memset(sql,0,sizeof(sql));
sprintf(sql,"insert into user values('%s','%s','%s','%s','%s','%s');",userinfo.name,userinfo.account,userinfo.password,userinfo.question,userinfo.answer,userinfo.identity);
ret = sqlite3_exec(db,sql,NULL,NULL,NULL);
if(ret != SQLITE_OK)
{
userback.result = reg_failure;
}
else
{
userback.result = reg_success;
}
}
void check_log(int local)
{
memset(&userback,0,sizeof(userback));
char **check;
int row;
int column;
memset(sql,0,sizeof(sql));
sprintf(sql,"select name,account,password,identity from user where account = '%s' and password = '%s';",userinfo.account,userinfo.password);
ret = sqlite3_get_table(db,sql,&check,&row,&column,NULL);
if(ret != SQLITE_OK)
{
perror("sqlite3_get_table");
}
if(row == 1)
{
ret = GetElem(list,check[4]);
if(ret == FAILURE)
{
userback.result = log_success;
ListInsert(list,check[4],local);
ListTraverse(list);
printf("#############################\n");
strcpy(userback.name,check[4]);
strcpy(userback.identity,check[7]);
}
else
{
userback.result = log_failure;
}
}
else
{
userback.result = log_failure;
}
sqlite3_free_table(check);
}
void deal_forget(int local)
{
memset(sql,0,sizeof(sql));
int row,column;
char **check;
sprintf(sql,"select password,question,answer from user where account = '%s';",userinfo.account);
ret = sqlite3_get_table(db,sql,&check,&row,&column,NULL);
if(ret != SQLITE_OK)
{
perror("deal_forget");
}
strcpy(userback.password,check[3]);
strcpy(userback.question,check[4]);
strcpy(userback.answer,check[5]);
}
void deal_private(int local)
{
int fd;
LinkList p = list->next;
while(p)
{
if(strcmp(p->name,userinfo.toname) == 0)
{
fd = p->data;
userback.cmd = client_private;
strcpy(userback.fromname,userinfo.name);
send(fd,&userback,sizeof(userback),0);
memset(&userback,0,sizeof(userback));
userback.result = send_success;
break;
}
p = p->next;
}
if(p == NULL)
{
userback.result = send_failure;
}
}
void deal_chat()
{
int fd;
int file;
LinkList p = list->next;
while(p)
{
if(!strcmp(p->name,userinfo.toname))
{
fd = p->data;
memset(&userback,0,sizeof(userback));
userback.cmd = chat;
strcpy(userback.fromname,userinfo.name);
strcpy(userback.message,userinfo.message);
send(fd,&userback,sizeof(userback),0);
memset(sql,0,sizeof(sql));
sprintf(sql,"%sand%s.txt",userinfo.name,userinfo.toname);
file = open(sql,O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
memset(sql,0,sizeof(sql));
sprintf(sql,"%s :%s\n",userinfo.name,userinfo.message);
write(file,sql,strlen(sql));
close(file);
memset(sql,0,sizeof(sql));
sprintf(sql,"%sand%s.txt",userinfo.toname,userinfo.name);
file = open(sql,O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
memset(sql,0,sizeof(sql));
sprintf(sql,"%s :%s\n",userinfo.name,userinfo.message);
write(file,sql,strlen(sql));
close(file);
break;
}
p = p->next;
}
}
void deal_group(int local)
{
int fd;
LinkList p = list->next;
while(p)
{
if(p->data != local)
{
fd = p->data;
userback.cmd = client_group;
strcpy(userback.fromname,userinfo.account);
strcpy(userback.message,userinfo.message);
send(fd,&userback,sizeof(userback),0);
memset(&userback,0,sizeof(userback));
strcpy(userback.recvname,p->name);
userback.cmd = group_chat;
userback.result = send_success;
userback.time = 1;
send(local,&userback,sizeof(userback),0);
}
p = p->next;
}
userback.time = 0;
}
void deal_online(int local)
{
int length = 0;
LinkList p = list->next;
while(p)
{
length++;
userback.cmd = online;
strcpy(userback.onlinename,p->name);
userback.time = 1;
send(local,&userback,sizeof(userback),0);
p = p->next;
}
userback.time = 0;
userback.number = length;
}
void deal_face(int local)
{
int fd;
LinkList p = list->next;
while(p)
{
if(!strcmp(p->name,userinfo.toname))
{
fd = p->data;
userback.cmd = client_face;
strcpy(userback.fromname,userinfo.account);
strcpy(userback.message,userinfo.message);
send(fd,&userback,sizeof(userback),0);
memset(&userback,0,sizeof(userback));
userback.cmd = face;
userback.result = send_success;
break;
}
p = p->next;
}
if(NULL == p)
{
userback.result = send_failure;
}
}
void deal_expression(int local)
{
int fd;
LinkList p = list->next;
while(p)
{
if(strcmp(p->name,userinfo.toname) == 0)
{
fd = p->data;
userback.cmd = client_expression;
strcpy(userback.fromname,userinfo.account);
strcpy(userback.message,userinfo.message);
send(fd,&userback,sizeof(userback),0);
memset(&userback,0,sizeof(userback));
userback.result = send_success;
break;
}
p = p->next;
}
if(NULL == p)
{
userback.result = send_failure;
}
}
void deal_chat_record(int local)
{
int fd;
memset(sql,0,sizeof(sql));
sprintf(sql,"%sand%s.txt",userinfo.account,userinfo.toname);
fd = open(sql,O_RDONLY);
if(-1 == fd)
{
userback.result = open_failure;
}
else
{
userback.result = open_success;
memset(sql,0,sizeof(sql));
read(fd,sql,sizeof(sql));
strcpy(userback.message,sql);
}
}
void deal_exit(int local)
{
ListDelete(list,userinfo.name);
}
void deal_ban(int local)
{
int fd;
LinkList p = list->next;
while(p)
{
if(strcmp(p->name,userinfo.toname) == 0)
{
fd = p->data;
userback.cmd = client_ban;
send(fd,&userback,sizeof(userback),0);
memset(&userback,0,sizeof(userback));
userback.result = ban_success;
break;
}
p = p->next;
}
if(NULL == p)
{
userback.result = ban_failure;
}
}
void deal_lift(int local)
{
int fd;
LinkList p = list->next;
while(p)
{
if(strcmp(p->name,userinfo.toname) == 0)
{
fd = p->data;
userback.cmd = client_lift;
send(fd,&userback,sizeof(userback),0);
memset(&userback,0,sizeof(userback));
userback.result = lift_success;
break;
}
p = p->next;
}
if(NULL == p)
{
userback.result = lift_failure;
}
}
void deal_kick(local)
{
int fd;
LinkList p = list->next;
while(p)
{
if(strcmp(p->name,userinfo.toname) == 0)
{
fd = p->data;
ListDelete(list,userinfo.toname);
userback.cmd = client_kick;
send(fd,&userback,sizeof(userback),0);
memset(&userback,0,sizeof(userback));
userback.result = kick_success;
break;
}
p = p->next;
}
if(NULL == p)
{
userback.result = kick_failure;
}
}
int main()
{
ret = ListInit(&list);
if(FAILURE == ret)
{
printf("List Init Failure!\n");
}
else
{
printf("List Init Success!\n");
}
ret = sqlite3_open("user.db",&db);
if(ret != SQLITE_OK)
{
perror("sqlite3_open");
exit(1);
}
memset(sql,0,sizeof(sql));
sprintf(sql,"create table if not exists user(name text,account text,password text,question text,answer text,identity text,primary key(account));");
ret = sqlite3_exec(db,sql,NULL,NULL,NULL);
if(ret != SQLITE_OK)
{
perror("sqlite3_create");
exit(1);
}
memset(sql,0,sizeof(sql));
int fd[100] = {0};
int length;
int i = 0;
struct sockaddr_in server_addr;
struct sockaddr_in client_addr;
pthread_t tid[100] = {0};
printf("Start Server ....\n");
sockfd = socket(PF_INET,SOCK_STREAM,0);
if(-1 == sockfd)
{
perror("socket");
exit(1);
}
int opt = 1;
setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
memset(&server_addr,0,sizeof(server_addr));
server_addr.sin_family = PF_INET;
server_addr.sin_port = PORT;
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
ret = bind(sockfd,(struct sockaddr *)&server_addr,sizeof(server_addr));
if(-1 == ret)
{
perror("bind");
exit(1);
}
printf("Listen ...\n");
ret = listen(sockfd,5);
if(-1 == ret)
{
perror("listen");
exit(1);
}
while(1)
{
length = sizeof(client_addr);
fd[i] = accept(sockfd,(struct sockaddr *)&client_addr,&length);
if(-1 == fd[i])
{
perror("accept");
exit(1);
}
printf("Accept %d \n",fd[i]);
ret = pthread_create(&tid[i],NULL,MyRecv,(void *)&fd[i]);
if(ret != 0)
{
perror("pthread_create");
exit(1);
}
i++;
}
close(sockfd);
sqlite3_close(db);
return 0;
}