Browse Source

server is running, expect more bugs

tonton Th 8 months ago
parent
commit
236e274656
10 changed files with 1652 additions and 1 deletions
  1. 5
    0
      .gitignore
  2. 36
    1
      Makefile
  3. 274
    0
      broadcast.c
  4. 196
    0
      clients.c
  5. 446
    0
      commands.c
  6. 126
    0
      drinks.c
  7. 187
    0
      lists.c
  8. 54
    0
      printlog.c
  9. 297
    0
      tools.c
  10. 31
    0
      xmem.c

+ 5
- 0
.gitignore View File

@@ -1 +1,6 @@
1
+
2
+
1 3
 *.o
4
+
5
+guinnessd
6
+

+ 36
- 1
Makefile View File

@@ -9,11 +9,46 @@ H_DEP =	broadcast.h commands.h defines.h guinnessd.h printlog.h 	\
9 9
 
10 10
 COPT =	-Wall -g
11 11
 
12
+D_OBJS = xmem.o broadcast.o printlog.o lists.o tools.o drinks.o		\
13
+	commands.o clients.o
14
+
15
+D_LIBS  = -lpthread -lcrypt
16
+
12 17
 # ---------------------------------------------------------
18
+#
19
+#	Main program
20
+#
21
+
22
+guinnessd:	guinnessd.o Makefile $(D_OBJS)
23
+	gcc -g $<   $(D_OBJS)  $(D_LIBS)     -o $@
13 24
 
14
-guinnessd.o:	guinnessd.c Makefile
25
+guinnessd.o:	guinnessd.c Makefile $(H_DEP)
15 26
 	gcc $(COPT) -c $<  
16 27
 
28
+# ---------------------------------------------------------
29
+#
30
+#	modules needed by the daemon
31
+#
32
+
33
+broadcast.o:	broadcast.c Makefile $(H_DEP)
34
+	gcc $(COPT) -c $<
35
+printlog.o:	printlog.c Makefile $(H_DEP)
36
+	gcc $(COPT) -c $<
37
+lists.o:	lists.c Makefile $(H_DEP)
38
+	gcc $(COPT) -c $<
39
+xmem.o:		xmem.c Makefile $(H_DEP)
40
+	gcc $(COPT) -c $<
41
+tools.o:	tools.c Makefile $(H_DEP)
42
+	gcc $(COPT) -c $<
43
+drinks.o:	drinks.c Makefile $(H_DEP)
44
+	gcc $(COPT) -c $<
45
+commands.o:	commands.c Makefile $(H_DEP)
46
+	gcc $(COPT) -c $<
47
+clients.o:	clients.c Makefile $(H_DEP)
48
+	gcc $(COPT) -c $<
49
+
17 50
 # ---------------------------------------------------------
18 51
 
52
+clients.o:	clients.c Makefile $(H_DEP)
53
+	gcc $(COPT) -c $<
19 54
 

+ 274
- 0
broadcast.c View File

