/* Accède au mineurs bitcoin via l'api. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "coinapi.h" #include "json.h" using namespace std; #define DEFAULT_PORT "4028" #define _TLMP_miner_call struct _F_miner_call { #define _F_miner_call_item(x) void x item(const char *parent, const char *name, const char *value) virtual _F_miner_call_item( )=0; }; static void miner_call( _F_miner_call &c, const char *command, const char *parameter, const char *miner, const char *port, bool silent) { glocal silent; glocal string cmd; glocal c; if (parameter != nullptr){ glocal.cmd = string_f("{\"command\":\"%s\",\"parameter\":\"%s\"}\n",command,parameter); }else{ glocal.cmd = string_f("{\"command\":\"%s\"}\n",command); } (miner,port,1); if (!glocal.silent) tlmp_error ("Ne peut connecter au mineur %s, port %s\n",info.host,info.port); send (glocal.cmd.c_str()); // printf ("line=%s\n",line); (line); glocal.c.item(parent,name,value); } // Lit la liste des mineurs ainsi que la liste des mineurs désactivés. static void readminers_nocheck(const char *minersfile, const char *offlinefile, vector &miners, set &offline) { glocal miners; glocal offline; if (minersfile != nullptr){ (minersfile,true); line = str_skip(line); if (line[0] != '#' && line[0] != '\0') glocal.miners.emplace_back(line); return 0; if (offlinefile != nullptr){ (offlinefile,true); glocal.offline.insert(line); return 0; } } } static void readminers(const char *minersfile, const char *offlinefile, vector &miners, set &offline) { readminers_nocheck(minersfile,offlinefile,miners,offline); if (miners.size()==0){ tlmp_error ("Aucun mineurs spécifiés\n"); exit (-1); } } // Retourne -1 si ne peut pas connecter au mineur int miner_getinfo (PARAM_STRING miner, const char *port, MINER_INFO &info, bool silent) { glocal info; glocal string currentid; glocal unsigned curr_pool = 0; ("pools+summary+stats+devdetails+temps+devs+tunerstatus",nullptr,miner.ptr,port,silent); // printf ("parent=:%s: name=:%s: value=:%s:\n",parent,name,value); if (strcmp(parent,"summary.SUMMARY")==0 && strcmp(name,"GHS av")==0){ glocal.info.avgth = atof(value); }else if (strcmp(parent,"summary.SUMMARY")==0 && strcmp(name,"MHS av")==0){ glocal.info.avgth = atof(value)/1000000.0; }else if (strcmp(parent,"summary.SUMMARY")==0 && strcmp(name,"Elapsed")==0){ int uptime = atoi(value); int jours = uptime/(24*60*60); uptime %= 24*60*60; int heures = uptime/(60*60); int minutes = (uptime-heures*60*60)/60; int secondes = uptime%60; glocal.info.since = string_f ("%d jours %d:%02d:%02d",jours,heures,minutes,secondes); }else if ((strcmp(parent,"devdetails.DEVDETAILS")==0 || strcmp(parent,"temps.TEMPS")==0 || strcmp(parent,"devs.DEVS")==0) && strcmp(name,"ID")==0){ glocal.currentid=value; }else if (strcmp(parent,"devdetails.DEVDETAILS")==0 && strcmp(name,"Chips")==0){ glocal.info.chains[glocal.currentid].acn=atoi(value); }else if (strcmp(parent,"devdetails.DEVDETAILS")==0 && strcmp(name,"Frequency")==0){ glocal.info.chains[glocal.currentid].freq=atof(value); }else if (strcmp(parent,"temps.TEMPS")==0 && strcmp(name,"Board")==0){ glocal.info.chains[glocal.currentid].temp=atof(value); }else if (strcmp(parent,"temps.TEMPS")==0 && strcmp(name,"Chip")==0){ glocal.info.chains[glocal.currentid].temp2=atof(value); }else if (strncmp(name,"temp_num",8)==0){ printf ("\t%s=%s\n",name,value); }else if (strncmp(name,"temp_max",8)==0){ printf ("\t%s=%s\n",name,value); }else if (strncmp(name,"temp2_",6)==0 && strcmp(value,"0")!=0){ glocal.info.chains[name+6].temp2 = atof(value); }else if (strncmp(name,"temp3_",6)==0 && strcmp(value,"0")!=0){ glocal.info.chains[name+6].temp3 = atof(value); }else if (strncmp(name,"temp",4)==0 && strcmp(value,"0")!=0){ glocal.info.chains[name+4].temp = atof(value); }else if (strncmp(name,"freq_avg",8)==0 && strcmp(value,"0.00")!=0){ glocal.info.chains[name+8].freq = atof(value); }else if (strncmp(name,"chain_rateideal",15)==0){ if (strcmp(value,"0.00")!=0){ glocal.info.chains[name+15].rateideal = atof(value); } }else if (strncmp(name,"chain_rate",10)==0 && strcmp(value,"")!=0){ glocal.info.chains[name+10].rate = atof(value); }else if (strncmp(name,"chain_acn",9)==0 && strcmp(value,"0")!=0){ glocal.info.chains[name+9].acn = atoi(value); }else if (strncmp(name,"chain_acs",9)==0 && strcmp(value,"")!=0){ glocal.info.chains[name+9].acs = value; }else if (strcmp(parent,"devs.DEVS")==0 && strcmp(name,"Nominal MHS")==0){ glocal.info.chains[glocal.currentid].rateideal = atof(value)/1000000.0; }else if (strcmp(parent,"devs.DEVS")==0 && strcmp(name,"MHS 1m")==0){ glocal.info.chains[glocal.currentid].rate = atof(value)/1000000.0; }else if (strcmp(parent,"devs.DEVS")==0 && strcmp(name,"Enabled")==0){ glocal.info.chains[glocal.currentid].enabled = value[0] == 'Y'; }else if (strcmp(parent,"pools.POOLS")==0 && strcmp(name,"POOL")==0){ glocal.curr_pool = atoi(value); while (glocal.info.pools.size() <= glocal.curr_pool) glocal.info.pools.push_back(POOL_INFO()); }else if (strcmp(parent,"pools.POOLS")==0 && strcmp(name,"Stratum Active")==0){ glocal.info.pools[glocal.curr_pool].active = strcmp(value,"true")==0; }else if (strcmp(parent,"pools.POOLS")==0 && strcmp(name,"URL")==0){ glocal.info.pools[glocal.curr_pool].url = value; }else if (strcmp(parent,"pools.POOLS")==0 && strcmp(name,"Status")==0){ glocal.info.pools[glocal.curr_pool].alive = strcmp(value,"Alive")==0; }else if (strcmp(parent,"tunerstatus.TUNERSTATUS.TunerChainStatus")==0 && strcmp(name,"HashchainIndex")==0){ glocal.currentid = value; // TUNERSTATUS.TunerChainStatus TuningElapsed=600594 // TUNERSTATUS.TunerChainStatus StageElapsed=600403 }else if (strcmp(parent,"tunerstatus.TUNERSTATUS.TunerChainStatus")==0 && strcmp(name,"Status")==0){ glocal.info.chains[glocal.currentid].tunerstatus = value; }else if (strcmp(name,"User")==0 && strcmp(value,"")!=0 && strcmp(value,glocal.info.user.c_str())!=0){ glocal.info.user = value; } return info.chains.size() > 0 ? 0 : -1; } static int miner_info (PARAM_STRING miner, const char *port, bool html, string &name, double &totalh, bool offline) { MINER_INFO info; int ret = miner_getinfo(miner,port,info,offline); if (ret != -1){ unsigned nbalive = 0; unsigned nbactive = 0; for (auto &m:info.pools){ if (m.active) nbactive++; if (m.alive) nbalive++; } totalh += info.avgth; if (html){ printf ("%s%s Exécute depuis %s\n",miner.ptr,miner.ptr,info.user.c_str(),info.since.c_str()); printf ("th/s moyen %6.2lf pools vivants %u, actifs %u\n",info.avgth,nbalive,nbactive); printf ("CarteTemp carteTemp chiptemp3Fréquenceth/s idéalth/sChipsTunerÉtat\n"); }else{ printf ("\t%-15s: %-35s Exécute depuis %s\n","Compte",info.user.c_str(),info.since.c_str()); printf ("\t%-15s: %6.2f%30s pools %u vivants, %u actifs\n","Calculs",info.avgth,"",nbalive,nbactive); } for (auto &c:info.chains){ if (html){ printf ("%s",c.first.c_str()); auto &inf = c.second; printf ("%5.2f%5.2f%5.2f%6.2f%5.2f%5.2f%2u%s%s\n" ,inf.temp,inf.temp2,inf.temp3 ,inf.freq/1000000.0 ,inf.rateideal,inf.rate,inf.acn ,inf.tunerstatus.c_str(),inf.enabled ? "actif" : ""); }else{ printf ("\tchain %s: ",c.first.c_str()); auto &inf = c.second; printf ("temp=%5.2f temp2=%5.2f temp3=%5.2f freq=%6.2f rateideal=%5.2f rate=%5.2f acn=%2u tuner=%s enabled=%s\n" ,inf.temp,inf.temp2,inf.temp3 ,inf.freq/1000000.0 ,inf.rateideal,inf.rate,inf.acn,inf.tunerstatus.c_str(),inf.enabled ? "actif" : ""); } } name = info.user; } return ret; } static int miner_info (PARAM_STRING miner, const char *port, bool html, string &name) { double totalh=0; return miner_info (miner,port,html,name,totalh,false); } static int miner_info (PARAM_STRING miner, const char *port, bool html, double &totalh) { string name; return miner_info(miner,port,html,name,totalh,true); } /* Obtient la température maximum (board) de tous les mineurs */ void miner_getmaxtemp ( PARAM_STRING minersfile, // Fichier contenant la liste des mineurs PARAM_STRING offlinefile, // Fichier contenant la liste des mineurs hors service vector &maxtemps, // Température maximum pour chaque mineur. 0 pour les mineurs hors ligne unsigned &mineurs_actif, // Nombre de mineurs actifs (pas hors ligne) unsigned &mineurs_running) // Nombre de mineurs en exécution { mineurs_actif = 0; mineurs_running = 0; maxtemps.clear(); vector miners; set offline; readminers(minersfile.ptr, offlinefile.ptr, miners, offline); for (auto &m:miners){ MINERMAXTEMP mxt(m); if (offline.count(m)==0){ mineurs_actif++; MINER_INFO info; miner_getinfo(m,DEFAULT_PORT,info,true); if (info.chains.size() > 0) mineurs_running++; for (auto &c:info.chains){ if (c.second.temp > mxt.maxtemp) mxt.maxtemp = c.second.temp; } } maxtemps.push_back(move(mxt)); } } // Initialise l'adresse de départ et de fin pour l'énumérationd d'adresses IP static bool coinapi_init_enumaddr (const char *startaddr, const char *endaddr, int saddr[4], int eaddr[4]) { bool ret = false; if (startaddr == nullptr || endaddr == nullptr){ tlmp_error ("Vous devez spécifier l'adresse de départ et de fin\n"); }else if (ipnum_aip24(startaddr,saddr)==-1){ tlmp_error ("Adresse de départ invalide: %s\n",startaddr); }else if (ipnum_aip24(endaddr,eaddr)==-1){ tlmp_error ("Adresse de fin invalide: %s\n",endaddr); }else{ ret = true; } return ret; } // Augmente l'adresse de un. Retourne vide si on a atteint la fin, sinon le numéro IP à tester static string coinapi_loop_enumaddr(int saddr[4], int eaddr[4]) { string ret; if (memcmp(saddr,eaddr,sizeof(int)*4) <=0){ ret = string_f("%d.%d.%d.%d",saddr[0],saddr[1],saddr[2],saddr[3]); // Augmente l'adresse for (int i=3; i>=0; i--){ if (saddr[i] < 255){ saddr[i]++; break; }else{ saddr[i] = 0; } } } return ret; } void coinapi_loadparams(const char *parmfile, map ¶ms) { glocal params; params.clear(); (parmfile,true); line = str_skip(line); if (line[0] != '#' && line[0] != '\0'){ auto tb = str_splitline(line,'='); if (tb.size()==2) glocal.params[tb[0]] = tb[1]; } return 0; } void coinapi_saveparams(const char *parmfile, const map ¶ms) { glocal params; (parmfile,false); for (auto &it:glocal.params){ fprintf (fout,"%s=%s\n",it.first.c_str(),it.second.c_str()); } return 0; } void coinapi_set_hashchain (const char *parmfile, const char *miner, int chain, const char *param, const char *val) { map params; coinapi_loadparams(parmfile,params); string key = string_f("%s.hashchain-%d.%s",miner,chain,param); params[key] = val; coinapi_saveparams (parmfile,params); } /* Imprime une ligne de configuration si présente dans params. Imprime rien sinon, le mineur utilise la valeur par défaut.i */ static void coinapi_printparam (const map ¶ms, const char *miner, int chain, const char *var) { string hashenable = string_f("%s.hashchain-%d.%s",miner,chain,var); auto it = params.find(hashenable); if (it != params.end()){ printf ("%s=%s\n",var,it->second.c_str()); } } void showdate(); int coinapi_main (int argc, char *argv[]) { glocal int ret = -1; glocal const char *port = DEFAULT_PORT; glocal vector miners; glocal set offline; // Mineurs désactivés glocal const char *minersfile = nullptr; glocal const char *offlinefile = nullptr; glocal const char *command = nullptr; glocal const char *off = nullptr; glocal const char *on = nullptr; glocal const char *param = nullptr; glocal const char *startaddr = "192.168.1.1"; glocal const char *endaddr = "192.168.1.254"; glocal unsigned nbscanproc=100; glocal bool scanverbose=false; glocal vector excludescan; glocal bool running = false; glocal bool stopped = false; glocal bool alive = false; glocal bool genconfig = false; glocal const char *accountfile = "/etc/serres/poolaccount.conf"; glocal const char *parmfile = "/etc/serres/parmfile.conf"; glocal const char *proxy = nullptr; glocal const char *miner = nullptr; glocal const char *dump = nullptr; glocal const char *dumpreq="pools+summary+stats+devdetails+temps+devs"; glocal.ret = (argc,argv); setproginfo ("coinapi","0.0","Obtient de l'information d'un ou plusieurs mineurs"); setarg ('c',"command","Commande à exécuter",glocal.command,false); setarg ('p',"param","Paramètre de la commande",glocal.param,false); setarg (' ',"off","Met un mineur hors service",glocal.off,false); setarg (' ',"on","Remet un mineur en service",glocal.on,false); setarg ('m',"mineur","Mineur à contacter",glocal.miners,false); setarg ('f',"mineurs","Fichier contenant une liste de mineurs",glocal.minersfile,false); setarg ('o',"offline","Fichier contenant une liste de mineurs désactivés",glocal.offlinefile,false); setarg ('r',"running","Mineurs actifs",glocal.running,false); setarg (' ',"alive","Mineurs actifs en exécution",glocal.alive,false); setarg (' ',"stopped","Mineurs actifs arrêtés",glocal.stopped,false); setgrouparg("Options pour la commande scan"); setarg ('S',"startaddr","Adresse de départ pour le scan",glocal.startaddr,false); setarg ('E',"endaddr","Adresse de fin pour le scan",glocal.endaddr,false); setarg (' ',"nbscanproc","Nombre de processus pour le scan",glocal.nbscanproc,false); setarg (' ',"scanverbose","Affiche le progrès",glocal.scanverbose,false); setarg (' ',"excludescan","Exclut ce mineur du scan",glocal.excludescan,false); setgrouparg("Options pour la configuration"); setarg (' ',"genconfig","Génère la configuration",glocal.genconfig,false); setarg (' ',"accountfile","Fichier contenant le compte slushpool",glocal.accountfile,false); setarg (' ',"miner","Nom du mineur",glocal.miner,false); setarg (' ',"parmfile","Fichier contenant des paramètres de configuration",glocal.parmfile,false); setarg (' ',"proxy","Utilise ce proxy au lieu des pools normaux",glocal.proxy,false); setgrouparg ("divers"); setarg (' ',"dump","Affiche le JSON du mineur (glocal.niner)",glocal.dump,false); setarg (' ',"dumpreq","Requête JSON",glocal.dumpreq,false); glocal int ret = -1; bool writeoffline = false; // glocal.offline a été modifié. if (!glocal.genconfig && !glocal.dump) readminers (glocal.minersfile,glocal.offlinefile,glocal.miners,glocal.offline); if (glocal.running){ for (auto &m:glocal.miners){ if (glocal.offline.count(m)==0) printf ("%s\n",m.c_str()); } glocal.ret = 0; }else if (glocal.alive || glocal.stopped){ for (auto &m:glocal.miners){ MINER_INFO info; int ok = miner_getinfo (m,glocal.port,info,true); if (glocal.offline.count(m) > 0){ if (ok != -1){ tlmp_error ("Mineur %s fonctionne alors qu'il est hors service\n",m.c_str()); } }else if (ok == -1){ if (glocal.stopped) printf ("%s\n",m.c_str()); }else{ if (glocal.alive) printf ("%s\n",m.c_str()); } } }else if (glocal.genconfig){ if (glocal.miner == nullptr){ tlmp_error ("Option miner est requise\n"); }else{ glocal string account; map params; (glocal.accountfile,true); if (strncmp(line,"ACCOUNT=",8)==0) glocal.account = line+8; return 0; tlmp_error ("Ne peut ouvrir le fichier %s\n",fname); exit (-1); if (glocal.account.empty()){ tlmp_error ("Le fichier %s ne contient pas de ligne ACCOUNT= valide\n",glocal.accountfile); exit (-1); } coinapi_loadparams(glocal.parmfile,params); printf ("[format]\n"); printf ("version = '1.2+'\n"); printf ("model = 'Antminer S9'\n"); printf ("generator = 'coinapi'\n"); printf ("timestamp = %ld\n",time(nullptr)); printf ("\n"); printf ("[fan_control]\n"); printf ("min_fans = 0\n"); printf ("\n"); printf ("[autotuning]\n"); { string line = string_f("%s.autotuning.enabled",glocal.miner); auto it = params.find(line); if (it != params.end()){ printf ("enabled = %s\n",it->second.c_str()); }else{ printf ("enabled = true\n"); } } printf ("\n"); printf ("[[group]]\n"); printf ("name = 'Default'\n"); printf ("\n"); if (glocal.proxy != nullptr){ printf ("[[group.pool]]\n"); printf ("enabled = true\n"); printf ("url = 'stratum+tcp://%s:3333'\n",glocal.proxy); printf ("user = '%s.%s'\n",glocal.account.c_str(),glocal.miner); printf ("password = '123'\n"); printf ("\n"); }else{ printf ("[[group.pool]]\n"); printf ("enabled = true\n"); printf ("url = 'stratum+tcp://ca.stratum.slushpool.com:3333'\n"); printf ("user = '%s.%s'\n",glocal.account.c_str(),glocal.miner); printf ("password = '123'\n"); printf ("\n"); printf ("[[group.pool]]\n"); printf ("enabled = true\n"); printf ("url = 'stratum+tcp://us-east.stratum.slushpool.com:3333'\n"); printf ("user = '%s.%s'\n",glocal.account.c_str(),glocal.miner); printf ("password = '123'\n"); printf ("\n"); printf ("[[group.pool]]\n"); printf ("enabled = true\n"); printf ("url = 'stratum+tcp://stratum.slushpool.com:3333'\n"); printf ("user = '%s.%s'\n",glocal.account.c_str(),glocal.miner); printf ("password = '123'\n"); } for (int i=6; i<9; i++){ printf ("\n[hash_chain.%d]\n",i); coinapi_printparam (params,glocal.miner,i,"enabled"); coinapi_printparam (params,glocal.miner,i,"frequency"); coinapi_printparam (params,glocal.miner,i,"voltage"); } glocal.ret = 0; } }else if (glocal.on != nullptr){ if (glocal.offlinefile == nullptr){ tlmp_error ("Option --offline non spécifié, ne peut continuer\n"); exit (-1); }else if (find(glocal.miners.begin(),glocal.miners.end(),glocal.on)==glocal.miners.end()){ tlmp_error ("Le mineur %s n'existe pas\n",glocal.on); }else if (glocal.offline.count(glocal.on)==0){ tlmp_error ("Le mineur %s est déjà actif\n",glocal.on); }else{ glocal.offline.erase(glocal.on); writeoffline = true; } }else if (glocal.off != nullptr){ if (glocal.offlinefile == nullptr){ tlmp_error ("Option --offline non spécifié, ne peut continuer\n"); exit (-1); }else if (find(glocal.miners.begin(),glocal.miners.end(),glocal.off)==glocal.miners.end()){ tlmp_error ("Le mineur %s n'existe pas\n",glocal.off); }else{ MINER_INFO info; int ok = miner_getinfo (glocal.off,glocal.port,info,true); if (ok != -1){ tlmp_error ("Le mineur %s est actif, il doit être arrêté avant\n",glocal.off); }else if (glocal.offline.insert(glocal.off).second){ writeoffline = true; }else{ tlmp_error ("Le mineur %s est déjà hors service\n",glocal.off); } } }else if (glocal.dump){ ("pools+summary+stats+devdetails+temps+devs",nullptr,glocal.dump,glocal.port,false); glocal.ret = 0; printf ("\t%s %s=%s\n",parent,name,value); }else{ if (glocal.command == nullptr){ usage(); }else{ for (auto &m:glocal.miners){ if (glocal.miners.size() > 1) printf ("Mineur %s\n",m.c_str()); if (glocal.offline.count(m)>0){ printf ("\tLe mineur est hors service\n"); }else{ (glocal.command,glocal.param,m.c_str(),glocal.port,false); glocal.ret = 0; printf ("\t%s %s=%s\n",parent,name,value); } } } } if (writeoffline){ (glocal.offlinefile,false); for (auto &o:glocal.offline) fprintf (fout,"%s\n",o.c_str()); glocal.ret = 0; return 0; } return glocal.ret; glocal int ret = -1; bool readdone = false; for (int i=0; i 1) printf ("Mineur %s\n",m.c_str()); int ok = miner_info (m,glocal.port,false,totalh); if (glocal.offline.count(m) > 0){ if (ok == -1){ printf ("\t le mineur est hors service\n"); }else{ errors += string_f ("\t ***** le mineur %s fonctionne alors qu'il est hors service\n",m.c_str()); } }else{ if (ok == -1) printf ("\t le mineur n'est pas actif\n"); } } printf ("\t%-15s: %6.2lf\n","Calculs total",totalh); if (errors.size() > 0){ printf ("\n"); fputs (errors.c_str(),stdout); } }else if (is_eq(arg,"infohtml")){ if (!readdone){ readminers (glocal.minersfile,glocal.offlinefile,glocal.miners,glocal.offline); readdone = true; } printf ("\n"); printf ("\n"); printf ("État des mineurs\n"); printf ("\n"); printf ("\n"); printf ("\n"); printf ("Maison\n"); printf ("
\n"); showdate(); printf ("

\n"); printf ("\n"); printf ("
Les mineurs\n"); double totalh = 0; for (auto &m:glocal.miners){ if (glocal.offline.count(m) > 0){ printf ("
%sle mineur est hors service\n",m.c_str(),m.c_str()); }else if (miner_info (m,glocal.port,true,totalh) == -1){ printf ("
%sle mineur n'est pas actif\n",m.c_str(),m.c_str()); } } printf ("
Total th/s%5.2lf\n",totalh); printf ("
\n"); printf ("

\n"); printf ("\n"); printf ("\n"); }else if (is_eq(arg,"scan")){ int saddr[4]; int eaddr[4]; if (coinapi_init_enumaddr(glocal.startaddr,glocal.endaddr,saddr,eaddr)){ glocal unsigned nbtest=0; glocal set founds; glocal set excludeset; glocal function fsend; if (!readdone){ readminers_nocheck (glocal.minersfile,glocal.offlinefile,glocal.miners,glocal.offline); readdone = true; } for (auto &m:glocal.miners) glocal.excludescan.push_back(m); for (auto &e:glocal.excludescan){ struct hostent *ent = gethostbyname(e.c_str()); if (ent != nullptr){ string ip = string_f("%u.%u.%u.%u" ,(unsigned char)ent->h_addr[0],(unsigned char)ent->h_addr[1] ,(unsigned char)ent->h_addr[2],(unsigned char)ent->h_addr[3]); printf ("scan: exclu %s -> %s\n",e.c_str(),ip.c_str()); glocal.excludeset.insert(ip); }else{ tlmp_error ("Exclusion invalide %s\n",e.c_str()); } } glocal.fsend = [&](int no){ while (true){ string ip = coinapi_loop_enumaddr(saddr,eaddr); if (ip.size() > 0){ if (glocal.excludeset.count(ip) == 0){ if (glocal.scanverbose) printf ("%-15s\n",ip.c_str()); fflush (stdout); string cmd = string_f("%s\n",ip.c_str()); write (no,cmd.c_str(),cmd.size()); break; } }else{ write (no,"quit\n",5); break; } } }; (); // printf ("nbclients = %d\n",getnbclients()); if (getnbclients() == 1) endserver = true; glocal.nbtest++; if (glocal.nbtest % 10 == 0) printf ("nbtest=%u found=%u\n",glocal.nbtest,(unsigned)glocal.founds.size()); //printf ("receive %s\n",line); glocal.fsend(no); if (strcmp(line,"none")!=0) glocal.founds.insert(line); for (unsigned i=0; i 0){ glocal string ret = "none\n"; glocal.buf[nb] = '\0'; strip_end (glocal.buf); // printf ("read %s\n",glocal.buf); if (strcmp(glocal.buf,"quit")==0) break; ("summary",nullptr,glocal.buf,glocal.port,true); if (strcmp(name,"GHS av")==0 || strcmp(name,"MHS av")==0){ glocal.ret = string_f("%s\n",glocal.buf); } // printf ("send ret=%s",glocal.ret.c_str()); write (glocal.tb[1],glocal.ret.c_str(),glocal.ret.size()); } _exit(0); }else{ close (glocal.tb[1]); s.inject (glocal.tb[0]); glocal.fsend(glocal.tb[0]); } } } s.loop(); map name2ip; for (auto &f:glocal.founds){ printf ("mineur %s\n",f.c_str()); string name; miner_info(f,glocal.port,false,name); const char *pt = strchr(name.c_str(),'.'); if (pt != nullptr) name2ip[pt+1] = f; } for (auto &n:name2ip) printf ("%s %s\n",n.second.c_str(),n.first.c_str()); } }else if (is_eq(arg,"enumaddr")){ int saddr[4]; int eaddr[4]; if (coinapi_init_enumaddr(glocal.startaddr,glocal.endaddr,saddr,eaddr)){ while (true){ string ip = coinapi_loop_enumaddr(saddr,eaddr); if (ip.size() == 0) break; printf ("%s\n",ip.c_str()); } } }else{ tlmp_error ("Commande invalide: %s\n",argv[i]); break; } } return glocal.ret;
return glocal.ret; }