server is running, expect more bugs
This commit is contained in:
446
commands.c
Normal file
446
commands.c
Normal file
@@ -0,0 +1,446 @@
|
||||
/*
|
||||
* commands
|
||||
* architecture clients/serveur guinness
|
||||
* Thomas Nemeth -- le 15 juin 2001
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include "config.h"
|
||||
#include "defines.h"
|
||||
#include "xmem.h"
|
||||
#include "tools.h"
|
||||
#include "printlog.h"
|
||||
#include "lists.h"
|
||||
#include "broadcast.h"
|
||||
#include "drinks.h"
|
||||
#include "clients.h"
|
||||
#include "guinnessd.h"
|
||||
#include "commands.h"
|
||||
|
||||
|
||||
extern FILE *logfile;
|
||||
extern int online;
|
||||
extern char *admin_passwd;
|
||||
extern char *chemin;
|
||||
extern Elt *clients_list;
|
||||
extern Elt *drinks_list;
|
||||
|
||||
|
||||
/* Signification des champs de commandes:
|
||||
* NOM AIDE ARGS ADM INTRV FCT
|
||||
*/
|
||||
cmdslst cmds_srv[] = {
|
||||
{"help", "cette page d'aide", FALSE, FALSE, FALSE, f_help},
|
||||
{"quit", "quitter", FALSE, FALSE, FALSE, f_quit},
|
||||
{"list", "liste des clients connectés", FALSE, FALSE, FALSE, f_list},
|
||||
{"blist", "liste des boissons disponibles", FALSE, FALSE, FALSE, f_bevr},
|
||||
{"round", "tournée générale (boisson en option ou préférée)",
|
||||
TRUE, FALSE, FALSE, f_turn},
|
||||
{"cold", "la guinness est servie à - de 10°C, sinon entre 12 et 15",
|
||||
FALSE, FALSE, FALSE, f_cold},
|
||||
{"msg", "message à tous les clients", TRUE, FALSE, FALSE, f_mesg},
|
||||
{"infos", "renvoie les infos du serveur", TRUE, FALSE, FALSE, f_info},
|
||||
{"nick", "change de pseudo", TRUE, FALSE, FALSE, f_nick},
|
||||
{"123456789", "nombre de verres à recevoir (boisson en option ou "
|
||||
"préférée)", FALSE, FALSE, TRUE, f_glas},
|
||||
{"admin", "passer en mode administration", TRUE, FALSE, FALSE, f_sadm},
|
||||
{"33", "arrêter le serveur", FALSE, TRUE, FALSE, f_shut},
|
||||
{"add", "ajoute un utilisateur dans la liste des habitués",
|
||||
TRUE, TRUE, FALSE, f_addu},
|
||||
{"del", "enlève un utilisateur de la liste des habitués",
|
||||
TRUE, TRUE, FALSE, f_delu},
|
||||
{"rldb", "recharge la liste des boissons", FALSE, TRUE, FALSE, f_rldb},
|
||||
{"save", "sauve la liste des habitués", FALSE, TRUE, FALSE, f_save},
|
||||
{"load", "charge la liste des habitués", FALSE, TRUE, FALSE, f_load},
|
||||
{NULL, NULL, FALSE, FALSE, FALSE, NULL}
|
||||
};
|
||||
|
||||
|
||||
|
||||
int security_ok (cmdslst cmd, userinfos infos) {
|
||||
return ( (cmd.adm == FALSE) ||
|
||||
( (cmd.adm == TRUE) && (infos.admin == TRUE) ) );
|
||||
}
|
||||
|
||||
|
||||
int reply (int socket_service, char *commande, userinfos *infos) {
|
||||
int i, cont = TRUE, found = FALSE;
|
||||
|
||||
|
||||
/* Tout d'abord, on remplace \n par \0 ! */
|
||||
for (i = 0 ; i <= strlen (commande) ; i++)
|
||||
if ( (commande[i] == '\n') || (commande[i] == '\r') ) {
|
||||
commande[i] = 0;
|
||||
}
|
||||
|
||||
if (strncmp (commande, "admin ", 6) != 0)
|
||||
printlog (LOG_NOTIFY, "Commande de %s : [%s] (%d)\n",
|
||||
infos->nom,
|
||||
commande,
|
||||
strlen (commande) );
|
||||
else {
|
||||
#ifdef DEBUG
|
||||
printlog (LOG_NOTIFY, "Commande de %s : [%s]\n", infos->nom, commande);
|
||||
#else
|
||||
printlog (LOG_NOTIFY, "Commande de %s : admin XXXXXX\n", infos->nom);
|
||||
#endif
|
||||
}
|
||||
|
||||
fflush (logfile);
|
||||
|
||||
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||
int cmp = -1;
|
||||
cmdslst cmd = cmds_srv[i];
|
||||
|
||||
if ( (cmd.interv) &&
|
||||
( (strlen (commande) == 1) ||
|
||||
(commande[1] == ' ') ) ) {
|
||||
cmp = strchr (cmd.nom, commande[0]) == NULL ? -1 : 0;
|
||||
} else {
|
||||
if (cmd.args)
|
||||
cmp = strncmp (commande, cmd.nom, strlen (cmd.nom) );
|
||||
else
|
||||
cmp = strcmp (commande, cmd.nom);
|
||||
}
|
||||
|
||||
if ( (cmp == 0) && (security_ok (cmd, *infos) == TRUE ) ) {
|
||||
found = TRUE;
|
||||
printlog (LOG_NOTIFY, "Commande reconnue : %s\n", cmd.nom);
|
||||
cont = cmd.fct (socket_service, commande, infos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! found)
|
||||
send_infos (socket_service, "Don't flood me with stupidities !\n");
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int send_servercmds (int socket_service) {
|
||||
char *data;
|
||||
char cmd[MAXSTRLEN];
|
||||
int size = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||
memset (cmd, 0, MAXSTRLEN);
|
||||
if (cmds_srv[i].adm)
|
||||
snprintf (cmd, MAXSTRLEN - 1, "*%s\n", cmds_srv[i].nom);
|
||||
else if (cmds_srv[i].interv)
|
||||
snprintf (cmd, MAXSTRLEN - 1, "+%s\n", cmds_srv[i].nom);
|
||||
else
|
||||
snprintf (cmd, MAXSTRLEN - 1, "%s\n", cmds_srv[i].nom);
|
||||
size += strlen (cmd);
|
||||
}
|
||||
|
||||
data = xmalloc ((size + 1) * sizeof (char));
|
||||
strcpy (data, "");
|
||||
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||
memset (cmd, 0, MAXSTRLEN);
|
||||
if (cmds_srv[i].adm)
|
||||
snprintf (cmd, MAXSTRLEN - 1, "*%s\n", cmds_srv[i].nom);
|
||||
else if (cmds_srv[i].interv)
|
||||
snprintf (cmd, MAXSTRLEN - 1, "+%s\n", cmds_srv[i].nom);
|
||||
else
|
||||
snprintf (cmd, MAXSTRLEN - 1, "%s\n", cmds_srv[i].nom);
|
||||
strcat (data, cmd);
|
||||
}
|
||||
|
||||
return send_infos (socket_service, data);
|
||||
}
|
||||
|
||||
|
||||
int f_help (int socket_service, const char *commande, userinfos *infos) {
|
||||
char *data;
|
||||
char ligne[MAXSTRLEN];
|
||||
int size = 0;
|
||||
int i;
|
||||
|
||||
memset (ligne, 0, MAXSTRLEN);
|
||||
size = strlen ("Commandes (précédées du caractère de commande) :\n");
|
||||
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||
if (security_ok (cmds_srv[i], *infos) == TRUE) {
|
||||
if (cmds_srv[i].args)
|
||||
snprintf (ligne, MAXSTRLEN - 1, " %s [opts]\t: %s\n",
|
||||
cmds_srv[i].nom, cmds_srv[i].aide);
|
||||
else
|
||||
snprintf (ligne, MAXSTRLEN - 1, " %s%s: %s\n",
|
||||
cmds_srv[i].nom,
|
||||
strlen (cmds_srv[i].nom) < 5 ? "\t\t" : "\t",
|
||||
cmds_srv[i].aide);
|
||||
size += strlen (ligne);
|
||||
}
|
||||
}
|
||||
|
||||
data = xmalloc ((size + 1) * sizeof (char));
|
||||
|
||||
strcpy (data, "Commandes (précédées du caractère de commande) :\n");
|
||||
for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
|
||||
if (security_ok (cmds_srv[i], *infos) == TRUE) {
|
||||
if (cmds_srv[i].args)
|
||||
snprintf (ligne, MAXSTRLEN - 1, " %s [opts]\t: %s\n",
|
||||
cmds_srv[i].nom, cmds_srv[i].aide);
|
||||
else
|
||||
snprintf (ligne, MAXSTRLEN - 1, " %s%s: %s\n",
|
||||
cmds_srv[i].nom,
|
||||
strlen (cmds_srv[i].nom) < 5 ? "\t\t" : "\t",
|
||||
cmds_srv[i].aide);
|
||||
strcat (data, ligne);
|
||||
}
|
||||
}
|
||||
|
||||
return send_infos (socket_service, data);
|
||||
}
|
||||
|
||||
|
||||
int f_quit (int socket_service, const char *commande, userinfos *infos) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int f_list (int socket_service, const char *commande, userinfos *infos) {
|
||||
char *data;
|
||||
int cont;
|
||||
|
||||
pthread_mutex_lock (&mutex_clients);
|
||||
data = list_clients ();
|
||||
pthread_mutex_unlock (&mutex_clients);
|
||||
|
||||
cont = send_infos (socket_service, data);
|
||||
free (data);
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_bevr (int socket_service, const char *commande, userinfos *infos) {
|
||||
char *data;
|
||||
int size = 0;
|
||||
int i;
|
||||
int cont;
|
||||
|
||||
size = strlen ("Boissons disponibles :\n");
|
||||
for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
|
||||
size += strlen (elt_number (drinks_list, i) );
|
||||
size += strlen ("\n");
|
||||
}
|
||||
|
||||
data = xmalloc ((size + 1) * sizeof (char));
|
||||
|
||||
strcpy (data, "Boissons disponibles :\n");
|
||||
for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
|
||||
strcat (data, elt_number (drinks_list, i) );
|
||||
strcat (data, "\n");
|
||||
}
|
||||
|
||||
cont = send_infos (socket_service, data);
|
||||
free (data);
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_cold (int socket_service, const char *commande, userinfos *infos) {
|
||||
int cont;
|
||||
|
||||
if (infos->cold == TRUE) {
|
||||
infos->cold = FALSE;
|
||||
cont = send_infos (socket_service, "Température normale.\n");
|
||||
} else {
|
||||
infos->cold = TRUE;
|
||||
cont = send_infos (socket_service, "Température fraîche (10°C).\n");
|
||||
}
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_turn (int socket_service, const char *commande, userinfos *infos) {
|
||||
int cont = TRUE;
|
||||
char *breuv = NULL;
|
||||
|
||||
if (strlen (commande) > 5) breuv = xstrdup (commande+6);
|
||||
|
||||
printlog (LOG_NOTIFY, "Breuvage pour tournée : %s\n",
|
||||
breuv ? breuv : "préféré");
|
||||
|
||||
if ( ( (breuv != NULL) && (exist_elt (drinks_list, breuv) == TRUE) ) ||
|
||||
(breuv == NULL) ) {
|
||||
if (! broadcast (TOURNEE, infos->nom, breuv) )
|
||||
cont = send_infos (socket_service, "Erreur de transmission !\n");
|
||||
} else
|
||||
cont = send_infos (socket_service, "Boisson non disponible !\n");
|
||||
|
||||
free (breuv);
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int f_mesg (int socket_service, const char *commande, userinfos *infos) {
|
||||
int cont = TRUE;
|
||||
|
||||
if (! broadcast (MESSAGE, infos->nom, commande + 4) )
|
||||
cont = send_infos (socket_service, "Erreur de transmission !\n");
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_info (int socket_service, const char *commande, userinfos *infos) {
|
||||
int cont = TRUE;
|
||||
char *data;
|
||||
|
||||
if (strlen (commande) == 5) {
|
||||
data = xmalloc (MAXSTRLEN + 1);
|
||||
snprintf (data, MAXSTRLEN, "guinnessd - v %s (compilation %s : %s)\n",
|
||||
VERSION, OS_TYPE, COMPIL_DATE);
|
||||
} else
|
||||
data = infos_client (infos->admin, commande + 6);
|
||||
|
||||
cont = send_infos (socket_service, data);
|
||||
|
||||
free (data);
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_nick (int socket_service, const char *commande, userinfos *infos) {
|
||||
int cont = TRUE, rename_ok;
|
||||
char *new_nick, *old_nick;
|
||||
|
||||
old_nick = xstrdup (infos->nom);
|
||||
new_nick = xstrdup (commande + 5);
|
||||
|
||||
pthread_mutex_lock (&mutex_clients);
|
||||
rename_ok = rename_client (infos, new_nick);
|
||||
pthread_mutex_unlock (&mutex_clients);
|
||||
|
||||
if (rename_ok) {
|
||||
char texte[MAXSTRLEN + 1];
|
||||
snprintf (texte, MAXSTRLEN, "%s s'appelle maintenant %s.\n",
|
||||
old_nick, new_nick);
|
||||
if (! broadcast (MESSAGE, NULL, texte) )
|
||||
cont = send_infos (socket_service, "Erreur de transmission !\n");
|
||||
} else {
|
||||
cont = send_infos (socket_service, "Pseudo déjà utilisé !\n");
|
||||
}
|
||||
|
||||
free (old_nick);
|
||||
free (new_nick);
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_glas (int socket_service, const char *commande, userinfos *infos) {
|
||||
int i, nb, cont = TRUE;
|
||||
char *breuv;
|
||||
char *data;
|
||||
|
||||
if (strlen (commande) > 2)
|
||||
breuv = xstrdup (commande + 2);
|
||||
else
|
||||
breuv = xstrdup (infos->prefb);
|
||||
|
||||
printlog (LOG_NOTIFY, "Breuvage désiré : %s\n", breuv);
|
||||
|
||||
data = drinks_get (breuv);
|
||||
nb = atoi (commande);
|
||||
for (i = 0 ; i < nb ; i++)
|
||||
if ( (cont = send_infos (socket_service, data) ) == FALSE) break;
|
||||
free (data);
|
||||
free (breuv);
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_sadm (int socket_service, const char *commande, userinfos *infos) {
|
||||
int cont = TRUE;
|
||||
|
||||
if ( (admin_passwd) && (strcmp (admin_passwd, commande + 6) == 0) ) {
|
||||
char message[] = "Vous êtes maintenant ADMINISTRATEUR.\n"
|
||||
"Nouvelles commandes :";
|
||||
char *data;
|
||||
int size = 0, i;
|
||||
|
||||
infos->admin = TRUE;
|
||||
for (i = 0 ; cmds_srv[i].nom != NULL ; i++)
|
||||
if (cmds_srv[i].adm) size += 1 + strlen (cmds_srv[i].nom);
|
||||
|
||||
size += strlen (message);
|
||||
data = xmalloc ((size + 1) * sizeof (char));
|
||||
memset (data, 0, size);
|
||||
|
||||
strcpy (data, message);
|
||||
for (i = 0 ; cmds_srv[i].nom != NULL ; i++)
|
||||
if (cmds_srv[i].adm) {
|
||||
strcat (data, " ");
|
||||
strcat (data, cmds_srv[i].nom);
|
||||
}
|
||||
|
||||
cont = send_infos (socket_service, data);
|
||||
free (data);
|
||||
} else {
|
||||
infos->admin = FALSE;
|
||||
cont = send_infos (socket_service,
|
||||
"Vous n'êtes PLUS administrateur.\n");
|
||||
}
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
|
||||
int f_shut (int socket_service, const char *commande, userinfos *infos) {
|
||||
|
||||
online = FALSE;
|
||||
send_infos (socket_service, "Arrêt en cours...\n");
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
int f_rldb (int socket_service, const char *commande, userinfos *infos) {
|
||||
|
||||
free_list (&drinks_list);
|
||||
add_elt (&drinks_list, "guinness");
|
||||
if (! chemin) chemin = xstrdup (DRINKS_DIR);
|
||||
drinks_list_files (chemin);
|
||||
drinks_display_list ();
|
||||
|
||||
return send_infos (socket_service, "Liste des boissons rechargée...\n");
|
||||
}
|
||||
|
||||
|
||||
int f_addu (int socket_service, const char *commande, userinfos *infos) {
|
||||
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||
}
|
||||
|
||||
int f_delu (int socket_service, const char *commande, userinfos *infos) {
|
||||
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||
}
|
||||
|
||||
int f_save (int socket_service, const char *commande, userinfos *infos) {
|
||||
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||
}
|
||||
|
||||
int f_load (int socket_service, const char *commande, userinfos *infos) {
|
||||
return send_infos (socket_service, "Fonction non implémentée...\n");
|
||||
}
|
||||
Reference in New Issue
Block a user