@@ -0,0 +1,274 @@
1
+/*
2
+ * guinnessd
3
+ * architecture clients/serveur guinness : broadcast messages
4
+ * Thomas Nemeth -- le 15 juin 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <unistd.h>
11
+#include <errno.h>
12
+#include <signal.h>
13
+#include <pthread.h>
14
+#include <fcntl.h>
15
+#include <sys/types.h>
16
+#include <sys/socket.h>
17
+#include <netinet/in.h>
18
+#include <string.h>
19
+#include <strings.h>
20
+#include "defines.h"
21
+#include "printlog.h"
22
+#include "xmem.h"
23
+#include "guinnessd.h"
24
+#include "lists.h"
25
+#include "tools.h"
26
+#include "broadcast.h"
27
+#include "drinks.h"
28
+
29
+
30
+extern Elt  *clients_list;
31
+extern FILE *outerr;
32
+
33
+
34
+static int           count = 0;
35
+static unsigned long id = 0;
36
+static Elt          *bdcast_list = NULL;
37
+
38
+
39
+unsigned long get_first_id () {
40
+    unsigned long ret = id;
41
+
42
+    if (bdcast_list) {
43
+        char *first_msg;
44
+        first_msg = elt_number (bdcast_list, 0);
45
+        ret = strtoul (first_msg, (char **)NULL, 10);
46
+    }
47
+
48
+    return ret;
49
+}
50
+
51
+
52
+unsigned long get_last_id () {
53
+    unsigned long ret = id;
54
+
55
+    if (bdcast_list) {
56
+        char *last_msg;
57
+        last_msg = elt_number (bdcast_list, get_nb_elts (bdcast_list) - 1);
58
+        ret = strtoul (last_msg, (char **)NULL, 10);
59
+    }
60
+
61
+    return ret;
62
+}
63
+
64
+
65
+void next_broadcast (int new) {
66
+#ifdef DEBUG
67
+        printlog (LOG_NOTIFY, "Suivant ? (%ld restants / %s)\n",
68
+                  get_nb_elts (bdcast_list), new ? "NEW" : "SUITE");
69
+#endif
70
+    if ( (new && (get_nb_elts (bdcast_list) == 1) ) ||
71
+         ( (!new) && (get_nb_elts (bdcast_list) >= 1) ) ) {
72
+        pthread_mutex_lock (&mutex_clients);
73
+        count = get_nb_elts (clients_list);
74
+        pthread_mutex_unlock (&mutex_clients);
75
+        id = get_last_id ();
76
+#ifdef DEBUG
77
+        printlog (LOG_NOTIFY, "Message en lisse (id = %ld / count = %d)...\n",
78
+                  id, count);
79
+#endif
80
+    }
81
+}
82
+
83
+
84
+int broadcast (int t, const char *f, const char *m) {
85
+    int   taille;
86
+    char  sid[MAXSTRLEN];
87
+    char  stype[MAXSTRLEN];
88
+    char *message;
89
+
90
+    pthread_mutex_lock (&mutex_clients);
91
+    if (get_nb_elts (clients_list) == 0) {
92
+        pthread_mutex_unlock (&mutex_clients);
93
+        return TRUE;
94
+    }
95
+    pthread_mutex_unlock (&mutex_clients);
96
+
97
+    pthread_mutex_lock (&mutex_broadcast);
98
+
99
+    memset (sid, 0, MAXSTRLEN);
100
+    memset (stype, 0, MAXSTRLEN);
101
+    snprintf (sid, MAXSTRLEN - 1, "%ld", get_last_id () + 1);
102
+    snprintf (stype, MAXSTRLEN - 1, "%d", t);
103
+
104
+    taille = (strlen (sid)         +
105
+              strlen (stype)       +
106
+              (f ? strlen (f) : 3) +
107
+              (m ? strlen (m) : 0) +
108
+              5) * sizeof (char);
109
+
110
+    message = xmalloc (taille);
111
+    memset (message, 0, taille);
112
+    /*                          i_| t_| f_| m_  */
113
+    snprintf (message, taille, "%s%s%s%s%s%s%s",
114
+              sid,           SEP,
115
+              stype,         SEP,
116
+              f ? f : "---", SEP,
117
+              m ? m : "");
118
+
119
+    add_elt (&bdcast_list, message);
120
+    free (message);
121
+    next_broadcast (TRUE);
122
+
123
+#ifdef DEBUG
124
+    printlog (LOG_NOTIFY,
125
+              "Broadcast id = %s\t"
126
+              "type = %s\t"
127
+              "de = %s\n",
128
+              sid,
129
+              t == 1 ? "QUITTER" :
130
+              t == 2 ? "TOURNÉE" :
131
+              t == 3 ? "MESSAGE" : "RIEN",
132
+              f);
133
+#endif
134
+
135
+    pthread_mutex_unlock (&mutex_broadcast);
136
+
137
+    return TRUE;
138
+}
139
+
140
+
141
+int new_message (long cid) {
142
+    int res;
143
+
144
+    pthread_mutex_lock (&mutex_broadcast);
145
+    res = (id > cid);
146
+    pthread_mutex_unlock (&mutex_broadcast);
147
+
148
+    return res;
149
+}
150
+
151
+
152
+int get_broadcastid () {
153
+    int res;
154
+
155
+    pthread_mutex_lock (&mutex_broadcast);
156
+    res = id;
157
+    pthread_mutex_unlock (&mutex_broadcast);
158
+
159
+    return res;
160
+}
161
+
162
+
163
+void get_broadcastmsg (int *t, char **f, char **m) {
164
+    char *token, *bdcast, *saveptr;
165
+
166
+    pthread_mutex_lock (&mutex_broadcast);
167
+    bdcast = xstrdup (elt_number (bdcast_list, 0));
168
+    pthread_mutex_unlock (&mutex_broadcast);
169
+
170
+    if (bdcast) {
171
+#ifdef DEBUG
172
+        printf ("Broadcast tokenisation : %s\n", bdcast);
173
+#endif
174
+
175
+        /* id */
176
+        token = strtok_r (bdcast, SEP, &saveptr);
177
+#ifdef DEBUG
178
+        printf ("Reçu : ID      = %s\n", token);
179
+#endif
180
+
181
+        /* type */
182
+        token = strtok_r (NULL, SEP, &saveptr);
183
+#ifdef DEBUG
184
+        printf ("Reçu : TYPE    = %s\n", token);
185
+#endif
186
+        *t = atoi (token);
187
+
188
+        /* from */
189
+        token = strtok_r (NULL, SEP, &saveptr);
190
+#ifdef DEBUG
191
+        printf ("Reçu : FROM    = %s\n", token);
192
+#endif
193
+        *f = NULL;
194
+        if (token) *f = xstrdup (token);
195
+
196
+        /* message */
197
+        token = strtok_r (NULL, SEP, &saveptr);
198
+#ifdef DEBUG
199
+        printf ("Reçu : MESSAGE = %s\n", token);
200
+#endif
201
+        *m = NULL;
202
+        if (token) *m = xstrdup (token);
203
+
204
+        pthread_mutex_lock (&mutex_broadcast);
205
+        if (count > 0) count--;
206
+#ifdef DEBUG
207
+        printf ("count = %d\n", count);
208
+#endif
209
+
210
+        if (count == 0) {
211
+            remove_elt_n (&bdcast_list, 0);
212
+#ifdef DEBUG
213
+            printf ("Suppression du premier élément. Liste = %s\n",
214
+                    bdcast_list ? "OK." : "NULL !");
215
+#endif
216
+            next_broadcast (FALSE);
217
+        }
218
+        pthread_mutex_unlock (&mutex_broadcast);
219
+    }
220
+}
221
+
222
+
223
+int send_broadcast (int socket_service, userinfos *infos) {
224
+    char  datas[MAXSTRLEN];
225
+    char  head[MAXSTRLEN];
226
+    char *from = NULL, *mesg = NULL, *breuv = NULL;
227
+    int   type, cont = TRUE;
228
+
229
+    memset (datas, 0, MAXSTRLEN);
230
+    get_broadcastmsg (&type, &from, &mesg);
231
+
232
+    printlog (LOG_NOTIFY, "Broadcast pour [%s] : %s\n",
233
+              infos->nom,
234
+              type == 1 ? "QUITTER" :
235
+              type == 2 ? "TOURNÉE" :
236
+              type == 3 ? "MESSAGE" :
237
+              "ERREUR");
238
+    printlog (LOG_NOTIFY, "   de [%s] : %s\n", from, mesg ? mesg : "RIEN");
239
+
240
+    switch (type) {
241
+        case QUITTER: /* Un utilisateur se déconnecte */
242
+            snprintf (datas, MAXSTRLEN - 1, "Déconnexion de [%s] : %s",
243
+                      from, mesg);
244
+            break;
245
+        case TOURNEE: /* Tournée générale */
246
+            if (mesg == NULL) {
247
+                snprintf (head, MAXSTRLEN - 1,
248
+                          " -+- Tournée générale offerte par %s ! -+-",
249
+                          from);
250
+                breuv = drinks_get (infos->prefb);
251
+            } else {
252
+                snprintf (head, MAXSTRLEN - 1,
253
+                          " -+- Tournée de %s offerte par %s ! -+-",
254
+                          mesg, from);
255
+                breuv = drinks_get (mesg);
256
+            }
257
+            snprintf (datas, MAXSTRLEN - 1, "%s\n%s%s\n", head, breuv, head);
258
+            free (breuv);
259
+            break;
260
+        case MESSAGE: /* Message */
261
+            snprintf (datas, MAXSTRLEN - 1, "<%s> %s\n", from, mesg);
262
+            break;
263
+        default:
264
+            printlog (LOG_ERROR, "Type de message broadcast non supporté.\n");
265
+            type = -1;
266
+    }
267
+
268
+    if (from) free (from);
269
+    if (mesg) free (mesg);
270
+
271
+    if (type != -1) cont = send_infos (socket_service, datas);
272
+
273
+    return cont;
274
+}

+ 196
- 0
clients.c View File

