Browse Source

client compiled :)

tonton Th 8 months ago
parent
commit
0ef949ce91
4 changed files with 557 additions and 2 deletions
  1. 1
    0
      .gitignore
  2. 10
    2
      Makefile
  3. 529
    0
      guinness.c
  4. 17
    0
      guinness.h

+ 1
- 0
.gitignore View File

@@ -3,4 +3,5 @@
3 3
 *.o
4 4
 
5 5
 guinnessd
6
+guinness
6 7
 

+ 10
- 2
Makefile View File

@@ -12,6 +12,8 @@ COPT =	-Wall -g
12 12
 D_OBJS = xmem.o broadcast.o printlog.o lists.o tools.o drinks.o		\
13 13
 	commands.o clients.o
14 14
 
15
+C_OBJS = xmem.o tools.o
16
+
15 17
 D_LIBS  = -lpthread -lcrypt
16 18
 
17 19
 # ---------------------------------------------------------
@@ -25,6 +27,14 @@ guinnessd:	guinnessd.o Makefile $(D_OBJS)
25 27
 guinnessd.o:	guinnessd.c Makefile $(H_DEP)
26 28
 	gcc $(COPT) -c $<  
27 29
 
30
+#
31
+
32
+guinness:	guinness.o Makefile $(D_OBJS)
33
+	gcc -g $<   $(C_OBJS)  $(D_LIBS)     -o $@
34
+
35
+guinness.o:	guinness.c Makefile $(H_DEP)
36
+	gcc $(COPT) -c $<  
37
+
28 38
 # ---------------------------------------------------------
29 39
 #
30 40
 #	modules needed by the daemon
@@ -49,6 +59,4 @@ clients.o:	clients.c Makefile $(H_DEP)
49 59
 
50 60
 # ---------------------------------------------------------
51 61
 
52
-clients.o:	clients.c Makefile $(H_DEP)
53
-	gcc $(COPT) -c $<
54 62
 

+ 529
- 0
guinness.c View File

@@ -0,0 +1,529 @@
1
+/*
2
+ * guinness
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 <getopt.h>
13
+#include <signal.h>
14
+#include <pthread.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 "xmem.h"
22
+#include "guinness.h"
23
+#include "tools.h"
24
+#include "config.h"
25
+
26
+
27
+#ifdef SunOS
28
+char *crypt(const char *key, const char *salt);
29
+#else
30
+extern char *crypt __P ((__const char *__key, __const char *__salt));
31
+#endif
32
+
33
+
34
+/* VARIABLES GLOBALES */
35
+char **commandes    = NULL;
36
+char  *utilisateur  = NULL;
37
+char  *boisson      = NULL;
38
+char  *serveur      = NULL;
39
+char  *prompt       = NULL;
40
+char  *logout       = NULL;
41
+char   cmdchr       = 0;
42
+int    port         = 0;
43
+int    nb_cmd       = 0;
44
+
45
+
46
+/*
47
+ * Lecture du fichier de config : récupération des valeurs
48
+ *
49
+ */
50
+char *get_string_from_token (char *line) {
51
+    char *result = line;
52
+    char *tmp;
53
+    int   keyval = 0;
54
+
55
+    while ( (keyval != 1) && (result [0] != 0) ) {
56
+        if (result [0] == '=') keyval = 1;
57
+        if (keyval == 0) result++;
58
+    }
59
+    tmp = result++;
60
+    while (tmp [0] != 0) {
61
+        if (tmp [0] == '\n') tmp [0] = 0;
62
+        tmp++;
63
+    }
64
+    return result;
65
+}
66
+
67
+
68
+/*
69
+ * Lecture du fichier de config
70
+ *
71
+ */
72
+void load_config () {
73
+    FILE *file;
74
+    char *configfile;
75
+    char  tmpstr[MAXSTRLEN + 1];
76
+    char *Home;
77
+    char *value;
78
+
79
+    Home = getenv ("HOME");
80
+    configfile = xmalloc ((strlen (Home) + 
81
+                           strlen (CONFIG_FILE) + 2) * sizeof (char));
82
+    snprintf (configfile, MAXSTRLEN, "%s/%s", Home, CONFIG_FILE);
83
+
84
+    /* Ouverture du fichier */
85
+    if ( (file = fopen (configfile, "r") ) != NULL) {
86
+        /* Lecture du fichier */
87
+        while (! feof (file) ) {
88
+            memset (tmpstr, 0, MAXSTRLEN + 1);
89
+            fgets (tmpstr, (int) MAXSTRLEN, file);
90
+            value = get_string_from_token (tmpstr);
91
+            if ( (strncmp (tmpstr, "user=", 5) == 0) && (utilisateur == NULL) )
92
+                utilisateur = xstrdup (value);
93
+            if ( (strncmp (tmpstr, "server=", 7) == 0) && (serveur == NULL) )
94
+                serveur = xstrdup (value);
95
+            if ( (strncmp (tmpstr, "port=", 5) == 0) && (port == 0) )
96
+                port = atoi (value);
97
+            if ( (strncmp (tmpstr, "prompt=", 7) == 0) && (prompt == NULL) )
98
+                prompt = xstrdup (value);
99
+            if ( (strncmp (tmpstr, "pref=", 5) == 0) && (boisson == NULL) )
100
+                boisson = xstrdup (value);
101
+            if ( (strncmp (tmpstr, "cmdchr=", 7) == 0) && (cmdchr == 0) )
102
+                cmdchr = value[0];
103
+            if ( (strncmp (tmpstr, "logout=", 7) == 0) && (logout == NULL) )
104
+                logout = xstrdup (value);
105
+        }
106
+        fclose (file);
107
+#ifdef DEBUG
108
+    } else {
109
+        fprintf (stderr, "Pas de fichier de config (%s).\n", configfile);
110
+#endif
111
+    }
112
+    free (configfile);
113
+}
114
+
115
+
116
+/*
117
+ * Fonction de nettoyage
118
+ *
119
+ */
120
+void libere () {
121
+    if (utilisateur) free (utilisateur);
122
+    if (serveur)     free (serveur);
123
+    if (boisson)     free (boisson);
124
+    if (logout)      free (logout);
125
+}
126
+
127
+
128
+/*
129
+ * Aide
130
+ *
131
+ */
132
+void Usage (int help) {
133
+    printf ("guinness by Thomas Nemeth - v %s (compilation %s : %s)\n",
134
+            VERSION, OS_TYPE, COMPIL_DATE);
135
+    if (help)
136
+        printf ("Usage : guinness [-h] [-v] [-m machine] "
137
+                "[-p port] [-u utilisateur] [-b boisson] [-q msgdx]\n"
138
+                "   -h             : aide sur les paramètres\n"
139
+                "   -v             : affiche la version\n"
140
+                "   -m machine     : spéficie le nom du serveur\n"
141
+                "   -p port        : spécifie le numéro du port\n"
142
+                "   -u utilisateur : nom d'utilisateur\n"
143
+                "   -b boisson     : boisson préférée\n"
144
+                "   -q msgdx       : message d'au-revoir à la déconnexion\n"
145
+                " Online (précédé du caractère de commande \"/\") :\n"
146
+                "   help           : affiche l'aide sur les commandes\n"
147
+                "   quit           : quitte\n\n");
148
+    libere ();
149
+    exit (1);
150
+}
151
+
152
+
153
+/*
154
+ * Traitement des arguments
155
+ *
156
+ */
157
+void traite_argv (int argc, char *argv[]) {
158
+    int option;
159
+
160
+    /* Vérification des paramètres */
161
+    while ((option = getopt (argc, argv, "hvm:p:u:b:q:")) != -1) {
162
+        switch (option) {
163
+            case 'h' :
164
+                Usage (TRUE);
165
+                break;
166
+            case 'v' :
167
+                Usage (FALSE);
168
+                break;
169
+            case 'm' :
170
+                SET_STRING (serveur, optarg);
171
+                break;
172
+            case 'p' :
173
+                port = atoi (optarg);
174
+                break;
175
+            case 'u' :
176
+                SET_STRING (utilisateur, optarg);
177
+                break;
178
+            case 'b' :
179
+                SET_STRING (boisson, optarg);
180
+                break;
181
+            case 'q' :
182
+                SET_STRING (logout, optarg);
183
+                break;
184
+            default:
185
+                Usage (TRUE);
186
+                break;
187
+        }
188
+    } 
189
+    if (optind < argc) {
190
+        if (argc - optind == 1)
191
+            fprintf (stderr, "%s: option inconnue --", argv[0]);
192
+        else
193
+            fprintf (stderr, "%s: options inconnues --", argv[0]);
194
+        for ( ; optind < argc ; optind++)
195
+            fprintf (stderr, " %s", argv[optind]);
196
+        fprintf (stderr, "\n");
197
+        Usage (TRUE);
198
+    }
199
+}
200
+
201
+
202
+/*
203
+ * Envoi de commande
204
+ *
205
+ */
206
+int send_cmd (int socket_client) {
207
+    char  clavier[MAXSTRLEN + 1];
208
+    char *commande;
209
+    char *admin_crypt;
210
+    int   i, found = FALSE, cont = TRUE;
211
+
212
+    /* Lecture d'une commande au clavier */
213
+    memset (clavier, 0, MAXSTRLEN);
214
+    if ( (fgets (clavier, (int) MAXSTRLEN, stdin) == NULL) &&
215
+         feof (stdin) ) {
216
+        snprintf (clavier, MAXSTRLEN, "%cquit", cmdchr);
217
+    }
218
+
219
+    /* Détermination du type (commande explicite / message) */
220
+    if (clavier[0] == cmdchr)
221
+        commande = xstrdup (clavier + 1);
222
+    else {
223
+        commande = xmalloc ((strlen (clavier) + 6) * sizeof (char));
224
+        snprintf (commande, strlen (clavier) + 6, "msg %s", clavier);
225
+    }
226
+
227
+    /* Suppression des retours à la ligne pour comparaison */
228
+    for (i = 0 ; i < strlen (commande) ; i++)
229
+        if (commande[i] == '\n') commande[i] = '\0';
230
+
231
+    /* Recherche de la bonne commande */
232
+    if (strlen (commande) > 0)
233
+        for (i = 0 ; i < nb_cmd ; i++) {
234
+            int cmp = -1;
235
+
236
+            if (commandes[i][0] == '*') /* Commandes d'administration */
237
+                cmp = strncmp (commandes[i]+1, commande,
238
+                               strlen (commandes[i])-1);
239
+            else if (commandes[i][0] == '+') /* Commandes à intervalle */
240
+                cmp = ( (strchr (commandes[i]+1, commande[0]) != NULL) &&
241
+                        ( (strlen (commande) == 1) ||
242
+                          (commande[1] == ' ') ) ) ? 0 : -1;
243
+            else { /* Commande simple : vérification pour la commande entière
244
+                    * ou le premier caractère.
245
+                    */
246
+                cmp = (
247
+                    /* comparaison exacte entre les deux commandes
248
+                    */
249
+                    (strncmp (commandes[i], commande,
250
+                              strlen (commandes[i]) ) == 0) ||
251
+                    /* comparaison entre les 2 premières lettres en
252
+                     * cas de présence de paramètres
253
+                     */
254
+                    ( (commandes[i][0] == commande[0]) &&
255
+                      (commande[1] == ' ') ) ||
256
+                    /* Comparaison entre les deux premières lettres en cas
257
+                     * de présence d'une unique lettre dans la commande
258
+                     */
259
+                    ( (commandes[i][0] == commande[0]) &&
260
+                      (strlen (commande) == 1) ) ) ? 0 : -1;
261
+                /* Commande trouvée : si un seul caractère, remplacement par
262
+                 * la commande complète.
263
+                 */
264
+                if ( (cmp == 0) &&
265
+                     (strncmp (commandes[i], commande,
266
+                               strlen (commandes[i]) ) != 0) ) {
267
+                    char *tmpstr;
268
+                    tmpstr = xmalloc ( (strlen (commande) + 
269
+                                        strlen (commandes[i]) ) *
270
+                                        sizeof (char) );
271
+                    strcpy (tmpstr, commandes[i]);
272
+                    strcat (tmpstr, commande+1);
273
+#ifdef DEBUG
274
+                    printf ("Nouvelle commande = %s | %d\n",
275
+                            tmpstr, strlen (tmpstr) );
276
+#endif
277
+                    if (strlen (tmpstr) > MAXSTRLEN) {
278
+                        fprintf (stderr, "Commande trop longue !\n");
279
+                        printf (prompt);
280
+                        return TRUE; /* continue */
281
+                    }
282
+                    free (commande);
283
+                    commande = xstrdup (tmpstr);
284
+                    free (tmpstr);
285
+                }
286
+#ifdef DEBUG
287
+                printf ("l = %c / c = %c ==> %d\n",
288
+                        commandes[i][0], commande[0], cmp);
289
+#endif
290
+            }
291
+
292
+            if (cmp == 0) {
293
+#ifdef DEBUG
294
+                int j;
295
+                printf ("Commande reconnue : %s\n[%s (%d)] :",
296
+                        commandes[i], commande, strlen (commande) );
297
+                for (j = 0 ; j < strlen (commande) ; j++)
298
+                    printf (" %d", commande[j]);
299
+                printf ("\n");
300
+#endif
301
+                found = TRUE;
302
+            }
303
+        }
304
+
305
+    if (! found) {
306
+#ifdef DEBUG
307
+        fprintf (stderr, "Commande inconnue : [%s (%d)]",
308
+                 commande, strlen (commande) );
309
+        for (i = 0 ; i < strlen (commande) ; i++)
310
+            fprintf (stderr, " %d", commande[i]);
311
+        fprintf (stderr, ".\n\n");
312
+#else
313
+        fprintf (stderr, "Commande inconnue : [%s]\n", commande);
314
+#endif
315
+        printf (prompt);
316
+        return TRUE; /* continue */
317
+    }
318
+
319
+    /* Mode administrateur  */
320
+    if ( (strncmp (commande, "admin ", 6) == 0) && (strlen (commande) > 6) ) {
321
+        int taille;
322
+        admin_crypt = xstrdup (crypt (commande + 6, "Gs"));
323
+        free (commande);
324
+        taille = strlen ("admin ") + strlen (admin_crypt) + 1;
325
+        commande = xmalloc (taille);
326
+        snprintf (commande, taille, "admin %s", admin_crypt + 2);
327
+    }
328
+
329
+    cont = send_infos (socket_client, commande);
330
+
331
+    free (commande);
332
+
333
+    return cont;
334
+}
335
+
336
+
337
+void set_cmds (char *cmds) {
338
+    char *tok, *save;
339
+    int   i = 0;
340
+#ifdef DEBUG
341
+    int   j;
342
+#endif
343
+
344
+    nb_cmd = 0;
345
+    save = xstrdup (cmds);
346
+#ifdef DEBUG
347
+    printf ("Commandes disponibles : \n");
348
+/*     printf ("%s\n", cmds); */
349
+#endif
350
+    tok = strtok (save, "\n");
351
+    while (tok != NULL) {
352
+        nb_cmd++;
353
+        tok = strtok (NULL, "\n");
354
+    }
355
+
356
+    commandes = xmalloc ((nb_cmd) * sizeof (char*));
357
+
358
+    tok = strtok (cmds, "\n");
359
+    while (tok != NULL) {
360
+        commandes[i] = xstrdup (tok);
361
+#ifdef DEBUG
362
+        if (tok[0] == '+') {
363
+            for (j = 1 ; j < strlen (commandes[i]) ; j++)
364
+                printf ("%c%c ", cmdchr, commandes[i][j]);
365
+        } else if (tok[0] != '*') {
366
+            printf ("%c%s ", cmdchr, commandes[i]);
367
+        }
368
+#endif
369
+        i++;
370
+        tok = strtok (NULL, "\n");
371
+    }
372
+    printf ("\n");
373
+
374
+    free (save);
375
+}
376
+
377
+
378
+/*
379
+ * Fonction d'initialisation de la communication
380
+ *
381
+ */
382
+int initiate (int socket_client) {
383
+    char cmds[MAXSTRLEN];
384
+    char datas[MAXSTRLEN];
385
+    char nick_ok[MAXSTRLEN];
386
+    int  cont = TRUE;
387
+
388
+    memset (datas, 0, MAXSTRLEN);
389
+
390
+    /* Réception de la liste des commandes */
391
+    cont = read_infos (socket_client, cmds);
392
+
393
+    if (cont) {
394
+        set_cmds (cmds);
395
+
396
+        snprintf (datas, MAXSTRLEN - 1, "%s\n%s\n%s",
397
+                  utilisateur, boisson, logout);
398
+
399
+        /* Envoi des données utilisateur */
400
+        cont = send_infos (socket_client, datas);
401
+
402
+        read_infos (socket_client, nick_ok);
403
+        if (nick_ok[0] == '@') {
404
+            printf ("%s", nick_ok + 1);
405
+            return FALSE;
406
+        }
407
+        printf ("%s", nick_ok);
408
+
409
+        /* Traitement des commandes et des infos */
410
+        printf (prompt);
411
+    }
412
+
413
+    return cont;
414
+}
415
+
416
+
417
+/*
418
+ * Boucle de commande et de réception
419
+ *
420
+ */
421
+void data_rw (int socket_client) {
422
+    int    cont = TRUE;
423
+    char   infos[MAXSTRLEN];
424
+    fd_set lire;
425
+
426
+    cont = initiate (socket_client);
427
+
428
+    while (cont == TRUE) {
429
+        fflush (stdout);
430
+
431
+        /* Construction de l'ensemble à scruter en lecture : */
432
+        FD_ZERO (&lire);
433
+        FD_SET (STDIN_FILENO, &lire);
434
+        FD_SET (socket_client, &lire);
435
+
436
+        /*  Attente d'un message sur la liste : */
437
+        select (socket_client + 1, &lire, NULL, NULL, NULL);
438
+
439
+        if (FD_ISSET (STDIN_FILENO, &lire) ) {
440
+            cont = send_cmd (socket_client);
441
+        } else {
442
+            int is;
443
+
444
+            cont = read_infos (socket_client, infos);
445
+
446
+            is = 0;
447
+            do {
448
+                printf ("%s\n", infos + is);
449
+                while (is < MAXSTRLEN && infos[is]) is ++;
450
+                /* on suppose qu'un seul '\0' sépare deux messages */
451
+                is ++;
452
+            } while (is < MAXSTRLEN && infos[is]);
453
+
454
+            /* Hack pour faire afficher le message par xmessage
455
+             * Pas très joli lors des déconnexions.
456
+             */
457
+/*             if (getenv ("DISPLAY")) { */
458
+/*                 if (! fork ()) */
459
+/*                     execlp ("xmessage", "xmessage", infos, NULL); */
460
+/*             } */
461
+            fflush (stdout);
462
+            printf (prompt);
463
+        }
464
+    }
465
+
466
+    printf ("%s\n", logout);
467
+    close (socket_client);
468
+}
469
+
470
+
471
+/*
472
+ * Gestionnaire de signal SIGPIPE
473
+ *
474
+ */
475
+void handler_sigpipe (int sig) {
476
+    printf ("Signal SIGPIPE reçu...\n");
477
+}
478
+
479
+
480
+/*
481
+ * Fonction principale
482
+ *
483
+ */
484
+int main (int argc, char *argv[]) {
485
+    int   socket_client;
486
+    char *environ_user;
487
+
488
+    signal (SIGPIPE, handler_sigpipe);
489
+
490
+    /* Vérification des paramètres */
491
+    traite_argv (argc, argv);
492
+
493
+    /* Lecture du fichier de config */
494
+    load_config ();
495
+
496
+    /* Valeurs par défaut */
497
+    if (! utilisateur) {
498
+        environ_user = getenv ("USER");
499
+        if (environ_user && *environ_user) 
500
+            utilisateur = xstrdup (environ_user);
501
+        else
502
+            utilisateur = xstrdup ("toto");
503
+    }
504
+    if (IS_NOT_GOOD (serveur)) SET_STRING (serveur, DEFAULT_SERVER);
505
+    if (IS_NOT_GOOD (prompt))  SET_STRING (prompt,  DEFAULT_PROMPT);
506
+    if (IS_NOT_GOOD (boisson)) SET_STRING (boisson, DEFAULT_DRINK);
507
+    if (IS_NOT_GOOD (logout))  SET_STRING (logout,  DEFAULT_LOGOUT);
508
+    if (cmdchr == 0) cmdchr  = '/';
509
+    if (port == 0)   port    = DEFAULT_SERVER_PORT;
510
+
511
+    printf ("Serveur     : [%s]\t", serveur);
512
+    printf ("Port    : [%d]\n",     port);
513
+    printf ("Utilisateur : [%s]\t", utilisateur);
514
+    printf ("\tBoisson : [%s]\t",   boisson);
515
+    printf ("Logout : [%s]\n",      logout);
516
+    printf ("Préfixe     : [%c]\n", cmdchr);
517
+
518
+    /* Connexion au serveur */
519
+    if ( (socket_client = connect_server (serveur, port) ) == -1) {
520
+        fprintf (stderr, "Connexion refusee...\n");
521
+        return -1;
522
+    }
523
+    printf ("-+- Connexion acceptee. -+-\n");
524
+
525
+    data_rw (socket_client);
526
+
527
+    libere ();
528
+    return 0;
529
+}

+ 17
- 0
guinness.h View File

@@ -0,0 +1,17 @@
1
+/*
2
+ * guinness
3
+ * architecture clients/serveur guinness.
4
+ * Thomas Nemeth -- le 15 juin 2001
5
+ *
6
+ */
7
+
8
+#ifndef GUINNESS_CLIENT
9
+#define GUINNESS_CLIENT
10
+
11
+#define CONFIG_FILE    ".guinnessrc"
12
+
13
+#define DEFAULT_SERVER "127.0.0.1"
14
+#define DEFAULT_PROMPT "> "
15
+
16
+
17
+#endif

Loading…
Cancel
Save