IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

le getopt() du pauvre, avec deux cuillères à café.


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Par défaut le getopt() du pauvre, avec deux cuillères à café.
    Bonsoir,

    Je cherches a intégrer un bout de code me permettant d'analyser un tableau
    avec plusieurs agruments , comme cette ligne:

    "--level 82 -t --weight 2 --mark-spam -y -a"


    J'en suis là pour l'instant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
        int i = 0;
        char *cmd = NULL;
     
        // le getop() du pauvre, avec deux cuillères à café et strtok() //
        while ( (cmd = strtok( (i == 0) ? (char*)(argv[0]) : NULL, " "))) {
    	i++;
    	while (cmd[0] == '-') cmd++;
    	switch ( cmd[0] ) {
    	    case 't': 
    	    case 'T': 
    		exec[execn++] = US"--test";
    		break;
    	    case 'L':  /* "-L" */
    	    case 'l':   /* "--level" */
    		cmd = strtok(NULL, " ");
    		if ( ! isdigit(cmd[0]) ) /* l'arg suivant doit être un digit */
    		    break;
    		exec[execn++] = US"--level";
    		exec[execn++] = US cmd;
    		break;
    	// bla bla bla//
                default:
    		break;
    	};
    	if ( i >= 5 ) /* stop avec 5 arguments */
    	    break;
        };
    Je ne suis pas mécontent de ce code (je suis débutant ), mais est-il possible d'améliorer la structure, ayant l'objectif que ce ceci doit rester 'petit' et surtout rapide.

    Merci

  2. #2
    Membre habitué
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Par défaut
    Sans réponse, j'en déduit que c'est pas trop 'dégueulasse' comme code.

    Et côte optimisation, on peut faire mieux ?

    C'est pour un plugin qui est chargé rapidement et son temps d'execution ne dépasse pas 0.030 secondes .

  3. #3
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par ListD Voir le message
    Sans réponse, j'en déduit que c'est pas trop 'dégueulasse' comme code.
    D'abord, c'est samedi donc il y a moins de monde sur le forum.

    Ensuite pourquoi ne pas utiliser la fonction getopt(). Elle est bien et en plus, elle n'est pas buggée (ou alors, cela se saurait ).

    Et enfin, on ne peut pas tester ton code car tout n'y est pas, c'est quoi ce "US" (exec[execn++] = US"--test"; par exemple)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  4. #4
    Membre habitué
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Par défaut
    Il s'agit d'un plugin pour le MTA Exim qui intégré avec dlfunc, (programmatic interface to the dynamic linker) chargement de bibliothèques dynamiques, la doc http://exim.org/exim-html-current/do...expansionitems

    Il est donc chargé à chaque appel de cette manière (dans le fichier de configuration d'Exim):

    exim.conf:
    ----------

    warn condition = ${if eq{$acl_m_spam}{checkspam}}
    set acl_m_bmf = ${dlfunc{/usr/lib/exim/junkprobe-bmf.so{junkprobe}\
    {db:${spool_directory}/junkprobe/bmf}\
    {-t -k 20 defer_no}}
    add_header = X-BMF-Status: $acl_m_bmf



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
     
    #include <stdio.h>
    #include <sys/wait.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <sys/types.h> 
    #include <sys/stat.h> 
    #include <unistd.h> 
    /* Exim includes */
    #include "local_scan.h"
    /* JunkProbe include */
    #include "libJunkProbe.h"
     
    /* Macros */
    #define TIMEOUT			20
    #ifndef FILTER_LOCATION
    #  define FILTER_LOCATION 	"/usr/bin/bmf"
    #endif
     
    #define US   (unsigned char *)
     
    /* Importation des fonctions d'Exim */
    extern uschar  *spool_directory;
    extern uschar 	*primary_hostname;
    extern int 	strcmpic(uschar *s, uschar *t);
     
    // ou 'uschar' est un 'unsigned char' dans l'API 'local_scan.h' //
    int junkprobe(uschar **yield, int argc, uschar *argv[]) {
     
        volatile FILE 	*scan_fout = NULL;
        uschar 		buffer[1024];
        int 		execn = 0;
        uschar 		**exec = malloc(sizeof (char*) * 15);
        int 		mod_reg = 0;
        uschar 		*flag = NULL;
        uschar 		*learn = US"yes";
        float 		value = -1, require = -1;
        struct stat 	st;
        int 		i = 0;
        char 		*cmd = NULL;
        int 		defer_ok = 0;
     
    /* benchmark: */
        starttime = benchmark();
     
    /* command */
        exec[execn++] = US FILTER_LOCATION;
     
        if ( argc < 1 ) /* argv[0] , n'est pas utiliser pour indiquer le chemin */
                              /* de la database de BMF . Attribution de la base par defaut. */
    	argv[0] = string_sprintf("%s/junkprobe/bmf", spool_directory);
     
    /* argv[0] contient le type et le chemin de la base de cette */
    /* manière: {db:/var/spool/exim/bmf} */
        switch( argv[0][0] ) {
    	case 't': /* type text */
    	    argv[0] += 5;
    	    exec[execn++] = US"text";
    	    break;
    	case 'd': /* type db */
    	    argv[0] += 3;
    	    exec[execn++] = US"db";
    	    break;
    	case 'm': /* type mysql */
    	    argv[0] += 6;
    	    exec[execn++] = US"mysql";
    	    break;
    	default:
    	    execn = 1; /* le type n'est pas reconnu, on laisse alors BMF */
                                  /* le detecter lui-même. On enlève l'argument '-f' */
                                  /* inseré plus haut */
    	    break; 
        };
     
    /* vérification de la database */
        if ( ! exec[execn-1][0] == 'm'   /* pas de teste si type MySQL */
    	|| Ustat(argv[0], &st) == -1  /* la database doit exister*/
    	|| ! S_ISDIR(st.st_mode) ) {  /* la database est un répertoire */
    	log_write(0, LOG_MAIN
    	    , "${dlfunc bmf warning: failed calling database %s", argv[0]);
     
    	if ( ( exec[1][0] == '-' )
    	    || ( exec[1][1] == 'f' ) )
    	    execn = 1; /* le type n'est pas reconnu, on laisse alors BMF */
                                  /* le detecter lui-même. On enlève l'argument '-f' */
                                  /* inseré plus haut */
     
    	/* Alors on met la DB par defaut */
    	argv[0] = string_sprintf("%s/junkprobe/bmf", spool_directory);
     
           /* on re-teste l'exsistance de la DB pour valider */
    	if ( stat(argv[0], &st) == -1 ) {
    	    log_write(0, LOG_MAIN | LOG_PANIC
    		, "${dlfunc bmf ERROR: failed calling database %s"
    		, argv[0]);
    	    goto bail;
    	};
        };
     
    /* tout va bien, on ajoute l'agument '-d' pour BMF */
        exec[execn++] = US"-d";
    /* chemin de la DB */
        exec[execn++] = argv[0];
     
    /* "le getopt() du pauvre" pour récuper les arguments pour BMF */
    /* et les valider */
        while ( (cmd = strtok( (i == 0) ? (char*)(argv[1]) : NULL, " "))) {
    	i++;
     
    	while (cmd[0] == '-') cmd++; /* on enlève le ou les "-" */
     
    	switch ( cmd[0] ) {
    	    case 't': /* mode teste. */
    		exec[execn++] = US"-t";
    		learn = US"no";
    		mod_reg = 0;
    		break;
    	    case 'n': /* enregistrement non-spam. */
    		exec[execn++] = US"-n";
    		learn = US"ham";
    		mod_reg = 1;
    		break;
    	    case 'N': /* Enregistrement non-spam et nétoyage spam. */
    		exec[execn++] = US"-N";
    		learn = US"reg_ham";
    		mod_reg = 1;
    		break;
    	    case 's': /* enregistrement spam. */
    		exec[execn++] = US"-s";
    		learn = US"spam";
    		mod_reg = 2;
    		break;
    	    case 'S': /* Enregistrement spam et nétoyage non-spam. */
    		exec[execn++] = US"-S";
    		learn = US"reg_spam";
    		mod_reg = 2;
    		break;
    	    case 'k': /* pour le Bayes calculation. Defaut 15. */
    		cmd = strtok(NULL, " ");
    		if ( ! isdigit(cmd[0]) ) /* l'argument suivant doit être de type 'digit' */
    		    break;
    		exec[execn++] = US"-k";
    		exec[execn++] = US cmd;
    		break;
    	    case 'd':
    		if ( strcmpic( US cmd, US"defer_ok" ) == 0 )
    		    defer_ok = 1; /* en cas de probleme */
    		break;
                default:
    		break;
    	};
    	if ( i >= 3 ) /* pas plus de  >= 3 arguments */
    	    break;
        };
     
        exec[execn++] = US"-p";
        exec[execn++] = NULL;
     
    /* Ouverture du pipe avec avec les arguments réciltés plus haut */
        scan_fout = (FILE *)open_pipe(exec, NULL, TIMEOUT);
        if ( scan_fout == (FILE *)NULL )
    	goto bail;
     
       free(exec);
    Le code continue pour analyser le résultat, mais je penses que le reste n'et pas intéressant ici

  5. #5
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    OK, je comprends un peu mieux ton besoin (mêm si je n'ai pas tout saisi).

    D'abord, tu perturbes le lecteur avec le mot getopt. getopt() est une fonction (de la librairie C ?) qui permet d'analyser les paramètres passés à un programme. En général, c'est toujours utilisé avec argc et argv qui sont les paramètres passés à la fonction main().

    Pour ton problème, regarde du côté des expressions régulières. cela permet de faire des choses puissantes de manière souple et surtout facilement évolutive (une fois que le canevas de ton code est fait et répond à ton problème).

    Pour ce qui est des expression régulières, regarde du côté de regcomp()
    Il y a aussi quelques tuto :
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  6. #6
    Membre habitué
    Inscrit en
    Mars 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Mars 2009
    Messages : 13
    Par défaut
    Merci pour ces liens. D'ailleurs, l'API 'local_scan.h' donne des fonctions avec 'pcre'.

Discussions similaires

  1. [JTable] Cellule avec deux boutons
    Par cherbox dans le forum Composants
    Réponses: 3
    Dernier message: 12/08/2004, 17h26
  2. comment filtrer une table avec deux criteres càd 2 colonnes
    Par athmane2dz dans le forum Bases de données
    Réponses: 7
    Dernier message: 28/07/2004, 15h25
  3. [CR] instruction If avec deux opérations
    Par MaDmAtT dans le forum SAP Crystal Reports
    Réponses: 2
    Dernier message: 19/07/2004, 13h54
  4. Réponses: 10
    Dernier message: 10/06/2004, 16h20
  5. [langage] split avec deux motifs (Newbie)
    Par Raumsog II dans le forum Langage
    Réponses: 2
    Dernier message: 07/06/2004, 09h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo