Faire suivre une variable entre deux fonctions ?
4nth0nym3
-
[Dal] Messages postés 6122 Date d'inscription Statut Contributeur Dernière intervention -
[Dal] Messages postés 6122 Date d'inscription Statut Contributeur Dernière intervention -
Bonjour, comment puis je faire suivre une variable ? dans deux fonctions différente,
je m'explique :
je voudrais récupéré la variable domain+1 ici (localisé dans le même fichier source) a la place du "Indisponible":
Merci à vous pour votre aide
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. |
3 réponses
-
Salut 4nth0nym3,
Si le même tableau de chaînes est passé en av, il te suffit de refairechar * domain; domain = strchr (av[1],'@');
et d'utiliser domain comme tu l'entends dans la seconde fonctiondenora_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 dedenora_event_302()
, qui renvoieint
(alors qu'aucunreturn
d'unint
n'est fait explicitement...), et lui faire renvoyer un pointeur surchar
, qui pointera surdomain
.
Donc, un prototypechar * denora_event_302(char *source, int ac, char **av)
et unreturn domain;
avant la fin de ta fonction.
Cela sera la responsabilité de la fonction appelantdenora_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 -
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 ?
-
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- 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;
}
etint 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
-
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
-
-
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-
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 charuh_c_nick
, et le moment oùdenora_event_nick()
s'exécute, le contenu pointé par la même zone mémoire change, alorsuh_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 utiliserstrncpy()
(prototype dans string.h) pour sauvegarder les données dedans... et probablement pareil pouruh_c_mask
.
Une autre hypothèse est que la fonctiondenora_event_302()
soit appelée plusieurs fois avantdenora_event_nick()
et avec des paramètres différents. -
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, dansdenora_event_nick()
, remplaceruh_c_nick = av[0];
par :strncpy(uh_c_nick, av[0], sizeof(uh_c_nick));
Dal -
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
-