/* This file is part of dc_qt. dc_qt is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. dc_qt is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dc_qt; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "dc_hub.h" #include "dc_parse.h" #include "dc_settings.h" #include "util.h" #include "debugdlg.h" #include #include #include #include #include using namespace std; const char *HUBLIST = "hublist"; dc_hub::dc_hub() : QObject(this,"scheiss"), proc(0), loadAborted(false) {} void dc_hub::load_list_from_web(const QString &url) { if(url!=QString::null) load_list_from_process("hublist",QString::null,"HUBLIST="+url); else load_list_from_process("hublist",QString::null,url); } void dc_hub::load_list_from_disk() { load_list_from_process("cat",settings.get_home_dir() + "/.dc_qt/hublist.cache",QString::null); //debugWin->print("dc_hub::load_list_from_disk(): Unimplemented right now.\n"); } // Called when the hublist process terminates. Parses output and places the result in our hublist. void dc_hub::readFromStdout() { if(loadAborted) { loadAborted = false; return; } bool writefile = true; if(proc->arguments()[0]=="cat") writefile=false; // Open the cachefile QFile file(settings.get_home_dir() + "/.dc_qt/hublist.cache"); if(writefile) { if(!file.open(IO_WriteOnly)) writefile = false; } QTextStream stream(&file); while(proc->canReadLineStdout ()) { QString s = proc->readLineStdout(); // Attempt to read a line if(writefile) stream << s << "\n"; // the file we read in must be of the form // name|ip|desc|num users||||| // one hub per line dc_parse p(s.latin1(), '|'); if (p.num_strs() >= 3) { hub_info *h = new hub_info(p.get_str(HUBNAME), p.get_str(HUBIP), p.get_str(COMMENT), p.get_str(NUMUSERS)); hubs.push_back(h); } } emit got_list(); delete proc; proc = NULL; } // load a hublist from a command line process // probably either a cat of a file or a hublist void dc_hub::load_list_from_process(const QString& process,const QString& arg,const QString& env) { if( proc!=0 && proc->isRunning() ) return; debugWin->print("Getting hublist, " + env); clear_list(hubs); proc = new QProcess(this); proc->addArgument( process ); if(arg!=QString::null) proc->addArgument(arg); proc->setCommunication( QProcess::Stdout ); connect( proc, SIGNAL(processExited()), this, SLOT(readFromStdout()) ); QStringList sl; sl+=env; if ( !proc->start(&sl) ) { // TODO - error handling debugWin->print("Error, could not start hublist\n"); QMessageBox::critical(0,"dc-qt Error","Error: could not start the hublist process.\nIs DCTC properly installed?","Ok"); } } dc_hub::~dc_hub() { clear_list(hubs); clear_list(running); } void dc_hub::clear_list(vector &l) { while (!l.empty()) { hub_info *h = l.back(); l.pop_back(); delete h; } } // Returns the number of running dctc instances int dc_hub::getNumClients() { int ret = 0; const QString dir_name = settings.get_home_dir() + "/.dctc/running"; QDir dir(dir_name, "dctc-*", QDir::Name|QDir::IgnoreCase, QDir::System); for (unsigned int i = 0; i < dir.count(); i++) { QString fname = dir[i]; QString pid_hex = fname.mid(5, 8); bool ok; int pid = pid_hex.toInt(&ok,16); QString ip = fname.mid(14); if (ip.right(4) == ".udp" || ip.right(5) == ".done") continue; if(ip=="dummy_client") continue; if( -1 != getsid(pid)) ret++; } return ret; } void dc_hub::load_running_hubs() { clear_list(running); bool ok; const QString dir_name = settings.get_home_dir() + "/.dctc/running"; // list all files, including system files (ie sockets) in the direction // ~/.dctc/running QDir dir(dir_name, "dctc-*", QDir::Name|QDir::IgnoreCase, QDir::System); for (unsigned int i = 0; i < dir.count(); i++) { QString fname = dir[i]; // the socket name is of the form: // dctc-0000hhhh-iiiiiiiiii... // where hhhh is the hex value of the pid of the dctc client // and iiii... is the hub ip, which is of arbitrary length QString pid_hex = fname.mid(5, 8); QString ip = fname.mid(14); // skip sockets that end with the name .udp or .done if (ip.right(4) == ".udp" || ip.right(5) == ".done") continue; // Skip the dummy client, it should not be visible for connection if(ip=="dummy_client") continue; // See if this process really exists, remove file otherwise int bajs = pid_hex.toInt(&ok, 16); int skit = getsid(bajs); // debugWin->print("SKIT=" + QString::number(skit) + ","+ QString::number(bajs) + "\n"); if( skit == -1 ) { QFile::remove (fname); QFile::remove (fname+".udp"); continue; } // get the hub_info from the list of public hubs hub_info *info = new hub_info(get_public_hub(ip)); // if we didn't find it, just place the info we know in the list if (*info == hub_info("", "", "", "")) { info->name = "n/a"; info->comment = "n/a"; info->users = "n/a"; } QString ptemp = pid_hex; info->ip = ip; info->pid = ptemp.toInt(&ok, 16); running.push_back(info); } } const hub_info dc_hub::get_public_hub(const QString &ip) { for (unsigned int i = 0; i < hubs.size(); i++) { if (hubs[i]->ip == ip) return *hubs[i]; } return hub_info("", "", "", ""); } const hub_info dc_hub::get_running_hub(const QString &ip) { for (unsigned int i = 0; i < running.size(); i++) { if (running[i]->ip == ip) return *running[i]; } return hub_info("", "", "", ""); } void dc_hub::abortLoad( ) { if(proc) { proc->tryTerminate(); loadAborted = true; } }