@@ -0,0 +1,196 @@
1
+/*
2
+ * clients
3
+ * architecture clients/serveur guinness : clients list
4
+ * Thomas Nemeth -- le 15 juin 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <unistd.h>
11
+#include <string.h>
12
+#include <strings.h>
13
+#include "defines.h"
14
+#include "printlog.h"
15
+#include "xmem.h"
16
+#include "guinnessd.h"
17
+#include "lists.h"
18
+#include "tools.h"
19
+#include "clients.h"
20
+
21
+
22
+extern Elt *clients_list;
23
+
24
+void add_client (userinfos *infos) {
25
+    char *datas;
26
+    int   size;
27
+
28
+    size = strlen (infos->nom);
29
+    size += strlen (infos->prefb);
30
+    size += strlen (infos->cxdate);
31
+    size += strlen (infos->host);
32
+    size += strlen (infos->ip);
33
+    size += 5 * strlen (SEP) + 10;
34
+
35
+    datas = xmalloc (size + 1);
36
+
37
+    sprintf (datas, "%s%s%s%s%s%s%s%s%s%s%d",
38
+             infos->nom,    SEP,
39
+             infos->prefb,  SEP,
40
+             infos->cxdate, SEP,
41
+             infos->host,   SEP,
42
+             infos->ip,     SEP,
43
+             infos->port);
44
+
45
+    add_elt (&clients_list, datas);
46
+
47
+#ifdef DEBUG
48
+    printf ("Taille des éléments :\n"
49
+            "nom   : %d [%s]\n"
50
+            "bière : %d [%s]\n"
51
+            "date  : %d [%s]\n"
52
+            "hôte  : %d [%s]\n"
53
+            "ip    : %d [%s]\n",
54
+            strlen (infos->nom), infos->nom,
55
+            strlen (infos->prefb), infos->prefb,
56
+            strlen (infos->cxdate), infos->cxdate,
57
+            strlen (infos->host), infos->host,
58
+            strlen (infos->ip), infos->ip);
59
+
60
+    printf ("Ajout des infos : size = %d -- [%s]\n", size, datas);
61
+#endif
62
+
63
+    free (datas);
64
+}
65
+
66
+
67
+void remove_client (userinfos *infos) {
68
+    remove_elt (&clients_list, infos->nom);
69
+}
70
+
71
+
72
+int rename_client (userinfos *infos, const char *new_nick) {
73
+    if (exist_elt (clients_list, new_nick)) return FALSE;
74
+    remove_elt (&clients_list, infos->nom);
75
+    snprintf (infos->nom, MAXSTRLEN, "%s", new_nick);
76
+    add_client (infos);
77
+    return TRUE;
78
+}
79
+
80
+
81
+char *list_clients () {
82
+    char *list;
83
+    char *lstelt;
84
+    char *rt;
85
+    char  text[MAXSTRLEN + 1];
86
+    int   size;
87
+    int   i;
88
+
89
+    size = strlen ("Client(s) connecté(s) :\n");
90
+    for (i = 0 ; i < get_nb_elts (clients_list) ; i++) {
91
+        lstelt = elt_number (clients_list, i);
92
+        rt = strstr (lstelt, SEP);
93
+        strncpy (text, lstelt, rt - lstelt);
94
+        text[rt - lstelt] = 0;
95
+        size += 1 + strlen (text);
96
+    }
97
+
98
+    list = xmalloc ((size + 1) * sizeof (char));
99
+
100
+    strcpy (list, "Client(s) connecté(s) :\n");
101
+    for (i = 0 ; i < get_nb_elts (clients_list) ; i++) {
102
+        lstelt = elt_number (clients_list, i);
103
+        rt = strstr (lstelt, SEP);
104
+        strncpy (text, lstelt, rt - lstelt);
105
+        text[rt - lstelt] = 0;
106
+        strcat (list, text);
107
+        strcat (list, "\n");
108
+    }
109
+
110
+    return list;
111
+}
112
+
113
+char *infos_client (int admin, const char *nick) {
114
+    char *datas;
115
+    char *infos;
116
+    char *token, *use, *saveptr;
117
+    char *nom  = NULL, *biere = NULL, *date = NULL;
118
+    char *host = NULL, *ip    = NULL, *port = NULL;
119
+    int   size = 0;
120
+
121
+    infos = get_elt (clients_list, nick);
122
+    if (! infos) {
123
+        datas = xmalloc (strlen (nick) + strlen (" : pseudo inconnu !\n"));
124
+        sprintf (datas, "%s : pseudo inconnu !\n", nick);
125
+        return datas;
126
+    }
127
+
128
+    use = xstrdup (infos);
129
+
130
+    /* nom */
131
+    token = strtok_r (use, SEP, &saveptr);
132
+    if (token) nom = xstrdup (token);
133
+
134
+    /* bière */
135
+    token = strtok_r (NULL, SEP, &saveptr);
136
+    if (token) biere = xstrdup (token);
137
+
138
+    /* date */
139
+    token = strtok_r (NULL, SEP, &saveptr);
140
+    if (token) date = xstrdup (token);
141
+
142
+    /* hôte */
143
+    token = strtok_r (NULL, SEP, &saveptr);
144
+    if (token) host = xstrdup (token);
145
+
146
+    /* ip */
147
+    token = strtok_r (NULL, SEP, &saveptr);
148
+    if (token) ip = xstrdup (token);
149
+
150
+    /* port */
151
+    token = strtok_r (NULL, SEP, &saveptr);
152
+    if (token) port = xstrdup (token);
153
+
154
+    size += strlen ("Pseudo    : ");
155
+    size += strlen ("Bière     : ");
156
+    size += strlen ("Connexion : ");
157
+    size += 1 + (nom   ? strlen (nom)   : 1);
158
+    size += 1 + (biere ? strlen (biere) : 1);
159
+    size += 1 + (date  ? strlen (date)  : 1);
160
+    if (admin) {
161
+        size += strlen ("Hôte      : ");
162
+        size += strlen ("IP        : ");
163
+        size += strlen ("Port      : ");
164
+        size += 1 + (host ? strlen (host) : 1);
165
+        size += 1 + (ip   ? strlen (ip)   : 1);
166
+        size += 1 + (port ? strlen (port) : 1);
167
+    }
168
+
169
+    datas = xmalloc (size + 1);
170
+
171
+    sprintf (datas,
172
+             "Pseudo    : %s\n"
173
+             "Bière     : %s\n"
174
+             "Connexion : %s\n",
175
+             nom   ? nom   : "-",
176
+             biere ? biere : "-",
177
+             date  ? date  : "-");
178
+    if (admin)
179
+        sprintf (datas, "%s"
180
+                 "Hôte      : %s\n"
181
+                 "IP        : %s\n"
182
+                 "Port      : %s\n",
183
+                 datas,
184
+                 host ? host : "-",
185
+                 ip   ? ip   : "-",
186
+                 port ? port : "-");
187
+
188
+    if (nom)   free (nom);
189
+    if (biere) free (biere);
190
+    if (date)  free (date);
191
+    if (host)  free (host);
192
+    if (ip)    free (ip);
193
+    if (port)  free (port);
194
+
195
+    return datas;
196
+}

+ 446
- 0
commands.c View File

