- Etablissement de connexion
Les commandes décrites dans cette section sont utilisées pour établir une connexion d’un
client avec un serveur.
- Message USER
Commande: USER
Paramètres: <nom d'utilisateur> <nom réel>
Le message USER est utilisé au début d'une connexion pour spécifier le nom d'utilisateur, le
véritable nom d'un nouvel client. C'est seulement après avoir envoyé le USER et le NICK
qu'un utilisateur devient enregistré.
Notez aussi que le paramètre 'vrai nom' doit être le dernier paramètre, car il peut contenir des
espaces, et il doit être préfixé par deux points (':') de façon à être reconnu comme tel.
Réponses numériques :
ERR_NEEDMOREPARAMS : besoin de plus de paramètres.
ERR_ALREADYREGISTRED : utilisateur déjà enregistré.
Exemple:
USER guest :Ronnie Reagan ; Utilisateur s'enregistrant avec un nom d'utilisateur de
"guest" un vrai nom de "Ronnie Reagan".
- Message NICK
Commande : NICK
Paramètres : <pseudonyme>
Le message NICK est utilisé pour donner un pseudonyme à un utilisateur, ou pour changer le
pseudonyme précédent. Ce message n’est pris en compte que lorsqu’une connexion au serveur
est déjà établie grâce à la commande USER.
Si un message NICK arrive à un serveur qui connaît déjà un autre client de pseudo identique,
une collision de pseudonymes a lieu. Si le message NICK à l'origine de la collision de
pseudonymes est un changement de pseudonyme, alors le pseudo originel (l'ancien) doit aussi
être retiré, dans le cas contraire, le serveur ignore la commande NICK.
Réponses numériques :
ERR_NONICKNAMEGIVEN : pseudonyme non spécifié dans la commande.
ERR_NICKNAMEINUSE : pseudonyme en cours d’utilisation par un autre
utilisateur.
Exemple:
NICK Wiz ; Ajout d'un nouveau pseudo "Wiz".
- Message QUIT
Commande: QUIT
Paramètres: [<Message de départ >]
Une session de client se termine par un message QUIT. Le serveur doit rompre la connexion
avec le client qui envoie un message QUIT. Si un <Message de départ> est fourni, il sera
transmis au lieu du message par défaut, le pseudonyme.
Si pour une autre raison, une connexion d'un client est fermée sans que le client ait envoyé de
message QUIT (par exemple, le programme client se termine), le serveur doit remplir le
message QUIT avec un message reflétant la nature de l'événement à la cause de cette
déconnexion.
Exemple:
QUIT :Parti déjeuner ; Format de message préféré.
- Opérations sur les canaux
Ce groupe de messages s'intéresse à la manipulation de canaux, à leurs propriétés (mode des
canaux), et à leur contenu (typiquement des clients).
- Le message JOIN
Commande: JOIN
Paramètres: <canal>{,<canal>}*
La commande JOIN est utilisée par un client pour commencer à écouter un canal spécifique.
L'accès à un canal est autorisé ou non uniquement par le serveur; Les conditions qui affectent
ceci sont les suivantes :
1. L'utilisateur doit être invité si le canal est en mode "sur invitation seulement"
2. Le pseudo/nom d'utilisateur ne doit pas correspondre à un bannissement actif.
Une fois qu'un utilisateur a accès à un canal, ils reçoivent des notifications sur toutes les
commandes que leur serveur reçoit qui affectent le canal. Cela inclut MODE, KICK, PART,
QUIT, et bien sûr PRIVMSG/NOTICE.
Si un JOIN a lieu avec succès, on envoie à l'utilisateur le sujet du canal (topic) et la liste des
utilisateurs du canal, y compris lui-même.
Dans le cas où le canal n’existe pas auparavant, un nouveau canal sera crée avec le même
nom, et le client à l’origine de cette commande JOIN devient l’opérateur de ce canal.
Réponses numériques :
ERR_NEEDMOREPARAMS : paramètres manquants.
ERR_BANNEDFROMCHAN : utilisateur banni dans ce canal.
ERR_INVITEONLYCHAN : canal en mode invitation seulement.
ERR_NOSUCHCHANNEL : nom de canal non valide.
ERR_FULLCHANNEL : nombre d’utilisateur dépasse la limite autorisé.
Exemple:
JOIN #foobar ; accède au canal #foobar.
JOIN #foo,#bar; accède au canal #foo et au canal #bar.
- Message PART
Commande: PART
Paramètres: <canal>{,< canal >}*
Le message PART provoque le retrait du client expéditeur de la liste des utilisateurs actifs
pour tous les canaux listé dans la chaîne de paramètre.
Réponses numériques:
ERR_NEEDMOREPARAMS : paramètres manquants.
ERR_NOSUCHCHANNEL : nom de canal non valide.
Exemple:
PART #twilight_zone ; quitte le canal "#twilight_zone"
- Message MODE
Commande: MODE
La commande MODE permet de changer les modes des utilisateurs et des canaux.
Les modes des canaux
Paramètres: <canal> [ [+|-]o <pseudonyme>] [[+|-] i] [ l <limite>]
La commande MODE permet aux opérateurs de canaux de changer les caractéristiques de
'leur' canal. Le serveur doit aussi pouvoir changer les modes du canal, de façon à pouvoir
créer des opérateurs.
Les modes disponibles pour les canaux sont les suivants :
o- donne/retire les privilèges d'opérateur de canal.
i - drapeau de canal accessible uniquement sur invitation.
l - définit le nombre maximal de personnes dans un canal.
Le changement du mode d’un canal ne peut être effectué que par un opérateur ou le serveur.
Notons que l’utilisateur qui a crée un canal (grâce à la commande « join »), sera le premier
opérateur de ce canal.
Réponses numériques :
ERR_NOSUCHNICK : pseudonyme non valide.
ERR_UNKNOWNMODE : le mode spécifié est inconnu.
ERR_NEEDMOREPARAMS : paramètres manquants.
ERR_NOSUCHCHANNEL : nom de canal non valide.
ERR_PERMISSIONDENIED : permission non accordé (l’utilisateur courant n’est
pas un opérateur).
Exemples:
Utilisation des modes de canal:
MODE #Finnish +i ; Rend le canal #Finnish 'uniquement sur invitation'.
MODE #Finnish +o Kilroy ; Donne le privilège de 'chanop' à Kilroy sur le canal
#Finnish.
4. Le message TOPIC
Commande: TOPIC
Paramètres: <canal> [<sujet>]
Le message TOPIC est utilisé pour modifier ou voir le sujet d'un canal. Le sujet du canal
<canal> est renvoyé s'il n'y a pas de <sujet> fourni en paramètre. Si le paramètre <sujet> est
présent, le sujet du canal changera selon le paramètre spécifié.
Réponses numériques :
ERR_NEEDMOREPARAMS : paramètres manquants.
ERR_NOSUCHCHANNEL : nom de canal non valide.
Exemples:
TOPIC #test :another topic ;Change le sujet du canal #test en "another topic".
TOPIC #test ; Vérifie le sujet de #test.
- Message NAMES
Commande: NAMES
Paramètres: [<canal>{,<canal>}*]
En utilisant la commande NAMES, un utilisateur peut obtenir la liste des pseudonymes
visibles sur n'importe quel canal qu'il peut voir. Le paramètre <canal> spécifie quels sont les
canaux dont l'information est voulue, s'ils sont valides. Si le paramètre <canal> n'est pas
donné, la liste de tous les canaux et de leurs occupants est renvoyée.
Réponses numériques:
ERR_NOSUCHCHANNEL : nom de canal non valide.
Exemples:
NAMES #twilight_zone; liste les utilisateurs sur #twilight_zone.
NAMES ; liste tous les canaux, et tous les utilisateurs.
6. Message LIST
Commande: LIST
Paramètres: [<canal>{,<canal>}*]
Le message liste est utilisé pour lister les canaux et leur sujet. Si le paramètre <canal> est
utilisé, seul le statut de ces canaux est affiché.
Réponses numériques :
ERR_NOSUCHCHANNEL : nom de canal non valide.
Exemples:
LIST ; Liste tous les canaux.
LIST #twilight_zone,#42 ; Liste les canaux #twilight_zone et #42
7. Message INVITE
Commande: INVITE
Paramètres: <pseudonyme> <canal>
Le message INVITE est utilisé pour inviter des utilisateurs dans un canal. Le paramètre
<pseudonyme> est le pseudonyme de la personne à inviter dans le canal destination <canal>.
Il n'est pas nécessaire que le canal dans lequel la personne est invitée existe, ni même soit
valide. Pour inviter une personne dans un canal en mode sur invitation (MODE +i), le client
envoyant l'invitation doit être opérateur sur le canal désigné.
Réponses numériques :
ERR_NOSUCHNICK : pseudonyme non valide.
ERR_NEEDMOREPARAMS : paramètres manquants.
ERR_NOSUCHCHANNEL : nom de canal non valide.
ERR_PERMISSIONDENIED : permission non accordé (l’utilisateur n’est pas un
opérateur du canal).
Exemple:
INVITE Wiz #Twilight_Zone ; Commande pour inviter WiZ sur #Twilight_zone
8. Commande KICK
Commande: KICK
Paramètres: [ban] <canal> <utilisateur> [<commentaire>]
La commande KICK est utilisée pour retirer par la force un utilisateur d'un canal (PART
forcé). Seul un opérateur de canal peut faire retirer un autre utilisateur hors d'un canal. Le
serveur, en recevant un message KICK, vérifie si le message est valide (c'est-à-dire si
l'expéditeur est bien un opérateur du canal) avant d'ôter la victime du canal.
Si l’option « ban », est précisée, alors l’utilisateur sera retiré et banni de ce canal. En effet, le
serveur inscrit l’utilisateur dans la liste des utilisateurs bannis à joindre ce canal.
Réponses numériques :
ERR_NOSUCHNICK : pseudonyme non valide.
ERR_NEEDMOREPARAMS : paramètres manquants.
ERR_NOSUCHCHANNEL : nom de canal non valide.
ERR_PERMISSIONDENIED : permission non accordé (l’utilisateur courant n’est
pas un opérateur).
Exemple:
KICK #Finnish John :Speaking English ; Kick John de #Finnish en spécifiant
"Speaking English" comme raison (commentaire).
c. Envoi de messages
Le but principal de ce protocole est de fournir une base afin que des clients puissent
communiquer entre eux. PRIVMSG et NOTICE sont les seuls messages disponibles qui
réalisent effectivement l'acheminement d'un message textuel d'un client à un autre - le reste le
rend juste possible et assure que cela se passe de façon fiable et structurée.
1. Messages privés
Commande: PRIVMSG
Paramètres: <destinataire>{,<destinataire>}* <texte à envoyer >
PRIVMSG est utilisé pour envoyer un message privé entre des utilisateurs. <destinataire> est
le pseudonyme du destinataire du message. <destinataire> peut aussi être une liste de nom ou
de canaux, séparés pas des virgules.
Réponses Numériques:
ERR_NOSUCHNICK : pseudonyme non valide.
ERR_NEEDMOREPARAMS : paramètres manquants.
ERR_PERMISSIONDENIED : permission non accordé (l’utilisateur courant n’est
pas un opérateur).
ERR_CANNOTSENDTOCHAN : impossible d’envoyer un message à ce canal.
ERR_NOTEXTTOSEND : pas de texte spécifié pour l’envoie.
Exemples:
PRIVMSG Angel :oui, je le reçois ! ; Message à Angel.
PRIVMSG #support :j’ai besoin d’aide ; Message au canal support.
- Notice
Commande: NOTICE
Paramètres: <pseudonyme> <texte>
Le message NOTICE s'utilise de la même façon que PRIVMSG. La différence entre NOTICE
et PRIVMSG est qu'aucune réponse automatique ne doit être envoyée en réponse à un
message NOTICE.
Voir PRIVMSG pour les détails sur les réponses, et pour les exemples.
d. Messages divers
1. Message PING
Commande: PING
Paramètres: <pseudonyme>
Le message PING est utilisé pour tester la présence d'un client actif à l'autre bout de la
connexion. Un message PING est envoyé régulièrement par le serveur si aucune activité n'est
détectée sur une connexion. Si la connexion ne répond pas à la commande PING dans un
certain délai, la connexion est fermée.
Tout client qui reçoit un message PING doit répondre au serveur aussi rapidement que
possible, avec un message PONG approprié pour indiquer qu'il est toujours là et actif.
Exemple:
PING WiZ ; message PING envoyé au pseudo WiZ
2. Message PONG
Commande: PONG
Paramètres: aucun
Le message PONG est la réponse à un
message PING.
ceci est le code du serveur
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <pthread.h>
#include <string.h>
#include<string.h>
#define NMAX_CLIENT 20
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex1 = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex_set = PTHREAD_MUTEX_INITIALIZER;
int test=0;
fd_set readfds, testfds,writefds;
/////////////////////
//char champ1[10],champ2[10],champ3[10];
typedef struct _client
{
// pthread_t id;
int sock;
char nuser[10];
char vnom[10];
char pseudonom[15];
int invite;
int pong_reponse;
}client;
typedef struct _canal
{
char sujet[10];
char nom_canal[10];
client *tab_clients[20];
int lg;
int mode;//0 :invité / 1:acces
int invite_fd[20];
int sz_invite;
int operateur[20];
int sz_operateur;
}canal;
typedef struct _cellule
{
canal* canal;
struct cellule *suiv;
}cellule;
//--------
int cl=0,cn=1;
canal *canales[20];
client *clients[20];
//-----
void init_canales()
{int i;
/*for(i=0;i<21;i++)
{
//bzero(canales[i]->sujet,sizeof(canales[i]->sujet));
bzero(canales[i]->nom_canal,sizeof(canales[i]->nom_canal));
canales[i]->sz_invite=0;
}*/
canal* c;
c=malloc (sizeof(canal));
strcpy(c->sujet,"ensi");
strcpy(c->nom_canal,"home");
canales[0]=c;
canales[0]->mode=1;// home est accès pour tous les clients dès la connection
canales[0]->sz_operateur=0;
}
/*
void ini
t_liste()
{
liste_canaux=malloc(sizeof( cellule));
canal* c;
c=malloc (sizeof(canal));
strcpy(c->sujet,"home");
strcpy(c->nom_canal,"ensi");
bzero(&liste_canaux,sizeof(liste_canaux));
inserer_liste(c);
}
/*cellule *liste_canaux;
////////////////////
/***********************
int longueur_liste( )
{int lg=0;
cellule *p=malloc(sizeof(cellule));
cellule *p1=malloc(sizeof(cellule));
p=liste_canaux;
while(p!=NULL);
{p1=p->suiv;p=p1;lg++;}
return lg;
}
/********************
void suppression_liste(char *msg)
{
int i;cellule *p=malloc(sizeof(cellule));
cellule*prec=malloc(sizeof(cellule));
if(longueur_liste()>1)
{while(p!=NULL)
{canal *c=malloc(sizeof(canal));c=p->canal;
if(strcmp(c->nom_canal,msg)&&p!=NULL)
{prec=p;
p=p->suiv;}
else
break;
}
if(p!=NULL)
prec->suiv=p->suivfor(ii=pos+1;msg[ii]!='\0';ii++)
m[h++]=msg[ii];;
}
}
//////////////////////////
//**************************/
void copier_client(int n,int i,client* c)
{
(canales[n]->tab_clients[i])->sock=c->sock;
(canales[n]->tab_clients[i])->invite=c->invite;
strcpy((canales[n]->tab_clients[i])->nuser,c->nuser);
strcpy((canales[n]->tab_clients[i])->vnom,c->vnom);
strcpy((canales[n]->tab_clients[i])->pseudonom,c->pseudonom);
}
//***************************
void ajout_client_canales(int n,int sk)
{int i;
//pthread_mutex_lock(&mutex);
i=canales[n]->lg;
canales[n]->tab_clients[i]=(client*)malloc (sizeof(client));
(canales[n]->tab_clients[i])->sock=sk;
(canales[n]->tab_clients[i])->invite=0;
//strcpy(canales[n]->tab_clients[i]->canal_invite[0],canales[0]->nom_canal);
// canales[n]->tab_clients[i]->sz_invite=0;
// strcpy((canales[n]->tab_clients[i])->nuser,nu);
// strcpy((canales[n]->tab_clients[i])->vnom,vn);
// strcpy((canales[n]->tab_clients[i])->pseudonom,ps);
canales[n]->lg+=1;
//pthread_mutex_unlock(&mutex);
}
//////////////////////////////
inserer_canal( canal *c)
{ if(cn<20)
{
//pthread_mutex_lock(&mutex);
canales[cn]=malloc(sizeof(canal));
canales[cn]=c;
cn++;
//pthread_mutex_unlock(&mutex);
}
else
printf("erreur inserer_canal");
}
//**************************
char * liste_connectes(int n)
{char liste[2500];int i;int cc=canales[n]->lg;
//strcat(liste,"la liste est:\n");
//pthread_mutex_lock(&mutex);
bzero(liste,sizeof(liste));
for(i=0;i<cc;i++)
{strcat(liste,(canales[n]->tab_clients[i])->pseudonom);strcat(liste," + ");}
//pthread_mutex_unlock(&mutex);
return liste;
}
//**************************************************
//**************************************************
int type_cmd(char* ch)
{
int i=0;char cmd[800];
for(i=0;ch[i]!=' ';i++)
{
;
}
strncpy(cmd,ch,i);
if(!strcmp(cmd,"user"))
return 1;
else
if(!strcmp(cmd,"nick"))
return 2;
else
if(!strcmp(cmd,"send"))
return 3;
else
if(!strcmp(cmd,"quit"))
return 4;
else
if(!strcmp(cmd,"join"))
return 5;
else
if(!strcmp(cmd,"part"))
return 6;
else
if(!strcmp(cmd,"mode"))
return 7;
else
if(!strcmp(cmd,"topic"))
return 8;
else
if(!strcmp(cmd,"names"))
return
9;
else
if(!strcmp(cmd,"list"))
return 10;
else
if(!strcmp(cmd,"invite"))
return 11;
else
if(!strcmp(cmd,"kick"))
return 12;
else
if(!strcmp(cmd,"privmsg"))
return 13;
else
if(!strcmp(cmd,"notice"))
return 14;
else
if(!strcmp(cmd,"ping"))
return 15;
if(!strcmp(cmd,"pong"))
return 16;
else
return 0;
}
//************************************
void tr_cmd_pong(int fd)
{
int i;
for(i = 0; i<canales[0]->lg&&canales[0]->tab_clients[i]->sock!=fd; i++);
if(i<canales[0]->lg)
canales[0]->tab_clients[i]->pong_reponse=1;
}
//*********************************************
void tr_cmd_quit(int fd,char *msg)
{
int i,j=0,k,u,l,t=0,z,cpt,taille;
char ps[10],num[10][20];
if(msg[5]==';')
{pthread_mutex_lock(&mutex);
for(k=0;k<cn;k++)
{
for(u=0;u<canales[k]->lg&&(canales[k]->tab_clients[u])->sock!=fd;u++);
if(u!=canales[k]->lg)
{
//FD_CLR(canales[k]->tab_clients[u]->sock, &readfds);
close(canales[k]->tab_clients[u]->sock);
for(z=u;z<canales[k]->lg;z++)
{
canales[k]->tab_clients[z]=canales[k]->tab_clients[z+1] ;
}
(canales[k]->lg)--;canales[k]->tab_clients[z-1]=NULL;
}
}
pthread_mutex_unlock(&mutex);
}
}
//*************************************
//*************************************
void fct_ping()
{int i;int tour=0;char msg[10];char pingo[50];
sleep(400);
while(1)
{
for(i = 0; i<canales[0]->lg; i++)
{
bzero(pingo,sizeof(pingo));
strcat(pingo,canales[0]->tab_clients[i]->pseudonom);
strcat(pingo,": ping");
send(canales[0]->tab_clients[i]->sock,pingo,50,0);
canales[0]->tab_clients[i]->pong_reponse=0;tour=2;
//send(canales[0]->tab_clients[i]->sock,"repondez au ping!",20,0);
}
sleep(5);
for(i = 0; i<canales[0]->lg; i++)
{
if(canales[0]->tab_clients[i]->pong_reponse==0)
{
sleep(1);send(canales[0]->tab_clients[i]->sock,"tu es deconnecté",20,0);
strcpy(msg,"quit ;");tr_cmd_quit(canales[0]->tab_clients[i]->sock,msg);
pthread_mutex_lock(&mutex_set);
//send(canales[0]->tab_clients[i]->sock,"quit\0",8,0);
FD_CLR(canales[0]->tab_clients[i]->sock, &readfds);
close(canales[0]->tab_clients[i]->sock);
pthread_mutex_unlock(&mutex_set);
}
}
sleep(300);
}
}
//**************************************
void tr_cmd_list(int fd,char *msg)
{
int i,k,j=0,l,t=0,taille,cpt,nu;char num[8][20];char tt[200];
cpt=5;
while(msg[cpt]!=';')
{
for(i=cpt;msg[i]!=' ';i++)
num[j][t++]=msg[i];
num[j][t]='\0';
cpt=i+1;j++;t=0;
}
taille=j;
if(msg [5]!=';')
{
bzero(tt,sizeof(tt));
for(l=0;l<taille;l++)
pthread_mutex_lock(&mutex);
{
for(k=0;k<cn&&strcmp(canales[k]->nom_canal,num[l]);k++)
;
if(k!=cn)
{
strcat(tt,canales[k]->nom_canal);
strcat(tt,":");
strcat(tt,canales[k]->sujet);
strcat(tt,"\n");
}
else
send(fd,"ERR_NOSUCHCHANNEL:nom de canal non valide\0",50,0);
}
send(fd,tt,sizeof(tt),0);
pthread_mutex_unlock(&mutex);
}
else
{
bzero(tt,sizeof(tt));
for(t=0;t<cn;t++)
{
strcat(tt,canales[t]->nom_canal);
strcat(tt,":");
strcat(tt,canales[t]->sujet);
strcat(tt,"\n");
}
send(fd,tt,sizeof(tt),0);
}
}
//*****************************************
void tr_cmd_mode(int fd,char *msg)
{
int i,j,k=0,m,n,t,l,test=0;char canal[15];char option1='a',ps[15];char option2='a';char signe1='^';char signe2='^';
for(i=5;msg[i]!=' ';i++)
canal[k++]=msg[i];
canal[k]='\0';i++;k=0;
signe1=msg[i];i++;
option1=msg[i];i++;
if(option1=='o')
{
for(j=i+1;msg[j]!=' ';j++)
ps[k++]=msg[j];
ps[k]='\0';
j++;signe2=msg[j];j++;
option2=msg[j];
}
else
{signe2=signe1;option2=option1;}
for(m=0;m<cn && strcmp(canales[m]->nom_canal,canal);m++);//trouver le canal
if(m!=cn)//si canal existe
{
for(t=0;t<canales[m]->sz_operateur&&canales[m]->operateur[t]!=fd;t++)
{
if(canales[m]->operateur[t]==canales[m]->tab_clients[n]->sock)
test=1;l=t;
}
if(t==canales[m]->sz_operateur)
send(fd,"ERR_PERMISSIONDENIED: premission non accordée",60,0);
else//il est un operateur
{
//send(fd,msg[i],15,0);
if(option2=='i')
{
if(signe2=='-')
{
canales[m]->mode=0;send(fd,"le canal est en mode invitation ",50,2);
}
if(signe2=='+')
{
canales[m]->mode=1;send(fd,"le canal est un mode accées",50,2);
}
}
if(option1=='o')
{
for(n=0;(n<canales[m]->lg)&&(strcmp(canales[m]->tab_clients[n]->pseudonom,ps));n++);
if(n!=canales[m]->lg)//si pseudonom existe
{
if(signe1=='+')
{canales[m]->operateur[canales[m]->sz_operateur++]=canales[m]->tab_clients[n]->sock;
send(fd,"ajout d'un operateur",20,0);
}
else
{
if(signe1=='-')
{canales[m]->operateur[l]=-1;
send(fd,"retirer un operateur ",20,0);
}
}
}
else
send(fd,"ERR_NOSUCHNICK: pseudo non valide",40,0);
}
}
}
else
send(fd,"ERR_NOSUCHCANAL: nom de canal non valide ",40,0);
}
//*********************************************
void tr_cmd_kick(int fd,char *msg)
{
int i,j,k=0,l,m;int s;
char canal[20],ps[20];char commt[60];bzero(commt,sizeof(commt));
for (i=5;msg[i]!=' ';i++)
canal[k++]=msg[i];
canal[k]='\0';
k=0;
for (j=i+1;msg[j]!=' ';j++)
ps[k++]=msg[j];
ps[k]='\0';k=0;j++;
if(msg[j]!=';')
{
for(s=j;msg[s]!=' ';s++)
commt[k++]=msg[s];
commt[k]='\0';
}
pthread_mutex_lock(&mutex);
for(l=0;l<cn&&strcmp(canales[l]->nom_canal,canal);l++);
if(l==cn)
send(fd,"ERR_NOSUCHCANAL: nom de canal non valide\n ",60,0);
else
{
for(m=0;m<(canales[l]->sz_operateur)&&canales[l]->operateur[m]!=fd;m++);
if(m!=canales[l]->sz_operateur)
{
for(k=0;k<canales[l]->lg&&strcmp(canales[l]->tab_clients[k]->pseudonom,ps);k++);
if(k==canales[l]->lg)
send(fd,"ERR_NONSUCHNICK: pseudonyme non valide\n",60,0);
else
{
for(j=k;j+1<canales[l]->lg;j++)
{
canales[l]->tab_clients[j]=canales[l]->tab_clients[j+1];
}
//canales[l]->tab_clients[j]=NULL;
canales[l]->lg--;
send(fd,"ok",5,0);
}
}
else
send(fd,"ERR_PERMISSIONDENIED: permission nom accordée\n",30,0) ;
}
pthread_mutex_unlock(&mutex);
}
//*********************************************
void tr_cmd_invite(int fd,char *msg )
{
int i,j,k=0,l,h=0;char canal[15],ps[20];
for(i=7;msg[i]!=' ';i++)
ps[h++]=msg[i];
ps[h]='\0';
for(j=i+1;msg[j]!=' ';j++)
canal[k++]=msg[j];
canal[k]='\0';
pthread_mutex_lock(&mutex);
for(l=0;l<(canales[0]->lg)&&strcmp(canales[0]->tab_clients[l]->pseudonom,ps);l++)
;
if(l==canales[0]->lg)
send(fd,"pseudonyme n'existe pas\n",30,0);
else
{
for(i=0;i<cn&&strcmp(canales[i]->nom_canal,canal);i++)
;
if(i==cn)
send(fd,"canal n'existe pas!\n",20,0);
else
{
for(j=0;(j<canales[i]->lg)&&(canales[i]->tab_clients[j]->sock!=fd);j++)
;
if(j==canales[i]->lg)
send(fd,"tu n'es pas un operateur\n",30,0);
else
{
canales[i]->invite_fd[canales[i]->sz_invite++]=canales[0]->tab_clients[l]->sock;
send(canales[0]->tab_clients[l]->sock,"tu es invite au canal :n",25,0);
send(canales[0]->tab_clients[l]->sock,canal,10,0);
send(fd,"invitation ok\n",15,0);
}
}
}
pthread_mutex_unlock(&mutex);
}
//**********************************************
void tr_cmd_topic(int fd,char *msg)
{
int i,j,k=0,l,h,etat;
char canal[10];char sujet[10];
for (i=6;msg[i]!=' ';i++)
canal[k++]=msg[i];
canal[k]='\0';
k=0;
if(msg[i+1]==';')
etat=0;
else
{
etat=1;
for(h=i+1;msg[h]!=' ';h++)
sujet[k++]=msg[h];
sujet[k]='\0';
}
//------------
pthread_mutex_lock(&mutex);
for(j=0;strcmp(canales[j]->nom_canal,canal);j++)
pthread_mutex_unlock(&mutex);
;
//-------------
if(j==cn)
send(fd,"nom de canal non valide\n",30,0);
else
{
if(etat==0)
{
if(strlen(canales[j]->sujet)==0)
send(fd,"verifier la sujet\n",19,0);
else
// send(fd,"le sujet est :",15,0);
send(fd,canales[j]->sujet,10,0);
}
else
{
strcpy(canales[j]->sujet,sujet);
send(fd,"changement effectue\n",20,0);
send(fd,canales[j]->sujet,10,0);
}
}
}
//*********************************************
void tr_cmd_join(int fd,char *msg)
{canal *c;c=malloc(sizeof(canal));
int i,j,u,h=0,k=0;char canal[15];
//FILE *pts,*plex;
for(j=5;msg[j]!=' ';j++)
canal[h++]=msg[j];
canal[h]='\0';
pthread_mutex_lock(&mutex);
while(strcmp(canales[k]->nom_canal,canal))
{
k++;
if(k==cn)
break;
}
for(u=0;canales[0]->tab_clients[u]->sock!=fd;u++)
;
if(k==cn)
{
strcpy(c->nom_canal,canal);
//for(u=0;canales[0]->tab_clients[u]->sock!=fd;u++)
// ;
// strcpy(c->tab_clients[(c->lg)++]->pseudonom,(canales[0]->tab_clients[u])->pseudonom);
inserer_canal(c);
//ajout_client_canales(cn-1,fd);
//canales[cn-1]->tab_clients[c->lg]=malloc (sizeof(client));
canales[cn-1]->lg=0;
canales[cn-1]->sz_operateur=0;
canales[cn-1]->sz_invite=0;
canales[cn-1]->tab_clients[(canales[cn-1]->lg)]=canales[0]->tab_clients[u];
(canales[cn-1]->lg)+=1;
canales[cn-1]->mode=0;//canal en invitation
if(canales[cn-1]->sz_operateur==0)
canales[cn-1]->operateur[(canales[cn-1]->sz_operateur)++]=fd;
//canales[cn-1]->lg++;
// for(u=0;canales[0]->tab_clients[u]->sock!=fd;u++)
// ;
//strcpy(canales[cn-1]->tab_clients[(c->lg)-1]->pseudonom,(canales[0]->tab_clients[u])->pseudonom);
//send(fd,liste_connectes(cn-1),20,0);
send(fd,"creation du canal :OK\n",25,0);
}
else
{
if(canales[k]->mode==0)
{
for(j=0;(j<canales[k]->lg)&&(canales[k]->invite_fd[j]!=fd);j++);
if(j!=canales[k]->lg)
{
canales[k]->tab_clients[(canales[k]->lg)++]=canales[0]->tab_clients[u];
send(fd,"OK:le canal est en mode acces \n",30,0);
}
else
{
send(fd,"vous devez etre invité\n",20,0);
}
}
else
{
canales[k]->tab_clients[(canales[k]->lg)++]=canales[0]->tab_clients[u];
send(fd,"OK:le canal est en mode acces \n",30,0);
//send(fd,"le canal est en mode invitation tu peux l'ecouter (¤:\n",40,0);
}
}
pthread_mutex_unlock(&mutex);
}
//********************************************
////////////////////////////////////////////
void tr_cmd_part(int fd,char *msg)
{
int i,j=0,k,u,l,t=0,z,cpt,taille;
char ps[10],num[10][20];
pthread_mutex_lock(&mutex);
cpt=5;
while(msg[cpt]!=';')
{
for(i=cpt;msg[i]!=' ';i++)
num[j][t++]=msg[i];
num[j][t]='\0';
cpt=i+1;j++;t=0;
}
taille=j;
if(msg[5]!=';')
{
for(l=0;l<taille;l++)
{
for(k=0;k<cn&&strcmp(canales[k]->nom_canal,num[l]);k++)
;
if(k!=cn)
{
for(u=0;(canales[k]->tab_clients[u])->sock!=fd;u++)
;
for(z=u;z<canales[k]->lg;z++)
{
canales[k]->tab_clients[z]=canales[k]->tab_clients[z+1];
}
(canales[k]->lg)--;canales[k]->tab_clients[z]=NULL;
}
}
}
pthread_mutex_unlock(&mutex);
}
//*********************************************
void tr_cmd_user(int n,int fd,char *msg )
{
char buff[10];
int top=0;
int i,j=0,jj=0;
int c=0;int cc=canales[n]->lg;
pthread_mutex_lock(&mutex);
while(c<cc&&(canales[n]->tab_clients[c])->sock!=fd)
{c++;}
for(i=5;msg[i+1]!=';';i++)
{
if(msg[i]==' ')
{top=1;(canales[n]->tab_clients[c])->nuser[jj]='\0';}
if(top==0)
(canales[n]->tab_clients[c])->nuser[jj++]=msg[i];
if(top==1)
(canales[n]->tab_clients[c])->vnom[j++]=msg[i+1];
}
(canales[n]->tab_clients[c])->vnom[j]='\0';
pthread_mutex_unlock(&mutex);
send(fd,"mise a jour effectué :\n",30,0);
//send(fd,(canales[n]->tab_clients[c])->vnom,sizeof((canales[n]->tab_clients[c])->vnom),0);
//send(fd,(canales[n]->tab_clients[c])->nuser,sizeof((canales[n]->tab_clients[c])->nuser),0);
}
//**********************
void tr_cmd_nick(int n,int fd,char *msg)
{
int c=0,i,h=0,j=0;char ps[20];int cc=canales[n]->lg;
for(i=5;msg[i]!=' ';i++)
ps[j++]=msg[i];
ps[j]='\0';
pthread_mutex_lock(&mutex);
while(c<cc&&(canales[n]->tab_clients[c])->sock!=fd)
{c++;}
while(strcmp((canales[n]->tab_clients[h])->pseudonom,ps))
{h++;
if(h==cc)
break;
}
if(h==cc){
strcpy((canales[n]->tab_clients[c])->pseudonom,ps);
send(fd,"pseudo ok\n",10,0);
}
else
send(fd,"ERR_NICKNAMEUSE: pseudo en cours d'utilisation par un autre utilisateur\n",50,0);
pthread_mutex_unlock(&mutex);
}
//***********************************
//******************
void tr_cmd_privmsg(int n,int fd,char* msg)
{int i,ii,d,t=0,l,k,kk=0,pos,h,cpt=0,j=0;char dest[50];char pst[10][50];char m[200];char ps[50];
int cc=canales[n]->lg;int test=0;
for(ii=0;ii<cn&&canales[0]->tab_clients[ii]->sock!=fd;ii++);
cpt=8;
// k=8;
/*while(msg[k]!=' '&&k<100)
ps[kk++]=msg[k++];
ps[kk]='\0';*/
while(msg[k]!=' ')
{
for(k=cpt;msg[k]!=','&&msg[k]!=' ';k++)
pst[j][t++]=msg[k];
pst[j][t]='\0';
cpt=k+1;j++;t=0;
}
k++;
cpt=0;
while(msg[k]!=';'&&k<100)
m[cpt++]=msg[k++];
m[cpt]='\0';
for(d=0;d<j;d++)
{
test=0;
bzero(ps,sizeof(ps));
strcpy(ps,pst[d]);
pthread_mutex_lock(&mutex);
h=0;
while(strcmp((canales[n]->tab_clients[h])->pseudonom,ps))
{h++;
if(h==cc)
break;
}
if(h==cc)
{
h=0;test=1;
while(strcmp(canales[h]->nom_canal,ps))
{h++;
if(h==cn)
break;
}
}
pthread_mutex_unlock(&mutex);
if(test==0)
{
if(h!=cc)
{ char mmm[500];bzero(mmm,sizeof(mmm));
strcat(mmm,"[");
strcat(mmm,canales[0]->tab_clients[ii]->pseudonom);
strcat (mmm,"->");
strcat(mmm,(canales[n]->tab_clients[h])->pseudonom);
strcat(mmm,"] :");
strcat(mmm,m);
send((canales[n]->tab_clients[h])->sock,mmm,200,0);
}
}
else
{
if(h!=cn)
{
int p;
for(p=0;p<canales[h]->lg;p++)
{
char mmm[200];bzero(mmm,sizeof(mmm));
strcat(mmm,"[");
strcat(mmm,canales[0]->tab_clients[ii]->pseudonom);
strcat (mmm,"->");
strcat(mmm,(canales[h]->tab_clients[p])->pseudonom);
strcat(mmm,"] :");
strcat(mmm,m);
send((canales[h]->tab_clients[p])->sock,mmm,200,0);
}
}
else
send(fd,"ERR_NOSUCHNICK: pseudo non valide\nERR_NOSUCHCANAL: impossible d'envoyer ce message à ce canal",150,0);
}
//pthread_mutex_unlock(&mutex);
/*h=0;
if (h==cl)
send((canales[n]->tab_clients[kk])->sock,m,sizeof(m),0);
else
send(fd,dest,sizeof(dest),0);send(fd,m,sizeof(m),0);
/////////////////////////////
/*or(i=8;i<strlen(msg);i++)
{
if(msg[i]==' ')
pos=i;
}*/
/* for(cpt=8;msg[cpt]!=' ';cpt++)
{
dest[k++]=msg[cpt];
}
dest[k]='\0';
pthread_mutex_lock(&mutex);
while(strcmp(clients[kk]->pseudonom,dest))
{kk++;
if(kk==cl)
break;
}
pthread_mutex_unlock(&mutex);
if(kk!=cl)
send(clients[kk]->sock,m,sizeof(m),0);
else
{ send(fd,dest,sizeof(dest),0);send(fd,m,sizeof(m),0);}
//send(4,m,9,0);
/* for(j=7;j<pos;j++)
{ if(msg[i]!=',')
dest[k][kk++]==msg[i];
else
{
kk=0;
send(cher_fd(dest[k]),m,sizeof(m),0);
k++;
}
}*/
}
}
//--------------
void tr_cmd_names(int fd,char* msg)
{int i,k,j=0,l,t=0,taille,cpt,nu;char num[8][20];char tt[500];
//FILE *pts,*plex;
// system("rm lex");
/*pts=fopen("split","w");
fprintf(pts,"%s",msg);
system("./exe <split 02>kol");
plex=fopen("lex","r");
fgets(num,6,plex);
fgets(num,6,plex);
fclose (pts);fclose(plex);
system("rm lex ");*/
cpt=6;
while(msg[cpt]!=';')
{
for(i=cpt;msg[i]!=' ';i++)
num[j][t++]=msg[i];
num[j][t]='\0';
cpt=i+1;j++;t=0;
}
taille=j;
if(msg [6]!=';')
{
bzero(tt,sizeof(tt));
for(l=0;l<taille;l++)
{
for(k=0;k<cn&&strcmp(canales[k]->nom_canal,num[l]);k++)
;
if(k!=cn)
{
strcat(tt,canales[k]->nom_canal);
strcat(tt,":");
strcat(tt,liste_connectes(k));
strcat(tt,"\n");
}
else
send(fd,"canal non existent\0",20,0);
}
send(fd,tt,sizeof(tt),0);
}
else
{
bzero(tt,sizeof(tt));
for(t=0;t<cn;t++)
{
strcat(tt,canales[t]->nom_canal);
strcat(tt," :: ");
strcat(tt,liste_connectes(t));
strcat(tt,"\n");
}
send(fd,tt,sizeof(tt),0);
}
}
//******************
//*****************
void* fct(void* fd)
{
int dest;int i,j,k=0;char d[25]="verifier la dest";
int y;char ch[250];
y=recv((int)fd, ch,sizeof(ch),0 );
switch(type_cmd(ch))
{
case 4:tr_cmd_quit((int)fd,ch);break;
case 10:tr_cmd_list((int)fd,ch);break;
case 6:tr_cmd_part((int)fd,ch);break;
case 5:tr_cmd_join((int)fd,ch);break;
case 13:tr_cmd_privmsg(0,(int)fd,ch);break;
case 2:tr_cmd_nick(0,(int)fd,ch);break;
// printf("%d",type_cmd(ch));tr_cmd_nick(fd,ch);break;
case 1:tr_cmd_user(0,(int)fd,ch);break;
case 9:tr_cmd_names((int)fd,ch);//send((int)fd,liste_connectes(0),125,0);//sizeof(liste_connectes()),0);
break;
case 8:tr_cmd_topic((int)fd,ch);break;
case 12:tr_cmd_kick((int)fd,ch);break;
case 11:tr_cmd_invite((int)fd,ch);break;
case 16:tr_cmd_pong((int)fd);break;
case 7:tr_cmd_mode((int)fd,ch);break;
case 3: //for(i=5;ch[i]!=' ';i++)
// ;
//i++;
//for(j=i;ch[j]!=' ';j++)
// d[k]=ch[j];
dest=atoi(ch+5);printf("%d\n",dest);
pthread_mutex_lock(&mutex);
for(j=0;clients[j]->sock!=dest&&j<cl;j++);
//void accepter(int server_sockfd,int ) ;
if(j<cl)
send(dest,ch,y-1,0);
else
send(4,d,y-1,0);
pthread_mutex_unlock(&mutex);
break;
default:send((int)fd,"ereur\n",20,0);break;
}
}
//***********************************
void afficher_clients()
{int i;int cc=canales[0]->lg;
system("clear");
pthread_mutex_lock(&mutex);
for(i=0;i<cc;i++)
{
printf("client present n:%d\n\0",(canales[0]->tab_clients[i])->sock);
}
pthread_mutex_unlock(&mutex);
}
//**************************************
/*void* ajout_client( int sk,char*nu)//,char*vn,char* ps )
{
clients[cl]=(client*)malloc (sizeof(client));
bzero((canales[0]->tab_clients[cl]),sizeof(client));
//clients[cl].id=pt;
clients[cl]->sock=sk;
clients[cl]->invite=0;
strcpy(clients[cl]->nuser,nu);
//strcpy(clients[cl].vnom,vn);
//strcpy(clients[cl].pseudonom,ps);
cl++;
//printf("adding client et son descript: fd %d\n", sk);
}*/
//**************************************
int main()
{
int numthread=0;
int server_sockfd, client_sockfd;
int server_len, client_len;
struct timeval timeout;
struct sockaddr_in server_address;
struct sockaddr_in client_address;
int result;
char nom_serv[1500];
char buff[100];
// pthread_t idptr;
int pfr;int num, i=0;
gethostname(nom_serv,sizeof(nom_serv));
printf("nom_serv: %s",nom_serv);
server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = htonl(INADDR_ANY);
server_address.sin_port = htons(15000);
server_len = sizeof(server_address);
bind(server_sockfd, (struct sockaddr *)&server_address, server_len);
listen(server_sockfd, 5);
FD_ZERO(&readfds);
pthread_t thread[21];
FD_SET(server_sockfd, &readfds);
//bzero(canales,sizeof(canal)*20);
init_canales();
pthread_t pingo;
//
while(1)
{
char *name="hamma";
char ch[150];
int fd;
int nread;
timeout.tv_sec=2;
timeout.tv_usec=000000;
testfds = readfds;
//pthread_mutex_lock(&mutex_set);
result = select(FD_SETSIZE, &testfds, (fd_set *)0, (fd_set *)0, (struct timeval *) 0);
//pthread_mutex_unlock(&mutex_set);
if(result == -1)
{
perror("server5");
exit(1);
}
if(result==0)
{
printf("aucune connection !\n");
}
for(fd = 0; fd <FD_SETSIZE; fd++)
{
if(FD_ISSET(fd,&testfds))
{
if(fd == server_sockfd)
{
client_len = sizeof(client_address);
client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_address, &client_len);
send(client_sockfd,canales[0]->nom_canal,32,0);
pthread_mutex_lock(&mutex_set);
FD_SET(client_sockfd, &readfds);
pthread_mutex_unlock(&mutex_set);
ajout_client_canales(0, client_sockfd);//,name );
afficher_clients();
}
else
{ ioctl(fd, FIONREAD, &nread);
if(nread == 0)
{
close(fd);
pthread_mutex_lock(&mutex_set);
FD_CLR(fd, &readfds);
pthread_mutex_unlock(&mutex_set);
printf("removing client on fd %d\n", fd);
}
else
{
//printf("%s\n",champ1);
pthread_create(&thread[i++%20],NULL,(void*)fct,(void*)fd);
}
}
}
}
if(test++==0)
pthread_create(&pingo,NULL,(void*)fct_ping,NULL);
}
}
void* traiter_client(void* sk)
{
int sock=(int)sk;
int i,lg;
char msg[2000];
char buffer[4000];
client* me;
me = (client *) malloc(sizeof(client));
bzero(me,sizeof(client));
send(sock,"hello tu es connectE",20,0);
lg=read(sock,msg,sizeof(msg));
//tester la msg lex & yacc
if(lg<=0)
{
printf("\nErreur\n");
close(sock);
free(me);
me = NULL;
// nb_clients--;
pthread_exit(NULL);
}
}
//*************
//*************
/*char* get_msg()
{
char buff[50];
int s=52;
recv (client_sockfd,buff,s,0);
return buff;
} */
ceci est le code du client
#include <string.h>
#include <pthread.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include <pthread.h>
#include<fcntl.h>
#include <gtk/gtk.h>
int test=0;int create_socket;
//-------------------------------------
pthread_mutex_t fichier = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutex2 = PTHREAD_MUTEX_INITIALIZER;
char ch[1200];char buff1[2054];char buff2[2000];
void on_activate_entry(GtkWidget *pEntry, gpointer data);
void afficher( GtkWidget *file_selection);
void deteruire()
{
close (create_socket);
gtk_main_quit();
}
//---------------------------
GtkWidget *pWindow;
GtkWidget *pVBox;
GtkWidget *pHBox;
GtkWidget *pEntry;
GtkWidget *pButton;
GtkWidget *pLabel;
GtkWidget *text_view;
GtkWidget *scrollbar;
GdkFont *fixed_font;
GError *error = NULL;
//les variable de la fenetre projet
//--------------------------------------------
/*void *fct_recv(void* k)
{
FILE*pf;
int lg1,l;
char buff[50];
while(1)
{
l=recv ((int)k,buff,sizeof(buff),0);
if(l>0)
// pthread_mutex_lock(&fichier);
pf=fopen("fich","a+");
fprintf(buff,"%s\n",pf);
strcpy(buff1,buff);
fclose(pf);
//pthread_mutex_unlock(&fichier);*
}
}*/
//-------------------------------------------------
/*void* fct_send( void* k)
{
int lg=54;
FILE *pf1,*plex;int f;char err[7];
// while(1)
// {
char buffer[50];char buffer1[30];char ch[40];
bzero(buffer1,sizeof(buffer1));
bzero(buffer,sizeof(buffer));
//printf("Message to send: ");
fgets(buffer, sizeof(buffer), stdin);
pf1=fopen("sortie","w+");
f=open("entrer",02|O_CREAT,0666);
write(f,buffer,sizeof(buffer));
system ("./exe <entrer 01>sortie 02>sortie ");
close(f);
fgets(err,7,pf1);
fclose(pf1);
if(!strcmp(err," "))
{
plex=fopen("lex","r");
fgets(ch,30,plex);
strcpy(buffer1,ch);
fclose(plex);
//printf("%s",buffer1);
send((int)k,buffer1,sizeof(buffer1),0);
}
else
printf("verifiez votre commande \n");
plex=fopen("lex","w");
fclose(plex);
//}
}*/
//----------------------------------------------------------------------------
//**************************************************
void*connexion (char *arg)
{
pthread_t thread0,thread1,thread2;
int bufsize = 1250;
// char *buffer = malloc(bufsize);
struct sockaddr_in address;
printf("\x1B[2J");
if ((create_socket = socket(AF_INET,SOCK_STREAM,0)) > 0)
printf("la Socket est crée\n");
address.sin_family = AF_INET;
address.sin_port = htons(15000);
inet_pton(AF_INET,arg,&address.sin_addr); /// segfault
if (connect(create_socket,(struct sockaddr *)&address,sizeof(address)) == 0)
printf("la connexion est acceptée avec le serveur %s...\n",inet_ntoa(address.sin_addr));
}
//-------------------------------------------------------------------------------------
//---------------------------------------------------------------
int fenetre( int argc,char **argv)
{
pWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(pWindow), "chat ******** E.N.S.I ***********");
gtk_window_set_default_size(GTK_WINDOW(pWindow), 320, 200);
g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(deteruire), NULL);
pVBox = gtk_vbox_new(FALSE,10);
pHBox = gtk_hbox_new(FALSE,10);
pButton= gtk_button_new_with_label("QUITTER");
gtk_container_add(GTK_CONTAINER(pWindow), pVBox);
scrollbar = gtk_scrolled_window_new(NULL, NULL);
//gtk_scrolled_window_set_hadjustment(scrollbar,NULL);
gtk_box_pack_start(GTK_BOX(pVBox), scrollbar,TRUE,TRUE, 0);
//set_scroll_adjustments(text_view, TRUE, TRUE, NULL);
//fixed_font = gdk_font_load ("-misc-fixed-medium-r-*-*-*-140-*-*-*-*-*-*");
/* Creation du GtkEntry */
text_view=gtk_text_view_new();
gtk_text_view_set_left_margin(text_view,10);
gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view),FALSE);
gtk_container_add(GTK_CONTAINER(scrollbar),text_view);
//gtk_scrolled_window_add_with_viewport(GTK_CONTAINER(scrollbar),text_view);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbar), GTK_POLICY_ALWAYS, GTK_POLICY_ALWAYS);
pEntry = gtk_entry_new();
/* Insertion du GtkEntry dans la GtkVBox */
// gtk_box_pack_start(GTK_BOX(pVBox), text_view, TRUE, TRUE,TRUE);
gtk_box_pack_start(GTK_BOX(pVBox), pHBox, FALSE,FALSE,2);
gtk_box_pack_start(GTK_BOX(pHBox), pEntry, TRUE,TRUE, 5);
gtk_box_pack_end(GTK_BOX(pHBox), pButton, FALSE,FALSE, 5);
// pButton = gtk_button_new_with_label("Copier");
//gtk_box_pack_end(GTK_BOX(pVBox), pButton, TRUE, FALSE, 0);
pLabel = gtk_label_new(NULL);
//gtk_box_pack_start(GTK_BOX(pVBox), pLabel, TRUE, FALSE, 0);
/* Connexion du signal "activate" du GtkEntry */
///++++// g_signal_connect(G_OBJECT(pEntry), "activate", G_CALLBACK(on_activate_entry), (GtkWidget*) pLabel);
g_signal_connect(G_OBJECT(pEntry), "activate", G_CALLBACK(on_activate_entry), (GtkWidget*) pLabel);
g_signal_connect(G_OBJECT(pButton), "clicked", G_CALLBACK(deteruire), NULL);
/* Connexion du signal "clicked" du GtkButton */
/* La donnee supplementaire est la GtkVBox pVBox */
// g_sig gdk_threads_enter();
gtk_widget_show_all(pWindow);
connexion("127.0.0.1");
}
/* enter the GTK main loop */
/* Fonction callback execute lors du signal "activate" */
//---------------------------------------------------------------------------------------
char * analyser_cmd_mode(char* msg)
{int i,k=0;
char chaine[50];bzero(chaine,sizeof(chaine));
for(i=0;msg[i]!=';';i++)
{
if(msg[i]!='#'&&msg[i]!=':')
{
chaine[k++]=msg[i];
}
}
strcat(chaine,";");
return chaine;
}
//--------------------------------------------
void on_activate_entry(GtkWidget *pEntry, gpointer data)
{
FILE* pf,*pf2;
char *sText;int i;char msg[10];
GtkTextBuffer *buffer_text;
buffer_text = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view));
char argv[10]="127.0.0.1";
//bzero(sText,sizeof(sText));
/* Recuperation du texte contenu dans le GtkEntry */
sText = gtk_entry_get_text(GTK_ENTRY(pEntry));
int lg=54;
FILE *pf1,*plex;int f;char err[7];
char buffer[50];char buffer1[30];char ch[40];
bzero(buffer,sizeof(buffer));
bzero(ch,sizeof(ch));
pf1=fopen("sortie","w+");
f=open("entrer",02|O_CREAT,0666);
strcpy(buffer,sText);
write(f,buffer,sizeof(buffer));
if(strncmp(buffer,"mode",4)&&strncmp(buffer,"privmsg",7))
{ system ("./exe <entrer 01>sortie 02>sortie ");
close(f);
fgets(err,7,pf1);
fclose(pf1);
if(!strcmp(err," "))
{
plex=fopen("lex","r");
fgets(ch,30,plex);
strcpy(buffer1,ch);
fclose(plex);
send(create_socket,buffer1,sizeof(buffer1),0);
plex=fopen("lex","w");
fclose(plex);
strcpy(buff2,buffer1);
strcat(buff2,"\n");
}
else
{ strcpy(buff2,sText);
strcat(buff2," :\n verifiez votre command\n");
}
}
else
{
send(create_socket,analyser_cmd_mode(buffer),sizeof(buffer1),0);
strcpy(buff2,analyser_cmd_mode(buffer));
strcat(buff2,"\n");
}
pthread_mutex_lock(&fichier);//section critique
gtk_text_buffer_insert_at_cursor(buffer_text,g_locale_to_utf8(buff2, -1, NULL, NULL, NULL), -1);
bzero(buff2,sizeof(buff2));
bzero(buffer1,sizeof(buffer1));
pthread_mutex_unlock(&fichier);//fin section
gtk_entry_set_text(GTK_ENTRY(pEntry),"");
}
//------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------
//void afficher(GtkWidget *bouton, GtkWidget *view)
void afficher(GtkWidget *view)
{
gchar *mark_name;
GtkTextMark *mark;
GtkTextBuffer *buffer;
GtkTextIter start;
GtkTextIter end;
FILE*pf;
int lg1,l;
char buff[4000];
while(1)
{
recv (create_socket,buff,sizeof(buff),0);
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view));
strcat(buff1,buff);
strcat (buff,"\n");
gtk_text_buffer_get_end_iter(buffer,&end);
//gtk_text_buffer_get_end_iter(buffer,&start);
pthread_mutex_lock(&fichier);//prologue
gtk_text_buffer_insert_at_cursor(buffer,buff, -1);
mark =gtk_text_buffer_get_insert (buffer);
gtk_text_view_scroll_mark_onscreen(text_view,mark);
pthread_mutex_unlock(&fichier);//epilogue
bzero(buff,sizeof(buff));
}
}
//--------------------------------------------------------
int main (int argc, char *argv)
{
/* Initialize GTK+ */
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, (GLogFunc) gtk_false, NULL);
gtk_init (&argc, &argv); g_thread_init(NULL);gdk_threads_init();
g_log_set_handler ("Gtk", G_LOG_LEVEL_WARNING, g_log_default_handler, NULL);
fenetre(argc,&argv);
if(test++==0)
{
if (!g_thread_create(afficher,text_view, FALSE, &error))
{
g_printerr ("Failed to create NO thread: %s\n", error->message);
}
}
/* Enterer à main loop */
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
return 0;
}