Faire suivre une variable entre deux fonctions ?

Fermé
4nth0nym3 - Modifié par baladur13 le 14/03/2017 à 17:24
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 - 15 mars 2017 à 17:54
Bonjour, comment puis je faire suivre une variable ? dans deux fonctions différente,

je m'explique :

int denora_event_302(char *source, int ac, char **av)
{
    if (denora->protocoldebug) {
        protocol_debug(source, ac, av);
    }
char * domain;

    domain = strchr (av[1],'@');

    if (domain != NULL) 
send_cmd(s_StatServ, "PRIVMSG #CS :vhost = %s", domain+1);
    else
send_cmd(s_StatServ, "PRIVMSG #CS :@ non trouvé");
}


je voudrais récupéré la variable domain+1 ici (localisé dans le même fichier source) a la place du "Indisponible":

        int denora_event_nick(char *source, int ac, char **av)
        {
            char *ipchar = NULL;
            Server *s;

            if (denora->protocoldebug) {
                protocol_debug(source, ac, av);
            }
            if (ac != 2) {
                s = findserver_uid(servlist, av[5]);
          ipchar = host_resolve(av[4]);
          send_cmd(s_StatServ, "USERHOST :%s", av[0]);
                 do_nick("", av[0], av[3], "Indisponible", s ? s->name : source, av[6],
                        UplinkSynced ? time(NULL) : 0, 0, ipchar, NULL, NULL,
                        strtoul(av[4], NULL, 10), "+i", NULL);
               send_cmd(s_StatServ, "PRIVMSG %s :VERSION", av[0]);
          free(ipchar);
            } else {
                do_nick(source, av[0], NULL, NULL, NULL, NULL,
                        0, 0, NULL, NULL, NULL, 0, NULL, NULL);
            }
            return MOD_CONT;
        }      


Merci à vous pour votre aide
EDIT : Ajout des balises de code (la coloration syntaxique).
Explications disponibles ici : ICI

Merci d'y penser dans tes prochains messages.
A voir également:

3 réponses