@@ -0,0 +1,446 @@
1
+/*
2
+ * commands
3
+ * architecture clients/serveur guinness
4
+ * Thomas Nemeth -- le 15 juin 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <unistd.h>
11
+#include <errno.h>
12
+#include <signal.h>
13
+#include <pthread.h>
14
+#include <fcntl.h>
15
+#include <sys/types.h>
16
+#include <sys/socket.h>
17
+#include <netinet/in.h>
18
+#include <string.h>
19
+#include <strings.h>
20
+#include "config.h"
21
+#include "defines.h"
22
+#include "xmem.h"
23
+#include "tools.h"
24
+#include "printlog.h"
25
+#include "lists.h"
26
+#include "broadcast.h"
27
+#include "drinks.h"
28
+#include "clients.h"
29
+#include "guinnessd.h"
30
+#include "commands.h"
31
+
32
+
33
+extern FILE *logfile;
34
+extern int   online;
35
+extern char *admin_passwd;
36
+extern char *chemin;
37
+extern Elt  *clients_list;
38
+extern Elt  *drinks_list;
39
+
40
+
41
+/* Signification des champs de commandes:
42
+ *   NOM     AIDE                               ARGS   ADM    INTRV  FCT
43
+ */
44
+cmdslst cmds_srv[] = {
45
+    {"help",  "cette page d'aide",              FALSE, FALSE, FALSE, f_help},
46
+    {"quit",  "quitter",                        FALSE, FALSE, FALSE, f_quit},
47
+    {"list",  "liste des clients connectés",    FALSE, FALSE, FALSE, f_list},
48
+    {"blist", "liste des boissons disponibles", FALSE, FALSE, FALSE, f_bevr},
49
+    {"round", "tournée générale (boisson en option ou préférée)",
50
+                                                TRUE,  FALSE, FALSE, f_turn},
51
+    {"cold",  "la guinness est servie à - de 10°C, sinon entre 12 et 15",
52
+                                                FALSE, FALSE, FALSE, f_cold},
53
+    {"msg",   "message à tous les clients",     TRUE,  FALSE, FALSE, f_mesg},
54
+    {"infos", "renvoie les infos du serveur",   TRUE,  FALSE, FALSE, f_info},
55
+    {"nick",  "change de pseudo",               TRUE,  FALSE, FALSE, f_nick},
56
+    {"123456789", "nombre de verres à recevoir (boisson en option ou "
57
+     "préférée)",                               FALSE, FALSE, TRUE,  f_glas},
58
+    {"admin", "passer en mode administration",  TRUE,  FALSE, FALSE, f_sadm},
59
+    {"33", "arrêter le serveur",                FALSE, TRUE,  FALSE, f_shut},
60
+    {"add", "ajoute un utilisateur dans la liste des habitués",
61
+                                                TRUE,  TRUE,  FALSE, f_addu},
62
+    {"del", "enlève un utilisateur de la liste des habitués",
63
+                                                TRUE,  TRUE,  FALSE, f_delu},
64
+    {"rldb", "recharge la liste des boissons",  FALSE, TRUE,  FALSE, f_rldb},
65
+    {"save", "sauve la liste des habitués",     FALSE, TRUE,  FALSE, f_save},
66
+    {"load", "charge la liste des habitués",    FALSE, TRUE,  FALSE, f_load},
67
+    {NULL, NULL, FALSE, FALSE, FALSE, NULL}
68
+};
69
+
70
+
71
+
72
+int security_ok (cmdslst cmd, userinfos infos) {
73
+    return ( (cmd.adm == FALSE) ||
74
+             ( (cmd.adm == TRUE) && (infos.admin == TRUE) ) );
75
+}
76
+
77
+
78
+int reply (int socket_service, char *commande, userinfos *infos) {
79
+    int  i, cont = TRUE, found = FALSE;
80
+
81
+
82
+    /* Tout d'abord, on remplace \n par \0 ! */
83
+    for (i = 0 ; i <= strlen (commande) ; i++)
84
+        if ( (commande[i] == '\n') || (commande[i] == '\r') ) {
85
+            commande[i] = 0;
86
+        }
87
+
88
+    if (strncmp (commande, "admin ", 6) != 0)
89
+        printlog (LOG_NOTIFY, "Commande de %s : [%s] (%d)\n",
90
+                 infos->nom,
91
+                 commande,
92
+                 strlen (commande) );
93
+    else {
94
+#ifdef DEBUG
95
+        printlog (LOG_NOTIFY, "Commande de %s : [%s]\n", infos->nom, commande);
96
+#else
97
+        printlog (LOG_NOTIFY, "Commande de %s : admin XXXXXX\n", infos->nom);
98
+#endif
99
+    }
100
+
101
+    fflush (logfile);
102
+
103
+    for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
104
+        int      cmp = -1;
105
+        cmdslst  cmd = cmds_srv[i];
106
+
107
+        if ( (cmd.interv) &&
108
+             ( (strlen (commande) == 1) ||
109
+                 (commande[1] == ' ') ) ) {
110
+            cmp = strchr (cmd.nom, commande[0]) == NULL ? -1 : 0;
111
+        } else {
112
+            if (cmd.args)
113
+                cmp = strncmp (commande, cmd.nom, strlen (cmd.nom) );
114
+            else
115
+                cmp = strcmp (commande, cmd.nom);
116
+        }
117
+
118
+        if ( (cmp == 0) && (security_ok (cmd, *infos) == TRUE ) ) {
119
+            found = TRUE;
120
+            printlog (LOG_NOTIFY, "Commande reconnue : %s\n", cmd.nom);
121
+            cont = cmd.fct (socket_service, commande, infos);
122
+            break;
123
+        }
124
+    }
125
+
126
+    if (! found)
127
+        send_infos (socket_service, "Don't flood me with stupidities !\n");
128
+
129
+    return cont;
130
+}
131
+
132
+
133
+int send_servercmds (int socket_service) {
134
+    char *data;
135
+    char  cmd[MAXSTRLEN];
136
+    int   size = 0;
137
+    int   i;
138
+
139
+    for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
140
+        memset (cmd, 0, MAXSTRLEN);
141
+        if (cmds_srv[i].adm)
142
+            snprintf (cmd, MAXSTRLEN - 1, "*%s\n", cmds_srv[i].nom);
143
+        else if (cmds_srv[i].interv)
144
+            snprintf (cmd, MAXSTRLEN - 1, "+%s\n", cmds_srv[i].nom);
145
+        else
146
+            snprintf (cmd, MAXSTRLEN - 1, "%s\n", cmds_srv[i].nom);
147
+        size += strlen (cmd);
148
+    }
149
+
150
+    data = xmalloc ((size + 1) * sizeof (char));
151
+    strcpy (data, "");
152
+    for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
153
+        memset (cmd, 0, MAXSTRLEN);
154
+        if (cmds_srv[i].adm)
155
+            snprintf (cmd, MAXSTRLEN - 1, "*%s\n", cmds_srv[i].nom);
156
+        else if (cmds_srv[i].interv)
157
+            snprintf (cmd, MAXSTRLEN - 1, "+%s\n", cmds_srv[i].nom);
158
+        else
159
+            snprintf (cmd, MAXSTRLEN - 1, "%s\n", cmds_srv[i].nom);
160
+        strcat (data, cmd);
161
+    }
162
+
163
+    return send_infos (socket_service, data);
164
+}
165
+
166
+
167
+int f_help (int socket_service, const char *commande, userinfos *infos) {
168
+    char *data;
169
+    char  ligne[MAXSTRLEN];
170
+    int   size = 0;
171
+    int   i;
172
+
173
+    memset (ligne, 0, MAXSTRLEN);
174
+    size = strlen ("Commandes (précédées du caractère de commande) :\n");
175
+    for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
176
+        if (security_ok (cmds_srv[i], *infos) == TRUE) {
177
+            if (cmds_srv[i].args)
178
+                snprintf (ligne, MAXSTRLEN - 1, "   %s [opts]\t: %s\n",
179
+                         cmds_srv[i].nom, cmds_srv[i].aide);
180
+            else
181
+                snprintf (ligne, MAXSTRLEN - 1, "   %s%s: %s\n",
182
+                          cmds_srv[i].nom,
183
+                          strlen (cmds_srv[i].nom) < 5 ? "\t\t" : "\t",
184
+                          cmds_srv[i].aide);
185
+            size += strlen (ligne);
186
+        }
187
+    }
188
+
189
+    data = xmalloc ((size + 1) * sizeof (char));
190
+
191
+    strcpy (data, "Commandes (précédées du caractère de commande) :\n");
192
+    for (i = 0 ; cmds_srv[i].nom != NULL ; i++) {
193
+        if (security_ok (cmds_srv[i], *infos) == TRUE) {
194
+            if (cmds_srv[i].args)
195
+                snprintf (ligne, MAXSTRLEN - 1, "   %s [opts]\t: %s\n",
196
+                         cmds_srv[i].nom, cmds_srv[i].aide);
197
+            else
198
+                snprintf (ligne, MAXSTRLEN - 1, "   %s%s: %s\n",
199
+                          cmds_srv[i].nom,
200
+                          strlen (cmds_srv[i].nom) < 5 ? "\t\t" : "\t",
201
+                          cmds_srv[i].aide);
202
+            strcat (data, ligne);
203
+        }
204
+    }
205
+
206
+    return send_infos (socket_service, data);
207
+}
208
+
209
+
210
+int f_quit (int socket_service, const char *commande, userinfos *infos) {
211
+    return FALSE;
212
+}
213
+
214
+
215
+int f_list (int socket_service, const char *commande, userinfos *infos) {
216
+    char *data;
217
+    int   cont;
218
+
219
+    pthread_mutex_lock (&mutex_clients);
220
+    data = list_clients ();
221
+    pthread_mutex_unlock (&mutex_clients);
222
+
223
+    cont = send_infos (socket_service, data);
224
+    free (data);
225
+
226
+    return cont;
227
+}
228
+
229
+
230
+int f_bevr (int socket_service, const char *commande, userinfos *infos) {
231
+    char *data;
232
+    int   size = 0;
233
+    int   i;
234
+    int   cont;
235
+
236
+    size = strlen ("Boissons disponibles :\n");
237
+    for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
238
+        size += strlen (elt_number (drinks_list, i) );
239
+        size += strlen ("\n");
240
+    }
241
+
242
+    data = xmalloc ((size + 1) * sizeof (char));
243
+
244
+    strcpy (data, "Boissons disponibles :\n");
245
+    for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
246
+        strcat (data, elt_number (drinks_list, i) );
247
+        strcat (data, "\n");
248
+    }
249
+
250
+    cont = send_infos (socket_service, data);
251
+    free (data);
252
+
253
+    return cont;
254
+}
255
+
256
+
257
+int f_cold (int socket_service, const char *commande, userinfos *infos) {
258
+    int cont;
259
+
260
+    if (infos->cold == TRUE) {
261
+        infos->cold = FALSE;
262
+        cont = send_infos (socket_service, "Température normale.\n");
263
+    } else {
264
+        infos->cold = TRUE;
265
+        cont = send_infos (socket_service, "Température fraîche (10°C).\n");
266
+    }
267
+
268
+    return cont;
269
+}
270
+
271
+
272
+int f_turn (int socket_service, const char *commande, userinfos *infos) {
273
+    int cont = TRUE;
274
+    char *breuv = NULL;
275
+
276
+    if (strlen (commande) > 5) breuv = xstrdup (commande+6);
277
+
278
+    printlog (LOG_NOTIFY, "Breuvage pour tournée : %s\n",
279
+             breuv ? breuv : "préféré");
280
+
281
+    if ( ( (breuv != NULL) && (exist_elt (drinks_list, breuv) == TRUE) ) ||
282
+         (breuv == NULL) ) {
283
+        if (! broadcast (TOURNEE, infos->nom, breuv) )
284
+            cont = send_infos (socket_service, "Erreur de transmission !\n");
285
+    } else
286
+        cont = send_infos (socket_service, "Boisson non disponible !\n");
287
+
288
+    free (breuv);
289
+
290
+    return cont;
291
+}
292
+
293
+
294
+
295
+int f_mesg (int socket_service, const char *commande, userinfos *infos) {
296
+    int cont = TRUE;
297
+
298
+    if (! broadcast (MESSAGE, infos->nom, commande + 4) )
299
+        cont = send_infos (socket_service, "Erreur de transmission !\n");
300
+
301
+    return cont;
302
+}
303
+
304
+
305
+int f_info (int socket_service, const char *commande, userinfos *infos) {
306
+    int   cont = TRUE;
307
+    char *data;
308
+
309
+    if (strlen (commande) == 5) {
310
+        data = xmalloc (MAXSTRLEN + 1);
311
+        snprintf (data, MAXSTRLEN, "guinnessd - v %s (compilation %s : %s)\n",
312
+                  VERSION, OS_TYPE, COMPIL_DATE);
313
+    } else
314
+        data = infos_client (infos->admin, commande + 6);
315
+
316
+    cont = send_infos (socket_service, data);
317
+
318
+    free (data);
319
+
320
+    return cont;
321
+}
322
+
323
+
324
+int f_nick (int socket_service, const char *commande, userinfos *infos) {
325
+    int   cont = TRUE, rename_ok;
326
+    char *new_nick, *old_nick;
327
+
328
+    old_nick = xstrdup (infos->nom);
329
+    new_nick = xstrdup (commande + 5);
330
+
331
+    pthread_mutex_lock (&mutex_clients);
332
+    rename_ok = rename_client (infos, new_nick);
333
+    pthread_mutex_unlock (&mutex_clients);
334
+
335
+    if (rename_ok) {
336
+        char texte[MAXSTRLEN + 1];
337
+        snprintf (texte, MAXSTRLEN, "%s s'appelle maintenant %s.\n",
338
+                  old_nick, new_nick);
339
+        if (! broadcast (MESSAGE, NULL, texte) )
340
+            cont = send_infos (socket_service, "Erreur de transmission !\n");
341
+    } else {
342
+        cont = send_infos (socket_service, "Pseudo déjà utilisé !\n");
343
+    }
344
+
345
+    free (old_nick);
346
+    free (new_nick);
347
+
348
+    return cont;
349
+}
350
+
351
+
352
+int f_glas (int socket_service, const char *commande, userinfos *infos) {
353
+    int   i, nb, cont = TRUE;
354
+    char *breuv;
355
+    char *data;
356
+
357
+    if (strlen (commande) > 2)
358
+        breuv = xstrdup (commande + 2);
359
+    else
360
+        breuv = xstrdup (infos->prefb);
361
+
362
+    printlog (LOG_NOTIFY, "Breuvage désiré : %s\n", breuv);
363
+
364
+    data = drinks_get (breuv);
365
+    nb = atoi (commande);
366
+    for (i = 0 ; i < nb ; i++)
367
+        if ( (cont = send_infos (socket_service, data) ) == FALSE) break;
368
+    free (data);
369
+    free (breuv);
370
+
371
+    return cont;
372
+}
373
+
374
+
375
+int f_sadm (int socket_service, const char *commande, userinfos *infos) {
376
+    int   cont = TRUE;
377
+
378
+    if ( (admin_passwd) && (strcmp (admin_passwd, commande + 6) == 0) ) {
379
+        char message[] = "Vous êtes maintenant ADMINISTRATEUR.\n"
380
+                         "Nouvelles commandes :";
381
+        char *data;
382
+        int   size = 0, i;
383
+
384
+        infos->admin = TRUE;
385
+        for (i = 0 ; cmds_srv[i].nom != NULL ; i++)
386
+            if (cmds_srv[i].adm) size += 1 + strlen (cmds_srv[i].nom);
387
+
388
+        size += strlen (message);
389
+        data = xmalloc ((size + 1) * sizeof (char));
390
+        memset (data, 0, size);
391
+
392
+        strcpy (data, message);
393
+        for (i = 0 ; cmds_srv[i].nom != NULL ; i++)
394
+            if (cmds_srv[i].adm) {
395
+                strcat (data, " ");
396
+                strcat (data, cmds_srv[i].nom);
397
+            }
398
+
399
+        cont = send_infos (socket_service, data);
400
+        free (data);
401
+    } else {
402
+        infos->admin = FALSE;
403
+        cont = send_infos (socket_service,
404
+                           "Vous n'êtes PLUS administrateur.\n");
405
+    }
406
+
407
+    return cont;
408
+}
409
+
410
+
411
+int f_shut (int socket_service, const char *commande, userinfos *infos) {
412
+
413
+    online = FALSE;
414
+    send_infos (socket_service, "Arrêt en cours...\n");
415
+
416
+    return FALSE;
417
+}
418
+
419
+
420
+int f_rldb (int socket_service, const char *commande, userinfos *infos) {
421
+
422
+    free_list (&drinks_list);
423
+    add_elt (&drinks_list, "guinness");
424
+    if (! chemin) chemin = xstrdup (DRINKS_DIR);
425
+    drinks_list_files (chemin);
426
+    drinks_display_list ();
427
+
428
+    return send_infos (socket_service, "Liste des boissons rechargée...\n");
429
+}
430
+
431
+
432
+int f_addu (int socket_service, const char *commande, userinfos *infos) {
433
+    return send_infos (socket_service, "Fonction non implémentée...\n");
434
+}
435
+
436
+int f_delu (int socket_service, const char *commande, userinfos *infos) {
437
+    return send_infos (socket_service, "Fonction non implémentée...\n");
438
+}
439
+
440
+int f_save (int socket_service, const char *commande, userinfos *infos) {
441
+    return send_infos (socket_service, "Fonction non implémentée...\n");
442
+}
443
+
444
+int f_load (int socket_service, const char *commande, userinfos *infos) {
445
+    return send_infos (socket_service, "Fonction non implémentée...\n");
446
+}

+ 126
- 0
drinks.c View File

@@ -0,0 +1,126 @@
1
+/*
2
+ * drinks
3
+ * architecture clients/serveur guinness
4
+ * Thomas Nemeth -- le 15 juin 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <string.h>
11
+#include <strings.h>
12
+#include <dirent.h>
13
+#include <unistd.h>
14
+#include <sys/stat.h>
15
+#include "defines.h"
16
+#include "xmem.h"
17
+#include "printlog.h"
18
+#include "lists.h"
19
+#include "drinks.h"
20
+#include "pint.h"
21
+
22
+extern char *pinte;
23
+extern char *chemin;
24
+extern Elt  *drinks_list;
25
+extern FILE *logfile;
26
+extern FILE *outerr;
27
+
28
+
29
+char *drinks_get_from_file (const char *nom) {
30
+    struct stat  fileinfos;
31
+    char         filename[MAXSTRLEN + 1];
32
+    char        *datas;
33
+    FILE        *fichier;
34
+
35
+    snprintf (filename, MAXSTRLEN, "%s/%s", chemin, nom);
36
+    if (stat (filename, &fileinfos) == -1) {
37
+        printlog (LOG_ERROR, "Accès impossible au fichier [%s]\n",
38
+                 filename);
39
+        perror ("stat ");
40
+        return NULL;
41
+    }
42
+
43
+    if ( (fichier = fopen (filename, "r")) == NULL) return NULL;
44
+    datas = xmalloc ((fileinfos.st_size + 3) * sizeof (char));
45
+    memset (datas, 0, fileinfos.st_size + 3);
46
+    fread (datas, sizeof (char), fileinfos.st_size, fichier);
47
+    fclose (fichier);
48
+
49
+    return datas;
50
+}
51
+
52
+
53
+char *drinks_get (const char *nom) {
54
+    char *breuvage = NULL;
55
+    int   i;
56
+
57
+    if (nom == NULL) return NULL;
58
+
59
+    /* Élément 0 (Guinness) disponible par défaut */
60
+    if (strcmp (nom, "guinness")  == 0) breuvage = xstrdup (pinte);
61
+
62
+    /* Sinon on cherche dans la liste des fichiers :
63
+     * on commence à 1 pour éviter la pinte de Guinness qui est traitée
64
+     * juste avant.
65
+     */
66
+    if (! breuvage) {
67
+        for (i = 1 ; i < get_nb_elts (drinks_list) ; i++)
68
+            if (strcmp (nom, elt_number (drinks_list, i)) == 0)
69
+                breuvage = drinks_get_from_file (nom);
70
+    }
71
+
72
+    /* Dernier cas : on n'a rien trouvé => pinte par défaut */
73
+    if (! breuvage) breuvage = xstrdup (pinte);
74
+
75
+    return breuvage;
76
+}
77
+
78
+void drinks_list_files (const char *path) {
79
+    DIR           *rep;
80
+    struct dirent *dirinfos;
81
+    struct stat    fileinfos;
82
+    int            nbfiles = 0;
83
+    char           filename[MAXSTRLEN + 1];
84
+
85
+    if ( (rep = opendir (path)) == NULL) {
86
+        printlog (LOG_ERROR, "Impossible d'ouvrir le répertoire [%s]\n", path);
87
+#ifdef DEBUG
88
+        perror ("opendir ");
89
+#endif
90
+        return;
91
+    }
92
+
93
+    printlog (LOG_NOTIFY, "Liste des fichiers à intégrer :\n");
94
+    while ((dirinfos = readdir (rep)) != NULL) {
95
+        snprintf (filename, MAXSTRLEN, "%s/%s", path, dirinfos->d_name);
96
+        if (stat (filename, &fileinfos) == -1) {
97
+            printlog (LOG_ERROR, "Accès impossible au fichier [%s]\n",
98
+                     filename);
99
+#ifdef DEBUG
100
+            perror ("stat ");
101
+#endif
102
+        }
103
+        if ( (dirinfos->d_name[0] != '.') &&
104
+             ( (fileinfos.st_mode & S_IFMT) == S_IFREG) ) {
105
+            printlog (LOG_NOTIFY, "   fichier : [%s]\n",
106
+                     dirinfos->d_name);
107
+            add_elt (&drinks_list, dirinfos->d_name);
108
+            nbfiles++;
109
+        }
110
+    }
111
+    printlog (LOG_NOTIFY, "Fin de la liste : %d fichier%s.\n",
112
+             nbfiles, nbfiles > 1 ? "s" : "");
113
+    closedir (rep);
114
+}
115
+
116
+
117
+void drinks_display_list () {
118
+    int   i;
119
+    char *breuvage;
120
+
121
+    printlog (LOG_NOTIFY, "Boissons disponibles :\n");
122
+    for (i = 0 ; i < get_nb_elts (drinks_list) ; i++) {
123
+        breuvage = elt_number (drinks_list, i);
124
+        printlog (LOG_NOTIFY, "%d\t: %s\n", i, breuvage);
125
+    }
126
+}