[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 14/03/2017 à 18:36
Salut 4nth0nym3,

Si le même tableau de chaînes est passé en av, il te suffit de refaire

char * domain;
domain = strchr (av[1],'@');

et d'utiliser domain comme tu l'entends dans la seconde fonction
denora_event_nick()
.

Si cette information n'est plus là et que tu as vraiment besoin de la garder à ce moment, tu peux, par exemple, changer le prototype de
denora_event_302()
, qui renvoie
int
(alors qu'aucun
return
d'un
int
n'est fait explicitement...), et lui faire renvoyer un pointeur sur
char
, qui pointera sur
domain
.

Donc, un prototype
char * denora_event_302(char *source, int ac, char **av)
et un
return domain;
avant la fin de ta fonction.

Cela sera la responsabilité de la fonction appelant
denora_event_302()
que de garder la valeur de retour pour qu'elle puisse être passée ultérieurement à
denora_event_nick()
(dont il faudra donc aussi changer le prototype).

Dal
0
d'accord merci sauf que c denora_event_nick qui lance denora_event_302 via une commande IRC ( send_cmd(s_StatServ, "USERHOST %s", av[0]); ) du coup ce n'est pas possible ?
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
14 mars 2017 à 22:06
Tout d'abord, je ne connais rien à ton programme, et je ne fais que lire le code que tu as posté. Cela vient d'où ce code ?

Sinon :

1. non, denora_event_nick() ne contient aucun appel à denora_event_302() dans le code que tu as copié.

2. s'agissant de send_cmd() on ne sait pas ce que cela fait, car tu ne postes pas son code. si on se fie au contexte, cela doit envoyer une chaîne de texte formatable à un serveur, probablement IRC, et, a priori, cette fonction est appelée tant par denora_event_nick() que denora_event_302(), et non pas l'inverse

3. tu n'as rien dis sur ce que je disais "Si le même tableau de chaînes est passé en av (...)" et la solution proposée dans ce cas.


Dal
0
4nth0nym3 > [Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024
Modifié par 4nth0nym3 le 14/03/2017 à 22:20
enfaite le programme ne recoit pas les memes donnée sur denora_event_nick & 302 ensuite StatServ envoi un USERHOST pseudo sur irc qui lui renvoi la raw 302 avec la donnée a récupérer et ensuite retransmettre a denora_event_nick via variable global modifiable ? sachant que la donnée recu est un hostname crypter ex : 152685554.net
du genre :

int denora_event_302(char *source, int ac, char **av)
{
if (denora->protocoldebug) {
protocol_debug(source, ac, av);
}
char * domain;
domain = strchr (av[1],'@');
ma_super_var_global = domain+1;
}

et

int denora_event_nick(char *source, int ac, char **av)
{
char *ipchar = NULL;
Server *s;

if (denora->protocoldebug) {
protocol_debug(source, ac, av);
}
if (ac != 2) {
s = findserver_uid(servlist, av[5]);
ipchar = host_resolve(av[4]);
send_cmd(s_StatServ, "USERHOST :%s", av[0]);
do_nick("", av[0], av[3], ma_super_var_global, s ? s->name : source, av[6],
UplinkSynced ? time(NULL) : 0, 0, ipchar, NULL, NULL,
strtoul(av[4], NULL, 10), NULL, NULL);
strtoul(av[4], NULL, 10), NULL, NULL);
send_cmd(s_StatServ, "PRIVMSG %s :VERSION", av[0]);
free(ipchar);
} else {
do_nick(source, av[0], NULL, NULL, NULL, NULL,
0, 0, NULL, NULL, NULL, 0, NULL, NULL);
}
return MOD_CONT;
}



Merci de ton aide
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
Modifié par [Dal] le 15/03/2017 à 00:06
je ne saisis pas trop tes explications (à partir de "ensuite")

en principe on devrait éviter les variables globales, c'est une mauvaise pratique, c'est pourquoi je te proposais une solution alternative.

cependant, si ton problème est de savoir comment on la déclare, il suffit de la déclarer au dehors de toute fonction, dans ton fichier .c sous la forme :

char * ma_super_var_global;

ou mieux :

static char * ma_super_var_global;

pour que ta variable globale ne le soit que pour l'unité de compilation de ton fichier et ses entêtes, et ne risque pas d'interférer avec d'autres unités de compilation.

Dal
0
Merci, en revanche mes deux procedures ne trouve pas le même resultat ? :o

peut tu m'éclairer s'il te plait ?

mes static :

/* Next Generation IRC Server IRCD functions

#include "denora.h"
#include "ngircd.h"
#include <stdio.h>
static char * uh_c_nick;
static char * uh_c_mask;
IRCDVar myIrcd[] = {
.... suite de la source ....


mes procedure située sur la meme source ( denora_event_302 ) :

int denora_event_302(char *source, int ac, char **av)
{
char * domain;
send_cmd(s_StatServ, "PRIVMSG #CS :Debug Serv: %s - %s - %s - %s Client :%s", av[0], av[1], av[2], av[3], uh_c_nick);
domain = strchr (av[1],'@');
uh_c_mask = domain+1;
change_user_host(uh_c_nick, uh_c_mask);
send_cmd(s_StatServ, "PRIVMSG #CS :Fix-Host Change_User_Host %s pour %s : Apperement Ok !", uh_c_nick, uh_c_mask);
}


et juste en dessous celle-ci ( denora_event_nick ) :

int denora_event_nick(char *source, int ac, char **av)
{
char *ipchar = NULL;
Server *s;

if (denora->protocoldebug) {
protocol_debug(source, ac, av);
}
if (ac != 2) {
s = findserver_uid(servlist, av[5]);
ipchar = host_resolve(av[4]);
uh_c_nick = av[0];
send_cmd(s_StatServ, "PRIVMSG #CS :Bug-Host pour %s", uh_c_nick);
send_cmd(s_StatServ, "USERHOST :%s", uh_c_nick);
do_nick("", av[0], av[3], NULL, s ? s->name : source, av[6],
UplinkSynced ? time(NULL) : 0, 0, ipchar, NULL, NULL,
strtoul(av[4], NULL, 10), NULL, NULL);
send_cmd(s_StatServ, "PRIVMSG %s :VERSION", av[0]);
free(ipchar);
} else {
do_nick(source, av[0], NULL, NULL, NULL, NULL,
0, 0, NULL, NULL, NULL, 0, NULL, NULL);
}
return MOD_CONT;
}


Conclusions :

denora_event_302 renvoie tatServ en uh_c_nick

[09:55] <StatServ> Fix-Host Change_User_Host tatServ pour 5817885781.Org : Apperement Ok !
[09:55] <StatServ> Debug Serv: StatServ - Pooshy-S*=***@*** - - Client :tatServ
[09:55]<StatServ> Fix-Host Change_User_Host tatServ pour 1356338937.fr : Apperement Ok !
[09:55] <StatServ> Debug Serv: StatServ - Eva*=***@*** - - Client :tatServ
etc etc

denora_event_nick renvoie bien la bonne valeur a savoir le nick de la personne.

[09:55] <StatServ> Bug-Host pour etonnante-fauvette
[09:55] <StatServ> Bug-Host pour ficelle35
[09:55] <StatServ> Bug-Host pour Milip0w

etc etc


Merci d'ava
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
15 mars 2017 à 13:59
il n'y a pas de "procédures" en C, mais des fonctions.

Une hypothèse possible est que : si entre le moment où
denora_event_302()
fixe le pointeur sur char
uh_c_nick
, et le moment où
denora_event_nick()
s'exécute, le contenu pointé par la même zone mémoire change, alors
uh_c_nick
pointera vers ce contenu.

Si cette hypothèse est plausible, alors, tu devrais créer la variable globale de sorte qu'elle soit un tableau de chars suffisamment dimensionné, et utiliser
strncpy()
(prototype dans string.h) pour sauvegarder les données dedans... et probablement pareil pour
uh_c_mask
.

Une autre hypothèse est que la fonction
denora_event_302()
soit appelée plusieurs fois avant
denora_event_nick()
et avec des paramètres différents.
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
15 mars 2017 à 14:13
par exemple, avec des nick d'une longueur maximale de 31 char et un masque de 255 char maximum :

static char uh_c_nick[32];
static char uh_c_mask[256];

(...)

int denora_event_302(char *source, int ac, char **av)
{
  char * domain;
  send_cmd(s_StatServ, "PRIVMSG #CS :Debug Serv: %s - %s - %s - %s Client :%s", av[0], av[1], av[2], av[3], uh_c_nick);
  domain = strchr (av[1],'@');
  strncpy(uh_c_mask, domain+1, sizeof(uh_c_mask));
(...)
}

de même, dans
denora_event_nick()
, remplacer
uh_c_nick = av[0];
par :
strncpy(uh_c_nick, av[0], sizeof(uh_c_nick));

Dal
0
[Dal] Messages postés 6198 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 13 décembre 2024 1 096
15 mars 2017 à 17:54
Encore un détail.

Il faut bien vérifier les limites, car si la chaîne à copier dépasse la taille fournie en 3ème paramètre de strncpy, la chaîne sera tronquée et ne sera pas terminée. En cas de doute, ou pour assurer le coup dans tous les cas, il est recommandable de terminer d'office avec un '\0' en dernière position pour éviter ce problème.

Par exemple :

strncpy(uh_c_mask, domain+1, sizeof(uh_c_mask));
uh_c_mask[sizeof(uh_c_mask) - 1] = '\0';

Dal
0