+ 187
- 0
lists.c View File

@@ -0,0 +1,187 @@
1
+/*
2
+ * lists
3
+ * architecture clients/serveur guinness
4
+ * Thomas Nemeth -- le 15 juin 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <string.h>
11
+#include <strings.h>
12
+#include "defines.h"
13
+#include "xmem.h"
14
+#include "lists.h"
15
+
16
+
17
+void add_elt (Elt **elt, const char *nom) {
18
+    Elt *e;
19
+
20
+    if (*elt == NULL) {
21
+        *elt = xmalloc ((1) * sizeof (Elt));
22
+        (*elt)->nom = xstrdup (nom);
23
+        (*elt)->next = NULL;
24
+    } else {
25
+        e = *elt;
26
+        while (e->next != NULL) e = e->next;
27
+        e->next = xmalloc ((1) * sizeof (Elt));
28
+        e       = e->next;
29
+        e->nom  = xstrdup (nom);
30
+        e->next = NULL;
31
+    }
32
+}
33
+
34
+
35
+void remove_elt (Elt **elt, const char *nom) {
36
+    Elt  *e = *elt, *p = NULL;
37
+    int   res = FALSE;
38
+    char *rt, *text ;
39
+
40
+    do {
41
+        if (e != NULL) {
42
+            if ((rt = strstr (e->nom, SEP)) != NULL) {
43
+                text = xmalloc (rt - e->nom + 2);
44
+                memset (text, 0, rt - e->nom + 2);
45
+                strncpy (text, e->nom, rt - e->nom);
46
+#ifdef DEBUG
47
+                printf ("Comparaison (l) de [%s] avec [%s]\n", text, nom);
48
+#endif
49
+                res = (strcmp (text, nom) == 0);
50
+                free (text);
51
+            } else {
52
+#ifdef DEBUG
53
+                printf ("Comparaison (c) de [%s] avec [%s]\n", e->nom, nom);
54
+#endif
55
+                res = (strcmp (e->nom, nom) == 0);
56
+            }
57
+            if (res == FALSE) {
58
+                p = e;
59
+                e = e->next;
60
+            }
61
+        }
62
+    } while ( (e != NULL) && (res != TRUE) );
63
+
64
+    if (e == NULL) return;
65
+    if (e == *elt) *elt = e->next;
66
+    if (p) p->next = e->next;
67
+    free (e->nom);
68
+    free (e);
69
+}
70
+
71
+
72
+void remove_elt_n (Elt **elt, int i) {
73
+    Elt *e = *elt, *p = NULL;
74
+    int  n = 0;
75
+
76
+    while ( (e != NULL) && (n != i) ) {
77
+        n++;
78
+        e = e->next;
79
+    }
80
+    if (e == NULL) return;
81
+    if (e == *elt) *elt = e->next;
82
+    if (p) p->next = e->next;
83
+    free (e->nom);
84
+    free (e);
85
+}
86
+
87
+
88
+int get_nb_elts (Elt *elt) {
89
+    Elt *e = elt;
90
+    int  n = 0;
91
+
92
+    while (e != NULL) {
93
+        n++;
94
+        e = e->next;
95
+    }
96
+
97
+    return n;
98
+}
99
+
100
+
101
+char *elt_number (Elt *elt, int i) {
102
+    Elt *e = elt;
103
+    int  n = 0;
104
+
105
+    while ( (e != NULL) && (n != i) ) {
106
+        n++;
107
+        e = e->next;
108
+    }
109
+    if (e == NULL) return NULL;
110
+
111
+    return e->nom;
112
+}
113
+
114
+
115
+int exist_elt (Elt *elt, const char *nom) {
116
+    Elt  *e   = elt;
117
+    int   res = FALSE;
118
+    char *rt, *text ;
119
+
120
+    do {
121
+        if (e != NULL) {
122
+            if ((rt = strstr (e->nom, SEP)) != NULL) {
123
+                text = xmalloc (rt - e->nom + 2);
124
+                memset (text, 0, rt - e->nom + 2);
125
+                strncpy (text, e->nom, rt - e->nom);
126
+#ifdef DEBUG
127
+                printf ("Comparaison (l) de [%s] avec [%s]\n", text, nom);
128
+#endif
129
+                res = (strcmp (text, nom) == 0);
130
+                free (text);
131
+            } else {
132
+#ifdef DEBUG
133
+                printf ("Comparaison (c) de [%s] avec [%s]\n", e->nom, nom);
134
+#endif
135
+                res = (strcmp (e->nom, nom) == 0);
136
+            }
137
+            e = e->next;
138
+        }
139
+    } while ( (e != NULL) && (res != TRUE) );
140
+
141
+    return res;
142
+}
143
+
144
+
145
+char *get_elt (Elt *elt, const char *nom) {
146
+    Elt  *e = elt;
147
+    int   res = FALSE;
148
+    char *rt, *text ;
149
+
150
+    do {
151
+        if (e != NULL) {
152
+            if ((rt = strstr (e->nom, SEP)) != NULL) {
153
+                text = xmalloc (rt - e->nom + 2);
154
+                memset (text, 0, rt - e->nom + 2);
155
+                strncpy (text, e->nom, rt - e->nom);
156
+#ifdef DEBUG
157
+                printf ("Comparaison (l) de [%s] avec [%s]\n", text, nom);
158
+#endif
159
+                res = (strcmp (text, nom) == 0);
160
+                free (text);
161
+            } else {
162
+#ifdef DEBUG
163
+                printf ("Comparaison (c) de [%s] avec [%s]\n", e->nom, nom);
164
+#endif
165
+                res = (strcmp (e->nom, nom) == 0);
166
+            }
167
+            if (res == FALSE) e = e->next;
168
+        }
169
+    } while ( (e != NULL) && (res != TRUE) );
170
+
171
+    if (e == NULL) return NULL;
172
+
173
+    return e->nom;
174
+}
175
+
176
+
177
+void free_list (Elt **elt) {
178
+    Elt *e = *elt, *p;
179
+
180
+    while (e != NULL) {
181
+        p = e;
182
+        e = e->next;
183
+        free (p->nom);
184
+        free (p);
185
+    }
186
+    *elt = NULL;
187
+}

+ 54
- 0
printlog.c View File

@@ -0,0 +1,54 @@
1
+/*
2
+ * printlog
3
+ * architecture clients/serveur guinness
4
+ * Thomas Nemeth / Arnaud Giersch -- le 23 août 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <time.h>
10
+#ifdef SunOS
11
+#include <sys/varargs.h>
12
+#else
13
+#include <stdarg.h>
14
+#endif
15
+#include <string.h>
16
+#include "defines.h"
17
+#include "printlog.h"
18
+
19
+
20
+extern FILE *outerr;
21
+extern FILE *logfile;
22
+
23
+
24
+void printlog (log_level loglevel, const char *format, ...) {
25
+    va_list    ap;
26
+    FILE      *stream = logfile;
27
+    time_t     now;
28
+    struct tm *today;
29
+    char       date_time[MAXSTRLEN];
30
+
31
+    va_start (ap, format);
32
+
33
+    switch (loglevel) {
34
+        case LOG_NOTIFY:
35
+            stream = logfile;
36
+            break;
37
+        case LOG_ERROR:
38
+            stream = outerr;
39
+            break;
40
+        default:
41
+            stream = outerr;
42
+            break;
43
+    }
44
+
45
+    time (&now);
46
+    today = localtime (&now);
47
+    memset (date_time, 0, MAXSTRLEN);
48
+    strftime (date_time, MAXSTRLEN - 1, "%a %d %b %Y %T", today);
49
+    fprintf  (stream, "guinnessd: %s - ", date_time);
50
+    vfprintf (stream, format, ap);
51
+
52
+    va_end (ap);
53
+}
54
+

+ 297
- 0
tools.c View File

@@ -0,0 +1,297 @@
1
+/*
2
+ * tools
3
+ * Création et manipulation de sockets
4
+ * Thomas Nemeth -- le 15 juin 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <unistd.h>
11
+#include <errno.h>
12
+#include <signal.h>
13
+#include <netdb.h>
14
+#include <sys/types.h>
15
+#include <sys/socket.h>
16
+#include <netinet/in.h>
17
+#include <string.h>
18
+#include <strings.h>
19
+#include <arpa/inet.h>
20
+#include "defines.h"
21
+#include "xmem.h"
22
+#include "tools.h"
23
+
24
+/*
25
+ * Ouverture d'une socket de type flot de données
26
+ *
27
+ * création d'une socket serveur : port != 0
28
+ *
29
+ */
30
+int ouvre_socket (int port, char *adr_ip, struct sockaddr_in *ptr_adresse) {
31
+    int                desc_soc;
32
+    int                lg_adresse = sizeof (struct sockaddr_in);
33
+    int                lg_linger  = sizeof (struct linger);
34
+    struct sockaddr_in adresse;
35
+    struct linger      ling;
36
+
37
+    /*
38
+     * Création de la socket
39
+     *
40
+     */
41
+    if ( (desc_soc = socket (AF_INET, SOCK_STREAM, 0) ) == -1) {
42
+#ifdef DEBUG
43
+        fprintf (stderr, "Ne peut pas ouvrir la socket de connexion.\n");
44
+#endif
45
+        perror (__FILE__ " socket");
46
+        return -1;
47
+    }
48
+
49
+    /*
50
+     * Affectation des options
51
+     *
52
+     */
53
+    if (port != 0) {
54
+        int opt = 1;
55
+        if (setsockopt (desc_soc, SOL_SOCKET,
56
+                        SO_REUSEADDR, &opt, sizeof (int) ) == -1) {
57
+#ifdef DEBUG
58
+            fprintf (stderr, "Impossible de positionner REUSEADDR.\n");
59
+#endif
60
+            perror (__FILE__ " setsockopt -- REUSEADDR");
61
+            return -1;
62
+        }
63
+    }
64
+    ling.l_onoff  = 0;
65
+    ling.l_linger = 0;
66
+    if (setsockopt (desc_soc, SOL_SOCKET, SO_LINGER, &ling, lg_linger) == -1) {
67
+#ifdef DEBUG
68
+        fprintf (stderr, "Impossible de positionner LINGER.\n");
69
+#endif
70
+        perror (__FILE__ " setsockopt -- LINGER");
71
+        return -1;
72
+    }
73
+
74
+    /*
75
+     * Préparation de l'adresse d'attachement
76
+     *
77
+     */
78
+    memset (&adresse, 0, sizeof (adresse) );
79
+    adresse.sin_family = AF_INET;
80
+    if (adr_ip) {
81
+        struct in_addr ia;
82
+
83
+        if (inet_aton(adr_ip, &ia)) {
84
+            adresse.sin_addr = ia;
85
+        } else {
86
+            struct hostent *h;
87
+
88
+            h = gethostbyname(adr_ip);
89
+            if (!h) {
90
+                fprintf (stderr, "Adresse %s inconnue.\n", adr_ip);
91
+                return -1;
92
+            }
93
+            memcpy (&adresse.sin_addr.s_addr, h->h_addr, h->h_length);
94
+        }
95
+    } else
96
+        adresse.sin_addr.s_addr = htonl (INADDR_ANY);
97
+    adresse.sin_port        = htons (port);
98
+
99
+    /*
100
+     * Demande d'attachement de la socket
101
+     *
102
+     */
103
+    if (bind (desc_soc, (struct sockaddr*) &adresse, lg_adresse) == -1) {
104
+#ifdef DEBUG
105
+        fprintf (stderr,
106
+                 "Ne peut donner de nom à la socket de connexion.\n"
107
+                 "Attendez quelques minutes avant de relancer.\n");
108
+#endif
109
+        perror (__FILE__ " bind");
110
+        close (desc_soc);
111
+        return -1;
112
+    }
113
+
114
+    /*
115
+     * Récupération de l'adresse effective d'attachement
116
+     *
117
+     */
118
+    if (ptr_adresse != NULL)
119
+        getsockname (desc_soc, (struct sockaddr *) ptr_adresse, &lg_adresse);
120
+
121
+  return desc_soc;
122
+}
123
+
124
+
125
+int connect_server (const char *machine, int port) {
126
+    struct hostent     *serveur;
127
+    struct sockaddr_in  adresse_serveur, adresse_client;
128
+    int                 socket_client;
129
+
130
+    /* Recherche de la machine où se trouve le serveur */
131
+    if ( (serveur = gethostbyname (machine) ) == NULL) {
132
+#ifdef DEBUG
133
+        fprintf (stderr, "Machine %s inconnue...\n", machine);
134
+#endif
135
+        return -1;
136
+    }
137
+
138
+    /* Création et attachement de la socket du client --
139
+     * port quelconque => 0
140
+     */
141
+    if ( (socket_client = ouvre_socket
142
+          (0, NULL, (struct sockaddr_in *) &adresse_client)) == -1) {
143
+#ifdef DEBUG
144
+        fprintf (stderr, "Création de la socket du client impossible.\n");
145
+#endif
146
+        return -1;
147
+    }
148
+
149
+    /* Préparation de l'adresse du serveur */
150
+    adresse_serveur.sin_family = AF_INET;
151
+    adresse_serveur.sin_port   = htons (port);
152
+    memcpy (&adresse_serveur.sin_addr.s_addr,
153
+            serveur->h_addr, serveur->h_length);
154
+
155
+    /* Demande de connexion au serveur */
156
+    if (connect (socket_client, (struct sockaddr *) &adresse_serveur,
157
+                 sizeof (adresse_serveur) ) == -1) {
158
+#ifdef DEBUG
159
+        fprintf (stderr, "Impossible de se connecter au serveur.\n");
160
+#endif
161
+        perror (__FILE__ " connect");
162
+        return -1;
163
+    }
164
+
165
+    return socket_client;
166
+}
167
+
168
+
169
+int install_server (int port, char *adr_ip, struct sockaddr_in *ecoute) {
170
+    int socket_ecoute;
171
+
172
+    /* Ouverture de la socket */
173
+    if ( (socket_ecoute = ouvre_socket (port, adr_ip, ecoute)) == -1) {
174
+#ifdef DEBUG
175
+        fprintf (stderr, "Création de la socket du serveur impossible.\n");
176
+#endif
177
+        return -1;
178
+    }
179
+
180
+    /* Déclaration d'ouverture du service */
181
+    if (listen (socket_ecoute, 10) == -1) {
182
+#ifdef DEBUG
183
+        fprintf (stderr, "Impossible d'enregistrer le service.\n");
184
+#endif
185
+        perror (__FILE__ " listen");
186
+        return -1;
187
+    }
188
+
189
+    return socket_ecoute;
190
+}
191
+
192
+
193
+/*
194
+ * Fonction de réception de données
195
+ *
196
+ */
197
+int read_infos (int socket_data, char *infos) {
198
+    int  nb;
199
+
200
+    /* SSIZE_MAX = 2147483647 */
201
+    memset (infos, 0, MAXSTRLEN);
202
+    nb = read (socket_data, infos, MAXSTRLEN - 1);
203
+
204
+    if ( (nb == -1) || (nb == 0) ) {
205
+#ifdef DEBUG
206
+        fprintf (stderr, "Erreur de connexion réception !\n");
207
+#endif
208
+        if ( (errno == EPIPE) || (nb == 0) ) return FALSE; /* cont = FALSE; */
209
+    }
210
+
211
+#ifdef DEBUG
212
+    printf ("Reçu : [%s] lg = %d/%d\n", infos, strlen (infos), nb);
213
+#endif
214
+
215
+    return TRUE;
216
+}
217
+
218
+
219
+/*
220
+ * Fonction d'émisson de données
221
+ *
222
+ */
223
+int send_infos (int socket_data, const char *infos) {
224
+
225
+#ifdef DEBUG
226
+    printf ("Émission de : %s [%d]\n", infos, strlen (infos));
227
+#endif
228
+
229
+    if (write (socket_data, (void *) infos, strlen (infos) + 1) == -1) {
230
+        /* Erreur : plus de socket ! */
231
+#ifdef DEBUG
232
+        fprintf (stderr, "Erreur de connexion émission !\n");
233
+#endif
234
+        if (errno == EPIPE) return FALSE; /*cont = FALSE;*/
235
+    }
236
+#ifdef DEBUG
237
+        fprintf (stderr, "Émission ok !\n");
238
+#endif
239
+    return TRUE;
240
+}
241
+
242
+
243
+void get_sock_infos (int sock, char **nom, char **adr, int *prl, int *prd) {
244
+    struct sockaddr_in  name;
245
+#ifdef OpenBSD
246
+    int                 namelen;
247
+#else
248
+    socklen_t           namelen;
249
+#endif
250
+    struct hostent     *machine;
251
+
252
+    /* Initialisations en cas d'échecs */
253
+    *nom = NULL;
254
+    *adr = NULL;
255
+    *prd = 0;
256
+
257
+    /* Infos locales (port) */
258
+    namelen = sizeof (name);
259
+    if (getsockname (sock, (struct sockaddr *) &name, &namelen) == 0)
260
+        *prl = ntohs (name.sin_port);
261
+    else {
262
+        perror ("getsockname() ");
263
+        *prl = 0;
264
+    }
265
+
266
+    /* Port et adresse IP distants */
267
+    namelen = sizeof (name);
268
+    if (getpeername (sock, (struct sockaddr *) &name, &namelen) != 0) {
269
+#ifdef DEBUG
270
+        perror ("Erreur de récupération d'information sur pair !\n"
271
+                "getpeername() ");
272
+#else
273
+        perror ("Impossible d'obtenir les infos distantes ");
274
+#endif
275
+        return;
276
+    }
277
+
278
+    *adr = xstrdup (inet_ntoa (name.sin_addr));
279
+    *prd = ntohs (name.sin_port);
280
+
281
+    /* Nom de machine distante */
282
+    machine = gethostbyaddr ((char *)&name.sin_addr,
283
+                             sizeof name.sin_addr, name.sin_family);
284
+    if (machine == NULL) {
285
+#ifdef DEBUG
286
+        perror ("Erreur de récupération de nom de pair.\n"
287
+                "gethostbyaddr() ");
288
+        fprintf (stderr, "Adresse : %s (%s)\tFamille : %d (2 == AF_INET)\n",
289
+                 *adr, (char *)&name.sin_addr, name.sin_family);
290
+#else
291
+        perror ("Impossible d'obtenir le nom d'hôte distant ");
292
+#endif
293
+        return;
294
+    }
295
+
296
+    *nom = xstrdup (machine->h_name);
297
+}

+ 31
- 0
xmem.c View File

@@ -0,0 +1,31 @@
1
+/*
2
+ * xmem
3
+ * architecture clients/serveur guinness : gestion mémoire
4
+ * Thomas Nemeth -- le 24 août 2001
5
+ *
6
+ */
7
+
8
+#include <stdio.h>
9
+#include <stdlib.h>
10
+#include <string.h>
11
+#include <strings.h>
12
+#include "xmem.h"
13
+
14
+
15
+void *xmalloc (size_t taille) {
16
+    void *ret = malloc (taille);
17
+    if (ret == NULL) {
18
+        perror ("malloc() ");
19
+        exit (-1);
20
+    } else
21
+        return ret;
22
+}
23
+
24
+char *xstrdup (const char *chaine) {
25
+    char *ret = strdup (chaine);
26
+    if (ret == NULL) {
27
+        perror ("strdup() ");
28
+        exit (-1);
29
+    } else
30
+        return ret;
31
+}

Loading…
Cancel
Save